This sample demonstrates how to access and chain multiple location services together. It uses the basemap layer, geocoding, routing, and demographics location service.
Access the basemap layer, geocoding, routing, and demographics location service.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Esri Leaflet</title>
<!-- Load Leaflet from CDN -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script>
<!-- Load Esri Leaflet from CDN -->
<script src="https://unpkg.com/esri-leaflet@3.0.14/dist/esri-leaflet.js"></script>
<script src="https://unpkg.com/esri-leaflet-vector@4.2.7/dist/esri-leaflet-vector.js"></script>
<script src="https://unpkg.com/esri-leaflet-geocoder@3.1.4/dist/esri-leaflet-geocoder.js"></script>
<!-- Load Turf from CDN -->
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
<!-- Load ArcGIS REST JS libraries from https://unpkg.com -->
<script src="https://unpkg.com/@esri/arcgis-rest-request@4/dist/bundled/request.umd.js"></script>
<script src="https://unpkg.com/@esri/arcgis-rest-demographics@4/dist/bundled/demographics.umd.js"></script>
<script src="https://unpkg.com/@esri/arcgis-rest-routing@4/dist/bundled/routing.umd.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: #323232;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
const accessToken = "YOUR_ACCESS_TOKEN";
const authentication = arcgisRest.ApiKeyManager.fromKey(accessToken);
const basemapEnum = "arcgis/navigation";
const startcoords = [37.7749, -122.4194];
const zoomLevel = 14;
let getData = false;
const map = L.map("map", {
minZoom: 2
}).setView(startcoords, 6);
const tileLayer = L.esri.Vector.vectorBasemapLayer(basemapEnum, {
token: accessToken
});
tileLayer.addTo(map);
setTimeout(() => {
getData = true;
map.flyTo(startcoords, zoomLevel, {
animate: true,
duration: 3.0
});
}, 1500);
const layerGroup = L.layerGroup().addTo(map);
const layerGroupCoffeeShops = L.layerGroup().addTo(map);
// Add select to go to places
L.Control.PlacesControl = L.Control.extend({
onAdd: function (map) {
// Array of places
const places = [
["Choose a city or click the map", "0.0"],
["San Francisco", "37.7749,-122.4194"],
["New York", "40.7128,-74.0060"],
["London", "51.5074, -0.1278"],
["Sydney", "-33.8688, 151.2093"],
["Toronto", "43.6532, -79.3832"],
["Bangkok", "13.7367,100.5231"]
];
// Create select
const select = L.DomUtil.create("select", "");
select.setAttribute("id", "selectLocation");
select.setAttribute("style", "font-size: 16px; padding: 2px 4px;");
places.forEach(function (place) {
let option = L.DomUtil.create("option");
option.innerHTML = place[0];
option.value = place[1];
select.appendChild(option);
});
L.DomEvent.disableClickPropagation(select);
return select;
},
onRemove: function (map) {
// Nothing to do here
}
});
L.control.placesControl = function (opts) {
return new L.Control.PlacesControl(opts);
};
L.control
.placesControl({
position: "topright"
})
.addTo(map);
document.getElementById("selectLocation").addEventListener("change", goToLocation);
function goToLocation(e) {
getData = true;
const latlngArray = JSON.parse("[" + e.target.value + "]");
var latlng = L.latLng(latlngArray);
map.flyTo(latlng, zoomLevel, {
animate: true,
duration: 2.0
});
}
map.on("moveend", function (e) {
if (getData) {
getDemographicData(e.target.getCenter());
}
getData = false;
});
map.on("click", (e) => {
getDemographicData(e.latlng);
});
function getDemographicData(latlng) {
// Request demographic data for drive time areas
arcgisRest
.queryDemographicData({
studyAreas: [
{
geometry: { x: latlng.lng, y: latlng.lat },
areaType: "NetworkServiceArea",
bufferUnits: "Minutes",
bufferRadii: [2, 5],
travel_mode: "Driving"
}
],
returnGeometry: true,
authentication: authentication
})
.then((response) => {
const data = document.getElementById("data");
if (
response.results[0].value.FeatureSet.length > 0 &&
response.results[0].value.FeatureSet[0].features.length === 2 // Two drive time areas
) {
// Show popup with demographics
const featureSet = response.results[0].value.FeatureSet[0]; //.features[0];
const attributes = featureSet.features[1].attributes;
const content = `<b>Demographics and coffee shops within 2 and 5 minute drive areas</b><br>Population: ${attributes.TOTPOP}<br>Males: ${attributes.TOTMALES} <br>Females: ${attributes.TOTFEMALES}<br>Average Household Size: ${attributes.AVGHHSZ}`;
var popup = L.popup().setLatLng(latlng).setContent(content).openOn(map);
// Display drive time areas
let innerDriveTimeArea = L.esri.Util.arcgisToGeoJSON(featureSet.features[0]);
let outerDriveTimeArea = L.esri.Util.arcgisToGeoJSON(featureSet.features[1]);
displayDrivetimeAreas([innerDriveTimeArea, outerDriveTimeArea]);
// Find coffee shops in drive time area
findPlaces(latlng, outerDriveTimeArea);
} else {
console.log("No data found.");
}
});
function displayDrivetimeAreas(driveTimeAreas) {
layerGroup.clearLayers();
layerGroupCoffeeShops.clearLayers();
driveTimeAreas.forEach((area) => {
L.geoJSON(area, {
style: (feature) => {
const style = {
fillOpacity: 0.5,
weight: 1
};
if (feature.properties.bufferRadii === 0) {
style.color = "hsl(210, 80%, 40%)";
} else if (feature.properties.bufferRadii === 2) {
style.color = "hsl(210, 80%, 60%)";
} else {
style.color = "hsl(210, 80%, 80%)";
}
return style;
}
}).addTo(layerGroup);
});
}
function findPlaces(latlng, serviceAreaPolygon) {
const geocoder = L.esri.Geocoding.geocodeService({
apikey: accessToken
});
geocoder
.geocode()
.category("Coffee shop")
.nearby(latlng, 50)
.run(function (error, response) {
if (error) {
return;
}
const intersectedFeatures = response.results.filter((feature) => {
return turf.booleanPointInPolygon([feature.latlng.lng, feature.latlng.lat], serviceAreaPolygon);
});
intersectedFeatures.forEach((searchResult) => {
L.marker(searchResult.latlng)
.addTo(layerGroupCoffeeShops)
.bindPopup(`<b>${searchResult.properties.PlaceName}</b></br>${searchResult.properties.Place_addr}`);
});
});
}
}
</script>
</body>
</html>