Store Locator with Custom Markers Using Data Labels ¶
See the example fullscreen
What is needed ¶
-
Magic Lane API key token
-
Web server
Setup ¶
Get your Magic Lane API key token: if you do not have a token, see the Getting Started guide.
Adding controls ¶
Adding Custom Markers with Data Labels ¶
How it works ¶
1 let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("Madrid_shops.geojson", "" /*icon*/, ""/*iconFilter*/, {
2 marker: {
3 width: 45,
4 height: 45,
5 hoverWidth: 45,
6 hoverHeight: 45,
7 cssClass: 'store-marker',
8 highlightClass: 'highlight-store-marker',
9 markerFunction: function (itemInfoString) {
10 let labelDiv = document.createElement('div');
11 labelDiv.className = 'store-marker-text';
12 let textlabel = labelDiv.appendChild(document.createElement('span'));
13 let jsonInfo = JSON.parse(itemInfoString);
14 if (jsonInfo.properties.rate)
15 textlabel.innerHTML = 'rate ' + jsonInfo.properties.rate;
16 else
17 textlabel.innerHTML = 'rate n.a.';
18 return labelDiv;
19 }
20 },
21 markerGrouping: {
22 maxLevel: 15,
23 style: gem.control.MarkersGroupStyleType.circle
24 },
25 markerBubble: {
26 title: ['name'],
27 image: ['preview']
28 }
29 });
To customize the markers with data labels you can use the data source control options:
-
marker.cssClass - specify custom style rules class for markers
-
marker.markerFunction - specify how to style the marker inner elements and optionally use the item data to add labels or filters to the marker
1 <style>
2 .store-marker {
3 background-image: url(./custom.svg);
4 background-position: center;
5 background-repeat: no-repeat;
6 background-size: contain;
7 width: 45px;
8 height: 45px;
9 position: absolute;
10 margin: 0px auto;
11 cursor: pointer;
12 text-align: center;
13 }
14
15 .store-marker.active {
16 filter: hue-rotate(200deg) contrast(1.5);
17 }
18
19 .store-marker-text {
20 display: inline-block;
21 position: relative;
22 border-radius: 50%;
23 max-width: 30px;
24 min-width: 18px;
25 min-height: 10px;
26 text-align: center;
27 font-weight: 600;
28 top: 5px;
29 line-height: 9px;
30 -webkit-touch-callout: none;
31 -webkit-user-select: none;
32 -khtml-user-select: none;
33 -moz-user-select: none;
34 -ms-user-select: none;
35 user-select: none;
36 color: white;
37 }
38
39 .store-marker-text span {
40 font-size: 0.6rem;
41 margin: 0px;
42 }
43
44 .highlight-store-marker {
45 filter: hue-rotate(80deg) contrast(1.5);
46 }
47 </style>
Complete example code ¶
1 // Start by setting your token from https://developer.magiclane.com/api/projects
2 if (gem.core.App.token === undefined)
3 gem.core.App.token = "";
4
5 var defaultAppScreen = gem.core.App.initAppScreen({
6 container: "map-canvas",
7 zoom: 10,
8 center: [40.431404, -3.680445], // Madrid
9 style: "./Printemps.style"
10 });
11
12 let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("Madrid_shops.geojson", "" /*icon*/, ""/*iconFilter*/, {
13 marker: {
14 width: 45,
15 height: 45,
16 hoverWidth: 45,
17 hoverHeight: 45,
18 cssClass: 'store-marker',
19 highlightClass: 'highlight-store-marker',
20 markerFunction: function (itemInfoString) {
21 let labelDiv = document.createElement('div');
22 labelDiv.className = 'store-marker-text';
23 let textlabel = labelDiv.appendChild(document.createElement('span'));
24 let jsonInfo = JSON.parse(itemInfoString);
25 if (jsonInfo.properties.rate)
26 textlabel.innerHTML = 'rate ' + jsonInfo.properties.rate;
27 else
28 textlabel.innerHTML = 'rate n.a.';
29 return labelDiv;
30 }
31 },
32 markerGrouping: {
33 maxLevel: 15,
34 style: gem.control.MarkersGroupStyleType.circle
35 },
36 markerBubble: {
37 title: ['name'],
38 image: ['preview']
39 }
40 });
41
42 let listUIControl = new gem.control.ListControl({
43 sourceControl: geojsonDataControl,
44 container: "menu-list-container",
45 displayCount: true,
46 flyToItemAltitude: 250,
47 menuName: 'Marker Data Labels, GeoJSON data source',
48 titleProperties: ['name'],
49 detailsProperties: ['kinds'],
50 imageProperty: ['preview']
51 });
52
53 defaultAppScreen.addControl(geojsonDataControl);
54 defaultAppScreen.addControl(listUIControl);
55
56 let searchControl = new gem.control.SearchControl({
57 highlightOptions: {
58 contourColor: { r: 0, g: 255, b: 0, a: 0 }
59 },
60 searchPreferences: {
61 maximumMatches: 3,
62 addressSearch: true,
63 mapPoisSearch: true,
64 setCursorReferencePoint: true
65 }
66 });
67 defaultAppScreen.addControl(searchControl);
1 <!DOCTYPE html>
2 <html lang="en-us">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1, user-scalable=no, shrink-to-fit=no" />
6 <title>Markers Data Labels</title>
7 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
8 <link rel="stylesheet" href="/fonts/webfonts.css" type="text/css" media="all" />
9
10 <style>
11 .store-marker {
12 background-image: url(./custom.svg);
13 background-position: center;
14 background-repeat: no-repeat;
15 background-size: contain;
16 width: 45px;
17 height: 45px;
18 position: absolute;
19 margin: 0px auto;
20 cursor: pointer;
21 text-align: center;
22 }
23
24 .store-marker.active {
25 filter: hue-rotate(200deg) contrast(1.5);
26 }
27
28 .store-marker-text {
29 display: inline-block;
30 position: relative;
31 border-radius: 50%;
32 max-width: 30px;
33 min-width: 18px;
34 min-height: 10px;
35 text-align: center;
36 font-weight: 600;
37 top: 5px;
38 line-height: 9px;
39 -webkit-touch-callout: none;
40 -webkit-user-select: none;
41 -khtml-user-select: none;
42 -moz-user-select: none;
43 -ms-user-select: none;
44 user-select: none;
45 color: white;
46 }
47
48 .store-marker-text span {
49 font-size: 0.6rem;
50 margin: 0px;
51 }
52
53 .highlight-store-marker {
54 filter: hue-rotate(80deg) contrast(1.5);
55 }
56 </style>
57 </head>
58
59 <body>
60 <div id="store-locator" style="width: 100%; height: 100%">
61 <div id="menu-list-container" class="menu-list-container" style="width: 30%; height: 100%; position: absolute"></div>
62 <div id="map-canvas" style="width: 70%; left: 30%; height: 100%; position: absolute; overflow: hidden"></div>
63 </div>
64
65 <script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
66 <script type="text/javascript" src="token.js"></script>
67 <script type="text/javascript" src="storeGeoJSONDataMarkers.js"></script>
68 </body>
69 </html>
Files ¶
JavaScript
HTML
Printemps Map Style
GeoJSON data downloaded from OpenTripMap :
Madrid Shops Example GeoJSON
Icon customized from Iconpacks :
Custom Marker Image