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
- 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:
How it works
- JavaScript
- HTML
// Start by setting your token from https://developer.magiclane.com/api/projects
if (gem.core.App.token === undefined)
gem.core.App.token = "";
var defaultAppScreen = gem.core.App.initAppScreen({
container: "map-canvas",
zoom: 11,
center: [48.85671, 2.35138], // Paris latitude and longitude
style: "./Printemps.style"
});
let searchControl = new gem.control.SearchControl({
highlightOptions: {
contourColor: { r: 0, g: 255, b: 0, a: 0 }
},
searchPreferences: {
maximumMatches: 3,
addressSearch: true,
mapPoisSearch: true,
setCursorReferencePoint: true
}
});
defaultAppScreen.addControl(searchControl);
let queryAddedDataControl = new gem.control.QueryAddedDataControl(
{
languages: ["en"],
storeId: 1,
},
"icon.svg",
{
marker: {
highlightClass: 'highlight-store-marker'
},
markerBubble: {
title: ['name'],
image: ['preview'],
},
markerGrouping: {
maxLevel: 15,
style: gem.control.MarkersGroupStyleType.circle
}
}
);
let listUIControl = new gem.control.ListControl({
sourceControl: queryAddedDataControl,
container: "menu-list-container",
displayCount: true,
flyToItemAltitude: 250, // meters
menuName: 'Circle Marker Groups Example',
titleProperties: ['name'],
imageProperty: ['preview']
});
defaultAppScreen.addControl(queryAddedDataControl);
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.
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1, user-scalable=no, shrink-to-fit=no" />
<title>Marker Groups Circle Style - MagicLane Maps SDK for JavaScript</title>
<link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css">
<link rel="stylesheet" href="/fonts/webfonts.css" type="text/css" media="all" />
<style>
.highlight-store-marker {
filter: hue-rotate(40deg) contrast(1.5);
transform: scale(1.4);
}
</style>
</head>
<body>
<div id="store-locator" style="width: 100%; height: 100%">
<div id="menu-list-container" class="menu-list-container" style="width: 30%; height: 100%; position: absolute"></div>
<div id="map-canvas" style="width: 70%; left: 30%; height: 100%; position: absolute; overflow: hidden"></div>
</div>
<script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
<script type="text/javascript" src="token.js"></script>
<script type="text/javascript" src="jsStoreCircleMarkerGroups.js"></script>
</body>
</html>
Files
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:
How it works
- JavaScript
- HTML
// Start by setting your token from https://developer.magiclane.com/api/projects
if (gem.core.App.token === undefined)
gem.core.App.token = "";
var defaultAppScreen = gem.core.App.initAppScreen({
container: "map-canvas",
zoom: 11,
center: [48.85671, 2.35138], // Paris latitude and longitude
style: "./Printemps.style"
});
let searchControl = new gem.control.SearchControl({
highlightOptions: {
contourColor: { r: 0, g: 255, b: 0, a: 0 },
},
searchPreferences: {
maximumMatches: 3,
addressSearch: true,
mapPoisSearch: true,
setCursorReferencePoint: true
}
});
defaultAppScreen.addControl(searchControl);
let queryAddedDataControl = new gem.control.QueryAddedDataControl(
{
languages: ["en"],
storeId: 1
},
"icon.svg",
{
marker: {
highlightClass: 'highlight-store-marker'
},
markerBubble: {
title: ['name'],
image: ['preview']
},
markerGrouping: {
maxLevel: 15,
style: gem.control.MarkersGroupStyleType.custom,
markerGroupFunction: function (groupsize) {
let customGroupDiv = document.createElement('div');
customGroupDiv.className = 'store-marker-group';
if (groupsize > 100) {
customGroupDiv.classList.add('large');
}
else if (groupsize > 25) {
customGroupDiv.classList.add('medium');
}
else {
customGroupDiv.classList.add('small');
}
let textDiv = customGroupDiv.appendChild(document.createElement('div'));
textDiv.className = 'store-marker-group-text';
let textGroupSize = textDiv.appendChild(document.createElement('span'));
textGroupSize.innerHTML = groupsize;
return customGroupDiv;
}
}
}
);
let listUIControl = new gem.control.ListControl({
sourceControl: queryAddedDataControl,
container: "menu-list-container",
displayCount: true,
flyToItemAltitude: 250, // meters
menuName: 'Custom Marker Groups Example',
titleProperties: ['name'],
imageProperty: ['preview']
});
defaultAppScreen.addControl(queryAddedDataControl);
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.
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1, user-scalable=no, shrink-to-fit=no" />
<title>Custom Marker Groups - MagicLane Maps SDK for JavaScript</title>
<link rel="stylesheet" type="text/css" href="https://www.magiclane.com/sdk/js/gem.css" />
<link rel="stylesheet" href="/fonts/webfonts.css" type="text/css" media="all" />
<style>
.highlight-store-marker {
filter: hue-rotate(40deg) contrast(1.5);
transform: scale(1.4);
}
.store-marker-group {
height: 20px;
width: 20px;
position: absolute;
}
.store-marker-group.large {
background-image: url(./shops_large.svg);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 30px;
height: 30px;
}
.store-marker-group.medium {
background-image: url(./shops_medium.svg);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 25px;
height: 25px;
}
.store-marker-group.small {
background-image: url(./shops_small.svg);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 20px;
height: 20px;
}
.store-marker-group-text {
display: inline-block;
position: relative;
border-radius: 50%;
max-width: 30px;
min-width: 18px;
min-height: 10px;
text-align: center;
font-weight: 600;
box-shadow: 0 2px 4px rgb(0 0 0 / 20%), 0 -1px 0 rgb(0 0 0 / 2%);
}
.store-marker-group-text span {
font-size: 0.7rem;
margin: 2px;
}
.store-marker-group.small .store-marker-group-text {
left: 12px;
top: -9px;
background-color: #6cdd76;
}
.store-marker-group.medium .store-marker-group-text {
left: 17px;
top: -6px;
background-color: #ffff5c;
}
.store-marker-group.large .store-marker-group-text {
left: 20px;
top: -3px;
background-color: #ffa849;
}
</style>
</head>
<body>
<div id="store-locator" style="width: 100%; height: 100%">
<div id="menu-list-container" class="menu-list-container" style="width: 30%; height: 100%; position: absolute"></div>
<div id="map-canvas" style="width: 70%; left: 30%; height: 100%; position: absolute; overflow: hidden"></div>
</div>
<script src="https://www.magiclane.com/sdk/js/gemapi.js"></script>
<script type="text/javascript" src="token.js"></script>
<script type="text/javascript" src="jsStoreCustomMarkerGroups.js"></script>
</body>
</html>
Files
Icons customized from Iconpacks:
Right-click on the links and select Save As.
JavaScript Examples
Maps SDK for JavaScript Examples can be downloaded or cloned with Git