Skip to content

Store Locator with different Marker Groups Styles

This guide shows how the appearance of the marker groups style can be customized using previously added data source controls for your stores data.

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.

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 controls

To see how to add data source control, store list control and free text search control check out the guides Store Locator using a GeoJSON File as Data Source, Store Locator using SQL Server as Data Source, Store Locator using Studio Defined Data Source or Store Locator using GeoJSON Text String as Data Source.

Store Locator with Marker Groups displayed with Circle Style

The finished example using the marker grouping circle style will look like this:

See the example fullscreen

How it works

 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: 11,
 8     center: [48.85671, 2.35138], // Paris latitude and longitude
 9     style: "./Printemps.style"
10 });
11
12 let searchControl = new gem.control.SearchControl({
13     highlightOptions: {
14             contourColor: { r: 0, g: 255, b: 0, a: 0 }
15     },
16     searchPreferences: {
17             maximumMatches: 3,
18             addressSearch: true,
19             mapPoisSearch: true,
20             setCursorReferencePoint: true
21     }
22 });
23 defaultAppScreen.addControl(searchControl);
24
25 let queryAddedDataControl = new gem.control.QueryAddedDataControl(
26     {
27             languages: ["en"],
28             storeId: 1,
29     },
30     "icon.svg",
31     {
32             marker: {
33                     highlightClass: 'highlight-store-marker'
34             },
35             markerBubble: {
36                     title: ['name'],
37                     image: ['preview'],
38             },
39             markerGrouping: {
40                     maxLevel: 15,
41                     style: gem.control.MarkersGroupStyleType.circle
42             }
43     }
44 );
45
46 let listUIControl = new gem.control.ListControl({
47     sourceControl: queryAddedDataControl,
48     container: "menu-list-container",
49     displayCount: true,
50     flyToItemAltitude: 250, // meters
51     menuName: 'Circle Marker Groups Example',
52     titleProperties: ['name'],
53         imageProperty: ['preview']
54 });
55
56 defaultAppScreen.addControl(queryAddedDataControl);
57 defaultAppScreen.addControl(listUIControl);
The data source control option markerGrouping.style is used to change the marker groups appearance from the default style to the circles images.
 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>Marker Groups Circle Style - MagicLane Maps SDK for JavaScript</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       .highlight-store-marker {
12         filter: hue-rotate(40deg) contrast(1.5);
13         transform: scale(1.4);
14       }
15     </style>
16   </head>
17
18   <body>
19     <div id="store-locator" style="width: 100%; height: 100%">
20       <div id="menu-list-container" class="menu-list-container" style="width: 30%; height: 100%; position: absolute"></div>
21       <div id="map-canvas" style="width: 70%; left: 30%; height: 100%; position: absolute; overflow: hidden"></div>
22     </div>
23
24     <script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
25     <script type="text/javascript" src="token.js"></script>
26     <script type="text/javascript" src="jsStoreCircleMarkerGroups.js"></script>
27   </body>
28 </html>

Files


JavaScript
HTML
Printemps Map Style

Right-click on the links and select Save As.

Store Locator with Custom Marker Groups

The finished example using a custom marker grouping style will look like this:

See the example fullscreen

How it works

 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: 11,
 8     center: [48.85671, 2.35138], // Paris latitude and longitude
 9     style: "./Printemps.style"
10 });
11
12 let searchControl = new gem.control.SearchControl({
13     highlightOptions: {
14             contourColor: { r: 0, g: 255, b: 0, a: 0 },
15     },
16     searchPreferences: {
17             maximumMatches: 3,
18             addressSearch: true,
19             mapPoisSearch: true,
20             setCursorReferencePoint: true
21     }
22 });
23 defaultAppScreen.addControl(searchControl);
24
25 let queryAddedDataControl = new gem.control.QueryAddedDataControl(
26     {
27             languages: ["en"],
28             storeId: 1
29     },
30     "icon.svg",
31     {
32             marker: {
33                     highlightClass: 'highlight-store-marker'
34             },
35             markerBubble: {
36                     title: ['name'],
37                     image: ['preview']
38             },
39             markerGrouping: {
40                     maxLevel: 15,
41                     style: gem.control.MarkersGroupStyleType.custom,
42                     markerGroupFunction: function (groupsize) {
43                             let customGroupDiv = document.createElement('div');
44                             customGroupDiv.className = 'store-marker-group';
45                             if (groupsize > 100) {
46                                     customGroupDiv.classList.add('large');
47                             }
48                             else if (groupsize > 25) {
49                                     customGroupDiv.classList.add('medium');
50                             }
51                             else {
52                                     customGroupDiv.classList.add('small');
53                             }
54                             let textDiv = customGroupDiv.appendChild(document.createElement('div'));
55                             textDiv.className = 'store-marker-group-text';
56                             let textGroupSize = textDiv.appendChild(document.createElement('span'));
57                             textGroupSize.innerHTML = groupsize;
58                             return customGroupDiv;
59                     }
60             }
61     }
62 );
63
64 let listUIControl = new gem.control.ListControl({
65     sourceControl: queryAddedDataControl,
66     container: "menu-list-container",
67     displayCount: true,
68     flyToItemAltitude: 250, // meters
69     menuName: 'Custom Marker Groups Example',
70     titleProperties: ['name'],
71         imageProperty: ['preview']
72 });
73
74 defaultAppScreen.addControl(queryAddedDataControl);
75 defaultAppScreen.addControl(listUIControl);
The data source control option markerGrouping.style set with the value gem.control.MarkersGroupStyleType.custom is used to enable the customization of the marker groups.
Using the option markerGrouping.markerGroupFunction and the parameter groupsize the store markers groups can be stylized based on any group size and with any style.
In the example above the marker groups have been styled differently based on the category they belong to: large groups are considered to include over 100 items, medium ones are between 99 and 26 items and small groups are below and including 25 items.
 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>Custom Marker Groups - MagicLane Maps SDK for JavaScript</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       .highlight-store-marker {
12         filter: hue-rotate(40deg) contrast(1.5);
13         transform: scale(1.4);
14       }
15
16       .store-marker-group {
17         height: 20px;
18         width: 20px;
19         position: absolute;
20       }
21
22       .store-marker-group.large {
23         background-image: url(./shops_large.svg);
24         background-position: center;
25         background-repeat: no-repeat;
26         background-size: contain;
27         width: 30px;
28         height: 30px;
29       }
30
31       .store-marker-group.medium {
32         background-image: url(./shops_medium.svg);
33         background-position: center;
34         background-repeat: no-repeat;
35         background-size: contain;
36         width: 25px;
37         height: 25px;
38       }
39
40       .store-marker-group.small {
41         background-image: url(./shops_small.svg);
42         background-position: center;
43         background-repeat: no-repeat;
44         background-size: contain;
45         width: 20px;
46         height: 20px;
47       }
48
49       .store-marker-group-text {
50         display: inline-block;
51         position: relative;
52         border-radius: 50%;
53         max-width: 30px;
54         min-width: 18px;
55         min-height: 10px;
56         text-align: center;
57         font-weight: 600;
58         box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%);
59       }
60
61       .store-marker-group-text span {
62         font-size: 0.7rem;
63         margin: 2px;
64       }
65
66       .store-marker-group.small .store-marker-group-text {
67         left: 12px;
68         top: -9px;
69         background-color: #6cdd76;
70       }
71
72       .store-marker-group.medium .store-marker-group-text {
73         left: 17px;
74         top: -6px;
75         background-color: #ffff5c;
76       }
77
78       .store-marker-group.large .store-marker-group-text {
79         left: 20px;
80         top: -3px;
81         background-color: #ffa849;
82       }
83     </style>
84   </head>
85
86   <body>
87     <div id="store-locator" style="width: 100%; height: 100%">
88       <div id="menu-list-container" class="menu-list-container" style="width: 30%; height: 100%; position: absolute"></div>
89       <div id="map-canvas" style="width: 70%; left: 30%; height: 100%; position: absolute; overflow: hidden"></div>
90     </div>
91
92     <script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
93     <script type="text/javascript" src="token.js"></script>
94     <script type="text/javascript" src="jsStoreCustomMarkerGroups.js"></script>
95   </body>
96 </html>

Files


JavaScript
HTML
Printemps Map Style
Icons customized from Iconpacks:
Large Marker Group Image
Medium Marker Group Image
Small Marker Group Image

right-click on the links and select Save As.

JavaScript Examples

Maps SDK for JavaScript Examples can be downloaded or cloned with Git