<html>
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" type="text/css" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>
<!-- Add references to the Azure Maps Map Drawing Tools JavaScript and CSS files. -->
<link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/drawing/0/atlas-drawing.min.css" type="text/css" />
<script src="https://atlas.microsoft.com/sdk/javascript/drawing/0/atlas-drawing.min.js"></script>
<body>
<div id="map"></div>
<img id="loadingIcon" src="https://assets.codepen.io/1717245/loadingIcon.gif" title="Loading" style="position:absolute;left:calc(50% - 25px);top:calc(50% - 25px);display:none;" />
<div id="legend">
<div style="font-size:14px;font-weight:bold;">Elevation</div>
<div style="float:left">
<div class="colorSquare" style="background-color:#d7191c"></div>
<div class="colorSquare" style="background-color:#fdae61"></div>
<div class="colorSquare" style="background-color:#ffffbf"></div>
<div class="colorSquare" style="background-color:#a6d96a"></div>
<div class="colorSquare" style="background-color:#1a9641"></div>
</div>
<div style="float:left;margin:9px 5px 0 5px;">
<div class="colorSquare">200m</div>
<div class="colorSquare">150m</div>
<div class="colorSquare">100m</div>
<div class="colorSquare">50m</div>
</div>
</div>
<div style="position:absolute;top:0px;left:calc(50% - 100px);background-color:white;padding:5px;">Draw rectangle on the map</div>
</body>
</html>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
#legend {
position: absolute;
top: 10px;
right: 10px;
background-color: white;
border-radius: 10px;
padding: 10px;
font-size: 11px;
}
.colorSquare {
width: 16px;
height: 16px;
text-align: center;
}
var map, datasource, layer, drawingManager;
var elevationBoundsUrl = 'https://{azMapsDomain}/elevation/lattice/json?api-version=1.0&bounds={bounds}&rows={rows}&columns={columns}';
var maxSamples = 2000;
var colors = ['#006837', '#1a9850', '#66bd63', '#a6d96a', '#d9ef8b', '#ffffbf', '#fee08b', '#fdae61', '#f46d43', '#d73027', '#a50026'];
//Initialize a map instance.
map = new atlas.Map('map', {
center: [-119.949, 46.53],
zoom: 12,
style: 'satellite',
view: "Auto",
//Add your Azure Maps subscription client ID to the map SDK.
authOptions: {
authType: "anonymous",
clientId: "04ec075f-3827-4aed-9975-d56301a2d663", //Your Azure Maps account Client ID is required to access your Azure Maps account.
getToken: function (resolve, reject, map) {
//URL to your authentication service that retrieves an Azure Active Directory Token.
var tokenServiceUrl = "https://azuremapscodesamples.azurewebsites.net/Common/TokenService.ashx";
fetch(tokenServiceUrl).then(r => r.text()).then(token => resolve(token));
}
}
});
//Wait until the map resources are ready.
map.events.add('ready', function () {
//Create a data source for the route line.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Create a layer for rendering the elevation points.
layer = new atlas.layer.BubbleLayer(datasource, null, {
color: [
'interpolate',
['linear'],
['get', 'elevation'],
400, '#006837',
450, '#1a9850',
500, '#66bd63',
550, '#a6d96a',
600, '#d9ef8b',
650, '#ffffbf',
700, '#fee08b',
750, '#fdae61',
800, '#f46d43',
850, '#d73027',
900, '#a50026'
],
//Don't outline the bubbles. This will make them blend together to create a heat map like visual.
strokeWidth: 0
});
map.layers.add(layer);
//Create an instance of the drawing manager and display the line drawing option of the drawing toolbar.
drawingManager = new atlas.drawing.DrawingManager(map, {
toolbar: new atlas.control.DrawingToolbar({
buttons: ['draw-rectangle'],
position: 'top-left',
style: 'light'
})
});
///Clear the map and drawing canvas when the user enters into a drawing mode.
map.events.add('drawingmodechanged', drawingManager, drawingModeChanged);
//Monitor for when a rectangle drawing has been completed.
map.events.add('drawingcomplete', drawingManager, getElevations);
});
function drawingModeChanged(mode) {
//Clear the drawing canvas and data source.
if (mode.startsWith('draw')) {
drawingManager.getSource().clear();
datasource.clear();
}
}
function getElevations(rectangle) {
//Exit drawing mode and clear the drawing canvas.
drawingManager.setOptions({ mode: 'idle' });
drawingManager.getSource().clear();
//Get the bounding box of the rectangle.
var bbox = rectangle.getBounds();
//Get the width and height of the bounding box in meters.
var nw = atlas.data.BoundingBox.getNorthWest(bbox);
var width = atlas.math.getDistanceTo(nw, atlas.data.BoundingBox.getNorthEast(bbox));
var height = atlas.math.getDistanceTo(nw, atlas.data.BoundingBox.getSouthWest(bbox));
//In this sample we want to create an evenly distributed grid, so aspect ratio will be used to determine the number of requires rows/columns.
var aspectRatio = width / height;
//The square root of the max number of samples, gives use the number of row/columns for a perfect square. Apply the square root of the aspect ratio to this to handle rectangles.
var numRows = Math.floor(Math.sqrt(maxSamples / aspectRatio));
var numColumns = Math.floor(Math.sqrt(maxSamples * aspectRatio));
//Format line coordinates as "SouthwestCorner_Longitude,SouthwestCorner_Latitude,NortheastCorner_Longitude,NortheastCorner_Latitude"
var bounds = bbox.join(',');
var url = elevationBoundsUrl.replace('{bounds}', bounds).replace('{rows}', numRows).replace('{columns}', numColumns);
//Show loading icon.
document.getElementById('loadingIcon').style.display = '';
processRequest(url).then(response => {
if (response.error) {
alert(response.error.message);
return;
}
var points = [];
var minElv = Infinity;
var maxElv = -Infinity;
//Loop through the elevations, create point features with an elevation property and calculate min/max elevation.
response.data.forEach(c => {
points.push(new atlas.data.Feature(new atlas.data.Point([c.coordinate.longitude, c.coordinate.latitude]), {
elevation: c.elevationInMeter
}));
if (c.elevationInMeter < minElv) {
minElv = c.elevationInMeter;
}
if (c.elevationInMeter > maxElv) {
maxElv = c.elevationInMeter;
}
});
//Calculate a new style expression based on the
updateStyle(minElv, maxElv);
//Overwrite the points to the data source.
datasource.setShapes(points);
//Hide loading icon.
document.getElementById('loadingIcon').style.display = 'none';
});
}
function updateStyle(minElv, maxElv) {
//Get the difference between min/max elevation.
var de = maxElv - minElv;
//If the difference is 0, set de to 1 to prevent devide by zero issues.
if (de === 0) {
de = 1;
}
var elvStep = de / colors.length;
var exp = [
'interpolate', //This will cause the colors from each data point to create a gradient between points.
['linear'],
['get', 'elevation'],
];
for (var i = 0; i < colors.length; i++) {
//Set the elevation interval and its color.
exp.push(minElv + elvStep * i, colors[i]);
}
layer.setOptions({ color: exp });
//Create legend, with highest value first.
//Determine a reasonable value to round by.
var roundFactor = (de < 10) ? 10 : 1;
var colorSquares = [];
var elvSteps = [];
for (var i = colors.length; i >= 0; i--) {
colorSquares.push(`<div class="colorSquare" style="background-color:${colors[i]}"></div>`);
elvSteps.push(`<div class="colorSquare">${Math.round((minElv + elvStep * i) * roundFactor) / roundFactor}m</div>`);
}
var legend = [
'<div style="font-size:14px;font-weight:bold;">Elevation</div><div style="float:left">',
...colorSquares,
'</div><div style="float:left;margin:9px 5px 0 5px;">',
...elvSteps,
'</div></div>'
];
document.getElementById('legend').innerHTML = legend.join('');
}
function processRequest(url) {
return new Promise((resolve, reject) => {
//Replace the domain placeholder to ensure the same Azure Maps cloud is used throughout the app.
url = url.replace('{azMapsDomain}', atlas.getDomain());
//Get the authentication details from the map for use in the request.
var requestParams = map.authentication.signRequest({ url: url });
//Transform the request.
var transform = map.getServiceOptions().tranformRequest;
if (transform) {
requestParams = transform(request);
}
fetch(requestParams.url, {
method: 'GET',
mode: 'cors',
headers: new Headers(requestParams.headers)
})
.then(r => r.json(), e => reject(e))
.then(r => {
resolve(r);
}, e => reject(e));
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.