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.