Store Locator with Custom Markers Using Data Labels
This guide shows how the appearance of the markers style can be customized using properties available in the data source. The finished example will look like this:
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.
To see how to style the marker groups check out the guide Store Locator with different Marker Groups Styles.
To learn how to customize the free text search control check out the guide Free Text Search.
Adding Custom Markers with Data Labels
- JavaScript
- HTML
let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("Madrid_shops.geojson", "" /*icon*/, ""/*iconFilter*/, {
marker: {
width: 45,
height: 45,
hoverWidth: 45,
hoverHeight: 45,
cssClass: 'store-marker',
highlightClass: 'highlight-store-marker',
markerFunction: function (itemInfoString) {
let labelDiv = document.createElement('div');
labelDiv.className = 'store-marker-text';
let textlabel = labelDiv.appendChild(document.createElement('span'));
let jsonInfo = JSON.parse(itemInfoString);
if (jsonInfo.properties.rate)
textlabel.innerHTML = 'rate ' + jsonInfo.properties.rate;
else
textlabel.innerHTML = 'rate n.a.';
return labelDiv;
}
},
markerGrouping: {
maxLevel: 15,
style: gem.control.MarkersGroupStyleType.circle
},
markerBubble: {
title: ['name'],
image: ['preview']
}
});
To customize the markers with data labels you can use the data source control options:
- marker.cssClass - specify custom style rules class for markers
- marker.markerFunction - specify how to style the marker inner elements and optionally use the item data to add labels or filters to the marker
<style>
.store-marker {
background-image: url(./custom.svg);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 45px;
height: 45px;
position: absolute;
margin: 0px auto;
cursor: pointer;
text-align: center;
}
.store-marker.active {
filter: hue-rotate(200deg) contrast(1.5);
}
.store-marker-text {
display: inline-block;
position: relative;
border-radius: 50%;
max-width: 30px;
min-width: 18px;
min-height: 10px;
text-align: center;
font-weight: 600;
top: 5px;
line-height: 9px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
color: white;
}
.store-marker-text span {
font-size: 0.6rem;
margin: 0px;
}
.highlight-store-marker {
filter: hue-rotate(80deg) contrast(1.5);
}
</style>
Complete example code
- 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: 10,
center: [40.431404, -3.680445], // Madrid
style: "./Printemps.style"
});
let geojsonDataControl = new gem.control.GeoJsonAddedDataControl("Madrid_shops.geojson", "" /*icon*/, ""/*iconFilter*/, {
marker: {
width: 45,
height: 45,
hoverWidth: 45,
hoverHeight: 45,
cssClass: 'store-marker',
highlightClass: 'highlight-store-marker',
markerFunction: function (itemInfoString) {
let labelDiv = document.createElement('div');
labelDiv.className = 'store-marker-text';
let textlabel = labelDiv.appendChild(document.createElement('span'));
let jsonInfo = JSON.parse(itemInfoString);
if (jsonInfo.properties.rate)
textlabel.innerHTML = 'rate ' + jsonInfo.properties.rate;
else
textlabel.innerHTML = 'rate n.a.';
return labelDiv;
}
},
markerGrouping: {
maxLevel: 15,
style: gem.control.MarkersGroupStyleType.circle
},
markerBubble: {
title: ['name'],
image: ['preview']
}
});
let listUIControl = new gem.control.ListControl({
sourceControl: geojsonDataControl,
container: "menu-list-container",
displayCount: true,
flyToItemAltitude: 250,
menuName: 'Marker Data Labels, GeoJSON data source',
titleProperties: ['name'],
detailsProperties: ['kinds'],
imageProperty: ['preview']
});
defaultAppScreen.addControl(geojsonDataControl);
defaultAppScreen.addControl(listUIControl);
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);
<!DOCTYPE html>
<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>Markers Data Labels</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>
.store-marker {
background-image: url(./custom.svg);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 45px;
height: 45px;
position: absolute;
margin: 0px auto;
cursor: pointer;
text-align: center;
}
.store-marker.active {
filter: hue-rotate(200deg) contrast(1.5);
}
.store-marker-text {
display: inline-block;
position: relative;
border-radius: 50%;
max-width: 30px;
min-width: 18px;
min-height: 10px;
text-align: center;
font-weight: 600;
top: 5px;
line-height: 9px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
color: white;
}
.store-marker-text span {
font-size: 0.6rem;
margin: 0px;
}
.highlight-store-marker {
filter: hue-rotate(80deg) contrast(1.5);
}
</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="storeGeoJSONDataMarkers.js"></script>
</body>
</html>
Files
Source code for this example:
GeoJSON data downloaded from OpenTripMap :
Icon 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.