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:
See the example fullscreen
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.
Adding stores data¶
1// Start by setting your token from https://developer.magiclane.com/api/projects
2gem.core.App.token="your_API_key_token";
gem.core.App.token
1// Start by setting your token from https://developer.magiclane.com/api/projects
2if (gem.core.App.token === undefined)
3 gem.core.App.token = "";
4
5let defaultAppScreen = gem.core.App.initAppScreen({
6 container: 'map-canvas'
7}
8);
9
10// Custom GeoJSON data - this can be stored on the server, or in a separate file,
11// or right here in a string:
12let geoJsonObject = {
13 "type": "FeatureCollection", "features": [
14
15 { "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" } },
16
17 { "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" } },
18
19 { "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" } }
20
21 ]
22};
23let geojsonDataControl = new gem.control.GeoJsonAddedDataControl(geoJsonObject, "" /*icon default*/, "" /*no icon filter*/,
24 {
25 markerBubble: {
26 title: ['name'],
27 image: ['preview']
28 }
29 });
30defaultAppScreen.addControl(geojsonDataControl);
div
container with the id map-canvas
in the HTML page.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.defaultAppScreen.addControl(geojsonDataControl);
1<!doctype html>
2<html lang="en-us">
3
4<head>
5 <meta charset="utf-8">
6 <title>Store Locator using GeoJSON Text String Data - MagicLane Maps SDK for JavaScript</title>
7 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
8</head>
9
10<body>
11 <div id="store-locator" style="width: 100%; height: 100%">
12 <div id="map-canvas" style="width: 100%; height: 100%; position:absolute;">
13 </div>
14 </div>
15 <script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
16 <script type="text/javascript" src="token.js"></script>
17 <script type="text/javascript" src="jsStoreGeojsonString01.js"></script>
18</body>
19
20</html>
map-canvas
is the drawing area where the map is rendered.
The canvas is configured to fill the browser window.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:
1let listUIControl = new gem.control.ListControl({
2 sourceControl: geojsonDataControl,
3 container: 'menu-list-container',
4 menuName: 'Store locations',
5 titleProperties: ['name'], // Geojson property keys to use for store title
6 detailsProperties: ['kinds'], // Geojson property keys to use for store details
7 imageProperty: ['preview'] // Geojson property key to use for image
8});
9defaultAppScreen.addControl(listUIControl);
1<div id="store-locator" style="width: 100%; height: 100%">
2 <div id="menu-list-container" style="width: 30%; height: 100%; position: absolute;"></div>
3 <div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%;">
4 </div>
5</div>
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%.menuName
.titleProperties
and detailsProperties
.Adding free text search¶
To add free-form text search functionality simply add the following JavaScript code:
1let searchControl = new gem.control.SearchControl({
2 searchPreferences: {
3 exactMatch: true,
4 maximumMatches: 3,
5 addressSearch: true,
6 mapPoisSearch: true,
7 setCursorReferencePoint: true
8 },
9 highlightOptions: {
10 contourColor: { r: 0, g: 255, b: 0, a: 0 }
11 }
12});
13defaultAppScreen.addControl(searchControl);
Complete example code¶
1// Start by setting your token from https://developer.magiclane.com/api/projects
2if (gem.core.App.token === undefined)
3 gem.core.App.token = "";
4
5let defaultAppScreen = gem.core.App.initAppScreen({
6 container: 'map-canvas'
7}
8);
9// Custom GeoJSON data - this can be stored on the server, or in a separate file,
10// or right here in a string:
11let geoJsonObject = {
12 "type": "FeatureCollection", "features": [
13
14 { "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" } },
15
16 { "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" } },
17
18 { "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" } }
19
20 ]
21};
22let geojsonDataControl = new gem.control.GeoJsonAddedDataControl(geoJsonObject, "" /*icon default*/, "" /*no icon filter*/,
23 {
24 markerBubble: {
25 title: ['name'],
26 image: ['preview']
27 }
28 });
29defaultAppScreen.addControl(geojsonDataControl);
30
31let listUIControl = new gem.control.ListControl({
32 sourceControl: geojsonDataControl,
33 container: 'menu-list-container',
34 menuName: 'Store locations',
35 titleProperties: ['name'], // Geojson property keys to use for store title
36 detailsProperties: ['kinds'], // Geojson property keys to use for store details
37 imageProperty: ['preview'] // Geojson property keys to use for store details
38});
39defaultAppScreen.addControl(listUIControl);
40
41let searchControl = new gem.control.SearchControl({
42 searchPreferences: {
43 exactMatch: true,
44 maximumMatches: 3,
45 addressSearch: true,
46 mapPoisSearch: true,
47 setCursorReferencePoint: true
48 },
49 highlightOptions: {
50 contourColor: { r: 0, g: 255, b: 0, a: 0 }
51 }
52});
53defaultAppScreen.addControl(searchControl);
1<!doctype html>
2<html lang="en-us">
3
4<head>
5 <meta charset="utf-8">
6 <title>Store Locator using GeoJSON Text String data - MagicLane Maps SDK for JavaScript</title>
7 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
8</head>
9
10<body>
11 <div id="store-locator" style="width: 100%; height: 100%">
12 <div id="menu-list-container" style="width: 30%; height: 100%; position: absolute;"></div>
13 <div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%;">
14 </div>
15 </div>
16 <script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
17 <script type="text/javascript" src="token.js"></script>
18 <script type="text/javascript" src="jsStoreGeojsonString03.js"></script>
19</body>
20
21</html>
Files¶
The finished example consists of the project directory containing 3 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:
JavaScriptHTML
SVG icon
right-click on the links and select Save As.