Store Locator using Studio Query Data Source ¶
This guide shows you how to build a store locator from scratch using store locations previously uploaded to the online Map Studio in GeoJSON format using queries around a searched location and a distance radius.The finished example will look like this:
See the example fullscreen
When to use ¶
-
The entire store location data set is relatively big.
-
The data set is 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)
-
Store locations in GeoJSON format previously uploaded to the online Map Studio and saved to datasets
Setup ¶
Get your Magic Lane API key token: if you do not have a token, see the Getting Started guide.
Adding stores data ¶
1// Start by setting your token from https://www.magiclane.com/api/projects
2if (gem.core.App.token === undefined) gem.core.App.token = '';
3
4const studioQueryControl = new gem.control.StudioQueryDataControl('1973209755' /* studio data source id */, '', {
5 markerBubble: {
6 title: ['name'],
7 image: ['preview']
8 },
9 markerGrouping: {
10 maxLevel: 14
11 }
12});
13
14const searchControl = new gem.control.DataQuerySearchControl({
15 highlightOptions: {
16 contourColor: { r: 0, g: 255, b: 0, a: 0 }
17 },
18 searchPreferences: {
19 maximumMatches: 4,
20 addressSearch: false,
21 mapPoisSearch: false,
22 setCursorReferencePoint: true
23 },
24 searchResults: {
25 initialPlaceSearch: 'Paris'
26 }
27}, studioQueryControl);
28
29const defaultAppScreen = gem.core.App.initAppScreen({
30 container: 'map-canvas',
31 center: [48.8562, 2.3516, 10000]
32});
33defaultAppScreen.addControl(studioQueryControl);
34defaultAppScreen.addControl(searchControl);
gem.core.App.initAppScreen
is used to initialize the map. The map is rendered
in the
div
container with the id
map-canvas
in the HTML page.
gem.control.StudioQueryDataControl()
is used to
add GeoJSON data previously saved in the online Map Studio.
defaultAppScreen.addControl(studioQueryControl);
gem.control.DataQuerySearchControl
is used to add search control integrated with the studio
query control. The free text search result is used as a reference location for searching for stores data
around the picked location using a 10 km radius (default setting).
1<!doctype html>
2<html lang="en-us">
3 <meta charset="utf-8" />
4 <head>
5 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
6 <title>Studio Query Controls - MagicLane Maps SDK for JavaScript</title>
7 </head>
8
9 <body>
10 <div id="storeLocator" style="width: 100%; height: 100%;">
11 <div id="map-canvas" style="width: 100%; height: 100%; position: absolute;">
12 </div>
13 </div>
14
15 <script type="text/javascript" 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="storeStudioDataQuery01.js"></script>
18 </body>
19</html>
map-canvas
is the drawing area where the map is rendered.
The canvas is configured to fill the browser window.
Adding stores list ¶
To display a list of the store locations add a menu list container to your HTML file and the following JavaScript code:
1const listUIControl = new gem.control.ListControl({
2 sourceControl: studioQueryControl,
3 flyToItemAltitude: 300,
4 container: 'stores-list',
5 menuName: 'Studio Query Data Example',
6 titleProperties: ['name'],
7 detailsProperties: ['kinds'],
8 imageProperty: ['preview']
9});
10defaultAppScreen.addControl(listUIControl);
1<div id="storeLocator" style="width: 100%; height: 100%;">
2 <div id="stores-list" style="width: 30%; height: 100%; position: absolute;"></div>
3 <div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%;">
4 </div>
5</div>
Adding a distance filter ¶
To add distance filter functionality simply add the following JavaScript and HTML code:
1const distanceFilterControl = new gem.control.DistanceFilterControl({
2 parentContainer: 'filter-distance',
3 name: 'byDistance',
4 title: 'Search radius (km)',
5 thresholds: [10, 25, 50, 100],
6 eUnit: 'km'
7}, studioQueryControl);
8defaultAppScreen.addControl(distanceFilterControl);
1<style>
2 .filters-container {
3 position: absolute;
4 width: 21%;
5 max-width: 300px;
6 right: 0px;
7 top: 50px;
8 margin: 8px;
9 z-index: 9;
10 background-color: white;
11 box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%);
12 }
13 </style>
14 </head>
15
16 <body>
17 <div id="storeLocator" style="width: 100%; height: 100%">
18 <div id="stores-list" style="width: 30%; height: 100%; position: absolute"></div>
19 <div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%"></div>
20 <div id="filters-container" class="filters-container">
21 <div id="filter-distance" class="filter-distance"></div>
22 </div>
23 </div>
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
4const studioQueryControl = new gem.control.StudioQueryDataControl('1973209755' /* studio data source id */, '', {
5 markerBubble: {
6 title: ['name'],
7 image: ['preview']
8 },
9 markerGrouping: {
10 maxLevel: 14
11 }
12});
13const listUIControl = new gem.control.ListControl({
14 sourceControl: studioQueryControl,
15 flyToItemAltitude: 300,
16 container: 'stores-list',
17 menuName: 'Studio Query Data Example',
18 titleProperties: ['name'],
19 detailsProperties: ['kinds'],
20 imageProperty: ['preview']
21});
22
23const searchControl = new gem.control.DataQuerySearchControl({
24 highlightOptions: {
25 contourColor: { r: 0, g: 255, b: 0, a: 0 }
26 },
27 searchPreferences: {
28 maximumMatches: 4,
29 addressSearch: false,
30 mapPoisSearch: false,
31 setCursorReferencePoint: true
32 },
33 searchResults: {
34 initialPlaceSearch: 'Paris'
35 }
36}, studioQueryControl);
37
38const distanceFilterControl = new gem.control.DistanceFilterControl({
39 parentContainer: 'filter-distance',
40 name: 'byDistance',
41 title: 'Search radius (km)',
42 thresholds: [10, 25, 50, 100],
43 eUnit: 'km'
44}, studioQueryControl);
45
46const defaultAppScreen = gem.core.App.initAppScreen({
47 container: 'map-canvas',
48 center: [48.8562, 2.3516, 10000]
49});
50defaultAppScreen.addControl(studioQueryControl);
51defaultAppScreen.addControl(listUIControl);
52defaultAppScreen.addControl(searchControl);
53defaultAppScreen.addControl(distanceFilterControl);
1<!doctype html>
2<html lang="en-us">
3 <meta charset="utf-8" />
4 <head>
5 <link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css" />
6 <title>Studio Query Controls - MagicLane Maps SDK for JavaScript</title>
7
8 <style>
9 .filters-container {
10 position: absolute;
11 width: 21%;
12 max-width: 300px;
13 right: 0px;
14 top: 50px;
15 margin: 8px;
16 z-index: 9;
17 background-color: white;
18 box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%);
19 }
20 </style>
21 </head>
22
23 <body>
24 <div id="storeLocator" style="width: 100%; height: 100%">
25 <div id="stores-list" style="width: 30%; height: 100%; position: absolute"></div>
26 <div id="map-canvas" style="width: 70%; height: 100%; position: absolute; left: 30%"></div>
27 <div id="filters-container" class="filters-container">
28 <div id="filter-distance" class="filter-distance"></div>
29 </div>
30 </div>
31
32 <script type="text/javascript" src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
33 <script type="text/javascript" src="token.js"></script>
34 <script type="text/javascript" src="storeStudioDataQuery03.js"></script>
35 </body>
36</html>
Files ¶
The finished example consists of the project directory containing 2 files:
-
JavaScript code (
.js
file extension) -
HTML code (
.html
file extension)
To run the example, the HTML file is loaded in a browser.
Source code for this example:
JavaScriptHTML
right-click on the links and select Save As.