Store Locator using GeoJSON File as Data Source with Custom Controls¶
This guide shows you how to build a store locator from scratch using a GeoJSON file containing the store locations.The finished example will look like this:
See the example fullscreen
When to use¶
The entire store location data set is relatively small and can be easily downloaded.
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)
GeoJSON file containing the store locations (or use our sample GeoJSON)
Setup¶
Get your Magic Lane API key token: if you do not have a token, see the Getting Started guide.
(1) Interactive Map¶
The first step is to render an interactive map.
How it works¶
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
5var defaultAppScreen = gem.core.App.initAppScreen({
6 container: "map-canvas",
7 style: "./Mono-Day.style" // map style downloaded from Studio
8});
gem.core.App.token
map-canvas
container with a custom map style downloaded from Studio:
gem.core.App.initAppScreen();
1<!DOCTYPE html>
2<html lang="en-us">
3 <head>
4 <meta charset="utf-8" />
5 <title>Store Locator using GeoJSON data with Custom Controls - Step 1</title>
6 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css" />
7 <link rel="stylesheet" href="/fonts/webfonts.css" type="text/css" media="all" />
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; overflow: hidden"></div>
13 </div>
14
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="storeGeojsonCustomControls01.js"></script>
18 </body>
19</html>
(2) Render Store Locations using Map Markers and Information Bubbles¶
Next, we render store locations on the map using a SVG image as marker.
How it works¶
Create a directory for this project in the root directory of your web server.
In our case, the root directory for our local web server is htdocs
,
in which we create the project directory named storeGeojsonCustomControls
.
htdocs/storeGeojsonCustomControls
http://localhost/storeGeojsonCustomControls
Copy your SVG store logo file and GeoJSON store locations file into the project directory.
In our case, we are using the SVG file icon.svg
and
the GeoJSON file paris.geojson
, which can be downloaded from here:
1// stores data source control
2let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("paris.geojson", "icon.svg", undefined /*icon filter*/, {
3 marker: {
4 cssClass: 'store-marker',
5 highlightClass: 'highlight-marker-icon'
6 },
7 markerBubble: {
8 markerBubbleClass: 'store-bubble',
9 markerBubbleFunction: function (elMarker, properties, coords) {
10 elMarker.innerHTML = '<div class="store-bubble">' +
11 '<div class="store-bubble--title">Supermarket</div>' +
12 '<div class="store-bubble--description">' + properties['addr:street'] + ', ' + properties['addr:city'] +
13 '</div></div>';
14 }
15 },
16 markerGrouping: {
17 maxLevel: 14
18 }
19});
20defaultAppScreen.addControl(geojsonDataControl);
1<style>
2 .store-locator {
3 font: 400 15px/22px "Source Sans Pro", "Helvetica Neue", Sans-serif;
4 }
5 .store-marker {
6 background-image: url(./icon.svg);
7 width: 20px;
8 height: 20px;
9 position: absolute;
10 cursor: pointer;
11 }
12
13 .store-marker.active {
14 width: 25px;
15 height: 25px;
16 }
17
18 .store-marker button {
19 position: absolute;
20 top: -50%;
21 left: 50%;
22 background: white;
23 color: #5390d9;
24 border-color: #5390d9;
25 border-style: solid;
26 padding: 0px;
27 cursor: pointer;
28 font-weight: 900;
29 font-size: 60%;
30 border-radius: 9px;
31 min-width: 18px;
32 min-height: 18px;
33 box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%);
34 }
35
36 .highlight-marker-icon {
37 filter: hue-rotate(300deg);
38 transform: scale(1.5);
39 }
40
41 .store-bubble {
42 width: 180px;
43 bottom: 180%;
44 left: 50%;
45 margin-left: -90px;
46 position: absolute;
47 }
48
49 .store-bubble::after {
50 content: "";
51 position: absolute;
52 top: 100%;
53 left: 50%;
54 margin-left: -10px;
55 border-width: 10px;
56 border-style: solid;
57 border-color: white transparent transparent transparent;
58 }
59
60 .store-bubble--title {
61 background: #48bfe3;
62 color: #fff;
63 font-weight: 700;
64 font-size: 16px;
65 text-align: center;
66 display: block;
67 padding: 10px;
68 border-radius: 3px 3px 0px 0px;
69 }
70
71 .store-bubble--description {
72 display: block;
73 padding: 10px;
74 background: #fff;
75 border-radius: 0px 0px 3px 3px;
76 color: grey;
77 }
78</style>
(4) Adding Search Control¶
How it works¶
1let searchControl = new gem.control.SearchControl({
2 highlightOptions: {
3 showContour: false
4 },
5 searchPreferences: {
6 exactMatch: true,
7 maximumMatches: 3,
8 addressSearch: true,
9 mapPoisSearch: true,
10 setCursorReferencePoint: true,
11 placeholderText: 'Search...'
12 },
13 searchResults: {
14 showLandmarkIcons: false
15 }
16});
17defaultAppScreen.addControl(searchControl);
Files¶
The finished example consists of the project directory containing these files:
JavaScript code (
.js
file extension)HTML code (
.html
file extension)GeoJSON store location file (
.geojson
file extension)SVG store logo (
.svg
file extension)Map style (
.style
file extension)
To run the example, the HTML file is loaded in a browser.
Source code for this example:
JavaScriptHTML
GeoJSON store locations
SVG store logo
Map style
right-click on the links and select Save As.