Store Locator using GeoJSON Text String as Data Source
This guide shows you how to build a store locator from scratch using store locations loaded from GeoJSON data, defined in a string variable in the JavaScript example.
The finished example will look like this:
When to use
- The entire store location data set is very small and can be easily put in a string in the JavaScript code.
- The data set is not changing frequently.
What is needed
- Magic Lane API key token
- Web server (an example is provided)
- SVG file of the store logo (or use our sample SVG)
- Store locations in GeoJSON format (or use our sample locations)
Setup
Get your Magic Lane API key token: if you do not have a token, see the Getting Started guide.
This project needs a web server. If you do not have access to a web server, you can easily install a local web server, see the Installing a Local Web Server guide. In this project we use a local web server.
Adding stores data
- JavaScript
- HTML
// Start by setting your token from https://developer.magiclane.com/api/projects
gem.core.App.token="your_API_key_token";
The first step in JavaScript is to set your API key token gem.core.App.token
.
// Start by setting your token from https://developer.magiclane.com/api/projects
if (gem.core.App.token === undefined)
gem.core.App.token = "";
let defaultAppScreen = gem.core.App.initAppScreen({
container: 'map-canvas'
}
);
// Custom GeoJSON data - this can be stored on the server, or in a separate file,
// or right here in a string:
let geoJsonObject = {
"type": "FeatureCollection", "features": [
{ "type": "Feature", "id": 9475889, "geometry": { "type": "Point", "coordinates": [2.339905, 48.867035] }, "properties": { "preview": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/P1040471_Paris_II_galerie_Vivienne_rwk.JPG/400px-P1040471_Paris_II_galerie_Vivienne_rwk.JPG", "image": "https://commons.wikimedia.org/wiki/File:P1040471%20Paris%20II%20galerie%20Vivienne%20rwk.JPG", "xid": "N253963375", "sources": { "geometry": "osm", "attributes": ["osm", "wikidata"] }, "rate": "3h", "name": "Galerie Vivienne", "osm": "node/253963375", "otm": "https://opentripmap.com/en/card/N253963375", "kinds": "historic_architecture,architecture,urban_environment,cultural,interesting_places,shops,squares,malls,tourist_facilities,other_buildings_and_structures", "wikipedia": "https://en.wikipedia.org/wiki/Galerie%20Vivienne", "wikidata": "Q1314020" } },
{ "type": "Feature", "id": 9522262, "geometry": { "type": "Point", "coordinates": [2.338843, 48.866386] }, "properties": { "preview": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Galerie_Colbert.jpg/400px-Galerie_Colbert.jpg", "image": "https://commons.wikimedia.org/wiki/File:Galerie%20Colbert.jpg", "xid": "N4376621091", "sources": { "geometry": "osm", "attributes": ["osm", "wikidata"] }, "rate": "3h", "name": "Galerie Colbert", "osm": "node/4376621091", "otm": "https://opentripmap.com/en/card/N4376621091", "kinds": "historic_architecture,architecture,urban_environment,cultural,interesting_places,installation,shops,squares,malls,tourist_facilities,other_buildings_and_structures", "wikipedia": "https://fr.wikipedia.org/wiki/Galerie%20Colbert", "wikidata": "Q1294677" } },
{ "type": "Feature", "id": 9806855, "geometry": { "type": "Point", "coordinates": [2.339182, 48.866165] }, "properties": { "preview": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Passage_des_Deux-Pavillons,_Paris_1.jpg/400px-Passage_des_Deux-Pavillons,_Paris_1.jpg", "image": "https://commons.wikimedia.org/wiki/File:Passage%20des%20Deux-Pavillons%2C%20Paris%201.jpg", "xid": "W54046684", "sources": { "geometry": "osm", "attributes": ["osm", "wikidata"] }, "rate": "3h", "bbox": { "lat_max": 48.866197, "lat_min": 48.86612, "lon_max": 2.339265, "lon_min": 2.339048 }, "name": "Passage des Deux-Pavillons", "osm": "way/54046684", "otm": "https://opentripmap.com/en/card/W54046684", "kinds": "historic_architecture,architecture,urban_environment,cultural,interesting_places,shops,squares,malls,tourist_facilities,other_buildings_and_structures", "wikipedia": "https://fr.wikipedia.org/wiki/Passage%20des%20Deux-Pavillons", "wikidata": "Q3368108" } }
]
};
let geojsonDataControl = new gem.control.GeoJsonAddedDataControl(geoJsonObject, "" /*icon default*/, "" /*no icon filter*/,
{
markerBubble: {
title: ['name'],
image: ['preview']
}
});
defaultAppScreen.addControl(geojsonDataControl);
The map is rendered in the div
container with the id map-canvas
in the HTML page.
The map is centered on the center of the dataset.
A GeoJSON text string is defined containing 1 or more store locations.
A gem.control.GeoJsonAddedDataControl(geoJsonFileOrObject, iconLocation, iconFilter, dataOptions);
is instantiated with the string containing the store locations in GeoJSON format, the filename of an SVG logo to use for rendering the store locations (optional), an icon filter (optional) and options for styling the store marker bubble that appears on hover/click action.
The store locations are added to the map: defaultAppScreen.addControl(geojsonDataControl);
.
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Store Locator using GeoJSON Text String Data - MagicLane Maps SDK for JavaScript</title>
<link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
</head>
<body>
<div id="store-locator" style="width: 100%; height: 100%">
<div id="map-canvas" style="width: 100%; height: 100%; position:absolute;">
</div>
</div>
<script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
<script type="text/javascript" src="token.js"></script>
<script type="text/javascript" src="jsStoreGeojsonString01.js"></script>
</body>
</html>
The map-canvas
is the drawing area where the map is rendered. The canvas is configured to fill the browser window.
At the bottom, gemapi.js, the Maps SDK for JavaScript is loaded.
Next, the JavaScript source of this example is loaded.
Adding stores list
To display a list of the store locations add a menu list container to your HTML file and the following JavaScript code:
- JavaScript
- HTML
let listUIControl = new gem.control.ListControl({
sourceControl: geojsonDataControl,
container: 'menu-list-container',
menuName: 'Store locations',
titleProperties: ['name'], // Geojson property keys to use for store title
detailsProperties: ['kinds'], // Geojson property keys to use for store details
imageProperty: ['preview'] // Geojson property key to use for image
});
defaultAppScreen.addControl(listUIControl);
<div id="store-locator" style="width: 100%; height: 100%">
<div id="menu-list-container" style="width: 30%; height: 100%; position: absolute;"></div>
<div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%;">
</div>
</div>
The menu-list-container
is the HTML element where the stores list is created. It is setup using the list control option container
. In this case the list container has been configured to occupy 30% width of the screen and the map canvas 70%.
The stores list header text can also be customized using the list control option menuName
.
You can also customize which GeoJSON properties to use for store names and details in the list using the list control options titleProperties
and detailsProperties
.
Adding free text search
To add free-form text search functionality simply add the following JavaScript code:
- JavaScript
let searchControl = new gem.control.SearchControl({
searchPreferences: {
exactMatch: true,
maximumMatches: 3,
addressSearch: true,
mapPoisSearch: true,
setCursorReferencePoint: true
},
highlightOptions: {
contourColor: { r: 0, g: 255, b: 0, a: 0 }
}
});
defaultAppScreen.addControl(searchControl);
Complete example code
- JavaScript
- HTML
// Start by setting your token from https://developer.magiclane.com/api/projects
if (gem.core.App.token === undefined)
gem.core.App.token = "";
let defaultAppScreen = gem.core.App.initAppScreen({
container: 'map-canvas'
}
);
// Custom GeoJSON data - this can be stored on the server, or in a separate file,
// or right here in a string:
let geoJsonObject = {
"type": "FeatureCollection", "features": [
{ "type": "Feature", "id": 9475889, "geometry": { "type": "Point", "coordinates": [2.339905, 48.867035] }, "properties": { "preview": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/P1040471_Paris_II_galerie_Vivienne_rwk.JPG/400px-P1040471_Paris_II_galerie_Vivienne_rwk.JPG", "image": "https://commons.wikimedia.org/wiki/File:P1040471%20Paris%20II%20galerie%20Vivienne%20rwk.JPG", "xid": "N253963375", "sources": { "geometry": "osm", "attributes": ["osm", "wikidata"] }, "rate": "3h", "name": "Galerie Vivienne", "osm": "node/253963375", "otm": "https://opentripmap.com/en/card/N253963375", "kinds": "historic_architecture,architecture,urban_environment,cultural,interesting_places,shops,squares,malls,tourist_facilities,other_buildings_and_structures", "wikipedia": "https://en.wikipedia.org/wiki/Galerie%20Vivienne", "wikidata": "Q1314020" } },
{ "type": "Feature", "id": 9522262, "geometry": { "type": "Point", "coordinates": [2.338843, 48.866386] }, "properties": { "preview": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Galerie_Colbert.jpg/400px-Galerie_Colbert.jpg", "image": "https://commons.wikimedia.org/wiki/File:Galerie%20Colbert.jpg", "xid": "N4376621091", "sources": { "geometry": "osm", "attributes": ["osm", "wikidata"] }, "rate": "3h", "name": "Galerie Colbert", "osm": "node/4376621091", "otm": "https://opentripmap.com/en/card/N4376621091", "kinds": "historic_architecture,architecture,urban_environment,cultural,interesting_places,installation,shops,squares,malls,tourist_facilities,other_buildings_and_structures", "wikipedia": "https://fr.wikipedia.org/wiki/Galerie%20Colbert", "wikidata": "Q1294677" } },
{ "type": "Feature", "id": 9806855, "geometry": { "type": "Point", "coordinates": [2.339182, 48.866165] }, "properties": { "preview": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Passage_des_Deux-Pavillons,_Paris_1.jpg/400px-Passage_des_Deux-Pavillons,_Paris_1.jpg", "image": "https://commons.wikimedia.org/wiki/File:Passage%20des%20Deux-Pavillons%2C%20Paris%201.jpg", "xid": "W54046684", "sources": { "geometry": "osm", "attributes": ["osm", "wikidata"] }, "rate": "3h", "bbox": { "lat_max": 48.866197, "lat_min": 48.86612, "lon_max": 2.339265, "lon_min": 2.339048 }, "name": "Passage des Deux-Pavillons", "osm": "way/54046684", "otm": "https://opentripmap.com/en/card/W54046684", "kinds": "historic_architecture,architecture,urban_environment,cultural,interesting_places,shops,squares,malls,tourist_facilities,other_buildings_and_structures", "wikipedia": "https://fr.wikipedia.org/wiki/Passage%20des%20Deux-Pavillons", "wikidata": "Q3368108" } }
]
};
let geojsonDataControl = new gem.control.GeoJsonAddedDataControl(geoJsonObject, "" /*icon default*/, "" /*no icon filter*/,
{
markerBubble: {
title: ['name'],
image: ['preview']
}
});
defaultAppScreen.addControl(geojsonDataControl);
let listUIControl = new gem.control.ListControl({
sourceControl: geojsonDataControl,
container: 'menu-list-container',
menuName: 'Store locations',
titleProperties: ['name'], // Geojson property keys to use for store title
detailsProperties: ['kinds'], // Geojson property keys to use for store details
imageProperty: ['preview'] // Geojson property keys to use for store details
});
defaultAppScreen.addControl(listUIControl);
let searchControl = new gem.control.SearchControl({
searchPreferences: {
exactMatch: true,
maximumMatches: 3,
addressSearch: true,
mapPoisSearch: true,
setCursorReferencePoint: true
},
highlightOptions: {
contourColor: { r: 0, g: 255, b: 0, a: 0 }
}
});
defaultAppScreen.addControl(searchControl);
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Store Locator using GeoJSON Text String data - MagicLane Maps SDK for JavaScript</title>
<link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
</head>
<body>
<div id="store-locator" style="width: 100%; height: 100%">
<div id="menu-list-container" style="width: 30%; height: 100%; position: absolute;"></div>
<div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%;">
</div>
</div>
<script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
<script type="text/javascript" src="token.js"></script>
<script type="text/javascript" src="jsStoreGeojsonString03.js"></script>
</body>
</html>
Files
The finished example consists of the project directory containing these files:
- JavaScript code (
.js
file extension) - HTML code (
.html
file extension) - SVG icon (
.svg
file extension)
To run the example, the HTML file is loaded in a browser.
Source code for this example:
Right-click on the links and select Save As.
Related
See Store Locator using a GeoJSON File as Data Source for an example with GeoJSON data loaded from a file and rendered on the map.
See Store Locator using Studio Defined Data Source for an example with GeoJSON data uploaded to the map studio and rendered on the map.
See Store Locator using SQL Server as Data Source for an example with GeoJSON data queried dynamically using SQL from a server and rendered on the map.
See Store Locator using GeoJSON File as Data Source with Custom Controls for an example with GeoJSON data loaded from a file, using controls with custom options for map browsing, map markers, markers list and free text search control.
JavaScript Examples
Maps SDK for JavaScript Examples can be downloaded or cloned with Git.