Store Locator using GeoJSON Data Source with Custom Marker Bubbles ¶
This guide shows you how to customize store marker bubbles using previously added data source control for your stores data. A GeoJSON file with stores locations and properties is used as an example data source.The finished example will look like this:
See the example fullscreen
What is needed ¶
-
Magic Lane API key token
-
Web server (an example is provided)
-
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.
Adding controls ¶
To see how to add GeoJSON data control, store list control and free text search control check out the guides Store Locator using a GeoJSON File as Data Source or Store Locator using GeoJSON Text String as Data Source .
Customizing the marker bubbles ¶
To customize the store marker bubbles you can use the data source control option
markerBubbleFunction
for
specifying your own style rules for marker hover or click event.
1let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("Paris.geojson", "" /*icon default*/, "" /*no icon filter*/,
2 {
3 markerBubble: {
4 markerBubbleClass: 'store-bubble',
5 markerBubbleFunction: function (elMarker, properties, coords) {
6 elMarker.innerHTML = '<div class="store-bubble--img-container">' +
7 '<img class="store-bubble--img" src=' + properties.preview + '></div>' +
8 '<div class="store-bubble--content">' +
9 '<div class="store-bubble--title">' + properties['name'] + '</div></div>';
10 }
11 },
12 marker: {
13 highlightClass: 'highlight-marker-icon'
14 }
15 });
16defaultAppScreen.addControl(geojsonDataControl);
1<style>
2 .store-bubble {
3 display: block;
4 -webkit-box-sizing: border-box;
5 -moz-box-sizing: border-box;
6 box-sizing: border-box;
7 position: absolute;
8 width: 240px;
9 height: 200px;
10 background: #fff;
11 border-radius: 7px;
12 text-decoration: none;
13 -webkit-font-smoothing: antialiased;
14 bottom: 120%;
15 left: 50%;
16 margin-left: -120px;
17 font-size: 14px;
18 display: flex;
19 flex-direction: column-reverse;
20 -webkit-box-shadow: 0px 5px 15px rgb(0 0 0 / 15%);
21 box-shadow: 0px 5px 15px rgb(0 0 0 / 15%);
22 }
23
24 .store-bubble--title {
25 position: absolute;
26 text-overflow: ellipsis;
27 text-align: center;
28 white-space: nowrap;
29 overflow: hidden;
30 bottom: 12px;
31 width: 100%;
32 font-weight: 600;
33 color: #04aa6d;
34 }
35
36 .store-bubble--description {
37 padding: 17px 10px 7px 10px;
38 background: #fff;
39 color: grey;
40 text-overflow: ellipsis;
41 text-align: center;
42 white-space: nowrap;
43 overflow: hidden;
44 }
45
46 .store-bubble--img-container {
47 position: absolute;
48 width: 100%;
49 height: 80%;
50 top: 0;
51 bottom: 0px;
52 left: 0;
53 border-radius: 3px 3px 0 0;
54 overflow: hidden;
55 display: flex;
56 flex-wrap: wrap;
57 flex-direction: column;
58 }
59
60 .store-bubble--img {
61 background-position-x: 40px !important;
62 background-position-y: 5px !important;
63 position: absolute;
64 top: 0px;
65 right: 0;
66 left: 0px;
67 background-position-x: 12px;
68 background-position-y: 15px;
69 background-size: cover;
70 width: 100%;
71 height: 100%;
72 object-fit: cover;
73 }
74
75 .store-bubble--content {
76 background: #fff;
77 height: 20%;
78 width: 100%;
79 border-radius: 10px;
80 overflow: hidden;
81 }
82
83 .highlight-marker-icon {
84 filter: hue-rotate(70deg) contrast(6.5);
85 transform: scale(1.2);
86 }
87</style>
Complete example code ¶
1// Start by setting your token from https://www.magiclane.com/api/projects
2if (gem.core.App.token === undefined) gem.core.App.token = "";
3
4defaultAppScreen = gem.core.App.initAppScreen({
5 container: "map-canvas"
6});
7
8let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("Paris.geojson", "" /*icon default*/, "" /*no icon filter*/,
9 {
10 markerBubble: {
11 markerBubbleClass: 'store-bubble',
12 markerBubbleFunction: function (elMarker, properties, coords) {
13 elMarker.innerHTML = '<div class="store-bubble--img-container">' +
14 '<img class="store-bubble--img" src=' + properties.preview + '></div>' +
15 '<div class="store-bubble--content">' +
16 '<div class="store-bubble--title">' + properties['name'] + '</div></div>';
17 }
18 },
19 marker: {
20 highlightClass: 'highlight-marker-icon'
21 }
22 });
23let listUIControl = new gem.control.ListControl({
24 sourceControl: geojsonDataControl,
25 container: 'menu-list-container',
26 menuName: 'Store locations example',
27 titleProperties: ['name'],
28 detailsProperties: ['kinds'],
29 imageProperty: ['preview']
30});
31defaultAppScreen.addControl(geojsonDataControl);
32defaultAppScreen.addControl(listUIControl);
33
34let searchControl = new gem.control.SearchControl({
35 searchPreferences: {
36 exactMatch: true,
37 maximumMatches: 3,
38 setCursorReferencePoint: true
39 },
40 highlightOptions: {
41 contourColor: { r: 0, g: 255, b: 0, a: 255 }
42 }
43});
44defaultAppScreen.addControl(searchControl);
1<html>
2 <meta charset="utf-8" />
3 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css" />
4 <title>Store Locator Custom Bubble</title>
5
6 <head>
7 <style>
8 .store-bubble {
9 display: block;
10 -webkit-box-sizing: border-box;
11 -moz-box-sizing: border-box;
12 box-sizing: border-box;
13 position: absolute;
14 width: 240px;
15 height: 200px;
16 background: #fff;
17 border-radius: 7px;
18 text-decoration: none;
19 -webkit-font-smoothing: antialiased;
20 bottom: 120%;
21 left: 50%;
22 margin-left: -120px;
23 font-size: 14px;
24 display: flex;
25 flex-direction: column-reverse;
26 -webkit-box-shadow: 0px 5px 15px rgb(0 0 0 / 15%);
27 box-shadow: 0px 5px 15px rgb(0 0 0 / 15%);
28 }
29
30 .store-bubble--title {
31 position: absolute;
32 text-overflow: ellipsis;
33 text-align: center;
34 white-space: nowrap;
35 overflow: hidden;
36 bottom: 12px;
37 width: 100%;
38 font-weight: 600;
39 color: #04aa6d;
40 }
41
42 .store-bubble--description {
43 padding: 17px 10px 7px 10px;
44 background: #fff;
45 color: grey;
46 text-overflow: ellipsis;
47 text-align: center;
48 white-space: nowrap;
49 overflow: hidden;
50 }
51
52 .store-bubble--img-container {
53 position: absolute;
54 width: 100%;
55 height: 80%;
56 top: 0;
57 bottom: 0px;
58 left: 0;
59 border-radius: 3px 3px 0 0;
60 overflow: hidden;
61 display: flex;
62 flex-wrap: wrap;
63 flex-direction: column;
64 }
65
66 .store-bubble--img {
67 background-position-x: 40px !important;
68 background-position-y: 5px !important;
69 position: absolute;
70 top: 0px;
71 right: 0;
72 left: 0px;
73 background-position-x: 12px;
74 background-position-y: 15px;
75 background-size: cover;
76 width: 100%;
77 height: 100%;
78 object-fit: cover;
79 }
80
81 .store-bubble--content {
82 background: #fff;
83 height: 20%;
84 width: 100%;
85 border-radius: 10px;
86 overflow: hidden;
87 }
88
89 .highlight-marker-icon {
90 filter: hue-rotate(70deg) contrast(6.5);
91 transform: scale(1.2);
92 }
93 </style>
94 </head>
95
96 <body>
97 <div id="store-locator" style="width: 100%; height: 100%">
98 <div id="menu-list-container" style="width: 30%; height: 100%; position: absolute"></div>
99 <div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%"></div>
100 </div>
101 <script type="text/javascript" src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
102 <script type="text/javascript" src="token.js"></script>
103 <script type="text/javascript" src="jsStoreLocatorCustomBubble.js"></script>
104 </body>
105</html>
Files ¶
The finished example consists of the project directory containing these files:
-
JavaScript code (
.js
file extension) -
HTML code (
.html
file extension) -
Store locations in GeoJSON format (
.geojson
file extension)
To run the example, the HTML file is loaded in a browser.
Source code for this example:
JavaScriptHTML
Store locations in GeoJSON format
right-click on the links and select Save As.