KEMBAR78
2.azure Azure Maps | PDF | Microsoft Azure | Java Script
0% found this document useful (0 votes)
43 views1,526 pages

2.azure Azure Maps

Azure Maps is a suite of geospatial services and SDKs that provide mapping, geocoding, routing, and weather data for web and mobile applications. It includes REST APIs and a Web SDK for developers to create location-based experiences, with features like real-time traffic information and geofencing. Users can sign up for a free account to access these services and utilize various tools for developing applications that integrate geographic context.

Uploaded by

cikes47667
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views1,526 pages

2.azure Azure Maps

Azure Maps is a suite of geospatial services and SDKs that provide mapping, geocoding, routing, and weather data for web and mobile applications. It includes REST APIs and a Web SDK for developers to create location-based experiences, with features like real-time traffic information and geofencing. Users can sign up for a free account to access these services and utilize various tools for developing applications that integrate geographic context.

Uploaded by

cikes47667
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1526

Tell us about your PDF experience.

Azure Maps Documentation


Azure Maps is a set of mapping and geospatial services that enable developers and
organizations to build intelligent location-based experiences for applications across
many different industries and use cases. Use the Azure Maps REST APIs and Web SDK to
bring maps, geocoding, location search, routing, real-time traffic, geolocation, time zone
information, and weather data into your web and mobile solutions.

About Azure Maps

e OVERVIEW

What is Azure Maps?

p CONCEPT

Azure Maps Coverage

Localization support

Supported map styles

q VIDEO

Introduction to Azure Maps

Get Started

f QUICKSTART

Create a web application using Azure Maps

p CONCEPT

Authentication with Azure Maps

c HOW-TO GUIDE

Manage Azure Maps accounts

Manage authentication with Azure Maps

Manage Azure Maps account pricing tier


View Azure Maps API usage metrics

Developing with Web SDK

p CONCEPT

Getting started with web map control

Azure Maps web SDK code samples

Web SDK supported browsers

g TUTORIAL

Search for point of interest

Route to a point of interest

Create a store locator

c HOW-TO GUIDE

Use the Azure Maps map control

Use the drawing tools module

Use the services module

Use the spatial IO module

Web SDK supported browsers

i REFERENCE

Map control

Drawing tools module

Service module

Spatial IO module

Developing with Location-Based Services

p CONCEPT
Zoom levels and tile grids

g TUTORIAL

EV Routing using Azure Notebooks (Python)

c HOW-TO GUIDE

Search for an address (geocoding)

Best Practices using Search Service

Best Practices using Route Service

Render custom data on static map

i REFERENCE

Search Service

Route Service

Traffic Service

Time Zones Service

Spatial analysis with Power BI

c HOW-TO GUIDE

Getting started

Understanding layers

Manage access

Developing with Weather services

p CONCEPT

Weather services concepts

Weather services FAQ

g TUTORIAL
Analyze weather data using Azure Notebooks (Python)

c HOW-TO GUIDE

Request real-time and forecasted weather data

i REFERENCE

Weather services
What is Azure Maps?
Article • 03/31/2025

Azure Maps is a collection of geospatial services and SDKs that use fresh mapping data
to provide geographic context to web and mobile applications. Azure Maps provides:

REST APIs to render vector and raster maps in multiple styles and satellite imagery.
Search services to locate addresses, places, and points of interest around the
world.
Various routing options; such as point-to-point, multipoint, multipoint
optimization, isochrone, electric vehicle, commercial vehicle, traffic influenced, and
matrix routing.
Traffic flow view and incidents view, for applications that require real-time traffic
information.
Time zone and Geolocation services.
Geofencing service with location information hosted in Azure.
Location intelligence through geospatial analytics.

Additionally, Azure Maps services are available through the Web SDK. These tools help
developers quickly develop and scale solutions that integrate location information into
Azure solutions.

You can sign up for a free Azure Maps account and start developing.

The following video explains Azure Maps in depth:

https://learn.microsoft.com/Shows/Internet-of-Things-Show/Azure-Maps/player?
format=ny

Map controls

Web SDK
The Azure Maps Web SDK lets you customize interactive maps with your own content
and imagery. You can use this interactive map for both your web or mobile applications.
The map control makes use of WebGL, so you can render large data sets with high
performance. You can develop with the SDK by using JavaScript or TypeScript.

Services in Azure Maps


Azure Maps consists of the following services that can provide geographic context to
your Azure applications.

Geolocation service
Use the Geolocation service to retrieve the two-letter country/region code for an IP
address. This service can help you enhance user experience by providing customized
application content based on geographic location.

For more information, see Geolocation in the Azure Maps REST API documentation.

Render service
Render service introduces a new version of the Get Map Tile API that supports using
Azure Maps tiles not only in the Azure Maps SDKs but other map controls as well. It
includes raster and vector tile formats, 256x256 or 512x512 tile sizes (where applicable)
and numerous map types such as road, weather, contour, or map tiles. For a complete
list, see TilesetID in the REST API documentation. You're required to display the
appropriate copyright attribution on the map anytime you use the Azure Maps Render
service, either as basemaps or layers, in any third-party map control. For more
information, see How to use the Get Map Attribution API.

7 Note

Azure Maps Render v1 service retirement

The Azure Maps Render v1 service is now deprecated and will be retired on
9/17/26. To avoid service disruptions, all calls to Render v1 API will need to be
updated to use the latest version by 9/17/26.

Route service
The route service is used to calculate the estimated arrival times (ETAs) for each
requested route. Factors such as real-time traffic information and historic traffic data,
like the typical road speeds on the requested day of the week and time of day are
considered. The route service returns the shortest or fastest routes available to multiple
destinations at a time in sequence or in optimized order, based on time or distance. The
service allows developers to calculate directions across several travel modes, such as car,
truck, bicycle, or walking, and electric vehicle. The service also considers inputs, such as
departure time, weight restrictions, or hazardous material transport.

The Route service offers advanced set features, such as:

Batch processing of multiple route requests.


Matrices of travel time and distance between a set of origins and destinations.
Finding routes or distances that users can travel based on time or fuel
requirements.

For more information, see Route in the Azure Maps REST API documentation.

Search service
The Search service helps developers search for addresses, places, business listings by
name or category, and other geographic information. Also, services can reverse
geocode addresses and cross streets based on latitudes and longitudes.

The Search service also provides advanced features such as:

Search along a route.


Search inside a wider area.
Batch a group of search requests.
Search electric vehicle charging stations and Point of Interest (POI) data by brand
name.

For more information, see Search in the Azure Maps REST API documentation.

Timezone service
The Time zone service enables you to query current, historical, and future time zone
information. You can use either latitude and longitude pairs or an IANA ID as an input.
The Time zone service also allows for:

Converting Microsoft Windows time-zone IDs to IANA time zones.


Fetching a time-zone offset to UTC.
Getting the current time in a chosen time zone.

A typical JSON response for a query to the Time zone service looks like the following
sample:

JSON

{
"Version": "2020a",
"ReferenceUtcTimestamp": "2020-07-31T19:15:14.4570053Z",
"TimeZones": [
{
"Id": "America/Los_Angeles",
"Names": {
"ISO6391LanguageCode": "en",
"Generic": "Pacific Time",
"Standard": "Pacific Standard Time",
"Daylight": "Pacific Daylight Time"
},
"ReferenceTime": {
"Tag": "PDT",
"StandardOffset": "-08:00:00",
"DaylightSavings": "01:00:00",
"WallTime": "2020-07-31T12:15:14.4570053-07:00",
"PosixTzValidYear": 2020,
"PosixTz": "PST+8PDT,M3.2.0,M11.1.0"
}
}
]
}

For more information, see Timezone in the Azure Maps REST API documentation.

Traffic service
The Traffic service is a suite of web services that developers can use for web or mobile
applications that require traffic information. The service provides two data types:

Traffic flow: Real-time observed speeds and travel times for all key roads in the
network.
Traffic incidents: An up-to-date view of traffic jams and incidents around the road
network.

For more information, see Traffic in the Azure Maps REST API documentation.

Weather service
The Weather service offers API to retrieve weather information for a particular location.
This information includes observation date and time, weather conditions, precipitation
indicator flags, temperature, and wind speed information. Other details such as
RealFeel™ Temperature and UV index are also returned.

Developers can use the Get Weather along route API to retrieve weather information
along a particular route. Also, the service supports the generation of weather
notifications for waypoints affected by weather hazards, such as flooding or heavy rain.

The Get Map Tile API allows you to request past, current, and future radar and satellite
tiles.

Programming model
Azure Maps is built for mobility and can help you develop cross-platform applications. It
uses a programming model that's language agnostic and supports JSON output
through REST APIs.

Also, Azure Maps offers a convenient JavaScript map control with a simple
programming model. The development is quick and easy for both web and mobile
applications.

Power BI visual
The Azure Maps Power BI visual provides a rich set of data visualizations for spatial data
on top of a map. It's estimated that over 80% of business data has a location context.
The Azure Maps Power BI visual offers a no-code solution for gaining insights into how
this location context relates to and influences your business data.

For more information, see Get started with Azure Maps Power BI visual.

Usage
To access Azure Maps services, go to the Azure portal and create an Azure Maps
account.

Azure Maps uses a key-based authentication scheme. When you create your account,
two keys are generated. To authenticate for Azure Maps services, you can use either key.

7 Note

Azure Maps shares customer-provided address/location queries with third-party


TomTom for mapping functionality purposes. These queries aren't linked to any
customer or end user when shared with TomTom and can't be used to identify
individuals.

TomTom is a subprocessor that is authorized to subprocess Azure Maps customer


data. For more information, see the Microsoft Online Services Subprocessor List
located in the Microsoft Trust Center .
Supported regions
Azure Maps services are currently available except in the following countries/regions:

China
South Korea

Verify that the location of your current IP address is in a supported country/region.

Next steps
Try a sample app that showcases Azure Maps:

Quickstart: Create a web app

Stay up to date on Azure Maps:

Azure Maps blog

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Quickstart: Create an interactive search
map with Azure Maps
Article • 02/11/2025

This quickstart demonstrates how to use Azure Maps to create a map that gives users an
interactive search experience. It walks you through these basic steps:

Create your own Azure Maps account.


Get your Azure Maps subscription key to use in the demo web application.
Download and open the demo map application.

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

Sign in to the Azure portal .

Create an Azure Maps account


Create a new Azure Maps account with the following steps:

1. Select Create a resource in the upper left-hand corner of the Azure portal .

2. Type Azure Maps in the Search services and Marketplace box.

3. Select Azure Maps in the drop-down list that appears, then select the Create
button.

4. On the Create an Azure Maps Account resource page, enter the following values
then select the Create button:

The Subscription that you want to use for this account.


The Resource group name for this account. You may choose to Create new or
Select existing resource group.
The Name of your new Azure Maps account.
The Pricing tier for this account. Select Gen2.
Read the License and Privacy Statement, then select the checkbox to accept
the terms.

Get the subscription key for your account


Once your Azure Maps account is successfully created, retrieve the subscription key that
enables you to query the Maps APIs.

1. Open your Maps account in the portal.


2. In the settings section, select Authentication.
3. Copy the Primary Key and save it locally to use later in this tutorial.

7 Note

This quickstart uses the Shared Key authentication approach for demonstration
purposes, but the preferred approach for any production environment is to use
Microsoft Entra ID authentication.

Download and update the Azure Maps demo


1. Copy the contents of the file: Interactive Search Quickstart.html .
2. Save the contents of this file locally as AzureMapDemo.html. Open it in a text
editor.
3. Add the Primary Key value you got in the preceding section
a. Comment out all of the code in the authOptions function, this code is used for
Microsoft Entra authentication.
b. Uncomment the last two lines in the authOptions function, this code is used for
Shared Key authentication, the approach being used in this quickstart.
c. Replace <Your Azure Maps Key> with the subscription key value from the
preceding section.
Open the demo application
1. Open the file AzureMapDemo.html in a browser of your choice.

2. Observe the map shown of the City of Los Angeles. Zoom in and out to see how
the map automatically renders with more or less information depending on the
zoom level.

3. Change the default center of the map. In the AzureMapDemo.html file, search for
the variable named center. Replace the longitude, latitude pair value for this
variable with the new values [-74.0060, 40.7128]. Save the file and refresh your
browser.

4. Try out the interactive search experience. In the search box on the upper-left
corner of the demo web application, search for restaurants.

5. Move your mouse over the list of addresses and locations that appear below the
search box. Notice how the corresponding pin on the map pops out information
about that location. For privacy of private businesses, fictitious names and
addresses are shown.

Clean up resources

) Important
The tutorials listed in the Next Steps section detail how to use and configure Azure
Maps with your account. Don't clean up the resources created in this quickstart if
you plan to continue to the tutorials.

If you don't plan to continue to the tutorials, take these steps to clean up the resources:

1. Close the browser that runs the AzureMapDemo.html web application.


2. Navigate to the Azure portal. Select All resources from the main portal page, or
select the menu icon in the upper left-hand corner then All resources.
3. Select your Azure Maps account, then select Delete at the top of the page.

For more code examples and an interactive coding experience, see these articles:

Find an address with Azure Maps search service


Use the Azure Maps Map Control

Next steps
In this quickstart, you created an Azure Maps account and a demo application. Take a
look at the following tutorials to learn more about Azure Maps:

Search nearby points of interest with Azure Maps

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Search nearby points of interest
using Azure Maps
Article • 09/03/2024

This tutorial shows how to set up an account with Azure Maps, then use the Maps APIs
to search for a point of interest. In this tutorial, you learn how to:

" Create an Azure Maps account


" Retrieve the subscription key for your Maps account
" Create a new web page using the map control API
" Use the Maps search service to find a nearby point of interest

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

An Azure Maps account


A subscription key

7 Note

For more information on authentication in Azure Maps, see manage authentication


in Azure Maps.

Create a new map


The Map Control API is a convenient client library. This API allows you to easily integrate
Maps into your web application. It hides the complexity of the bare REST service calls
and boosts your productivity with customizable components. The following steps show
you how to create a static HTML page embedded with the Map Control API.

1. On your local machine, create a new file and name it MapSearch.html.

2. Add the following HTML components to the file:

HTML

<!DOCTYPE html>
<html>
<head>
<title>Map Search</title>
<meta charset="utf-8" />

<!-- Add references to the Azure Maps Map control JavaScript and
CSS files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.
js"></script>

<script>
function GetMap(){
//Add Map Control JavaScript code here.
}
</script>

<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}

#myMap {
width: 100%;
height: 100%;
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
</body>
</html>

Some things to know regarding the above HTML:

The HTML header includes CSS and JavaScript resource files hosted by the
Azure Map Control library.
The onload event in the body of the page calls the GetMap function when the
body of the page has loaded.
The GetMap function contains the inline JavaScript code used to access the
Azure Maps APIs. It's added in the next step.

3. Add the following JavaScript code to the GetMap function of the HTML file. Replace
the string <Your Azure Maps Subscription Key> with the subscription key that you
copied from your Azure Maps account.
JavaScript

//Instantiate a map object


var map = new atlas.Map("myMap", {
view: 'Auto',

// Add your Azure Maps subscription key. https://aka.ms/am-


primaryKey
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Subscription Key>'
}
});

Some things to know regarding this JavaScript:

The core of the GetMap function, which initializes the Map Control API for
your Azure Maps account key.
atlas is the namespace that contains the API and related visual components.
atlas.Map provides the control for a visual and interactive web map.

4. Save your changes to the file and open the HTML page in a browser. The map
shown is the most basic map that you can make by calling atlas.Map using your
account key.

5. In the GetMap function, after initializing the map, add the following JavaScript code.

JavaScript
//Wait until the map resources are ready.
map.events.add('ready', function() {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a layer for rendering point data.


var resultLayer = new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'pin-round-darkblue',
anchor: 'center',
allowOverlap: true
},
textOptions: {
anchor: "top"
}
});

map.layers.add(resultLayer);
});

About this code:

A ready event is added to the map, which fires when the map resources
finish loading and the map is ready to be accessed.
In the map ready event handler, a data source is created to store result data.
A symbol layer is created and attached to the data source. This layer specifies
how the result data in the data source should be rendered. In this case, the
result is rendered with a dark blue round pin icon, centered over the results
coordinate that allows other icons to overlap.
The result layer is added to the map layers.

Add search capabilities


This section shows how to use the Maps Search API to find a point of interest on your
map. It's a RESTful API designed for developers to search for addresses, points of
interest, and other geographical information. The Search service assigns a latitude and
longitude information to a specified address.

 Tip

Azure Maps offers a set of npm modules for the Azure Maps JavaScript REST SDK.
These modules include client libraries that simplify the use of Azure Maps REST
services in Node.js applications. For a complete list of the available modules, see
JavaScript/TypeScript REST SDK Developers Guide (preview).

Search service
1. Add the following script block in the map ready event handler. This is the code to
build the search query. It uses the Fuzzy Search service, a basic search API of the
Search Service. Fuzzy Search service handles most fuzzy inputs like addresses,
places, and points of interest (POI). This code searches for nearby gas stations
within the specified radius of the provided latitude and longitude. A GeoJSON
feature collection is then extracted and added to the data source, which
automatically results in the data being rendered on the maps symbol layer. The last
part of this script block sets the maps camera view using the bounding box of the
results using the Map's setCamera property.

JavaScript

var query = 'gasoline-station';


var radius = 9000;
var lat = 47.64452336193245;
var lon = -122.13687658309935;
var url = `https://atlas.microsoft.com/search/poi/json?api-
version=1.0&query=${query}&lat=${lat}&lon=${lon}&radius=${radius}`;

fetch(url, {
headers: {
"Subscription-Key": map.authentication.getToken()
}
})
.then((response) => response.json())
.then((response) => {
var bounds = [];

//Extract GeoJSON feature collection from the response and add it


to the datasource
var data = response.results.map((result) => {
var position = [result.position.lon, result.position.lat];
bounds.push(position);
return new atlas.data.Feature(new atlas.data.Point(position), {
...result });
});
datasource.add(data);

//Set camera to bounds to show the results


map.setCamera({
bounds: new atlas.data.BoundingBox.fromLatLngs(bounds),
zoom: 10,
padding: 15
});
});

2. Save the MapSearch.html file and refresh your browser. You should see the map
centered on Seattle with round-blue pins for locations of gas stations in the area.

3. You can see the raw data that the map is rendering by entering the following
HTTPRequest in your browser. Replace <Your Azure Maps Subscription Key> with
your subscription key.

HTTP

https://atlas.microsoft.com/search/poi/json?api-
version=1.0&query=gasoline%20station&subscription-key={Your-Azure-Maps-
Subscription-key}&lat=47.6292&lon=-122.2337&radius=100000

At this point, the MapSearch page can display the locations of points of interest that are
returned from a fuzzy search query. Let's add some interactive capabilities and more
information about the locations.

Add interactive data


The map so far only looks at the longitude/latitude data for the search results. However,
the raw JSON that the Maps Search service returns contains additional information
about each gas station. Including the name and street address. You can incorporate that
data into the map with interactive popup boxes.
1. Add the following lines of code in the map ready event handler after the code to
query the fuzzy search service. This code creates an instance of a Popup and adds
a mouseover event to the symbol layer.

JavaScript

// Create a popup but leave it closed so we can update it and display


it later.
popup = new atlas.Popup();

//Add a mouse over event to the result layer and display a popup when
this event fires.
map.events.add('mouseover', resultLayer, showPopup);

The API atlas.Popup provides an information window anchored at the required


position on the map.

2. Add the following lines of code in the map ready event handler after the code to
create an instance of a Popup and add a mouseover event to the symbol layer. This
code shows a popup window with the results when you mouse over a point of
interest.

JavaScript

function showPopup(e) {
//Get the properties and coordinates of the first shape that the
event occurred on.

var p = e.shapes[0].getProperties();
var position = e.shapes[0].getCoordinates();

//Create HTML from properties of the selected result.


var html = `
<div style="padding:5px">
<div><b>${p.poi.name}</b></div>
<div>${p.address.freeformAddress}</div>
<div>${position[1]}, ${position[0]}</div>
</div>`;

//Update the content and position of the popup.


popup.setPopupOptions({
content: html,
position: position
});

//Open the popup.


popup.open(map);
}
3. Save the file and refresh your browser. Now the map in the browser shows
information popups when you hover over any of the search pins.

For the completed code used in this tutorial, see the search tutorial on GitHub.
To view this sample live, see Search for points of interest on the Azure Maps
Code Samples site.

Next steps
The next tutorial demonstrates how to display a route between two locations.

Route to a destination

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: How to display route directions
using Azure Maps Route service and
Map control
Article • 09/03/2024

This tutorial shows you how to use the Azure Maps Route service API and Map control
to display route directions from start to end point. This tutorial demonstrates how to:

" Create and display the Map control on a web page.


" Define the display rendering of the route by defining Symbol layers and Line layers.
" Create and add GeoJSON objects to the Map to represent start and end points.
" Get route directions from start and end points using the Get Route directions API.

See the route tutorial in GitHub for the source code. See Route to a destination for
a live sample.

Prerequisites
An Azure Maps account
A subscription key

Create and display the Map control


The following steps show you how to create and display the Map control in a web page.

1. On your local machine, create a new file and name it MapRoute.html.

2. Add the following HTML to the file:

HTML

<!DOCTYPE html>
<html>
<head>
<title>Map Route</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Add references to the Azure Maps Map control JavaScript and
CSS files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css">
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.
js"></script>

<script>
var map, datasource, client;

function GetMap() {
//Add Map Control JavaScript code here.
}
</script>
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}

#myMap {
width: 100%;
height: 100%;
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
</body>
</html>

Some things to know about the HTML:

The HTML header includes CSS and JavaScript resource files hosted by the
Azure Map Control library.
The onload event in the body of the page calls the GetMap function when the
body of the page finishes loading.
The GetMap function contains the inline JavaScript code used to access the
Azure Maps APIs. This function is added in the next step.

3. Next, add the following JavaScript code to the GetMap function, just beneath the
code added in the last step. This code creates a map control and initializes it using
your Azure Maps subscription keys that you provide. Make sure and replace the
string <Your Azure Maps Key> with the Azure Maps primary key that you copied
from your Maps account.

JavaScript
//Instantiate a map object
var map = new atlas.Map('myMap', {
// Replace <Your Azure Maps Key> with your Azure Maps subscription
key. https://aka.ms/am-primaryKey
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

Some things to know about the JavaScript:

This is the core of the GetMap function, which initializes the Map Control API
for your Azure Maps account key.
atlas is the namespace that contains the Azure Maps API and related visual
components.
atlas.Map provides the control for a visual and interactive web map.

4. Save your changes to the file and open the HTML page in a browser. The map
shown is the most basic map that you can make by calling atlas.Map using your
Azure Maps account subscription key.

Define route display rendering


In this tutorial, the route is rendered using a line layer. The start and end points are
rendered using a symbol layer. For more information on adding line layers, see Add a
line layer to a map. To learn more about symbol layers, see Add a symbol layer to a map.

1. In the GetMap function, after initializing the map, add the following JavaScript code.

JavaScript

//Wait until the map resources are ready.


map.events.add('ready', function() {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a layer for rendering the route lines and have it render
under the map labels.
map.layers.add(new atlas.layer.LineLayer(datasource, null, {
strokeColor: '#2272B9',
strokeWidth: 5,
lineJoin: 'round',
lineCap: 'round'
}), 'labels');

//Add a layer for rendering point data.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: ['get', 'icon'],
allowOverlap: true
},
textOptions: {
textField: ['get', 'title'],
offset: [0, 1.2]
},
filter: ['any', ['==', ['geometry-type'], 'Point'], ['==',
['geometry-type'], 'MultiPoint']] //Only render Point or MultiPoints in
this layer.
}));
});

Some things to know about the JavaScript:

This code implements the Map control's ready event handler. The rest of the
code in this tutorial is placed inside the ready event handler.
In the map control's ready event handler, a data source is created to store
the route from start to end point.
To define how the route line is rendered, a line layer is created and attached
to the data source. To ensure that the route line doesn't cover up the road
labels, pass a second parameter with the value of 'labels' .
Next, a symbol layer is created and attached to the data source. This layer specifies
how the start and end points are rendered. Expressions were added to retrieve the
icon image and text label information from properties on each point object. To
learn more about expressions, see Data-driven style expressions.

2. Next, set the start point at Microsoft, and the end point at a gas station in Seattle.
Start and points are created by appending the following code in the Map control's
ready event handler:

JavaScript

//Create the GeoJSON objects which represent the start and end points
of the route.
var startPoint = new atlas.data.Feature(new
atlas.data.Point([-122.130137, 47.644702]), {
title: "Redmond",
icon: "pin-blue"
});

var endPoint = new atlas.data.Feature(new atlas.data.Point([-122.3352,


47.61397]), {
title: "Seattle",
icon: "pin-round-blue"
});

//Add the data to the data source.


datasource.add([startPoint, endPoint]);

map.setCamera({
bounds: atlas.data.BoundingBox.fromData([startPoint, endPoint]),
padding: 80
});

Some things to know about the JavaScript:

This code creates two GeoJSON Point objects to represent start and end
points, which are then added to the data source.
The last block of code sets the camera view using the latitude and longitude
of the start and end points.
The start and end points are added to the data source.
The bounding box for the start and end points is calculated using the
atlas.data.BoundingBox.fromData function. This bounding box is used to set

the map cameras view over the entire route using the map.setCamera
function.
Padding is added to compensate for the pixel dimensions of the symbol
icons.
For more information about the Map control's setCamera property, see the
setCamera(CameraOptions | CameraBoundsOptions & AnimationOptions)
property.

3. Save MapRoute.html and refresh your browser. The map is now centered over
Seattle. The blue teardrop pin marks the start point. The blue round pin marks the
end point.

Get route directions


This section shows you how to use the Azure Maps Route Directions API to get route
directions and the estimated time of arrival from one point to another.

 Tip

The Azure Maps Route services offer APIs to plan routes based on different route
types such as fastest, shortest, eco, or thrilling routes based on distance, traffic
conditions, and mode of transport used. The service also lets users plan future
routes based on historical traffic conditions. Users can see the prediction of route
durations for any given time. For more information, see Get Route directions API.

1. In the GetMap function, inside the control's ready event handler, add the following
to the JavaScript code.

JavaScript
var query = startPoint.geometry.coordinates[1] + "," +
startPoint.geometry.coordinates[0] + ":" +
endPoint.geometry.coordinates[1] + "," +
endPoint.geometry.coordinates[0];
var url = `https://atlas.microsoft.com/route/directions/json?api-
version=1.0&query=${query}`;

//Make a search route request


fetch(url, {
headers: {
"Subscription-Key": map.authentication.getToken()
}
})
.then((response) => response.json())
.then((response) => {
var route = response.routes[0];
//Create an array to store the coordinates of each turn
var routeCoordinates = [];
route.legs.forEach((leg) => {
var legCoordinates = leg.points.map((point) => {
return [point.longitude, point.latitude];
});
//Add each turn to the array
routeCoordinates = routeCoordinates.concat(legCoordinates);
});
//Add route line to the datasource
datasource.add(new atlas.data.Feature(new
atlas.data.LineString(routeCoordinates)));
});

Some things to know about the JavaScript:

This code constructs the route from the start to end point.
The url queries the Azure Maps Route service API to calculate route
directions.
An array of coordinates is then extracted from the response and added to the
data source.

2. Save the MapRoute.html file and refresh your web browser. The map should now
display the route from the start to end points.

For the completed code used in this tutorial, see the route tutorial on GitHub.
To view this sample live, see Route to a destination on the Azure Maps Code
Samples site.

Next steps
The next tutorial shows you how to create a route query with restrictions, like mode of
travel or type of cargo. You can then display multiple routes on the same map.

Find routes for different modes of travel

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Find and display routes for
different modes of travel using Azure
Maps
Article • 09/03/2024

This tutorial demonstrates how to use the Azure Maps Route service and Map control to
display route directions for both private vehicles and commercial vehicles (trucks) with
USHazmatClass2 cargo type.

In this tutorial, you learn how to:

" Create and display the Map control on a web page


" Render real-time traffic data on a map
" Request and display private and commercial vehicle routes on a map

Prerequisites
An Azure Maps account
A subscription key

7 Note

For more information on authentication in Azure Maps, see manage authentication


in Azure Maps.

Create a new web page using the map control


API
The following steps show you how to create and display the Map control in a web page.

1. On your local machine, create a new file and name it MapTruckRoute.html.

2. Add the following HTML to the file:

HTML

<!DOCTYPE html>
<html>
<head>
<title>Map Route</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Add references to the Azure Maps Map control JavaScript and
CSS files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css">
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.
js"></script>

<script>
var map, datasource, client;

function GetMap() {
//Add Map Control JavaScript code here.
}
</script>
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}

#myMap {
width: 100%;
height: 100%;
}
</style>
</head>
<body onload="GetMap()">
<div id="myMap"></div>
</body>
</html>

Some things to know about the HTML:

The HTML header includes CSS and JavaScript resource files hosted by the
Azure Map Control library.
The onload event in the body of the page calls the GetMap function when the
body of the page finishes loading.
The GetMap function contains the inline JavaScript code used to access the
Azure Maps API.
3. Next, add the following JavaScript code to the GetMap function, just beneath the
code added in the last step. This code creates a map control and initializes it using
your Azure Maps subscription keys that you provide. Make sure and replace the
string <Your Azure Maps Subscription Key> with the Azure Maps subscription key
that you copied from your Maps account.

JavaScript

//Instantiate a map object


var map = new atlas.Map("myMap", {
// Replace <Your Azure Maps Subscription Key> with your Azure Maps
subscription key. https://aka.ms/am-primaryKey
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Subscription Key>'
}
});

Some things to know about the JavaScript:

This code is the core of the GetMap function, which initializes the Map Control
API for your Azure Maps account.
atlas is the namespace that contains the Azure Maps API and related visual
components.
atlas.Map provides the control for a visual and interactive web map.

4. Save the file and open it in your browser. The browser displays a basic map by
calling atlas.Map using your Azure Maps subscription key.


Render real-time traffic data on a map
1. In the GetMap function, after initializing the map, add the following JavaScript code.
This code implements the Map control's ready event handler.

JavaScript

map.events.add("ready", function() {
// Add Traffic Flow to the Map
map.setTraffic({
flow: "relative"
});
});

Some things to know about the JavaScript:

This code implements the Map control's ready event handler. The rest of the
code in this tutorial is placed inside the ready event handler.
In the map ready event handler, the traffic flow setting on the map is set to
relative , which is the speed of the road relative to free-flow.

For more traffic options, see TrafficOptions interface.

2. Save the MapTruckRoute.html file and refresh the page in your browser. If you
zoom into any city, like Los Angeles, the streets display with current traffic flow
data.


Define route display rendering
In this tutorial, two routes are calculated on the map. The first route is calculated for a
private vehicle (car). The second route is calculated for a commercial vehicle (truck) to
show the difference between the results. When rendered, the map displays a symbol
icon for the start and end points of the route, and route line geometries with different
colors for each route path. For more information on adding line layers, see Add a line
layer to a map. To learn more about symbol layers, see Add a symbol layer to a map.

1. In the Map control's ready event handler, append the following code.

JavaScript

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a layer for rendering the route lines and have it render under
the map labels.
map.layers.add(new atlas.layer.LineLayer(datasource, null, {
strokeColor: ['get', 'strokeColor'],
strokeWidth: ['get', 'strokeWidth'],
lineJoin: 'round',
lineCap: 'round'
}), 'labels');

//Add a layer for rendering point data.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: ['get', 'icon'],
allowOverlap: true
},
textOptions: {
textField: ['get', 'title'],
offset: [0, 1.2]
},
filter: ['any', ['==', ['geometry-type'], 'Point'], ['==',
['geometry-type'], 'MultiPoint']] //Only render Point or MultiPoints in
this layer.
}));

Some things to know about the JavaScript:

In the Map control's ready event handler, a data source is created to store
the route from start to finish.
Expressions are used to retrieve the line width and color from properties on
the route line feature.
To ensure that the route line doesn't cover up the road labels, pass a second
parameter with the value of 'labels' .

Next, a symbol layer is created and attached to the data source. This layer specifies
how the start and end points are rendered. Expressions are added to retrieve the
icon image and text label information from properties on each point object. To
learn more about expressions, see Data-driven style expressions.

2. Next, set the start point as a fictitious company in Seattle called Fabrikam, and the
end point as a Microsoft office. In the Map control's ready event handler, append
the following code.

JavaScript

//Create the GeoJSON objects which represent the start and end point of
the route.
var startPoint = new atlas.data.Feature(new
atlas.data.Point([-122.356099, 47.580045]), {
title: 'Fabrikam, Inc.',
icon: 'pin-blue'
});

var endPoint = new atlas.data.Feature(new


atlas.data.Point([-122.201164, 47.616940]), {
title: 'Microsoft - Lincoln Square',
icon: 'pin-round-blue'
});

//Add the data to the data source.


datasource.add([startPoint, endPoint]);

//Fit the map window to the bounding box defined by the start and end
positions.
map.setCamera({
bounds: atlas.data.BoundingBox.fromData([startPoint, endPoint]),
padding: 100
});

About the JavaScript:

This code creates two GeoJSON Point objects to represent start and end
points, which are then added to the data source.
The last block of code sets the camera view using the latitude and longitude
of the start and end points.
The start and end points are added to the data source.
The bounding box for the start and end points is calculated using the
atlas.data.BoundingBox.fromData function. This bounding box is used to set
the map cameras view over the entire route using the map.setCamera
function.
Padding is added to compensate for the pixel dimensions of the symbol
icons.
For more information, see the setCamera function in the Microsoft technical
documentation.

3. Save TruckRoute.html and refresh your browser. The map is now centered over
Seattle. The blue teardrop pin marks the start point. The round blue pin marks the
end point.

Request and display private and commercial


vehicle routes on a map
This section shows you how to use the Azure Maps Route service to get directions from
one point to another, based on your mode of transport. Two modes of transport are
used: truck and car.

 Tip

The Route service provides APIs to plan fastest, shortest, eco, or thrilling routes
based on distance, traffic conditions, and mode of transport used. The service also
lets users plan future routes based on historical traffic conditions. Users can see the
prediction of route durations for any given time. For more information, see Get
Route directions API.
1. In the GetMap function, inside the control's ready event handler, add the following
JavaScript code to construct a truck route from the start to end points. This route is
created and displayed for a truck carrying USHazmatClass2 classed cargo.

JavaScript

//Start and end point input to the search route request


var query = startPoint.geometry.coordinates[1] + "," +
startPoint.geometry.coordinates[0] + ":" +
endPoint.geometry.coordinates[1] + "," +
endPoint.geometry.coordinates[0];
//Make a search route request for a truck vehicle type
var truckRouteUrl = `https://atlas.microsoft.com/route/directions/json?
api-
version=1.0&travelMode=truck&vehicleWidth=2&vehicleHeight=2&vehicleLeng
th=5&vehicleLoadType=USHazmatClass2&query=${query}`;
fetch(truckRouteUrl, {
headers: {
"Subscription-Key": map.authentication.getToken()
}
})
.then((response) => response.json())
.then((response) => {
var route = response.routes[0];
//Create an array to store the coordinates of each turn
var routeCoordinates = [];
route.legs.forEach((leg) => {
var legCoordinates = leg.points.map((point) => {
return [point.longitude, point.latitude];
});
//Add each turn to the array
routeCoordinates = routeCoordinates.concat(legCoordinates);
});

//Add the route line to the data source. We want this to render
below the car route which will likely be added to the data source
faster, so insert it at index 0.
datasource.add(
new atlas.data.Feature(new
atlas.data.LineString(routeCoordinates), {
strokeColor: "#2272B9",
strokeWidth: 9
}),
0
);
});

About the above JavaScript:

This code queries the Azure Maps Route service through the Azure Maps
Route Directions API.
The route line is then created from the coordinates of each turn from the
response.
The route line is then added to the data source.
Two properties are added to the truck route line: a blue stroke color #2272B9 ,
and a stroke width of nine pixels.
The route line is given an index of 0 to ensure that the truck route is rendered
before any other lines in the data source. The reason is the truck route
calculation are often slower than a car route calculation. If the truck route line
is added to the data source after the car route, it will render above it.

 Tip

To see all possible options and values for the Azure Maps Route Directions
API, see URI Parameters for Post Route Directions.

2. Next, append the following JavaScript code to create a route for a car.

JavaScript

var carRouteUrl = `https://atlas.microsoft.com/route/directions/json?


api-version=1.0&query=${query}`;
fetch(carRouteUrl, {
headers: {
"Subscription-Key": map.authentication.getToken()
}
})
.then((response) => response.json())
.then((response) => {
var route = response.routes[0];
//Create an array to store the coordinates of each turn
var routeCoordinates = [];
route.legs.forEach((leg) => {
var legCoordinates = leg.points.map((point) => {
return [point.longitude, point.latitude];
});
//Add each turn to the array
routeCoordinates = routeCoordinates.concat(legCoordinates);
});

//Add the route line to the data source. This will add the car
route after the truck route.
datasource.add(
new atlas.data.Feature(new
atlas.data.LineString(routeCoordinates), {
strokeColor: "#B76DAB",
strokeWidth: 5
})
);
});

About the JavaScript:

This code queries the Azure Maps routing service through the Azure Maps
Route Directions API method.
The route line is then created from the coordinates of each turn and added to
the data source.
Two properties are added to the truck route line: a purple stroke color
#B76DAB , and a stroke width of five pixels.

3. Save the TruckRoute.html file and refresh your web browser. The map should now
display both the truck and car routes.

The truck route is displayed using a thick blue line and the car route is
displayed using a thin purple line.
The car route goes across Lake Washington via I-90, passing through tunnels
beneath residential areas. Because the tunnels are in residential areas,
hazardous waste cargo is restricted. The truck route, which specifies a
USHazmatClass2 cargo type, is directed to use a different route that doesn't

have this restriction.

For the completed code used in this tutorial, see the Truck Route tutorial on
GitHub.
To view this sample live, see Multiple routes by mode of travel on the Azure
Maps Code Samples site.
You can also use Data-driven style expressions.
Next steps
The next tutorial demonstrates the process of creating a simple store locator using
Azure Maps.

Create a store locator using Azure Maps

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Use Azure Maps to create a
store locator
Article • 09/05/2024

This tutorial guides you through the process of creating a simple store locator using
Azure Maps.

In this tutorial, you'll learn how to:

" Create a new webpage by using the Azure Map Control API.


" Load custom data from a file and display it on a map.
" Use the Azure Maps Search service to find an address or enter a query.
" Get the user's location from the browser and show it on the map.
" Combine multiple layers to create custom symbols on the map.
" Cluster data points.
" Add zoom controls to the map.

Prerequisites
Visual Studio Code is recommended for this tutorial, but you can use any
suitable integrated development environment (IDE).
An Azure Maps account
A subscription key

7 Note

For more information on authentication in Azure Maps, see manage authentication


in Azure Maps.

Sample code
This tutorial demonstrates how to create a store locator for a fictional company named
Contoso Coffee, along with tips to extend the store locator with additional functionality.

To see a live sample of what you're creating in this tutorial, see Simple Store Locator
on the Azure Maps Code Samples site.

To more easily follow and engage this tutorial, download the following resources:
Simple Store Locator source code.
Store location data used to import into the store locator dataset.
The Map images .

Store locator features


This section lists the Azure Maps features that are demonstrated in the Contoso Coffee
store locator application created in this tutorial.

User interface features


A store logo on the header
A map that supports panning and zooming
A My Location button to search over the user's current location.
A Page layout that adjusts based on the width of the devices screen
A search box and a search button

Functionality features
A keypress event added to the search box triggers a search when the user presses
Enter.
When the map moves, the distance to each location from the center of the map
recalculates. The results list updates to display the closest locations at the top of
the map.
When the user selects a result in the results list, the map is centered over the
selected location and information about the location appears in a pop-up window.
When the user selects a specific location, the map triggers a pop-up window.
When the user zooms out, locations are grouped in clusters. Each cluster is
represented by a circle with a number inside the circle. Clusters form and separate
as the user changes the zoom level.
Selecting a cluster zooms in two levels on the map and centers over the location of
the cluster.

Store locator design


The following screenshot shows the general layout of the Contoso Coffee store locator
application. To view and interact with the live sample, see the Simple Store Locator
sample application on the Azure Maps Code Samples site.

To maximize the usefulness of this store locator, we include a responsive layout that
adjusts when a user's screen width is smaller than 700 pixels wide. A responsive layout
makes it easy to use the store locator on a small screen, like on a mobile device. Here's a
screenshot showing a sample of the small-screen layout:

Create the store location dataset


This section describes how to create a dataset of the stores that you want to display on
the map. The dataset for the Contoso Coffee locator is created inside an Excel
workbook. The dataset contains 10,213 Contoso Coffee coffee shop locations spread
across nine countries or regions: the United States, Canada, the United Kingdom, France,
Germany, Italy, the Netherlands, Denmark, and Spain. Here's a screenshot of what the
data looks like:
Download the excel file containing the full dataset for the Contoso Coffee locator
sample application from the data folder of the Azure Maps code samples repository in
GitHub.

From the above screenshot of the data, we can make the following observations:

Location information is stored in the following six columns: AddressLine, City,


Municipality (county), AdminDivision (state/province), PostCode (postal code),
and Country.
The Latitude and Longitude columns contain the coordinates for each Contoso
Coffee location. If you don't have coordinate information, you can use the Search
service to determine the location coordinates.
Some other columns contain metadata that's related to the coffee shops: a phone
number, Boolean columns, and store opening and closing times in 24-hour format.
The Boolean columns are for Wi-Fi and wheelchair accessibility. You can create
your own columns that contain metadata that's more relevant to your location
data.

7 Note

Azure Maps renders data in the Spherical Mercator projection "EPSG:3857 " but
reads data in "EPSG:4326 " that use the WGS84 datum.

Load Contoso Coffee shop locator dataset


The Contoso Coffee shop locator dataset is small, so it can be converted into a tab-
delimited text file that the browser downloads when the application loads.

 Tip

If your dataset is too large for client download, or is updated frequently, you might
consider storing your dataset in a database. After your data is loaded into a
database, you can then set up a web service that accepts queries for the data, then
sends the results to the user's browser.

Convert data to tab-delimited text file


To convert the Contoso Coffee shop location data from an Excel workbook into a tab-
delimited text file:

1. Download the Excel workbook ContosoCoffee.xlsx and Open it in Excel.

2. Select File > Save As....

3. In the Save as type drop-down list, select Text (Tab delimited)(*.txt).

4. Name the file ContosoCoffee.

If you open the text file in Notepad, it looks similar to the following text:
Set up the project
1. Open Visual Studio Code , or your choice of development environments.

2. Select File > Open Workspace....

3. Create a new folder named ContosoCoffee.

4. Select ContosoCoffee in the explorer.

5. Create the following three files that define the layout, style, and logic for the
application:

index.html
index.css
index.js

6. Create a folder named data.

7. Add the ContosoCoffee.txt file that you previously created from the Excel workbook
ContosoCoffee.xlsx to the data folder.

8. Create another folder named images.

9. If you haven't already, download the 10 Map images from the images directory
in the GitHub Repository and add them to the images folder.

Your workspace folder should now look like the following screenshot:

Create the HTML


To create the HTML:

1. Add the following meta tags to the head of index.html:

HTML

<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

2. Add references to the Azure Maps web control JavaScript and CSS files:

HTML

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css">
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.
js"></script>

3. Add references to index.js and index.css.

HTML

<!-- Add references to the store locator JavaScript and CSS files. -->
<link rel="stylesheet" href="index.css" type="text/css">
<script src="index.js"></script>

4. In the body of the document, add a header tag. Inside the header tag, add the
logo and company name.

HTML

<header>
<img src="images/Logo.png" />
<span>Contoso Coffee</span>
</header>

5. Add a main tag and create a search panel that has a text box and search button.
Also, add div references for the map, the list panel, and the My Location GPS
button.

HTML

<main>
<div class="searchPanel">
<div>
<input id="searchTbx" type="search" placeholder="Find a
store" />
<button id="searchBtn" title="Search"></button>
</div>
</div>
<div id="listPanel"></div>
<div id="myMap"></div>
<button id="myLocationBtn" title="My Location"></button>
</main>

Once completed, index.html should look like Simple Store Locator.html in the tutorial
sample code.

Define the CSS styles


The next step is to define the CSS styles. CSS styles define how the application
components are laid out and the application's appearance.

1. Open index.css.

2. Add the following css code:

7 Note

The @media style defines alternate style options to use when the screen width
is smaller than 700 pixels.

CSS

html, body {
padding: 0;
margin: 0;
font-family: Gotham, Helvetica, sans-serif;
overflow-x: hidden;
}

header {
width: calc(100vw - 10px);
height: 30px;
padding: 15px 0 20px 20px;
font-size: 25px;
font-style: italic;
font-family: "Comic Sans MS", cursive, sans-serif;
line-height: 30px;
font-weight: bold;
color: white;
background-color: #007faa;
}

header span {
vertical-align: middle;
}

header img {
height: 30px;
vertical-align: middle;
}

.searchPanel {
position: relative;
width: 350px;
}

.searchPanel div {
padding: 20px;
}
.searchPanel input {
width: calc(100% - 50px);
font-size: 16px;
border: 0;
border-bottom: 1px solid #ccc;
}

#listPanel {
position: absolute;
top: 135px;
left: 0px;
width: 350px;
height: calc(100vh - 135px);
overflow-y: auto;
}

#myMap {
position: absolute;
top: 65px;
left: 350px;
width: calc(100vw - 350px);
height: calc(100vh - 65px);
}

.statusMessage {
margin: 10px;
}

#myLocationBtn, #searchBtn {
margin: 0;
padding: 0;
border: none;
border-collapse: collapse;
width: 32px;
height: 32px;
text-align: center;
cursor: pointer;
line-height: 32px;
background-repeat: no-repeat;
background-size: 20px;
background-position: center center;
z-index: 200;
}

#myLocationBtn {
position: absolute;
top: 150px;
right: 10px;
box-shadow: 0px 0px 4px rgba(0,0,0,0.16);
background-color: white;
background-image: url("images/GpsIcon.png");
}

#myLocationBtn:hover {
background-image: url("images/GpsIcon-hover.png");
}

#searchBtn {
background-color: transparent;
background-image: url("images/SearchIcon.png");
}

#searchBtn:hover {
background-image: url("images/SearchIcon-hover.png");
}

.listItem {
height: 50px;
padding: 20px;
font-size: 14px;
}

.listItem:hover {
cursor: pointer;
background-color: #f1f1f1;
}

.listItem-title {
color: #007faa;
font-weight: bold;
}

.storePopup {
min-width: 150px;
}

.storePopup .popupTitle {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
padding: 8px;
height: 30px;
background-color: #007faa;
color: white;
font-weight: bold;
}

.storePopup .popupSubTitle {
font-size: 10px;
line-height: 12px;
}

.storePopup .popupContent {
font-size: 11px;
line-height: 18px;
padding: 8px;
}

.storePopup img {
vertical-align:middle;
height: 12px;
margin-right: 5px;
}

/* Adjust the layout of the page when the screen width is fewer than
700 pixels. */
@media screen and (max-width: 700px) {
.searchPanel {
width: 100vw;
}

#listPanel {
top: 385px;
width: 100%;
height: calc(100vh - 385px);
}

#myMap {
width: 100vw;
height: 250px;
top: 135px;
left: 0px;
}

#myLocationBtn {
top: 220px;
}
}

.mapCenterIcon {
display: block;
width: 10px;
height: 10px;
border-radius: 50%;
background: orange;
border: 2px solid white;
cursor: pointer;
box-shadow: 0 0 0 rgba(0, 204, 255, 0.4);
animation: pulse 3s infinite;
}

@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(0, 204, 255, 0.4);
}

70% {
box-shadow: 0 0 0 50px rgba(0, 204, 255, 0);
}

100% {
box-shadow: 0 0 0 0 rgba(0, 204, 255, 0);
}
}
If you run the application at this point, the header, search box, and search button
appear. However, the map isn't visible because it hasn't been loaded yet. If you try to do
a search, nothing happens. The next section describes adding the JavaScript logic
needed to access all the functionality of the store locator.

Add JavaScript code


The JavaScript code in the Contoso Coffee shop locator app enables the following
processes:

1. Adds an event listener called ready to wait until the page has completed its
loading process. When the page loading is complete, the event handler creates
more event listeners to monitor the loading of the map, and give functionality to
the search and My location buttons.

2. When the user selects the search button, or types a location in the search box then
presses enter, a fuzzy search against the user's query begins. The code passes in an
array of country/region ISO 2 values to the countrySet option to limit the search
results to those countries/regions. Limiting the countries/regions to search helps
increase the accuracy of the results that are returned.

3. Once the search completes, the first location result is used as the center focus of
the map. When the user selects the My Location button, the code retrieves the
user's location using the HTML5 Geolocation API that's built into the browser. Once
the location is retrieved, the code centers the map over the user's location.

To add the JavaScript:

1. Open index.js.

2. Add global options to make settings easier to update. Define the variables for the
map, pop up window, data source, icon layer, and HTML marker. Set the HTML
marker to indicate the center of a search area. And, define an instance of the Azure
Maps search service client.

JavaScript

//The maximum zoom level to cluster data point data on the map.
var maxClusterZoomLevel = 11;

//The URL to the store location data.


var storeLocationDataUrl = 'data/ContosoCoffee.txt';

//The URL to the icon image.


var iconImageUrl = 'images/CoffeeIcon.png';
//An array of country region ISO2 values to limit searches to.
var countrySet = ['US', 'CA', 'GB', 'FR','DE','IT','ES','NL','DK'];

//
var map, popup, datasource, iconLayer, centerMarker;

// Used in function updateListItems


var listItemTemplate = '<div class="listItem"
onclick="itemSelected(\'{id}\')"><div class="listItem-title">{title}
</div>{city}<br />Open until {closes}<br />{distance} miles
away</div>';

3. Add the following initialization code. Make sure to replace <Your Azure Maps Key>
with your Azure Maps subscription key.

 Tip

When you use pop-up windows, it's best to create a single Popup instance and
reuse the instance by updating its content and position. For every
Popup instance you add to your code, multiple DOM elements are added to

the page. The more DOM elements there are on a page, the more things the
browser has to keep track of. If there are too many items, the browser might
become slow.

JavaScript

function initialize() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-90, 40],
zoom: 2,

//Add your Azure Maps subscription key to the map SDK.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Create a pop-up window, but leave it closed so we can update it


and display it later.
popup = new atlas.Popup();

//If the user selects the search button, geocode the value the user
passed in.
document.getElementById('searchBtn').onclick = performSearch;
//If the user presses Enter in the search box, perform a search.
document.getElementById('searchTbx').onkeyup = function(e) {
if (e.keyCode === 13) {
performSearch();
}
};

//If the user selects the My Location button, use the Geolocation
API to get the user's location. Center and zoom the map on that
location.
document.getElementById('myLocationBtn').onclick =
setMapToUserLocation;

//Wait until the map resources are ready.


map.events.add('ready', function() {

//Add your maps post load functionality.

});
}

function performSearch() {
var query = document.getElementById('searchTbx').value;
//Pass in the array of country/region ISO2 for which we want to
limit the search to.
var url = `https://atlas.microsoft.com/search/fuzzy/json?api-
version=1.0&countrySet=${countrySet}&query=${query}&view=Auto`;

//Perform a fuzzy search on the users query.


fetch(url, {
headers: {
"Subscription-Key": map.authentication.getToken()
}
})
.then((response) => response.json())
.then((response) => {
if (Array.isArray(response.results) && response.results.length
> 0) {
var result = response.results[0];
var bbox = [
result.viewport.topLeftPoint.lon,
result.viewport.btmRightPoint.lat,
result.viewport.btmRightPoint.lon,
result.viewport.topLeftPoint.lat
];
//Set the camera to the bounds of the first result.
map.setCamera({
bounds: bbox,
padding: 40
});
} else {
document.getElementById('listPanel').innerHTML = '<div
class="statusMessage">Unable to find the location you searched for.
</div>';
}
});
}

function setMapToUserLocation() {
//Request the user's location.
navigator.geolocation.getCurrentPosition(function(position) {
//Convert the geolocation API position into a
longitude/latitude position value the map can understand and center the
map over it.
map.setCamera({
center: [position.coords.longitude,
position.coords.latitude],
zoom: maxClusterZoomLevel + 1
});
}, function(error) {
//If an error occurs when trying to access the users position
information, display an error message.
switch (error.code) {
case error.PERMISSION_DENIED:
alert('User denied the request for geolocation.');
break;
case error.POSITION_UNAVAILABLE:
alert('Position information is unavailable.');
break;
case error.TIMEOUT:
alert('The request to get user position timed out.');
break;
case error.UNKNOWN_ERROR:
alert('An unknown error occurred.');
break;
}
});
}

//Initialize the application when the page is loaded.


window.onload = initialize;

4. In the map's ready event handler, add a zoom control and an HTML marker to
display the center of a search area.

JavaScript

//Add a zoom control to the map.


map.controls.add(new atlas.control.ZoomControl(), {
position: 'top-right'
});

//Add an HTML marker to the map to indicate the center to use for
searching.
centerMarker = new atlas.HtmlMarker({
htmlContent: '<div class="mapCenterIcon"></div>',
position: map.getCamera().center
});

map.markers.add(centerMarker);

5. In the map's ready event handler, add a data source. Then, make a call to load and
parse the dataset. Enable clustering on the data source. Clustering on the data
source groups overlapping points together in a cluster. As the user zooms in, the
clusters separate into individual points. This behavior provides a better user
experience and improves performance.

JavaScript

//Create a data source, add it to the map, and then enable clustering.
datasource = new atlas.source.DataSource(null, {
cluster: true,
clusterMaxZoom: maxClusterZoomLevel - 1
});

map.sources.add(datasource);

//Load all the store data now that the data source has been defined.
loadStoreData();

6. After the dataset loads in the map's ready event handler, define a set of layers to
render the data. A bubble layer renders clustered data points. A symbol layer
renders the number of points in each cluster above the bubble layer. A second
symbol layer renders a custom icon for individual locations on the map.

Add mouseover and mouseout events to the bubble and icon layers to change the
mouse cursor when the user hovers over a cluster or icon on the map. Add a click
event to the cluster bubble layer. This click event zooms in the map two levels
and centers the map over a cluster when the user selects any cluster. Add a click
event to the icon layer. This click event displays a pop-up window that shows the
details of a coffee shop when a user selects an individual location icon. Add an
event to the map to monitor when the map is finished moving. When this event
fires, update the items in the list panel.

JavaScript

//Create a bubble layer to render clustered data points.


var clusterBubbleLayer = new atlas.layer.BubbleLayer(datasource, null,
{
radius: 12,
color: '#007faa',
strokeColor: 'white',
strokeWidth: 2,
filter: ['has', 'point_count'] //Only render data points that have
a point_count property; clusters have this property.
});

//Create a symbol layer to render the count of locations in a cluster.


var clusterLabelLayer = new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'none' //Hide the icon image.
},

textOptions: {
textField: ['get', 'point_count_abbreviated'],
size: 12,
font: ['StandardFont-Bold'],
offset: [0, 0.4],
color: 'white'
}
});

map.layers.add([clusterBubbleLayer, clusterLabelLayer]);

//Load a custom image icon into the map resources.


map.imageSprite.add('myCustomIcon', iconImageUrl).then(function() {

//Create a layer to render a coffee cup symbol above each bubble for
an individual location.
iconLayer = new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
//Pass in the ID of the custom icon that was loaded into the
map resources.
image: 'myCustomIcon',

//Optionally, scale the size of the icon.


font: ['SegoeUi-Bold'],

//Anchor the center of the icon image to the coordinate.


anchor: 'center',

//Allow the icons to overlap.


allowOverlap: true
},

filter: ['!', ['has', 'point_count']] //Filter out clustered


points from this layer.
});

map.layers.add(iconLayer);

//When the mouse is over the cluster and icon layers, change the
cursor to a pointer.
map.events.add('mouseover', [clusterBubbleLayer, iconLayer],
function() {
map.getCanvasContainer().style.cursor = 'pointer';
});
//When the mouse leaves the item on the cluster and icon layers,
change the cursor back to the default (grab).
map.events.add('mouseout', [clusterBubbleLayer, iconLayer],
function() {
map.getCanvasContainer().style.cursor = 'grab';
});

//Add a click event to the cluster layer. When the user selects a
cluster, zoom into it by two levels.
map.events.add('click', clusterBubbleLayer, function(e) {
map.setCamera({
center: e.position,
zoom: map.getCamera().zoom + 2
});
});

//Add a click event to the icon layer and show the shape that was
selected.
map.events.add('click', iconLayer, function(e) {
showPopup(e.shapes[0]);
});

//Add an event to monitor when the map has finished rendering.


map.events.add('render', function() {
//Update the data in the list.
updateListItems();
});
});

7. When the coffee shop dataset is needed, it must first be downloaded. Once
downloaded, the file must be split into lines. The first line contains the header
information. To make the code easier to follow, we parse the header into an object,
which we can then use to look up the cell index of each property. After the first
line, loop through the remaining lines and create a point feature. Add the point
feature to the data source. Finally, update the list panel.

JavaScript

function loadStoreData() {

//Download the store location data.


fetch(storeLocationDataUrl)
.then(response => response.text())
.then(function(text) {

//Parse the tab-delimited file data into GeoJSON features.


var features = [];

//Split the lines of the file.


var lines = text.split('\n');

//Grab the header row.


var row = lines[0].split('\t');

//Parse the header row and index each column to make the code
for parsing each row easier to follow.
var header = {};
var numColumns = row.length;
for (var i = 0; i < row.length; i++) {
header[row[i]] = i;
}

//Skip the header row and then parse each row into a GeoJSON
feature.
for (var i = 1; i < lines.length; i++) {
row = lines[i].split('\t');

//Ensure that the row has the correct number of columns.


if (row.length >= numColumns) {

features.push(new atlas.data.Feature(new
atlas.data.Point([parseFloat(row[header['Longitude']]),
parseFloat(row[header['Latitude']])]), {
AddressLine: row[header['AddressLine']],
City: row[header['City']],
Municipality: row[header['Municipality']],
AdminDivision: row[header['AdminDivision']],
Country: row[header['Country']],
PostCode: row[header['PostCode']],
Phone: row[header['Phone']],
StoreType: row[header['StoreType']],
IsWiFiHotSpot:
(row[header['IsWiFiHotSpot']].toLowerCase() === 'true') ? true : false,
IsWheelchairAccessible:
(row[header['IsWheelchairAccessible']].toLowerCase() === 'true') ? true
: false,
Opens: parseInt(row[header['Opens']]),
Closes: parseInt(row[header['Closes']])
}));
}
}

//Add the features to the data source.


datasource.add(new atlas.data.FeatureCollection(features));

//Initially, update the list items.


updateListItems();
});
}

8. When the list panel is updated, the distance is calculated. This distance is from the
center of the map to all point features in the current map view. The features are
then sorted by distance. HTML is generated to display each location in the list
panel.
JavaScript

var listItemTemplate = '<div class="listItem"


onclick="itemSelected(\'{id}\')"><div class="listItem-title">{title}
</div>{city}<br />Open until {closes}<br />{distance} miles
away</div>';

function updateListItems() {
//Hide the center marker.
centerMarker.setOptions({
visible: false
});

//Get the current camera and view information for the map.
var camera = map.getCamera();
var listPanel = document.getElementById('listPanel');

//Check to see if the user is zoomed out a substantial distance. If


they are, tell them to zoom in and to perform a search or select the My
Location button.
if (camera.zoom < maxClusterZoomLevel) {
//Close the pop-up window; clusters might be displayed on the
map.
popup.close();
listPanel.innerHTML = '<div class="statusMessage">Search for a
location, zoom the map, or select the My Location button to see
individual locations.</div>';
} else {
//Update the location of the centerMarker property.
centerMarker.setOptions({
position: camera.center,
visible: true
});

//List the ten closest locations in the side panel.


var html = [], properties;

/*
Generating HTML for each item that looks like this:
<div class="listItem" onclick="itemSelected('id')">
<div class="listItem-title">1 Microsoft Way</div>
Redmond, WA 98052<br />
Open until 9:00 PM<br />
0.7 miles away
</div>
*/

//Get all the shapes that have been rendered in the bubble
layer.
var data = map.layers.getRenderedShapes(map.getCamera().bounds,
[iconLayer]);

//Create an index of the distances of each shape.


var distances = {};
data.forEach(function (shape) {
if (shape instanceof atlas.Shape) {

//Calculate the distance from the center of the map to


each shape and store in the index. Round to 2 decimals.
distances[shape.getId()] =
Math.round(atlas.math.getDistanceTo(camera.center,
shape.getCoordinates(), 'miles') * 100) / 100;
}
});

//Sort the data by distance.


data.sort(function (x, y) {
return distances[x.getId()] - distances[y.getId()];
});

data.forEach(function(shape) {
properties = shape.getProperties();
html.push('<div class="listItem" onclick="itemSelected(\'',
shape.getId(), '\')"><div class="listItem-title">',
properties['AddressLine'],
'</div>',
//Get a formatted addressLine2 value that consists of City,
Municipality, AdminDivision, and PostCode.
getAddressLine2(properties),
'<br />',

//Convert the closing time to a format that is easier to


read.
getOpenTillTime(properties),
'<br />',

//Get the distance of the shape.


distances[shape.getId()],
' miles away</div>');
});

listPanel.innerHTML = html.join('');

//Scroll to the top of the list panel in case the user has
scrolled down.
listPanel.scrollTop = 0;
}
}

//This converts a time that's in a 24-hour format to an AM/PM time or


noon/midnight string.
function getOpenTillTime(properties) {
var time = properties['Closes'];
var t = time / 100;
var sTime;

if (time === 1200) {


sTime = 'noon';
} else if (time === 0 || time === 2400) {
sTime = 'midnight';
} else {
sTime = Math.round(t) + ':';

//Get the minutes.


t = (t - Math.round(t)) * 100;

if (t === 0) {
sTime += '00';
} else if (t < 10) {
sTime += '0' + t;
} else {
sTime += Math.round(t);
}

if (time < 1200) {


sTime += ' AM';
} else {
sTime += ' PM';
}
}

return 'Open until ' + sTime;


}

//Create an addressLine2 string that contains City, Municipality,


AdminDivision, and PostCode.
function getAddressLine2(properties) {
var html = [properties['City']];

if (properties['Municipality']) {
html.push(', ', properties['Municipality']);
}

if (properties['AdminDivision']) {
html.push(', ', properties['AdminDivision']);
}

if (properties['PostCode']) {
html.push(' ', properties['PostCode']);
}

return html.join('');
}

9. When the user selects an item in the list panel, the shape to which the item is
related is retrieved from the data source. A pop-up window is generated that's
based on the property information stored in the shape. The map centers over the
shape. If the map is fewer than 700 pixels wide, the map view is offset so the pop-
up window is visible.
JavaScript

//When a user selects a result in the side panel, look up the shape by
its ID value and display the pop-up window.
function itemSelected(id) {
//Get the shape from the data source by using its ID.
var shape = datasource.getShapeById(id);
showPopup(shape);

//Center the map over the shape on the map.


var center = shape.getCoordinates();
var offset;

//If the map is fewer than 700 pixels wide, then the layout is set
for small screens.
if (map.getCanvas().width < 700) {
//When the map is small, offset the center of the map relative
to the shape so that there is room for the popup to appear.
offset = [0, -80];
}

map.setCamera({
center: center,
centerOffset: offset
});
}

function showPopup(shape) {
var properties = shape.getProperties();

/* Generating HTML for the pop-up window that looks like this:

<div class="storePopup">
<div class="popupTitle">
3159 Tongass Avenue
<div class="popupSubTitle">Ketchikan, AK 99901</div>
</div>
<div class="popupContent">
Open until 22:00 PM<br/>
<img title="Phone Icon" src="images/PhoneIcon.png">
<a href="tel:1-800-XXX-XXXX">1-800-XXX-XXXX</a>
<br>Amenities:
<img title="Wi-Fi Hotspot" src="images/WiFiIcon.png">
<img title="Wheelchair Accessible"
src="images/WheelChair-small.png">
</div>
</div>
*/

//Calculate the distance from the center of the map to the shape
in miles, round to 2 decimals.
var distance =
Math.round(atlas.math.getDistanceTo(map.getCamera().center,
shape.getCoordinates(), 'miles') * 100)/100;
var html = ['<div class="storePopup">'];
html.push('<div class="popupTitle">',
properties['AddressLine'],
'<div class="popupSubTitle">',
getAddressLine2(properties),
'</div></div><div class="popupContent">',

//Convert the closing time to a format that's easier to read.


getOpenTillTime(properties),

//Add the distance information.


'<br/>', distance,
' miles away',
'<br /><img src="images/PhoneIcon.png" title="Phone Icon"/><a
href="tel:',
properties['Phone'],
'">',
properties['Phone'],
'</a>'
);

if (properties['IsWiFiHotSpot'] ||
properties['IsWheelchairAccessible']) {
html.push('<br/>Amenities: ');

if (properties['IsWiFiHotSpot']) {
html.push('<img src="images/WiFiIcon.png" title="Wi-Fi
Hotspot"/>');
}

if (properties['IsWheelchairAccessible']) {
html.push('<img src="images/WheelChair-small.png"
title="Wheelchair Accessible"/>');
}
}

html.push('</div></div>');

//Update the content and position of the pop-up window for the
specified shape information.
popup.setOptions({

//Create a table from the properties in the feature.


content: html.join(''),
position: shape.getCoordinates()
});

//Open the pop-up window.


popup.open(map);
}
Now, you have a fully functional store locator. Open the index.html file in a web browser.
When the clusters appear on the map, you can search for a location using any of the
following methods:

1. The search box.


2. Selecting the My Location button
3. Selecting a cluster
4. Zooming in on the map to see individual locations.

The first time a user selects the My Location button, the browser displays a security
warning that asks for permission to access the user's location. If the user agrees to share
their location, the map zooms in on the user's location, and nearby coffee shops are
shown.

When you zoom in close enough in an area that has coffee shop locations, the clusters
separate into individual locations. Select one of the icons on the map or select an item
in the side panel to see a pop-up window. The pop-up shows information for the
selected location.

If you resize the browser window to fewer than 700 pixels wide or open the application
on a mobile device, the layout changes to be better suited for smaller screens.
In this tutorial, you learned how to create a basic store locator by using Azure Maps. The
store locator you create in this tutorial might have all the functionality you need. You
can add features to your store locator or use more advance features for a more custom
user experience:

Enable suggestions as you type in the search box.


Add support for multiple languages .
Allow the user to filter locations along a route .
Add the ability to set filters .
Add support to specify an initial search value by using a query string. When you
include this option in your store locator, users are then able to bookmark and
share searches. It also provides an easy method for you to pass searches to this
page from another page.
Deploy your store locator as an Azure App Service Web App.
Store your data in a database and search for nearby locations. To learn more, see
the SQL Server spatial data types overview and Query spatial data for the nearest
neighbor.

Additional information
For the completed code, see the Simple Store Locator tutorial on GitHub .
To view this sample live, see Simple Store Locator on the Azure Maps Code
Samples site.
learn more about the coverage and capabilities of Azure Maps by using Zoom
levels and tile grid.
You can also Use data-driven style expressions to apply to your business logic.

Next steps
To see more code examples and an interactive coding experience:

How to use the map control

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Route electric vehicles by using
Azure Notebooks (Python)
Article • 10/30/2024

Azure Maps is a portfolio of geospatial service APIs integrated into Azure, enabling
developers to create location-aware applications for various scenarios like IoT, mobility,
and asset tracking.

Azure Maps REST APIs support languages like Python and R for geospatial data analysis
and machine learning, offering robust routing APIs for calculating routes based on
conditions such as vehicle type or reachable area.

This tutorial guides users through routing electric vehicles using Azure Maps APIs along
with Jupyter Notebooks in VS Code and Python to find the closest charging station
when the battery is low.

In this tutorial, you will:

" Create and run a Jupyter Notebook in VS Code .


" Call Azure Maps REST APIs in Python.
" Search for a reachable range based on the electric vehicle's consumption model.
" Search for electric vehicle charging stations within the reachable range, or
isochrone.
" Render the reachable range boundary and charging stations on a map.
" Find and visualize a route to the closest electric vehicle charging station based on
drive time.

Prerequisites
An Azure Maps account
A subscription key
Visual Studio Code
A working knowledge of Jupyter Notebooks in VS Code
Environment set up to work with Python in Jupyter Notebooks. For more
information, see Setting up your environment .

7 Note
For more information on authentication in Azure Maps, see manage authentication
in Azure Maps.

Install project level packages


The EV Routing and Reachable Range project has dependencies on the aiohttp and
IPython python libraries. You can install these in the Visual Studio terminal using pip:

Python

pip install aiohttp


pip install ipython

Open Jupyter Notebook in Visual Studio Code


Download then open the Notebook used in this tutorial:

1. Open the file EVrouting.ipynb in the AzureMapsJupyterSamples repository in


GitHub.

2. Select the Download raw file button in the upper-right corner of the screen to
save the file locally.

3. Open the downloaded Notebook in Visual Studio Code by right-clicking on the file
then selecting Open with > Visual Studio Code, or through the VS Code File
Explorer.

Load the required modules and frameworks


Once your code is added, you can run a cell using the Run icon to the left of the cell and
the output is displayed below the code cell.

Run the following script to load all the required modules and frameworks.

Python
import time
import aiohttp
import urllib.parse
from IPython.display import Image, display

Request the reachable range boundary


A package delivery company operates a fleet that includes some electric vehicles. These
vehicles need to be recharged during the day without returning to the warehouse. When
the remaining charge drops below an hour, a search is conducted to find charging
stations within a reachable range. The boundary information for the range of these
charging stations is then obtained.

The requested routeType is eco to balance economy and speed. The following script
calls the Get Route Range API of the Azure Maps routing service, using parameters
related to the vehicle's consumption model. The script then parses the response to
create a polygon object in GeoJSON format, representing the car's maximum reachable
range.

Python

subscriptionKey = "Your Azure Maps key"


currentLocation = [34.028115,-118.5184279]
session = aiohttp.ClientSession()

# Parameters for the vehicle consumption model


travelMode = "car"
vehicleEngineType = "electric"
currentChargeInkWh=45
maxChargeInkWh=80
timeBudgetInSec=550
routeType="eco"
constantSpeedConsumptionInkWhPerHundredkm="50,8.2:130,21.3"

# Get boundaries for the electric vehicle's reachable range.


routeRangeResponse = await (await
session.get("https://atlas.microsoft.com/route/range/json?subscription-key=
{}&api-version=1.0&query={}&travelMode={}&vehicleEngineType=
{}&currentChargeInkWh={}&maxChargeInkWh={}&timeBudgetInSec={}&routeType=
{}&constantSpeedConsumptionInkWhPerHundredkm={}"

.format(subscriptionKey,str(currentLocation[0])+","+str(currentLocation[1]),
travelMode, vehicleEngineType, currentChargeInkWh, maxChargeInkWh,
timeBudgetInSec, routeType,
constantSpeedConsumptionInkWhPerHundredkm))).json()

polyBounds = routeRangeResponse["reachableRange"]["boundary"]

for i in range(len(polyBounds)):
coordList = list(polyBounds[i].values())
coordList[0], coordList[1] = coordList[1], coordList[0]
polyBounds[i] = coordList

polyBounds.pop()
polyBounds.append(polyBounds[0])

boundsData = {
"geometry": {
"type": "Polygon",
"coordinates":
[
polyBounds
]
}
}

Search for electric vehicle charging stations


within the reachable range
After determining the electric vehicle's reachable range (isochrone), you can search for
charging stations within that area.

The following script uses the Azure Maps Post Search Inside Geometry API to find
charging stations within the vehicle’s maximum reachable range. It then parses the
response into an array of reachable locations.

Python

# Search for electric vehicle stations within reachable range.


searchPolyResponse = await (await session.post(url =
"https://atlas.microsoft.com/search/geometry/json?subscription-key={}&api-
version=1.0&query=electric vehicle
station&idxSet=POI&limit=50".format(subscriptionKey), json =
boundsData)).json()

reachableLocations = []
for loc in range(len(searchPolyResponse["results"])):
location = list(searchPolyResponse["results"][loc]
["position"].values())
location[0], location[1] = location[1], location[0]
reachableLocations.append(location)

Render the charging stations and reachable


range on a map
Call the Azure Maps Get Map Image service to render the charging points and
maximum reachable boundary on the static map image by running the following script:

Python

# Get boundaries for the bounding box.


def getBounds(polyBounds):
maxLon = max(map(lambda x: x[0], polyBounds))
minLon = min(map(lambda x: x[0], polyBounds))

maxLat = max(map(lambda x: x[1], polyBounds))


minLat = min(map(lambda x: x[1], polyBounds))

# Buffer the bounding box by 10 percent to account for the pixel size of
pins at the ends of the route.
lonBuffer = (maxLon-minLon)*0.1
minLon -= lonBuffer
maxLon += lonBuffer

latBuffer = (maxLat-minLat)*0.1
minLat -= latBuffer
maxLat += latBuffer

return [minLon, maxLon, minLat, maxLat]

minLon, maxLon, minLat, maxLat = getBounds(polyBounds)


polyBoundsFormatted = ('|'.join(map(str,
polyBounds))).replace('[','').replace(']','').replace(',','')
reachableLocationsFormatted = ('|'.join(map(str,
reachableLocations))).replace('[','').replace(']','').replace(',','')

path = "lcff3333|lw3|la0.80|fa0.35||{}".format(polyBoundsFormatted)
pins = "custom|an15 53||{}||https://raw.githubusercontent.com/Azure-
Samples/AzureMapsCodeSamples/e3a684e7423075129a0857c63011e7cfdda213b7/Static
/images/icons/ev_pin.png".format(reachableLocationsFormatted)

encodedPins = urllib.parse.quote(pins, safe='')

# Render the range and electric vehicle charging points on the map.
staticMapResponse = await
session.get("https://atlas.microsoft.com/map/static/png?api-version=2022-08-
01&subscription-key={}&pins={}&path={}&bbox=
{}&zoom=12".format(subscriptionKey,encodedPins,path,str(minLon)+",
"+str(minLat)+", "+str(maxLon)+", "+str(maxLat)))

poiRangeMap = await staticMapResponse.content.read()

display(Image(poiRangeMap))

Find the optimal charging station


First, identify all the potential charging stations within the vehicle’s reachable range.
Next, determine which of these stations can be accessed in the shortest possible time.

The following script calls the Azure Maps Matrix Routing API. It returns the vehicle's
location, travel time, and distance to each charging station. The subsequent script parses
this response to identify the closest charging station that can be reached in the least
amount of time.

Python

locationData = {
"origins": {
"type": "MultiPoint",
"coordinates": [[currentLocation[1],currentLocation[0]]]
},
"destinations": {
"type": "MultiPoint",
"coordinates": reachableLocations
}
}
# Get the travel time and distance to each specified charging station.
searchPolyRes = await (await session.post(url =
"https://atlas.microsoft.com/route/matrix/json?subscription-key={}&api-
version=1.0&routeType=shortest&waitForResults=true".format(subscriptionKey),
json = locationData)).json()

distances = []
for dist in range(len(reachableLocations)):
distances.append(searchPolyRes["matrix"][0][dist]["response"]
["routeSummary"]["travelTimeInSeconds"])

minDistLoc = []
minDistIndex = distances.index(min(distances))
minDistLoc.extend([reachableLocations[minDistIndex][1],
reachableLocations[minDistIndex][0]])
closestChargeLoc = ",".join(str(i) for i in minDistLoc)

Calculate the route to the closest charging


station
After locating the nearest charging station, use the Get Route Directions API to obtain
detailed directions from the vehicles current location. Run the script in the next cell to
generate and parse a GeoJSON object representing the route.

Python

# Get the route from the electric vehicle's current location to the closest
charging station.
routeResponse = await (await
session.get("https://atlas.microsoft.com/route/directions/json?subscription-
key={}&api-version=1.0&query={}:{}".format(subscriptionKey,
str(currentLocation[0])+","+str(currentLocation[1]),
closestChargeLoc))).json()

route = []
for loc in range(len(routeResponse["routes"][0]["legs"][0]["points"])):
location = list(routeResponse["routes"][0]["legs"][0]
["points"][loc].values())
location[0], location[1] = location[1], location[0]
route.append(location)

routeData = {
"type": "LineString",
"coordinates": route
}

Visualize the route


To visualize the route, use the Get Map Image API to render it on the map.

Python

destination = route[-1]

#destination[1], destination[0] = destination[0], destination[1]

routeFormatted = ('|'.join(map(str,
route))).replace('[','').replace(']','').replace(',','')
path = "lc0f6dd9|lw6||{}".format(routeFormatted)
pins = "default|codb1818||{} {}|{}
{}".format(str(currentLocation[1]),str(currentLocation[0]),destination[0],de
stination[1])

# Get boundaries for the bounding box.


minLon, maxLon = (float(destination[0]),currentLocation[1]) if
float(destination[0])<currentLocation[1] else (currentLocation[1],
float(destination[0]))
minLat, maxLat = (float(destination[1]),currentLocation[0]) if
float(destination[1])<currentLocation[0] else (currentLocation[0],
float(destination[1]))

# Buffer the bounding box by 10 percent to account for the pixel size of
pins at the ends of the route.
lonBuffer = (maxLon-minLon)*0.1
minLon -= lonBuffer
maxLon += lonBuffer

latBuffer = (maxLat-minLat)*0.1
minLat -= latBuffer
maxLat += latBuffer

# Render the route on the map.


staticMapResponse = await
session.get("https://atlas.microsoft.com/map/static/png?api-version=2022-08-
01&subscription-key={}&&path={}&pins={}&bbox=
{}&zoom=16".format(subscriptionKey,path,pins,str(minLon)+", "+str(minLat)+",
"+str(maxLon)+", "+str(maxLat)))

staticMapImage = await staticMapResponse.content.read()

await session.close()
display(Image(staticMapImage))
In this tutorial, you learned how to call Azure Maps REST APIs directly and visualize
Azure Maps data by using Python.

For more information on the Azure Maps APIs used in this tutorial, see:

Get Route Directions


Get Route Range
Post Route Matrix
Post Search Inside Geometry
Render - Get Map Image

For a complete list of Azure Maps REST APIs, see Azure Maps REST APIs.

Next steps
Learn more about all the notebooks experiences from Microsoft and GitHub
Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Join sensor data with weather
forecast data by using Azure Notebooks
(Python)
Article • 10/30/2024

Wind power is one alternative energy source for fossil fuels to combat against climate
change. Because wind isn't consistent by nature, wind power operators need to build
machine learning (ML) models to predict the wind power capacity. This prediction is
necessary to meet electricity demand and ensure the grid stability. In this tutorial, we
walk through how Azure Maps weather forecast data is combined with demo data for
weather readings. Weather forecast data is requested by calling Azure Maps Weather
services.

In this tutorial, you will:

" Create and run a Jupyter Notebook in VS Code .


" Load demo data from file.
" Call Azure Maps REST APIs in Python.
" Render location data on the map.
" Enrich the demo data with Azure Maps Daily Forecast weather data.
" Plot forecast data in graphs.

7 Note

The Jupyter notebook file for this project can be downloaded from the Weather
Maps Jupyter Notebook repository .

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

An Azure Maps account


A subscription key
Visual Studio Code
A working knowledge of Jupyter Notebooks in VS Code
Environment set up to work with Python in Jupyter Notebooks. For more
information, see Setting up your environment .
7 Note

For more information on authentication in Azure Maps, see manage authentication


in Azure Maps.

Install project level packages


The EV Routing and Reachable Range project has dependencies on the aiohttp and
IPython python libraries. You can install these in the Visual Studio terminal using pip:

Python

pip install aiohttp


pip install ipython
pip install pandas

Open Jupyter Notebook in Visual Studio Code


Download then open the Notebook used in this tutorial:

1. Open the file weatherDataMaps.ipynb in the AzureMapsJupyterSamples


repository in GitHub.

2. Select the Download raw file button in the upper-right corner of the screen to
save the file locally.

3. Open the downloaded Notebook in Visual Studio Code by right-clicking on the file
then selecting Open with > Visual Studio Code, or through the VS Code File
Explorer.

Load the required modules and frameworks


Once your code is added, you can run a cell using the Run icon to the left of the cell and
the output is displayed below the code cell.

Run the following script to load all the required modules and frameworks.

Python

import aiohttp
import pandas as pd
import datetime
from IPython.display import Image, display

Import weather data


This tutorial uses weather data readings from sensors installed at four different wind
turbines. The sample data consists of 30 days of weather readings. These readings are
gathered from weather data centers near each turbine location. The demo data contains
data readings for temperature, wind speed and, direction. You can download the demo
data contained in weather_dataset_demo.csv from GitHub. The script below imports
demo data to the Azure Notebook.

Python

df = pd.read_csv("./data/weather_dataset_demo.csv")

Request daily forecast data


In our scenario, we would like to request daily forecast for each sensor location. The
following script calls the Daily Forecast API of the Azure Maps Weather services. This API
returns weather forecast for each wind turbine, for the next 15 days from the current
date.

Python

subscription_key = "Your Azure Maps key"

# Get a lists of unique station IDs and their coordinates


station_ids = pd.unique(df[['StationID']].values.ravel())
coords = pd.unique(df[['latitude','longitude']].values.ravel())

years,months,days = [],[],[]
dates_check=set()
wind_speeds, wind_direction = [], []

# Call azure maps Weather services to get daily forecast data for 15 days
from current date
session = aiohttp.ClientSession()
j=-1
for i in range(0, len(coords), 2):
wind_speeds.append([])
wind_direction.append([])

query = str(coords[i])+', '+str(coords[i+1])


forecast_response = await(await
session.get("https://atlas.microsoft.com/weather/forecast/daily/json?query=
{}&api-version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&duration=15".format(query, subscription_key))).json()
j+=1
for day in range(len(forecast_response['forecasts'])):
date = forecast_response['forecasts'][day]['date'][:10]
wind_speeds[j].append(forecast_response['forecasts'][day]['day']
['wind']['speed']['value'])
wind_direction[j].append(forecast_response['forecasts'][day]
['day']['windGust']['direction']['degrees'])

if date not in dates_check:


year,month,day= date.split('-')
years.append(year)
months.append(month)
days.append(day)
dates_check.add(date)

await session.close()

The following script renders the turbine locations on the map by calling the Get Map
Image service.

Python

# Render the turbine locations on the map by calling the Azure Maps Get Map
Image service
session = aiohttp.ClientSession()

pins="default|la-25+60|ls12|lc003C62|co9B2F15||'Location A'{} {}|'Location


B'{} {}|'Location C'{} {}|'Location D'{}
{}".format(coords[1],coords[0],coords[3],coords[2],coords[5],coords[4],
coords[7],coords[6])

image_response = "https://atlas.microsoft.com/map/static/png?subscription-
key={Your-Azure-Maps-Subscription-key}&api-
version=1.0&layer=basic&style=main&zoom=6&center={},{}&pins=
{}".format(subscription_key,coords[7],coords[6],pins)

static_map_response = await session.get(image_response)

poi_range_map = await static_map_response.content.read()

await session.close()

display(Image(poi_range_map))

Group the forecast data with the demo data based on the station ID. The station ID is
for the weather data center. This grouping augments the demo data with the forecast
data.

Python

# Group forecasted data for all locations


df = df.reset_index(drop=True)
forecast_data = pd.DataFrame(columns=
['StationID','latitude','longitude','Year','Month','Day','DryBulbCelsius','W
etBulbFarenheit','WetBulbCelsius','DewPointFarenheit','DewPointCelsius','Rel
ativeHumidity','WindSpeed','WindDirection'])

for i in range(len(station_ids)):
loc_forecast = pd.DataFrame({'StationID':station_ids[i],
'latitude':coords[0], 'longitude':coords[1], 'Year':years, 'Month':months,
'Day':days, 'WindSpeed':wind_speeds[i], 'WindDirection':wind_direction[i]})
forecast_data = pd.concat([forecast_data,loc_forecast], axis=0,
sort=False)

combined_weather_data = pd.concat([df,forecast_data])
grouped_weather_data = combined_weather_data.groupby(['StationID'])

The following table displays the combined historical and forecast data for one of the
turbine locations.

Python

# Display data for first location


grouped_weather_data.get_group(station_ids[0]).reset_index()

Plot forecast data


Plot the forecasted values against the days for which they're forecasted. This plot allows
us to see the speed and direction changes of the wind for the next 15 days.

Python

# Plot wind speed


curr_date = datetime.datetime.now().date()
windsPlot_df = pd.DataFrame({ 'Location A': wind_speeds[0], 'Location B':
wind_speeds[1], 'Location C': wind_speeds[2], 'Location D': wind_speeds[3]},
index=pd.date_range(curr_date,periods=15))
windsPlot = windsPlot_df.plot.line()
windsPlot.set_xlabel("Date")
windsPlot.set_ylabel("Wind speed")

Python

#Plot wind direction


windsPlot_df = pd.DataFrame({ 'Location A': wind_direction[0], 'Location B':
wind_direction[1], 'Location C': wind_direction[2], 'Location D':
wind_direction[3]}, index=pd.date_range(curr_date,periods=15))
windsPlot = windsPlot_df.plot.line()
windsPlot.set_xlabel("Date")
windsPlot.set_ylabel("Wind direction")

The following graphs visualize the forecast data. For the change of wind speed, see the
left graph. For change in wind direction, see the right graph. This data is prediction for
next 15 days from the day the data is requested.
In this tutorial, you learned how to call Azure Maps REST APIs to get weather forecast
data. You also learned how to visualize the data on graphs.

To explore the Azure Maps APIs that are used in this tutorial, see:

Daily Forecast
Render - Get Map Image

For a complete list of Azure Maps REST APIs, see Azure Maps REST APIs.

Next steps
Learn more about all the notebooks experiences from Microsoft and GitHub

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Analyze trip using Snap to
Roads in Microsoft Fabric notebook
Article • 11/19/2024

Snap to Roads is an Azure Maps service that processes a set of GPS points collected
along a route and snaps them to the most probable roads the vehicle traveled. This
feature is useful in determining the exact path followed by a vehicle, even when the GPS
data collected is off slightly.

This tutorial explains how to use Azure Maps Snap to Roads API with Microsoft Fabric to
analyze GPS data from moving assets, even when the data is inaccurate or incomplete
due to signal loss. It walks you through making calls to the Azure Maps Snap to Roads
API from a Microsoft Fabric notebook to snap the GPS points to the nearest road, fill
missing points using interpolated data points and enhance them with additional
attributes such as road names and speed limits.

In this tutorial, you will:

" Create a Microsoft Fabric Lakehouse and import a vechicle's raw GPS data into it.
" Create a Microsoft Fabric notebook that takes raw GPS data and returns the
requested snapped coordinate information using the Azure Maps Snap to Roads
API.
" Create an eventhouse and KQL database and import the snapped GPS data into it.
" Create a Real-Time Dashboard using the snapped GPS data in the Kusto Database.
" Query KQL data and display the snapped GPS data in a Map Visual.

Prerequisites
An Azure Maps account
A subscription key
A Microsoft Fabric account
Basic understanding of Microsoft Fabric .

7 Note

For more information on authentication in Azure Maps, see manage authentication


in Azure Maps.
Create a Microsoft Fabric notebook and
lakehouse
Follow these steps to create a Microsoft Fabric notebook:

1. Go to your My Workspace and select New item.

2. When the New item screen appears, scroll down and select Notebook.

3. In the notebook Explorer screen, select the Lakehouses arrow >.


4. Select the Add button.

5. In the Add lakehouse dialog, select New Lakehouse then the Add button.

6. In the New lakehouse dialog, enter a name "Azure_Maps_Data" then select the
Create button.

Add a data file to the lakehouse


Snap to Roads takes GPS point data (lat, lon), and returns a list of objects that form a
route snapped to the roads on a map. A data file containing the required GPS data can
be added as a file to the lakehouse and referenced by the python code in your
notebook.

Download data file


Download the sample data (mockData_20240919.csv) from GitHub to your local storage
device to upload into lakehouse in the next section. This file contains an array of GPS
coordinates that the Snap to Roads service modifies as needed to ensure that each
coordinate points to a valid road.

1. Open the file mockData_20240919.csv in GitHub.

2. Select the Download raw file button in the upper-right corner of the screen and
save the file locally.

Upload data file into lakehouse


The following steps explain how to add a data source to lakehouse.

1. From the Files folder in lakehouse, select Upload > Upload files.

2. Bring up the file open dialog by selecting the folder icon. Select the
mockData_20240919.csv file you downloaded in the previous section then the
Open button. Once the file open dialog box closes and the correct filename
appears in the Upload files control, select the Upload button to upload the file
into lakehouse.

Add code to notebook


You need to add and execute four cells of code into your notebook to perform the Snap
to Roads scenario. The following sections walk you through this.

Install packages
You first need to load the required packages:

Python

!pip install geopandas


!pip install geojson

Enter the pip install statements into the first cell of your notebook, then execute the
statements by selecting the run arrow.

Load data
Next, load the sample data you previously uploaded into your lakehouse.

1. Hover your pointer just below the cell used to install the packages. Options appear
to add code or markdown. Select Code to add another code cell to your notebook.

2. Once the new cell is created, add the following code.

Python

import geopandas as gpd


import pandas as pd

lakehouseFilePath = "/lakehouse/default/Files/"

mockdata_df = gpd.read_file(lakehouseFilePath +
"mockData_20240919.csv")
mockdata_df = gpd.GeoDataFrame(
mockdata_df, geometry=gpd.points_from_xy(mockdata_df.longitude,
mockdata_df.latitude), crs="EPSG:4326"
)

mockdata_df.head()

mockdata_df.tripID.unique()

3. Execute the code by selecting the run arrow. This loads your sample data.

Enhance with Snap to Roads


The code in this notebook cell reads raw GPS data from the data file in lakehouse and
passes it to the Azure Maps Snap to Road API. With interpolation enabled, the API adds
points between GPS locations to complete the route path along the road. It also
provides attributes like road names and speed limits when available.

1. Hover your pointer just below the cell used to install the packages in the previous
step. Options appear to add code or markdown. Select Code to add another code
cell to your notebook.

2. Once the new cell is created, add the following code. Make sure you add your
subscription key.

Python

import requests
import json

az_maps_subkey = ""
az_maps_snaproads_url = "https://atlas.microsoft.com/route/snapToRoads?
api-version=2024-07-01-preview&subscription-key=" + az_maps_subkey

# Function to process snap to road for each given trip


def process_route(df, outputFilePath):
# List to store successful responses
successful_responses = []

# Function to send a chunk of features


def send_chunk_snaproads(chunk):
geojson_data = chunk.to_json()
# Convert the JSON string to a Python dictionary
geojson_dict = json.loads(geojson_data)

# Add the new fields at the end of the dictionary


geojson_dict['includeSpeedLimit'] = True
geojson_dict['interpolate'] = True
geojson_dict['travelMode'] = "driving"

# Convert the dictionary back to a JSON string


updated_geojson_data = json.dumps(geojson_dict)

response = requests.post(
az_maps_snaproads_url,
headers={'Content-Type': 'application/json'},
data=updated_geojson_data
)

if response.status_code == 200:
print('Chunk request was successful...')
successful_responses.append(response.json())
else:
print(f'Failed to send request. Status code:
{response.status_code}')
print('Response body:', response.text)

# Loop over the GeoDataFrame in chunks of 100


chunk_size = 100
for start in range(0, len(df), chunk_size):
end = start + chunk_size
chunk = df.iloc[start:end]
send_chunk_snaproads(chunk)

# Extract features with geometry from successful responses


features_with_geometry = []
for response in successful_responses:
if 'features' in response:
for feature in response['features']:
if 'geometry' in feature:
longitude = feature['geometry']['coordinates'][0]
latitude = feature['geometry']['coordinates'][1]
feature['properties']['latitude'] = latitude
feature['properties']['longitude'] = longitude
features_with_geometry.append(feature)

# Convert the list of features with geometry to a GeoDataFrame


if features_with_geometry:
responses_gdf =
gpd.GeoDataFrame.from_features(features_with_geometry)

# Write successful responses to a cvs file


#responses_gdf.to_file(outputFilePath, driver='GeoJSON')
responses_gdf.to_csv(outputFilePath, encoding='utf-8',
index=False)

print(f'Successful responses written to {outputFilePath}')


else:
print('No valid features with geometry found in the
responses.')

3. Execute the code by selecting the run arrow.


Create file with enhanced data
The following code takes the output created in the previous code cell and creates a new
CSV file in the lakehouse named SnapRoadResponses.csv. This new data file contains
updated GPS coordinates that are aligned with the appropriate road, it also includes
street names and speed limits when available. SnapRoadResponses.csv will be imported
into an eventhouse and used to create a map visual later in this tutorial.

1. Hover your pointer just below the cell used to Enhance with Snap to Roads in the
previous step. Options appear to add code or markdown. Select Code to add
another code cell to your notebook.

2. Once the new cell is created, add the following code.

Python

lakehouseFilePath = "/lakehouse/default/Files/"
#execute snap to road
outputFilePath = lakehouseFilePath + "SnapRoadResponses" + ".csv"
df = mockdata_df.sort_values(by='timeStamp').reset_index(drop=True)
process_route(df, outputFilePath)

3. Execute the code by selecting the run arrow. This saves SnapRoadResponses.csv
with updated GPS coordinates to the lakehouse.

 Tip

If the new file does not appear after running the notebook code, you may need to
refresh your browser.

Copy file path


The ABFS path to SnapRoadResponses.csv is required later in this tutorial when you
create the eventhouse. To get the ABFS path to this file, select the ellipse (...) next to the
file, then from the popup menu, select Copy ABFS Path. Once copied, save it for later.

Create eventhouse and link to data in


lakehouse
Create an eventhouse to manage the telemetry data for your fleet or moving assets. A
KQL database is created automatically by default. In this tutorial, you'll import the
snapped data from the lake house into the KQL database. For real-time analytics, add
streaming data. Once the data is uploaded, you can query your data using Kusto Query
Language in a KQL queryset.

1. Go to your My Workspace and select New item.

2. When the New item screen appears, scroll down and select Eventhouse.

3. In the New Eventhouse screen, enter a name for your new eventhouse, such as
SnapToRoadDemo.

Next, link the lakehouse you created previously to your new eventhouse.

4. Select the ellipse next to your new eventhouse, then Get data > OneLake from the
popup menu.

5. Select New table, name it GPSData then select Next.

6. Enter the ABFS path to the Lakehouse data file (SnapRoadResponses.csv) in the
OneLake file control that you saved previously, then select the plus sign (+) to add
it to the list.

7. Select Next.

8. After verifying the data in the Inspect the data screen, select Finish.

9. Select Close to close Summary page.


The eventhouse should now be created and contain the GPS data.

Create Real-Time Dashboard


A Real-Time Dashboard can be created to connect to your dataset in the eventhouse.
The input in this tutorial is static data, not a real-time stream, but the tiles in the
dashboard, such as Azure Maps Visual, can be used for visual representation and
analytics.
Add data source
1. Go to your My Workspace and select New item.

2. When the New item screen appears, search for, or scroll down and select Real-
Time Dashboard.

3. In the New Real-Time Dashboard screen, enter the name SnapToRoadDashboard,


then select Create.

4. In the new Real-Time Dashboard screen, select New data source.

5. Select the Add button, then select OneLake data hub.

6. Select your data source, then Connect.

7. Enter a Display name then select Add.


8. Close the Data sources panel.

Now that you have added the datasource for your real-time dashboard, you can add a
query and map visual.

Add query and map visual


1. Select Add tile.

2. Enter GPSData in the query then select Run. Once you verified that the query
works, select Add visual.

3. In the Visual formatting panel, select Map from the Visual type drop-down.

4. Next, set your values in the Data section:

ノ Expand table

Data setting value

Define by location Latitude and longitude

Latitude column latitude (real)

Longitude column longitude (real)

5. Update the map info card by selecting a value from the Label column drop-down.
Select SpeedLimitInKilometersPerHour.

6. Select Apply changes

Your map visual appears. You can select any point on the map to get the coordinates
and Speed Limit In Kilometers Per Hour for that location.

Next steps
To learn more about Microsoft Fabric notebooks:

How to use Microsoft Fabric notebooks

This tutorial created a dashboard for post trip route analysis. For a step-by-step guide to
building real-time dashboards in Microsoft Fabric:

Real-Time Intelligence

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Authentication with Azure Maps
Article • 10/12/2023

Azure Maps supports three ways to authenticate requests: Shared Key authentication,
[Microsoft Entra ID] authentication, and Shared Access Signature (SAS) Token
authentication. This article explains authentication methods to help guide your
implementation of Azure Maps services. The article also describes other account
controls such as disabling local authentication for Azure Policy and Cross-Origin
Resource Sharing (CORS).

7 Note

To improve secure communication with Azure Maps, we now support Transport


Layer Security (TLS) 1.2, and we're retiring support for TLS 1.0 and 1.1. If you
currently use TLS 1.x, evaluate your TLS 1.2 readiness and develop a migration plan
with the testing described in Solving the TLS 1.0 Problem.

Shared Key authentication


For information about viewing your keys in the Azure portal, see View authentication
details.

Primary and secondary keys are generated after the Azure Maps account is created.
You're encouraged to use the primary key as the subscription key when calling Azure
Maps with shared key authentication. Shared Key authentication passes a key generated
by an Azure Maps account to an Azure Maps service. For each request to Azure Maps
services, add the subscription key as a parameter to the URL. The secondary key can be
used in scenarios like rolling key changes.

Example using the subscription key as a parameter in your URL:

HTTP

https://atlas.microsoft.com/mapData/upload?api-
version=1.0&dataFormat=zip&subscription-key={Your-Azure-Maps-Subscription-
key}

) Important
Primary and Secondary keys should be treated as sensitive data. The shared key is
used to authenticate all Azure Maps REST API. Users who use a shared key should
abstract the API key away, either through environment variables or secure secret
storage, where it can be managed centrally.

Microsoft Entra authentication


Azure Subscriptions are provided with a Microsoft Entra tenant to enable fine grained
access control. Azure Maps offers authentication for Azure Maps services using
Microsoft Entra ID. Microsoft Entra ID provides identity-based authentication for users
and applications registered in the Microsoft Entra tenant.

Azure Maps accepts OAuth 2.0 access tokens for Microsoft Entra tenants associated
with an Azure subscription that contains an Azure Maps account. Azure Maps also
accepts tokens for:

Microsoft Entra users


Partner applications that use permissions delegated by users
Managed identities for Azure resources

Azure Maps generates a unique identifier (client ID) for each Azure Maps account. You
can request tokens from Microsoft Entra ID when you combine this client ID with other
parameters.

For more information about how to configure Microsoft Entra ID and request tokens for
Azure Maps, see Manage authentication in Azure Maps.

For general information about authenticating with Microsoft Entra ID, see
Authentication vs. authorization.

Managed identities for Azure resources and


Azure Maps
Managed identities for Azure resources provide Azure services with an automatically
managed application based security principal that can authenticate with Microsoft Entra
ID. With Azure role-based access control (Azure RBAC), the managed identity security
principal can be authorized to access Azure Maps services. Some examples of managed
identities include: Azure App Service, Azure Functions, and Azure Virtual Machines. For a
list of managed identities, see Azure services that can use managed identities to access
other services. For more information on managed identities, see Manage authentication
in Azure Maps.
Configure application Microsoft Entra authentication
Applications authenticate with the Microsoft Entra tenant using one or more supported
scenarios provided by Microsoft Entra ID. Each Microsoft Entra application scenario
represents different requirements based on business needs. Some applications may
require user sign-in experiences and other applications may require an application sign-
in experience. For more information, see Authentication flows and application scenarios.

After the application receives an access token, the SDK and/or application sends an
HTTPS request with the following set of required HTTP headers in addition to other
REST API HTTP headers:

Header Name Value

x-ms-client-id 30d7cc…9f55

Authorization Bearer eyJ0e…HNIVN

7 Note

x-ms-client-id is the Azure Maps account-based GUID that appears on the Azure

Maps authentication page.

Here's an example of an Azure Maps route request that uses a Microsoft Entra ID OAuth
Bearer token:

HTTP

GET /route/directions/json?api-
version=1.0&query=52.50931,13.42936:52.50274,13.43872
Host: atlas.microsoft.com
x-ms-client-id: 30d7cc….9f55
Authorization: Bearer eyJ0e…HNIVN

For information about viewing your client ID, see View authentication details.

 Tip

Getting the Client ID programmatically

When using PowerShell, the Client ID is stored as the UniqueId Property in the
IMapsAccount object. You retrieve this property using Get-AzMapsAccount , for

example:
PowerShell

$maps = Get-AzMapsAccount -Name {Azure-Maps_Account-Name} -


ResourceGroupName {Resource-Group-Name} -SubscriptionId
{SubscriptionId}
$ClientId = $maps.UniqueId

When using the Azure CLI use the az maps account show command with the --
query parameter, for example:

Azure CLI

$ClientId = az maps account show --name {Azure-Maps_Account-Name} --


resource-group {Resource-Group-Name} --subscription {SubscriptionId} --
query properties.uniqueId

Authorization with role-based access control

Prerequisites
If you're new to Azure RBAC, Azure role-based access control (Azure RBAC) overview
provides Principal types are granted a set of permissions, also known as a role definition.
A role definition provides permissions to REST API actions. Azure Maps supports access
to all principal types for Azure role-based access control (Azure RBAC) including:
individual Microsoft Entra users, groups, applications, Azure resources, and Azure
managed identities. Applying access to one or more Azure Maps accounts is known as a
scope. A role assignment is created when a principal, role definition, and scope are
applied.

Overview
The next sections discuss concepts and components of Azure Maps integration with
Azure RBAC. As part of the process to set up your Azure Maps account, a Microsoft
Entra directory is associated to the Azure subscription, which the Azure Maps account
resides.

When you configure Azure RBAC, you choose a security principal and apply it to a role
assignment. To learn how to add role assignments on the Azure portal, see Assign Azure
roles using the Azure portal.
Picking a role definition
The following role definition types exist to support application scenarios.

Azure Role Definition Description

Azure Maps Search and Provides access to only search and render Azure Maps REST APIs
Render Data Reader to limit access to basic web browser use cases.

Azure Maps Data Reader Provides access to immutable Azure Maps REST APIs.

Azure Maps Data Provides access to mutable Azure Maps REST APIs. Mutability,
Contributor defined by the actions: write and delete.

Azure Maps Data Read and This role can be used to assign read and batch actions on Azure
Batch Role Maps.

Custom Role Definition Create a crafted role to enable flexible restricted access to Azure
Maps REST APIs.

Some Azure Maps services may require elevated privileges to perform write or delete
actions on Azure Maps REST APIs. Azure Maps Data Contributor role is required for
services, which provide write or delete actions. The following table describes what
services Azure Maps Data Contributor is applicable when using write or delete actions.
When only read actions are required, the Azure Maps Data Reader role can be used in
place of the Azure Maps Data Contributor role.

Azure Maps service Azure Maps Role Definition

Data Azure Maps Data Contributor

Creator Azure Maps Data Contributor

Spatial Azure Maps Data Contributor

Batch Search and Route Azure Maps Data Contributor

For information about viewing your Azure RBAC settings, see How to configure Azure
RBAC for Azure Maps.

Custom role definitions

One aspect of application security is the principle of least privilege, the practice of
limiting access rights to the rights required for the current job. Limiting access rights is
accomplished by creating custom role definitions that support use cases requiring
further granularity to access control. To create a custom role definition, select specific
data actions to include or exclude for the definition.

The custom role definition can then be used in a role assignment for any security
principal. To learn more about Azure custom role definitions, see Azure custom roles.

Here are some example scenarios where custom roles can improve application security.

Scenario Custom Role Data Action(s)

A public facing or interactive sign- Microsoft.Maps/accounts/services/render/read


in web page with base map tiles
and no other REST APIs.

An application, which only requires Microsoft.Maps/accounts/services/search/read


reverse geocoding and no other
REST APIs.

A role for a security principal, which Microsoft.Maps/accounts/services/data/read ,


requests a reading of Azure Maps Microsoft.Maps/accounts/services/render/read
Creator based map data and base
map tile REST APIs.

A role for a security principal, which Microsoft.Maps/accounts/services/data/read ,


requires reading, writing, and Microsoft.Maps/accounts/services/data/write ,
deleting of Creator based map Microsoft.Maps/accounts/services/data/delete
data. Defined as a map data editor
role that doesn't allow access to
other REST API like base map tiles.

Understand scope
When creating a role assignment, it's defined within the Azure resource hierarchy. The
top of the hierarchy is a management group and the lowest is an Azure resource, like an
Azure Maps account. Assigning a role assignment to a resource group can enable access
to multiple Azure Maps accounts or resources in the group.

 Tip

Microsoft's general recommendation is to assign access to the Azure Maps account


scope because it prevents unintended access to other Azure Maps accounts
existing in the same Azure subscription.

Disable local authentication


Azure Maps accounts support the standard Azure property in the Management API for
Microsoft.Maps/accounts called disableLocalAuth . When true , all authentication to the

Azure Maps data-plane REST API is disabled, except [Microsoft Entra authentication].
This is configured using Azure Policy to control distribution and management of shared
keys and SAS tokens. For more information, see What is Azure Policy?.

Disabling local authentication doesn't take effect immediately. Allow a few minutes for
the service to block future authentication requests. To re-enable local authentication, set
the property to false and after a few minutes local authentication resumes.

JSON

{
// omitted other properties for brevity.
"properties": {
"disableLocalAuth": true
}
}

Shared access signature token authentication


Shared access signature (SAS) tokens are authentication tokens created using the JSON
Web token (JWT) format and are cryptographically signed to prove authentication for an
application to the Azure Maps REST API. A SAS token, created by integrating a user-
assigned managed identity with an Azure Maps account in your Azure subscription. The
user-assigned managed identity is given authorization to the Azure Maps account
through Azure RBAC using either built-in or custom role definitions.

Functional key differences of SAS token from Microsoft Entra access tokens:

Lifetime of a token for a max expiration of one day (24 hours).


Azure location and geography access control per token.
Rate limits per token for an approximate of 1 to 500 requests per second.
Private keys of the token are the primary and secondary keys of an Azure Maps
account resource.
Service Principal object for authorization is supplied by a user-assigned managed
identity.

SAS tokens are immutable. This means that once a token is created, the SAS token is
valid until the expiry has been met and the configuration of the allowed regions, rate
limits, and user-assigned managed identity can't be changed. Read more below on
understanding access control for SAS token revocation and changes to access control.
Understand SAS token rate limits

SAS token maximum rate limit can control billing for an Azure
Maps resource

When specifying a maximum rate limit on the token ( maxRatePerSecond ), the excess rates
aren't billed to the account allowing you to set an upper limit of billable transactions for
the account, when using the token. However, the application receives client error
responses with 429 (TooManyRequests) for all transactions once that limit it reached. It's
the responsibility of the application to manage retry and distribution of SAS tokens.
There's no limit on how many SAS tokens can be created for an account. To allow for an
increase or decrease in an existing token's limit; a new SAS token must be created. The
old SAS token is still valid until its expiration.

Estimated Example:

Approximate Maximum Actual Rate Per Duration of sustained Total billable


Rate Per Second Second rate in seconds transactions

10 20 600 6,000

Actual rate limits vary based on Azure Maps ability to enforce consistency within a span
of time. However, this allows for preventive control of billing cost.

Rate limits are enforced per Azure location, not globally or


geographically
For example, a single SAS token with a maxRatePerSecond of 10 can be used to limit the
throughput in the East US location. If that same token is used in West US 2 , a new
counter is created to limit the throughput to 10 in that location, independent of the
East US location. To control costs and improve predictability, we recommend:

1. Create SAS tokens with designated allowed Azure locations for targeted
geography. Continue reading to understand creating SAS tokens.
2. Use geographic data-plane REST API endpoints, https://us.atlas.microsoft.com
or https://eu.atlas.microsoft.com .

Consider the application topology where the endpoint https://us.atlas.microsoft.com


routes to the same US locations that the Azure Maps services are hosted, such as East
US , West Central US , or West US 2 . The same idea applies to other geographical

endpoints such as https://eu.atlas.microsoft.com between West Europe and North


Europe . To prevent unexpected authorization denials, use a SAS token that uses the

same Azure locations that the application consumes. The endpoint location is defined
using the Azure Maps Management REST API.

Default rate limits take precedent over SAS token rate limits
As described in Azure Maps rate limits, individual service offerings have varying rate
limits that are enforced as an aggregate of the account.

Consider the case of Search service - Non-Batch Reverse, with its limit of 250 queries
per second (QPS) for the following tables. Each table represents estimated total
successful transactions from example usage.

The first table shows one token that has a maximum request per second of 500, and
actual usage of the application is 500 request per second for a duration of 60 seconds.
Search service - Non-Batch Reverse has a rate limit of 250, meaning of the total 30,000
requests made in the 60 seconds; 15,000 of those requests are billable transactions. The
remaining requests result in status code 429 (TooManyRequests) .

Name Approximate Actual Rate Duration of Approximate total


Maximum Rate Per Per Second sustained rate in successful
Second seconds transactions

token 500 500 60 ~15,000

For example, if two SAS tokens are created in, and use the same location as an Azure
Maps account, each token now shares the default rate limit of 250 QPS. If each token is
used at the same time with the same throughput token 1 and token 2 would
successfully grant 7500 successful transactions each.

Name Approximate Actual Rate Duration of Approximate total


Maximum Rate Per Per Second sustained rate in successful
Second seconds transactions

token 250 250 60 ~7500


1

token 250 250 60 ~7500


2

Understand SAS token access control


SAS tokens use RBAC to control access to the REST API. When you create a SAS token,
the prerequisite managed identity on the Map Account is assigned an Azure RBAC role
that grants access to specific REST API actions. See Picking a role definition to determine
which APIs the application allows.

If you want to assign temporary access and remove access for before the SAS token
expires, revoke the token. Other reasons to revoke access may be if the token is
distributed with Azure Maps Data Contributor role assignment unintentionally and
anyone with the SAS token may be able to read and write data to Azure Maps REST APIs
that may expose sensitive data or unexpected financial cost from usage.

there are two options to revoke access for SAS token(s):

1. Regenerate the key that was used by the SAS token or secondaryKey of the map
account.
2. Remove the role assignment for the managed identity on the associated map
account.

2 Warning

Deleting a managed identity used by a SAS token or revoking access control of the
managed identity will cause instances of your application using the SAS token and
managed identity to intentionally return 401 Unauthorized or 403 Forbidden from
Azure Maps REST APIs which will create application disruption.

To avoid disruption:

1. Add a second managed identity to the Map Account and grant the new
managed identity the correct role assignment.
2. Create a SAS token using secondaryKey , or a different managed identity than
the previous one, as the signingKey and distribute the new SAS token to the
application.
3. Regenerate the primary key, remove the managed identity from the account,
and remove the role assignment for the managed identity.

Create SAS tokens


To create SAS tokens, you must have Contributor role access to both manage Azure
Maps accounts and user-assigned identities in the Azure subscription.

) Important
Existing Azure Maps accounts created in the Azure location global don't support
managed identities.

First, you should Create a user-assigned managed identity in the same location as the
Azure Maps account.

 Tip

You should use the same location for both the managed identity and the Azure
Maps account.

Once a managed identity is created, you can create or update the Azure Maps account
and attach it. For more information, see Manage your Azure Maps account.

Once the account is successfully created or updated with the managed identity; assign
role-based access control for the managed identity to an Azure Maps data role at the
account scope. This enables the managed identity to be given access to the Azure Maps
REST API for your map account.

Next, create a SAS token using the Azure Management SDK tooling, List SAS operation
on Account Management API, or the Azure portal Shared Access Signature page of the
Map account resource.

SAS token parameters:

Parameter Name Example Value Description

signingKey primaryKey Required, the string enum value for the signingKey
either primaryKey , secondaryKey or managed
identity is used to create the signature of the SAS.

principalId <GUID> Required, the principalId is the Object (principal)


ID of the user-assigned managed identity attached
to the map account.

regions [ "eastus", Optional, the default value is null . The regions


"westus2", control which regions the SAS token can be used
"westcentralus" ] in the Azure Maps REST data-plane API. Omitting
regions parameter allows the SAS token to be
used without any constraints. When used in
combination with an Azure Maps data-plane
geographic endpoint like us.atlas.microsoft.com
and eu.atlas.microsoft.com allows the application
to control usage with-in the specified geography.
Parameter Name Example Value Description

This allows prevention of usage in other


geographies.

maxRatePerSecond 500 Required, the specified approximate maximum


request per second which the SAS token is
granted. Once the limit is reached, more
throughput is rate limited with HTTP status code
429 (TooManyRequests) .

start 2021-05- Required, a UTC date that specifies the date and
24T10:42:03.1567373Z time the token becomes active.

expiry 2021-05- Required, a UTC date that specifies the date and
24T11:42:03.1567373Z time the token expires. The duration between start
and expiry can't be more than 24 hours.

Configuring application with SAS token


After the application receives a SAS token, the Azure Maps SDK and/or applications
send an HTTPS request with the following required HTTP header in addition to other
REST API HTTP headers:

Header Name Value

Authorization jwt-sas eyJ0e….HNIVN

7 Note

jwt-sas is the authentication scheme to denote using SAS token. Do not include

x-ms-client-id or other Authorization headers or subscription-key query string

parameter.

Cross origin resource sharing (CORS)


CORS is an HTTP protocol that enables a web application running under one domain
to access resources in another domain. Web browsers implement a security restriction
known as same-origin policy that prevents a web page from calling APIs in a different
domain; CORS provides a secure way to allow one domain (the origin domain) to call
APIs in another domain. Using the Azure Maps account resource, you can configure
which origins are allowed to access the Azure Maps REST API from your applications.
) Important

CORS is not an authorization mechanism. Any request made to a map account


using REST API, when CORS is enabled, also needs a valid map account
authentication scheme such as Shared Key, Microsoft Entra ID, or SAS token.

CORS is supported for all map account pricing tiers, data-plane endpoints, and
locations.

Prerequisites
To prevent malicious code execution on the client, modern browsers block requests
from web applications to resources running in a separate domain.

If you're unfamiliar with CORS, see Cross-origin resource sharing (CORS) , it lets
an Access-Control-Allow-Origin header declare which origins are allowed to call
endpoints of an Azure Maps account. CORS protocol isn't specific to Azure Maps.

CORS requests
A CORS request from an origin domain may consist of two separate requests:

A preflight request, which queries the CORS restrictions imposed by the service.
The preflight request is required unless the request is standard method GET, HEAD,
POST, or requests that contain Authorization request header.

The actual request, made against the desired resource.

Preflight request
The preflight request is done not only as a security measure to ensure that the server
understands the method and headers that are sent in the actual request and that the
server knows and trusts the source of the request, but it also queries the CORS
restrictions that have been established for the map account. The web browser (or other
user agent) sends an OPTIONS request that includes the request headers, method and
origin domain. The map account service tries to fetch any CORS rules if account
authentication is possible through the CORS preflight protocol.

If authentication isn't possible, the maps service evaluates a preconfigured set of CORS
rules that specify which origin domains, request methods, and request headers may be
specified on an actual request against the maps service. By default, a maps account is
configured to allow all origins to enable seamless integration into web browsers.

The service responds to the preflight request with the required Access-Control headers
if the following criteria are met:

1. The OPTIONS request contains the required CORS headers (the Origin and Access-
Control-Request-Method headers)
2. Authentication was successful and A CORS rule is enabled for the account that
matches the preflight request.
3. Authentication was skipped due to required Authorization request headers that
can't be specified on preflight request.

When preflight request is successful, the service responds with status code 200 (OK) ,
and includes the required Access-Control headers in the response.

The service rejects preflight requests if the following conditions occur:

1. If the OPTIONS request doesn’t contain the required CORS headers (the Origin and
Access-Control-Request-Method headers), the service responds with status code
400 (Bad request) .

2. If authentication was successful on preflight request and no CORS rule matches the
preflight request, the service responds with status code 403 (Forbidden) . This may
occur if the CORS rule is configured to accept an origin that doesn't match the
current browser client origin request header.

7 Note

A preflight request is evaluated against the service and not against the requested
resource. The account owner must have enabled CORS by setting the appropriate
account properties in order for the request to succeed.

Actual request
Once the preflight request is accepted and the response is returned, the browser
dispatches the actual request against the map service. The browser denies the actual
request immediately if the preflight request is rejected.

The actual request is treated as a normal request against the map service. The presence
of the Origin header indicates that the request is a CORS request and the service then
validates against the CORS rules. If a match is found, the Access-Control headers are
added to the response and sent back to the client. If a match isn't found, the response
returns a 403 (Forbidden) indicating a CORS origin error.

Enable CORS policy


When a Map account is created or updated, its properties specify the allowed origins to
be configured. You can set a CORS rule on the Azure Maps account properties through
Azure Maps Management SDK, Azure Maps Management REST API, and portal. Once
you set the CORS rule for the service, then a properly authorized request made to the
service from a different domain are evaluated to determine whether it's allowed
according to the rule you've specified. For example:

JSON

{
"location": "eastus",
"sku": {
"name": "G2"
},
"kind": "Gen2",
"properties": {
"cors": {
"corsRules": [
{
"allowedOrigins": [
"https://www.azure.com",
"https://www.microsoft.com"
]
}
]
}
}
}

Only one CORS rule with its list of allowed origins can be specified. Each origin allows
the HTTP request to be made to Azure Maps REST API in the web browser of the
specified origin.

Remove CORS policy


You can remove CORS:

Manually in the Azure portal


Programmatically using:
The Azure Maps SDK
Azure Maps management REST API
An ARM template

 Tip

If you use the Azure Maps management REST API , use PUT or PATCH with an empty
corsRule list in the request body.

JSON

{
"location": "eastus",
"sku": {
"name": "G2"
},
"kind": "Gen2",
"properties": {
"cors": {
"corsRules": []
}
}
}
}

Understand billing transactions


Azure Maps doesn't count billing transactions for:

5xx HTTP Status Codes


401 (Unauthorized)
403 (Forbidden)
408 (Timeout)
429 (TooManyRequests)
CORS preflight requests

For more information on billing transactions and other Azure Maps pricing information,
see Azure Maps pricing .

Next steps
To learn more about security best practices, see:

Authentication and authorization best practices


To learn more about authenticating an application with Microsoft Entra ID and Azure
Maps, see:

Manage authentication in Azure Maps

To learn more about authenticating the Azure Maps Control with Microsoft Entra ID, see:

Use the Azure Maps Map Control


Authentication best practices
Article • 05/02/2025

The security of your application is crucial. Regardless of how excellent the user experience is, an
insecure application can be compromised by hackers, undermining its integrity and
deteriorating user trust.

This article contains tips to ensure the security of your Azure Maps application. When using
Azure, it's important to familiarize yourself with the available security tools. For more
information, See Introduction to Azure security in the Azure security documentation.

Understanding security threats


If hackers gain access to your account, they could potentially execute unlimited billable
transactions, leading to unexpected costs and reduced performance due to QPS limits.

To implement best practices for securing your Azure Maps applications, it's essential to
understand the various authentication options available.

Authentication best practices in Azure Maps


When developing publicly facing client applications with Azure Maps, it's crucial to ensure that
your authentication secrets remain private and aren't publicly accessible.

Subscription key-based authentication (Shared Key) can be used in client-side applications or


web services, but it's the least secure method for protecting your application or web service.
This is because the key can be easily extracted from an HTTP request, granting access to all
Azure Maps REST APIs available in the SKU (Pricing Tier). If you use subscription keys, make
sure to rotate them regularly and remember that Shared Key doesn't support configurable
lifetimes, so rotation must be done manually. Consider using Shared Key authentication with
Azure Key Vault to securely store your secret in Azure.

When using Microsoft Entra authentication or Shared Access Signature (SAS) Token
authentication, access to Azure Maps REST APIs is authorized using role-based access control
(RBAC). RBAC enables you to specify the level of access granted to the issued tokens. It's
important to consider the duration for which access should be granted. Unlike Shared Key
authentication, the lifetime of these tokens is configurable.

 Tip

For more information on configuring token lifetimes, see:


Configurable token lifetimes in the Microsoft identity platform (preview)
Create SAS tokens

Public client and confidential client applications


There are different security concerns between public and confidential client applications. For
more information about what is considered a public versus confidential client application, see
Public client and confidential client applications in the Microsoft identity platform
documentation.

Public client applications


For applications running on devices, desktop computers, or web browsers, it's advisable to
define which domains can access your Azure Maps account using Cross origin resource sharing
(CORS). CORS informs the client's browser which origins, such as "https://microsoft.com," are
permitted to request resources for the Azure Maps account.

7 Note

If you're developing a web server or service, configuring your Azure Maps account with
CORS is unnecessary. However, if your client-side web application includes JavaScript
code, CORS does apply.

Confidential client applications


For server-based applications, such as web services and service/daemon apps, consider using
Managed Identities to avoid the complexity of managing secrets. Managed identities can
provide an identity for your web service to connect to Azure Maps using Microsoft Entra
authentication. Your web service can then use this identity to obtain the necessary Microsoft
Entra tokens. It's recommended to use Azure RBAC to configure the access granted to the web
service, applying the Least privileged roles possible.

Next steps
Authentication with Azure Maps

Manage authentication in Azure Maps


Tutorial: Add app authentication to your web app running on Azure App Service
React to Azure Maps events by using
Event Grid
Article • 01/10/2024

Azure Maps integrates with Azure Event Grid, so that users can send event notifications
to other services and trigger downstream processes. The purpose of this article is to
help you configure your business applications to listen to Azure Maps events. This
allows users to react to critical events in a reliable, scalable, and secure manner. For
example, users can build an application to update a database, create a ticket, and deliver
an email notification, every time a device enters a geofence.

Azure Event Grid is a fully managed event routing service, which uses a publish-
subscribe model. Event Grid has built-in support for Azure services like Azure Functions
and Azure Logic Apps. It can deliver event alerts to non-Azure services using webhooks.
For a complete list of the event handlers that Event Grid supports, see An introduction
to Azure Event Grid.

Azure Maps events types


Event Grid uses event subscriptions to route event messages to subscribers. An Azure
Maps account emits the following event types:

ノ Expand table
Event type Description

Microsoft.Maps.GeofenceEntered Raised when received coordinates have moved from outside


of a given geofence to within

Microsoft.Maps.GeofenceExited Raised when received coordinates have moved from within a


given geofence to outside

Microsoft.Maps.GeofenceResult Raised every time a geofencing query returns a result,


regardless of the state

Event schema
The following example shows the schema for GeofenceResult:

JSON

{
"id":"451675de-a67d-4929-876c-5c2bf0b2c000",

"topic":"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/prov
iders/Microsoft.Maps/accounts/{accountName}",
"subject":"/spatial/geofence/udid/{udid}/id/{eventId}",
"data":{
"geometries":[
{
"deviceId":"device_1",
"udId":"1a13b444-4acf-32ab-ce4e-9ca4af20b169",
"geometryId":"1",
"distance":999.0,
"nearestLat":47.609833,
"nearestLon":-122.148274
}
],
"expiredGeofenceGeometryId":[
],
"invalidPeriodGeofenceGeometryId":[
]
},
"eventType":"Microsoft.Maps.GeofenceResult",
"eventTime":"2018-11-08T00:52:08.0954283Z",
"metadataVersion":"1",
"dataVersion":"1.0"
}

Tips for consuming events


Applications that handle Azure Maps geofence events should follow a few
recommended practices:

Configure multiple subscriptions to route events to the same event handler. It's
important not to assume that events are from a particular source. Always check the
message topic to ensure that the message came from the source that you expect.
Use the X-Correlation-id field in the response header to understand if your
information about objects is up to date. Messages can arrive out of order or after a
delay.
When a GET or a POST request in the Geofence API is called with the mode
parameter set to EnterAndExit , then an Enter or Exit event is generated for each
geometry in the geofence for which the status has changed from the previous
Geofence API call.

Next steps
For details about all the events supported by Azure Maps and the schema, see Azure
Maps as an Event Grid source.

To learn more about how to use geofencing to control operations at a construction site,
see:

Set up a geofence by using Azure Maps


Azure Maps service geographic scope
Article • 04/13/2023

Azure Maps is a global service that supports specifying a geographic scope, which
allows you to limit data residency to the European (EU) or United States (US) geographic
areas (geos). All requests (including input data) are stored exclusively in the specified
geographic area. For more information on Azure regions and geographies, see Azure
geographies .

Data locations
For disaster recovery and high availability, Microsoft may replicate customer data to
other regions within the same geographic area. For example, if you use the Azure Maps
Europe API geographic endpoint, your requests (including input data) are kept in an
Azure datacenter in Europe. The only impact is where request data is saved, it doesn't
limit the locations from which the customers, or their end users, may access customer
data via Azure Maps API.

Geographic API endpoint mapping


The following table describes the mapping between geography and supported Azure
geographic API endpoint. For example, if you want all Azure Maps Search Address
requests to be processed and stored within the European Azure geography, use the
eu.atlas.microsoft.com endpoint.

Azure Geographic areas (geos) API geographic endpoint

Europe eu.atlas.microsoft.com

United States us.atlas.microsoft.com

 Tip

When using the Azure Government cloud, use the atlas.azure.us endpoint. For
more information, see Azure Government cloud support.

URL example for geographic mapping


The following code snippet is an example of the Search - Get Search Address request:
HTTP

GET https://{geography}.atlas.microsoft.com/search/address/{format}?api-
version=1.0&query={query}

In the previous URL, to ensure data residency remains in Europe for the Azure Maps API
calls (and input data) replace {geography} with eu :

HTTP

GET https://eu.atlas.microsoft.com/search/address/{format}?api-
version=1.0&query={query}

Additional information
For information on limiting what regions a SAS token can use in see Authentication with
Azure Maps

Azure geographies
Azure Government cloud support
Consent management
Article • 11/27/2024

Azure Maps is a global service that is available worldwide. When creating your Azure
Maps account, you select a Region. The Region selection is the accounts geographic
scope, which allows you to limit data residency to the selected region. All requests
(including input data) are processed and stored exclusively in the specified geographic
area (region).

In some cases, you will need to enable your search requests to be processed in a region
or geography other than the one your Azure Maps Account is in. For example, due to
local data residency laws, all South Korean addresses must be processed in South Korea,
which is the Korea Central region in Azure Maps. To do this, you must give Azure Maps
consent to process your data in the Korea Central region. For more information on how
to give Azure maps consent to process data in a different region, see Configure global
data processing.

For more information on geographic scope in Azure Maps, see Azure Maps service
geographic scope.

Frequently asked questions


My scenario doesn't have any South Korea data. Do I still need to enable cross region
processing to use Azure Maps?

No, if your scenario doesn't require South Korea data, you don't need to enable cross
region processing. This is a specific regional requirement due to data residency laws.

Where will my data be stored if I enable cross region processing in South Korea?

Giving consent to process data in a different region will not affect where your metadata
and logs are stored. Those are still contained within the region specified when creating
your Azure Maps Account.

Next steps
Configure global data processing

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Creator for indoor maps
Article • 09/16/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

This article introduces concepts and tools that apply to Azure Maps Creator. We
recommend that you read this article before you begin to use the Azure Maps Creator
API and SDK.

You can use Creator to develop applications with map features that are based on indoor
map data. This article describes the process of uploading, converting, creating, and
using your map data. Typically, the workflow is completed by two different personas
with distinct areas of expertise and responsibility:

Map maker: responsible for curating and preparing the map data.
Creator map data user: uses customer map data in applications.

The following diagram illustrates the entire workflow.

Create Azure Maps Creator


To use Creator services, an Azure Maps Creator resource must be created and associated
to an Azure Maps account with the Gen 2 pricing tier. For information about how to
create an Azure Maps Creator resource in Azure, see Manage Azure Maps Creator.

 Tip
For pricing information see the Creator section in Azure Maps pricing .

Creator authentication
Creator inherits Azure Maps Access Control (IAM) settings. All API calls for data access
must be sent with authentication and authorization rules.

Creator usage data is incorporated in your Azure Maps usage charts and activity log. For
more information, see Manage authentication in Azure Maps.

) Important

We recommend using:

Microsoft Entra ID in all solutions that are built with an Azure Maps account
using Creator services. For more information about Microsoft Entra ID, see
Microsoft Entra authentication.

Role-based access control settings. Using these settings, map makers can act
as the Azure Maps Data Contributor role, and Creator map data users can act
as the Azure Maps Data Reader role. For more information, see Authorization
with role-based access control.

Creator data item types


Creator services create, store, and use various data types that are defined and discussed
in the following sections. A creator data item can be of the following types:

Converted data
Dataset
Tileset
style
Map configuration
Routeset

Upload a drawing package


Creator collects indoor map data by converting an uploaded drawing package. The
drawing package represents a constructed or remodeled facility. For information about
drawing package requirements, see Drawing package requirements.

Follow the steps outlined in the How to create data registry article to upload the
drawing package into your Azure storage account then register it in your Azure Maps
account.

) Important

Make sure to make a note of the unique identifier ( udid ) value, you will need it. The
udid is required to convert the uploaded package into indoor map data.

Convert a drawing package


The Conversion service converts an uploaded drawing package into indoor map data.
The Conversion service also validates the package. Validation issues are classified into
two types:

Errors: If any errors are detected, the conversion process fails. When an error
occurs, the Conversion service provides a link to the Azure Maps Drawing Error
Visualizer stand-alone web application. You can use the Drawing Error Visualizer to
inspect Drawing package warnings and errors that occurred during the conversion
process. After you fix the errors, you can attempt to upload and convert the
package.
Warnings: If any warnings are detected, the conversion succeeds. However, we
recommend that you review and resolve all warnings. A warning means that part of
the conversion was ignored or automatically fixed. Failing to resolve the warnings
could result in errors in later processes. For more information, see Drawing
package warnings and errors.

Create indoor map data


Azure Maps Creator provides the following services that support map creation:

Dataset service.
Tileset service. Use the Tileset service to create a vector-based representation of a
dataset. Applications can use a tileset to present a visual tile-based view of the
dataset.
Custom styling service. Use the style service or visual style editor to customize
the visual elements of an indoor map.
Wayfinding service. Use the wayfinding API to generate a path between two points
within a facility. Use the routeset API to create the data that the wayfinding service
needs to generate paths.

Datasets
A dataset is a collection of indoor map features. The indoor map features represent
facilities that are defined in a converted drawing package. After you create a dataset
with the Dataset service, you can create any number of tilesets.

At any time, developers can use the Dataset service to add or remove facilities to an
existing dataset. For more information about how to update an existing dataset using
the API, see the append options in Dataset service. For an example of how to update a
dataset, see Data maintenance.

Tilesets
A tileset is a collection of vector data that represents a set of uniform grid tiles.
Developers can use the Tileset service to create tilesets from a dataset.

To reflect different content stages, you can create multiple tilesets from the same
dataset. For example, you can make one tileset with furniture and equipment, and
another tileset without furniture and equipment. You might choose to generate one
tileset with the most recent data updates, and another tileset without the most recent
data updates.

In addition to the vector data, the tileset provides metadata for map rendering
optimization. For example, tileset metadata contains a minimum and maximum zoom
level for the tileset. The metadata also provides a bounding box that defines the
geographic extent of the tileset. An application can use a bounding box to
programmatically set the correct center point. For more information about tileset
metadata, see Tileset List.

After a tileset is created, it's retrieved using the Render service.

If a tileset becomes outdated and is no longer useful, you can delete the tileset. For
information about how to delete tilesets, see Data maintenance.

7 Note

A tileset is independent of the dataset from which it was created. If you create
tilesets from a dataset, and then subsequently update that dataset, the tilesets isn't
updated.

To reflect changes in a dataset, you must create new tilesets. Similarly, if you delete
a tileset, the dataset isn't affected.

Custom styling (preview)


A style defines the visual appearance of a map. It defines what data to draw, the order
to draw it in, and how to style the data when drawing it. Azure Maps Creator styles
support the MapLibre standard for style layers and sprites .

When you convert a drawing package after uploading it to your Azure Maps account,
default styles are applied to the elements of your map. The custom styling service
enables you to customize the visual appearance of your map. You can do this by
manually editing the style JSON and importing it into your Azure Maps account using
the Style - Create HTTP request, however the recommended approach is to use the
visual style editor . For more information, see Create custom styles for indoor maps.

Example layer in the style.json file:

JSON

{
"id": "indoor_unit_gym_label",
"type": "symbol",
"filter": ["all", ["has","floor0"], ["any", ["==", "categoryName",
"room.gym"]]],
"layout": {
"visibility": "none",
"icon-image": "gym",
"icon-size": {"stops": [[17.5, 0.7], [21, 1.1]]},
"symbol-avoid-edges": true,
"symbol-placement": "point",
"text-anchor": "top",
"text-field": "{name}",
"text-font": ["SegoeFrutigerHelveticaMYingHei-Medium"],
"text-keep-upright": true,
"text-letter-spacing": 0.1,
"text-offset": [0, 1.05],
"text-size": {"stops": [[18, 5], [18.5, 6.5], [19, 8], [19.5, 9.5],
[20, 11]]}
},
"metadata": {"microsoft.maps:layerGroup": "labels_indoor"},
"minzoom": 17.5,
"paint": {
"text-color": "rgba(0, 0, 0, 1)",
"text-halo-blur": 0.5,
"text-halo-color": "rgba(255, 255, 255, 1)",
"text-halo-width": 1,
"text-opacity": ["step", ["zoom"], 0, 18, 1]
},
"source-layer": "Indoor unit"
},

ノ Expand table

Layer Description
Properties

id The name of the layer

type The rendering type for this layer.


Some of the more common types include:
fill: A filled polygon with an optional stroked border.
Line: A stroked line.
Symbol: An icon or a text label.
fill-extrusion: An extruded (3D) polygon.

filter Only features that match the filter criteria are displayed.

layout Layout properties for the layer.

minzoom A number between 0 and 24 that represents the minimum zoom level for the
layer. At zoom levels less than the minzoom, the layer is hidden.

paint Default paint properties for this layer.

source-layer A source supplies the data, from a vector tile source, displayed on a map.
Required for vector tile sources; prohibited for all other source types, including
GeoJSON sources.

Map configuration

The map configuration is an array of configurations. Each configuration consists of a


basemap and one or more layers, each layer consisting of a style + tileset tuple.

The map configuration is used when you Instantiate the Indoor Manager of a Map
object when developing applications in Azure Maps. It's referenced using the
mapConfigurationId or alias . Map configurations are immutable. When making

changes to an existing map configuration, a new map configuration is created, resulting


in a different mapConfingurationId . Anytime you create a map configuration using an
alias already used by an existing map configuration, it points to the new map
configuration.
The following JSON is an example of a default map configuration. See the following
table for a description of each element of the file:

JSON

{
"version": 1.0,
"description": "This is the default Azure Maps map configuration for
facility ontology tilesets.",
"defaultConfiguration": "indoor_light",
"configurations": [
{
"name": "indoor_light",
"displayName": "Indoor light",
"description": "A base style for Azure Maps.",
"thumbnail": "indoor_2022-01-01.png",
"baseMap": "microsoft_light",
"layers": [
{
"tilesetId": "fa37d225-924e-3f32-8441-6128d9e5519a",
"styleId": "microsoft-maps:indoor_2022-01-01"
}
]
},
{
"name": "indoor_dark",
"displayName": "Indoor dark",
"description": "A base style for Azure Maps.",
"thumbnail": "indoor_dark_2022-01-01.png",
"baseMap": "microsoft_dark",
"layers": [
{
"tilesetId": "fa37d225-924e-3f32-8441-6128d9e5519a",
"styleId": "microsoft-maps:indoor_dark_2022-01-01"
}
]
}
]
}

ノ Expand table

Style Object Description


Properties

Name The name of the style.

displayName The display name of the style.

description The user defined description of the style.


Style Object Description
Properties

thumbnail Use to specify the thumbnail used in the style picker for this style. For more
information, see the style picker control.

baseMap Use to Set the base map style.

layers The layers array consists of one or more tileset + Style tuples, each being a
layer of the map. This enables multiple buildings on a map, each building
represented in its own tileset.

Additional information
For more information how to modify styles using the style editor, see Create
custom styles for indoor maps.
For more information on style Rest API, see style in the Maps Creator Rest API
reference.
For more information on the map configuration Rest API, see Creator - map
configuration Rest API.

Wayfinding (preview)
The Wayfinding service enables you to provide your customers with the shortest path
between two points within a facility. Once you've imported your indoor map data and
created your dataset, you can use that to create a routeset. The routeset provides the
data required to generate paths between two points. The wayfinding service takes into
account things such as the minimum width of openings and can optionally exclude
elevators or stairs when navigating between levels as a result.

Creator wayfinding is powered by Havok .

Wayfinding paths

When a wayfinding path is successfully generated, it finds the shortest path between
two points in the specified facility. Each floor in the journey is represented as a separate
leg, as are any stairs or elevators used to move between floors.

For example, the first leg of the path might be from the origin to the elevator on that
floor. The next leg is the elevator, and then the final leg is the path from the elevator to
the destination. The estimated travel time is also calculated and returned in the HTTP
response JSON.
Structure

For wayfinding to work, the facility data must contain a structure. The wayfinding service
calculates the shortest path between two selected points in a facility. The service creates
the path by navigating around structures, such as walls and any other impermeable
structures.

Vertical penetration

If the selected origin and destination are on different floors, the wayfinding service
determines what verticalPenetration objects such as stairs or elevators, are available as
possible pathways for navigating vertically between levels. By default, the option that
results in the shortest path is used.

The Wayfinding service includes stairs or elevators in a path based on the value of the
vertical penetration's direction property. For more information on the direction
property, see verticalPenetration in the Facility Ontology article. See the avoidFeatures
and minWidth properties in the wayfinding API documentation to learn about other
factors that can affect the path selection between floor levels.

For more information, see the Indoor maps wayfinding service how-to article.

Using indoor maps

Render - Get Map Tile API


The Azure Maps [Render - Get Map Tile] API has been extended to support Creator
tilesets.

Applications can use the Render - Get Map Tile API to request tilesets. The tilesets can
then be integrated into a map control or SDK. For an example of a map control that
uses the Render service, see Indoor Maps Module.

Web Feature service API


You can use the Web Feature service (WFS) to query datasets. WFS follows the Open
Geospatial Consortium API Features. You can use the WFS API to query features within
the dataset itself. For example, you can use WFS to find all mid-size meeting rooms of a
specific facility and floor level.

Alias API
Creator services such as Conversion, Dataset, and Tileset return an identifier for each
resource that's created from the APIs. The Alias API allows you to assign an alias to
reference a resource identifier.

Indoor Maps module


The Azure Maps Web SDK includes the Indoor Maps module. This module offers
extended functionalities to the Azure Maps Map Control library. The Indoor Maps
module renders indoor maps created in Creator. It integrates widgets such as floor
picker that help users to visualize the different floors.

You can use the Indoor Maps module to create web applications that integrate indoor
map data with other Azure Maps services. The most common application setups include
adding knowledge from other maps - such as road, imagery, weather, and transit - to
indoor maps.

The Indoor Maps module also supports dynamic map styling for more information, see
Enhance your indoor maps with real-time map feature styling .

Azure Maps integration


As you begin to develop solutions for indoor maps, you can discover ways to integrate
existing Azure Maps capabilities. For example, you can implement asset tracking or
safety scenarios by using the Geofence service with Creator indoor maps. For example,
you can use the Geofence API to determine whether a worker enters or leaves specific
indoor areas.

Data maintenance
You can use the Azure Maps Creator List, Update, and Delete API to list, update, and
delete your datasets and tilesets.

7 Note

When you review a list of items to determine whether to delete them, consider the
impact of that deletion on all dependent API or applications. For example, if you
delete a tileset that's being used by an application by means of the [Render - Get
Map Tile] API, the application fails to render that tileset.

Example: Updating a dataset


The following example shows how to update a dataset, create a new tileset, and delete
an old tileset:

1. Follow steps in the Upload a drawing package and Convert a drawing package
sections to upload and convert the new drawing package.
2. Use Dataset Create to append the converted data to the existing dataset.
3. Use Tileset Create to generate a new tileset out of the updated dataset.
4. Save the new tilesetId for the next step.
5. To enable the visualization of the updated campus dataset, update the tileset
identifier in your application. If the old tileset is no longer used, you can delete it.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Creator service geographic scope
Article • 09/24/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

Azure Maps Creator is a geographically scoped service. Creator offers a resource


provider API that, given an Azure region, creates an instance of Creator data deployed at
the geographical level. The mapping from an Azure region to geography happens
behind the scenes as described in the following table. For more information on Azure
regions and geographies, see Azure geographies .

Data locations
For disaster recovery and high availability, Microsoft may replicate customer data to
other regions only within the same geographic area. For example, data in West Europe
may be replicated to North Europe, but not to the United States. Regardless, no matter
which geography the customer selected, Microsoft doesn’t control or limit the locations
from which the customers, or their end users, may access customer data via Azure Maps
API.

Geographic and regional mapping


The following table describes the mapping between geography and supported Azure
regions, and the respective geographic API endpoint. For example, if a Creator account
is provisioned in the West US 2 region that falls within the United States geography, all
API calls to the Conversion service must be made to
us.atlas.microsoft.com/conversion/convert .

ノ Expand table

Azure Geographic areas (geos) Azure datacenters (regions) API geographic endpoint

Europe West Europe, North Europe eu.atlas.microsoft.com


Azure Geographic areas (geos) Azure datacenters (regions) API geographic endpoint

United States West US 2, East US 2 us.atlas.microsoft.com

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Azure Data Encryption at rest
Article • 04/16/2025

Microsoft Azure includes tools to safeguard data according to your company's security and
compliance needs. This paper focuses on:

How data is protected at rest across Microsoft Azure


Discusses the various components taking part in the data protection implementation,
Reviews pros and cons of the different key management protection approaches.

Encryption at Rest is a common security requirement. In Azure, organizations can encrypt data
at rest without the risk or cost of a custom key management solution. Organizations have the
option of letting Azure completely manage Encryption at Rest. Additionally, organizations have
various options to closely manage encryption or encryption keys.

What is encryption at rest?


Encryption is the secure encoding of data used to protect confidentiality of data. The
Encryption at Rest designs in Azure use symmetric encryption to encrypt and decrypt large
amounts of data quickly according to a simple conceptual model:

A symmetric encryption key is used to encrypt data as it is written to storage.


The same encryption key is used to decrypt that data as it is readied for use in memory.
Data may be partitioned, and different keys may be used for each partition.
Keys must be stored in a secure location with identity-based access control and audit
policies. Data encryption keys which are stored outside of secure locations are encrypted
with a key encryption key kept in a secure location.

In practice, key management and control scenarios, as well as scale and availability assurances,
require additional constructs. Microsoft Azure Encryption at Rest concepts and components are
described below.

The purpose of encryption at rest


Encryption at rest provides data protection for stored data (at rest). Attacks against data at-rest
include attempts to obtain physical access to the hardware on which the data is stored, and
then compromise the contained data. In such an attack, a server's hard drive may have been
mishandled during maintenance allowing an attacker to remove the hard drive. Later the
attacker would put the hard drive into a computer under their control to attempt to access the
data.
Encryption at rest is designed to prevent the attacker from accessing the unencrypted data by
ensuring the data is encrypted when on disk. If an attacker obtains a hard drive with encrypted
data but not the encryption keys, the attacker must defeat the encryption to read the data. This
attack is much more complex and resource consuming than accessing unencrypted data on a
hard drive. For this reason, encryption at rest is highly recommended and is a high priority
requirement for many organizations.

Encryption at rest may also be required by an organization's need for data governance and
compliance efforts. Industry and government regulations such as HIPAA, PCI and FedRAMP, lay
out specific safeguards regarding data protection and encryption requirements. Encryption at
rest is a mandatory measure required for compliance with some of those regulations. For more
information on Microsoft's approach to FIPS 140-2 validation, see Federal Information
Processing Standard (FIPS) Publication 140-2.

In addition to satisfying compliance and regulatory requirements, encryption at rest provides


defense-in-depth protection. Microsoft Azure provides a compliant platform for services,
applications, and data. It also provides comprehensive facility and physical security, data access
control, and auditing. However, it's important to provide additional "overlapping" security
measures in case one of the other security measures fails and encryption at rest provides such
a security measure.

Microsoft is committed to encryption at rest options across cloud services and giving
customers control of encryption keys and logs of key use. Additionally, Microsoft is working
towards encrypting all customer data at rest by default.

Azure Encryption at Rest Components


As described previously, the goal of encryption at rest is that data that is persisted on disk is
encrypted with a secret encryption key. To achieve that goal secure key creation, storage,
access control, and management of the encryption keys must be provided. Though details may
vary, Azure services Encryption at Rest implementations can be described in terms illustrated in
the following diagram.
Azure Key Vault
The storage location of the encryption keys and access control to those keys is central to an
encryption at rest model. The keys need to be highly secured but manageable by specified
users and available to specific services. For Azure services, Azure Key Vault is the recommended
key storage solution and provides a common management experience across services. Keys are
stored and managed in key vaults, and access to a key vault can be given to users or services.
Azure Key Vault supports customer creation of keys or import of customer keys for use in
customer-managed encryption key scenarios.

Microsoft Entra ID
Permissions to use the keys stored in Azure Key Vault, either to manage or to access them for
Encryption at Rest encryption and decryption, can be given to Microsoft Entra accounts.

Envelope Encryption with a Key Hierarchy


More than one encryption key is used in an encryption at rest implementation. Storing an
encryption key in Azure Key Vault ensures secure key access and central management of keys.
However, service local access to encryption keys is more efficient for bulk encryption and
decryption than interacting with Key Vault for every data operation, allowing for stronger
encryption and better performance. Limiting the use of a single encryption key decreases the
risk that the key will be compromised and the cost of re-encryption when a key must be
replaced. Azure encryption at rest models use envelope encryption, where a key encryption key
encrypts a data encryption key. This model forms a key hierarchy which is better able to
address performance and security requirements:
Data Encryption Key (DEK) – A symmetric AES256 key used to encrypt a partition or
block of data, sometimes also referred to as simply a Data Key. A single resource may
have many partitions and many Data Encryption Keys. Encrypting each block of data with
a different key makes crypto analysis attacks more difficult. And keeping DEKs local to the
service encrypting and decrypting data maximizes performance.
Key Encryption Key (KEK) – An encryption key used to encrypt the Data Encryption Keys
using envelope encryption, also referred to as wrapping. Use of a Key Encryption Key that
never leaves Key Vault allows the data encryption keys themselves to be encrypted and
controlled. The entity that has access to the KEK may be different than the entity that
requires the DEK. An entity may broker access to the DEK to limit the access of each DEK
to a specific partition. Since the KEK is required to decrypt the DEKs, customers can
cryptographically erase DEKs and data by disabling of the KEK.

Resource providers and application instances store the encrypted Data Encryption Keys as
metadata. Only an entity with access to the Key Encryption Key can decrypt these Data
Encryption Keys. Different models of key storage are supported. For more information, see data
encryption models.

Encryption at rest in Microsoft cloud services


Microsoft Cloud services are used in all three cloud models: IaaS, PaaS, SaaS. Below you have
examples of how they fit on each model:

Software services, referred to as Software as a Service or SaaS, which have applications


provided by the cloud such as Microsoft 365.
Platform services in which customers use the cloud for things like storage, analytics, and
service bus functionality in their applications.
Infrastructure services, or Infrastructure as a Service (IaaS) in which customer deploys
operating systems and applications that are hosted in the cloud and possibly leveraging
other cloud services.

Encryption at rest for SaaS customers


Software as a Service (SaaS) customers typically have encryption at rest enabled or available in
each service. Microsoft 365 has several options for customers to verify or enable encryption at
rest. For information about Microsoft 365 services, see Encryption in Microsoft 365.

Encryption at rest for PaaS customers


Platform as a Service (PaaS) customer's data typically resides in a storage service such as Blob
Storage but may also be cached or stored in the application execution environment, such as a
virtual machine. To see the encryption at rest options available to you, examine the Data
encryption models for the storage and application platforms that you use.

Encryption at rest for IaaS customers


Infrastructure as a Service (IaaS) customers can have a variety of services and applications in
use. IaaS services can enable encryption at rest in their Azure hosted virtual machines and
VHDs using Azure Disk Encryption.

Encrypted storage
Like PaaS, IaaS solutions can leverage other Azure services that store data encrypted at rest. In
these cases, you can enable the Encryption at Rest support as provided by each consumed
Azure service. The Data encryption models enumerates the major storage, services, and
application platforms and the model of Encryption at Rest supported.

Encrypted compute
All Managed Disks, Snapshots, and Images are encrypted using Storage Service Encryption
using a service-managed key. A more complete Encryption at Rest solution ensures that the
data is never persisted in unencrypted form. While processing the data on a virtual machine,
data can be persisted to the Windows page file or Linux swap file, a crash dump, or to an
application log. To ensure this data is encrypted at rest, IaaS applications can use Azure Disk
Encryption on an Azure IaaS virtual machine (Windows or Linux) and virtual disk.

Custom encryption at rest


It is recommended that whenever possible, IaaS applications leverage Azure Disk Encryption
and Encryption at Rest options provided by any consumed Azure services. In some cases, such
as irregular encryption requirements or non-Azure based storage, a developer of an IaaS
application may need to implement encryption at rest themselves. Developers of IaaS solutions
can better integrate with Azure management and customer expectations by leveraging certain
Azure components. Specifically, developers should use the Azure Key Vault service to provide
secure key storage as well as provide their customers with consistent key management options
with that of most Azure platform services. Additionally, custom solutions should use Azure
managed service identities to enable service accounts to access encryption keys. For developer
information on Azure Key Vault and Managed Service Identities, see their respective SDKs.
Azure resource providers encryption model
support
Microsoft Azure Services each support one or more of the encryption at rest models. For some
services, however, one or more of the encryption models may not be applicable. For services
that support customer-managed key scenarios, they may support only a subset of the key
types that Azure Key Vault supports for key encryption keys. Additionally, services may release
support for these scenarios and key types at different schedules. This section describes the
encryption at rest support at the time of this writing for each of the major Azure data storage
services.

Azure disk encryption


Any customer using Azure Infrastructure as a Service (IaaS) features can achieve encryption at
rest for their IaaS VMs and disks through Azure Disk Encryption. For more information on
Azure Disk encryption, see Azure Disk Encryption for Linux VMs or Azure Disk Encryption for
Windows VMs.

Azure storage

All Azure Storage services (Blob storage, Queue storage, Table storage, and Azure Files) support
server-side encryption at rest; some services additionally support customer-managed keys and
client-side encryption.

Server-side: All Azure Storage Services enable server-side encryption by default using
service-managed keys, which is transparent to the application. For more information, see
Azure Storage Service Encryption for Data at Rest. Azure Blob storage and Azure Files also
support RSA 2048-bit customer-managed keys in Azure Key Vault. For more information,
see Storage Service Encryption using customer-managed keys in Azure Key Vault.
Client-side: Azure Blobs, Tables, and Queues support client-side encryption. When using
client-side encryption, customers encrypt the data and upload the data as an encrypted
blob. Key management is done by the customer. For more information, see Client-Side
Encryption and Azure Key Vault for Microsoft Azure Storage.

Azure SQL Database

Azure SQL Database currently supports encryption at rest for Microsoft-managed service side
and client-side encryption scenarios.

Support for server encryption is currently provided through the SQL feature called Transparent
Data Encryption. Once an Azure SQL Database customer enables TDE, keys are automatically
created and managed for them. Encryption at rest can be enabled at the database and server
levels. As of June 2017, Transparent Data Encryption (TDE) is enabled by default on newly
created databases. Azure SQL Database supports RSA 2048-bit customer-managed keys in
Azure Key Vault. For more information, see Transparent Data Encryption with Bring Your Own
Key support for Azure SQL Database and Data Warehouse.

Client-side encryption of Azure SQL Database data is supported through the Always Encrypted
feature. Always Encrypted uses a key that is created and stored by the client. Customers can
store the master key in a Windows certificate store, Azure Key Vault, or a local Hardware
Security Module. Using SQL Server Management Studio, SQL users choose what key they'd like
to use to encrypt which column.

Conclusion
Protection of customer data stored within Azure Services is of paramount importance to
Microsoft. All Azure hosted services are committed to providing Encryption at Rest options.
Azure services support either service-managed keys, customer-managed keys, or client-side
encryption. Azure services are broadly enhancing Encryption at Rest availability and new
options are planned for preview and general availability in the upcoming months.

Next steps
See data encryption models to learn more about service-managed keys and customer-
managed keys.
Learn how Azure uses double encryption to mitigate threats that come with encrypting
data.
Learn what Microsoft does to ensure platform integrity and security of hosts traversing
the hardware and firmware build-out, integration, operationalization, and repair pipelines.
Azure services and resource types
supporting managed identities
Article • 05/09/2025

Managed identities for Azure resources provide an automatically managed identity in


Microsoft Entra ID, enabling secure, credential-free authentication to Azure services. This article
lists Azure services and resource types that support managed identities.

This page provides links to services' content that can use managed identities to access other
Azure resources as well as a list of Azure resource providers and resource types that support
managed identities.

Additional resource provider namespace information is available in Resource providers for


Azure services.

) Important

New technical content is added daily. This list does not include every article that talks
about managed identities. Please refer to each service's content set for details on their
managed identities support.

Services supporting managed identities


The following Azure services support managed identities for Azure resources:

ノ Expand table

Service Name Documentation

API Management Use managed identities in Azure API Management

Application Gateway TLS termination with Key Vault certificates

Azure App Configuration How to use managed identities for Azure App Configuration

Azure App Services How to use managed identities for App Service and Azure
Functions

Azure Arc enabled Kubernetes Quickstart: Connect an existing Kubernetes cluster to Azure Arc

Azure Arc enabled servers Authenticate against Azure resources with Azure Arc-enabled
servers

Azure Automanage Repair an Automanage Account


Service Name Documentation

Azure Automation Azure Automation account authentication overview

Azure Batch Configure customer-managed keys for your Azure Batch account
with Azure Key Vault and Managed Identity
Configure managed identities in Batch pools

Azure Blueprints Stages of a blueprint deployment

Azure Cache for Redis Managed identity for storage accounts with Azure Cache for Redis

Azure Chaos Studio Permissions and security in Azure Chaos Studio

Azure Communications Gateway Deploy Azure Communications Gateway

Azure Communication Services How to use Managed Identity with Azure Communication Services

Azure Container Apps Managed identities in Azure Container Apps

Azure Container Instance How to use managed identities with Azure Container Instances

Azure Container Registry Use an Azure-managed identity in ACR Tasks

Azure CycleCloud Using Managed Identities

Azure AI services Configure customer-managed keys with Azure Key Vault for Azure
AI services

Azure Data Box Use customer-managed keys in Azure Key Vault for Azure Data Box

Azure Data Explorer Configure managed identities for your Azure Data Explorer cluster

Azure Data Factory Managed identity for Data Factory

Azure Data Lake Storage Gen1 Customer-managed keys for Azure Storage encryption

Azure Data Share Roles and requirements for Azure Data Share

Azure DevTest Labs Enable user-assigned managed identities on lab virtual machines in
Azure DevTest Labs

Azure Digital Twins Enable a managed identity for routing Azure Digital Twins events

Azure Event Grid Event delivery with a managed identity

Azure Event Hubs Authenticate a managed identity with Microsoft Entra ID to access
Event Hubs Resources

Azure File Sync How to use managed identities with Azure File Sync

Azure Files Access Azure file shares using Microsoft Entra ID with Azure Files
OAuth over REST
Service Name Documentation

Azure Health Data Services Authentication and authorization for Azure Health Data Services
workspace services

Azure Health Data Services de- Use managed identities with the de-identification service
identification service

Azure Image Builder Azure Image Builder overview

Azure Import/Export Use customer-managed keys in Azure Key Vault for Import/Export
service

Azure IoT Hub IoT Hub support for virtual networks with Private Link and
Managed Identity

Azure Kubernetes Service (AKS) Use managed identities in Azure Kubernetes Service

Azure Load Testing Use managed identities for Azure Load Testing

Azure Logic Apps Authenticate access to Azure resources using managed identities in
Azure Logic Apps

Azure Log Analytics workspace Enable managed identity for Log Analytics workspace

Azure Log Analytics cluster Azure Monitor customer-managed key

Azure Machine Learning Services Use Managed identities with Azure Machine Learning

Azure Managed Disk Use the Azure portal to enable server-side encryption with
customer-managed keys for managed disks

Azure Media services Managed identities

Azure Monitor Azure Monitor customer-managed key

Azure Policy Remediate non-compliant resources with Azure Policy

Microsoft Purview Credentials for source authentication in Microsoft Purview

Azure Quantum Authenticate using a managed identity

Azure Resource Mover Move resources across regions (from resource group)

Azure Site Recovery Replicate machines with private endpoints

Azure Search Set up an indexer connection to a data source using a managed


identity

Azure Service Bus Authenticate a managed identity with Microsoft Entra ID to access
Azure Service Bus resources

Azure Service Fabric Using Managed identities for Azure with Service Fabric
Service Name Documentation

Azure SignalR Service Managed identities for Azure SignalR Service

Azure Spring Apps Enable system-assigned managed identity for an application in


Azure Spring Apps

Azure SQL Managed identities in Microsoft Entra for Azure SQL

Azure SQL Managed Instance Managed identities in Microsoft Entra for Azure SQL

Azure Stack Edge Manage Azure Stack Edge secrets using Azure Key Vault

Azure Static Web Apps Securing authentication secrets in Azure Key Vault

Azure Stream Analytics Authenticate Stream Analytics to Azure Data Lake Storage Gen1
using managed identities

Azure Synapse Azure Synapse workspace managed identity

Azure VM image builder Configure Azure Image Builder Service permissions using Azure CLI

Azure Virtual Machine Scale Sets Configure managed identities on virtual machine scale set - Azure
CLI

Azure Virtual Machines Secure and use policies on virtual machines in Azure

Azure Web PubSub Service Managed identities for Azure Web PubSub Service

Resource providers and resource types supporting


managed identities
The following resource providers and resource types support managed identities:

ノ Expand table

Namespace ResourceType Identity types(s)

Microsoft.AVS privateClouds System-assigned


User-assigned

Microsoft.ApiManagement service System-assigned


User-assigned

Microsoft.App builders System-assigned


User-assigned

Microsoft.App containerApps System-assigned


User-assigned
Namespace ResourceType Identity types(s)

Microsoft.App jobs System-assigned


User-assigned

Microsoft.App managedEnvironments System-assigned


User-assigned

Microsoft.App sessionPools System-assigned


User-assigned

Microsoft.AppConfiguration configurationStores System-assigned


User-assigned

Microsoft.AppPlatform Spring System-assigned

Microsoft.AppPlatform Spring/apps System-assigned


User-assigned

Microsoft.Automation automationAccounts System-assigned


User-assigned

Microsoft.AzureStackHCI clusters System-assigned

Microsoft.AzureStackHCI devicePools System-assigned

Microsoft.AzureStackHCI edgeMachines System-assigned

Microsoft.AzureStackHCI virtualMachines System-assigned

Microsoft.Batch batchAccounts System-assigned


User-assigned

Microsoft.Batch batchAccounts/pools User-assigned

Microsoft.Blueprint blueprintAssignments System-assigned


User-assigned

Microsoft.Cache Redis System-assigned


User-assigned

Microsoft.Cache redisEnterprise System-assigned


User-assigned

Microsoft.Cdn profiles System-assigned


User-assigned

Microsoft.ChangeAnalysis profile System-assigned

Microsoft.CognitiveServices accounts System-assigned


User-assigned
Namespace ResourceType Identity types(s)

Microsoft.CognitiveServices accounts/encryptionScopes

Microsoft.Communication CommunicationServices System-assigned


User-assigned

Microsoft.Compute diskEncryptionSets System-assigned


User-assigned

Microsoft.Compute galleries System-assigned


User-assigned

Microsoft.Compute virtualMachineScaleSets System-assigned


User-assigned

Microsoft.Compute virtualMachines System-assigned


User-assigned

Microsoft.ContainerInstance containerGroups System-assigned


User-assigned

Microsoft.ContainerInstance containerScaleSets System-assigned


User-assigned

Microsoft.ContainerInstance nGroups System-assigned


User-assigned

Microsoft.ContainerRegistry registries System-assigned


User-assigned

Microsoft.ContainerRegistry registries/credentialSets System-assigned

Microsoft.ContainerRegistry registries/exportPipelines System-assigned


User-assigned

Microsoft.ContainerRegistry registries/importPipelines System-assigned


User-assigned

Microsoft.ContainerRegistry registries/taskRuns User-assigned

Microsoft.ContainerRegistry registries/tasks System-assigned


User-assigned

Microsoft.ContainerService fleets System-assigned


User-assigned

Microsoft.ContainerService managedClusters System-assigned


User-assigned

Microsoft.ContainerService managedclustersnapshots System-assigned


User-assigned
Namespace ResourceType Identity types(s)

Microsoft.ContainerService snapshots System-assigned


User-assigned

Microsoft.CustomProviders resourceProviders System-assigned

Microsoft.DBforMariaDB servers System-assigned

Microsoft.DBforMySQL flexibleServers User-assigned

Microsoft.DBforMySQL servers System-assigned

Microsoft.DBforPostgreSQL flexibleServers System-assigned


User-assigned

Microsoft.DBforPostgreSQL serverGroupsv2 User-assigned

Microsoft.DBforPostgreSQL servers System-assigned

Microsoft.DataBox jobs System-assigned


User-assigned

Microsoft.DataBoxEdge DataBoxEdgeDevices System-assigned

Microsoft.DataFactory factories System-assigned


User-assigned

Microsoft.DataLakeStore accounts System-assigned

Microsoft.DataMigration SqlMigrationServices System-assigned

Microsoft.DataMigration migrationServices System-assigned

Microsoft.DataProtection BackupVaults System-assigned


User-assigned

Microsoft.DataShare accounts System-assigned

Microsoft.Databricks accessConnectors System-assigned


User-assigned

Microsoft.DesktopVirtualization hostpools System-assigned


User-assigned

Microsoft.DevCenter devcenters System-assigned


User-assigned

Microsoft.DevCenter devcenters/encryptionsets System-assigned


User-assigned

Microsoft.DevCenter projects System-assigned


User-assigned
Namespace ResourceType Identity types(s)

Microsoft.DevCenter projects/environmentTypes System-assigned


User-assigned

Microsoft.DevOpsInfrastructure pools User-assigned

Microsoft.DevTestLab labs System-assigned


User-assigned

Microsoft.DevTestLab labs/serviceRunners System-assigned


User-assigned

Microsoft.DeviceUpdate accounts System-assigned


User-assigned

Microsoft.DeviceUpdate updateAccounts System-assigned


User-assigned

Microsoft.Devices IotHubs System-assigned


User-assigned

Microsoft.Devices ProvisioningServices System-assigned


User-assigned

Microsoft.DigitalTwins digitalTwinsInstances System-assigned


User-assigned

Microsoft.DocumentDB cassandraClusters System-assigned

Microsoft.DocumentDB databaseAccounts System-assigned


User-assigned

Microsoft.DocumentDB databaseAccounts/encryptionScopes User-assigned

Microsoft.DocumentDB garnetClusters System-assigned

Microsoft.DocumentDB managedResources System-assigned

Microsoft.DocumentDB throughputPools System-assigned

Microsoft.DocumentDB throughputPools/throughputPoolAccounts System-assigned

Microsoft.ElasticSan elasticSans/volumeGroups System-assigned


User-assigned

Microsoft.EventGrid domains System-assigned


User-assigned

Microsoft.EventGrid namespaces System-assigned


User-assigned
Namespace ResourceType Identity types(s)

Microsoft.EventGrid partnerTopics System-assigned


User-assigned

Microsoft.EventGrid systemTopics System-assigned


User-assigned

Microsoft.EventGrid topics System-assigned


User-assigned

Microsoft.EventHub namespaces System-assigned


User-assigned

Microsoft.HDInsight clusters System-assigned


User-assigned

Microsoft.HybridCompute machines System-assigned

Microsoft.HybridNetwork networkfunctions System-assigned


User-assigned

Microsoft.HybridNetwork publishers System-assigned

Microsoft.HybridNetwork serviceManagementContainers System-assigned


User-assigned

Microsoft.HybridNetwork siteNetworkServices System-assigned


User-assigned

Microsoft.IoTCentral IoTApps System-assigned

Microsoft.KeyVault managedHSMs User-assigned

Microsoft.Kubernetes connectedClusters System-assigned

Microsoft.KubernetesConfiguration extensions System-assigned

Microsoft.Kusto clusters System-assigned


User-assigned

Microsoft.LoadTestService loadtests System-assigned


User-assigned

Microsoft.Logic integrationAccounts System-assigned


User-assigned

Microsoft.Logic integrationServiceEnvironments System-assigned


User-assigned

Microsoft.Logic workflows System-assigned


User-assigned
Namespace ResourceType Identity types(s)

Microsoft.MachineLearningServices registries System-assigned


User-assigned

Microsoft.MachineLearningServices workspaces System-assigned


User-assigned

Microsoft.MachineLearningServices workspaces/batchEndpoints System-assigned

Microsoft.MachineLearningServices workspaces/computes System-assigned


User-assigned

Microsoft.MachineLearningServices workspaces/inferencePools/groups System-assigned


User-assigned

Microsoft.MachineLearningServices workspaces/linkedServices System-assigned

Microsoft.MachineLearningServices workspaces/onlineEndpoints System-assigned


User-assigned

Microsoft.Maps accounts System-assigned


User-assigned

Microsoft.Media mediaservices System-assigned


User-assigned

Microsoft.Migrate migrateprojects System-assigned

Microsoft.Migrate modernizeProjects System-assigned

Microsoft.Migrate moveCollections System-assigned

Microsoft.MobileNetwork mobileNetworks User-assigned

Microsoft.MobileNetwork packetCoreControlPlanes User-assigned

Microsoft.MobileNetwork simGroups System-assigned


User-assigned

Microsoft.NetApp netAppAccounts System-assigned


User-assigned

Microsoft.Network networkWatchers/flowLogs User-assigned

Microsoft.OperationalInsights clusters System-assigned


User-assigned

Microsoft.OperationalInsights workspaces System-assigned


User-assigned

Microsoft.PowerPlatform enterprisePolicies System-assigned


Namespace ResourceType Identity types(s)

User-assigned

Microsoft.Purview accounts System-assigned


User-assigned

Microsoft.Quantum Workspaces System-assigned

Microsoft.RecoveryServices vaults System-assigned


User-assigned

Microsoft.RedHatOpenShift OpenShiftClusters System-assigned

Microsoft.Search searchServices System-assigned


User-assigned

Microsoft.Security dataScanners System-assigned

Microsoft.Security pricings/securityOperators System-assigned

Microsoft.ServiceBus namespaces System-assigned


User-assigned

Microsoft.ServiceFabric clusters System-assigned


User-assigned

Microsoft.ServiceFabric clusters/applications System-assigned


User-assigned

Microsoft.ServiceFabric managedclusters System-assigned


User-assigned

Microsoft.ServiceFabric managedclusters/applications System-assigned


User-assigned

Microsoft.SignalRService SignalR System-assigned


User-assigned

Microsoft.SignalRService WebPubSub System-assigned


User-assigned

Microsoft.Solutions applications System-assigned


User-assigned

Microsoft.Sql managedInstances System-assigned


User-assigned

Microsoft.Sql servers System-assigned


User-assigned

Microsoft.Sql servers/databases User-assigned


Namespace ResourceType Identity types(s)

Microsoft.Sql servers/jobAgents User-assigned

Microsoft.Storage storageAccounts System-assigned


User-assigned

Microsoft.Storage storageTasks System-assigned

Microsoft.StorageCache amlFilesystems User-assigned

Microsoft.StorageCache caches System-assigned


User-assigned

Microsoft.StorageSync storageSyncServices System-assigned


User-assigned

Microsoft.StreamAnalytics streamingjobs System-assigned


User-assigned

Microsoft.Synapse workspaces System-assigned


User-assigned

Microsoft.VirtualMachineImages imageTemplates User-assigned

Microsoft.Web hostingEnvironments System-assigned


User-assigned

Microsoft.Web sites System-assigned


User-assigned

Microsoft.Web sites/slots System-assigned


User-assigned

Microsoft.Web staticSites System-assigned


User-assigned

Next steps
Managed identities overview
Geographic coverage information
Article • 02/27/2023

The following links provide detail coverage information for each of the services in Azure
Maps.

Geocoding and search coverage


Traffic coverage
Render coverage
Routing coverage
Weather coverage

Next steps
Learn about supported regions, languages, and map styles:

Supported region

Localization support

Supported map styles


Azure Maps geocoding coverage
06/13/2025

The Search service supports geocoding, which means that your API request can have search
terms, like an address or the name of a place, and returns the result as latitude and longitude
coordinates. For example, Get Search Address receives queries that contain location
information, and returns results as latitude and longitude coordinates.

However, the Search service doesn't have the same level of information and accuracy for all
countries/regions. Use this article to determine what kind of locations you can reliably search
for in each region.

The ability to geocode in a country/region is dependent upon the road data coverage and
geocoding precision of the geocoding service. The following categorizations are used to
specify the level of geocoding support in each country/region.

Address points - Address data can be resolved to latitude/longitude coordinates within


the address parcel (property boundary). Address points are often referred to as being
'Rooftop' accurate, which is the highest level of accuracy available for addresses.
House numbers - Addresses are interpolated to a latitude/longitude coordinate on the
street.
Street level - Addresses are resolved to the latitude/longitude coordinate of the street
that contains the address. The house number may not be processed.
City level - City place names are supported.

Americas
ノ Expand table

Country/Region Address House Street City Points of


points numbers level level interest

Anguilla ✓ ✓

Antigua & Barbuda ✓ ✓ ✓

Argentina ✓ ✓ ✓ ✓ ✓

Aruba ✓ ✓

Bahamas ✓ ✓ ✓

Barbados ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Belize ✓ ✓ ✓

Bermuda ✓ ✓ ✓

Bolivia ✓ ✓ ✓

Bonaire, Sint Eustatius, & Saba ✓ ✓

Brazil ✓ ✓ ✓ ✓ ✓

British Virgin Islands ✓ ✓

Canada ✓ ✓ ✓ ✓ ✓

Cayman Islands ✓ ✓ ✓

Chile ✓ ✓ ✓ ✓ ✓

Clipperton Island ✓ ✓

Colombia ✓ ✓ ✓ ✓ ✓

Costa Rica ✓ ✓ ✓

Cuba ✓ ✓ ✓

Curaçao ✓ ✓

Dominica ✓ ✓ ✓

Dominican Republic ✓ ✓ ✓

Ecuador ✓ ✓ ✓ ✓ ✓

El Salvador ✓ ✓ ✓

Falkland Islands ✓ ✓

French Guiana ✓ ✓ ✓ ✓ ✓

Greenland ✓ ✓

Grenada ✓ ✓ ✓

Guadeloupe ✓ ✓ ✓ ✓ ✓

Guatemala ✓ ✓ ✓

Guyana ✓ ✓ ✓

Haiti ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Honduras ✓ ✓ ✓

Jamaica ✓ ✓ ✓

Martinique ✓ ✓ ✓ ✓ ✓

Mexico ✓ ✓ ✓ ✓ ✓

Montserrat ✓ ✓

Nicaragua ✓ ✓ ✓

Panama ✓ ✓ ✓

Paraguay ✓ ✓ ✓

Peru ✓ ✓ ✓ ✓

Puerto Rico ✓ ✓ ✓ ✓

Saint Barthélemy ✓ ✓ ✓

Saint Kitts & Nevis ✓ ✓ ✓

Saint Lucia ✓ ✓

Saint Martin ✓ ✓ ✓

Saint Pierre & Miquelon ✓ ✓ ✓

Saint Vincent & the Grenadines ✓ ✓

Sint Maarten ✓ ✓ ✓

South Georgia & the South ✓ ✓


Sandwich Islands

Suriname ✓ ✓ ✓

Trinidad & Tobago ✓ ✓ ✓

Turks & Caicos Islands ✓ ✓

U.S. Outlying Islands ✓ ✓

U.S. Virgin Islands ✓ ✓ ✓ ✓

United States ✓ ✓ ✓ ✓ ✓

Uruguay ✓ ✓ ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Venezuela ✓ ✓ ✓

Asia Pacific
ノ Expand table

Country/Region Address House Street City Points of


points numbers level level interest

American Samoa ✓ ✓ ✓

Australia ✓ ✓ ✓ ✓ ✓

Bangladesh ✓ ✓

Bhutan ✓ ✓

Brunei ✓ ✓ ✓ ✓

Cambodia ✓ ✓ ✓ ✓ ✓

China ✓ ✓

Christmas Island ✓ ✓ ✓ ✓ ✓

Cocos (Keeling) Islands ✓ ✓ ✓

Comoros ✓ ✓

Cook Islands ✓ ✓

Fiji ✓ ✓ ✓

French Polynesia ✓ ✓ ✓

Guam ✓ ✓ ✓ ✓ ✓

Heard Island & McDonald ✓ ✓


Islands

Hong Kong SAR ✓ ✓ ✓ ✓ ✓

India ✓ ✓ ✓ ✓

Indonesia ✓ ✓ ✓ ✓ ✓

Japan ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Kiribati ✓ ✓

Laos ✓ ✓ ✓ ✓

Macao SAR ✓ ✓ ✓ ✓ ✓

Malaysia ✓ ✓ ✓ ✓ ✓

Maldives ✓ ✓

Myanmar ✓ ✓ ✓ ✓ ✓

Micronesia ✓ ✓

Mongolia ✓ ✓

Nauru ✓ ✓

Nepal ✓ ✓

New Caledonia ✓ ✓

New Zealand ✓ ✓ ✓ ✓ ✓

Niue ✓ ✓

Norfolk Island ✓ ✓ ✓

North Korea ✓ ✓

Northern Mariana Islands ✓ ✓ ✓

Pakistan ✓ ✓

Palau ✓ ✓

Papua New Guinea ✓ ✓

Philippines ✓ ✓ ✓ ✓

Pitcairn Islands ✓ ✓

Samoa ✓ ✓

Singapore ✓ ✓ ✓ ✓ ✓

Solomon Islands ✓ ✓

South Korea1 ✓ ✓

Sri Lanka ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Taiwan ✓ ✓ ✓ ✓ ✓

Thailand ✓ ✓ ✓ ✓

Timor-Leste ✓ ✓

Tokelau ✓ ✓

Tonga ✓ ✓

Turks & Caicos Islands ✓ ✓

Tuvalu ✓ ✓

Vanuatu ✓ ✓

Vietnam ✓ ✓ ✓ ✓

Wallis & Futuna ✓ ✓

1
Coverage is dependent on enabling data processing in South Korea. For more information,
see Configure global data processing.

Europe
ノ Expand table

Country/Region Address House Street City Points of


points numbers level level interest

Albania ✓ ✓ ✓

Andorra ✓ ✓ ✓ ✓ ✓

Armenia ✓ ✓ ✓ ✓

Austria ✓ ✓ ✓ ✓ ✓

Azerbaijan ✓ ✓ ✓ ✓

Belarus ✓ ✓ ✓ ✓ ✓

Belgium ✓ ✓ ✓ ✓ ✓

Bosnia & ✓ ✓ ✓ ✓ ✓
Herzegovina
Country/Region Address House Street City Points of
points numbers level level interest

Bulgaria ✓ ✓ ✓ ✓ ✓

Croatia ✓ ✓ ✓ ✓ ✓

Cyprus ✓ ✓ ✓ ✓ ✓

Czech Republic ✓ ✓ ✓ ✓ ✓

Denmark ✓ ✓ ✓ ✓ ✓

Estonia ✓ ✓ ✓ ✓ ✓

Faroe Islands ✓ ✓ ✓ ✓ ✓

Finland ✓ ✓ ✓ ✓ ✓

France ✓ ✓ ✓ ✓ ✓

Georgia ✓ ✓ ✓ ✓ ✓

Germany ✓ ✓ ✓ ✓ ✓

Gibraltar ✓ ✓ ✓ ✓

Greece ✓ ✓ ✓ ✓ ✓

Guernsey ✓ ✓ ✓ ✓

Hungary ✓ ✓ ✓ ✓ ✓

Iceland ✓ ✓ ✓ ✓ ✓

Ireland ✓ ✓ ✓ ✓ ✓

Isle of Man ✓ ✓ ✓ ✓

Italy ✓ ✓ ✓ ✓ ✓

Jan Mayen ✓ ✓

Jersey ✓ ✓ ✓ ✓

Kazakhstan ✓ ✓ ✓ ✓ ✓

Kosovo ✓ ✓ ✓ ✓ ✓

Kyrgyzstan ✓ ✓ ✓ ✓

Latvia ✓ ✓ ✓ ✓

Liechtenstein ✓ ✓ ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Lithuania ✓ ✓ ✓ ✓ ✓

Luxembourg ✓ ✓ ✓ ✓ ✓

Malta ✓ ✓ ✓

Moldova ✓ ✓ ✓ ✓ ✓

Monaco ✓ ✓ ✓ ✓

Montenegro ✓ ✓ ✓

Netherlands ✓ ✓ ✓ ✓ ✓

North Macedonia ✓ ✓ ✓ ✓ ✓

Norway ✓ ✓ ✓ ✓ ✓

Poland ✓ ✓ ✓ ✓ ✓

Portugal ✓ ✓ ✓ ✓ ✓

Romania ✓ ✓ ✓ ✓ ✓

Russia ✓ ✓ ✓ ✓ ✓

San Marino ✓ ✓ ✓ ✓ ✓

Serbia ✓ ✓ ✓ ✓ ✓

Slovakia ✓ ✓ ✓ ✓ ✓

Slovenia ✓ ✓ ✓ ✓ ✓

Spain ✓ ✓ ✓ ✓ ✓

Svalbard ✓ ✓ ✓ ✓ ✓

Sweden ✓ ✓ ✓ ✓

Switzerland ✓ ✓ ✓ ✓ ✓

Tajikistan ✓ ✓ ✓

Türkiye ✓ ✓ ✓ ✓ ✓

Turkmenistan ✓ ✓

Ukraine ✓ ✓ ✓ ✓ ✓

United Kingdom ✓ ✓ ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Uzbekistan ✓ ✓

Vatican City ✓ ✓ ✓

Middle East & Africa


ノ Expand table

Country/Region Address House Street City Points of


points numbers level level interest

Afghanistan ✓ ✓

Algeria ✓ ✓ ✓ ✓ ✓

Angola ✓ ✓ ✓

Bahrain ✓ ✓ ✓ ✓ ✓

Benin ✓ ✓ ✓

Botswana ✓ ✓ ✓

Bouvet Island ✓ ✓

Burkina Faso ✓ ✓ ✓

Burundi ✓ ✓ ✓

Cameroon ✓ ✓ ✓

Cabo Verde ✓ ✓ ✓

Central African Republic ✓ ✓ ✓

Chad ✓ ✓

Congo ✓ ✓

Congo (DRC) ✓ ✓ ✓

Côte d'Ivoire ✓ ✓ ✓

Djibouti ✓ ✓ ✓

Egypt ✓ ✓ ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Equatorial Guinea ✓ ✓

Eritrea ✓ ✓

Ethiopia ✓ ✓ ✓

French Southern Territories ✓ ✓

Gabon ✓ ✓ ✓

Gambia ✓ ✓ ✓

Ghana ✓ ✓ ✓

Guinea ✓ ✓ ✓

Guinea-Bissau ✓ ✓ ✓

Iran ✓ ✓

Iraq ✓ ✓ ✓

Israel ✓ ✓ ✓ ✓ ✓

Jordan ✓ ✓ ✓ ✓

Kenya ✓ ✓ ✓

Kuwait ✓ ✓ ✓ ✓ ✓

Lebanon ✓ ✓ ✓ ✓ ✓

Lesotho ✓ ✓ ✓

Liberia ✓ ✓

Libya ✓ ✓

Madagascar ✓ ✓ ✓

Malawi ✓ ✓ ✓

Mali ✓ ✓

Mauritania ✓ ✓

Mauritius ✓ ✓ ✓

Mayotte ✓ ✓ ✓

Morocco ✓ ✓ ✓ ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Mozambique ✓ ✓ ✓

Namibia ✓ ✓ ✓ ✓ ✓

Niger ✓ ✓

Nigeria ✓ ✓ ✓ ✓

Oman ✓ ✓ ✓

Qatar ✓ ✓ ✓ ✓

Réunion ✓ ✓ ✓ ✓ ✓

Rwanda ✓ ✓ ✓

Saint Helena, Ascension, and ✓ ✓


Tristan da Cunha

São Tomé & Príncipe ✓ ✓ ✓

Saudi Arabia ✓ ✓ ✓ ✓

Senegal ✓ ✓ ✓

Seychelles ✓ ✓ ✓

Sierra Leone ✓ ✓ ✓

Somalia ✓ ✓

South Africa ✓ ✓ ✓ ✓ ✓

South Sudan ✓ ✓

Sudan ✓ ✓

Syria ✓ ✓

Tanzania ✓ ✓ ✓

Togo ✓ ✓ ✓

Tunisia ✓ ✓ ✓ ✓ ✓

Uganda ✓ ✓ ✓

United Arab Emirates ✓ ✓ ✓ ✓ ✓

Yemen ✓ ✓
Country/Region Address House Street City Points of
points numbers level level interest

Zambia ✓ ✓ ✓

Zimbabwe ✓ ✓ ✓

Next steps
Learn more about Azure Maps geocoding:

Azure Maps Search service


Azure Maps traffic coverage
Article • 03/25/2025

The Azure Maps Traffic service is a suite of web services designed for developers to
create web and mobile applications around real-time traffic. This data can be visualized
on maps or used to generate smarter routes that factor in current driving conditions.

The following tables provide information about what kind of traffic information you can
request from each country or region. If a market is missing in the following tables, it isn't
currently supported.

Incidents: Provides an accurate view about traffic jams and incidents around a road
network.
Flow: Provides real time observed speeds and travel times for all key roads in a
network.

Americas
ノ Expand table

Country/Region Incidents Flow

Argentina ✓ ✓

Brazil ✓ ✓

Canada ✓ ✓

Chile ✓ ✓

Colombia ✓ ✓

Guadeloupe ✓ ✓

Martinique ✓ ✓

Mexico ✓ ✓

Peru ✓ ✓

United States ✓ ✓

Uruguay ✓ ✓

Asia Pacific
ノ Expand table

Country/Region Incidents Flow

Australia ✓ ✓

Brunei ✓ ✓

Hong Kong SAR ✓ ✓

India ✓ ✓

Indonesia ✓ ✓

Kazakhstan ✓ ✓

Macao SAR ✓ ✓

Malaysia ✓ ✓

New Zealand ✓ ✓

Philippines ✓ ✓

Singapore ✓ ✓

Taiwan ✓ ✓

Thailand ✓ ✓

Vietnam ✓ ✓

Europe
ノ Expand table

Country/Region Incidents Flow

Belgium ✓ ✓

Bosnia and Herzegovina ✓ ✓

Bulgaria ✓ ✓

Croatia ✓ ✓

Cyprus ✓ ✓

Czech Republic ✓ ✓

Denmark ✓ ✓
Country/Region Incidents Flow

Estonia ✓ ✓

Finland ✓ ✓

France ✓ ✓

Germany ✓ ✓

Gibraltar ✓ ✓

Greece ✓ ✓

Hungary ✓ ✓

Iceland ✓ ✓

Ireland ✓ ✓

Italy ✓ ✓

Latvia ✓ ✓

Liechtenstein ✓ ✓

Lithuania ✓ ✓

Luxembourg ✓ ✓

Malta ✓ ✓

Monaco ✓ ✓

Netherlands ✓ ✓

Norway ✓ ✓

Poland ✓ ✓

Portugal ✓ ✓

Romania ✓ ✓

San Marino ✓ ✓

Serbia ✓ ✓

Slovakia ✓ ✓

Slovenia ✓ ✓

Spain ✓ ✓
Country/Region Incidents Flow

Sweden ✓ ✓

Switzerland ✓ ✓

Türkiye ✓ ✓

United Kingdom ✓ ✓

Middle East & Africa


ノ Expand table

Country/Region Incidents Flow

Bahrain ✓ ✓

Egypt ✓ ✓

Kenya ✓ ✓

Kuwait ✓ ✓

Lesotho ✓ ✓

Morocco ✓ ✓

Mozambique ✓ ✓

Nigeria ✓ ✓

Oman ✓ ✓

Qatar ✓ ✓

Reunion ✓ ✓

Saudi Arabia ✓ ✓

South Africa ✓ ✓

United Arab Emirates ✓ ✓

Next steps
See the following articles in the REST API documentation for detailed information.
Get Traffic Flow Segment

Get Traffic Flow Tile

Get Traffic Incident Detail

Get Traffic Incident Tile

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Azure Maps render coverage
Article • 09/22/2023

The render coverage tables below list the countries/regions that support Azure Maps
road tiles. Both raster and vector tiles are supported. At the lowest resolution, the entire
world fits in a single tile. At the highest resolution, a single tile represents 38 square
meters. You'll see more details about continents, regions, cities, and individual streets as
you zoom in the map. For more information about tiles, see Zoom levels and tile grid.

7 Note

Azure Maps Render v1 service retirement

The Azure Maps Render v1 service is now deprecated and will be retired on
9/17/26. To avoid service disruptions, all calls to Render v1 API will need to be
updated to use Render v2 API by 9/17/26.

Legend

Symbol Meaning

✓ Country/region is provided with detailed data.

◑ Country/region is provided with simplified data.

v2 Country/region is only supported in the Render v2 service.

Country/region is missing Country/region data isn't provided.

Americas
Country/Region Coverage

Anguilla ✓

Antigua & Barbuda ✓

Argentina ✓

Aruba ✓

Bahamas ✓
Country/Region Coverage

Barbados ✓

Bermuda ✓

Bonaire, St Eustatius & Saba ✓

Brazil ✓

British Virgin Islands ✓

Canada ✓

Cayman Islands ✓

Chile ✓

Clipperton Island ✓

Colombia ✓

Curaçao ✓

Dominica ✓

Falkland Islands ✓

Grenada ✓

Guadeloupe ✓

Haiti ✓

Jamaica ✓

Martinique ✓

Mexico ✓

Montserrat ✓

Peru ✓

Puerto Rico ✓

Saint Barthélemy ✓

Saint Kitts & Nevis ✓

Saint Lucia ✓

Saint Martin ✓
Country/Region Coverage

Saint Pierre & Miquelon ✓

Saint Vincent & Grenadines ✓

Sint Maarten ✓

South Georgia & Sandwich Islands ✓

Trinidad & Tobago ✓

Turks & Caicos Islands ✓

U.S. Virgin Islands ✓

United States ✓

Uruguay ✓

Venezuela ✓

Asia Pacific
Country/Region Coverage

Australia ✓

Brunei ✓

Cambodia ✓

Guam ✓

China v2

Hong Kong Special Administrative Region ✓

India ✓

Indonesia ✓

Japan v2

Laos ✓

Macao Special Administrative Region ✓

Malaysia ✓

Myanmar ✓
Country/Region Coverage

New Zealand ✓

Philippines ✓

Singapore ✓

South Korea ◑

Taiwan ✓

Thailand ✓

Vietnam ✓

Europe
Country/Region Coverage

Albania ✓

Andorra ✓

Austria ✓

Belarus ✓

Belgium ✓

Bosnia-Herzegovina ✓

Bulgaria ✓

Croatia ✓

Cyprus ✓

Czech Republic ✓

Denmark ✓

Estonia ✓

Finland ✓

France ✓

Germany ✓

Gibraltar ✓
Country/Region Coverage

Greece ✓

Hungary ✓

Iceland ✓

Ireland ✓

Italy ✓

Latvia ✓

Liechtenstein ✓

Lithuania ✓

Luxembourg ✓

Malta ✓

Moldova ✓

Monaco ✓

Montenegro ✓

Netherlands ✓

North Macedonia ✓

Norway ✓

Poland ✓

Portugal ✓

Romania ✓

Russian Federation ✓

San Marino ✓

Serbia ✓

Slovakia ✓

Slovenia ✓

Spain ✓

Sweden ✓
Country/Region Coverage

Switzerland ✓

Türkiye ✓

Ukraine ✓

United Kingdom ✓

Vatican City ✓

Middle East & Africa


Country/Region Coverage

Algeria ✓

Angola ✓

Bahrain ✓

Benin ✓

Botswana ✓

Burkina Faso ✓

Burundi ✓

Cameroon ✓

Congo ✓

Democratic Republic of Congo ✓

Egypt ✓

Gabon ✓

Ghana ✓

Iraq ✓

Jordan ✓

Kenya ✓

Kuwait ✓

Lebanon ✓
Country/Region Coverage

Lesotho ✓

Malawi ✓

Mali ✓

Mauritania ✓

Mauritius ✓

Mayotte ✓

Morocco ✓

Mozambique ✓

Namibia ✓

Niger ✓

Nigeria ✓

Oman ✓

Qatar ✓

Reunion ✓

Rwanda ✓

Saudi Arabia ✓

Senegal ✓

South Africa ✓

Swaziland ✓

Tanzania ✓

Togo ✓

Tunisia ✓

Uganda ✓

United Arab Emirates ✓

Yemen ✓

Zambia ✓
Country/Region Coverage

Zimbabwe ✓

Next steps
Zoom levels and tile grid

Get map tiles

Azure Maps routing coverage


Azure Maps Route service coverage
06/13/2025

This article provides coverage information for the Azure Maps Route service. Upon a search
query, Azure Maps returns an optimal route from location A to location B. You're provided with
accurate travel times, live updates of travel information, and route instructions. You can also
add more search parameters such as current traffic, vehicle type, and conditions to avoid. The
optimization of the route depends on the region. That's because, Azure Maps has various levels
of information and accuracy for different regions. The tables in this article list the regions and
what kind of information you can request for them.

Calculate Route
The Calculate Route service calculates a route between an origin and a destination, passing
through waypoints if they're specified. For more information, see Get Route Directions in the
REST API documentation.

Calculate Reachable Range


The Calculate Reachable Range service calculates a set of locations that can be reached from
the origin point. For more information, see Get Route Range in the REST API documentation.

Matrix Routing
The Matrix Routing service calculates travel time and distance between all possible pairs in a
list of origins and destinations. It doesn't provide any detailed information about the routes.
You can get one-to-many, many-to-one, or many-to-many route options simply by varying the
number of origins and/or destinations. For more information, see Matrix Routing service in the
REST API documentation.

Traffic
Delivers real-time information to show current traffic conditions, including congestion,
accidents, road closures, and a detailed view of the current speed and travel times across the
entire road network. For more information, see Traffic service in the REST API documentation.

Truck routes
The Azure Maps Truck Routing API provides travel routes that take truck attributes into
consideration. Truck attributes include things such as width, height, weight, turning radius and
type of cargo. This is important as not all trucks can travel the same routes as other vehicles.
Here are some examples:

Bridges have heights and weight limits.


Tunnels often have restrictions on flammable or hazardous materials.
Longer trucks have difficulty making tight turns.
Highways often have a separate speed limit for trucks.
Certain trucks may want to avoid roads that have steep gradients.

Azure Maps supports truck routing in the countries/regions indicated in the following tables.

Azure Maps Route service coverage tables


The following tables provide coverage information for version 1 of the Azure Maps routing
service:

Americas

ノ Expand table

Country/Region Calculate Route, Reachable Range & Real-time Truck


Matrix Routing Traffic Route

Anguilla ✓

Antigua & Barbuda ✓

Argentina ✓ ✓ ✓

Aruba ✓

Bahamas ✓

Barbados ✓

Belize ✓

Bermuda ✓

Bolivia ✓

Bonaire, Sint Eustatius, & Saba ✓

Brazil ✓ ✓ ✓
Country/Region Calculate Route, Reachable Range & Real-time Truck
Matrix Routing Traffic Route

British Virgin Islands ✓

Canada ✓ ✓ ✓

Cayman Islands ✓

Chile ✓ ✓

Colombia ✓ ✓

Costa Rica ✓

Cuba ✓

Curaçao ✓

Dominica ✓

Dominican Republic ✓

Ecuador ✓

El Salvador ✓

Falkland Islands ✓

French Guiana ✓

Grenada ✓

Guadeloupe ✓

Guatemala ✓

Guyana ✓

Haiti ✓

Honduras ✓

Jamaica ✓

Martinique ✓

Mexico ✓ ✓ ✓

Montserrat ✓

Nicaragua ✓

Panama ✓
Country/Region Calculate Route, Reachable Range & Real-time Truck
Matrix Routing Traffic Route

Paraguay ✓

Peru ✓ ✓

Puerto Rico ✓

Sint Maarten ✓

South Georgia & South ✓


Sandwich Islands

St. Barthélemy ✓

St. Kitts & Nevis ✓

St. Lucia ✓

St. Martin ✓

St. Pierre & Miquelon ✓

St. Vincent & Grenadines ✓

Suriname ✓

Trinidad & Tobago ✓

Turks & Caicos Islands ✓

U.S. Virgin Islands ✓

United States ✓ ✓ ✓

Uruguay ✓ ✓ ✓

Venezuela ✓

Asia Pacific

ノ Expand table

Country/Region Calculate Route, Reachable Range & Matrix Real-time Truck


Routing Traffic Route

American Samoa ✓

Australia ✓ ✓ ✓
Country/Region Calculate Route, Reachable Range & Matrix Real-time Truck
Routing Traffic Route

Bangladesh ✓

Bhutan ✓

Brunei ✓ ✓

Cambodia ✓

China ✓

Christmas Island ✓

Cocos (Keeling) Islands ✓

Comoros ✓

Cook Islands ✓

Fiji ✓

French Polynesia ✓

Guam ✓

Hong Kong SAR ✓ ✓

India ✓ ✓

Indonesia ✓ ✓ ✓

Kiribati ✓

Laos ✓

Macao SAR ✓ ✓

Malaysia ✓ ✓ ✓

Micronesia ✓

Mongolia ✓

Myanmar ✓

Nauru ✓

Nepal ✓

New Caledonia ✓

New Zealand ✓ ✓ ✓
Country/Region Calculate Route, Reachable Range & Matrix Real-time Truck
Routing Traffic Route

Niue ✓

Norfolk Island ✓

Northern Mariana ✓
Islands

Pakistan ✓

Palau ✓

Papua New Guinea ✓

Philippines ✓ ✓ ✓

Pitcairn Islands ✓

Samoa ✓

Singapore ✓ ✓ ✓

Solomon Islands ✓

Sri Lanka ✓

Taiwan ✓ ✓ ✓

Thailand ✓ ✓ ✓

Timor-Leste ✓

Tokelau ✓

Tonga ✓

Tuvalu ✓

Vanuatu ✓

Vietnam ✓ ✓ ✓

Wallis & Futuna ✓

Europe

ノ Expand table
Country/Region Calculate Route, Reachable Range & Matrix Real-time Truck
Routing Traffic Route

Albania ✓ ✓

Andorra ✓ ✓ ✓

Armenia ✓

Austria ✓ ✓ ✓

Azerbaijan ✓

Belarus ✓ ✓

Belgium ✓ ✓ ✓

Bosnia & ✓ ✓ ✓
Herzegovina

Bouvet Island ✓

Bulgaria ✓ ✓ ✓

Croatia ✓ ✓ ✓

Cyprus ✓ ✓

Czech Republic ✓ ✓ ✓

Denmark ✓ ✓ ✓

Estonia ✓ ✓ ✓

Faroe Islands ✓

Finland ✓ ✓ ✓

France ✓ ✓ ✓

Georgia ✓

Germany ✓ ✓ ✓

Gibraltar ✓ ✓ ✓

Greece ✓ ✓ ✓

Greenland ✓

Guernsey ✓

Hungary ✓ ✓ ✓
Country/Region Calculate Route, Reachable Range & Matrix Real-time Truck
Routing Traffic Route

Iceland ✓ ✓

Ireland ✓ ✓ ✓

Isle of Man ✓

Italy ✓ ✓ ✓

Jersey ✓

Kazakhstan ✓ ✓

Kyrgyzstan ✓

Latvia ✓ ✓ ✓

Liechtenstein ✓ ✓ ✓

Lithuania ✓ ✓ ✓

Luxembourg ✓ ✓ ✓

Malta ✓ ✓ ✓

Moldova ✓

Monaco ✓ ✓ ✓

Montenegro ✓ ✓

Netherlands ✓ ✓ ✓

North Macedonia ✓

Norway ✓ ✓ ✓

Poland ✓ ✓ ✓

Portugal ✓ ✓ ✓

Romania ✓ ✓ ✓

Russia ✓ ✓ ✓

San Marino ✓ ✓ ✓

Serbia ✓ ✓ ✓

Slovakia ✓ ✓ ✓

Slovenia ✓ ✓ ✓
Country/Region Calculate Route, Reachable Range & Matrix Real-time Truck
Routing Traffic Route

Spain ✓ ✓ ✓

Sweden ✓ ✓ ✓

Switzerland ✓ ✓ ✓

Tajikistan ✓

Türkiye ✓ ✓ ✓

Turkmenistan ✓

Ukraine ✓ ✓

United Kingdom ✓ ✓ ✓

Uzbekistan ✓

Vatican City ✓ ✓ ✓

Middle East & Africa

ノ Expand table

Country/Region Calculate Route, Reachable Range & Real-time Truck


Matrix Routing Traffic Route

Afghanistan ✓

Algeria ✓

Angola ✓

Bahrain ✓ ✓

Benin ✓

Botswana ✓

Burkina Faso ✓

Burundi ✓

Cameroon ✓

Cabo Verde ✓

Central African Republic ✓


Country/Region Calculate Route, Reachable Range & Real-time Truck
Matrix Routing Traffic Route

Chad ✓

Congo ✓

Congo (DRC) ✓

Côte d'Ivoire ✓

Djibouti ✓

Egypt ✓ ✓

Equatorial Guinea ✓

Eritrea ✓

Ethiopia ✓

French Southern Territories ✓

Gabon ✓

Gambia ✓

Ghana ✓

Guinea ✓

Guinea-Bissau ✓

Iran ✓

Iraq ✓

Israel ✓ ✓ ✓

Jordan ✓

Kenya ✓ ✓

Kuwait ✓ ✓

Lebanon ✓

Lesotho ✓ ✓

Liberia ✓

Libya ✓

Madagascar ✓
Country/Region Calculate Route, Reachable Range & Real-time Truck
Matrix Routing Traffic Route

Malawi ✓

Maldives ✓

Mali ✓

Marshall Islands ✓

Mauritania ✓

Mauritius ✓

Mayotte ✓

Morocco ✓ ✓

Mozambique ✓ ✓

Namibia ✓

Niger ✓

Nigeria ✓ ✓

Oman ✓ ✓

Qatar ✓ ✓

Réunion ✓

Rwanda ✓

São Tomé & Príncipe ✓

Saudi Arabia ✓ ✓

Senegal ✓

Seychelles ✓

Sierra Leone ✓

Somalia ✓

South Africa ✓ ✓ ✓

South Sudan ✓

St. Helena, Ascension, and Tristan ✓


da Cunha
Country/Region Calculate Route, Reachable Range & Real-time Truck
Matrix Routing Traffic Route

Sudan ✓

Swaziland ✓

Syria ✓

Tanzania ✓

Togo ✓

Tunisia ✓

Uganda ✓

United Arab Emirates ✓ ✓

Yemen ✓

Zambia ✓

Zimbabwe ✓

Next steps
For more information about Azure Maps routing, see the Routing service documentation.

For more coverage tables, see:

Check out coverage for Geocoding.


Check out coverage for Traffic.
Check out coverage for Render.
Azure Maps weather services coverage
Article • 03/26/2023

This article provides coverage information for Azure Maps Weather services.

Weather information supported

Infrared satellite tiles


Infrared satellite imagery, showing clouds by their temperature, is returned when
tilesetID is set to microsoft.weather.infrared.main when making calls to Get Map Tile

and can then be overlaid on the map image.

Minute forecast
The Get Minute forecast service returns minute-by-minute forecasts for the specified
location for the next 120 minutes.

Radar tiles
Radar tiles, showing areas of rain, snow, ice and mixed conditions, are returned when
tilesetID is set to microsoft.weather.radar.main when making calls to Get Map Tile

and can then be overlaid on the map image.

Severe weather alerts


Severe weather alerts service returns severe weather alerts from both official
Government Meteorological Agencies and other leading severe weather alert providers.
The service can return details such as alert type, category, level and detailed description.
Severe weather includes conditions like hurricanes, tornados, tsunamis, severe
thunderstorms, and fires.

Other
Air quality. The Air Quality service returns current, hourly or daily forecasts that
include pollution levels, air quality index values, the dominant pollutant, and a brief
statement summarizing risk level and suggested precautions.
Current conditions. The Get Current Conditions service returns detailed current
weather conditions such as precipitation, temperature and wind for a given
coordinate location.
Daily forecast. The Get Daily Forecast service returns detailed weather forecasts
such as temperature and wind by day for the next 1, 5, 10, 15, 25, or 45 days for a
given coordinate location.
Daily indices. The Get Daily Indices service returns index values that provide
information that can help in planning activities. For example, a health mobile
application can notify users that today is good weather for running or playing golf.
Historical weather. The Historical Weather service includes Daily Historical
Records, Actuals and Normals that return climatology data such as past daily
record temperatures, precipitation and snowfall at a given coordinate location.
Hourly forecast. The Get Hourly Forecast service returns detailed weather forecast
information by the hour for up to 10 days.
Quarter-day forecast. The Get Quarter Day Forecast service returns detailed
weather forecast by quarter-day for up to 15 days.
Tropical storms. The Tropical Storm service provides information about active
storms, tropical storm forecasts and locations and the ability to search for tropical
storms by year, basin ID, or government ID.
Weather along route. The Get Weather Along Route service returns hyper local (1
kilometer or less), up-to-the-minute weather nowcasts, weather hazard
assessments, and notifications along a route described as a sequence of waypoints.

Azure Maps Weather coverage tables

7 Note

Azure Maps doesn't have the same level of detail and accuracy for all countries and
regions.

Americas
Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Anguilla ✓ ✓ ✓

Antarctica ✓ ✓

Antigua & Barbuda ✓ ✓ ✓


Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Argentina ✓ ✓ ✓

Aruba ✓ ✓ ✓

Bahamas ✓ ✓ ✓

Barbados ✓ ✓ ✓

Belize ✓ ✓ ✓

Bermuda ✓ ✓

Bolivia ✓ ✓ ✓

Bonaire ✓ ✓ ✓

Brazil ✓ ✓ ✓ ✓

British Virgin Islands ✓ ✓ ✓

Canada ✓ ✓ ✓ ✓

Cayman Islands ✓ ✓ ✓

Chile ✓ ✓ ✓

Colombia ✓ ✓ ✓

Costa Rica ✓ ✓ ✓

Cuba ✓ ✓ ✓

Curaçao ✓ ✓ ✓

Dominica ✓ ✓ ✓

Dominican Republic ✓ ✓ ✓

Ecuador ✓ ✓ ✓

El Salvador ✓ ✓ ✓

Falkland Islands ✓ ✓ ✓

French Guiana ✓ ✓ ✓

Greenland ✓ ✓

Grenada ✓ ✓ ✓

Guadeloupe ✓ ✓ ✓
Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Guatemala ✓ ✓ ✓

Guyana ✓ ✓ ✓

Haiti ✓ ✓ ✓

Honduras ✓ ✓ ✓

Jamaica ✓ ✓ ✓

Martinique ✓ ✓ ✓

Mexico ✓ ✓ ✓

Montserrat ✓ ✓ ✓

Nicaragua ✓ ✓ ✓

Panama ✓ ✓ ✓

Paraguay ✓ ✓ ✓

Peru ✓ ✓ ✓

Puerto Rico ✓ ✓ ✓ ✓

Saint Barthélemy ✓ ✓ ✓

Saint Kitts & Nevis ✓ ✓ ✓

Saint Lucia ✓ ✓ ✓

Saint Martin ✓ ✓ ✓

Saint Pierre & Miquelon ✓ ✓

Saint Vincent & the ✓ ✓ ✓


Grenadines

Sint Eustatius ✓ ✓

Sint Maarten ✓ ✓ ✓

South Georgia & South ✓ ✓


Sandwich Islands

Suriname ✓ ✓ ✓

Trinidad & Tobago ✓ ✓ ✓


Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Turks & Caicos Islands ✓ ✓ ✓

U.S. Outlying Islands ✓ ✓

U.S. Virgin Islands ✓ ✓ ✓ ✓

United States ✓ ✓ ✓ ✓

Uruguay ✓ ✓ ✓

Venezuela ✓ ✓ ✓

Asia Pacific
Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Afghanistan ✓ ✓ ✓

American Samoa ✓ ✓ ✓

Australia ✓ ✓ ✓ ✓

Bangladesh ✓ ✓ ✓

Bhutan ✓ ✓ ✓

British Indian Ocean ✓ ✓


Territory

Brunei ✓ ✓ ✓

Cambodia ✓ ✓ ✓

China ✓ ✓ ✓ ✓

Christmas Island ✓ ✓

Cocos (Keeling) Islands ✓ ✓

Cook Islands ✓ ✓

Fiji ✓ ✓

French Polynesia ✓ ✓

Guam ✓ ✓ ✓ ✓
Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Heard Island & ✓ ✓


McDonald Islands

Hong Kong SAR ✓ ✓ ✓

India ✓ ✓ ✓

Indonesia ✓ ✓ ✓

Japan ✓ ✓ ✓ ✓

Kazakhstan ✓ ✓ ✓

Kiribati ✓ ✓

Korea ✓ ✓ ✓ ✓

Kyrgyzstan ✓ ✓ ✓

Laos ✓ ✓ ✓

Macao SAR ✓ ✓ ✓

Malaysia ✓ ✓ ✓

Maldives ✓ ✓

Marshall Islands ✓ ✓ ✓

Micronesia ✓ ✓ ✓

Mongolia ✓ ✓

Myanmar ✓ ✓

Nauru ✓ ✓

Nepal ✓ ✓ ✓

New Caledonia ✓ ✓

New Zealand ✓ ✓ ✓ ✓

Niue ✓ ✓

Norfolk Island ✓ ✓

North Korea ✓ ✓ ✓

Northern Mariana Islands ✓ ✓ ✓ ✓


Country/Region Infrared satellite & Minute Severe weather Other*
Radar tiles forecast alerts

Pakistan ✓ ✓ ✓

Palau ✓ ✓ ✓ ✓

Papua New Guinea ✓ ✓ ✓

Philippines ✓ ✓ ✓ ✓

Pitcairn Islands ✓ ✓

Samoa ✓ ✓

Singapore ✓ ✓ ✓

Solomon Islands ✓ ✓

Sri Lanka ✓ ✓ ✓

Taiwan ✓ ✓ ✓

Tajikistan ✓ ✓ ✓

Thailand ✓ ✓ ✓

Timor-Leste ✓ ✓ ✓

Tokelau ✓ ✓

Tonga ✓ ✓

Turkmenistan ✓ ✓ ✓

Tuvalu ✓ ✓

Uzbekistan ✓ ✓ ✓

Vanuatu ✓ ✓

Vietnam ✓ ✓ ✓

Wallis & Futuna ✓ ✓

Europe
Country/Region Infrared satellite & Radar Minute Severe weather Other*
tiles forecast alerts

Albania ✓ ✓ ✓
Country/Region Infrared satellite & Radar Minute Severe weather Other*
tiles forecast alerts

Andorra ✓ ✓ ✓ ✓

Armenia ✓ ✓ ✓

Austria ✓ ✓ ✓ ✓

Azerbaijan ✓ ✓ ✓

Belarus ✓ ✓ ✓

Belgium ✓ ✓ ✓ ✓

Bosnia & ✓ ✓ ✓ ✓
Herzegovina

Bulgaria ✓ ✓ ✓ ✓

Croatia ✓ ✓ ✓ ✓

Cyprus ✓ ✓ ✓ ✓

Czechia ✓ ✓ ✓ ✓

Denmark ✓ ✓ ✓ ✓

Estonia ✓ ✓ ✓ ✓

Faroe Islands ✓ ✓

Finland ✓ ✓ ✓ ✓

France ✓ ✓ ✓ ✓

Georgia ✓ ✓ ✓

Germany ✓ ✓ ✓ ✓

Gibraltar ✓ ✓ ✓

Greece ✓ ✓ ✓ ✓

Guernsey ✓ ✓

Hungary ✓ ✓ ✓ ✓

Iceland ✓ ✓ ✓

Ireland ✓ ✓ ✓ ✓

Isle of Man ✓ ✓
Country/Region Infrared satellite & Radar Minute Severe weather Other*
tiles forecast alerts

Italy ✓ ✓ ✓ ✓

Jan Mayen ✓ ✓

Jersey ✓ ✓

Kosovo ✓ ✓ ✓ ✓

Latvia ✓ ✓ ✓

Liechtenstein ✓ ✓ ✓ ✓

Lithuania ✓ ✓ ✓

Luxembourg ✓ ✓ ✓ ✓

North Macedonia ✓ ✓ ✓

Malta ✓ ✓ ✓

Moldova ✓ ✓ ✓ ✓

Monaco ✓ ✓ ✓ ✓

Montenegro ✓ ✓ ✓ ✓

Netherlands ✓ ✓ ✓ ✓

Norway ✓ ✓ ✓ ✓

Poland ✓ ✓ ✓ ✓

Portugal ✓ ✓ ✓ ✓

Romania ✓ ✓ ✓ ✓

Russia ✓ 1 ✓ ✓

San Marino ✓ ✓ ✓

Serbia ✓ ✓ ✓ ✓

Slovakia ✓ ✓ ✓ ✓

Slovenia ✓ ✓ ✓ ✓

Spain ✓ ✓ ✓ ✓

Svalbard ✓ ✓

Sweden ✓ ✓ ✓ ✓
Country/Region Infrared satellite & Radar Minute Severe weather Other*
tiles forecast alerts

Switzerland ✓ ✓ ✓ ✓

Türkiye ✓ ✓ ✓

Ukraine ✓ ✓ ✓

United Kingdom ✓ ✓ ✓ ✓

Vatican City ✓ ✓ ✓

1 Partial coverage includes Moscow and Saint Petersburg

Middle East & Africa


Country/Region Infrared satellite & Minute Severe Other*
Radar tiles forecast weather alerts

Algeria ✓ ✓ ✓

Angola ✓ ✓ ✓

Bahrain ✓ ✓ ✓

Benin ✓ ✓ ✓

Botswana ✓ ✓ ✓

Bouvet Island ✓ ✓

Burkina Faso ✓ ✓ ✓

Burundi ✓ ✓ ✓

Cameroon ✓ ✓ ✓

Cape Verde ✓ ✓ ✓

Central African Republic ✓ ✓ ✓

Chad ✓ ✓ ✓

Comoros ✓ ✓ ✓

Congo (DRC) ✓ ✓ ✓

Côte d'Ivoire ✓ ✓ ✓

Djibouti ✓ ✓ ✓
Country/Region Infrared satellite & Minute Severe Other*
Radar tiles forecast weather alerts

Egypt ✓ ✓ ✓

Equatorial Guinea ✓ ✓ ✓

Eritrea ✓ ✓ ✓

Eswatini ✓ ✓ ✓

Ethiopia ✓ ✓ ✓

French Southern Territories ✓ ✓

Gabon ✓ ✓ ✓

Gambia ✓ ✓ ✓

Ghana ✓ ✓ ✓

Guinea ✓ ✓ ✓

Guinea-Bissau ✓ ✓ ✓

Iran ✓ ✓ ✓

Iraq ✓ ✓ ✓

Israel ✓ ✓ ✓ ✓

Jordan ✓ ✓ ✓

Kenya ✓ ✓ ✓

Kuwait ✓ ✓ ✓

Lebanon ✓ ✓ ✓

Lesotho ✓ ✓ ✓

Liberia ✓ ✓ ✓

Libya ✓ ✓ ✓

Madagascar ✓ ✓ ✓

Malawi ✓ ✓ ✓

Mali ✓ ✓ ✓

Mauritania ✓ ✓ ✓

Mauritius ✓ ✓ ✓
Country/Region Infrared satellite & Minute Severe Other*
Radar tiles forecast weather alerts

Mayotte ✓ ✓ ✓

Morocco ✓ ✓

Mozambique ✓ ✓ ✓

Namibia ✓ ✓ ✓

Niger ✓ ✓ ✓

Nigeria ✓ ✓ ✓

Oman ✓ ✓ ✓

Palestinian Authority ✓ ✓ ✓

Qatar ✓ ✓ ✓

Réunion ✓ ✓ ✓

Rwanda ✓ ✓ ✓

Saint Helena, Ascension, ✓ ✓ ✓


Tristan da Cunha

São Tomé & Príncipe ✓ ✓ ✓

Saudi Arabia ✓ ✓ ✓

Senegal ✓ ✓ ✓

Seychelles ✓ ✓ ✓

Sierra Leone ✓ ✓ ✓

Somalia ✓ ✓ ✓

South Africa ✓ ✓ ✓

South Sudan ✓ ✓ ✓

Sudan ✓ ✓ ✓

Syria ✓ ✓ ✓

Tanzania ✓ ✓ ✓

Togo ✓ ✓ ✓

Tunisia ✓ ✓ ✓
Country/Region Infrared satellite & Minute Severe Other*
Radar tiles forecast weather alerts

Uganda ✓ ✓ ✓

United Arab Emirates ✓ ✓ ✓

Yemen ✓ ✓ ✓

Zambia ✓ ✓ ✓

Zimbabwe ✓ ✓ ✓

Next steps
Weather services in Azure Maps

Azure Maps weather services frequently asked questions (FAQ)


Localization support in Azure Maps
06/13/2025

Azure Maps supports various languages and views based on country/region. This article
provides the supported languages and views to help guide your Azure Maps implementation.

Azure Maps supported languages

7 Note

For supported cultures, street names are localized to the local language. For instance, if
you request a location in France, the street names are in French. However, the level of
localization for other data, such as country or region names, can vary by culture. For
example, not every culture code can have a localized name for 'United States.'

Azure Maps is localized in variety languages across its services. The following table provides
the supported language codes for each service.

Azure Maps offers localization in a wide range of languages across its various services. The
following table lists the supported language codes for previous versions of its services. The
Route column includes routes for driving, truck routes, and walking.

ノ Expand table

Culture Language Render Search Route Traffic Weather

af-ZA Afrikaans ✓ ✓

ar Arabic ✓ ✓ ✓ ✓ ✓

bg-BG Bulgarian ✓ ✓ ✓ ✓

bn-BD Bangla (Bangladesh) ✓

bn-IN Bangla (India) ✓

bs-BA Bosnian ✓

ca-ES Catalan ✓ ✓

cs-CZ Czech ✓ ✓ ✓ ✓ ✓

da-DK Danish ✓ ✓ ✓ ✓ ✓
Culture Language Render Search Route Traffic Weather

de-DE German ✓ ✓ ✓ ✓ ✓

el-GR Greek ✓ ✓ ✓ ✓ ✓

en-AU English (Australia) ✓ ✓ ✓

en-NZ English (New Zealand) ✓ ✓ ✓ ✓

en-GB English (United Kingdom) ✓ ✓ ✓ ✓ ✓

en-US English (USA) ✓ ✓ ✓ ✓ ✓

es-419 Spanish (Latin America) ✓ ✓

es-ES Spanish (Spain) ✓ ✓ ✓ ✓ ✓

es-MX Spanish (Mexico) ✓ ✓ ✓

et-EE Estonian ✓ ✓ ✓

eu-ES Basque ✓

fi-FI Finnish ✓ ✓ ✓ ✓ ✓

fil-PH Filipino ✓

fr-CA French (Canada) ✓ ✓

fr-FR French (France) ✓ ✓ ✓ ✓ ✓

gl-ES Galician ✓

gu-IN Gujarati ✓

he-IL Hebrew ✓ ✓ ✓

hi-IN Hindi ✓

hr-HR Croatian ✓ ✓

hu-HU Hungarian ✓ ✓ ✓ ✓ ✓

id-ID Indonesian ✓ ✓ ✓ ✓ ✓

is-IS Icelandic ✓

it-IT Italian ✓ ✓ ✓ ✓ ✓

ja-JP Japanese ✓

kk-KZ Kazakh ✓ ✓
Culture Language Render Search Route Traffic Weather

kn-IN Kannada ✓

ko-KR Korean ✓ ✓ ✓

lt-LT Lithuanian ✓ ✓ ✓ ✓ ✓

lv-LV Latvian ✓ ✓ ✓

mk-MK Macedonian ✓

mr-IN Marathi ✓

ms-MY Malay ✓ ✓ ✓ ✓

nb-NO Norwegian Bokmål ✓ ✓ ✓ ✓ ✓

NGT Neutral Ground Truth (Local)1 ✓ ✓

NGT-Latn Neutral Ground Truth (Latin)2 ✓ ✓

nl-BE Dutch (Belgium) ✓ ✓

nl-NL Dutch (Netherlands) ✓ ✓ ✓ ✓ ✓

pa-IN Punjabi ✓

pl-PL Polish ✓ ✓ ✓ ✓ ✓

pt-BR Portuguese (Brazil) ✓ ✓ ✓ ✓

pt-PT Portuguese (Portugal) ✓ ✓ ✓ ✓ ✓

ro-RO Romanian ✓ ✓ ✓

ru-RU Russian ✓ ✓ ✓ ✓ ✓

sk-SK Slovak ✓ ✓ ✓ ✓ ✓

sl-SI Slovenian ✓ ✓ ✓ ✓

sr-Cyrl-RS Serbian (Cyrillic) ✓ ✓

sr-Latn-RS Serbian (Latin) ✓

sv-SE Swedish ✓ ✓ ✓ ✓ ✓

ta-IN Tamil ✓

te-IN Telugu ✓

th-TH Thai ✓ ✓ ✓ ✓ ✓
Culture Language Render Search Route Traffic Weather

tr-TR Turkish ✓ ✓ ✓ ✓ ✓

uk-UA Ukrainian ✓ ✓

ur-PK Urdu ✓

uz-Latn-UZ Uzbek ✓

vi-VN Vietnamese ✓ ✓

zh-HanS-CN Chinese (Simplified, China) ✓ ✓ ✓

zh-HanT-HK Chinese (Traditional, Hong Kong SAR) ✓

zh-HanT-TW Chinese (Traditional, Taiwan) ✓ ✓ ✓ ✓

1
Neutral Ground Truth (Local) - Official languages for all regions in local scripts if available
2
Neutral Ground Truth (Latin) - Latin exonyms are used if available

Azure Maps supported views


You need to configure the View parameter as required for the REST APIs and the Web SDK, for
the services being used.

Azure Maps View parameter (also referred to as "user region parameter") is a two letter ISO-
3166 country/region Code that shows the correct maps for that country/region specifying
which set of geopolitically disputed content is returned via Azure Maps services, including
borders and labels displayed on the map.

REST APIs
Configuring the View parameter is required. This parameter determines which set of
geopolitically disputed content is returned by Azure Maps services.

Affected Azure Maps REST services:

Search

Get Search Fuzzy


Get Search POI
Get Search POI Category
Get Search Nearby
Get Search Address
Get Search Address Structured
Get Search Address Reverse
Get Search Address Reverse Cross Street
Post Search Inside Geometry
Post Search Address Batch
Post Search Address Reverse Batch
Post Search Along Route
Post Search Fuzzy Batch

Render

Get Map Tile


Get Map Image

SDKs
You need to have the latest version of Web SDK and configure the View parameter as required.
This parameter determines which set of geopolitically disputed content the Azure Maps service
returns.

By default, the View parameter is set to Unified, even if not defined in the request. Determine
the location of your users. Then, set the View parameter correctly for that location.
Alternatively, you can set 'View=Auto', which returns the map data based on the IP address of
the request. The View parameter in Azure Maps must be used in compliance with applicable
laws, including those laws about mapping of the country/region where maps, images, and
other data and third-party content that you're authorized to access via Azure Maps is made
available.

The following table provides supported views.

ノ Expand table

View Description Maps Search

AE United Arab Emirates (Arabic View) ✓

AR Argentina (Argentinian View) ✓ ✓

BH Bahrain (Arabic View) ✓

IN India (Indian View) ✓ ✓

IQ Iraq (Arabic View) ✓

JO Jordan (Arabic View) ✓

KW Kuwait (Arabic View) ✓


View Description Maps Search

LB Lebanon (Arabic View) ✓

MA Morocco (Moroccan View) ✓ ✓

OM Oman (Arabic View) ✓

PK Pakistan (Pakistani View) ✓ ✓

PS Palestinian Authority (Arabic View) ✓

QA Qatar (Arabic View) ✓

SA Saudi Arabia (Arabic View) ✓

SY Syria (Arabic View) ✓

YE Yemen (Arabic View) ✓

Auto Automatically detect based on request ✓ ✓

Unified Unified View (Others) ✓ ✓


Azure Maps supported built-in map
styles
Article • 03/31/2025

Azure Maps supports several different built-in map styles as described in this article.

road
A road map is a standard map that displays roads. It also displays natural and artificial
features, and the labels for those features.

Applicable APIs:

Get Map Static Image


Get Map Tile
Web SDK map control
Power BI visual

blank and blank_accessible


The blank and blank_accessible map styles provide a blank canvas for visualizing data.
The blank_accessible style continues to provide screen reader updates with map's
location details, even though the base map isn't displayed.

7 Note
In the Web SDK, you can change the background color of the map by setting the
CSS background-color style of map DIV element.

Applicable APIs:

Web SDK map control

satellite
The satellite style is a combination of satellite and aerial imagery.

Applicable APIs:

Get Map Tile


Web SDK map control
Power BI visual

satellite_road_labels
This map style is a hybrid of roads and labels overlaid on top of satellite and aerial
imagery.

Applicable APIs:

Web SDK map control


Power BI visual

grayscale_dark
grayscale dark is a dark version of the road map style.

Applicable APIs:

Get Map Static Image


Get Map Tile
Web SDK map control
Power BI visual

grayscale_light
grayscale light is a light version of the road map style.

Applicable APIs:

Web SDK map control


Power BI visual

night
night is a dark version of the road map style with colored roads and symbols.

Applicable APIs:

Web SDK map control


Power BI visual

road_shaded_relief
road shaded relief is an Azure Maps main style completed with contours of the Earth.

Applicable APIs:

Get Map Tile


Web SDK map control
Power BI visual

high_contrast_dark
high_contrast_dark is a dark map style with a higher contrast than the other styles.

Applicable APIs:

Web SDK map control


Power BI visual

high_contrast_light
high_contrast_light is a light map style with a higher contrast than the other styles.

Applicable APIs:

Web SDK map control


Power BI visual

Map style accessibility


The interactive Azure Maps map controls use vector tiles in the map styles to power the
screen reader to describe the area the map is displaying. Several map styles are also
designed to be fully accessible when it comes to color contrast. The following table
provides details on the accessibility features supported by each map style.

ノ Expand table

Map style Color Screen Notes


contrast reader

blank N/A No A blank canvas useful for developers who want to


use their own tiles as the base map, or want to
view their data without any background. The
screen reader doesn't rely on the vector tiles for
descriptions.

blank_accessible N/A Yes This map style continues to load the vector tiles
used to render the map, but makes that data
transparent. This way the data still loads, and can
be used to power the screen reader.

grayscale_dark Partial Yes Primarily designed for business intelligence


scenarios. Also useful for overlaying colorful layers
such as weather radar imagery.

grayscale_light Partial Yes This map style is primarily designed for business
intelligence scenarios.
Map style Color Screen Notes
contrast reader

high_contrast_dark Yes Yes Fully accessible map style for users in high contrast
mode with a dark setting. When the map loads,
high contrast settings are automatically detected.

high_contrast_light Yes Yes Fully accessible map style for users in high contrast
mode with a light setting. When the map loads,
high contrast settings are automatically detected.

night Partial Yes This style is designed for when the user is in low
light conditions and you don’t want to overwhelm
their senses with a bright map.

road Partial Yes The main colorful road map style in Azure Maps.
Due to the number of different colors and possible
overlapping color combinations, it's nearly
impossible to make it 100% accessible. That said,
this map style goes through regular accessibility
testing and is improved as needed to make labels
clearer to read.

road_shaded_relief Partial Yes Similar to the main road map style, but has an
added tile layer in the background that adds
shaded relief of mountains and land cover coloring
when zoomed out.

satellite N/A Yes Purely satellite and aerial imagery, no labels, or


road lines. The vector tiles are loaded behind the
scenes to power the screen reader and to make for
a smoother transition when switching to
satellite_with_roads .

satellite_with_roads No Yes Satellite and aerial imagery, with labels and road
lines overlaid. On a global scale, there's an
unlimited number of color combinations that
might occur between the overlaid data and the
imagery. A focus on making labels readable in
most common scenarios, however, in some places
the color contrast with the background imagery
might make labels difficult to read.

Next steps
Learn about how to set a map style in Azure Maps:

Choose a map style


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Zoom levels and tile grid
Article • 03/31/2025

Azure Maps use the Spherical Mercator projection coordinate system (EPSG:3857 ). A
projection is the mathematical model used to transform the spherical globe into a flat
map. The Spherical Mercator projection stretches the map at the poles to create a
square map. This projection significantly distorts the scale and area of the map but has
two important properties that outweigh this distortion:

It's a conformal projection, which means that it preserves the shape of relatively
small objects. Preserving the shape of small objects is especially important when
showing aerial imagery. For example, we want to avoid distorting the shape of
buildings. Square buildings should appear square, not rectangular.
It's a cylindrical projection. North and south are always up and down, and west and
east are always left and right.

To optimize the performance of map retrieval and display, the map is divided into
square tiles. The Azure Maps SDK's use tiles that have a size of 512 x 512 pixels for road
maps, and smaller 256 x 256 pixels for satellite imagery. Azure Maps provides raster and
vector tiles for 23 zoom levels, numbered 0 through 22. At zoom level 0, the entire world
fits on a single tile:

Zoom level 1 uses four tiles to render the world: a 2 x 2 square


Each additional zoom level quad-divides the tiles of the previous one, creating a grid of
2zoom x 2zoom. Zoom level 22 is a grid 222 x 222, or 4,194,304 x 4,194,304 tiles
(17,592,186,044,416 tiles in total).

The Azure Maps interactive map controls for web support 25 zoom levels, numbered 0
through 24. Although road data is only available at the zoom levels in when the tiles are
available.

The following table provides the full list of values for zoom levels where the tile size is
256 pixels square:

ノ Expand table

Zoom level Meters/pixel Meters/tile side

0 156543 40075017

1 78271.5 20037508

2 39135.8 10018754

3 19567.88 5009377.1

4 9783.94 2504688.5

5 4891.97 1252344.3

6 2445.98 626172.1
Zoom level Meters/pixel Meters/tile side

7 1222.99 313086.1

8 611.5 156543

9 305.75 78271.5

10 152.87 39135.8

11 76.44 19567.9

12 38.219 9783.94

13 19.109 4891.97

14 9.555 2445.98

15 4.777 1222.99

16 2.3887 611.496

17 1.1943 305.748

18 0.5972 152.874

19 0.2986 76.437

20 0.14929 38.2185

21 0.074646 19.10926

22 0.037323 9.55463

23 0.0186615 4.777315

24 0.00933075 2.3886575

Pixel coordinates
Having chosen the projection and scale to use at each zoom level, we can convert
geographic coordinates into pixel coordinates. The full pixel width and height of a map
image of the world for a particular zoom level is calculated as:

JavaScript

var mapWidth = tileSize * Math.pow(2, zoom);

var mapHeight = mapWidth;


Since the map width and height is different at each zoom level, so are the pixel
coordinates. The pixel at the upper-left corner of the map always has pixel coordinates
(0, 0). The pixel at the lower-right corner of the map has pixel coordinates (width-1,
height-1), or referring to the equations in the previous section, (tileSize * 2zoom–1, tileSize
* 2zoom–1). For example, when using 512 square tiles at level 2, the pixel coordinates
range from (0, 0) to (2047, 2047), like this:

Given latitude and longitude in degrees, and the level of detail, the pixel XY coordinates
is calculated as follows:

JavaScript

var sinLatitude = Math.sin(latitude * Math.PI/180);

var pixelX = ((longitude + 180) / 360) * tileSize * Math.pow(2, zoom);

var pixelY = (0.5 – Math.log((1 + sinLatitude) / (1 – sinLatitude)) / (4 *


Math.PI)) * tileSize * Math.pow(2, zoom);

The latitude and longitude values are assumed to be on the WGS 84 datum. Even
though Azure Maps uses a spherical projection, it's important to convert all geographic
coordinates into a common datum. WGS 84 is the selected datum. The longitude value
is assumed to range from -180 degrees to +180 degrees, and the latitude value must be
clipped to range from -85.05112878 to 85.05112878. Adhering to these values avoids a
singularity at the poles, and it ensures that the projected map is a squared shape.

Tile coordinates
To optimize the performance of map retrieval and display, the rendered map is cut into
tiles. The number of pixels and the number of tiles differ at each zoom level:

JavaScript

var numberOfTilesWide = Math.pow(2, zoom);

var numberOfTilesHigh = numberOfTilesWide;

Each tile is given XY coordinates ranging from (0, 0) in the upper left to (2zoom–1, 2zoom–
1) in the lower right. For example, at zoom level 3, the tile coordinates range from (0, 0)
to (7, 7) as follows:
Given a pair of pixel XY coordinates, you can easily determine the tile XY coordinates of
the tile containing that pixel:

JavaScript

var tileX = Math.floor(pixelX / tileSize);

var tileY = Math.floor(pixelY / tileSize);

Tiles are called by zoom level. The x and y coordinates correspond to the tile's position
on the grid for that zoom level.

When determining which zoom level to use, remember each location is in a fixed
position on its tile. As a result, the number of tiles needed to display a given expanse of
territory is dependent on the specific placement of zoom grid on the world map. For
instance, if there are two points 900 meters apart, it may only take three tiles to display
a route between them at zoom level 17. However, if the western point is on the right of
its tile, and the eastern point on the left of its tile, it may take four tiles:

Once the zoom level is determined, the x and y values can be calculated. The top-left tile
in each zoom grid is x=0, y=0; the bottom-right tile is at x=2zoom-1, y=2zoom-1.

Here's the zoom grid for zoom level 1:


Quadkey indices
Some mapping platforms use a quadkey indexing naming convention that combines the
tile ZY coordinates into a one-dimension string called quadtree keys or quadkeys for
short. Each quadkey uniquely identifies a single tile at a particular level of detail, and it
can be used as a key in common database B-tree indexes. The Azure Maps SDKs
support the overlaying of tile layers that use quadkey naming convention in addition to
other naming conventions as documented in the Add a tile layer document.

7 Note

The quadkeys naming convention only works for zoom levels of one or greater. The
Azure Maps SDK's support zoom level 0 which is a single map tile for the whole
world.

To convert tile coordinates into a quadkey , the bits of the Y and X coordinates are
interleaved, and the result is interpreted as a base-4 number (with leading zeros
maintained) and converted into a string. For instance, given tile XY coordinates of (3, 5)
at level 3, the quadkey is determined as follows:

tileX = 3 = 011 (base 2)

tileY = 5 = 101 (base 2)


quadkey = 100111 (base 2) = 213 (base 4) = "213"

Qquadkeys have several interesting properties. First, the length of a quadkey (the number

of digits) equals the zoom level of the corresponding tile. Second, the quadkey of any
tile starts with the quadkey of its parent tile (the containing tile at the previous level). As
shown in the following example, tile 2 is the parent of tiles 20 through 23:

Finally, quadkeys provide a one-dimensional index key that usually preserves the
proximity of tiles in XY space. In other words, two tiles that have nearby XY coordinates
usually have quadkeys that are relatively close together. This is important for optimizing
database performance, because neighboring tiles are often requested in groups, and it's
desirable to keep those tiles on the same disk blocks, in order to minimize the number
of disk reads.

Tile math source code


The following sample code illustrates how to implement the functions described in this
document. These functions can be easily translated into other programming languages
as needed.

C#
C#

using System;
using System.Text;

namespace AzureMaps
{
/// <summary>
/// Tile System math for the Spherical Mercator projection
coordinate system (EPSG:3857)
/// </summary>
public static class TileMath
{
//Earth radius in meters.
private const double EarthRadius = 6378137;

private const double MinLatitude = -85.05112878;


private const double MaxLatitude = 85.05112878;
private const double MinLongitude = -180;
private const double MaxLongitude = 180;

/// <summary>
/// Clips a number to the specified minimum and maximum values.
/// </summary>
/// <param name="n">The number to clip.</param>
/// <param name="minValue">Minimum allowable value.</param>
/// <param name="maxValue">Maximum allowable value.</param>
/// <returns>The clipped value.</returns>
private static double Clip(double n, double minValue, double
maxValue)
{
return Math.Min(Math.Max(n, minValue), maxValue);
}

/// <summary>
/// Calculates width and height of the map in pixels at a
specific zoom level from -180 degrees to 180 degrees.
/// </summary>
/// <param name="zoom">Zoom Level to calculate width at</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>Width and height of the map in pixels</returns>
public static double MapSize(double zoom, int tileSize)
{
return Math.Ceiling(tileSize * Math.Pow(2, zoom));
}

/// <summary>
/// Calculates the Ground resolution at a specific degree of
latitude in meters per pixel.
/// </summary>
/// <param name="latitude">Degree of latitude to calculate
resolution at</param>
/// <param name="zoom">Zoom level to calculate resolution
at</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>Ground resolution in meters per pixels</returns>
public static double GroundResolution(double latitude, double
zoom, int tileSize)
{
latitude = Clip(latitude, MinLatitude, MaxLatitude);
return Math.Cos(latitude * Math.PI / 180) * 2 * Math.PI *
EarthRadius / MapSize(zoom, tileSize);
}

/// <summary>
/// Determines the map scale at a specified latitude, level of
detail, and screen resolution.
/// </summary>
/// <param name="latitude">Latitude (in degrees) at which to
measure the map scale.</param>
/// <param name="zoom">Level of detail, from 1 (lowest detail)
to 23 (highest detail).</param>
/// <param name="screenDpi">Resolution of the screen, in dots
per inch.</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>The map scale, expressed as the denominator N of
the ratio 1 : N.</returns>
public static double MapScale(double latitude, double zoom, int
screenDpi, int tileSize)
{
return GroundResolution(latitude, zoom, tileSize) *
screenDpi / 0.0254;
}

/// <summary>
/// Global Converts a Pixel coordinate into a geospatial
coordinate at a specified zoom level.
/// Global Pixel coordinates are relative to the top left corner
of the map (90, -180)
/// </summary>
/// <param name="pixel">Pixel coordinates in the format of [x,
y].</param>
/// <param name="zoom">Zoom level</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>A position value in the format [longitude,
latitude].</returns>
public static double[] GlobalPixelToPosition(double[] pixel,
double zoom, int tileSize)
{
var mapSize = MapSize(zoom, tileSize);

var x = (Clip(pixel[0], 0, mapSize - 1) / mapSize) - 0.5;


var y = 0.5 - (Clip(pixel[1], 0, mapSize - 1) / mapSize);

return new double[] {


360 * x, //Longitude
90 - 360 * Math.Atan(Math.Exp(-y * 2 * Math.PI)) /
Math.PI //Latitude
};
}

/// <summary>
/// Converts a point from latitude/longitude WGS-84 coordinates
(in degrees) into pixel XY coordinates at a specified level of detail.
/// </summary>
/// <param name="position">Position coordinate in the format
[longitude, latitude]</param>
/// <param name="zoom">Zoom level.</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>A global pixel coordinate.</returns>
public static double[] PositionToGlobalPixel(double[] position,
int zoom, int tileSize)
{
var latitude = Clip(position[1], MinLatitude, MaxLatitude);
var longitude = Clip(position[0], MinLongitude,
MaxLongitude);

var x = (longitude + 180) / 360;


var sinLatitude = Math.Sin(latitude * Math.PI / 180);
var y = 0.5 - Math.Log((1 + sinLatitude) / (1 -
sinLatitude)) / (4 * Math.PI);

var mapSize = MapSize(zoom, tileSize);

return new double[] {


Clip(x * mapSize + 0.5, 0, mapSize - 1),
Clip(y * mapSize + 0.5, 0, mapSize - 1)
};
}

/// <summary>
/// Converts pixel XY coordinates into tile XY coordinates of
the tile containing the specified pixel.
/// </summary>
/// <param name="pixel">Pixel coordinates in the format of [x,
y].</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <param name="tileX">Output parameter receiving the tile X
coordinate.</param>
/// <param name="tileY">Output parameter receiving the tile Y
coordinate.</param>
public static void GlobalPixelToTileXY(double[] pixel, int
tileSize, out int tileX, out int tileY)
{
tileX = (int)(pixel[0] / tileSize);
tileY = (int)(pixel[1] / tileSize);
}
/// <summary>
/// Performs a scale transform on a global pixel value from one
zoom level to another.
/// </summary>
/// <param name="pixel">Pixel coordinates in the format of [x,
y].</param>
/// <param name="oldZoom">The zoom level in which the input
global pixel value is from.</param>
/// <returns>A scale pixel coordinate.</returns>
public static double[] ScaleGlobalPixel(double[] pixel, double
oldZoom, double newZoom)
{
var scale = Math.Pow(2, oldZoom - newZoom);

return new double[] { pixel[0] * scale, pixel[1] * scale };


}

/// <summary>
/// Performs a scale transform on a set of global pixel values
from one zoom level to another.
/// </summary>
/// <param name="pixels">A set of global pixel value from the
old zoom level. Points are in the format [x,y].</param>
/// <param name="oldZoom">The zoom level in which the input
global pixel values is from.</param>
/// <param name="newZoom">The new zoom level in which the output
global pixel values should be aligned with.</param>
/// <returns>A set of global pixel values that has been scaled
for the new zoom level.</returns>
public static double[][] ScaleGlobalPixels(double[][] pixels,
double oldZoom, double newZoom)
{
var scale = Math.Pow(2, oldZoom - newZoom);

var output = new System.Collections.Generic.List<double[]>


();
foreach (var p in pixels)
{
output.Add(new double[] { p[0] * scale, p[1] * scale });
}

return output.ToArray();
}

/// <summary>
/// Converts tile XY coordinates into a global pixel XY
coordinates of the upper-left pixel of the specified tile.
/// </summary>
/// <param name="tileX">Tile X coordinate.</param>
/// <param name="tileY">Tile Y coordinate.</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <param name="pixelX">Output parameter receiving the X
coordinate of the point, in pixels.</param>
/// <param name="pixelY">Output parameter receiving the Y
coordinate of the point, in pixels.</param>
public static double[] TileXYToGlobalPixel(int tileX, int tileY,
int tileSize)
{
return new double[] { tileX * tileSize, tileY * tileSize };
}

/// <summary>
/// Converts tile XY coordinates into a quadkey at a specified
level of detail.
/// </summary>
/// <param name="tileX">Tile X coordinate.</param>
/// <param name="tileY">Tile Y coordinate.</param>
/// <param name="zoom">Zoom level</param>
/// <returns>A string containing the quadkey.</returns>
public static string TileXYToQuadKey(int tileX, int tileY, int
zoom)
{
var quadKey = new StringBuilder();
for (int i = zoom; i > 0; i--)
{
char digit = '0';
int mask = 1 << (i - 1);
if ((tileX & mask) != 0)
{
digit++;
}
if ((tileY & mask) != 0)
{
digit++;
digit++;
}
quadKey.Append(digit);
}
return quadKey.ToString();
}

/// <summary>
/// Converts a quadkey into tile XY coordinates.
/// </summary>
/// <param name="quadKey">Quadkey of the tile.</param>
/// <param name="tileX">Output parameter receiving the tile X
coordinate.</param>
/// <param name="tileY">Output parameter receiving the tile Y
coordinate.</param>
/// <param name="zoom">Output parameter receiving the zoom
level.</param>
public static void QuadKeyToTileXY(string quadKey, out int
tileX, out int tileY, out int zoom)
{
tileX = tileY = 0;
zoom = quadKey.Length;
for (int i = zoom; i > 0; i--)
{
int mask = 1 << (i - 1);
switch (quadKey[zoom - i])
{
case '0':
break;

case '1':
tileX |= mask;
break;

case '2':
tileY |= mask;
break;

case '3':
tileX |= mask;
tileY |= mask;
break;

default:
throw new ArgumentException("Invalid QuadKey
digit sequence.");
}
}
}

/// <summary>
/// Calculates the XY tile coordinates that a coordinate falls
into for a specific zoom level.
/// </summary>
/// <param name="position">Position coordinate in the format
[longitude, latitude]</param>
/// <param name="zoom">Zoom level</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <param name="tileX">Output parameter receiving the tile X
position.</param>
/// <param name="tileY">Output parameter receiving the tile Y
position.</param>
public static void PositionToTileXY(double[] position, int zoom,
int tileSize, out int tileX, out int tileY)
{
var latitude = Clip(position[1], MinLatitude, MaxLatitude);
var longitude = Clip(position[0], MinLongitude,
MaxLongitude);

var x = (longitude + 180) / 360;


var sinLatitude = Math.Sin(latitude * Math.PI / 180);
var y = 0.5 - Math.Log((1 + sinLatitude) / (1 -
sinLatitude)) / (4 * Math.PI);

//tileSize needed in calculations as in rare cases the


multiplying/rounding/dividing can make the difference of a pixel which
can result in a completely different tile.
var mapSize = MapSize(zoom, tileSize);
tileX = (int)Math.Floor(Clip(x * mapSize + 0.5, 0, mapSize -
1) / tileSize);
tileY = (int)Math.Floor(Clip(y * mapSize + 0.5, 0, mapSize -
1) / tileSize);
}

/// <summary>
/// Calculates the tile quadkey strings that are within a
specified viewport.
/// </summary>
/// <param name="position">Position coordinate in the format
[longitude, latitude]</param>
/// <param name="zoom">Zoom level</param>
/// <param name="width">The width of the map viewport in pixels.
</param>
/// <param name="height">The height of the map viewport in
pixels.</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>A list of quadkey strings that are within the
specified viewport.</returns>
public static string[] GetQuadkeysInView(double[] position, int
zoom, int width, int height, int tileSize)
{
var p = PositionToGlobalPixel(position, zoom, tileSize);

var top = p[1] - height * 0.5;


var left = p[0] - width * 0.5;

var bottom = p[1] + height * 0.5;


var right = p[0] + width * 0.5;

var tl = GlobalPixelToPosition(new double[] { left, top },


zoom, tileSize);
var br = GlobalPixelToPosition(new double[] { right, bottom
}, zoom, tileSize);

//Boudning box in the format: [west, south, east, north];


var bounds = new double[] { tl[0], br[1], br[0], tl[1] };

return GetQuadkeysInBoundingBox(bounds, zoom, tileSize);


}

/// <summary>
/// Calculates the tile quadkey strings that are within a
bounding box at a specific zoom level.
/// </summary>
/// <param name="bounds">A bounding box defined as an array of
numbers in the format of [west, south, east, north].</param>
/// <param name="zoom">Zoom level to calculate tiles for.
</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>A list of quadkey strings.</returns>
public static string[] GetQuadkeysInBoundingBox(double[] bounds,
int zoom, int tileSize)
{
var keys = new System.Collections.Generic.List<string>();

if (bounds != null && bounds.Length >= 4)


{
PositionToTileXY(new double[] { bounds[3], bounds[0] },
zoom, tileSize, out int tlX, out int tlY);
PositionToTileXY(new double[] { bounds[1], bounds[2] },
zoom, tileSize, out int brX, out int brY);

for (int x = tlX; x <= brX; x++)


{
for (int y = tlY; y <= brY; y++)
{
keys.Add(TileXYToQuadKey(x, y, zoom));
}
}
}

return keys.ToArray();
}

/// <summary>
/// Calculates the bounding box of a tile.
/// </summary>
/// <param name="tileX">Tile X coordinate</param>
/// <param name="tileY">Tile Y coordinate</param>
/// <param name="zoom">Zoom level</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid.</param>
/// <returns>A bounding box of the tile defined as an array of
numbers in the format of [west, south, east, north].</returns>
public static double[] TileXYToBoundingBox(int tileX, int tileY,
double zoom, int tileSize)
{
//Top left corner pixel coordinates
var x1 = (double)(tileX * tileSize);
var y1 = (double)(tileY * tileSize);

//Bottom right corner pixel coordinates


var x2 = (double)(x1 + tileSize);
var y2 = (double)(y1 + tileSize);

var nw = GlobalPixelToPosition(new double[] { x1, y1 },


zoom, tileSize);
var se = GlobalPixelToPosition(new double[] { x2, y2 },
zoom, tileSize);

return new double[] { nw[0], se[1], se[0], nw[1] };


}

/// <summary>
/// Calculates the best map view (center, zoom) for a bounding
box on a map.
/// </summary>
/// <param name="bounds">A bounding box defined as an array of
numbers in the format of [west, south, east, north].</param>
/// <param name="mapWidth">Map width in pixels.</param>
/// <param name="mapHeight">Map height in pixels.</param>
/// <param name="latitude">Output parameter receiving the center
latitude coordinate.</param>
/// <param name="longitude">Output parameter receiving the
center longitude coordinate.</param>
/// <param name="zoom">Output parameter receiving the zoom
level</param>
/// <param name="padding">Width in pixels to use to create a
buffer around the map. This is to keep markers from being cut off on the
edge. Default: 0</param>
/// <param name="tileSize">The size of the tiles in the tile
pyramid. Default: 512</param>
/// <param name="maxZoom">Optional maximum zoom level to return.
Useful when the bounding box represents a very small area. Default:
24</param>
/// <param name="allowFloatZoom">Specifies if the returned zoom
level should be a float or rounded down to an whole integer zoom level.
Default: true</param>
public static void BestMapView(BoundingBox bounds, double
mapWidth, double mapHeight, out double centerLat, out double centerLon,
out double zoom, int padding = 0, int tileSize = 512, double maxZoom =
24, bool allowFloatZoom = true)
{
centerLat = 0;
centerLon = 0;
zoom = 0;

if (bounds != null && mapWidth > 0 && mapHeight > 0)


{
//Ensure padding is valid.
padding = Math.Abs(padding);

//Ensure max zoom is within valid range.


maxZoom = Clip(maxZoom, 0, 24);

//Do pixel calculations at zoom level 24 as that will


provide a high level of visual accuracy.
int pixelZoom = 24;

//Calculate mercator pixel coordinate at zoom level 24.


var wnPixel = PositionToGlobalPixel(new double[] {
bounds[0], bounds[3] }, pixelZoom, tileSize);
var esPixel = PositionToGlobalPixel(new double[] {
bounds[2], bounds[1] }, pixelZoom, tileSize);

//Calculate the pixel distance between pixels for each


axis.
double dx = esPixel[0] - wnPixel[0];
double dy = esPixel[1] - wnPixel[1];

//Calculate the average pixel positions to get the


visual center.
double xAvg = (esPixel[0] + wnPixel[0]) / 2;
double yAvg = (esPixel[1] + wnPixel[1]) / 2;

//Determine if the bounding box crosses the


antimeridian. (West pixel will be greater than East pixel).
if (wnPixel[0] > esPixel[0])
{
double mapSize = MapSize(24, tileSize);

//We are interested in the opposite area of the map.


Calculate the opposite area and visual center.
dx = mapSize - Math.Abs(dx);

//Offset the visual center by half the global map


width at zoom 24 on the x axis.
xAvg += mapSize / 2;
}

//Convert visual center pixel from zoom 24 to lngLat.


center = GlobalPixelToPosition(new Pixel(xAvg, yAvg),
pixelZoom, tileSize);

//Calculate scale of screen pixels per unit on the Web


Mercator plane.
double scaleX = (mapWidth - padding * 2) / Math.Abs(dx)
* Math.Pow(2, pixelZoom);
double scaleY = (mapHeight - padding * 2) / Math.Abs(dy)
* Math.Pow(2, pixelZoom);

//Calculate zoom levels based on the x/y scales. Choose


the most zoomed out value.
zoom = Math.Max(0, Math.Min(maxZoom,
Math.Log2(Math.Abs(Math.Min(scaleX, scaleY)))));

//Round down zoom level if float values are not desired.


if (!allowFloatZoom)
{
zoom = Math.Floor(zoom);
}
}

return new CameraOptions


{
Center = center,
Zoom = zoom
};
}
}
}

7 Note
The interactive map controls in the Azure Maps SDK's have helper functions for
converting between geospatial positions and viewport pixels.

Web SDK: Map pixel and position calculations

Next steps
Directly access map tiles from the Azure Maps REST services:

Get map tiles

Get traffic flow tiles

Get traffic incident tiles

Learn more about geospatial concepts:

Azure Maps glossary

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Weather services in Azure Maps
Article • 02/27/2023

This article introduces concepts that apply to Azure Maps Weather services. We
recommend going through this article before starting out with the weather APIs.

Unit types
Some of the Weather service APIs allow user to specify if the data is returned either in
metric or in imperial units. The returned responses for these APIs include unitType and a
numeric value that can be used for unit translations. See table below to interpret these
values.

unitType Description

0 feet

1 inches

2 miles

3 millimeter

4 centimeter

5 meter

6 kilometer

7 kilometersPerHour

8 knots

9 milesPerHour

10 metersPerSecond

11 hectoPascals

12 inchesOfMercury

13 kiloPascals

14 millibars

15 millimetersOfMercury

16 poundsPerSquareInch
unitType Description

17 celsius

18 fahrenheit

19 kelvin

20 percent

21 float

22 integer

31 MicrogramsPerCubicMeterOfAir

Weather icons
Some of the Weather service APIs return the iconCode in the response. The iconCode is
a numeric value used to define the icon. Don't link directly to these images from your
applications, the URLs can and will change.

Icon Number Icon Day Night Text

1 Yes No Sunny

2 Yes No Mostly Sunny

3 Yes No Partly Sunny

4 Yes No Intermittent Clouds

5 Yes No Hazy Sunshine

6 Yes No Mostly Cloudy

7 Yes Yes Cloudy


Icon Number Icon Day Night Text

8 Yes Yes Dreary (Overcast)

11 Yes Yes Fog

12 Yes Yes Showers

13 Yes No Mostly Cloudy with Showers

14 Yes No Partly Sunny with Showers

15 Yes Yes Thunderstorms

16 Yes No Mostly Cloudy with Thunderstorms

17 Yes No Partly Sunny with Thunderstorms

18 Yes Yes Rain

19 Yes Yes Flurries

20 Yes No Mostly Cloudy with Flurries

21 Yes No Partly Sunny with Flurries

22 Yes Yes Snow

23 Yes No Mostly Cloudy with Snow


Icon Number Icon Day Night Text

24 Yes Yes Ice

25 Yes Yes Sleet

26 Yes Yes Freezing Rain

29 Yes Yes Rain and Snow

30 Yes Yes Hot

31 Yes Yes Cold

32 Yes Yes Windy

33 No Yes Clear

34 No Yes Mostly Clear

35 No Yes Partly Cloudy

36 No Yes Intermittent Clouds

37 No Yes Hazy Moonlight

38 No Yes Mostly Cloudy

39 No Yes Partly Cloudy with Showers


Icon Number Icon Day Night Text

40 No Yes Mostly Cloudy with Showers

41 No Yes Partly Cloudy with Thunderstorms

42 No Yes Mostly Cloudy with Thunderstorms

43 No Yes Mostly Cloudy with Flurries

44 No Yes Mostly Cloudy with Snow

Radar and satellite imagery color scale


Via Get Map Tile v2 API users can request latest radar and infrared satellite images. See
below guide to help interpret colors used for radar and satellite tiles.

Radar Images
The table below provides guidance to interpret the radar images and create a map
legend for Radar tile data.

Hex color code Color sample Weather condition

#93c701 Rain-Light

#ffd701 Rain-Moderate

#f05514 Rain-Heavy

#dc250e Rain-Severe

#9ec8f2 Snow-Light

#2a8fdb Snow-Moderate

#144bed Snow-Heavy

#020096 Snow-Severe
Hex color code Color sample Weather condition

#e6a5c8 Ice-Light

#d24fa0 Ice-Moderate

#b71691 Ice-Severe

#7a1570 Ice-Heavy

#c196e6 Mix-Light

#ae6ee6 Mix-Moderate

#8a32d7 Mix-Heavy

#6500ba Mix-Severe

Detailed color palette for radar tiles with Hex color codes and dBZ values is shown
below. dBZ represents precipitation intensity in weather radar.

RAIN ICE SNOW MIXED

dBZ (color) dBZ (color) dBZ (color) dBZ (color)

1.25 (#93C701) 1.25 (#E6A5C8) 1.25 (#9EC8F2) 1.25 (#C196E6)

2.5 (#92C201) 2.5 (#E6A2C6) 2.5 (#98C5F0) 2.5 (#BF92E6)

3.75 (#92BE01) 3.75 (#E69FC5) 3.75 (#93C3EF) 3.75 (#BD8EE6)

5 (#92BA02) 5 (#E69DC4) 5 (#8DC1EE) 5 (#BB8BE6)

6.25 (#92B502) 6.25 (#E69AC2) 6.25 (#88BFEC) 6.25 (#BA87E6)

6.75 (#92B403) 7.5 (#E697C1) 7.5 (#82BDEB) 7.5 (#B883E6)

8 (#80AD02) 8.75 (#E695C0) 8.75 (#7DBAEA) 8.75 (#B680E6)

9.25 (#6FA602) 10 (#E692BE) 10 (#77B8E8) 10 (#B47CE6)

10.5 (#5EA002) 11.25 (#E68FBD) 11.25 (#72B6E7) 11.25 (#B378E6)

11.75 (#4D9902) 12.5 (#E68DBC) 12.5 (#6CB4E6) 12.5 (#B175E6)

12.25 (#479702) 13.75 (#E68ABA) 13.75 (#67B2E5) 13.75 (#AF71E6)

13.5 (#3D9202) 15 (#E687B9) 15 (#61AEE4) 15 (#AE6EE6)

14.75 (#338D02) 16.25 (#E685B8) 16.25 (#5BABE3) 16.25 (#AB6AE4)

16 (#298802) 17.5 (#E682B6) 17.5 (#56A8E2) 17.5 (#A967E3)


RAIN ICE SNOW MIXED

17.25 (#1F8302) 18.75 (#E67FB5) 18.75 (#50A5E1) 18.75 (#A764E2)

17.75 (#1B8103) 20 (#E67DB4) 20 (#4BA2E0) 20 (#A560E1)

19 (#187102) 21.25 (#E275B0) 21.25 (#459EDF) 21.25 (#A35DE0)

20.25 (#166102) 22.5 (#DF6DAD) 22.5 (#409BDE) 22.5 (#A15ADF)

20.75 (#165B02) 23.75 (#DC66AA) 23.75 (#3A98DD) 23.75 (#9F56DE)

22 (#135001) 25 (#D85EA6) 25 (#3595DC) 25 (#9D53DD)

23.25 (#114501) 26.25 (#D556A3) 26.25 (#2F92DB) 26.25 (#9B50DC)

24.5 (#0F3A01) 27.5 (#D24FA0) 27.5 (#2A8FDB) 27.5 (#9648DA)

25.75 (#124C01) 28.75 (#CE479E) 28.75 (#2581DE) 28.75 (#9241D9)

27 (#114401) 30 (#CB409C) 30 (#2173E2) 30 (#8E39D8)

28.25 (#0F3D01) 31.25 (#C7399A) 31.25 (#1C66E5) 31.25 (#8A32D7)

28.75 (#0F3A01) 32.5 (#C43298) 32.5 (#1858E9) 32.5 (#862ED2)

30 (#375401) 33.75 (#C12B96) 33.75 (#144BED) 33.75 (#832BCE)

31.25 (#5F6E01) 35 (#BD2494) 35 (#1348EA) 35 (#7F28C9)

32.5 (#878801) 36.25 (#BA1D92) 36.25 (#1246E7) 36.25 (#7C25C5)

33.75 (#AFA201) 37.5 (#B71691) 37.5 (#1144E4) 37.5 (#7822C1)

35 (#D7BC01) 38.75 (#B51690) 38.75 (#1142E1) 38.75 (#751FBC)

36.25 (#FFD701) 40 (#B3168F) 40 (#1040DE) 40 (#711CB8)

37.5 (#FEB805) 41.25 (#B1168E) 41.25 (#0F3EDB) 41.25 (#6E19B4)

38.75 (#FCAB06) 42.5 (#AF168D) 42.5 (#0F3CD8) 42.5 (#6D18B4)

40 (#FA9E07) 43.75 (#AD168C) 43.75 (#0E3AD5) 43.75 (#6D17B4)

41.25 (#F89209) 45 (#AB168B) 45 (#0D38D2) 45 (#6D16B4)

42.5 (#F05514) 46.25 (#A9168A) 46.25 (#0C36CF) 46.25 (#6C15B4)

43.75 (#E74111) 47.5 (#A81689) 47.5 (#0C34CC) 47.5 (#6C14B5)

45 (#DF2D0F) 48.75 (#A61688) 48.75 (#0B32C9) 48.75 (#6C13B5)

45.5 (#DC250E) 50 (#A41687) 50 (#0A30C6) 50 (#6B12B5)


RAIN ICE SNOW MIXED

46.75 (#D21C0C) 51.25 (#A21686) 51.25 (#0A2EC4) 51.25 (#6B11B5)

48 (#C9140A) 52.5 (#A01685) 52.5 (#092BC1) 52.5 (#6B10B6)

49.25 (#BF0C09) 53.75 (#9E1684) 53.75 (#0929BF) 53.75 (#6A0FB6)

50 (#BA0808) 55 (#9C1683) 55 (#0826BC) 55 (#6A0EB6)

56.25 (#6f031b) 56.25 (#9B1682) 56.25 (#0824BA) 56.25 (#6A0DB6)

57.5 (#9f0143) 57.5 (#981580) 57.5 (#0721B7) 57.5 (#690CB6)

58.75 (#c10060) 58.75 (#96157F) 58.75 (#071FB5) 58.75 (#690CB7)

60 (#e70086) 60 (#94157E) 60 (#071DB3) 60 (#690BB7)

61.25 (#e205a0) 61.25 (#92157D) 61.25 (#061AB0) 61.25 (#680AB7)

62.5 (#cc09ac) 62.5 (#90157C) 62.5 (#0618AE) 62.5 (#6809B7)

63.75 (#b50eb7) 63.75 (#8D157A) 63.75 (#0515AB) 63.75 (#6808B8)

65 (#9315c8) 65 (#8B1579) 65 (#0513A9) 65 (#6707B8)

66.25 (#8f21cc) 66.25 (#891578) 66.25 (#0410A6) 66.25 (#6706B8)

67.5 (#983acb) 67.5 (#871577) 67.5 (#040EA4) 67.5 (#6705B8)

68.75 (#9d49cb) 68.75 (#851576) 68.75 (#040CA2) 68.75 (#6604B8)

70 (#a661ca) 70 (#821574) 70 (#03099F) 70 (#6603B9)

71.25 (#ad72c9) 71.25 (#801573) 71.25 (#03079D) 71.25 (#6602B9)

72.5 (#b78bc6) 72.5 (#7E1572) 72.5 (#02049A) 72.5 (#6501B9)

73.75 (#bf9bc4) 73.75 (#7C1571) 73.75 (#020298) 73.75 (#6500B9)

75 (#c9b5c2) 75 (#7A1570) 75 (#020096) 75 (#6500BA)

Satellite Images
The table below provides guidance to interpret the infrared satellite images showing
clouds by their temperature and how to create a map legend for these tiles.

Hex color code Color sample Cloud Temperature

#b5b5b5 Temperature-Low
Hex color code Color sample Cloud Temperature

#d24fa0

#8a32d7

#144bed

#479702

#72b403

#93c701

#ffd701

#f05514

#dc250e

#ba0808

#1f1f1f Temperature-High

Detailed color palette for infrared satellite tiles is shown below.

Temp (K) Hex color code

198 #fe050505

198.43 #fe120505

198.87 #fc1f0505

199.3 #fc2c0606

199.74 #fa390606

200.17 #fa460606

200.61 #f8530606

201.04 #f8600707

201.48 #f66c0707

201.91 #f6790707

202.35 #f4860707

202.78 #f4930707

203.22 #f2a00808
Temp (K) Hex color code

203.65 #f2ad0808

204.09 #f0ba0808

204.52 #f0bd0a09

204.96 #eec00d09

205.39 #eec30f0a

205.83 #ecc5120a

206.26 #ecc8140b

206.7 #eacb170b

207.13 #eace190c

207.57 #e8d11b0c

208 #e8d41e0d

208.43 #e6d6200d

208.87 #e6d9230e

209.3 #e4dc250e

209.74 #e4df2c0f

210.17 #e2e23310

210.61 #e2e53a11

211.04 #e0e73a11

211.48 #e0ea4712

211.91 #deed4e13

212.35 #def05514

212.78 #dcf15e13

213.22 #dcf26811

213.65 #daf37110

214.09 #daf47a0f

214.52 #d8f5830d
Temp (K) Hex color code

214.96 #d8f68d0c

215.39 #d6f8960b

215.83 #d6f99f09

216.26 #d4faa908

216.7 #d4fbb206

217.13 #d2fcbb05

217.57 #d2fdc404

218 #d0fece02

218.43 #d0ffd701

218.87 #cef8d601

219.3 #cef2d501

219.74 #ccebd401

220.17 #cce4d301

220.61 #caddd201

221.04 #cad7d101

221.48 #c8d0d001

221.91 #c8c9cf01

222.35 #c6c2ce01

222.78 #c6bccd01

223.22 #c4b5cc01

223.65 #c4aecb01

224.09 #c2a7ca01

224.52 #c2a1c901

224.96 #c09ac801

225.39 #c093c701

225.83 #be90c501
Temp (K) Hex color code

226.26 #be8ec401

226.7 #bc8bc202

227.13 #bc88c102

227.57 #ba85bf02

228 #ba83be02

228.43 #b880bc02

228.87 #b87dba02

229.3 #b678b703

229.74 #b675b603

230.17 #b472b403

230.61 #b46eb203

231.04 #b26bb203

231.48 #b267ad03

231.97 #b064aa03

232.35 #b060a803

232.78 #ae5da603

233.22 #ae59a302

233.65 #ac55a102

234.09 #ac529e02

234.52 #aa4e9c02

234.96 #aa4b9902

235.39 #a8479702

235.83 #a845940b

236.26 #a6439115

236.7 #a6418e1e

237.13 #a43f8b28
Temp (K) Hex color code

237.57 #a43d8831

238 #a23b853a

238.43 #a2398244

238.87 #a0377f4d

239.3 #a0357c57

239.74 #9e337960

240.17 #9e317669

240.61 #9c2f7373

241.04 #9c2c6f7c

241.48 #9a2a6c86

241.91 #9a28698f

242.35 #98266698

242.78 #982463a2

243.22 #962260ab

243.65 #96205db5

244.09 #941e5abe

244.52 #941c57c7

244.85 #921a54d1

245.39 #921851da

245.83 #90164ee4

246.26 #90144bed

246.7 #8e2148eb

247.13 #8e2e45e8

247.57 #8c3b43e6

248 #8c4840e3

248.43 #8a563de1
Temp (K) Hex color code

248.87 #8a633ade

249.3 #887038dc

249.74 #887d35d9

250.17 #868a32d7

250.61 #869034d2

251.04 #849637ce

251.48 #849c39c9

251.91 #82a23cc5

252.35 #82a83ec0

252.78 #80ae41bc

253.22 #80b443b7

253.65 #7eba45b2

253.09 #7ec048ae

254.52 #7cc64aa9

254.96 #7ccc4da5

255.39 #7ad24fa0

255.83 #7ad85fac

256.26 #78dd6eb8

256.7 #78e37ec4

257.13 #76e98ed0

257.57 #76ee9ddb

258 #74f4ade7

258.43 #74f9bcf3

258.87 #72ffccff

259.3 #71ffffff

259.74 #71fcfcfc
Temp (K) Hex color code

260.17 #6ff6f6f6

260.61 #6ff6f6f6

261.04 #6df3f3f3

261.48 #6df3f3f3

261.91 #6bededed

262.35 #6bededed

262.78 #69e7e7e7

263.22 #69e7e7e7

263.65 #67e1e1e1

264.09 #67e1e1e1

264.52 #65dedede

264.96 #65dedede

265.39 #63d8d8d8

265.83 #63d8d8d8

265.84 #61d1d1d1

266.26 #61d1d1d1

267.13 #5fcecece

267.57 #5fcecece

268 #5dc8c8c8

268.43 #5dc8c8c8

268.87 #5bc2c2c2

269.3 #5bc2c2c2

269.74 #59bcbcbc

270.17 #59bcbcbc

270.61 #57b9b9b9

271.04 #57b9b9b9
Temp (K) Hex color code

271.48 #55b3b3b3

271.91 #55b3b3b3

272.35 #53adadad

272.78 #53adadad

273.22 #51aaaaaa

273.65 #51aaaaaa

274.09 #4fa4a4a4

274.52 #4fa4a4a4

274.96 #4d9e9e9e

275.39 #4d9e9e9e

275.83 #4b989898

276.26 #4b989898

276.7 #49959595

277.13 #49959595

277.57 #478f8f8f

278 #478f8f8f

278.43 #45898989

278.87 #45898989

279.2 #43868686

279.74 #43868686

280.17 #417f7f7f

280.61 #417f7f7f

281.04 #3f797979

281.48 #3f797979

281.91 #3d737373

282.35 #3d737373
Temp (K) Hex color code

282.78 #3b707070

283.22 #3b707070

283.65 #396a6a6a

284.09 #396a6a6a

284.52 #37646464

284.96 #37646464

285.39 #35616161

285.83 #35616161

286.26 #335b5b5b

286.7 #335b5b5b

287.13 #31555555

287.57 #31555555

288 #2f4f4f4f

288.43 #2f4f4f4f

288.87 #2d4c4c4c

289.3 #2d4c4c4c

289.74 #2b464646

290.17 #2b464646

290.61 #29404040

291.04 #29404040

291.48 #273d3d3d

291.91 #273d3d3d

292.35 #25373737

292.78 #25373737

293.22 #23313131

293.65 #23313131
Temp (K) Hex color code

294.09 #212a2a2a

294.52 #212a2a2a

294.96 #1f272727

295.39 #1f272727

295.83 #1d212121

296.26 #1d212121

296.7 #1b1b1b1b

297.13 #1b1b1b1b

297.57 #19181818

298 #19181818

298.43 #17121212

298.87 #17121212

299.3 #150c0c0c

299.74 #150c0c0c

300.17 #13060606

300.61 #13060606

301.04 #11000000

301.48 #11000000

301.91 #0f797979

302.35 #0f797979

302.78 #0d737373

303.22 #0d737373

303.65 #0b6d6d6d

304.09 #0b6d6d6d

304.52 #09676767

304.92 #09676767
Temp (K) Hex color code

305.39 #07616161

305.83 #07616161

306.26 #055b5b5b

306.7 #055b5b5b

307.13 #02555555

307.57 #02555555

308 #00525252

308 #00525252

Index IDs and Index Groups IDs


Get Daily Indices API allows users to restrict returned results to specific index types or
index groups.

Below is a table of available index IDs, their names, and a link to their range sets. Below
this table is a table listing the various index groups.

Index Name ID Value Range

Arthritis Pain 21 Beneficial-At Extreme Risk

Asthma 23 Beneficial-At Extreme Risk

Beach & Pool 10 Poor-Excellent 1

Bicycling 4 Poor-Excellent 1

Common Cold 25 Beneficial-At Extreme Risk

Composting 38 Poor-Excellent 1

Construction 14 Poor-Excellent 1

COPD 44 Beneficial-At Extreme Risk

Dog Walking Comfort 43 Poor-Excellent 1

Driving 40 Poor-Excellent 2

Dust & Dander 18 Low-Extreme 1


Index Name ID Value Range

Field Readiness 32 Poor-Excellent 1

Fishing 13 Poor-Excellent 1

Flight Delays -3 Very Unlikely-Very Likely 2

Flu 26 Beneficial-At Extreme Risk

Flying Travel Index 31 Excellent-Poor

Fuel Economy 37 Poor-Excellent 1

Golf Weather 5 Poor-Excellent 1

Grass Growing 33 Poor-Excellent 1

Hair Frizz 42 Unlikely-Emergency

Healthy Heart Fitness 16 Poor-Excellent 1

Hiking 3 Poor-Excellent 1

Home Energy Efficiency 36 Poor-Excellent 1

Hunting 20 Poor-Excellent 1

Indoor Activity -2 Poor-Excellent 1

Jogging 2 Poor-Excellent 1

Kite Flying 9 Poor-Excellent 1

Lawn Mowing 28 Poor-Excellent 1

Migraine Headache 27 Beneficial-At Extreme Risk

Morning School Bus 35 Poor-Excellent 1

Mosquito Activity 17 Low-Extreme 1

Outdoor Activity 29 Poor-Excellent 1

Outdoor Barbecue 24 Poor-Excellent 1

Outdoor Concert 8 Poor-Excellent 1

Running 1 Poor-Excellent 1

Tennis 6 Poor-Excellent 1

Thirst 41 Low-Extreme 2
Index Name ID Value Range

Sailing 11 Poor-Excellent 1

Shopping 39 Poor-Excellent 1

Sinus Headache 30 Beneficial-At Extreme Risk

Skateboarding 7 Poor-Excellent 1

Ski Weather 15 Poor-Excellent 1

Snow Days 19 Very Unlikely-Very Likely

Soil Moisture 34 Poor-Excellent 1

Stargazing 12 Poor-Excellent 1

Below is the list of available Index groups (indexGroupId):

ID Group Name Indices in this group

1 All All

2 Aches and Pains Arthritis Pain (21)


Migraine Headache (27)
Sinus Headache (30)

3 Respiratory Asthma (23)


Common Cold (25)
Flu Forecast (26)

4 Gardening Field Readiness (32)


Lawn Mowing (28)
Soil Moisture (34)

5 Environmental Compositing (38)


Home Energy Efficiency (36)
Fuel Economy (37)

6 Outdoor Living Outdoor Barbecue (24)


Mosquito Activity (17)

7 Beach and Marine Beach & Pool (10)


Fishing (13)
Sailing (11)

8 Sportsman Fishing (13)


Hunting (20)
Outdoor Activity (29)
ID Group Name Indices in this group

9 Farming Field Readiness (32)


Soil Moisture (34)

10 Health Arthritis Pain (21)


Asthma (23)
Common Cold (25)
Dust & Dander (18)
Flu (26)
Healthy Heart Fitness (16)
Migraine Headache (27)

11 Outdoor Outdoor Barbecue (24)


Beach & Pool (10)
Bicycling (4)
Outdoor Concert (8)
Field Readiness (32)
Fishing (13)
Golf Weather (5)
Hiking (3)
Hunting (20)
Jogging (2)
Kite Flying (9)
Mosquito Activity (17)
Lawn Mowing (28)
Outdoor Activity (29)
Running (1)
Sailing (11)
Skateboarding (7)
Ski Weather (15)
Soil Moisture (34)
Stargazing (12)
Tennis (6)

12 Sporting Bicycling (4)


Golf Weather (5)
Hiking (3)
Jogging (2)
Running (1)
Skateboarding (7)
Ski Weather (15)
Tennis (6)

13 Home Home Energy Efficiency (36)


Fuel Economy (37)
Indoor Activity (-2)
Daily index range sets
Get Daily Indices API returns the ranged value and its associated category name for each
index ID. Range sets aren't the same for all indices. The tables below show the various
range sets used by the supported indices listed in Index IDs and index groups IDs. To
find out which indices use which range sets, go to the Index IDs and Index Groups IDs
section of this document.

Poor-Excellent 1

Category Name Begin Range End Range

Poor 0 2.99

Fair 3 4.99

Good 5 6.99

Very Good 7 8.99

Excellent 9 10

Poor-Excellent 2

Category Name Begin Range End Range

Poor 0 3

Fair 3.01 6

Good 6.01 7.5

Very Good 7.51 8.99

Excellent 9 10

Excellent-Poor

Category Name Begin Range End Range

Excellent 0.00 1.00

Very Good 1.01 3.00

Good 3.01 5.00


Category Name Begin Range End Range

Fair 5.01 7.00

Poor 7.01 10.00

Low-Extreme 1

Category Name Begin Range End Range

Low 0 1.99

Moderate 2 3.99

High 4 5.99

Very High 6 7.99

Extreme 8 10

Low-Extreme 2

Category Name Begin Range End Range

Low 0 2.99

Moderate 3 4.99

High 5 6.99

Very High 7 8.99

Extreme 9 10

Very Unlikely-Very Likely

Category Name Begin Range End Range

Very Unlikely 0 1.99

Unlikely 2 3.99

Possibly 4 5.99

Likely 6 7.99

Very Likely 8 10
Very Unlikely-Very Likely 2

Category Name Begin Range End Range

Very Unlikely 0.00 1.00

Unlikely 1.01 3.00

Possibly 3.01 5.00

Likely 5.01 7.00

Very Likely 7.01 10.00

Unlikely-Emergency

Category Name Begin Range End Range

Unlikely 0 2.99

Watch 3 4.99

Advisory 5 6.99

Warning 7 8.99

Emergency 9 10

Beneficial-At Extreme Risk

Category Name Begin Range End Range

Beneficial 0 1.99

Neutral 2 3.99

At Risk 4 5.99

At High Risk 6 7.99

At Extreme Risk 8 10

Next steps
Azure Maps Weather services frequently asked questions (FAQ)
Azure Maps Weather services coverage

Weather services API


Azure Maps Weather service frequently
asked questions (FAQ)
FAQ

This article answers to common questions about Azure Maps Weather service data and
features. The following topics are covered:

Data sources and data models


Weather service coverage and availability
Data update frequency
Developing with Azure Maps SDKs
Options to visualize weather data, including Microsoft Power BI integration

Data sources and data models


How does Azure Maps source Weather data?
Azure Maps is built with the collaboration of world-class mobility and location technology
partners, including AccuWeather, who provides the underlying weather data. To read the
announcement of Azure Map's collaboration with AccuWeather, see Rain or shine: Azure Maps
Weather service will bring insights to your enterprise .

AccuWeather has real-time weather and environmental information available anywhere in the
world, largely because of their partnerships with many governmental weather agencies and
other proprietary arrangements. A list of this foundational information is provided below.

Publicly available global surface observations from government agencies


Proprietary surface observation datasets from governments and private companies
High-resolution radar data for over 40 countries/regions
Best-in-class real-time global lightning data
Government-issued weather warnings for over 60 countries/regions and territories
Satellite data from geostationary weather satellites covering the entire world
Over 150 numerical forecast models including internal, proprietary modeling, government
models such as the U.S. Global Forecast System (GFS), and unique downscaled models
provided by private companies
Air quality observations
Observations from departments of transportation

Tens of thousands of surface observations, along with other data, are incorporated to create
and influence the current conditions made available to users. These surface observations
include not only freely available standard datasets, but also unique observations obtained from
meteorological services in many countries/regions, such as India, Brazil, Canada, and other
proprietary inputs. These unique datasets increase the spatial and temporal resolution of
current condition data for our users.

These datasets are reviewed in real time for accuracy for the Digital Forecast System, which
uses AccuWeather’s proprietary artificial intelligence algorithms to continuously modify the
forecasts, ensuring they always incorporate the latest data and, in that way, maximize their
continual accuracy.

What models create weather forecast data?


Many weather forecast guidance systems are used to formulate global forecasts. Over 150
numerical forecast models are used each day, both external and internal datasets. These
models include government models such as the European Centre ECMWF and the U.S. Global
Forecast System (GFS). Also, AccuWeather incorporates proprietary high-resolution models that
downscale forecasts to specific locations and strategic regional domains to predict weather
with further accuracy. AccuWeather’s unique blending and weighting algorithms have been
developed over the last several decades. These algorithms optimally apply the many forecast
inputs to provide highly accurate forecasts.

Weather service coverage and availability


What kind of coverage can I expect for different
countries/regions?
Weather service coverage varies by country/region. All features aren't available in every
country/region. For more information, see coverage documentation.

Data update frequency


How often is Current Conditions data updated?
Current Conditions data is updated at least once an hour, but can be updated more frequently
with rapidly changing conditions – such as large temperature changes, sky conditions changes,
precipitation changes, and so on. Most observation stations around the world report many
times per hour as conditions change. However, a few areas will still only update once, twice, or
four times an hour at scheduled intervals.

Azure Maps caches the Current Conditions data for up to 10 minutes to help capture the near
real-time update frequency of the data as it occurs. To see when the cached response expires
and avoid displaying outdated data, you can use the Expires Header information in the HTTP
header of the Azure Maps API response.

How often is Daily and Hourly Forecast data


updated?
Daily and Hourly Forecast data is updated multiple times per day, as updated observations are
received. For example, if a forecasted high/low temperature is surpassed, our Forecast data will
adjust at the next update cycle. Updates happen at different intervals but typically happens
within an hour. Many sudden weather conditions may cause a forecast data change. For
example, on a hot summer afternoon, an isolated thunderstorm might suddenly emerge,
bringing heavy cloud coverage and rain. The isolated storm could effectively drop temperature
by as much as 10 degrees. This new temperature value will impact the Hourly and Daily
Forecasts for the rest of the day, and as such, will be updated in our datasets.

Azure Maps Forecast APIs are cached for up to 30 mins. To see when the cached response
expires and avoid displaying outdated data, you can look at the Expires Header information in
the HTTP header of the Azure Maps API response. We recommend updating as necessary
based on a specific product use case and UI (user interface).

Developing with Azure Maps SDKs


Does Azure Maps Web SDK natively support
Weather service integration?
The Azure Maps Web SDK provides a services module. The services module is a helper library
that makes it easy to use the Azure Maps REST services in web or Node.js applications. by
using JavaScript or TypeScript. To get started, see our documentation.

Does Azure Maps Android SDK natively support


Weather service integration?
The Azure Maps Android SDKs supports Mercator tile layers, which can have x/y/zoom
notation, quad key notation, or EPSG 3857 bounding box notation.

The Azure Maps Native SDK for Android is now deprecated and will be retired on 3/31/25. To
avoid service disruptions, migrate to the Azure Maps Web SDK by 3/31/25. For more
information, see The Azure Maps Android SDK migration guide.
Data visualizations
Does Azure Maps Power BI Visual support Azure
Maps weather tiles?
Yes. To learn how to migrate radar and infrared satellite tiles to the Microsoft Power BI visual,
see Add a tile layer to Power BI visual.

How do I interpret colors used for radar and satellite


tiles?
The Azure Maps Weather concept article includes a guide to help interpret colors used for
radar and satellite tiles. The article covers color samples and HEX color codes.

Can I create radar and satellite tile animations?


Yes. In addition to real-time radar and satellite tiles, Azure Maps customers can request past
and future tiles to enhance data visualizations with map overlays. Customers can call the Get
Map Tile v2 API or request tiles via Azure Maps web SDK. Radar tiles are available for up to 1.5
hours in the past, and for up to 2 hours in the future. The tiles are available in 5-minute
intervals. Infrared tiles are provided for up to 3 hours in the past, and are available in 10-
minute intervals. For more information, see the Show weather overlays on a map sample.

Do you offer icons for different weather conditions?


Yes. You can find icons and their respective codes here. Notice that only some of the Weather
service (Preview) APIs, such as Get Current Conditions API, return the iconCode in the response.
For more information, see the Get current weather at a location sample.

Next steps
If this FAQ doesn’t answer your question, you can contact us through the following channels (in
escalating order):

The comments section of this article.


MSFT Q&A page for Azure Maps.
Microsoft Support. To create a new support request, in the Azure portal , on the Help
tab, select the Help + support button, and then select New support request.
Learn how to request real-time and forecasted weather data using Azure Maps Weather
service:

Request Real-time weather data

Azure Maps Weather service concepts article:

Weather service concepts

Explore the Azure Maps Weather service API documentation:

Azure Maps Weather service


Migrate from Bing Maps to Azure Maps
overview
Article • 05/17/2024

This article provides the information needed to migrate applications created in Bing
Maps for Enterprise to Azure Maps, including links to specific Bing Maps API and SDK
migration guides, platform comparisons, and best practices.

Covered in this article:

A list comparing Bing Maps for Enterprise services that are available in Azure Maps.
Information on features in Azure Maps that are unavailable in Bing Maps for
Enterprise.
Differences in licensing and billing between Bing Maps for Enterprise and Azure
Maps.
Migration planning.
Links to more resources and support.

Azure Maps platform overview


Azure Maps is a set of mapping and geospatial services that enable developers and
organizations to build intelligent location-based experiences for applications across
many different industries and use cases. Use Azure Maps to bring maps, geocoding,
location search, routing, real-time traffic, geolocation, time zone info, weather, and
custom indoor maps into your web, mobile and server-side solutions. Azure Maps is an
Azure service, so it inherently includes many of the Azure security and compliance
promises that are important to enterprise customers. Azure Maps includes many of the
same features as Bing Maps for Enterprise, along with more functionality, like:

Multiple service authentication method options. For more information on security


and authentication in Azure Maps, See Authentication with Microsoft Azure Maps.
Data residency compliance support. For more information, see Azure Maps service
geographic scope.
Azure regulatory compliance standards (GDPR, ISO, FedRAMP, HIPAA, etc.). For
more information, see Microsoft Compliance.
Support for programmatically creating and managing Azure Maps accounts
(resources). For more information, see Create your Azure Maps account using an
ARM template.
Azure Maps Weather maps. For more information, see Weather infrared and radar
tiles in Get Map Tile.
Azure Maps Weather APIs. For more information, see Weather.
Azure Maps Geolocation APIs. For more information, see Geolocation - Get IP To
Location.
Azure Maps Creator (custom indoor maps). For more information, see Azure Maps
Creator.

High-level platform comparison


The following table provides a high-level summary of Bing Maps for Enterprise features
and equivalent support in Azure Maps.

ノ Expand table

Bing Maps for Enterprise Azure Maps

Autosuggest Search: Fuzzy (typehead)

Imagery: Static Maps Render: Map Static Image

Imagery: Map Tiles & Metadata Render: Map Tile

Locations: Forward Geocoding (unstructured) Search: Forward Geocoding

Locations: Forward Geocoding (structured) Search: Forward Geocoding

Locations: Reverse Geocoding Search: Reverse Geocoding

Locations: Points of Interest Search Search: Fuzzy Search (typeahead)

Routes: Directions (auto) Route Directions

Routes: Directions (truck) Route Directions

Routes: Distance Matrix Route Matrix

Routes: Isochrones Route Range

SDS: Geocode Dataflow Search: Forward Geocoding Batch


Search: Reverse Geocoding Batch

SDS: Geodata Search: Polygon

SDS: Points of Interest Search Search: Fuzzy


Search: POI

Time Zone Timezone

Traffic Incidents Traffic Incident Detail


Bing Maps for Enterprise Azure Maps

Web Map Control (SDK) Web Map Control (SDK)

Azure portal
With Bing Maps for Enterprise, the Bing Maps Account Center is where you manage
your API keys, view your transaction usage reports, see service announcements, etc. In
Azure Maps, the Azure portal is where you manage your Azure Maps account.
Specifically, the Azure portal is where you go to manage your Azure Maps
authentication (shared key authentication and Shared access signature token
authentication) and access control options, set up Cross-Origin Resource Sharing (CORS)
rules, view transaction usage reports, create budget alerts, provide map data feedback,
access technical support resources, get current service health status update, and more.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports
multiple authentication methods, such as a Shared Key, Microsoft Entra ID, or Shared
access signature token authentication. For more information on security and
authentication in Azure Maps, See Authentication with Microsoft Azure Maps.

Licensing and billing considerations


When migrating to Azure Maps from Bing Maps for Enterprise, the following aspects
should be considered regarding licensing and billing.

Azure Maps is a transactions-based usage offering for all use case types and
doesn't require special licensing, such as known users or tracked assets-based
licensing for certain use cases.
Unlike Bing Maps for Enterprise, Azure Maps is a pay-as-you-go offering – you
only pay for the services that you use.
With Azure Maps, billing (invoicing) happens monthly and doesn’t require an
annual commitment.
Azure Maps has a free monthly allotment of transactions. For more information,
see the Azure Maps pricing .
Azure Maps charges for the usage of web control (SDK) based on the number of
map tiles loaded, with one Azure Maps transaction being generated for every
fifteen 15 map tiles loaded.
The Azure Maps web control (SDK) uses 512 x 512 pixels map tiles, and typically
generates one or less transactions per map load.

Licensing and billing related resources for Azure Maps:

Azure Licensing
Azure Maps pricing
Azure pricing calculator
Understanding Azure Maps Transactions
View Azure Maps API usage metrics
Azure Maps terms of use . To get the terms of use that applies to your situation,
select the appropriate licensing program from the Select a Program to View Terms
drop-down list then scroll down to the Azure Maps section.

Suggested migration plan


Here are the suggested high-level migration steps:

1. Take an inventory of the specific Bing Maps for Enterprise APIs and SDKs that your
application is using and confirm that Azure Maps has equivalent services to
migrate to.
2. Confirm the transaction calculation differences between the Bing Maps for
Enterprise services and the Azure Maps services that you are migrating to in order
to understand any possible cost and pricing differences.
3. Create an Azure subscription and Azure Maps account.
4. Migrate your application code using the Bing Maps for Enterprise to Azure Maps
REST API and SDK migration resources.
5. Test and deploy your new Azure Maps application.

Create an Azure Maps account


To create an Azure Maps account and get access to the Azure Maps platform, follow
these steps:

Create a free Azure subscription if you don't already have one.


Sign in to the Azure portal .
Create an Azure Maps account.
Get your Azure Maps subscription key to try the Azure Maps APIs and SDK.
Follow the Authentication best practices.

Bing Maps for Enterprise migration guides


REST API migration guides
Bing Maps Imagery Services

Get Imagery Metadata

Bing Maps Locations Services

Find a Location by Address


Find a Location by Point
Find a Location by Query

Bing Maps Routes Services

Calculate a Route
Calculate a Truck Route

Bing Maps Spatial Data Services (SDS)

Data Source Management & Query


Geocode Dataflow
Geodata

Bing Maps Time Zone Services

Find Time Zone

Bing Maps Traffic Services

Get Traffic Incidents

Web SDK migration guides


Bing Maps for Enterprise to Azure Maps Web SDK migration guides

Web SDK
Copilot Bing Maps Web SDK to Azure Maps Web SDK migration guide

General Azure Maps resources


More Azure Maps resources:

Azure Maps product web site


Azure Maps product documentation
Azure Maps code samples
Azure Maps blog
Azure Maps data feedback
Azure Maps Q&A
Azure support options

Migration support
Developers can get migration support through the Azure Maps Q&A or through one of
the many Azure support options .
Migrate a web app from Bing Maps
Article • 09/09/2024

Web apps that use Bing Maps often use the Bing Maps V8 JavaScript SDK. The Azure
Maps Web SDK is the suitable Azure-based SDK to migrate to. The Azure Maps Web
SDK lets you customize interactive maps with your own content and imagery for display
in your web or mobile applications. This control makes use of WebGL, allowing you to
render large data sets with high performance. Develop with this SDK using JavaScript or
TypeScript. This article demonstrates how to:

" Load a map
" Localize a map
" Add pushpins, polylines, and polygons.
" Display information in a popup or infobox
" Load and display KML and GeoJSON data
" Cluster pushpins
" Overlay a tile layer
" Show traffic data
" Add a ground overlay

If developing using a JavaScript framework, one of the following open-source projects


can be useful:

ng-azure-maps - Angular 10 wrapper around Azure maps.


AzureMapsControl.Components - An Azure Maps Blazor component.
Azure Maps React Component - A react wrapper for the Azure Maps control.
Vue Azure Maps - An Azure Maps component for Vue application.

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

An Azure Maps account


A subscription key

Key features support


The following table lists key API features in the Bing Maps V8 JavaScript SDK and the
support of a similar API in the Azure Maps Web SDK.
ノ Expand table

Bing Maps Bing Maps module Azure Maps Web SDK support
feature

Pushpins ✓

Pushpin clustering Microsoft.Maps.Clustering ✓ Pushpin clustering

Polylines & ✓
polygons

Ground overlays ✓

Heat maps Microsoft.Maps.HeatMap ✓ Add a heat map

Tile layers ✓

KML layer Microsoft.Maps.GeoXml ✓ Spatial IO module

Contour layer Microsoft.Maps.Contour ✓ Contour layer code samples

Data binning layer Microsoft.Maps.DataBinning ✓ Included in the open-source Azure


Maps Gridded Data Source module

Animated tile layer ✓ Included in the open-source Azure


Maps Animation module

Drawing tools Microsoft.Maps.DrawingTools ✓ Add drawing tools

Geocoder service Microsoft.Maps.Search ✓ Search API or REST SDK

Directions service Microsoft.Maps.Directions ✓ Route API

Distance matrix ✓ Route Matrix API


service

Spatial data service Microsoft.Maps.SpatialDataService N/A

Satellite/Aerial ✓ Choose a map style


imagery

Birds eye imagery N/A

Streetside imagery N/A

GeoJSON support Microsoft.Maps.GeoJson ✓

GeoXML support Microsoft.Maps.GeoXml ✓ Spatial IO module

Well-Known Text Microsoft.Maps.WellKnownText ✓ Spatial IO module


support
Bing Maps Bing Maps module Azure Maps Web SDK support
feature

Indoor maps Microsoft.Maps.VenueMaps ✓ Creator

Traffic flow Microsoft.Maps.Traffic ✓ Traffic control

Spatial math Microsoft.Maps.SpatialMath ✓ atlas.math samples or turf js

Custom map styles Partial, Choose a map style

Azure Maps more open-source modules for the web SDK that extend its capabilities.

Notable differences in the web SDKs


The following are some of the key differences between the Bing Maps and Azure Maps
Web SDKs to be aware of:

In addition to providing a hosted endpoint for accessing the Azure Maps Web SDK,
an npm package is available for embedding the Web SDK into apps if preferred.
For more information, see Use the Azure Maps map control. This package also
includes TypeScript definitions.
Bing Maps provides two hosted branches of their SDK; Release and Experimental.
The Experimental branch can receive multiple updates a day when new
development is taking place. Azure Maps only hosts a release branch, however
experimental features are created as custom modules in the open-source Azure
Maps code samples project. Bing Maps used to have a frozen branch as well that
was updated less frequently, thus reducing the risk of breaking changes due to a
release. In Azure Maps, you can use the npm module and point to any previous
minor version release.

 Tip

Azure Maps publishes both minified and unminified versions of the SDK. Simply
remove .min from the file names. The unminified version is useful when debugging
issues but be sure to use the minified version in production to take advantage of
the smaller file size.

Once an instance of the Map class is created in Azure Maps, your code should wait
for the maps ready or load event to fire before interacting with the map. These
events ensure that all the map resources are loaded and ready to be accessed.
Both platforms use a similar tiling system for the base maps, however the tiles in
Bing Maps are 256 pixels and are 512 pixels in Azure Maps. To get the same map
view in Azure Maps as Bing Maps, subtract one zoom level in Azure Maps.

Coordinates in Bing Maps are referred to as latitude, longitude while Azure


Maps uses longitude, latitude . This format aligns with the standard [x, y] that
is followed by most GIS platforms.

Shapes in the Azure Maps Web SDK are based on the GeoJSON schema. Helper
classes are exposed through the atlas.data namespace. There's also the atlas.Shape
class that can be used to wrap GeoJSON objects and make them easy to update
and maintain in a data bindable way.

Coordinates in Azure Maps are defined as Position objects that can be specified as
a simple number array in the format [longitude, latitude] or new
atlas.data.Position(longitude, latitude) .

 Tip

The Position class has a static helper function for importing coordinates that are in
latitude, longitude format. The atlas.data.Position.fromLatLng function can often

be replace the new Microsoft.Maps.Location function in Bing Maps code.

Rather than specifying styling information on each shape that is added to the map,
Azure Maps separates styles from the data. Data is stored in data sources and is
connected to rendering layers that Azure Maps code uses to render the data. This
approach provides enhanced performance benefit. Many layers support data-
driven styling, done by adding business logic to layer style options that change
how individual shapes are rendered within a layer depending on its properties.
Azure Maps provides spatial math functions in the atlas.math namespace that
differ from Bing Maps spatial math functions. The primary difference is that Azure
Maps doesn’t provide built-in functions for binary operations such as union and
intersection . However, Azure Maps is based on the open GeoJSON standard and

there are open-source libraries available. One popular option that works well with
Azure Maps and provides spatial math capabilities is turf js .

For more information on terminology related to Azure Maps, see the Azure Maps
Glossary.

Web SDK side-by-side examples


The following list is a collection of code samples for each platform that cover common
use cases to help you migrate your web application from Bing Maps V8 JavaScript SDK
to the Azure Maps Web SDK. Code samples related to web applications are provided in
JavaScript; however, Azure Maps also provides TypeScript definitions in an npm module.
For more information about TypeScript definitions, see Use the Azure Maps map control.

Topics

Load a map
Localizing the map
Setting the map view
Adding a pushpin
Adding a custom pushpin
Adding a polyline
Adding a polygon
Display an infobox
Pushpin clustering
Add a heat map
Overlay a tile layer
Show traffic data
Add a ground overlay
Add KML data to the map
Add drawing tools

Load a map
Loading a map in both SDKs follows the same set of steps;

Add a reference to the Map SDK.


Add a div tag to the body of the page that acts as a placeholder for the map.
Create a JavaScript function that gets called once the page loads.
Create an instance of the respective map class.

Key differences

Bing maps require an account key specified in the script reference of the API or as
a map option. Authentication credentials for Azure Maps are specified as options
of the map class as either Shared Key authentication or Microsoft Entra ID.
Bing Maps takes in a callback function in the script reference of the API that is used
to call an initialization function to load the map. With Azure Maps, the onload
event of the page should be used.
When using an ID to reference the div element that the map is rendered in, Bing
Maps uses an HTML selector ( #myMap ), whereas Azure Maps only uses the ID value
( myMap ).
Coordinates in Azure Maps are defined as Position objects that can be specified as
a simple number array in the format [longitude, latitude] .
The zoom level in Azure Maps is one level lower than the Bing Maps example due
to the difference in tiling system sizes between the platforms.
By default, Azure Maps doesn’t add any navigation controls to the map canvas,
such as zoom buttons and map style buttons. There are however controls for
adding a map style picker, zoom buttons, compass or rotation control, and a pitch
control.
An event handler is added in Azure Maps to monitor the ready event of the map
instance. This fires when the map finishes loading the WebGL context and all
resources needed. Any post load code can be added in this event handler.

The following examples demonstrate loading a basic map centered over New York at
coordinates (longitude: -73.985, latitude: 40.747) and is at zoom level 12 in Bing Maps.

Before: Bing Maps

The following code is an example of how to display a Bing Map centered and zoomed
over a location.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;

function initMap() {
map = new Microsoft.Maps.Map('#myMap', {
credentials: '<Your Bing Maps Key>',
center: new Microsoft.Maps.Location(40.747, -73.985),
zoom: 12
});
}
</script>

<!-- Bing Maps Script Reference -->


<script src="https://www.bing.com/api/maps/mapcontrol?callback=initMap"
async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:

After: Azure Maps

The following code shows how to load a map with the same view in Azure Maps along
with a map style control and zoom buttons.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;

function initMap() {
map = new atlas.Map('myMap', {
center: [-73.985, 40.747], //Format coordinates as
longitude, latitude.
zoom: 11, //Subtract the zoom level by one.

//Add your Azure Maps key to the map SDK. Get an Azure Maps
key at https://azure.com/maps. NOTE: The primary key should be used as the
key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {
//Add zoom and map style controls to top right of map.
map.controls.add([
new atlas.control.StyleControl(),
new atlas.control.ZoomControl()
], {
position: 'top-right'
});
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:

For more information on how to set up and use the Azure Maps map control in a web
app, see Use the Azure Maps map control.

 Tip

Azure Maps publishes both minified and unminified versions of the SDK. Remove
.min from the file names. The unminified version is useful when debugging issues

but be sure to use the minified version in production to take advantage of the
smaller file size.

More resources

For more information on Azure Maps navigation controls for rotating and pitching
a map, see Add controls to a map.

Localizing the map


If your audience is spread across multiple countries/regions or speak different
languages, localization is important.

Before: Bing Maps

To localize Bing Maps, language and region are specified using the setLang and UR
parameters are added to <script> tag reference to the API. Certain features in Bing
Maps are only available in certain markets, as such the market of the user is specified
using the setMkt parameter.

HTML

<script type="text/javascript"
src="https://www.bing.com/api/maps/mapcontrol?callback=initMap&setLang=
{language-code}&setMkt={market}&UR={region-code}" async defer></script>

Here's an example of Bing Maps with the language set to fr-FR .

After: Azure Maps

Azure Maps only provides options for setting the language and regional view of the
map. A market parameter isn't used to limit features. There are two different ways of
setting the language and regional view of the map. The first option is to add this
information to the global atlas namespace that results in all map control instances in
your app defaulting to these settings. The following sets the language to French ( fr-FR )
and the regional view to "Auto" :

JavaScript

atlas.setLanguage('fr-FR');
atlas.setView('auto');

The second option is to pass this information into the map options when loading the
map like:

JavaScript
map = new atlas.Map('myMap', {
language: 'fr-FR',
view: 'auto',

authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

7 Note

Azure Maps can load multiple map instances on the same page with different
language and region settings. It is also possible to update these settings in the map
after it has loaded. For a list of supported languages in Azure Maps, see
Localization support in Azure Maps.

Here's an example of Azure Maps with the language set to "fr" and the user region set
to fr-FR .

Setting the map view


Dynamic maps in both Bing and Azure Maps can be programmatically moved to new
geographic locations by calling the appropriate functions in JavaScript. The following
example demonstrates a map displaying satellite aerial imagery, centered over a
location with coordinates (longitude: -111.0225, latitude: 35.0272) and change the zoom
level to 15 in Bing Maps.

7 Note

Bing Maps uses tiles that are 256 pixels in dimensions while Azure Maps uses a
larger 512-pixel tile. This reduces the number of network requests needed by Azure
Maps to load the same map area as Bing Maps. However, due to the way tile
pyramids work in map controls, the larger tiles in Azure Maps means that to
achieve that same viewable area as a map in Bing Maps, you need to subtract the
zoom level used in Bing Maps by 1 when using Azure Maps.

Before: Bing Maps

The Bing Maps map control can be programmatically moved using the setView function
that allows you to specify the center of the map and a zoom level.

JavaScript

map.setView({
mapTypeId: Microsoft.Maps.MapTypeId.aerial,
center: new Microsoft.Maps.Location(35.0272, -111.0225),
zoom: 15
});
After: Azure Maps

In Azure Maps, the map position can be changed programmatically by using the
setCamera function of the map and the map style can be changed using the setStyle

function. The coordinates in Azure Maps are in "longitude, latitude" format, and the
zoom level value is subtracted by 1.

JavaScript

map.setCamera({
center: [-111.0225, 35.0272],
zoom: 14
});

map.setStyle({
style: 'satellite_road_labels'
});

More resources

Choose a map style


Supported map styles

Adding a pushpin
In Azure Maps, there are multiple ways that point data can be rendered on the map;
HTML Markers – Renders points using traditional DOM elements. HTML Markers
support dragging.
Symbol Layer – Renders points with an icon and/or text within the WebGL context.
Bubble Layer – Renders points as circles on the map. The radii of the circles can be
scaled based on properties in the data.

Both Symbol and Bubble layers are rendered within the WebGL context and are capable
of rendering large sets of points on the map. These layers require data to be stored in a
data source. Data sources and rendering layers should be added to the map after the
ready event fires. HTML Markers are rendered as DOM elements within the page and

don’t use a data source. The more DOM elements a page has, the slower the page
becomes. If rendering more than a few hundred points on a map, try using one of the
rendering layers instead.

The following examples add a marker to the map at (longitude: -0.2, latitude: 51.5) with
the number 10 overlaid as a label.

Before: Bing Maps

With Bing Maps, markers are added to the map using the Microsoft.Maps.Pushpin
class*. Pushpins are then added to the map using one of two functions.

The first function is to create a layer, insert the pushpin to that and then add the layer to
the map’s layers property.

JavaScript

var pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(51.5,


-0.2), {
text: '10'
});

var layer = new Microsoft.Maps.Layer();


layer.add(pushpin);
map.layers.insert(layer);

The second is to add it using the map’s entities property. This function is marked
deprecated in the documentation for Bing Maps V8 however it remains partially
functional for basic scenarios.

JavaScript

var pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(51.5,


-0.2), {
text: '10'
});
map.entities.add(pushpin);

After: Azure Maps using HTML Markers

In Azure Maps, HTML markers can be used to easily display a point on the map and are
recommended for simple apps that only need to display a few points on the map. To use
an HTML marker, create an instance of the atlas.HtmlMarker class, set the text and
position options, and add the marker to the map using the map.markers.add function.

JavaScript

//Create a HTML marker and add it to the map.


map.markers.add(new atlas.HtmlMarker({
text: '10',
position: [-0.2, 51.5]
}));

After: Azure Maps using a Symbol Layer

When using a Symbol layer, the data must be added to a data source, and the data
source attached to the layer. Additionally, the data source and layer should be added to
the map after the ready event fires. To render a unique text value above a symbol, the
text information needs to be stored as a property of the data point and that property
referenced in the textField option of the layer. This is a bit more work than using HTML
markers but provides performance advantages.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>
<script type='text/javascript'>
var map, datasource;

function initMap() {
map = new atlas.Map('myMap', {
center: [-0.2, 51.5],
zoom: 9,

authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a point feature, add a property to store a label


for it, and add it to the data source.
datasource.add(new atlas.data.Feature(new
atlas.data.Point([-0.2, 51.5]), {
label: '10'
}));

//Add a layer for rendering point data as symbols.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null,
{
textOptions: {
//Use the label property to populate the text for
the symbols.
textField: ['get', 'label'],
color: 'white',
offset: [0, -1]
}
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources

Create a data source


Add a Symbol layer
Add a Bubble layer
Cluster point data
Add HTML Markers
Use data-driven style expressions
Symbol layer icon options
Symbol layer text option
HTML marker class
HTML marker options

Adding a custom pushpin


Custom images can be used to represent points on a map. The following image is used
in the below examples and uses a custom image to display a point on the map at
(latitude: 51.5, longitude: -0.2) and offsets the position of the marker so that the point of
the pushpin icon aligns with the correct position on the map.

ノ Expand table
yellow-pushpin.png

Before: Bing Maps

In Bing Maps, a custom marker is created by passing a URL to an image into the icon
options of a pushpin. The anchor option is used to align the point of the pushpin image
with the coordinate on the map. The anchor value in Bing Maps relative to the top-left
corner of the image.

JavaScript

var pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(51.5,


-0.2), {
icon: 'ylw-pushpin.png',
anchor: new Microsoft.Maps.Point(5, 30)
});

var layer = new Microsoft.Maps.Layer();


layer.add(pushpin);
map.layers.insert(layer);

After: Azure Maps using HTML Markers

To customize an HTML marker in Azure Maps an HTML string or HTMLElement can be


passed into the htmlContent option of the marker. In Azure Maps, an anchor option is
used to specify the relative position of the marker relative to the position coordinate
using one of nine defined reference points; "center", "top", "bottom", "left", "right", "top-
left", "top-right", "bottom-left", "bottom-right". The content is anchored and is centered
at the "bottom" by default. To make it easier to migrate code from Bing Maps, set the
anchor to "top-left", and then use the offset option with the same offset used in Bing
Maps. The offsets in Azure Maps move in the opposite direction of Bing Maps, so
multiply them by minus one.

 Tip

Add pointer-events:none as a style on the HTML content to disable the default


drag behavior in MS Edge that will display an unwanted icon.

HTML

map.markers.add(new atlas.HtmlMarker({
htmlContent: '<img src="ylw-pushpin.png" style="pointer-events: none;"
/>',
anchor: 'top-left',
pixelOffset: [-5, -30],
position: [-0.2, 51.5]
}));

After: Azure Maps using a Symbol Layer


Symbol layers in Azure Maps support custom images as well, but the image needs to be
loaded into the map resources first and assigned a unique ID. The symbol layer can then
reference this ID. The symbol can be offset to align to the correct point on the image by
using the icon offset option. In Azure Maps, an anchor option is used to specify the
relative position of the symbol relative to the position coordinate using one of nine
defined reference points; "center", "top", "bottom", "left", "right", "top-left", "top-right",
"bottom-left", "bottom-right". The content is anchored and set to "bottom" by default
that is the bottom center of the HTML content. To make it easier to migrate code from
Bing Maps, set the anchor to "top-left", and then use the offset option with the same
offset used in Bing Maps. The offsets in Azure Maps move in the opposite direction of
Bing Maps, so multiply them by minus one.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map, datasource;

function initMap() {
map = new atlas.Map('myMap', {
center: [-0.2, 51.5],
zoom: 9,
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Load the custom image icon into the map resources.


map.imageSprite.add('my-yellow-pin', 'ylw-
pushpin.png').then(function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a point and add it to the data source.


datasource.add(new atlas.data.Point([-0.2, 51.5]));

//Add a layer for rendering point data as symbols.


map.layers.add(new atlas.layer.SymbolLayer(datasource,
null, {
iconOptions: {
//Set the image option to the id of the custom
icon that was loaded into the map resources.
image: 'my-yellow-pin',
anchor: 'top-left',
offset: [-5, -30]
}
}));
});
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
 Tip

To create advanced custom rendering of points, use multiple rendering layers


together. For example, if you want to have multiple pushpins that have the same
icon on different colored circles, instead of creating a bunch of images for each
color overlay a symbol layer on top of a bubble layer and have them reference the
same data source. This will be much more efficient than creating, and having the
map maintain a bunch of different images.

More resources

Create a data source


Add a Symbol layer
Add HTML Markers
Use data-driven style expressions
Symbol layer icon options
Symbol layer text option
HTML marker class
HTML marker options

Adding a polyline
Polylines are used to represent a line or path on the map. The following example
demonstrates creating a dashed polyline on the map.

Before: Bing Maps

In Bing Maps, the Polyline class takes in an array of locations and a set of options.

JavaScript

//Get the center of the map.


var center = map.getCenter();

//Create the polyline.


var polyline = new Microsoft.Maps.Polyline([
center,
new Microsoft.Maps.Location(center.latitude - 0.5, center.longitude
- 1),
new Microsoft.Maps.Location(center.latitude - 0.5, center.longitude
+ 1)
], {
strokeColor: 'red',
strokeThickness: 4,
strokeDashArray: [3, 3]
});

//Add the polyline to the map using a layer.


var layer = new Microsoft.Maps.Layer();
layer.add(polyline);
map.layers.insert(layer);

After: Azure Maps

In Azure Maps, polylines are referred to the more commonly geospatial terms
LineString or MultiLineString objects. These objects can be added to a data source

and rendered using a line layer. The stroke color, width, and dash array options are
nearly identical between the platforms.

JavaScript

//Get the center of the map.


var center = map.getCamera().center;

//Create a data source and add it to the map.


var datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a line and add it to the data source.


datasource.add(new atlas.data.LineString([
center,
[center[0] - 1, center[1] - 0.5],
[center[0] + 1, center[1] - 0.5]
]));
//Add a layer for rendering line data.
map.layers.add(new atlas.layer.LineLayer(datasource, null, {
strokeColor: 'red',
strokeWidth: 4,
strokeDashArray: [3, 3]
}));

More resources

Add lines to the map


Line layer options
Use data-driven style expressions

Adding a polygon
Polygons are used to represent an area on the map. Azure Maps and Bing Maps provide
similar support for polygons. The following example shows how to create a polygon that
forms a triangle based on the center coordinate of the map.

Before: Bing Maps

In Bing Maps, the Polygon class takes in an array of coordinates or coordinate rings and
a set of options.

JavaScript
//Get the center of the map.
var center = map.getCenter();

//Create the polygon.


var polygon = new Microsoft.Maps.Polygon([
center,
new Microsoft.Maps.Location(center.latitude - 0.5, center.longitude
- 1),
new Microsoft.Maps.Location(center.latitude - 0.5, center.longitude
+ 1),
center
], {
fillColor: 'rgba(0, 255, 0, 0.5)',
strokeColor: 'red',
strokeThickness: 2
});

//Add the polygon to the map using a layer.


var layer = new Microsoft.Maps.Layer();
layer.add(polygon);
map.layers.insert(layer);

After: Azure Maps

In Azure Maps, Polygon and MultiPolygon objects can be added to a data source and
rendered on the map using layers. The area of a polygon can be rendered in a polygon
layer. The outline of a polygon can be rendered using a line layer.

JavaScript

//Get the center of the map.


var center = map.getCamera().center;
//Create a data source and add it to the map.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a polygon and add it to the data source.


datasource.add(new atlas.data.Polygon([
center,
[center[0] - 1, center[1] - 0.5],
[center[0] + 1, center[1] - 0.5],
center
]));

//Add a polygon layer for rendering the polygon area.


map.layers.add(new atlas.layer.PolygonLayer(datasource, null, {
fillColor: 'rgba(0, 255, 0, 0.5)'
}));

//Add a line layer for rendering the polygon outline.


map.layers.add(new atlas.layer.LineLayer(datasource, null, {
strokeColor: 'red',
strokeWidth: 2
}));

More resources

Add a polygon to the map


Add a circle to the map
Polygon layer options
Line layer options
Use data-driven style expressions

Display an infobox
More information for an entity can be displayed on the map as an
Microsoft.Maps.Infobox class in Bing Maps, in Azure Maps this is achieved using the
atlas.Popup class. The following example adds a pushpin/marker to the map that when

selected, displays an infobox/popup.

Before: Bing Maps

With Bing Maps, an infobox is created using the Microsoft.Maps.Infobox constructor.

JavaScript

//Add a pushpin where we want to display an infobox.


var pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(47.6,
-122.33));

//Add the pushpin to the map using a layer.


var layer = new Microsoft.Maps.Layer();
layer.add(pushpin);
map.layers.insert(layer);

//Create an infobox and bind it to the map.


var infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(47.6,
-122.33), {
description: '<div style="padding:5px"><b>Hello World!</b></div>',
visible: false
});
infobox.setMap(map);

//Add a click event to the pushpin to open the infobox.


Microsoft.Maps.Events.addHandler(pushpin, 'click', function () {
infobox.setOptions({ visible: true });
});
After: Azure Maps

In Azure Maps, a popup can be used to display more information for a location. An
HTML string or HTMLElement object can be passed into the content option of the
popup. Popups can be displayed independently of any shape if desired and thus require
a position value to be specified. To display a popup, call the open function and pass in
the map that the popup is to be displayed on.

JavaScript

//Add a marker to the map that to display a popup for.


var marker = new atlas.HtmlMarker({
position: [-122.33, 47.6]
});

//Add the marker to the map.


map.markers.add(marker);

//Create a popup.
var popup = new atlas.Popup({
content: '<div style="padding:10px"><b>Hello World!</b></div>',
position: [-122.33, 47.6],
pixelOffset: [0, -35]
});

//Add a click event to the marker to open the popup.


map.events.add('click', marker, function () {
//Open the popup
popup.open(map);
});

7 Note

To do the same thing with a symbol, bubble, line or polygon layer, pass the layer
into the maps event code instead of a marker.

More resources

Add a popup
Popup with Media Content
Popups on Shapes
Reusing Popup with Multiple Pins
Popup class
Popup options

Pushpin clustering
When visualizing many data points on the map, points overlap each other, the map
looks cluttered and it becomes difficult to see and use. Clustering of point data can be
used to improve this user experience and also improve performance. Clustering point
data is the process of combining point data that are near each other and representing
them on the map as a single clustered data point. As the user zooms into the map, the
clusters break apart into their individual data points.

The following example loads a GeoJSON feed of earthquake data from the past week
and adds it to the map. Clusters are rendered as scaled and colored circles depending
on the number of points they contain.

7 Note

There are several different algorithms used for pushpin clustering. Bing Maps uses
a simple grid-based function, while Azure Maps uses a more advanced and visually
appealing point-based clustering method.

Before: Bing Maps

In Bing Maps, GeoJSON data can be loaded using the GeoJSON module. Pushpins are
clustered by loading in the clustering module and using the clustering layer it contains.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson'
;

function initMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: '<Your Bing Maps Key>',
center: new Microsoft.Maps.Location(20, -160),
zoom: 2
});

//Load the GeoJSON and Clustering modules.


Microsoft.Maps.loadModule(['Microsoft.Maps.GeoJson',
'Microsoft.Maps.Clustering'], function () {

//Load the GeoJSON data from a URL.


Microsoft.Maps.GeoJson.readFromUrl(earthquakeFeed, function
(pins) {
//Create a ClusterLayer with options and add it to the
map.
clusterLayer = new Microsoft.Maps.ClusterLayer(pins, {
clusteredPinCallback: createCustomClusteredPin,
gridSize: 100
});

map.layers.insert(clusterLayer);
});
});
}

//A function that defines how clustered pins are rendered.


function createCustomClusteredPin(cluster) {
//Get the number of pushpins in the cluster
var clusterSize = cluster.containedPushpins.length;

var radius = 20; //Default radius to 20 pixels.


var fillColor = 'lime'; //Default to lime green.

if (clusterSize >= 750) {


radius = 40; //If point_count >= 750, radius is 40 pixels.
fillColor = 'red'; //If the point_count >= 750, color is
red.
} else if (clusterSize >= 100) {
radius = 30; //If point_count >= 100, radius is 30
pixels.
fillColor = 'yellow'; //If the point_count >= 100, color
is yellow.
}

//Create an SVG string of a circle with the specified radius and


color.
var svg = ['<svg xmlns="http://www.w3.org/2000/svg" width="',
(radius * 2), '" height="', (radius * 2), '">',
'<circle cx="', radius, '" cy="', radius, '" r="', radius,
'" fill="', fillColor, '"/>',
'<text x="50%" y="50%" dominant-baseline="middle" text-
anchor="middle" style="font-size:12px;font-family:arial;fill:black;" >{text}
</text>',
'</svg>'];

//Customize the clustered pushpin using the generated SVG and


anchor on its center.
cluster.setOptions({
icon: svg.join(''),
anchor: new Microsoft.Maps.Point(radius, radius),
textOffset: new Microsoft.Maps.Point(0, radius - 8)
//Subtract 8 to compensate for height of text.
});
}
</script>

<!-- Bing Maps Script Reference -->


<script src="https://www.bing.com/api/maps/mapcontrol?callback=initMap"
async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

After: Azure Maps

In Azure Maps, data is added and managed by a data source. Layers connect to data
sources and render the data in them. The DataSource class in Azure Maps provides
several clustering options.

cluster – Tells the data source to cluster point data.

clusterRadius - The radius in pixels to cluster points together.

clusterMaxZoom - The maximum zoom level that clustering occurs. Any other

zooming results in all points being rendered as symbols.


clusterProperties - Defines custom properties that are calculated using

expressions against all the points within each cluster and added to the properties
of each cluster point.

When clustering is enabled, the data source sends clustered and unclustered data points
to layers for rendering. The data source is capable of clustering hundreds of thousands
of data points. A clustered data point has the following properties on it:
ノ Expand table

Property name Type Description

cluster boolean Indicates if feature represents a cluster.

cluster_id string A unique ID for the cluster that can be used with the
DataSource classes getClusterExpansionZoom ,
getClusterChildren , and getClusterLeaves functions.

point_count number The number of points the cluster contains.

point_count_abbreviated string A string that abbreviates the point_count value if it's long.
(for example, 4,000 becomes 4K)

The DataSource class has the following helper function for accessing additional
information about a cluster using the cluster_id .

ノ Expand table

Function Return type Description

getClusterChildren(clusterId: Promise<Feature<Geometry, Retrieves the children of


number) any> | Shape> the given cluster on the
next zoom level. These
children can be a
combination of shapes
and subclusters. The
subclusters are features
with properties matching
cluster properties.

getClusterExpansionZoom(clusterId: Promise<number> Calculates a zoom level


number) that the cluster starts
expanding or break apart.

getClusterLeaves(clusterId: number, Promise<Feature<Geometry, Retrieves all points in a


limit: number, offset: number) any> | Shape> cluster. Set the limit to
return a subset of the
points and use the
offset to page through
the points.

When rendering clustered data on the map, it's often easiest to use two or more layers.
The following example uses three layers, a bubble layer for drawing scaled colored
circles based on the size of the clusters, a symbol layer to render the cluster size as text,
and a second symbol layer for rendering the unclustered points. For more information
on rendering clustered data in Azure Maps, see Clustering point data in the Web SDK.
GeoJSON data can be directly imported in Azure Maps using the importDataFromUrl
function on the DataSource class.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map, datasource;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson'
;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-160, 20],
zoom: 1,

//Add your Azure Maps key to the map SDK. Get an Azure Maps
key at https://azure.com/maps. NOTE: The primary key should be used as the
key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource(null, {
//Tell the data source to cluster point data.
cluster: true
});
map.sources.add(datasource);
//Create layers for rendering clusters, their counts and
unclustered points and add the layers to the map.
map.layers.add([
//Create a bubble layer for rendering clustered data
points.
new atlas.layer.BubbleLayer(datasource, null, {
//Scale the size of the clustered bubble based on
the number of points inthe cluster.
radius: [
'step',
['get', 'point_count'],
20, //Default of 20 pixel radius.
100, 30, //If point_count >= 100, radius is
30 pixels.
750, 40 //If point_count >= 750, radius is
40 pixels.
],

//Change the color of the cluster based on the value


on the point_cluster property of the cluster.
color: [
'step',
['get', 'point_count'],
'lime', //Default to lime green.
100, 'yellow', //If the point_count >= 100,
color is yellow.
750, 'red' //If the point_count >= 750,
color is red.
],
strokeWidth: 0,
filter: ['has', 'point_count'] //Only rendered data
points that have a point_count property, which clusters do.
}),

//Create a symbol layer to render the count of locations


in a cluster.
new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'none' //Hide the icon image.
},
textOptions: {
textField: ['get', 'point_count_abbreviated'],
offset: [0, 0.4]
}
}),

//Create a layer to render the individual locations.


new atlas.layer.SymbolLayer(datasource, null, {
filter: ['!', ['has', 'point_count']] //Filter out
clustered points from this layer.
})
]);

//Retrieve a GeoJSON data set and add it to the data source.


datasource.importDataFromUrl(earthquakeFeed);
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources

Add a Symbol layer


Add a Bubble layer
Cluster point data
Use data-driven style expressions

Add a heat map


Heat maps, also known as point density maps, are a type of data visualization used to
represent the density of data using a range of colors. They're often used to show the
data "hot spots" on a map and are a great way to render large point data sets.

The following example loads a GeoJSON feed of all earthquakes over the past month
from the USGS, rendered as a heat map.

Before: Bing Maps


In Bing Maps, to create a heat map, load in the heat map module. Similarly, the
GeoJSON module is loaded to add support for GeoJSON data.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson
';

function initMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: '<Your Bing Maps Key>',
center: new Microsoft.Maps.Location(20, -160),
zoom: 2,
mapTypeId: Microsoft.Maps.MapTypeId.aerial
});

//Load the GeoJSON and HeatMap modules.


Microsoft.Maps.loadModule(['Microsoft.Maps.GeoJson',
'Microsoft.Maps.HeatMap'], function () {

//Load the GeoJSON data from a URL.


Microsoft.Maps.GeoJson.readFromUrl(earthquakeFeed, function
(shapes) {

//Create a heat map and add it to the map.


var heatMap = new Microsoft.Maps.HeatMapLayer(shapes, {
opacity: 0.65,
radius: 10
});
map.layers.insert(heatMap);
});
});
}
</script>

<!-- Bing Maps Script Reference -->


<script src="https://www.bing.com/api/maps/mapcontrol?callback=initMap"
async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

After: Azure Maps

In Azure Maps, load the GeoJSON data into a data source and connect the data source
to a heat map layer. GeoJSON data can be directly imported in Azure Maps using the
importDataFromUrl function on the DataSource class.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson
';

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-160, 20],
zoom: 1,
style: 'satellite_road_labels',

//Add your Azure Maps key to the map SDK. Get an Azure Maps
key at https://azure.com/maps. NOTE: The primary key should be used as the
key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Load the earthquake data.


datasource.importDataFromUrl(earthquakeFeed);

//Create a layer to render the data points as a heat map.


map.layers.add(new atlas.layer.HeatMapLayer(datasource,
null, {
opacity: 0.65,
radius: 10
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
More resources

Add a heat map layer


Heat map layer class
Heat map layer options
Use data-driven style expressions

Overlay a tile layer


Tile layers allow you to overlay large images that have been broken up into smaller tiled
images that align with the maps tiling system. This is a common way to overlay large
images or large data sets.

The following example overlays a weather radar tile layer from Iowa Environmental
Mesonet of Iowa State University that uses an X, Y, Zoom tiling naming schema.

Before: Bing Maps

In Bing Maps, tile layers can be created by using the Microsoft.Maps.TileLayer class.

JavaScript

var weatherTileLayer = new Microsoft.Maps.TileLayer({


mercator: new Microsoft.Maps.TileSource({
uriConstructor:
'https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-
900913/{zoom}/{x}/{y}.png'
})
});
map.layers.insert(weatherTileLayer);

After: Azure Maps

In Azure Maps, a tile layer can be added to the map in much the same way as any other
layer. A formatted URL that has in x, y, zoom placeholders; {x} , {y} , {z} respectively is
used to tell the layer where to access the tiles. Azure Maps tile layers also support
{quadkey} , {bbox-epsg-3857} , and {subdomain} placeholders.

 Tip

In Azure Maps, layers can be rendered below other layers, including base map
layers. Often it is desirable to render tile layers below the map labels so that they
are easy to read. The map.layers.add function takes in a second parameter that is
the ID of a second layer to insert the new layer below. To insert a tile layer below
the map labels the following code can be used:

map.layers.add(myTileLayer, "labels");

JavaScript

//Create a tile layer and add it to the map below the label layer.
map.layers.add(new atlas.layer.TileLayer({
tileUrl: 'https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-
n0q-900913/{z}/{x}/{y}.png',
opacity: 0.8,
tileSize: 256
}), 'labels');

 Tip

Tile requests can be captured using the transformRequest option of the map. This
will allow you to modify or add headers to the request if desired.

More resources

Add tile layers


Tile layer class
Tile layer options

Show traffic data


Traffic data can be overlaid both Bing and Azure maps.

Before: Bing Maps

In Bing Maps, traffic data can be overlaid the map using the traffic module.

JavaScript

Microsoft.Maps.loadModule('Microsoft.Maps.Traffic', function () {
var manager = new Microsoft.Maps.Traffic.TrafficManager(map);
manager.show();
});

After: Azure Maps

Azure Maps provides several different options for displaying traffic. Traffic incidents,
such as road closures and accidents can be displayed as icons on the map. Traffic flow,
color coded roads, can be overlaid on the map and the colors can be modified relative
to the posted speed limit, relative to the normal expected delay, or absolute delay.
Incident data in Azure Maps is updated every minute and flow data every 2 minutes.

JavaScript

map.setTraffic({
incidents: true,
flow: 'relative'
});
If you select one of the traffic icons in Azure Maps, more information displays in a
popup.

More resources

Show traffic on the map


Traffic overlay options
Traffic control

Add a ground overlay


Both Bing and Azure maps support overlaying georeferenced images on the map that
they move and scale as you pan and zoom the map. In Bing Maps these are known as
ground overlays, in Azure Maps they're referred to as image layers. Image layers are
great for building floor plans, overlaying old maps, or imagery from a drone.

Before: Bing Maps

To create a ground overlay in Bing Maps, you need to specify the URL to the overlay
image and a bounding box that binds the image to the map. This example overlays a
map image of Newark New Jersey from 1922 on the map.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;

function initMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: '<Your Bing Maps Key>',
center: new Microsoft.Maps.Location(40.740, -74.18),
zoom: 12
});

var overlay = new Microsoft.Maps.GroundOverlay({


//Create a LocationRect from the edges of the bounding box;
north, west, south, east.
bounds: Microsoft.Maps.LocationRect.fromEdges(40.773941,
-74.22655, 40.712216, -74.12544),
imageUrl: 'newark_nj_1922.jpg'
});
map.layers.insert(overlay);
}
</script>

<!-- Bing Maps Script Reference -->


<script src="https://www.bing.com/api/maps/mapcontrol?callback=initMap"
async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:

After: Azure Maps

In Azure Maps, georeferenced images can be overlaid using the atlas.layer.ImageLayer


class. This class requires a URL to an image and a set of coordinates for the four corners
of the image. The image must be hosted either on the same domain or have CORs
enabled.

 Tip

If you only have north, south, east, west and rotation information, and not
coordinates for each corner of the image, you can use the static
atlas.layer.ImageLayer.getCoordinatesFromEdges function.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-74.18, 40.740],
zoom: 12,

//Add your Azure Maps key to the map SDK. Get an Azure Maps
key at https://azure.com/maps. NOTE: The primary key should be used as the
key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create an image layer and add it to the map.


map.layers.add(new atlas.layer.ImageLayer({
url: 'newark_nj_1922.jpg',
coordinates: [
[-74.22655, 40.773941], //Top Left Corner
[-74.12544, 40.773941], //Top Right Corner
[-74.12544, 40.712216], //Bottom Right Corner
[-74.22655, 40.712216] //Bottom Left Corner
]
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources

Overlay an image
Image layer class

Add KML data to the map


Both Azure and Bing maps can import and render KML, KMZ, GeoRSS, GeoJSON and
Well-Known Text (WKT) data on the map. Azure Maps also supports GPX, GML, spatial
CSV files, Web-Mapping Services (WMS), Web-Mapping Tile Services (WMTS), and Web
Feature Services (WFS).

Before: Bing Maps

Running this code in a browser displays a map that looks like the following image:

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;
function initMap() {
map = new Microsoft.Maps.Map('#myMap', {
credentials: '<Your Bing Maps Key>',
center: new Microsoft.Maps.Location(40.747, -73.985),
zoom: 12
});

Microsoft.Maps.loadModule('Microsoft.Maps.GeoXml', function () {
var callback = function (dataset) {
if (dataset.shapes) {
var l = new Microsoft.Maps.Layer();
l.add(dataset.shapes);
map.layers.insert(l);
}
if (dataset.layers) {
for (var i = 0, len = dataset.layers.length; i <
len; i++) {
map.layers.insert(dataset.layers[i]);
}
}
};
Microsoft.Maps.GeoXml.readFromUrl('myKMLFile.kml', { error:
function (msg) { alert(msg); } }, callback);
});
}
</script>

<!-- Bing Maps Script Reference -->


<script src="https://www.bing.com/api/maps/mapcontrol?callback=initMap"
async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
After: Azure Maps

In Azure Maps, GeoJSON is the main data format used in the web SDK, more spatial
data formats can be easily integrated in using the spatial IO module. This module has
functions for both reading and writing spatial data and also includes a simple data layer
that can easily render data from any of these spatial data formats. To read the data in a
spatial data file, pass in a URL, or raw data as string or blob into
the atlas.io.read function. This returns all the parsed data from the file that can then
be added to the map. KML is a bit more complex than most spatial data format as it
includes a lot more styling information. The SpatialDataLayer class supports rendering
most of these styles, however icons images have to be loaded into the map before
loading the feature data, and ground overlays have to be added as layers to the map
separately. When loading data via a URL, it should be hosted on a CORs enabled
endpoint, or a proxy service should be passed in as an option into the read function.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<!-- Add reference to the Azure Maps Spatial IO module. -->


<script src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.js"></script>

<script type='text/javascript'>
var map, datasource, layer;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',

//Add your Azure Maps key to the map SDK. Get an Azure Maps
key at https://azure.com/maps. NOTE: The primary key should be used as the
key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering the data.


layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);

//Read a KML file from a URL or pass in a raw KML string.


atlas.io.read('myKMLFile.kml').then(async r => {
if (r) {

//Check to see if there are any icons in the data


set that need to be loaded into the map resources.
if (r.icons) {
//For each icon image, create a promise to add
it to the map, then run the promises in parrallel.
var imagePromises = [];

//The keys are the names of each icon image.


var keys = Object.keys(r.icons);
if (keys.length !== 0) {
keys.forEach(function (key) {

imagePromises.push(map.imageSprite.add(key, r.icons[key]));
});

await Promise.all(imagePromises);
}
}

//Load all features.


if (r.features && r.features.length > 0) {
datasource.add(r.features);
}

//Load all ground overlays.


if (r.groundOverlays && r.groundOverlays.length > 0)
{
map.layers.add(r.groundOverlays);
}

//If bounding box information is known for data, set


the map view to it.
if (r.bbox) {
map.setCamera({ bounds: r.bbox, padding: 50 });
}
}
});
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources

atlas.io.read function
SimpleDataLayer
SimpleDataLayerOptions

Add drawing tools


Both Bing and Azure Maps provide a module to enable the user to draw and edit shapes
on the map using the mouse or other input devices. They both support drawing
pushpins, lines, and polygons. Azure Maps also provides options for drawing circles and
rectangles.

Before: Bing Maps

In Bing Maps the DrawingTools module is loaded using the Microsoft.Maps.loadModule


function. Once loaded, an instance of the DrawingTools class can be created and the
showDrawingManager function is called add a toolbar to the map.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map, drawingManager;

function initMap() {
map = new Microsoft.Maps.Map('#myMap', {
credentials: '<Your Bing Maps Key>'
});

//Load the DrawingTools module


Microsoft.Maps.loadModule('Microsoft.Maps.DrawingTools', function ()
{
//Create an instance of the DrawingTools class and bind it to
the map.
var tools = new Microsoft.Maps.DrawingTools(map);

//Show the drawing toolbar and enable editting on the map.


tools.showDrawingManager(function (manager) {
//Store a reference to the drawing manager as it will be
useful later.
drawingManager = manager;
});
});
}
</script>

<!-- Bing Maps Script Reference -->


<script src="https://www.bing.com/api/maps/mapcontrol?callback=initMap"
async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
After: Azure Maps

In Azure Maps, the drawing tools module needs to be loaded by loading the JavaScript
and CSS files need to be referenced in the app. Once the map is loaded, an instance of
the DrawingManager class can be created and a DrawingToolbar instance attached.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/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>

<script type='text/javascript'>
var map, drawingManager;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',

//Add your Azure Maps key to the map SDK. Get an Azure Maps
key at https://azure.com/maps. NOTE: The primary key should be used as the
key.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create an instance of the drawing manager and display the


drawing toolbar.
drawingManager = new atlas.drawing.DrawingManager(map, {
toolbar: new atlas.control.DrawingToolbar({ position:
'top-left' })
});
});
}
</script>
</head>
<body onload="initMap()">
<div id="myMap" style="position:relative;width:600px;height:400px;">
</div>
</body>
</html>

 Tip

In Azure Maps layers the drawing tools provide multiple ways that users can draw
shapes. For example, when drawing a polygon the user can click to add each point,
or hold the left mouse button down and drag the mouse to draw a path. This can
be modified using the interactionType option of the DrawingManager .

More resources

Use the drawing tools module


Drawing tools module code samples

Additional resources
Take a look at the open-source Azure Maps Web SDK modules. These modules provide
more functionality and are fully customizable.

Review code samples related migrating other Bing Maps features:

Data visualizations

Contour layer

Services
Search for points of interest

Get information from a coordinate (reverse geocode)

Show directions from A to B

Search Autosuggest with JQuery UI

Learn more about the Azure Maps Web SDK.

How to use the map control

How to use the drawing tools module

Code samples

Azure Maps Web SDK Service API reference documentation

Next steps
Learn more about migrating from Bing Maps to Azure Maps.

Migrate a web service

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Migrate Bing Maps Enterprise
applications to Azure Maps with GitHub
Copilot
Article • 05/17/2024

GitHub Copilot is an AI-powered code assistant that helps you write better code
faster. GitHub Copilot can generate code snippets from your prompts and suggest
completions for your existing code. GitHub Copilot can also learn from your code and
preferences and adapt to your style and needs. While GitHub Copilot can't directly
convert your code from Bing Maps Web SDK to Azure Maps Web SDK or from Bing
Maps APIs to Azure Maps APIs, this how-to article shows you how to use GitHub Copilot
to generate code for your Azure Maps applications. This can be especially helpful if
you're migrating from Bing Maps for Enterprise to Azure Maps.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps
A basic understanding of Azure Maps Web SDK
A basic understanding of Azure Maps APIs
A GitHub account and subscription for GitHub Copilot
A basic understanding of the differences between Bing Maps for Enterprise and
Azure Maps, see the following articles:
Migrate from Bing Maps to Azure Maps
Migrate a web app from Bing Maps

Tip 1: Write your prompts in clear sentences


The first step to use GitHub Copilot is to write your prompts in simple sentences. A
prompt is a short description of what you want to do or achieve with your code. For
example, if you want to display a GeoJSON file with Azure Maps Web SDK, you might
write a prompt like this:

Write an HTML program using Azure Maps WebSDK v3 to display GeoJSON features
in a SymbolLayer from the following URL:
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
GitHub Copilot then generates a code snippet that matches your prompt, using the
language and framework of your choice. For example, if you're using HTML and
JavaScript, GitHub Copilot might generate a code snippet like this:

HTML

<!DOCTYPE html>
<html>
<head>
<title>Earthquake Data</title>
<script
src='https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js'>
</script>
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<style>
#myMap { width: 100%; height: 500px; }
</style>
</head>
<body>
<div id="myMap"></div>
<script>
var map = new atlas.Map("myMap", {
center: [-100, 39],
zoom: 3,
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: 'Your Azure Maps Key'
}
});

map.events.add('ready', function() {

fetch('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geo
json')
.then(response => response.json())
.then(data => {
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
dataSource.add(data);

map.layers.add(new atlas.layer.SymbolLayer(dataSource));
});
});
</script>
</body>
</html>
As you can see, GitHub Copilot can generate a complete and functional code snippet
from a simple and clear prompt. You can then copy and paste the code snippet into
your code editor or modify it as you wish. You can also ask GitHub Copilot to generate
alternative code snippets, or to complete or suggest changes to your existing code.

The advantage of writing your prompts in clear sentences, rather than relying on code
snippets from your Bing Maps for Enterprise application, is that you can focus on the
logic and functionality of your application, making it more precise for GitHub Copilot to
understand your goal. You can also avoid copying and pasting code snippets that might
be ambiguous and could potentially confuse GitHub Copilot.

7 Note

You might get different results each time you run the same prompt, and
occasionally you might encounter inaccuracies, like a method that doesn't exist.
Make sure to check the browser console for any errors and adjust the code if
needed.

Tip 2: Provide detailed, step-by-step


instructions
The second tip for using GitHub Copilot is to provide detailed, step-by-step instructions.
Imagine that you are a product manager writing functional specifications for your
product. For instance, if you want to geocode the address, ‘1 Microsoft Way, Redmond,
WA’ and add a marker on the map, you can write a prompt like the following:

Write an HTML program using Azure Maps Web SDK v3 to make a geocode request
for the coordinates of '1 Microsoft Way, Redmond, WA' and then place a marker at
that location.

Step 1. Utilize the Geocode API endpoint: https://atlas.microsoft.com/geocode?api-


version=2023-06-01&subscription-key=${subscriptionKey}&query=${query} . An
example response is provided for reference.

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"address":
{"countryRegion":{"name":"United States"},"adminDistricts":[{"shortName":"WA"},
{"shortName":"King County"}],"formattedAddress":"15127 NE 24th St, Redmond, WA
98052","locality":"Redmond","postalCode":"98052","addressLine":"15127 NE 24th
St"},"type":"Address","confidence":"High","matchCodes":["Good"],"geocodePoints":
[{"geometry":{"type":"Point","coordinates":
[-122.138681,47.630358]},"calculationMethod":"Rooftop","usageTypes":["Display"]},
{"geometry":{"type":"Point","coordinates":
[-122.1386787,47.6302179]},"calculationMethod":"Rooftop","usageTypes":
["Route"]}]},"geometry":{"type":"Point","coordinates":
[-122.138681,47.630358]},"bbox":
[-122.14632282407,47.626495282429325,-122.13103917593001,47.63422071757068
]}]}

Step 2. Make a Geocode API request for the coordinates of '1 Microsoft Way,
Redmond, WA'.

Step 3. Use Azure Maps WebSDK to display a map, centering it on the coordinates
obtained from the Geocode API response.

Step 4. Wait until the map resources are ready.

Step 5. Place a marker on the map at the coordinates obtained from the API
response.

GitHub Copilot generates a code snippet that matches your instructions, using Azure
Maps Geocode API and Azure Maps Web SDK.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Azure Maps Geocode and Pushpin Example</title>
<script type="text/javascript"
src="https://atlas.microsoft.com/sdk/js/atlas.min.js?api-version=3">
</script>
<style>
#map {
width: 100%;
height: 400px;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var subscriptionKey = 'YOUR_SUBSCRIPTION_KEY'; // Replace with your
Azure Maps subscription key
var query = '1 Microsoft Way, Seattle';

// Make Geocode API request


fetch(`https://atlas.microsoft.com/geocode?api-version=2023-06-
01&subscription-key=${subscriptionKey}&query=${query}`)
.then(response => response.json())
.then(data => {
// Extract coordinates from the API response
var coordinates = data.features[0].geometry.coordinates;

// Initialize map
var map = new atlas.Map('map', {
center: coordinates,
zoom: 14,
view: 'Auto',
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: subscriptionKey
}
});

// Wait until map resources are ready


map.events.add('ready', function () {
// Add pushpin to the map
var pushpin = new atlas.HtmlMarker({
position: coordinates,
htmlContent: '<div style="background-color: #286090;
color: #fff; padding: 5px;">1 Microsoft Way</div>'
});
map.markers.add(pushpin);
});
})
.catch(error => console.error('Error:', error));
</script>
</body>
</html>
Breaking down a complex prompt into individual steps makes it easier for GitHub
Copilot to understand and follow, giving you better control over the code flow.

7 Note

To create effective prompts, you need to customize them for different scenarios.
Refining the prompt iteratively allows you to achieve the best possible outcome.

Tip 3: Include examples for API request inputs


and response outputs
The third tip for using GitHub Copilot is to include examples for API inputs and outputs.
Providing examples can improve Copilot's ability to generate accurate and relevant code
snippets by allowing it to learn how to handle the data.

To get examples of inputs and outputs for Azure Maps APIs, you may refer to the Azure
Maps REST API documentation. For example, you can see a sample request body and
response for the Azure Maps Geocoding Batch API and the Azure Maps Directions API. If
you want to create an application for routing between two locations using Azure Maps,
you can write a prompt like this:

Implement an HTML program using Azure Maps Web SDK v3 to show route
directions for user-specified locations.

Step 1. Create two input boxes for users to enter the starting and ending street
addresses. Add a submit button to proceed to the next step.
Step 2. Utilize the Geocode Batch POST API:
https://atlas.microsoft.com/geocode:batch?api-version=2023-06-01&subscription-
key=${subscriptionKey} to find the coordinates of the start and end points.

Example request body:

{ "batchItems": [ { "addressLine": "1 Microsoft Way, Redmond, WA" }, { "addressLine":


"400 Broad St, Seattle, WA" } ] }

Example response:

{"batchItems":[{"type":"FeatureCollection","features":[{"type":"Feature","geometry":
{"type":"Point","coordinates":[-122.128265,47.639385]},"bbox":
[-122.13590814413995,47.63552228242932,-122.12062185586005,47.643247717570
674],"properties":{"type":"Address","confidence":"Medium","matchCodes":
["Good"],"geocodePoints":[{"calculationMethod":"Rooftop","usageTypes":
["Display"],"geometry":{"type":"Point","coordinates":[-122.128265,47.639385]}},
{"calculationMethod":"Rooftop","usageTypes":["Route"],"geometry":
{"type":"Point","coordinates":[-122.1271239,47.6385519]}}],"address":
{"addressLine":"1 Microsoft
Way","postalCode":"98052","locality":"Redmond","formattedAddress":"1 Microsoft
Way, Redmond, WA 98052","countryRegion":{"name":"United
States","ISO":"US"},"adminDistricts":[{"shortName":"WA"},{"shortName":"King
County"}]}}}]},{"type":"FeatureCollection","features":[{"type":"Feature","geometry":
{"type":"Point","coordinates":[-122.349309,47.620498]},"bbox":
[-122.35694938292329,47.61663528242932,-122.34166861707672,47.624360717570
674],"properties":{"type":"Address","confidence":"High","matchCodes":
["Good"],"geocodePoints":[{"calculationMethod":"Rooftop","usageTypes":
["Display"],"geometry":{"type":"Point","coordinates":[-122.349309,47.620498]}},
{"calculationMethod":"Rooftop","usageTypes":["Route"],"geometry":
{"type":"Point","coordinates":[-122.3485587,47.6200534]}}],"address":
{"addressLine":"400 Broad St","postalCode":"98109","neighborhood":"Queen
Anne","locality":"Seattle","formattedAddress":"400 Broad St, Seattle, WA
98109","countryRegion":{"name":"United States","ISO":"US"},"adminDistricts":
[{"shortName":"WA"},{"shortName":"King County"}]}}}]}],"summary":
{"successfulRequests":2,"totalRequests":2}}

Step 3. Use Azure Maps WebSDK to display a map.

Step 4. Wait until the map resources are ready.

Step 5. Create and add a DataSource to the map.

Step 6. Create and add a SymbolLayer to the map.


Step 7. Create and add a LineLayer to the map.

Step 8. Utilize the Route POST API: https://atlas.microsoft.com/route/directions?api-


version=2023-10-01-preview&subscription-key=${subscriptionKey} to find the
route between the start and end points. Add the GeoJSON response to the
DataSource and adjust the map's camera based on the bounding box of the
response.

Example request body:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": {


"coordinates": [ -122.1271239, 47.6385519 ], "type": "Point" }, "properties": {
"pointIndex": 0, "pointType": "waypoint" } }, { "type": "Feature", "geometry": {
"coordinates": [ -122.3485587, 47.6200534 ], "type": "Point" }, "properties": {
"pointIndex": 1, "pointType": "waypoint" } } ], "routeOutputOptions": [ "routePath" ],

"travelMode": "driving" }

Example response:

{"type":"FeatureCollection","features":[{"type":"Feature","geometry":
{"type":"Point","coordinates":[-122.127124,47.638552]},"properties":
{"routePathPoint":{"legIndex":0,"pointIndex":0},"order":
{"inputIndex":0},"type":"Waypoint"}},{"type":"Feature","geometry":
{"type":"Point","coordinates":[-122.348533,47.620073]},"properties":
{"routePathPoint":{"legIndex":0,"pointIndex":113},"order":
{"inputIndex":1},"type":"Waypoint"}},{"type":"Feature","geometry":
{"type":"MultiLineString","coordinates":[[[-122.127123,47.638551],
[-122.127236,47.638786],[-122.127778,47.639321],[-122.127588,47.639453],
[-122.126935,47.639906],[-122.128569,47.64092],[-122.128269,47.641159],
[-122.128004,47.641435],[-122.128064,47.641947],[-122.127464,47.642446],
[-122.127433,47.642452],[-122.127358,47.642589],[-122.127333,47.642706],
[-122.127044,47.643317],[-122.127,47.646063],[-122.12707,47.646064],
[-122.1355,47.646072],[-122.135465,47.645943],[-122.134932,47.644569],
[-122.134655,47.643384],[-122.134688,47.64219],[-122.134994,47.640816],
[-122.135396,47.640114],[-122.135694,47.639576],[-122.136586,47.638589],
[-122.138502,47.637193],[-122.14906,47.631126],[-122.150578,47.630481],
[-122.152672,47.629904],[-122.15453,47.629628],[-122.156691,47.629525],
[-122.163925,47.630213],[-122.168574,47.629931],[-122.170237,47.629981],
[-122.171667,47.630214],[-122.179348,47.631954],[-122.181849,47.632144],
[-122.185924,47.632041],[-122.186778,47.632117],[-122.187833,47.632345],
[-122.188876,47.632739],[-122.190017,47.633476],[-122.190692,47.634194],
[-122.191623,47.635672],[-122.192652,47.636933],[-122.195835,47.639784],
[-122.197456,47.640891],[-122.199124,47.641725],[-122.20114,47.642394],
[-122.202483,47.642648],[-122.206548,47.643149],[-122.208346,47.643164],
[-122.210355,47.642861],[-122.218068,47.640503],[-122.219353,47.64005],
[-122.220547,47.639476],[-122.223398,47.637523],[-122.224491,47.636915],
[-122.22566,47.636477],[-122.226843,47.636165],[-122.228471,47.635972],
[-122.229575,47.636001],[-122.231286,47.636192],[-122.238445,47.637468],
[-122.241606,47.638218],[-122.243095,47.638484],[-122.269838,47.642514],
[-122.275227,47.643424],[-122.279804,47.644349],[-122.282342,47.644655],
[-122.289531,47.645049],[-122.29387,47.645413],[-122.296978,47.645393],
[-122.300182,47.645129],[-122.304222,47.64444],[-122.308205,47.64353],
[-122.30968,47.64328],[-122.31467,47.643113],[-122.318608,47.64274],
[-122.318874,47.642714],[-122.321852,47.642389],[-122.322434,47.642195],
[-122.322857,47.641863],[-122.323024,47.641566],[-122.323072,47.641284],
[-122.323134,47.638686],[-122.323246,47.637911],[-122.323243,47.637778],
[-122.323332,47.636353],[-122.323548,47.635195],[-122.323781,47.634413],
[-122.324407,47.632851],[-122.324663,47.632356],[-122.3252,47.631657],
[-122.326806,47.630159],[-122.327268,47.629875],[-122.327954,47.629266],
[-122.328755,47.628281],[-122.328928,47.627756],[-122.328967,47.626499],
[-122.329233,47.626199],[-122.330614,47.625588],[-122.332592,47.625034],
[-122.334379,47.624774],[-122.334564,47.624765],[-122.336411,47.624697],
[-122.340045,47.624729],[-122.342033,47.624546],[-122.343379,47.624517],
[-122.347561,47.624571],[-122.347564,47.624483],[-122.347606,47.62079],
[-122.347687,47.620726],[-122.348533,47.620073]]],"bbox":
[-122.348533,47.620073,-122.126935,47.646072]},"properties":{"resourceId":"v70,h-
1356265451,i0,a0,cen-
US,dAAAAAAAAAAA1,y0,s1,m1,o1,t0,wO6aTEbzRR0CPQkjMIohewA2v12,wBmPp6F3
PR0AfTybJTpZewA2v12,k1,qatt:1","trafficCongestion":"None","trafficDataUsed":"Non
e","distanceInMeters":21606,"durationInSeconds":1455,"departureTime":"2024-03-
04T03:05:01+00:00","arrivalTime":"2024-03-
04T03:29:16+00:00","type":"RoutePath","legs":
[{"distanceInMeters":21606,"durationInSeconds":1455,"departureTime":"2024-03-
04T03:05:01+00:00","arrivalTime":"2024-03-04T03:29:16+00:00","routePathRange":
{"legIndex":0,"range":[0,113]},"description":"WA-520 W"}]}}]}

GitHub Copilot can create the following code snippet to provide an interface for users to
enter start and end addresses and show the route on the map using Azure Maps APIs
based on the sample inputs and outputs.

HTML
<!DOCTYPE html>
<html>
<head>
<title>Azure Maps Route Directions</title>
<meta charset="utf-8" />
<link

href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
rel="stylesheet"
/>
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>
<style>
html,
body,
#myMap {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#inputPanel {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background-color: rgba(255, 255, 255, 0.7);
padding: 10px;
border-radius: 10px;
}
</style>
</head>
<body>
<div id="inputPanel">
<input id="startInput" placeholder="Enter starting address" />
<input id="endInput" placeholder="Enter ending address" />
<button id="submitBtn">Get Directions</button>
</div>
<div id="myMap"></div>
<script>
var subscriptionKey = "YOUR_SUBSCRIPTION_KEY";
var map, dataSource;

function getCoordinates() {
var startAddress = document.getElementById("startInput").value;
var endAddress = document.getElementById("endInput").value;

fetch(
`https://atlas.microsoft.com/geocode:batch?api-version=2023-06-
01&subscription-key=${subscriptionKey}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
batchItems: [
{
addressLine: startAddress,
},
{
addressLine: endAddress,
},
],
}),
}
)
.then((response) => response.json())
.then((data) => {
var startCoordinates =
data.batchItems[0].features[0].geometry.coordinates;
var endCoordinates =
data.batchItems[1].features[0].geometry.coordinates;
getRoute(startCoordinates, endCoordinates);
});
}

function getRoute(startCoordinates, endCoordinates) {


fetch(
`https://atlas.microsoft.com/route/directions?api-version=2023-10-
01-preview&subscription-key=${subscriptionKey}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
coordinates: startCoordinates,
type: "Point",
},
properties: {
pointIndex: 0,
pointType: "waypoint",
},
},
{
type: "Feature",
geometry: {
coordinates: endCoordinates,
type: "Point",
},
properties: {
pointIndex: 1,
pointType: "waypoint",
},
},
],
routeOutputOptions: ["routePath"],
travelMode: "driving",
}),
}
)
.then((response) => response.json())
.then((data) => {
dataSource.clear();
dataSource.add(data);
map.setCamera({
bounds: atlas.data.BoundingBox.fromData(data),
padding: 50,
});
});
}

map = new atlas.Map("myMap", {


authOptions: {
authType: "subscriptionKey",
subscriptionKey: subscriptionKey,
},
});

map.events.add("ready", function () {
dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

map.layers.add(new atlas.layer.LineLayer(dataSource));
map.layers.add(new atlas.layer.SymbolLayer(dataSource));

document
.getElementById("submitBtn")
.addEventListener("click", getCoordinates);
});
</script>
</body>
</html>
Providing examples of Azure Maps API request inputs and response outputs can help
GitHub Copilot generate more accurate and relevant code snippets. Minify the JSON to
reduce the token count when necessary. The same technique can also be applied when
calling your own API services, allowing GitHub Copilot to understand how your API
works.

Known limitations
Keep in mind that the generated code snippet requires engineering effort to review and
there are a few limitations:

1. CSS styling is typically not included unless you explicitly instruct GitHub Copilot to
add it.
2. If you ask Copilot to translate Bing Maps Web SDK code into Azure Maps Web SDK
code, it usually yields poor results because there isn't always a one-to-one
mapping between them.
3. You might encounter occasional inaccuracies, and it requires debugging skills and
some trial and error.

Conclusion
This how-to guide demonstrates how to use GitHub Copilot to generate code snippets
for your application. This capability can be helpful when migrating applications from
Bing Maps for Enterprise to Azure Maps.

We have covered the following:

Write your prompts in clear sentences.


Provide detailed, step-by-step instructions.
Include examples for Azure Maps API request inputs and response outputs.

Next steps
Explore other advanced Prompt engineering techniques to assist you in refining your
prompts.

Prompt engineering techniques


Migrate Bing Maps Get Imagery
Metadata API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Get Imagery Metadata API to the
Azure Maps Get Map Tile API.

The Azure Maps Get Map Tile API provides map tiles in vector or raster formats to be
used in the Azure Maps Web SDK or 3rd party map controls. Some example tiles that
can be requested are Azure Maps road, satellite/aerial, weather radar or indoor map tiles
(generated using Azure Maps Creator).

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Get Imagery Metadata API provides map tile metadata in the body of
the HTML response, including a URL to get the map tile image ( ImageUrl ). Azure
Maps Get Map Tile API provides the map tile image directly in the HTML response,
but doesn't include metadata.
Bing Maps Get Imagery Metadata API provides map tile metadata in the body of
the HTML response, including map tile vintage information ( vintageStart and
vintageEnd ). Azure Maps Get Map Tile API provides map tile vintage information in

the response header (Data-Capture-Date-Range), rather than in the body of the


HTML response.
Bing Maps Get Imagery Metadata API provides map tile metadata in the body of
the HTML response, including copyright information for the map tiles. For Azure
Maps Get Map Tile API, map copyright attribution information can be obtained
from Azure Maps Get Map Attribution API. Copyright attribution information
should be displayed on the map as per the Azure Maps Product Terms .
Azure Maps Get Map Tile API doesn't offer the following Bing Maps Get Imagery
Metadata API map styles: Streetside, Birdseye, and Ordnance Survey.
Azure Maps Get Map Tile API doesn't currently offer a satellite/aerial map style
with road labels, like Bing Maps Get Imagery Metadata API
AerialWithLabelsOnDemand map style. However, the Azure Maps Web SDK does
offer a similar map style called satellite_road_labels.
Bing Maps Get Imagery Metadata API offers 256 x 256 pixel tile size. Azure Maps
Get Map Tile API offers 256 x 256 pixel tile size and 512 x 512 pixel tile size. For
more information, see MapTileSize.
Bing Maps Get Imagery Metadata API supports XML and JSON response formats,
while Azure Maps Get Map Tile API only supports JSON.
Bing Maps Get Imagery Metadata API offers map style basemaps such as roads
and satellite/ hybrid using the imagerySet URI parameter. Azure Maps Get Map Tile
API provides similar offerings basemaps by using the TilesetID URI parameter.
Azure Maps TilesetID doesn't support AerialWithLabelsOnDemand or
AerialWithLabels tiles in Get Map Tiles. Hybrid tiles are only available in the Azure

Maps Web SDK Map Control.


Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports
specifying a geographic scope, which allows you to limit data residency to the
European (EU) or United States (US) geographic areas (geos). All requests
(including input data) are processed exclusively in the specified geographic area.
For more information, see Azure Maps service geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports
multiple ways to authenticate your API calls, such as a subscription key, Microsoft Entra
ID, and Shared Access Signature (SAS) Token. For more information on security and
authentication in Azure Maps, See Authentication with Azure Maps and the Security
section in the Azure Maps Get Map Tile documentation.

Request parameters
The following table lists the Bing Maps Get Imagery Metadata request parameters and
the Azure Maps equivalent:

ノ Expand table

Bing Maps Bing Maps Azure Required Azure Description


Request Request Maps in Azure Maps
Parameter Parameter Request Maps Data
Alias Parameter Type

imagerySet None tilesetId True TilesetID Azure Maps has some map
styles that Bing Maps Get
Bing Maps Bing Maps Azure Required Azure Description
Request Request Maps in Azure Maps
Parameter Parameter Request Maps Data
Alias Parameter Type

Imagery Metadata API


doesn’t have. Bing Maps Get
Imagery Metadata API has
some map styles that Azure
Maps doesn’t have. For more
information on the map
styles offered by Azure Maps,
see TilesetID.

centerPoint None x True integer For more information on X, Y


y int32 coordinates, see Zoom levels
and tile grid.

culture c language False string For more information, see


Azure Maps Supported
Languages.

include incl NA NA NA The only option for this


parameter in Bing Maps is
ImageryProviders . When
specified, attribution
information about the
imagery providers is returned
in the response, which should
be displayed on the map. For
Azure Maps Get Map Tile API,
map copyright attribution
information can be obtained
from Azure Maps Get Map
Attribution API. Copyright
attribution information
should be displayed on the
map as per the Azure Maps
Product Terms .

mapLayer ml NA N/A NA

orientation dir NA NA NA Applies to Bing Maps


Birdseye map style, which
isn't supported in Azure
Maps.

uriScheme NA NA NA
Bing Maps Bing Maps Azure Required Azure Description
Request Request Maps in Azure Maps
Parameter Parameter Request Maps Data
Alias Parameter Type

zoomLevel zl zoom True integer For more information on X, Y


int32 coordinates, see Zoom levels
and tile grid.

For more information about the Azure Maps request parameters, see URI Parameters.

Request examples
Bing Maps Get Imagery Metadata API request:

HTTP

http://dev.virtualearth.net/REST/V1/Imagery/Metadata/road/37.770864,-122.467
217?zl=15&key={YourBingMapsKey}

Azure Maps Get Map Tile API request:

HTTP

https://atlas.microsoft.com/map/tile?api-version=2022-08-
01&tilesetId=microsoft.base.&zoom=15&x=5236&y=12665&tileSize=256&subscriptio
n-key={Your-Azure-Maps-Subscription-key}

Response fields
The following table lists the fields that can appear in the HTTP response when running
the Bing Maps Get Imagery Metadata API and the Azure Maps equivalent:

ノ Expand table

Bing Maps Response Azure Maps Description


Field Response Field

imageHeight (Json) Not supported Azure Maps Get Map Tile API provides the map tile
ImageWidth (XML) image directly in the HTML response (binary image
string) and offers 256 x 256 and 512 x 512 pixel tile
sizes.
Bing Maps Response Azure Maps Description
Field Response Field

imageUrl (Json) Not supported Azure Maps Get Map Tile API provides the map tile
ImageUrl (XML) image directly in the HTML response (binary image
string), as oppsed to an image URL.

imageUrlSubdomains Not supported Azure Maps Get Map Tile API provides the map tile
(Json) image directly in the HTML response (binary image
ImageUrlSubdomains string), as oppsed to an image URL.
(XML)

imageWidth (Json) Not supported Azure Maps Get Map Tile API provides the map tile
ImageWidth (XML) image directly in the HTML response (binary image
string) and offers 256 x 256 and 512 x 512 pixel tile
sizes.

vintageEnd (Json) Not supported Azure Maps Get Map Tile API provides map tile
VintageEnd (XML) vintage information in the response header (Data-
Capture-Date-Range1), rather than in the response
body.

vintageStart (Json) Not supported Azure Maps Get Map Tile API provides map tile
VintageStart (XML) vintage information in the response header (Data-
Capture-Date-Range1), rather than in the response
body.

zoomMax (Json) Not supported For information on zoom levels and maximum zoom
ZoonMax (XML) supported by map tile styles, see Zoom levels and tile
grid and TilesetID.

zoomMin (Json) Not supported For information on zoom levels and maximum zoom
ZoomMin (XML) supported by map tile styles, see Zoom levels and tile
grid and TilesetID.

1
When using Azure Maps API to obtain RGB satellite images, you can also retrieve
information about the acquisition date. The HTTP response includes a header called
Data-Capture-Date-Range, which provides a date range indicating when the image was
captured. For instance, it might appear as “7/31/2022-9/1/2023”. Keep in mind that
satellite imagery often spans a date range due to batch processing and the stitching
together of multiple images from different dates to create seamless maps. So, while a
single date isn’t always applicable, the date range gives you insight into when the image
data was collected.

For more information about the Azure Maps Get Map Tile API response fields, see
Response.
Response examples
The following JSON sample shows what is returned in the body of the HTTP response
when executing the Bing Maps Get Imagery Metadata request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri":
"https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights
reserved. This API cannot be accessed and the content and any results may
not be used, reproduced or transmitted in any manner without express written
permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type":
"ImageryMetadata:http://schemas.microsoft.com/search/local/ws/rest/v1",
"imageHeight": 256,
"imageUrl":
"http://ecn.t2.tiles.virtualearth.net/tiles/r023010203332102.jpeg?
g=14374&mkt={culture}&shading=hill",
"imageUrlSubdomains": null,
"imageWidth": 256,
"imageryProviders": null,
"vintageEnd": "02 Dec 2019 GMT",
"vintageStart": "02 Dec 2019 GMT",
"zoomMax": 15,
"zoomMin": 15
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "c0630758c8475d6f60d65af81b548c6f|MWH0032BEB|0.0.0.1"
}

The following JSON sample shows what is returned in the body of the HTTP response
when executing an Azure Maps Get Map Tile request:

Status code: 200

HTTP

Content-Type: application/vnd.mapbox-vector-tile
Response Body

JSON

"binary image string"

Transactions usage
Bing Maps Get Imagery Metadata API generates one billable transaction per API
request. Azure Maps Get Map Tile API generates one billable transaction for every 15
tiles. For more information on Azure Maps transactions, see Understanding Azure Maps
Transactions.

Additional information
For more Azure Maps Render APIs see:

Get Map Attribution: Use to get map copyright attribution information for tiles.
Get Map Static Image: Use to render a user-defined, rectangular image containing
a map section.

Support
Microsoft Q&A Forum
Migrate Bing Maps Get a Static Map API
Article • 06/27/2024

This article explains how to migrate the Bing Maps Get a Static Map API to the Azure Maps Get Map
Static Image API. Azure Maps Get Map Static Image API renders a user-defined, rectangular Road,
Satellite/Aerial, or Traffic style map image.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Get a Static Map API offers Road, Satellite/Aerial, Traffic, Streetside, Birds Eye and
Ordnance Survey maps styles. Azure Maps Get Map Static Image API offers the same styles
except for Streetside, Birds Eye and Ordnance Survey.
Bing Maps Get a Static Map API supports getting a static map using coordinates, street address
or place name as the location input. Azure Maps Get Map Static Image API supports only
coordinates as the location input.
Bing Maps Get a Static Map API supports getting a static map of a driving, walking, or transit
route natively. Azure Maps Get Map Static Image API doesn't provide route map functionality
natively.
Bing Maps Get a Static Map API provides static maps in PNG, JPEG and GIF image formats.
Azure Maps Get Map Static Image API provides static maps in PNG and JPEG image formats.
Bing Maps Get a Static Map API supports XML and JSON response formats. Azure Maps Get
Map Static Image API supports only JSON response format.
Bing Maps Get a Static Map API supports HTTP GET and POST requests. Azure Maps Get Map
Static Image API supports HTTP GET requests.
Bing Maps Get a Static Map API uses coordinates in the latitude & longitude format. Azure
Maps Get Map Static Image API uses coordinates in the longitude & latitude format, as defined
in GeoJSON .
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a
geographic scope, which allows you to limit data residency to the European (EU) or United
States (US) geographic areas (geos). All requests (including input data) are processed
exclusively in the specified geographic area. For more information, see Azure Maps service
geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple ways
to authenticate your API calls, such as a subscription key, Microsoft Entra ID, and Shared Access
Signature (SAS) Token. For more information on security and authentication in Azure Maps, See
Authentication with Azure Maps and the Security section in the Azure Maps Get Map Static Image
documentation.

Request parameters
The following table lists the Bing Maps Get a Static Map request parameters and the Azure Maps
equivalent:

ノ Expand table

Bing Maps request Parameter Azure Required Azure Maps Description


parameter Alias Maps in Azure data type
request Maps
parameter

centerPoint center True (if number[] Bing Maps Get a Static Map API
not using requires coordinates be in latitude
bbox) & longitude format, whereas Azure
Maps Get Map Static Image API
requires longitude & latitude
format, as defined in the
GeoJSON format.

longitude,latitude range from


[-90, 90]​. Note: Either center or
bbox are required parameters.
They're mutually exclusive.

culture c language FALSE String In Azure Maps Get Map Static


Image API, this is the language in
which search results should be
returned and is specified in the
Azure Maps request header. For
more information, see Supported
Languages.

declutterPins dcl Not Not Not


supported supported supported

dpi dir Not Not Not


supported supported supported

drawCurve dv Path FALSE String

fieldOfView fov Not Not Not In Bing Maps, this parameter is used
supported supported supported for imagerySet Birdseye,
BirdseyeWithLabels , BirdseyeV2 ,
BirdseyeV2WithLabels ,
OrdnanceSurvey , Streetside . Azure
Maps doesn't support these maps
styles.
Bing Maps request Parameter Azure Required Azure Maps Description
parameter Alias Maps in Azure data type
request Maps
parameter

format fmt format TRUE String Bing Maps Get a Static Map API
provides static maps in PNG, JPEG
and GIF image formats. Azure Maps
Get Map Static Image API provides
static maps in PNG and JPEG image
formats.

heading Not Not Not In Bing Maps, this parameter is used


supported supported supported for imagerySet Birdseye,
BirdseyeWithLabels, BirdseyeV2,
BirdseyeV2WithLabels,
OrdnanceSurvey, Streetside. Azure
Maps doesn't support these maps
styles.

highlightEntity he Not Not Not In Bing Maps Get a Static Map API,
supported supported supported this parameter is used to get a
polygon of the location input
(entity) displayed on the map
natively. Azure Maps Get a Map
Static Image API doesn't support
this feature, however, you can get a
polygon of a location (locality) from
the Azure Maps Get Polygon API
and then display that on the static
map.

imagerySet tilesetID TRUE TilesetId

mapArea ma bbox True (if number[] A bounding box, defined by two


not using longitudes and two latitudes,
center) represents the four sides of a
rectangular area on the Earth, in the
format
of minLon, minLat, maxLon, maxLat .

Note: Either center or bbox are


required parameters. They're
mutually exclusive. bbox shouldn’t
be used with height or width .

mapLayer ml trafficLayer FALSE TrafficTilesetId Optional. If TrafficLayer is


provided, it returns map image with
corresponding traffic layer. For
more information, see tilesetId.

mapSize ms height TRUE integer int32

width

mapMetadata mmd Not Not Not


Bing Maps request Parameter Azure Required Azure Maps Description
parameter Alias Maps in Azure data type
request Maps
parameter

supported supported supported

orientation dir Not Not Not In Bing Maps Get a Static Map API,
supported supported supported this parameter is used for
'imagerySet' Birdseye,
BirdseyeWithLabels, BirdseyeV2,
BirdseyeV2WithLabels,
OrdnanceSurvey, Streetside. Azure
Maps doesn't support these maps
styles

pitch Not Not Not In Bing Maps Get a Static Map API,
supported supported supported this parameter is used for
'imagerySet' Birdseye,
BirdseyeWithLabels, BirdseyeV2,
BirdseyeV2WithLabels,
OrdnanceSurvey, Streetside. Azure
Maps doesn't support these maps
styles

pushpin pp pins FALSE String In Bing Maps Get a Static Map API,
an HTTP GET request is limited to
18 pins and an HTTP POST request
is limited to 100 pins per static map.
Azure Maps Get Map Static Image
API HTTP GET request doesn’t have
a limit on the number of pins per
static map. However, the number of
pins supported on the static map is
based on the maximum number of
characters supported in the HTTP
GET request. See Azure Maps Get
Map Static Image API ‘pins’
parameter in URI Parameters for
more details on pushpin support.

query Not Not Not Azure Maps Get Map Static Image
supported supported supported API supports only coordinates as
the location input, not street
address or place name. Use the
Azure Maps Get Geocoding API to
convert a street address or place
name to coordinates.

Route Parameters: None Not Not Not Azure Maps Get Maps Static Image
avoid supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, use the
Azure Maps Get Route Directions or
Post Route Directions API to get
route path coordinates of a given
route and then use the Azure Maps
Bing Maps request Parameter Azure Required Azure Maps Description
parameter Alias Maps in Azure data type
request Maps
parameter

Get Map Static Image API


drawCurve feature to overlay the
route path coordinates on the static
map.

Route Parameters: dbft Not Not Not Azure Maps Get Maps Static Image
distanceBeforeFirstTurn supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
a given route and then use the
Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

Route Parameters: dt Not Not Not Azure Maps Get Maps Static Image
dateTime supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
a given route and then use the
Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

Route Parameters: maxSolns Not Not Not Azure Maps Get Maps Static Image
maxSolutions supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
a given route and then use the
Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

Route Parameters: optmz Not Not Not Azure Maps Get Maps Static Image
optimize supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
Bing Maps request Parameter Azure Required Azure Maps Description
parameter Alias Maps in Azure data type
request Maps
parameter

a given route and then use the


Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

Route Parameters: tt Not Not Not Azure Maps Get Maps Static Image
timeType supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
a given route and then use the
Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

Route Parameters: None Not Not Not Azure Maps Get Maps Static Image
travelMode supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
a given route and then use the
Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

Route Parameters: wp.n Not Not Not Azure Maps Get Maps Static Image
waypoint.n supported supported supported API doesn’t provide route map
functionality natively. To get a static
map with a route path on it, you can
use the Azure Maps Get Route
Directions or Post Route Directions
API to get route path coordinates of
a given route and then use the
Azure Maps Get Map Static Image
API drawCurve feature to overlay
the route path coordinates on the
static map.

style st Not Not Not


supported supported supported

userRegion ur view FALSE String A string that represents an ISO


3166-1 Alpha-2 region/country
code . This alters geopolitical
Bing Maps request Parameter Azure Required Azure Maps Description
parameter Alias Maps in Azure data type
request Maps
parameter

disputed borders and labels to align


with the specified user region. By
default, the View parameter is set to
“Auto” even if not defined in the
request. For more information, see
Supported Views.

zoomLevel Zoom FALSE String Desired zoom level of the map.


Zoom value must be in the range:
0-20 (inclusive). Default value is 12.

highlightEntity he Not Not Not In Bing Maps Get a Static Map API,
supported supported supported this parameter is used to get a
polygon of the location input
(entity) displayed on the map
natively. Azure Maps Get a Map
Static Image API doesn't support
this feature, however, you can get a
polygon of a location (locality) from
the Azure Maps Get Polygon API
and then display that on the static
map.

For more information about the Azure Maps Get Map Static Image API request parameters, see URI
Parameters.

Request examples
Bing Maps Get a Static Map API sample GET request:

HTTP

https://dev.virtualearth.net/REST/v1/Imagery/Map/Road/51.504810,-0.113629/15?
mapSize=500,500&pp=51.504810,-0.113629;45&key={BingMapsKey}

Azure Maps Get Map Static Image API sample GET request:

HTTP

https://atlas.microsoft.com/map/static?api-version=2024-04-
01&tilesetId=microsoft.base.road&zoom=15&center=-0.113629,51.504810&subscription-key=
{Your-Azure-Maps-Subscription-key}

Response examples
The following screenshot shows what is returned in the body of the HTTP response when executing
the Bing Maps Get a Static Map request:

The following JSON sample shows what is returned in the body of the HTTP response when
executing an Azure Maps Get Map Static Image request:

Transactions usage
Like Bing Maps Get a Static Map API, Azure Maps Get Map Static Image API logs one billable
transaction per request. For more information on Azure Maps transactions, see Understanding Azure
Maps Transactions.

Additional information
Render custom data on a raster map

Support

Microsoft Q&A Forum

Feedback
Was this page helpful?  Yes  No

Provide product feedback


Migrate Bing Maps Find a Location by Address
API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Find a Location by Address API to the Azure Maps Get
Geocoding API. The Azure Maps Get Geocoding API is used to get longitude and latitude coordinates of a
street address a place or landmark. Azure Maps Get Geocoding API supports geocoding input in an
unstructured or structured format. This article covers scenarios where your geocoding input, such as street
address, is in structured format - similar to what Bing Maps Find a Location by Address API supports. For
information on how to migrate Bing Maps scenarios where the geocoding input is not structured to get
longitude and latitude coordinates of a street address, a place or landmark, see Migrate Bing Maps Find a
Location by Query API.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Find a Location by Address API only supports geocoding input in structured format, whereas
Azure Maps Get Geocoding API supports geocoding input in an unstructured (query=) or structured
(addressLine=) format. For geocoding landmark names, use Azure Maps Get Geocoding API using
unstructured input format.
Bing Maps Find a Location by Address API returns coordinates in latitude/longitude format, while Azure
Maps Get Geocoding API returns coordinates in longitude/latitude format, as defined by the
GeoJSON format.
Bing Maps Find a Location by Address API supports XML and JSON response format. Azure Maps Get
Geocoding API supports GeoJSON.
Unlike Bing Maps Find a Location by Address API, Azure Maps Get Geocoding API has a view input
parameter, which is a string that represents an ISO 3166-1 Alpha-2 region/country code . The view
input parameter alters geopolitical disputed borders and labels to align with the specified user region.
For more information, see URI Parameters.
Unlike Bing Maps Find a Location by Address API, Azure Maps Get Geocoding API doesn’t currently
support address geocoding for China, Japan, or South Korea.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a geographic
scope, allowing limits to data residency to the European (EU) or United States (US) geographic areas
(geos). All requests (including input data) are processed exclusively in the specified geographic area. For
more information, see geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple ways to
authenticate your API calls, such as a subscription key, Microsoft Entra ID, and Shared Access Signature (SAS)
Token. For more information on security and authentication in Azure Maps, See Authentication with Azure
Maps.

Request parameters
The following table lists the Bing Maps Find a Location by Address request parameters and the Azure Maps
equivalent:

ノ Expand table

Bing Maps Request Bing Azure Maps Required Azure Description


Parameter Maps Request in Azure Maps
Request Parameter Maps Data
Parameter Type
Alias

Bing Maps Request Bing Maps Azure Maps Required Azure Note
Parameter Name Request Request in Azure Maps Data
Parameter Parameter Maps Type
Alias Name

addressLine addressLine False string In Azure Maps Get Geocoding API, a street
address, or street address with locality and
adminDistrict , is supported input for
addressLine .

adminDistrict adminDistrict False string

countryRegion countryRegion False string

locality locality False string

postalCode postalCode False string

culture c Request False string As specified in the Azure Maps request


Header: header, culture defines the language used in
Accept- search results when using the Azure Maps Get
Language Geocoding API. For more information, see
Supported Languages.

include incl Not needed Not Not In Bing Maps Find a Location by Address API,
needed needed the ‘include’ input parameter is required in
order to get a two-letter ISO country code for
the location result in the response
(include=ciso2). In Azure Maps Get Geocoding
API, the two-letter ISO country code is
returned by default.

includeNeighborhood inclnb Not needed Not Not In Azure Maps Get Geocoding API,
needed needed neighborhood info is returned in the
response by default, when available.

maxResults maxRes top False Integer In Azure Maps Get Geocoding API, the default
(int32) number of responses returned is 5. The
minimum is 1 and the maximum is 20.

strictMatch sm Not Not Not


supported supported supported
Bing Maps Request Bing Azure Maps Required Azure Description
Parameter Maps Request in Azure Maps
Request Parameter Maps Data
Parameter Type
Alias

userIp uip Not Not Not


supported supported supported

userLocation ul coordinates False number[] In Azure Maps Get Geocoding API,


coordinates on the earth specified as in
longitude and latitude format
(longitude,latitude). When you specify this
parameter, the user’s location is considered,
and the results returned are more relevant to
the user.

userMapView umv bbox False number[] A rectangular area on the earth defined as a
bounding box object. The sides of the
rectangles are defined by longitude and
latitude values
( longitude1,latitude1,longitude2,latitude2 ).
Use the following syntax to specify a
bounding box:

West Longitude, South Latitude, East


Longitude, North Latitude

When you specify this parameter, the


geographical area is taken into account when
computing the results of a location query.

userRegion ur view False string A string that represents an ISO 3166-1 Alpha-
2 region/country code that alters
geopolitical disputed borders and labels to
align with the specified user region. By
default, the View parameter is set to Auto
even if not defined in the request. For more
information on available views, see Supported
Views.

For more information about the Azure Maps Get Geocoding API request parameters, see URI Parameters.

Request examples
Bing Maps Find a Location by Address API POST request:

HTTP

http://dev.virtualearth.net/REST/v1/Locations/US/WA/Redmond/15127 NE 24th Street?&key=


{BingMapsKey}

Azure Maps Get Geocoding API POST request:

HTTP

https://atlas.microsoft.com/geocode?api-version=2023-06-
01&adminDistrict=WA&locality=Redmond&addressLine=15127 NE 24th Street&subscription-key={Your-
Azure-Maps-Subscription-key}

Response fields
The following table lists the fields that can appear in the HTTP response when running the Bing Maps Find a
Location by Address request and the Azure Maps equivalent:

ノ Expand table

Bing Maps Field Azure Maps Field Description

address: addressLine address: addressLine


(JSON)

Address: AddressLine
(XML)

address: adminDistrict address: adminDistricts


(JSON)

Address: AdminDistrict
(XML)

address: adminDistrict2 address: adminDistricts


(JSON)

Address: AdminDistrict2
(XML)

address: countryRegion address: countryRegion


(JSON)

Address: CountryRegion
(XML)

address: address: countryRegion -


countryRegionIso2 iso
(JSON)

Address:
CountryRegionIso2
(XML)

address: neighborhood address: neighborhood


(JSON)

Address: Neighborhood
(XML)

address: address:
formattedAddress formattedAddress
(JSON)

Address:
FormattedAddress (XML)

address: locality (JSON) address: locality


Bing Maps Field Azure Maps Field Description

Address: Locality (XML)

address: postalCode address: postalCode


(JSON)

Address: PostalCode
(XML)

address: Intersection – address: intersection -


baseStreet (JSON) baseStreet

Address: Intersection –
BaseStreet (XML)

address: Intersection – address: intersection -


secondaryStreet1 (JSON) secondaryStreet1

address: Intersection – address: intersection -


secondaryStreet2 (JSON) secondaryStreet2

Address: Intersection –
SecondaryStreet2 (XML)

address: Intersection – address: intersection -


intersectionType (JSON) intersectionType

Address: Intersection –
IntersectionType (XML)

address: Intersection – address: intersection -


displayName (JSON) displayName

Address: Intersection –
DisplayName (XML)

bbox (JSON) features: bbox In Bing Maps Find a Location by Address API, the coordinates in
the response are in latitude/longitude format. The coordinates in
BoundingBox (XML) the response of the Azure Maps Get Geocoding API are in the
longitude/latitude format (since GeoJSON format is used).

calculationMethod properties:
(JSON) geocodePoints -
calculationMethod
CalculationMethod
(XML)

confidence (JSON) properties: confidence

Confidence (XML)

entityType (JSON) properties: type

EntityType (XML)

geocodePoints (JSON) properties:


geocodePoints -
GeocodePoint (XML) coordinates
Bing Maps Field Azure Maps Field Description

matchCodes (JSON) properties: matchCodes

MatchCode (XML)

name (JSON) Not supported formattedAddress is the Azure Maps equivalent.

Name (XML)

point (JSON) features: coordinates In Bing Maps Find a Location by Address API, the coordinates in
the response are in latitude/longitude format. The coordinates in
Point (XML) the response of the Azure Maps Get Geocoding API are in the
longitude/latitude format (since GeoJSON format is used).

queryParse (JSON) Not supported

QueryParse (XML)

usageTypes (JSON) properties:


geocodePoints:
usageType (XML) usageTypes

For more information about the Azure Maps Get Geocoding API response fields, see Definitions.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response when executing the
Bing Maps Find a Location by Address request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri": "https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights reserved. This API
cannot be accessed and the content and any results may not be used, reproduced or transmitted
in any manner without express written permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type": "Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox": [
47.62649628242932,
-122.14631082421619,
47.634221717570675,
-122.1310271757838
],
"name": "15127 NE 24th St, Redmond, WA 98052",
"point": {
"type": "Point",
"coordinates": [
47.630359,
-122.138669
]
},
"address": {
"addressLine": "15127 NE 24th St",
"adminDistrict": "WA",
"adminDistrict2": "King County",
"countryRegion": "United States",
"formattedAddress": "15127 NE 24th St, Redmond, WA 98052",
"locality": "Redmond",
"postalCode": "98052"
},
"confidence": "High",
"entityType": "Address",
"geocodePoints": [
{
"type": "Point",
"coordinates": [
47.630359,
-122.138669
],
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
]
},
{
"type": "Point",
"coordinates": [
47.630563,
-122.1387383
],
"calculationMethod": "Rooftop",
"usageTypes": [
"Route"
]
}
],
"matchCodes": [
"Good"
]
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "e0a7cb31a835ffbcc7e2b8f6b1a0b4e0|MWH0032BE3|0.0.0.1|Ref A:
9BC4F0B708B04F2EA6D52CB3461458A6 Ref B: CO1EDGE1411 Ref C: 2024-04-23T23:44:47Z"

The following JSON sample shows what is returned in the body of the HTTP response when executing an
Azure Maps Get Geocoding request:

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.138679,
47.630356
]
},
"bbox": [
-122.14632082377759,
47.62649328242932,
-122.1310371762224,
47.634218717570675
],
"properties": {
"type": "Address",
"confidence": "High",
"matchCodes": [
"Good"
],
"geocodePoints": [
{
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
],
"geometry": {
"type": "Point",
"coordinates": [
-122.138679,
47.630356
]
}
},
{
"calculationMethod": "Rooftop",
"usageTypes": [
"Route"
],
"geometry": {
"type": "Point",
"coordinates": [
-122.138685,
47.6305637
]
}
}
],
"address": {
"addressLine": "15127 NE 24th St",
"postalCode": "98052",
"locality": "Redmond",
"formattedAddress": "15127 NE 24th St, Redmond, WA 98052",
"countryRegion": {
"name": "United States",
"ISO": "US"
},
"adminDistricts": [
{
"shortName": "WA"
},
{
"shortName": "King County"
}
]
}
}
}
]
}

Transactions usage
Like Bing Maps Find a Location by Address API, Azure Maps Get Geocoding API logs one billable transaction
per request. For more information on Azure Maps transactions, see Understanding Azure Maps Transactions.

Additional information
Get Geocoding Batch: Use to send a batch of queries to the Get Geocoding API in a single synchronous
request.

Support

Microsoft Q&A Forum


Migrate Bing Maps Find a Location by
Point API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Find a Location by Point API to the
Azure Maps Get Reverse Geocoding API. The Azure Maps Get Reverse Geocoding API is
used to translate longitude and latitude coordinates into a human understandable street
address.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Find a Location by Point API supports XML and JSON response formats.
Azure Maps Get Reverse Geocoding API supports the GeoJSON response format.
Bing Maps Find a Location by Point API uses coordinates in the latitude/longitude
format. Azure Maps Get Reverse Geocoding API uses coordinates in the
longitude/latitude format, as defined by GeoJSON .
Unlike Bing Maps Find a Location by Point API, Azure Maps Get Reverse Geocoding
API doesn’t currently support address or street level data for China, Japan or South
Korea.
Unlike Bing Maps Find a Location by Point API, Azure Maps Get Reverse Geocoding
API has a view input parameter, which is a string that represents an ISO 3166-1
Alpha-2 region/country code . The view input parameter will alter geopolitical
disputed borders and labels to align with the specified user region. For more
information, see URI Parameters.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports
specifying a geographic scope, which allows you to limit data residency to the
European (EU) or United States (US) geographic areas (geos). All requests
(including input data) are processed exclusively in the specified geographic area.
For more information, see Azure Maps service geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports
multiple ways to authenticate your API calls, such as a subscription key, Microsoft Entra
ID, and Shared Access Signature (SAS) Token. For more information on security and
authentication in Azure Maps, See Authentication with Azure Maps.

Request parameters
The following table lists the Bing Maps Find a Location by Point request parameters and
the Azure Maps equivalent:

ノ Expand table

Bing Maps Request Bing Azure Required Azure Description


Parameter Maps Maps in Azure Maps
Request Request Maps Data
Parameter Parameter Type
Alias

culture c Request False string In Azure Maps Get


Header: Reverse Geocoding
Accept- API, this is the
Language language in which
search results
should be
returned. This is
specified in the
Azure Maps
request header.
Please refer
to Supported
Languages for
details.

include incl Not Not Not In Bing Maps Find


needed needed needed a Location by
Point, the ‘include’
input parameter is
required to get a
two-letter ISO
country code for
the location result
in the response. In
Azure Maps Get
Reverse Geocoding
API, the two-letter
ISO country code is
Bing Maps Request Bing Azure Required Azure Description
Parameter Maps Maps in Azure Maps
Request Request Maps Data
Parameter Parameter Type
Alias

returned by
default.

includeEntityTypes resultTypes False query

includeNeighborhood inclnb Not Not Not In Azure Maps Get


needed needed needed Reverse Geocoding
API, neighborhood
info is returned in
the response by
default, when
available.

point coordinates True number[] In Bing Maps Find


a Location by Point
API, the
coordinates in the
request and the
response are in
latitude/longitude
format, whereas
Azure Maps Get
Reverse Geocoding
API requires the
coordinates in the
request and the
coordinates in the
response use
longitude/latitude
format, as defined
by GeoJSON .

userRegion ur view False string A string that


represents an ISO
3166-1 Alpha-2
region/country
code . This will
alter geopolitical
disputed borders
and labels to align
with the specified
user region. By
default, the View
parameter is set to
Bing Maps Request Bing Azure Required Azure Description
Parameter Maps Maps in Azure Maps
Request Request Maps Data
Parameter Parameter Type
Alias

“Auto” even if you


haven’t defined it
in the request.

Please refer
to Supported
Views for details
and to see the
available Views.

verboseplacenames vbpn Not Not Not Azure Maps Get


supported supported supported Reverse Geocoding
API only supports
returning
[adminDistricts]
short name (FL
instead of Florida).

For more information about the Azure Maps Get Reverse Geocoding API request
parameters, see URI Parameters.

Request examples
Bing Maps Find a Location by Point API request:

HTTP

https://dev.virtualearth.net/REST/v1/Locations/48.830345,2.338166&key=
{BingMapsKey}

Azure Maps Get Reverse Geocoding API request:

HTTP

http://atlas.microsoft.com/reverseGeocode?api-version=2023-06-
01&coordinates=2.338166,48.830345&subscription-key={Your-Azure-Maps-
Subscription-key}

Response fields
The following table lists the fields that can appear in the HTTP response when running
the Bing Maps Find a Location by Point request and the Azure Maps equivalent:

ノ Expand table

Bing Maps Response Azure Maps Description


Response

address: addressLine address: addressLine


(JSON)
Address: AddressLine
(XML)

address: adminDistrict address:


(JSON) adminDistricts
Address: AdminDistrict
(XML)

address: address:
adminDistrict2 (JSON) adminDistricts
Address:
AdminDistrict2 (XML)

address: address:
countryRegion (JSON) countryRegion
Address:
CountryRegion (XML)

address: address:
countryRegionIso2 countryRegion - iso
(JSON)
Address:
CountryRegionIso2
(XML)

address: address:
neighborhood (JSON) neighborhood
Address:
Neighborhood (XML)

address: address:
formattedAddress formattedAddress
(JSON)
Address:
FormattedAddress
(XML)

address: locality address: locality


(JSON)
Bing Maps Response Azure Maps Description
Response

Address: Locality
(XML)

address: postalCode address: postalCode


(JSON)
Address: PostalCode
(XML)

address: Intersection – address: intersection -


baseStreet (JSON) baseStreet
Address: Intersection –
BaseStreet (XML)

address: Intersection – address: intersection -


secondaryStreet1 secondaryStreet1
(JSON)
Address: Intersection –
SecondaryStreet1
(XML)

address: Intersection – address: intersection -


secondaryStreet2 secondaryStreet2
(JSON)
Address: Intersection –
SecondaryStreet2
(XML)

address: Intersection – address: intersection -


intersectionType intersectionType
(JSON)
Address: Intersection –
IntersectionType
(XML)

address: Intersection – address: intersection -


displayName (JSON) displayName
Address: Intersection –
DisplayName (XML)

bbox (JSON) features: bbox In Bing Maps Find a Location by Point API, the
BoundingBox (XML) coordinates in the response are in
latitude/longitude format. In Azure Maps Get
Reverse Geocoding API the coordinates in the
response use longitude/latitude, as defined by
GeoJSON .

calculationMethod properties:
(JSON) geocodePoints -
Bing Maps Response Azure Maps Description
Response

CalculationMethod calculationMethod
(XML)

confidence (JSON) properties: confidence


Confidence (XML)

entityType (JSON) properties: type


EntityType (XML)

geocodePoints (JSON) properties:


GeocodePoint (XML) geocodePoints -
coordinates

matchCodes (JSON) properties:


MatchCode (XML) matchCodes

name (JSON) Not supported Azure Maps formattedAddress provides a


Name (XML) similar value to Bing Maps name

point (JSON) features: coordinates In Bing Maps Find a Location by Point API, the
Point (XML) coordinates in the response are in
latitude/longitude format. In Azure Maps Get
Reverse Geocoding API the coordinates in the
response use longitude/latitude format, as
defined by GeoJSON .

usageTypes (JSON) properties:


usageType (XML) geocodePoints:
usageTypes

For more information about the Azure Maps Get Reverse Geocoding API response fields,
see Definitions.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response
when executing the Bing Maps Find a Location by Point request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri":
"https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights
reserved. This API cannot be accessed and the content and any results may
not be used, reproduced or transmitted in any manner without express written
permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type":
"Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox": [
48.826534682429326,
2.330334564829834,
48.83426011757068,
2.345980835170166
],
"name": "30 Rue Cabanis, 75014 Paris, France",
"point": {
"type": "Point",
"coordinates": [
48.8303974,
2.3381577
]
},
"address": {
"addressLine": "30 Rue Cabanis",
"adminDistrict": "Île-de-France",
"adminDistrict2": "Paris",
"countryRegion": "France",
"formattedAddress": "30 Rue Cabanis, 75014 Paris,
France",
"intersection": {
"baseStreet": "Rue Cabanis",
"secondaryStreet1": "Villa de Lourcine",
"intersectionType": "Near",
"displayName": "Rue Cabanis and Villa de
Lourcine"
},
"locality": "Paris",
"neighborhood": "14th Arrondissement",
"postalCode": "75014"
},
"confidence": "High",
"entityType": "Address",
"geocodePoints": [
{
"type": "Point",
"coordinates": [
48.8303974,
2.3381577
],
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
]
}
],
"matchCodes": [
"Good"
]
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "c525b02f7f1e9e4ee3d7b81cce266671"

The following JSON sample shows what is returned in the body of the HTTP response
when executing an Azure Maps Get Reverse Geocoding request:

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
2.3381577,
48.8303974
]
},
"properties": {
"geocodePoints": [
{
"geometry": {
"type": "Point",
"coordinates": [
2.3381577,
48.8303974
]
},
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
]
}
],
"address": {
"addressLine": "30 Rue Cabanis",
"adminDistricts": [
{
"shortName": "Île-de-France"
},
{
"shortName": "Paris"
}
],
"countryRegion": {
"name": "France",
"iso": "FR"
},
"intersection": {
"baseStreet": "Rue Cabanis",
"displayName": "Rue Cabanis and Villa de Lourcine",
"intersectionType": "Near",
"secondaryStreet1": "Villa de Lourcine",
"secondaryStreet2": null
},
"locality": "Paris",
"neighborhood": "14th Arrondissement",
"postalCode": "75014",
"formattedAddress": "30 Rue Cabanis, 75014 Paris,
France"
},
"confidence": "High",
"matchCodes": [
"Good"
],
"type": "Address"
},
"bbox": [
2.330334564829834,
48.826534682429326,
2.345980835170166,
48.83426011757068
]
}
]
}

Transactions usage
Like Bing Maps Find a Location by Point API, Azure Maps Get Reverse Geocoding API
logs one billable transaction per request. For more information on Azure Maps
transactions, see Understanding Azure Maps Transactions.

Additional information
Azure Maps Get Reverse Geocoding Batch API: Use to send a batch of queries to
the Azure Maps Get Reverse Geocoding API in a single request.

Support

Microsoft Q&A Forum


Migrate Bing Maps Find a Location by Query
API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Find a Location by Query API to the Azure Maps Get
Geocoding API. The Azure Maps Get Geocoding API is used to get longitude and latitude coordinates of
a street address, a place or landmark. Azure Maps Get Geocoding API supports geocoding input in an
unstructured or structured format. This migration documentation is for scenarios where your geocoding
input, such as street address, locality, postal code, or landmark name, is in an unstructured format
(query=) - similar to what Bing Maps Find a Location by Query API supports. For information on how to
migrate Bing Maps scenarios where the geocoding input is structured to find a location by address, see
Migrate Bing Maps Find a Location by Address API.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Find a Location by Query API only supports geocoding input in unstructured format,
whereas Azure Maps Get Geocoding API supports geocoding input in an unstructured (query=) or
structured (addressLine=) format. For geocoding landmark names, use Azure Maps Get Geocoding
API using unstructured input format.
Bing Maps Find a Location by Query API returns coordinates in latitude/longitude format, while
Azure Maps Get Geocoding API returns coordinates in longitude/latitude format, as defined by the
GeoJSON format.
Bing Maps Find a Location by Query API supports XML and JSON response format. Azure Maps
Get Geocoding API supports GeoJSON.
Unlike Bing Maps Find a Location by Query API, Azure Maps Get Geocoding API has a view input
parameter, which is a string that represents an ISO 3166-1 Alpha-2 region/country code . The
view input parameter alters geopolitical disputed borders and labels to align with the specified

user region. For more information, see URI Parameters.


Unlike Bing Maps Find a Location by Query API, Azure Maps Get Geocoding API doesn’t currently
support address geocoding for China, Japan, or South Korea.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a
geographic scope, allowing limits to data residency to the European (EU) or United States (US)
geographic areas (geos). All requests (including input data) are processed exclusively in the
specified geographic area. For more information, see geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple ways to
authenticate your API calls, such as a subscription key, Microsoft Entra ID, and Shared Access Signature
(SAS) Token. For more information on security and authentication in Azure Maps, See Authentication
with Azure Maps.

Request parameters
The following table lists the Bing Maps Find a Location by Query request parameters and the Azure
Maps equivalent:

ノ Expand table

Bing Maps Request Bing Azure Required Azure Description


Parameter Maps Maps in Azure Maps
Request Request Maps Data
Parameter Parameter Type
Alias

culture c Request False string As specified in the Azure Maps request


Header: header, culture defines the language
Accept- used in search results when using the
Language Azure Maps Get Geocoding API. For more
information, see Supported Languages.

include incl Not Not Not In Bing Maps Find a Location by Query
needed needed needed API, the include input parameter is
required to get a two-letter ISO country
code for the location result in the
response (include=ciso2) and to specify
that the response shows how the query
string was parsed into address values
(include=queryParse). In Azure Maps Get
Geocoding API, the two-letter ISO country
code is returned by default and doesn’t
support a queryParse equivalent.

Not Not Not


supported supported supported

includeNeighborhood inclnb Not Not Not In Azure Maps Get Geocoding API,
needed needed needed neighborhood info is returned in the
response by default, when available.

maxResults maxRes top False Integer In Azure Maps Get Geocoding API, the
(int32) default number of responses returned is 5.
The minimum is 1 and the maximum is
20.

query q query True string

userIp uip Not Not Not


supported supported supported

userLocation ul coordinates False number[] In Azure Maps Get Geocoding API,


coordinates on the earth specified as in
longitude and latitude format
Bing Maps Request Bing Azure Required Azure Description
Parameter Maps Maps in Azure Maps
Request Request Maps Data
Parameter Parameter Type
Alias

(longitude,latitude). When you specify this


parameter, the user’s location is taken into
account, and the results returned are more
relevant to the user.

userMapView umv bbox False number[] A rectangular area on the earth defined as
a bounding box object. The sides of the
rectangles are defined by longitude and
latitude values
(longitude1,latitude1,longitude2,latitude2).
Use the following syntax to specify a
bounding box:

West Longitude, South Latitude, East


Longitude, North Latitude

When you specify this parameter, the


geographical area is taken into account
when computing the results of a location
query.

userRegion ur view False string A string that represents an ISO 3166-1


Alpha-2 region/country code . This alters
geopolitical disputed borders and labels
to align with the specified user region. By
default, the View parameter is set to Auto
even if not defined in the request.

For more information on available views,


see Supported Views.

For more information about the Azure Maps Get Geocoding API request parameters, see URI
Parameters.

Request examples
Bing Maps Find a Location by Query API POST request:

HTTP

http://dev.virtualearth.net/REST/v1/Locations/15127 NE 24th Street Redmond WA&key=


{BingMapsKey}

Azure Maps Get Geocoding API POST request:

HTTP

https://atlas.microsoft.com/geocode?api-version=2023-06-01&query=15127 NE 24th Street


Redmond WA&subscription-key={Your-Azure-Maps-Subscription-key}

Response fields
The following table lists the fields that can appear in the HTTP response when running the Bing Maps
Find a Location by Query request and the Azure Maps equivalent:

ノ Expand table

Bing Maps Field Azure Maps Field Description

address: addressLine address: addressLine


(JSON)

Address: AddressLine
(XML)

address: adminDistrict address: adminDistricts


(JSON)

Address: AdminDistrict
(XML)

address: adminDistrict2 address: adminDistricts


(JSON)

Address: AdminDistrict2
(XML)

address: countryRegion address: countryRegion


(JSON)

Address: CountryRegion
(XML)

address: address: countryRegion


countryRegionIso2 - iso
(JSON)

Address:
CountryRegionIso2
(XML)

address: neighborhood address: neighborhood


(JSON)

Address: Neighborhood
(XML)

address: address:
formattedAddress formattedAddress
(JSON)

Address:
Bing Maps Field Azure Maps Field Description

FormattedAddress
(XML)

address: locality (JSON) address: locality

Address: Locality (XML)

address: postalCode address: postalCode


(JSON)

Address: PostalCode
(XML)

address: Intersection – address: intersection -


baseStreet (JSON) baseStreet

Address: Intersection –
BaseStreet (XML)

address: Intersection – address: intersection -


secondaryStreet1 secondaryStreet1
(JSON)

address: Intersection – address: intersection -


secondaryStreet2 secondaryStreet2
(JSON)

Address: Intersection –
SecondaryStreet2
(XML)

address: Intersection – address: intersection -


intersectionType (JSON) intersectionType

Address: Intersection –
IntersectionType (XML)

address: Intersection – address: intersection -


displayName (JSON) displayName

Address: Intersection –
DisplayName (XML)

bbox (JSON) features: bbox In Bing Maps Find a Location by Query API, the coordinates
in the response are in latitude/longitude format. The
BoundingBox (XML) coordinates in the response of the Azure Maps Get
Geocoding API are in the longitude/latitude format (since
GeoJSON format is used).

calculationMethod properties:
(JSON) geocodePoints -
calculationMethod
CalculationMethod
(XML)
Bing Maps Field Azure Maps Field Description

confidence (JSON) properties: confidence

Confidence (XML)

entityType (JSON) properties: type

EntityType (XML)

geocodePoints (JSON) properties:


geocodePoints -
GeocodePoint (XML) coordinates

matchCodes (JSON) properties: matchCodes

MatchCode (XML)

name (JSON) Not supported formattedAddress is the Azure Maps equivalent.

Name (XML)

point (JSON) features: coordinates In Bing Maps Find a Location by Query API, the coordinates
in the response are in latitude/longitude format. The
Point (XML) coordinates in the response of the Azure Maps Get
Geocoding API are in the longitude/latitude format (since
GeoJSON format is used).

queryParse (JSON) Not supported

QueryParse (XML)

usageTypes (JSON) properties:


geocodePoints:
usageType (XML) usageTypes

For more information about the Azure Maps Get Geocoding API response fields, see Definitions.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response when executing
the Bing Maps Find a Location by Query request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri": "https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights reserved. This
API cannot be accessed and the content and any results may not be used, reproduced or
transmitted in any manner without express written permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type":
"Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox": [
47.62649628242932,
-122.14631082421619,
47.634221717570675,
-122.1310271757838
],
"name": "15127 NE 24th St, Redmond, WA 98052",
"point": {
"type": "Point",
"coordinates": [
47.630359,
-122.138669
]
},
"address": {
"addressLine": "15127 NE 24th St",
"adminDistrict": "WA",
"adminDistrict2": "King County",
"countryRegion": "United States",
"formattedAddress": "15127 NE 24th St, Redmond, WA 98052",
"locality": "Redmond",
"postalCode": "98052"
},
"confidence": "High",
"entityType": "Address",
"geocodePoints": [
{
"type": "Point",
"coordinates": [
47.630359,
-122.138669
],
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
]
},
{
"type": "Point",
"coordinates": [
47.630563,
-122.1387383
],
"calculationMethod": "Rooftop",
"usageTypes": [
"Route"
]
}
],
"matchCodes": [
"Good"
]
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "7896468b37528ac145ef77cc62484fd6|MWH0032BE2|0.0.0.1|Ref A:
7D01B283F7644D2891600E265FB30B24 Ref B: CO1EDGE2318 Ref C: 2024-04-23T18:29:55Z"
The following JSON sample shows what is returned in the body of the HTTP response when executing
an Azure Maps Get Geocoding request:

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.138679,
47.630356
]
},
"bbox": [
-122.14632082377759,
47.62649328242932,
-122.1310371762224,
47.634218717570675
],
"properties": {
"type": "Address",
"confidence": "High",
"matchCodes": [
"Good"
],
"geocodePoints": [
{
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
],
"geometry": {
"type": "Point",
"coordinates": [
-122.138679,
47.630356
]
}
},
{
"calculationMethod": "Rooftop",
"usageTypes": [
"Route"
],
"geometry": {
"type": "Point",
"coordinates": [
-122.138685,
47.6305637
]
}
}
],
"address": {
"addressLine": "15127 NE 24th St",
"postalCode": "98052",
"locality": "Redmond",
"formattedAddress": "15127 NE 24th St, Redmond, WA 98052",
"countryRegion": {
"name": "United States",
"ISO": "US"
},
"adminDistricts": [
{
"shortName": "WA"
},
{
"shortName": "King County"
}
]
}
}
}
]
}

Transactions usage
Like Bing Maps Find a Location by Query API, Azure Maps Get Geocoding API logs one billable
transaction per request. For more information on Azure Maps transactions, see Understanding Azure
Maps Transactions.

Additional information
Get Geocoding Batch: Use to send a batch of queries to the Get Geocoding API in a single
synchronous request.

Support

Microsoft Q&A Forum


Migrate Bing Maps Calculate a Route API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Calculate a Route API to the Azure Maps Route Directions
API. Azure Maps Route Directions is an API that returns the ideal route between an origin and destination for
automobile (driving), commercial trucks, and walking routes. The route considers factors such as current traffic
and the typical road speeds on the requested day of the week and time of day.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Calculate a Route API supports a GET request. Azure Maps Route Directions API supports a
POST request.
Bing Maps Calculate a Route API supports XML and JSON response format. Azure Maps Route Directions
API supports GeoJSON format.
Bing Maps Calculate a Route API requires waypoints and viaWaypoints to be in latitude/longitude format,
whereas, Azure Maps requires them to be in longitude/latitude format, as defined in the GeoJSON format.
Bing Maps Calculate a Route API supports waypoints and viaWaypoints as points, landmarks, or addresses.
Azure Maps Route Directions API supports points only. To convert a landmark or address to a point, you
can use the Azure Maps Get Geocoding API.
Bing Maps Calculate a Route API supports transit routing. Azure Maps Route Directions API doesn't.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a geographic
scope, allowing limits to data residency to the European (EU) or United States (US) geographic areas
(geos). All requests (including input data) are processed exclusively in the specified geographic area. For
more information, see geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple ways to
authenticate your API calls, such as a subscription key, Microsoft Entra ID, and Shared Access Signature (SAS)
Token. For more information on security and authentication in Azure Maps, See Authentication with Azure Maps
and the Security section in the Azure Maps Route Directions documentation.

Request parameters
The following table lists the Bing Maps Calculate a Route request parameters and the Azure Maps equivalent:

ノ Expand table
Bing Maps Request Bing Azure Maps Request Required Azure Description
Parameter Maps Parameter in Azure Maps
Request Maps Data
Parameter Type
Alias

avoid avoid False string Here are the Bing Maps


Calculate a Route API to Azure
Maps Route Directions API avoid
equivalents, where supported:

tolls: tollRoads
ferry: ferries
borderCrossings:
borderCrossings
minimizeDrivingSideTurn: Not
supported

minimizeAgainstDrivingSideTurn:
Not supported
minimizeUTurn: Not supported
minimizeTolls: Not supported
highways:
limitedAccessHighways
minimizeHighways: Not
supported

dateTime dt departAt False string Azure Maps Route Directions API


also supports arriveAt parameter
that is used to specify the
desired date and time of arrival.
It can't be used with departAt.

distanceBeforeFirstTurn dbft Not supported Not Not


supported supported

distanceUnit du Not required Not Not In Azure Maps Route Directions


required required API, the distance unit is meters.

heading hd heading False integer

itineraryGroups ig Not supported Not


supported

maxSolutions maxSolns maxRouteCount False Integer

optimize optmz optimizeRoute False String Here are the Bing Maps
Calculate a Route API to Azure
Maps Route Directions API
optimizeRoute equivalents:

time: fastestWithoutTraffic
timeWithTraffic:
fastestWithTraffic
Azure Maps Route Directions API
also supports optimizing routes
by distance to return the
shortest route by specifying
shortest as the ‘optimizeRoute’
input value.

optimizeWaypoints optWp optimizeWaypointOrder False boolean


Bing Maps Request Bing Azure Maps Request Required Azure Description
Parameter Maps Parameter in Azure Maps
Request Maps Data
Parameter Type
Alias

routeAttributes ra routeOutputOptions False string Here are the Bing Maps


Calculate a Route API to Azure
Maps Route Directions API
routeOutputOptions equivalents:

routePath: routePath
regionTravelSummary:
regionTravelSummary
Azure Maps Route Directions API
supports more values like
itinerary and routeSummary. See
the RouteOutputOption for
details.

routePathOutput rpo routeOutputOptions False string Azure Maps Route Directions API
supports returning the
coordinates for the route path
geometry by passing
routeOutputOptions=routePath
in the request.

timeType tt Not supported Not Not Azure Maps Route Directions API
supported supported doesn't support Transit Routing.

tolerances tl Not supported Not Not


supported supported

travelMode travelMode False String Here are the Bing Maps


Calculate a Route API to Azure
Maps Route Directions API
travelMode equivalents:

Driving: driving
Walking: walking
Transit: Not supported
Azure Maps support extra
travelMode ‘truck’ for truck
routing.

viaWaypoint.n vwp.n features True GeoJSON waypoint and viaWaypoint are


InputWaypointFeaturesItem[] Point specified as features, which is a
required parameter. However,
only waypoint is a required
pointType and the request can
be made without viaWaypoint.

In Bing Maps Calculate a Route


API, viaWaypoint can be a point,
landmark, or address, whereas,
in Azure Maps Route Directions
API, it must be a point. To
convert a landmark or address to
a point, you can use the Azure
Maps Get Geocoding API.

Bing Maps Calculate a Truck


Bing Maps Request Bing Azure Maps Request Required Azure Description
Parameter Maps Parameter in Azure Maps
Request Maps Data
Parameter Type
Alias

Route API requires viaWaypoints


to be in latitude/longitude
format, whereas, Azure Maps
requires them to be in
longitude/latitude format, as
defined in the GeoJSON format.

waypoint.n wp.n features True GeoJSON In Bing Maps Calculate a Route


InputWaypointFeaturesItem[] Point API, waypoint can be a point,
landmark, or address, whereas,
in Azure Maps Route Directions
API, it must be a point. To
convert a landmark or address to
a point, you can use the Azure
Maps Get Geocoding API.

Bing Maps Calculate a Route API


requires waypoints to be in
latitude/longitude format,
whereas, Azure Maps requires
them to be in longitude/latitude
format, as defined in the
GeoJSON format.

For more information about the Azure Maps Route Directions API request parameters, see URI Parameters.

Request examples
Bing Maps Calculate a Route API request:

HTTP

http://dev.virtualearth.net/REST/V1/Routes/driving?
wp.0=47.610173,-122.204171&wp.1=47.612440,-122.204171key={Your-Bing-Maps-Key}

Azure Maps Route Directions API POST request:

HTTP

https://atlas.microsoft.com/route/directions?api-version=2023-10-01-preview&subscription-key=
{Your-Azure-Maps-Subscription-key}

Included in the body of the request:

JSON

{
"type": "FeatureCollection",`
"features": [
{
"type": "Feature",
"geometry": {
"coordinates": [
-122.204171,47.610173
],
"type": "Point"
},
"properties": {
"pointIndex": 0,
"pointType": "waypoint"
}
},
{
"type": "Feature",
"geometry": {
"coordinates": [
-122.204171,47.612440
],
"type": "Point"
},
"properties": {
"pointIndex": 1,
"pointType": "waypoint"
}
}
]
}

Response fields
The following table lists the fields that can appear in the HTTP response when running the Bing Maps Calculate
a Route request and the Azure Maps equivalent:

ノ Expand table

Bing Maps Field Azure Maps Field Description

actualStart Point feature object Point feature object with type=”waypoint” and inputIndex = 0 defines the
routable start location.

actualEnd Point feature object Point feature object with type=”waypoint” and inputIndex = last defines
the routable end location.

alternateVias alternativeRoutes Bing Maps alternateVias identifies the separate routes. In Azure maps,
alternate routes are returned as a new feature collection under
alternativeRoutes.

compassDegrees compassDegrees

compassDirection compassDirection

description Not supported

details properties The properties of the feature object contain the information of the
maneuver.

distanceUnit Not applicable Azure Maps Route Directions API returns the distance in meters.

durationUnit Not applicable Azure Maps Route Directions API returns the duration in seconds.

endPathIndices range Azure Maps returns the start and end index covered by a specific leg of a
route as a range.

endWaypoint Not supported In Azure Maps Route Directions API response, the endWaypoint can be
derived from type=”waypoint” and inputIndex = last index
Bing Maps Field Azure Maps Field Description

formattedText formattedText

hints Not supported

hintType Not supported

iconType Not supported Bing Maps Calculate Route API specifies the icon type to represent the
mode of travel in user applications. For example, if a driving route has a
partial ferry route, the icon could be used to visually identify the different
modes of travel in a route.

Azure Maps Calculate Route API doesn't support iconType, however the
mode of travel can be derived from travelMode property in the
response.

instruction Instruction

isRealTimeTransit Not supported

isVia viaWaypoint In Azure Maps Route Directions API response, the via waypoint is
returned as "type": "ViaWaypoint"

locationCodes Not supported

locationIdentifier Not supported

maneuverPoint maneuverPoint In Azure Maps, type=maneuverPoint for point objects where a maneuver
is required.

In Bing Maps Calculate a Route API maneuverPoint is in


latitude/longitude format, whereas, in Azure Maps it is in
longitude/latitude format, as defined in the GeoJSON format.

maneuverType maneuverType

mode Not supported

names names

realTimeTransitDelay Not supported

roadType roadType

routePathIndex routePathPoint

routeSubLegs subLegs

sideOfStreet sideOfStreet

startPathIndices range Azure Maps returns the start and end index covered by a specific leg of a
route as a range.

startWaypoint Not supported In Azure Maps Route Directions API response, the startWaypoint can be
derived from type=”waypoint” and inputIndex = first index

towardsRoadName towardsRoadName

trafficCongestion trafficCongestion

trafficDataUsed trafficDataUsed

travelDistance distanceInMeters
Bing Maps Field Azure Maps Field Description

travelDuration durationInSeconds

travelDurationTraffic durationTrafficInSeconds

travelMode travelMode

For more information about the Azure Maps Route Directions API response fields, see Definitions.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response when executing the Bing
Maps Calculate a Route request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri": "https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights reserved. This API
cannot be accessed and the content and any results may not be used, reproduced or transmitted in
any manner without express written permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type": "Route:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox": [
47.610173,
-122.204193,
47.611674,
-122.203012
],
"id": "v70,h570425388,i0,a0,cen-
US,dAAAAAAAAAAA1,y0,s1,m1,o1,t4,wfPMbJhrOR0Cq8j0jEY1ewA2~AF2UnBAtW6QAAADgAQAAAAAA0~MTAybmQgQXZlIE
5F0~~~~~~~~v12,wkWEVb2TOR0Cq8j0jEY1ewA2~AF2UnBAdU6QAAADgAQAAgD8A0~MTAzcmQgQXZlIE5F0~~~~~~~~v12,k1
,pZ3NpLXBvaQ2-VHJ1ZQ2,pWC1GRC1GTElHSFQ1-Z3NpLXBvaQ2,p-,p-,p-",
"distanceUnit": "Kilometer",
"durationUnit": "Second",
"routeLegs": [
{
"actualEnd": {
"type": "Point",
"coordinates": [
47.611674,
-122.203084
]
},
"actualStart": {
"type": "Point",
"coordinates": [
47.610173,
-122.20414
]
},
"alternateVias": [],
"description": "102nd Ave NE, NE 1st St",
"endTime": "/Date(1713305954789-0700)/",
"itineraryItems": [
{
"compassDirection": "north",
"details": [
{
"compassDegrees": 356,
"endPathIndices": [
1
],
"maneuverType": "DepartStart",
"mode": "Driving",
"names": [
"102nd Ave NE"
],
"roadType": "Street",
"startPathIndices": [
0
]
}
],
"exit": "",
"iconType": "Auto",
"instruction": {
"formattedText": null,
"maneuverType": "DepartStart",
"text": "Head north on 102nd Ave NE toward NE 1st Pl"
},
"isRealTimeTransit": false,
"maneuverPoint": {
"type": "Point",
"coordinates": [
47.610173,
-122.20414
]
},
"realTimeTransitDelay": 0,
"sideOfStreet": "Unknown",
"tollZone": "",
"towardsRoadName": "NE 1st Pl",
"transitTerminus": "",
"travelDistance": 0.114,
"travelDuration": 36,
"travelMode": "Driving"
},
{
"compassDirection": "east",
"details": [
{
"compassDegrees": 89,
"endPathIndices": [
4
],
"maneuverType": "TurnRight",
"mode": "Driving",
"names": [
"NE 1st St"
],
"roadType": "Street",
"startPathIndices": [
1
]
}
],
"exit": "",
"iconType": "Auto",
"instruction": {
"formattedText": null,
"maneuverType": "TurnRight",
"text": "Turn right onto NE 1st St"
},
"isRealTimeTransit": false,
"maneuverPoint": {
"type": "Point",
"coordinates": [
47.611206,
-122.204193
]
},
"realTimeTransitDelay": 0,
"sideOfStreet": "Unknown",
"tollZone": "",
"transitTerminus": "",
"travelDistance": 0.106,
"travelDuration": 22,
"travelMode": "Driving"
},
{
"compassDirection": "northwest",
"details": [
{
"compassDegrees": 302,
"endPathIndices": [
5
],
"maneuverType": "TurnLeft",
"mode": "Driving",
"names": [
"103rd Ave NE"
],
"roadType": "Street",
"startPathIndices": [
4
]
}
],
"exit": "",
"iconType": "Auto",
"instruction": {
"formattedText": null,
"maneuverType": "TurnLeft",
"text": "Turn left onto 103rd Ave NE"
},
"isRealTimeTransit": false,
"maneuverPoint": {
"type": "Point",
"coordinates": [
47.611629,
-122.203012
]
},
"realTimeTransitDelay": 0,
"sideOfStreet": "Unknown",
"tollZone": "",
"transitTerminus": "",
"travelDistance": 0.007,
"travelDuration": 21,
"travelMode": "Driving"
},
{
"compassDirection": "northwest",
"details": [
{
"compassDegrees": 302,
"endPathIndices": [
5
],
"maneuverType": "ArriveFinish",
"mode": "Driving",
"names": [
"103rd Ave NE"
],
"roadType": "Street",
"startPathIndices": [
5
]
}
],
"exit": "",
"hints": [
{
"hintType": "PreviousIntersection",
"text": "The last intersection before your
destination is NE 2nd St"
}
],
"iconType": "Auto",
"instruction": {
"formattedText": null,
"maneuverType": "ArriveFinish",
"text": "Arrive at 103rd Ave NE"
},
"isRealTimeTransit": false,
"maneuverPoint": {
"type": "Point",
"coordinates": [
47.611674,
-122.203084
]
},
"realTimeTransitDelay": 0,
"sideOfStreet": "Unknown",
"tollZone": "",
"transitTerminus": "",
"travelDistance": 0,
"travelDuration": 0,
"travelMode": "Driving"
}
],
"routeRegion": "WWMX",
"routeSubLegs": [
{
"endWaypoint": {
"type": "Point",
"coordinates": [
47.611674,
-122.203084
],
"description": "103rd Ave NE",
"isVia": false,
"locationIdentifier":
"0|93|148|156|16|29|83|164|0|0|0|224|1|0|0|128|63|0|47.611674,-122.203084",
"routePathIndex": 5
},
"startWaypoint": {
"type": "Point",
"coordinates": [
47.610173,
-122.20414
],
"description": "102nd Ave NE",
"isVia": false,
"locationIdentifier":
"0|93|148|156|16|45|91|164|0|0|0|224|1|0|0|0|0|0|47.610173,-122.20414",
"routePathIndex": 0
},
"travelDistance": 0.227,
"travelDuration": 80
}
],
"startTime": "/Date(1713305874789-0700)/",
"travelDistance": 0.227,
"travelDuration": 80,
"travelMode": "Driving"
}
],
"trafficCongestion": "None",
"trafficDataUsed": "None",
"travelDistance": 0.227,
"travelDuration": 80,
"travelDurationTraffic": 71,
"travelMode": "Driving"
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "47969a89fd7bc08f1a922bf92f4a7541|MWH0032B15|0.0.0.0|MWH0031C9B, Leg0-MWH0031C8C"
}

The following JSON sample shows what is returned in the body of the HTTP response when executing an Azure
Maps Get Map Tile request:

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.20414,
47.610173
]
},
"properties": {
"durationInSeconds": 36,
"distanceInMeters": 114.00,
"exitIdentifier": "",
"signs": [],
"instruction": {
"formattedText": "<Action>Head</Action> <CmpsDir>north</CmpsDir> on
<RoadName>102nd Ave NE</RoadName> toward <Toward>NE 1st Pl</Toward>",
"maneuverType": "DepartStart",
"text": "Head north on 102nd Ave NE toward NE 1st Pl"
},
"towardsRoadName": "NE 1st Pl",
"routePathPoint": {
"legIndex": 0,
"pointIndex": 0
},
"compassDirection": "north",
"travelMode": "driving",
"steps": [
{
"maneuverType": "DepartStart",
"routePathRange": {
"legIndex": 0,
"range": [
0,
1
]
},
"names": [
"102nd Ave NE"
],
"compassDegrees": 356.00,
"roadType": "Street"
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.204193,
47.611206
]
},
"properties": {
"durationInSeconds": 22,
"distanceInMeters": 106.00,
"exitIdentifier": "",
"signs": [],
"instruction": {
"formattedText": "<Action>Turn</Action> <TurnDir>right</TurnDir> onto
<RoadName>NE 1st St</RoadName>",
"maneuverType": "TurnRight",
"text": "Turn right onto NE 1st St"
},
"routePathPoint": {
"legIndex": 0,
"pointIndex": 1
},
"compassDirection": "east",
"travelMode": "driving",
"steps": [
{
"maneuverType": "TurnRight",
"routePathRange": {
"legIndex": 0,
"range": [
1,
4
]
},
"names": [
"NE 1st St"
],
"compassDegrees": 89.00,
"roadType": "Street"
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.203012,
47.611629
]
},
"properties": {
"durationInSeconds": 21,
"distanceInMeters": 7.00,
"exitIdentifier": "",
"signs": [],
"instruction": {
"formattedText": "<Action>Turn</Action> <TurnDir>left</TurnDir> onto
<RoadName>103rd Ave NE</RoadName>",
"maneuverType": "TurnLeft",
"text": "Turn left onto 103rd Ave NE"
},
"routePathPoint": {
"legIndex": 0,
"pointIndex": 4
},
"compassDirection": "northwest",
"travelMode": "driving",
"steps": [
{
"maneuverType": "TurnLeft",
"routePathRange": {
"legIndex": 0,
"range": [
4,
5
]
},
"names": [
"103rd Ave NE"
],
"compassDegrees": 302.00,
"roadType": "Street"
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.203084,
47.611674
]
},
"properties": {
"durationInSeconds": 0,
"distanceInMeters": 0.00,
"exitIdentifier": "",
"signs": [],
"instruction": {
"formattedText": "<Action>Arrive</Action> at <WaypointName>103rd Ave
NE</WaypointName>",
"maneuverType": "ArriveFinish",
"text": "Arrive at 103rd Ave NE"
},
"routePathPoint": {
"legIndex": 0,
"pointIndex": 5
},
"compassDirection": "northwest",
"travelMode": "driving",
"steps": [
{
"maneuverType": "ArriveFinish",
"routePathRange": {
"legIndex": 0,
"range": [
5,
5
]
},
"names": [
"103rd Ave NE"
],
"compassDegrees": 302.00,
"roadType": "Street"
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": []
},
"properties": {
"resourceId": "v70,h570425388,i0,a0,cen-
US,dAAAAAAAAAAA1,y0,s1,m1,o1,t0,wfPMbJhrOR0Cq8j0jEY1ewA2~~~~~~~~~~v12,wkWEVb2TOR0Cq8j0jEY1ewA2~~~
~~~~~~~v12,k1,qatt:1",
"trafficCongestion": "Mild",
"trafficDataUsed": "None",
"distanceInMeters": 227.00,
"durationInSeconds": 80,
"departureTime": "2024-04-16T22:22:27+00:00",
"arrivalTime": "2024-04-16T22:23:47+00:00",
"type": "RoutePath",
"legs": []
}
}
]
}

Transactions usage
Similar to Bing Maps Calculate Route API, Azure Maps Route Direction API logs one billable transaction per API
request. For more information on Azure Maps transactions, see Understanding Azure Maps Transactions.

Additional information
Post Directions Batch: Use to send a batch of queries to the Route Directions API in a single synchronous
request.

Support

Microsoft Q&A Forum


Migrate Bing Maps Calculate a Truck Route API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Calculate a Truck Route API to the Azure Maps Route Directions
API. The Azure Maps Route Directions API returns the ideal route between an origin and destination for
automobile (driving), commercial trucks and walking routes, while considering local laws, vehicle dimensions, cargo
type, max speed, bridge, and tunnel heights to calculate the truck specific routes and avoid complex maneuvers
and difficult roads. To get trucking routing in Azure Maps Route Directions API, specify truck for the travelMode
input parameter in the request.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Calculate a Truck Route is a standalone API dedicated to truck routing. Azure Maps Route
Directions API provides truck routing support when travelMode=truck is specified in the request.
Bing Maps Calculate a Truck Route API supports GET or POST requests. Azure Maps Route Directions API
supports POST requests.
Bing Maps Calculate a Truck Route API supports XML and JSON response formats. Azure Maps Route
Directions API supports the GeoJSON response format.
Bing Maps Calculate a Truck Route API supports a maximum of 25 waypoints or viaWaypoints per request.
Azure Maps Route Directions API supports up to 150 waypoints per request, but doesn’t support
viaWaypoints.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a geographic scope,
allowing limits to data residency to the European (EU) or United States (US) geographic areas (geos). All
requests (including input data) are processed exclusively in the specified geographic area. For more
information, see geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple ways to authenticate
your API calls, such as a subscription key, Microsoft Entra ID, and Shared Access Signature (SAS) Token. For more
information on security and authentication in Azure Maps, See Authentication with Azure Maps and the Security
section in the Azure Maps Route Directions documentation.

Request parameters
The following table lists the Bing Maps Calculate a Truck Route request parameters and the Azure Maps equivalent:

ノ Expand table
Bing Maps Request Bing Azure Maps Request Required Azure Description
Parameter Maps Parameter in Azure Maps
Request Maps Data
Parameter Type
Alias

avoid avoid False string Here are the Bing Maps to Azure
Maps Route Directions API avoid
equivalents, where supported:

- tolls: tollRoads
- ferry: ferries
- borderCrossings:
borderCrossings
- highways:
limitedAccessHighways
- minimizeDrivingSideTurn: Not
supported
-
minimizeAgainstDrivingSideTurn:
Not supported
- minimizeUTurn: Not
supported
- minimizeTolls: Not supported
- minimizeHighways: Not
supported

borderRestriction Not supported Not Not In Azure Maps Route Directions


supported supported API, avoid=borderCrossings can
be used to restrict routes from
crossing country borders
however specifying a region list
for border restriction isn't
supported.

dateTime dt departAt False string Azure Maps Route Directions API


also supports arriveAt
parameter that is used to specify
the desired date and time of
arrival. It can't be used with
departAt .

dimensionUnit dims Not supported Not Not In Azure Maps Route Directions
supported supported API, the unit for truck height,
width, and length dimensions is
meters.

distanceUnit du Not supported Not Not In Azure Maps Route Directions


supported supported API, the distance unit is meters.

distanceBeforeFirstTurn dbft Not supported Not Not


supported supported

heading hd heading False integer

optimize optmz optimizeRoute False string Here are the Bing Maps
Calculate a Truck Route API to
Azure Maps Route Directions API
optimizeRoute equivalents:

- time: fastestWithoutTraffic
- timeWithTraffic:
fastestWithTraffic
Bing Maps Request Bing Azure Maps Request Required Azure Description
Parameter Maps Parameter in Azure Maps
Request Maps Data
Parameter Type
Alias

Azure Maps Route Directions API


also supports optimizing routes
by distance to return the
shortest route by specifying
shortest as the optimizeRoute
input value.

optimizeWaypoints optWp optimizeWaypointOrder False boolean

routeAttributes ra routeOutputOptions False string Here are the Bing Maps to Azure
Maps Route Directions API
routeOutputOptions equivalents:

- routePath: routePath
- regionTravelSummary:
regionTravelSummary

Azure Maps Route Directions API


supports extra values like
itinerary and routeSummary .
For more information, see
[RouteOutputOption].

tolerances tl Not supported Not Not


supported supported

viawaypoint.n vwp.n Not supported Not Not


supported supported

vehicleHeight height height False number

vehicleWidth width width False number

vehicleLength vl length False number

vehicleWeight weight weight False integer

vehicleAxles axles Not supported Not Not Azure Maps Route Directions API
supported supported supports weight restrictions per
axle that can be specified using
the parameter axleWeight .

vehicleTrailers vt Not supported Not Not The trailer length could be


supported supported added to the length of the
vehicle to be considered for
restrictions.

vehicleSemi semi Not supported Not Not Semi-trucks generally fall under
supported supported commercial vehicle category.
Azure Maps Route Directions API
supports isVehicleCommercial
property that could be used for
Semi-trucks.

vehicleMaxGradient vmg Not supported Not Not


supported supported
Bing Maps Request Bing Azure Maps Request Required Azure Description
Parameter Maps Parameter in Azure Maps
Request Maps Data
Parameter Type
Alias

vehicleMinTurnRadius vmtr Not supported Not Not


supported supported

vehicleHazardousMaterials vhm loadType False string Refer to Azure Maps Route


Directions API Vehicle Load
Types for corresponding US
Hazmat classes 1-9, and the
generic classification of cargo
types to hazardous material in
Bing Maps Calculate a Truck
Route API.

vehicleHazardousPermits Vhp Not supported Not Not


supported supported

waypoint.n wp.n features True GeoJSON


InputWaypointFeaturesItem[] Point

weightUnit wu Not supported Not Not In Azure Maps Route Directions


supported supported API, the weight unit is kilograms
(kg).

For more information about the Azure Maps Route Directions API request parameters, see URI Parameters.

Request examples
Bing Maps Calculate a Truck Route API POST request:

HTTP

https://dev.virtualearth.net/REST/v1/Routes/Truck?key={Your-Bing-Maps-Key}

Included in the body of the request:

JSON

{
"waypoints": [{
"latitude": 47.610133,
"longitude": -122.201478
},{
"latitude": 47.610096,
"longitude": -122.192463
}],
"vehicleSpec": {
"vehicleHazardousMaterials": "Flammable"
}
}

Azure Maps Route Directions API POST request:

HTTP
https://atlas.microsoft.com/route/directions?api-version=2023-10-01-preview&subscription-key={Your-
Azure-Maps-Subscription-key}

Included in the body of the request:

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"coordinates": [
-122.201478, 47.610133
],
"type": "Point"
},
"properties": {
"pointIndex": "0",
"pointType": "waypoint"
}
},
{
"type": "Feature",
"geometry": {
"coordinates": [
-122.192463, 47.610096
],
"type": "Point"
},
"properties": {
"pointIndex": "1",
"pointType": "waypoint"
}
}
],
"RouteOutputOptions": [
"itinerary"
],
"travelMode": "truck",
"vehicleSpec": {
"loadType": [
"USHazmatClass3",
"USHazmatClass4"
]
}
}

Response fields
The following table lists the fields that can appear in the HTTP response when running the Bing Maps Calculate a
Truck Route request and the Azure Maps equivalent:

ノ Expand table

Bing Maps Field Azure Maps Field Description

actualEnd Point feature object Point feature object with type=”waypoint” and inputIndex = last defines the
routable end location.
Bing Maps Field Azure Maps Field Description

actualStart Point feature object Point feature object with type=”waypoint” and inputIndex = 0 defines the
routable start location.

alternateVias alternativeRoutes Bing Maps alternateVias identifies the separate routes. In Azure maps
Route Directions API, alternate routes are returned as a new feature
collection under alternativeRoutes .

compassDegrees Not supported

compassDirection Not supported

description Not supported

details properties The properties of the feature object contain the information of the
maneuver.

distanceUnit Not applicable Azure Maps Route Directions API returns the distance in meters by default.

durationUnit Not applicable Azure Maps Route Directions API returns the duration in seconds.

endPathIndices range Azure Maps Route Directions API returns the start and end index covered by
a specific leg of a route as a range.

endWaypoint Not supported In Azure Maps Route Directions API response, the end waypoint can be
derived from type=”waypoint” and inputIndex = last index

formattedText formattedText

hints Not supported

hintType Not supported

iconType Not supported

instruction instruction

isRealTimeTransit Not supported

isVia Not supported Azure Maps Route Directions API doesn't support viaWaypoint for truck
routes.

locationCodes Not supported

locationIdentifier Not supported

maneuverPoint maneuverPoint In Azure Maps, _type=maneuverPoin_t is for point objects where a


maneuver is required.

maneuverType maneuverType

mode Not supported

names names

realTimeTransitDelay Not supported

roadType Not supported

routePathIndex routePathPoint

routeSubLegs subLegs

sideOfStreet sideOfStreet
Bing Maps Field Azure Maps Field Description

startPathIndices range Azure Maps Route Directions API returns the start and end index covered by
a specific leg of a route as a range.

startWaypoint Not supported In Azure Maps Route Directions API response, the start waypoint can be
derived from type=”waypoint” and inputIndex = first index

towardsRoadName towardsRoadName

trafficCongestion Not supported

trafficDataUsed trafficDataUsed

travelDistance distanceInMeters

travelDuration durationInSeconds

travelDurationTraffic durationTrafficInSeconds

travelMode travelMode

For more information about the Azure Maps Route Directions API response fields, see Definitions.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response when executing the Bing
Maps Calculate a Truck Route request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri": "https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights reserved. This API cannot
be accessed and the content and any results may not be used, reproduced or transmitted in any manner
without express written permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type": "Route:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox": [
47.610017,
-122.201495,
47.610133,
-122.192518
],
"distanceUnit": "Mile",
"durationUnit": "Second",
"routeLegs": [
{
"actualEnd": {
"type": "Point",
"coordinates": [
47.610052,
-122.192518
]
},
"actualStart": {
"type": "Point",
"coordinates": [
47.610109,
-122.201495
]
},
"alternateVias": [],
"description": "Main St",
"itineraryItems": [
{
"compassDirection": "east",
"details": [
{
"compassDegrees": 91,
"endPathIndices": [
1
],
"locationCodes": [
"114+10725"
],
"maneuverType": "DepartStart",
"mode": "Driving",
"names": [
"Main St"
],
"roadType": "Arterial",
"startPathIndices": [
0
]
}
],
"iconType": "Auto",
"instruction": {
"formattedText": "<Action>Head</Action>
<CmpsDir>east</CmpsDir> on <RoadName>Main St</RoadName> toward <Toward>105th Ave NE</Toward>",
"maneuverType": "DepartStart",
"text": "Head east on Main St toward 105th Ave NE"
},
"isRealTimeTransit": false,
"maneuverPoint": {
"type": "Point",
"coordinates": [
47.610109,
-122.201495
]
},
"realTimeTransitDelay": 0,
"sideOfStreet": "Unknown",
"towardsRoadName": "105th Ave NE",
"travelDistance": 0.418804,
"travelDuration": 68,
"travelMode": "Driving"
},
{
"compassDirection": "east",
"details": [
{
"compassDegrees": 90,
"endPathIndices": [
1
],
"locationCodes": [
"114+10725"
],
"maneuverType": "ArriveFinish",
"mode": "Driving",
"names": [
"Main St"
],
"roadType": "Arterial",
"startPathIndices": [
1
]
}
],
"hints": [
{
"hintType": "PreviousIntersection",
"text": "The last intersection before your destination
is 110th Pl SE"
}
],
"iconType": "Auto",
"instruction": {
"formattedText": "<Action>Arrive</Action> at
<WaypointName>Stop: Y, X = 47.610096, -122.192463</WaypointName>",
"maneuverType": "ArriveFinish",
"text": "Arrive at Stop: Y, X = 47.610096, -122.192463"
},
"isRealTimeTransit": false,
"maneuverPoint": {
"type": "Point",
"coordinates": [
47.610052,
-122.192518
]
},
"realTimeTransitDelay": 0,
"sideOfStreet": "Unknown",
"travelDistance": 0,
"travelDuration": 0,
"travelMode": "Driving"
}
],
"routeSubLegs": [
{
"endWaypoint": {
"type": "Point",
"coordinates": [
47.610052,
-122.192518
],
"description": "Stop: Y, X = 47.610096, -122.192463",
"isVia": false,
"locationIdentifier": "",
"routePathIndex": 1
},
"startWaypoint": {
"type": "Point",
"coordinates": [
47.610109,
-122.201495
],
"description": "Stop: Y, X = 47.610133, -122.201478",
"isVia": false,
"locationIdentifier": "",
"routePathIndex": 0
},
"travelDistance": 0.418805,
"travelDuration": 68
}
],
"travelDistance": 0.418805,
"travelDuration": 68,
"travelMode": "Truck"
}
],
"trafficCongestion": "Medium",
"trafficDataUsed": "None",
"travelDistance": 0.418805,
"travelDuration": 68,
"travelDurationTraffic": 93,
"travelMode": "Truck"
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "bb78d3da62a71f62683cea8e6653806f|MWH0032BED|0.0.0.0|MWH0031C93,Leg0-MWH0031C91"
}

The following JSON sample shows what is returned in the body of the HTTP response when executing an Azure
Maps Get Map Tile request:

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.2015,
47.61013
]
},
"properties": {
"durationInSeconds": 0,
"distanceInMeters": 3.00,
"routePathPoint": {
"legIndex": 0,
"pointIndex": 0
},
"travelMode": "truck",
"instruction": {
"formattedText": "Leave from <street>Bellevue Way SE</street>",
"maneuverType": "DepartStart",
"text": "Leave from Bellevue Way SE"
},
"towardsRoadName": "Bellevue Way SE",
"steps": [
{
"maneuverType": "DepartStart",
"routePathRange": {
"legIndex": 0,
"range": [
0,
1
]
},
"names": [
"Bellevue Way SE"
]
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.2015,
47.61011
]
},
"properties": {
"durationInSeconds": 111,
"distanceInMeters": 724.00,
"routePathPoint": {
"legIndex": 0,
"pointIndex": 1
},
"travelMode": "other",
"instruction": {
"formattedText": "Turn left onto <street>Main St</street>",
"maneuverType": "TurnLeft",
"text": "Turn left onto Main St"
},
"towardsRoadName": "Main St",
"steps": [
{
"maneuverType": "TurnLeft",
"routePathRange": {
"legIndex": 0,
"range": [
1,
32
]
},
"names": [
"Main St"
]
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.19195,
47.61005
]
},
"properties": {
"durationInSeconds": 14,
"distanceInMeters": 7.00,
"routePathPoint": {
"legIndex": 0,
"pointIndex": 32
},
"travelMode": "truck",
"instruction": {
"formattedText": "Turn left",
"maneuverType": "TurnLeft",
"text": "Turn left"
},
"steps": [
{
"maneuverType": "TurnLeft",
"routePathRange": {
"legIndex": 0,
"range": [
32,
33
]
}
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.19195,
47.61011
]
},
"properties": {
"durationInSeconds": 0,
"distanceInMeters": 0.00,
"routePathPoint": {
"legIndex": 0,
"pointIndex": 33
},
"travelMode": "truck",
"instruction": {
"formattedText": "You have arrived. Your destination is on the left",
"maneuverType": "ArriveFinish",
"text": "You have arrived. Your destination is on the left"
},
"sideOfStreet": "Left",
"steps": [
{
"maneuverType": "ArriveFinish",
"routePathRange": {
"legIndex": 0,
"range": [
33,
33
]
}
}
],
"type": "ManeuverPoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": []
},
"properties": {
"resourceId": "/ZlIBcVsx0+/BcpEi208gQ==",
"trafficDataUsed": "FlowAndClosure",
"distanceInMeters": 734.00,
"durationInSeconds": 100,
"departureTime": "2024-04-08T20:20:25+00:00",
"arrivalTime": "2024-04-08T20:22:30+00:00",
"type": "RoutePath",
"legs": []
}
}
]
}

Transactions usage
Bing Maps Calculate a Truck Route API logs three billable transactions per API request. Azure Maps Route
Directions API logs one billable transaction per API request. For more information on Azure Maps transactions, see
Understanding Azure Maps Transactions.
Additional information
Post Directions Batch: Use to send a batch of queries to the Route Directions API in a single synchronous
request.

Support

Microsoft Q&A Forum


Migrate Bing Maps Data Source
Management and Query API
Article • 05/22/2024

The Bing Maps Spatial Data Services (SDS) has several capabilities similar to Azure Maps
and other Azure services. Bing Maps SDS supports storing, managing, and querying
your custom spatial data using the SDS Data Source Management and Query API,
querying public points of interest data using the SDS Public Data Sources and Query
API, batch geocoding location data using the SDS Geocode Dataflow API and getting
geographical polygon boundaries using the SDS Geodata API.

This article covers alternatives to the SDS functionality for storing, managing, and
querying your custom spatial data sources. If you need guidance on migrating from the
other SDS capabilities to Azure Maps, refer to the following migration guides.

Migrating Bing Maps SDS Geocode Dataflow API


Migrating Bing Maps SDS Geodata API

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Bing Maps SDS Data Source Management and


Query API alternatives
Azure Maps in combination with other Azure services offer state of the art solutions for
storing, managing, and performing spatial querying on your custom location data. All
while handling security, compliance, and privacy requirements. Azure has several
alternative solutions to the Bing Maps SDS Data Source Management and Query API
available to you.

Azure Maps integrates with other Azure services to store, manage, and perform spatial
querying on your custom spatial data sources. For example, Azure offers several
database products that support geospatial data capabilities, such as the following
database products:
Azure SQL Database: A relational database that supports geography and geometry
data types and spatial methods, such as STArea, STDistance, STIntersects, STWithin,
and many more.
Azure Cosmos DB: A NoSQL database that supports GeoJSON data types and
spatial queries, such as ST_AREA, ST_DISTANCE, ST_WITHIN, ST_INTERSECTS,
ST_ISVALID, and ST_ISVALIDDETAILED.
Azure Database for PostgreSQL : An open-source relational database that
supports PostGIS , an extension that adds support for geographic objects and
spatial functions, such as ST_Area, ST_Distance, ST_Within, ST_Intersects, ST_IsValid,
and ST_IsValidReason .

To load and present your data on a map, you need to build a service layer (an API) that
is used by the Azure Maps Web SDK client to get the data that needs to be displayed on
the map. The following illustration is a simple architecture design showing what you
need for this scenario:

More information
Create a data source for a map in Microsoft Azure Maps
How to use the Azure Maps spatial IO module
Read and write spatial data with Microsoft Azure Maps

Locator starter project


If you need a locator solution, such as a store locator, job searching by location or
finding a house to buy or rent, we have a store locator starter project that uses Azure
Maps and Azure Cosmos DB to get you started quickly. The Azure Maps Store Locator
provides an impressive range of capabilities to enhance your location-based services:

Store Locator Backend: Offers REST APIs and a ‘Store Locator Web Control’.
Robust Autocomplete Search: Enables searching for store names, addresses,
points of interest (POI), or zip codes.
High Location Capacity: Supports over 10,000 locations.
Proximity Insights: Displays nearby stores and their respective distances.
Location-based Search: Allows searching based on the user's or device's location.
Travel Time Estimates: Presents travel time for walking and driving options.
Detailed Store Information: Offers store details via popups and directions.
Dynamic Filtering: Allows the user to filter based on dynamic store features.
Detailed Store Page: Explore what a specific store offers with an embedded map.
Security Measures: Utilizes Microsoft Entra ID for secure location management
system access, ensuring only authorized employees can update store details. For
more information, see Microsoft Entra authentication.
Rich Store Data: Includes store details such as location, opening hours, store
photos, and facilitates the addition of custom store features and services.
Accessibility Features: Incorporates speech recognition and other accessibility
options.
Seamless Deployment: Easy deployment within your Azure subscription.

The Azure Maps store locator starter project gives you the following general architecture
that you can customize and expand on to meet your specific business requirements.
Additional information
Azure-Samples/Azure-Maps-Locator: Azure Maps Locator Source Code
(github.com)
Azure Maps Store Locator Blog Post (microsoft.com)
Tutorial: Use Azure Maps to create store locator

Support
Microsoft Q&A Forum
Migrate Bing Maps Geocode Dataflow API
Article • 05/17/2024

This article explains how to migrate the Bing Maps Geocode Dataflow API to Azure Maps
Geocoding Batch and Reverse Geocoding Batch API. Azure Maps Geocoding Batch API is used
to get latitude and longitude coordinates of a street address or name of a place in batch mode
with a single API call. Azure Maps Geocoding Batch API is an HTTP POST request that sends
batches of queries to the Azure Maps Geocoding API in a single request. Azure Maps Reverse
Geocoding Batch API is used to translate latitude and longitude coordinates into a human
understandable street address. Azure Maps Reverse Geocoding Batch API is an HTTP POST
request that sends batches of queries to the Azure Maps Get Reverse Geocoding API in a
single request.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Geocode Dataflow API supports forward and reverse batch geocoding within
the same API. Azure Maps has separate API for forward and reverse geocoding.
Bing Maps Geocode Dataflow API requires uploading your location data as an XML or
text (csv, pipe, or tab delimited) data file. Azure Maps Geocoding Batch and Reverse
Geocoding Batch API don’t use a data file upload approach, but rather an HTTP POST
request with location data in GeoJSON format in the body of the request.
Bing Maps Geocode Dataflow API supports up to 200,000 entities per upload. The Azure
Maps Geocoding Batch and Reverse Geocoding Batch API supports up to 100 batched
queries in a synchronous request, and up to 200,000 in an asynchronous request.
Bing Maps Geocode Dataflow API requires a series of API calls following the initial data
upload to get the status and download results. The Azure Maps Geocoding Batch and
Reverse Geocoding Batch API synchronous request don’t require additional API calls. The
asynchronous request does require additional calls to get the batch process status and
download results.
Bing Maps Geocode Dataflow coordinates are in latitude/longitude format. Azure Maps
Geocoding Batch and Reverse Geocoding Batch API coordinates are in longitude/latitude
format (due to being in GeoJSON format).
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a
geographic scope, which allows you to limit data residency to the European (EU) or
United States (US) geographic areas (geos). All requests (including input data) are
processed exclusively in the specified geographic area. For more information, see Azure
Maps service geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple
ways to authenticate your API calls, such as a subscription key, Microsoft Entra ID, or Shared
Access Signature (SAS) Token. For more information on security and authentication in Azure
Maps, See Authentication with Azure Maps and the Security section in the Azure Maps
Geocoding Batch documentation..

Request parameters
The following table lists the Bing Maps Geocode Dataflow request parameters and the Azure
Maps equivalent:

ノ Expand table

Bing Maps Azure Maps Description


Parameter Parameter

dataLocation Not needed

input Not needed Bing Maps Geocode Dataflow API supports XML and Text (csv, tab,
and pipe delimited) format for the batch geocoding input data file.
Azure Maps supports JSON format for the batch geocoding input
data in the HTTP POST request.

output Not needed Bing Maps Geocode Dataflow API supports JSON and XML for the
batch geocode output data. Azure Maps supports JSON format for
the batch geocoding output data.

For more information about the Azure Maps URI parameters and request body, see the Azure
Maps Geocoding Batch and Reverse Geocoding Batch documentation.

Bing Maps Data Schema 2.0 input and output comparison to Azure Maps Geocode Batch and
Reverse Geocode Batch API:

ノ Expand table

Bing Maps Field Bing Maps Azure Maps Azure Maps Data Description
Operation Field Type

Address.AddressLine Geocode addressLine string


Request
Geocode
Response
Bing Maps Field Bing Maps Azure Maps Azure Maps Data Description
Operation Field Type

Address.AdminDistrict Geocode adminDistrict string


Request
Geocode
Response

Address.CountryRegion Geocode countryRegion string


Request
Geocode
Response

Address.District Geocode adminDistrict2 string


Request

Address.FormattedAddress Geocode
Response

Address.Landmark Geocode Not supported Not supported


Response

Address.Locality Geocode locality string


Request
Geocode
Response

Address.Neighborhood Geocode neighborhood string


Response

Address.PostalCode Geocode postalCode string


Request
Geocode
Response

Address.PostalTown Geocode adminDistrict3


Request

BoundingBox.SouthLatitude, Geocode bbox number[] Azure Maps


BoundingBox.EastLongitude, Response projection used is
BoundingBox.NorthLatitude, EPSG:3857. For
BoundingBox.EastLongitude more information,
see RFC 7946 .

Confidence Geocode confidence ConfidenceEnum For more


Response information, see
the Azure Maps
Geocoding Batch
and Reverse
Geocoding Batch
API
documentation.
Bing Maps Field Bing Maps Azure Maps Azure Maps Data Description
Operation Field Type

ConfidenceFilter.MinimumConfidence Geocode Not supported Not supported


Request
Reverse
Geocode
Request

Culture Geocode Request string For more


Request Header: Accept- information,
Reverse Language see Azure Maps
Geocode Supported
Request Languages.

EntityType Geocode type string For more


Response information, see
the Azure Maps
Geocoding Batch
and Reverse
Geocoding Batch
API
documentation.

FaultReason Geocode Not supported Not supported


Response

GeocodeEntity XML Not needed Not needed


container

GeocodeFeed XML Not needed Not needed


container

GeocodePoint Geocode geocodePoints GeocodePoints[] For more


Response information, see
the Azure Maps
Geocoding Batch
and Reverse
Geocoding Batch
API
documentation.

GeocodeRequest XML Not needed Not needed Azure Maps has


container separate APIs for
forward
geocoding and
reverse
geocoding.

Id Geocode Not needed Not needed


Request

IncludeEntityTypes Geocode Not supported Not supported


Request
Bing Maps Field Bing Maps Azure Maps Azure Maps Data Description
Operation Field Type

Reverse
Geocode
Request

IncludeNeighborhood Geocode Not needed Not needed In Azure Maps,


Request neighborhood
Reverse info is returned in
Geocode the response by
Request default when
available.

IncludeQueryParse Geocode Not supported Not supported


Request

Location.Latitude Reverse coordinates number[] Required as input


Location.Longitude Geocode if using Azure
Request Maps Reverse
Geocoding Batch
API to do reverse
geocoding.

MatchCodes Geocode matchCodes MatchCodesEnum For more


Response information, see
the Azure Maps
Geocoding Batch
and Reverse
Geocoding Batch
API
documentation.

MaxResults Geocode top integer In Azure Maps,


Request int32 the maximum
Reverse number of
Geocode responses that
Request are returned.
Default is 5,
minimum is 1,
and maximum is
20.

Name Geocode Not supported Not supported


Response

Point.Latitude, Point.Longitude Geocode coordinates number[] Bing Maps


Response returns the
coordinates in
latitude/longitude
format. Azure
Maps returns
coordinates in
longitude/latitude
Bing Maps Field Bing Maps Azure Maps Azure Maps Data Description
Operation Field Type

format (due to
being in
GeoJSON format).

Query Geocode query string


Request

QueryParseValue Geocode Not supported Not supported


Response

ReverseGeocodeRequest XML Not needed Not needed Azure Maps has


container separate APIs for
forward
geocoding and
reverse
geocoding.

StatusCode Geocode Not supported Not supported


Response

StrictMatch Geocode Not supported Not supported


Request

TraceId Geocode Not supported Not supported


Response

Version Not needed Not needed

For more information about the Azure Maps Geocoding Batch response fields, see the
response Definitions.

Request examples
Bing Maps Geocode Dataflow API request:

HTTP

http://spatial.virtualearth.net/REST/v1/Dataflows/Geocode?input=xml&key=
{BingMapsKey}

For examples that show sample input and output data for version 2.0 of the Geocode
Dataflow, see Geocode Dataflow Sample Input and Output Data Version 2.0.

Azure Maps Geocoding Batch API request:

HTTP
POST https://atlas.microsoft.com/geocode:batch?api-version=2023-06-
01&subscription-key={Your-Azure-Maps-Subscription-key}

To send the geocoding queries, use an HTTP POST request where the body of the request
contains the batchItems array in JSON format and the Content-Type header set to
application/json.

The following JSON shows a sample request containing two geocoding queries, with one
location in unstructured format and one location in structured format:

JSON

{
"batchItems": [
{
"addressLine": "One, Microsoft Way, Redmond, WA 98052",
"top": 2
},
{
"addressLine": "Pike Pl",
"adminDistrict": "WA",
"locality": "Seattle",
"top": 3
}
]
}

Sample Azure Maps Reverse Geocoding Batch API request:

HTTP

POST https://atlas.microsoft.com/reverseGeocode:batch?api-version=2023-06-
01&subscription-key={Your-Azure-Maps-Subscription-key}

To send the reverse geocoding queries, use an HTTP POST request where the body of the
request contains a batchItems array in JSON format and the Content-Type header is set to
application/json.

The following JSON shows a sample request containing two reverse geocoding queries:

JSON

{
"batchItems": [
{
"coordinates": [
-122.128275,
47.639429
],
"resultTypes": [
"Address",
"PopulatedPlace"
],
"optionalId": "4C3681A6C8AA4AC3441412763A2A25C81444DC8B"
},
{
"coordinates": [
-122.341979399674,
47.6095253501216
],
"optionalId": "6M9W39P12SNHGAIZ4JQ7F57NWJLV2BRYEQRD7OH7"
}
]
}

Response examples
A URL to download the geocode job results is provided when the Bing Maps Geocode
Dataflow batch job processes successfully, as shown by the completed job status. For an
example of a successful Bing Maps Geocode Dataflow output, see Geocode Dataflow Sample
Input and Output Data Version 2.0 in the Bing Maps documentation.

The following sample shows what is returned in the body of the HTTP response when
executing an Azure Maps Geocoding Batch API request:

JSON

{
"summary": {
"successfulRequests": 1,
"totalRequests": 2
},
"batchItems": [
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"type": "Address",
"confidence": "High",
"matchCodes": [
"Good"
],
"address": {
"locality": "Redmond",
"adminDistricts": [
{
"shortName": "WA"
},
{
"shortName": "King"
}
],
"countryRegion": {
"ISO": "US",
"name": "United States"
},
"postalCode": "98052",
"formattedAddress": "1 Microsoft Way, Redmond, WA 98052",
"addressLine": "1 Microsoft Way"
},
"geocodePoints": [
{
"geometry": {
"type": "Point",
"coordinates": [
-122.128275,
47.639429
]
},
"calculationMethod": "Rooftop",
"usageTypes": [
"Display",
"Route"
]
},
{
"geometry": {
"type": "Point",
"coordinates": [
-122.127028,
47.638545
]
},
"calculationMethod": "Rooftop",
"usageTypes": [
"Route"
]
}
]
},
"geometry": {
"type": "Point",
"coordinates": [
-122.128275,
47.639429
]
},
"bbox": [
-122.1359181505759,
47.63556628242932,
-122.1206318494241,
47.643291717570676
]
}
]
},
{
"error": {
"code": "Conflicting Parameters",
"message": "When 'query' is present, only the following parameters are
valid: 'bbox, location, view, top'. 'addressLine' was passed"
}
}
]
}

The following sample shows what is returned in the body of the HTTP response when
executing an Azure Maps Reverse Geocoding Batch API request:

JSON

{
"batchItems": [
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.1294081,
47.6391325
]
},
"properties": {
"geocodePoints": [
{
"geometry": {
"type": "Point",
"coordinates": [
-122.1294081,
47.6391325
]
},
"calculationMethod": "Rooftop",
"usageTypes": [
"Display"
]
}
],
"address": {
"addressLine": "15770 NE 31st St",
"adminDistricts": [
{
"shortName": "WA"
},
{
"shortName": "King Co."
}
],
"countryRegion": {
"name": "United States",
"iso": "US"
},
"locality": "Redmond",
"neighborhood": "Overlake",
"postalCode": "98052",
"formattedAddress": "15770 NE 31st St, Redmond, WA
98052, United States"
},
"confidence": "High",
"matchCodes": [
"Good"
],
"type": "Address"
},
"bbox": [
-122.13705120720665,
47.635269782429326,
-122.12176499279336,
47.64299521757068
]
}
]
},
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.341979399674,
47.6095253501216
]
},
"properties": {
"geocodePoints": [
{
"geometry": {
"type": "Point",
"coordinates": [
-122.341979399674,
47.6095253501216
]
},
"calculationMethod": "Interpolation",
"usageTypes": [
"Display",
"Route"
]
}
],
"address": {
"addressLine": "1736 Pike Pl",
"adminDistricts": [
{
"shortName": "WA"
},
{
"shortName": "King Co."
}
],
"countryRegion": {
"name": "United States",
"iso": "US"
},
"intersection": {
"baseStreet": "Pike Pl",
"displayName": "Pike Pl and Stewart St",
"intersectionType": "Near",
"secondaryStreet1": "Stewart St",
"secondaryStreet2": null
},
"locality": "Seattle",
"neighborhood": "Downtown Seattle",
"postalCode": "98101",
"formattedAddress": "1736 Pike Pl, Seattle, WA 98101,
United States"
},
"confidence": "Medium",
"matchCodes": [
"Good"
],
"type": "Address"
},
"bbox": [
-122.34961817972945,
47.605662632550924,
-122.33434061961856,
47.61338806769228
]
}
]
}
],
"summary": {
"successfulRequests": 2,
"totalRequests": 2
}
}

Transactions usage
Similar to Bing Maps Geocode Dataflow API, Azure Maps Geocoding Batch and Reverse
Geocoding Batch APIs log one billable transaction per geocoded item. For example, 100
locations geocoded in the batch request results in 100 billable transactions. For more
information on Azure Maps transactions, see Understanding Azure Maps Transactions.

Additional information
More Azure Maps Geocoding APIs
Get Geocoding: Use to get latitude and longitude coordinates of a street address or
name of a place.
Get Reverse Geocoding: Use to get a street address and location info from latitude and
longitude coordinates.

Support

Microsoft Q&A Forum


Migrate Bing Maps Geodata API
Article • 05/22/2024

This article explains how to migrate the Bing Maps Geodata API to the Azure Maps Get
Polygon API. The Azure Maps Get Polygon API is used to get polygon data of a
geographical area shape such as a city or a country region.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Geodata API supports Atom and JSON response formats. Azure Maps
Get Polygon API supports the GeoJSON response format.
Bing Maps Geodata API returns compressed polygons, which requires the use of a
decompression algorithm to get the polygon coordinates. Azure Maps Get
Polygon API returns polygon coordinates directly in the API response
uncompressed, without the need to use a decompression algorithm.
Bing Maps Geodata API uses coordinates in the latitude/longitude format. Azure
Maps Get Polygon API uses coordinates in the longitude/latitude format, as
defined by GeoJSON .
Bing Maps Geodata API returns more information about polygons that Azure Maps
Get Polygon API doesn't, such as AreaSqKm, BestMapViewBox, NumPoints,
PopulationClass, and WikipediaURL.
Unlike Bing Maps Geodata API, Azure Maps Get Polygon API has a view input
parameter, which is a string that represents an ISO 3166-1 Alpha-2 region/country
code . The view input parameter alters geopolitical disputed borders and labels
to align with the specified user region. For more information, see URI Parameters.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports
specifying a geographic scope, which allows you to limit data residency to the
European (EU) or United States (US) geographic areas (geos). All requests
(including input data) are processed exclusively in the specified geographic area.
For more information, see Azure Maps service geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports
multiple ways to authenticate your API calls, such as a subscription key, Microsoft Entra
ID, and Shared Access Signature (SAS) Token. For more information on security and
authentication in Azure Maps, See Authentication with Azure Maps and the Security
section in the Azure Maps Get Polygon documentation.

Request parameters
The following table lists the Bing Maps Geodata request parameters and the Azure Maps
equivalent:

ノ Expand table

Bing Maps request Azure Maps Required Azure Description


parameter request in Azure Maps data
parameter Maps type

address Not Not Not Azure Maps Get Polygon


supported supported supported API only supports
coordinates as location
input. To get the
coordinates for an address,
you can use the Azure
Maps Get Geocoding API.

culture Request False string In Azure Maps Get Polygon


Header: API, this is the language in
Accept- which search results should
Language be returned. This is
specified in the Azure Maps
request header. For more
information, see Supported
Languages.

entityType resultType True string Here are the Bing Maps


Geodata API to Azure Maps
Get Polygon API entityType
to resultType equivalents:

- AdminDivision1:
adminDistrict
- AdminDivision2:
adminDistrict2
-CountryRegion:
countryRegion
-Neighborhood:
neighborhood
Bing Maps request Azure Maps Required Azure Description
parameter request in Azure Maps data
parameter Maps type

-PopulatedPlace: locality
- Postcode1: postalCode
- Postcode2: postalCode2
- Postcode3: postalCode3
- Postcode4: postalCode4

getAllPolygons Not needed Not Not Azure Maps Get Polygon


needed needed API by default supports
returning all polygons for
the specified resultType .
For example, if you're
requesting the boundary of
the United States, many
polygons that include
Alaska, Hawaii, and various
outlying islands are
returned, not just a single
polygon representing the
main boundary of the
continental United States.

getEntityMetadata Not Not Not


supported supported supported

latitude, longitude coordinates string Bing Maps Geodata API


requires coordinates in
latitude/longitude format.
Azure Maps Get Polygon
API requires
longitude/latitude, as
defined by GeoJSON .

LevelOfDetail resolution False string Here are the Bing Maps


Geodata API to Azure Maps
Get Polygon API
LevelOfDetail to resolution
equivalents:

- 0: small
- 1: medium
- 2: large
- 3: huge

In Azure Maps Get Polygon


API, if resolution isn't
Bing Maps request Azure Maps Required Azure Description
parameter request in Azure Maps data
parameter Maps type

specified, the default is


medium .

preferCuratedPolygons Not Not Not


supported supported supported

responseFormat Not Not Not Azure Maps Get Polygon


supported supported supported API only supported
GeoJSON response format.

userRegion view False string A string that represents an


ISO 3166-1 Alpha-2
region/country code . This
alters geopolitical disputed
borders and labels to align
with the specified user
region. By default, the View
parameter is set to Auto
even if not defined it in the
request. For more
information on available
Views, see Supported
Views.

For more information about the Azure Maps Get Polygon API request parameters, see
URI Parameters.

Request examples
Bing Maps Geodata API request:

HTTP

https://platform.bing.com/geo/spatial/v1/public/Geodata?
SpatialFilter=GetBoundary(40.423432,-3.674974,0,%27PopulatedPlace%27,0,1,%27
en-US%27,%27US%27)&$format=json&key={BingMapsKey}

Azure Maps Get Polygon API request:

HTTP

https://atlas.microsoft.com/search/polygon?api-version=2023-06-
01&coordinates=-3.6749741,40.423432&resultType=locality&resolution=small&sub
scription-key={Your-Azure-Maps-Subscription-key}

Response fields
The following table lists the fields that can appear in the HTTP response when running
the Bing Maps Geodata request and the Azure Maps equivalent:

ノ Expand table

Bing Maps Azure Maps response Description


response

Copyright - properties:
CopyrightURL copyrightURL

Copyright - properties:
Sources geometriesCopyright

CopyrightSource - Not supported


SourceID

CopyrightSource - properties:
SourceName geometriesCopyright -
sourceName

CopyrightSource - properties:
Copyright geometriesCopyright -
copyright

EntityID Not supported

EntityMetadata - Not supported


AreaSqKm

EntityMetadata - Not supported


BestMapViewBox

EntityMetadata - Not supported


OfficialCulture

EntityMetadata - Not supported


PopulationClass

EntityMetadata - Not supported


RegionalCulture

EntityMetadata - Not supported


WikipediaURL
Bing Maps Azure Maps response Description
response

Name - properties: name


EntityName

Name - Culture Not supported

Name - SourceID Not supported

Primitives - Not supported


PrimativeID

Primitives - Shape GeometryCollection: Bing Maps Geodata API returns a comma-


geometries - delimited sequence starting with the version
coordinates number of the polygon set followed by a list of
compressed polygon “rings” (closed paths
represented by sequences of latitude/longitude
points). A Bing Maps Geodata API decompression
algorithm is needed to get the polygon
coordinates. Azure Maps Get Polygon API returns
the polygon coordinates directly in the response
uncompressed, with no need to use a
decompression algorithm.

Bing Maps Geodata API returns the coordinates in


latitude/longitude format, whereas Azure Maps
Get Polygon API returns the coordinates in
longitude/latitude format, as defined by
GeoJSON .

Primitives - Not supported


NumPoints

Primitives - Not supported


SourceID

For more information about the Azure Maps Get Polygon API response fields, see
Definitions.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response
when executing the Bing Maps _Geodata _ request:

JSON

{
"d": {
"Copyright": "© 2024 Microsoft and its suppliers. This API and any
results cannot be used or accessed without Microsoft's express written
permission.",
"results": [
{
"__metadata": {
"uri":
"https://platform.bing.com/geo/spatial/v1/public/Geodata?
$filter=GetEntity(5669357583933112321L,0,1,'en-US','US')"
},
"EntityID": "5669357583933112321",
"EntityMetadata": {
"BestMapViewBox": "MULTIPOINT ((-4.4419009 40.0715388),
(-2.9696372 40.7642994))",
"EntityType": "PopulatedPlace",
"PopulationClass": "PopClassOver1000000",
"WikipediaURL": "http://en.wikipedia.org/wiki/Madrid"
},
"Name": {
"EntityName": "Madrid",
"Culture": "en",
"SourceID": "133"
},
"Primitives": [
{
"PrimitiveID": "5669358580365524997",
"Shape":
"1,wskhomqijBsslyC84lmC8tiEh28BrsmD18kEo48E49pHwvzCujwpBx03Ollo5DnlrQs54Dut_
L51jM19vV2gwHsw3L695Cz_tB7j8Xhn0C_qgJqrsG55ZvlqDpgyDxk1Mkj4G217CmsF_2tFjwnGy
v3Ej4C_zGqzTongEy4qmBw1hR_l9Sg1pd47tO0qhW0mvzB1zoDy56GzjpZol4GhxzGj9uHy3lIq7
lO_7-
Hh2kB3m18B3kBum9VmniGw5hEv2oE1q3Bo8c9p2BywX4mzXnylHsiN_jnG8gJ8n3C489Z_u-
YixqN_oiG561H06uMiqsYxuwBvpgkC7wzEhw2I3gZp3uYn0iQr5wHn7lFr48av2nIwsuhBqgjvB8
5xOql1H8u9bhmZ463F5BrsW28vG48qB4gwN_hmJt74N_3rFsv2C05pF3yrEv51CtlyQggwF3k_Jq
judqt-BopnDw-9Nm89Rt92Jln3O26_UkkmDhzpch4U233Ftk4Eyn3Glv-
lBn5tgB9iyCnnuD7nHn82SixmI0qlpB90sIsjnhBglrVzvxC1l4c0y7d6oiG5qjhB8q3Jg-
jTjwhB9_0Np6xB461YrjpEgg0IlO0kBxwV_tTy3kGpqoGxyoE36_Du9tMj7mEkmnGnzlW0s0BnsC
miKvrC76DkjL0jb9GgiB6htB38pK5z9SqBm9iJs8xBzuqH4-
I6q2Dv5pYp07Iq6gM2pkDqtxC7wkD75sP-
hmMzw4G14Rw9pCunqrBp5qK48nVy62E0xiLu3iIjp_PlwBkmsJnz_E6x8Bj12EqwzhB-
qlgEjppC5rrC09Hp9uB71_Eu-xkB18mBog0P_hlBviD4u9Cvv-7Bv08L9yrR57tK2-
u0C3r4kC31yNvlxCkkogBzjmJ8n82C49nB_j2Z97kX68hT4l6M8x7Huu_Fly1zE36hVry8LvgKqq
iH33hLkrrDu2T5hwEg9oBo2sDmpsEp-
jB2wY9xzCqwsHtxzClz7H_mxCpuVggrC1qjCz_9Gj96BypvHy8qErhpEmt_Z84gM6gpDyyjCm9qB
4yjCp25D03pOo1uBjutCk-
jQq04Kw40H4z0C2_8I34xVzn5iBsi9MkmkM7rqHuyiWp1pDlu9Q4_2yB2_qI4_wMuluHg9rep8rI
4jhlCqwolBip9Nz3xCqx5oBvqhB48kuBhyuW2pmsDswtCtysI0rjEz9oEgp3Cio0FkyjFos80Dj0
8F-x6Xg28boz3a3rtJ79WrrwKu_plBny4C429eng2Hx73FrpEui-yB-qb896Fon7Eyl-
E9mjBqv4E_4wC_34Zxi_By2jH7l_Ol-2yB2zJ85Dnp4mBt5rB4s4FhpI-
7oNvvDkj9JnunBq3xzBp7hxCo9buo8C9wpK4q9F99_L6-3jBg8_Pu9tBx-yUjlwN-
36H7w2xBj8oIlp0bsvkNtusBm-
xjBu37GvmNuwhyC00yCg5axkwCxp5E5ztYn_gQ6mmCq0vb28wSp-
yKzs4Km4sKsooH6_T531B_24GmyhC73vCkkpE8rmMijaj-
xKn7pHxjhB78lOspwB1o3Il_xK75oR69G3jgEy0tDwg_PxkyIm4nF1oyJxkuFk3tCr_yGnj6Iovy
IigMn9nsEuryNt18JvqwhC_3ogBzt9Csm3P_lvBjw3BjjuV4whBpjPzwiC7wUtZt4oE_4xGq-
7hB903OplsDl-6CxkvH4xglBo6pF_z4P-
tEk8Yl0jQ7hf8h1Bj5wBi4M1qkPx4S365Igp9B3_sRrmS4hjE5wmS00GuzhBs97C5vtB7ktBo50B
-5hDx4vEq0ZjniLskQ8kqpB1m43D1px8DivnG1kqR2-
koB787FjzvBvmrFh0mF3ouI12Z1vL6ijC6w5D8o0Bmcy3d_gE_41C939Iilu9BwhyGrkhBsmkK1-
3sBhtkb09zQ9n0cgqvG4i7rDph6D9p_sDoluPn9oR3s4hC8up7Co-
zgB7uEwtIhj8XyqwhBzpo9B9h76B85phCy6FtmY7p2lBg1tsEukSqzmGvvrlV6llMu1idyh0gEtu
_1Cp23mBt25M-oovB38nG-hhBux4CjqmB7ouCgj-
Fiz0kBl6vctx2Wi1EmpiBy69lBs10Xkz6Dp3dqt97BljoLhooBrznRvt0Fwq2B_26tE4uR15lkB5
_qD8n8wBspu0B2kxN1h1Kg78BisuVw9tPopiT90vF0u7yB8klV",
"NumPoints": "554",
"SourceID": "5"
}
],
"Copyright": {
"CopyrightURL": "http://windows.microsoft.com/en-
us/windows-live/about-bing-data-suppliers",
"Sources": [
{
"SourceID": "5",
"SourceName": "TOM",
"Copyright": "TomTom"
}
]
}
}
]
}
}

The following JSON sample shows what is returned in the body of the HTTP response
when executing an Azure Maps Get Polygon request:

JSON

{
"type":"Feature",
"geometry": {
"type":"GeometryCollection",
"geometries":[ {
"type": "Polygon", "coordinates":[[[-3.59839,
40.312070000000006], [-3.5874500000000005, 40.31273], [-3.5782200000000004,
40.313860000000005], [-3.57622, 40.314800000000005], [-3.5779,
40.314710000000005], [-3.5792400000000004, 40.31566], [-3.5813300000000003,
40.31618], [-3.58387, 40.31588], [-3.5850400000000002, 40.31817], [-3.58442,
40.322100000000006], [-3.5828200000000003, 40.32625], [-3.5794500000000005,
40.32779], [-3.5719300000000005, 40.334360000000004], [-3.5698800000000004,
40.337480000000006], [-3.56958, 40.33966], [-3.5673000000000004,
40.341800000000006], [-3.5653, 40.34425], [-3.5621000000000005, 40.34698],
[-3.5607900000000003, 40.349120000000006], [-3.5583700000000005,
40.351130000000005], [-3.55765, 40.35255], [-3.55656, 40.352990000000005],
[-3.55323, 40.35591], [-3.5530100000000004, 40.36126], [-3.55486, 40.35987],
[-3.5555600000000003, 40.36032], [-3.55602, 40.362190000000005],
[-3.5553200000000005, 40.3639], [-3.5525700000000002, 40.365700000000004],
[-3.5511000000000004, 40.37008], [-3.55119, 40.3731], [-3.55025,
40.375350000000005], [-3.5486600000000004, 40.37711], [-3.54897, 40.38082],
[-3.5455, 40.385270000000006], [-3.5435800000000004, 40.388630000000006],
[-3.5424300000000004, 40.393040000000006], [-3.5372800000000004, 40.39126],
[-3.5327900000000003, 40.391630000000006], [-3.5290800000000004, 40.38933],
[-3.5268200000000003, 40.38973], [-3.5241100000000003, 40.39088], [-3.52177,
40.391200000000005], [-3.5203200000000003, 40.39206], [-3.5197700000000003,
40.396150000000006], [-3.5185400000000002, 40.39996], [-3.5180100000000003,
40.402460000000005], [-3.51907, 40.405170000000005], [-3.5190400000000004,
40.40863], [-3.5208600000000003, 40.412040000000005], [-3.52226, 40.41389],
[-3.5244400000000002, 40.415330000000004], [-3.5250900000000005,
40.41630000000001], [-3.5310500000000005, 40.42006000000001],
[-3.5302000000000002, 40.414680000000004], [-3.5327500000000005, 40.41407],
[-3.5351200000000005, 40.414280000000005], [-3.5361300000000004, 40.41264],
[-3.5375900000000002, 40.41241], [-3.5383500000000003, 40.411410000000004],
[-3.5396, 40.411550000000005], [-3.5396400000000003, 40.41049],
[-3.5492500000000002, 40.4123], [-3.5507400000000002, 40.411820000000006],
[-3.55168, 40.412180000000006], [-3.5534700000000004, 40.41174], [-3.55858,
40.41304], [-3.5645100000000003, 40.41351], [-3.57236, 40.411910000000006],
[-3.5774500000000002, 40.41344], [-3.5796400000000004, 40.417570000000005],
[-3.5754400000000004, 40.42549], [-3.5777300000000003, 40.42595],
[-3.5767100000000003, 40.428700000000006], [-3.5768500000000003, 40.42969],
[-3.57934, 40.433530000000005], [-3.57487, 40.43419], [-3.5757800000000004,
40.43679], [-3.5737600000000005, 40.43768], [-3.5685800000000003,
40.436220000000006], [-3.5660900000000004, 40.43773], [-3.5602600000000004,
40.43816], [-3.5520000000000005, 40.441520000000004], [-3.54245, 40.44332],
[-3.5411400000000004, 40.44371], [-3.5407, 40.444500000000005],
[-3.5380900000000004, 40.444160000000004], [-3.53838, 40.44502000000001],
[-3.5355600000000003, 40.44471], [-3.5349600000000003, 40.44496],
[-3.5352200000000003, 40.44635], [-3.5311200000000005, 40.446870000000004],
[-3.53291, 40.44896000000001], [-3.53433, 40.452510000000004],
[-3.5321300000000004, 40.454600000000006], [-3.53094, 40.4547],
[-3.5287400000000004, 40.454100000000004], [-3.5267800000000005, 40.45497],
[-3.5265400000000002, 40.456070000000004], [-3.5290500000000002,
40.45863000000001], [-3.5294800000000004, 40.460890000000006], [-3.52821,
40.46406], [-3.5250100000000004, 40.467800000000004], [-3.5250100000000004,
40.46904000000001], [-3.52653, 40.470380000000006], [-3.53066,
40.471610000000005], [-3.5324000000000004, 40.47471], [-3.5342000000000002,
40.476150000000004], [-3.5351000000000004, 40.48091], [-3.5373200000000002,
40.484550000000006], [-3.53696, 40.486470000000004], [-3.5413300000000003,
40.488910000000004], [-3.54171, 40.48977], [-3.5414900000000005, 40.49244],
[-3.5424900000000004, 40.49452], [-3.5450100000000004, 40.49618],
[-3.5505700000000004, 40.49795], [-3.5556200000000002, 40.501340000000006],
[-3.5548300000000004, 40.50303], [-3.5552500000000005, 40.503220000000006],
[-3.55514, 40.50864000000001], [-3.55426, 40.51142], [-3.56225,
40.511190000000006], [-3.5650100000000005, 40.51214], [-3.5720400000000003,
40.51249000000001], [-3.5757200000000005, 40.51057], [-3.57797,
40.510450000000006], [-3.58292, 40.50853], [-3.58475, 40.506780000000006],
[-3.5891300000000004, 40.504580000000004], [-3.5933300000000004, 40.50141],
[-3.60279, 40.501430000000006], [-3.6035200000000005, 40.502010000000006],
[-3.60591, 40.50435], [-3.6058000000000003, 40.50583], [-3.61005, 40.50784],
[-3.61085, 40.50883], [-3.6126300000000002, 40.509310000000006], [-3.61513,
40.511120000000005], [-3.6181400000000004, 40.51024], [-3.62109, 40.51026],
[-3.6228900000000004, 40.50918], [-3.6257, 40.509530000000005],
[-3.6285000000000003, 40.50851], [-3.6310900000000004, 40.50855000000001],
[-3.63322, 40.50773], [-3.6420500000000002, 40.508320000000005],
[-3.6449300000000004, 40.508100000000006], [-3.6481000000000003, 40.51057],
[-3.65241, 40.511230000000005], [-3.6547400000000003, 40.512930000000004],
[-3.6560400000000004, 40.51317], [-3.6578000000000004, 40.51156],
[-3.6586000000000003, 40.51176], [-3.6591000000000005, 40.513720000000006],
[-3.66155, 40.51758], [-3.6628600000000002, 40.52008], [-3.6661500000000005,
40.52123], [-3.6655400000000005, 40.52299], [-3.6658800000000005,
40.52460000000001], [-3.6676100000000003, 40.52514], [-3.67201,
40.52451000000001], [-3.6752200000000004, 40.52577], [-3.6772000000000005,
40.527120000000004], [-3.67104, 40.53211], [-3.66923, 40.53457],
[-3.6720200000000003, 40.537560000000006], [-3.6740800000000005, 40.5384],
[-3.67559, 40.540980000000005], [-3.6779200000000003, 40.542930000000005],
[-3.67871, 40.54553000000001], [-3.67857, 40.546760000000006],
[-3.6824000000000003, 40.551170000000006], [-3.6823600000000005,
40.554010000000005], [-3.6853300000000004, 40.558530000000005],
[-3.6868600000000002, 40.56322], [-3.68948, 40.5688], [-3.6893100000000003,
40.57056], [-3.69043, 40.56996], [-3.6905900000000003, 40.569230000000005],
[-3.6914100000000003, 40.56996], [-3.69498, 40.57374], [-3.69695,
40.575010000000006], [-3.6982200000000005, 40.57696000000001],
[-3.6998300000000004, 40.578140000000005], [-3.70155, 40.57826],
[-3.7015100000000003, 40.578610000000005], [-3.6993300000000002, 40.5786],
[-3.6914100000000003, 40.58059], [-3.6888600000000005, 40.58245], [-3.6846,
40.58352], [-3.6821200000000003, 40.585170000000005], [-3.66745,
40.592020000000005], [-3.6621400000000004, 40.59212], [-3.6605600000000003,
40.591660000000005], [-3.65614, 40.58881], [-3.6546200000000004,
40.586450000000006], [-3.6510300000000004, 40.57811], [-3.6502700000000003,
40.57744], [-3.64753, 40.57694], [-3.6442900000000003, 40.576930000000004],
[-3.6399200000000005, 40.575140000000005], [-3.6350100000000003, 40.57446],
[-3.6306200000000004, 40.574650000000005], [-3.628, 40.57368],
[-3.6249900000000004, 40.57379], [-3.6163200000000004, 40.580670000000005],
[-3.6118600000000005, 40.582080000000005], [-3.6089700000000002,
40.583600000000004], [-3.6087700000000003, 40.58411], [-3.60644, 40.58518],
[-3.6049700000000002, 40.58796], [-3.6035200000000005, 40.58885],
[-3.6023300000000003, 40.59010000000001], [-3.6018200000000005,
40.59207000000001], [-3.6035200000000005, 40.593120000000006], [-3.60483,
40.59449], [-3.6052100000000005, 40.59644], [-3.6069100000000005,
40.596810000000005], [-3.60876, 40.598440000000004], [-3.6105400000000003,
40.59873], [-3.61296, 40.599900000000005], [-3.61642, 40.601490000000005],
[-3.61614, 40.603060000000006], [-3.6171, 40.605470000000004], [-3.61683,
40.606930000000006], [-3.61837, 40.60889], [-3.6179500000000004, 40.61113],
[-3.61987, 40.61186], [-3.6224600000000002, 40.615790000000004],
[-3.6265000000000005, 40.61688], [-3.6285300000000005, 40.61834],
[-3.6286000000000005, 40.61975], [-3.6294500000000003, 40.620760000000004],
[-3.6287900000000004, 40.62259], [-3.6301500000000004, 40.626070000000006],
[-3.6296600000000003, 40.627610000000004], [-3.63011, 40.62854],
[-3.6328600000000004, 40.630930000000006], [-3.63756, 40.63797],
[-3.6387600000000004, 40.638670000000005], [-3.6444, 40.638360000000006],
[-3.6486500000000004, 40.64166], [-3.65201, 40.642900000000004],
[-3.6556100000000002, 40.64352], [-3.6584000000000003, 40.642340000000004],
[-3.6616000000000004, 40.63976], [-3.66725, 40.63143], [-3.6682900000000003,
40.62917], [-3.6684500000000004, 40.62632000000001], [-3.6670000000000003,
40.623070000000006], [-3.6666800000000004, 40.6199], [-3.6713500000000003,
40.61751], [-3.6743400000000004, 40.61679], [-3.6793000000000005,
40.611110000000004], [-3.6849800000000004, 40.60897000000001],
[-3.6875000000000004, 40.6069], [-3.6883100000000004, 40.605470000000004],
[-3.6910900000000004, 40.60007], [-3.6914100000000003, 40.59908],
[-3.6963100000000004, 40.590090000000004], [-3.7053400000000005,
40.584920000000004], [-3.7052000000000005, 40.583070000000006],
[-3.7083600000000003, 40.58362], [-3.7104800000000004, 40.58314],
[-3.7130000000000005, 40.583270000000006], [-3.7145, 40.58265], [-3.71729,
40.5829], [-3.71938, 40.58209], [-3.7301, 40.585210000000004], [-3.73342,
40.58536], [-3.73722, 40.58615], [-3.73815, 40.58652], [-3.74073,
40.590700000000005], [-3.7458000000000005, 40.59225], [-3.7492600000000005,
40.59272], [-3.7501100000000003, 40.59248], [-3.7528900000000003,
40.594750000000005], [-3.75842, 40.596140000000005], [-3.75979,
40.597030000000004], [-3.7658500000000004, 40.598560000000006], [-3.76813,
40.599610000000006], [-3.7705100000000003, 40.599920000000004],
[-3.7782800000000005, 40.601760000000006], [-3.7793, 40.60159],
[-3.7816500000000004, 40.600840000000005], [-3.7828700000000004,
40.601760000000006], [-3.7835400000000003, 40.60177], [-3.7851000000000004,
40.60047], [-3.7863700000000002, 40.600390000000004], [-3.7898300000000003,
40.59901], [-3.79537, 40.599970000000006], [-3.7970400000000004, 40.59985],
[-3.7991200000000003, 40.598510000000005], [-3.8035500000000004,
40.599030000000006], [-3.8003000000000005, 40.604890000000005],
[-3.8004200000000004, 40.605470000000004], [-3.8005000000000004,
40.605830000000005], [-3.8061100000000003, 40.60783], [-3.80628, 40.60947],
[-3.8091000000000004, 40.609280000000005], [-3.80954, 40.60987],
[-3.8126900000000004, 40.608180000000004], [-3.8101800000000003,
40.606640000000006], [-3.80967, 40.605470000000004], [-3.80608, 40.59987],
[-3.8126, 40.596830000000004], [-3.81436, 40.595420000000004], [-3.81612,
40.595000000000006], [-3.8202000000000003, 40.59503], [-3.8226800000000005,
40.594390000000004], [-3.8278200000000004, 40.59465], [-3.8332400000000004,
40.593560000000004], [-3.83557, 40.59203], [-3.8377200000000005, 40.59138],
[-3.8404700000000003, 40.592400000000005], [-3.84323, 40.592510000000004],
[-3.8456300000000003, 40.591370000000005], [-3.85007, 40.59049], [-3.85489,
40.588010000000004], [-3.85991, 40.5882], [-3.8635900000000003, 40.58953],
[-3.8658500000000005, 40.591640000000005], [-3.8671900000000003, 40.59208],
[-3.86729, 40.59214], [-3.8739000000000003, 40.591150000000006],
[-3.8761500000000004, 40.59004], [-3.8761, 40.589270000000006],
[-3.8769000000000005, 40.588620000000006], [-3.8836600000000003,
40.585260000000005], [-3.8835100000000002, 40.582550000000005],
[-3.8842600000000003, 40.58127], [-3.8839200000000003, 40.578430000000004],
[-3.8857000000000004, 40.574250000000006], [-3.88844, 40.572210000000005],
[-3.8890000000000002, 40.570870000000006], [-3.8869700000000003,
40.566190000000006], [-3.88384, 40.563810000000004], [-3.8850200000000004,
40.560790000000004], [-3.88228, 40.55948], [-3.8782400000000004, 40.55939],
[-3.8754500000000003, 40.558730000000004], [-3.8751500000000005,
40.558020000000006], [-3.87393, 40.55758], [-3.8729700000000005, 40.55521],
[-3.8728800000000003, 40.553470000000004], [-3.8706600000000004, 40.55102],
[-3.86905, 40.5482], [-3.86939, 40.54733], [-3.8671900000000003,
40.545440000000006], [-3.8656200000000003, 40.54355], [-3.8655000000000004,
40.542370000000005], [-3.8638500000000002, 40.53931], [-3.86296,
40.534740000000006], [-3.86059, 40.53295000000001], [-3.85807,
40.530150000000006], [-3.8576, 40.52788], [-3.8561000000000005,
40.527010000000004], [-3.8536200000000003, 40.52438], [-3.8543900000000004,
40.5214], [-3.8533500000000003, 40.519510000000004], [-3.8513200000000003,
40.51758], [-3.8522300000000005, 40.5155], [-3.8533600000000003,
40.514430000000004], [-3.8540000000000005, 40.51198], [-3.8523700000000005,
40.509640000000005], [-3.8370800000000003, 40.50585], [-3.8386500000000003,
40.502700000000004], [-3.8393800000000002, 40.4994], [-3.8345200000000004,
40.49416], [-3.83319, 40.487770000000005], [-3.8341800000000004,
40.484190000000005], [-3.8366700000000002, 40.480920000000005],
[-3.8373800000000005, 40.4757], [-3.8362100000000003, 40.474680000000006],
[-3.8374400000000004, 40.47303], [-3.8381100000000004, 40.47091],
[-3.8382400000000003, 40.467760000000006], [-3.8342400000000003,
40.464310000000005], [-3.8309300000000004, 40.46591], [-3.8289600000000004,
40.46629], [-3.8271100000000002, 40.46598], [-3.8247700000000004, 40.46482],
[-3.8173900000000005, 40.46441], [-3.8151500000000005, 40.4637],
[-3.8128800000000003, 40.463710000000006], [-3.81056, 40.46419],
[-3.8104800000000005, 40.464580000000005], [-3.8051100000000004,
40.463680000000004], [-3.8047400000000002, 40.462790000000005],
[-3.8033300000000003, 40.46255], [-3.8026800000000005, 40.46162],
[-3.8014600000000005, 40.461310000000005], [-3.7987800000000003, 40.45875],
[-3.7958800000000004, 40.45785], [-3.7954700000000003, 40.45649],
[-3.7928900000000003, 40.45382], [-3.7933100000000004, 40.4532],
[-3.7922100000000003, 40.451710000000006], [-3.7910500000000003, 40.44785],
[-3.79036, 40.447700000000005], [-3.7901700000000003, 40.446580000000004],
[-3.7888200000000003, 40.44576], [-3.7892200000000003, 40.444630000000004],
[-3.7886, 40.44373], [-3.7874600000000003, 40.444230000000005],
[-3.7831300000000003, 40.44431], [-3.78257, 40.44511000000001], [-3.7793,
40.444120000000005], [-3.7775000000000003, 40.44368], [-3.7706800000000005,
40.4436], [-3.7707800000000002, 40.42969], [-3.7793, 40.42392],
[-3.7804100000000003, 40.42183], [-3.78141, 40.417500000000004], [-3.7793,
40.411500000000004], [-3.7788100000000004, 40.40889000000001], [-3.77633,
40.403960000000005], [-3.7744000000000004, 40.40204000000001], [-3.77457,
40.40021], [-3.7760900000000004, 40.40001], [-3.7776300000000003, 40.39905],
[-3.7781100000000003, 40.39764], [-3.7793, 40.39717], [-3.78195, 40.39397],
[-3.7854, 40.393080000000005], [-3.79042, 40.392320000000005], [-3.79246,
40.39356], [-3.7937600000000002, 40.393550000000005], [-3.79646, 40.39217],
[-3.7989100000000002, 40.39211], [-3.8048800000000003, 40.39202],
[-3.8108600000000004, 40.39271], [-3.8148500000000003, 40.39394],
[-3.8193400000000004, 40.396300000000004], [-3.8210100000000002, 40.39652],
[-3.8350800000000005, 40.396100000000004], [-3.8335100000000004, 40.39491],
[-3.8279500000000004, 40.387370000000004], [-3.82547, 40.384820000000005],
[-3.82343, 40.381400000000006], [-3.8183800000000003, 40.37621],
[-3.8128800000000003, 40.36948], [-3.8104700000000005, 40.36366],
[-3.8070100000000004, 40.36645], [-3.80283, 40.363220000000005],
[-3.7945200000000003, 40.36151], [-3.78764, 40.35857], [-3.7793, 40.36222],
[-3.7733300000000005, 40.359860000000005], [-3.7718400000000005,
40.359590000000004], [-3.7716300000000005, 40.35985], [-3.7607600000000003,
40.357730000000004], [-3.75992, 40.357940000000006], [-3.75768, 40.35712],
[-3.73579, 40.36202], [-3.7273400000000003, 40.36455], [-3.72102, 40.36513],
[-3.7240800000000003, 40.341800000000006], [-3.72494, 40.33469],
[-3.7241100000000005, 40.33348], [-3.72068, 40.331], [-3.71504,
40.328010000000006], [-3.7147900000000003, 40.32705], [-3.71315, 40.32616],
[-3.71253, 40.323690000000006], [-3.70325, 40.32209], [-3.6966200000000002,
40.32229], [-3.6933100000000003, 40.32045], [-3.6920800000000003,
40.320240000000005], [-3.6914100000000003, 40.320890000000006],
[-3.6849600000000002, 40.322320000000005], [-3.6821800000000002, 40.32361],
[-3.6809700000000003, 40.32446], [-3.6803700000000004, 40.325630000000004],
[-3.6792000000000002, 40.32623], [-3.67403, 40.32574], [-3.6703600000000005,
40.324940000000005], [-3.6681600000000003, 40.325520000000004],
[-3.6639600000000003, 40.32883], [-3.66305, 40.328860000000006],
[-3.6611300000000004, 40.32771], [-3.6598300000000004, 40.327690000000004],
[-3.6500200000000005, 40.332150000000006], [-3.6490700000000005,
40.333110000000005], [-3.6442200000000002, 40.33034000000001],
[-3.6430900000000004, 40.32905], [-3.6373100000000003, 40.325880000000005],
[-3.6323600000000003, 40.321740000000005], [-3.6292000000000004, 40.32001],
[-3.6260600000000003, 40.31897], [-3.6251800000000003, 40.31985], [-3.62447,
40.31992], [-3.6199800000000004, 40.319120000000005], [-3.6162600000000005,
40.31781], [-3.6133400000000004, 40.31514000000001], [-3.61119,
40.31429000000001], [-3.6035200000000005, 40.312830000000005], [-3.59839,
40.312070000000006]]]
}
]
}
,
"properties": {

"name":"Madrid",
"copyright":"© 2024 Microsoft and its suppliers. This API and any
results cannot be used or accessed without Microsoft's express written
permission.",
"copyrightURL":"https://azure.microsoft.com/support/legal/preview-
supplemental-terms/",
"geometriesCopyright":[ {
"sourceName": "TOM", "copyright":"TomTom"
}

]
}
}

Transactions usage
Like Bing Maps Geodata API, Azure Maps Get Polygon API logs one billable transaction
per request. For more information on Azure Maps transactions, see Understanding
Azure Maps Transactions.

Additional information
Azure Maps Get Geocoding API: Use to get latitude and longitude coordinates of a
street address or name of a place.
Azure Maps Get Geocoding Batch API: Use to send a batch of queries to the Azure
Maps Get Geocoding API in a single request.

Support

Microsoft Q&A Forum


Migrate Bing Maps Find Time Zone API
Article • 05/17/2024

This article explains how to migrate from the Bing Maps Find Time Zone API to the
Azure Maps Get Timezone By Coordinates API. The Azure Maps Get Timezone By
Coordinates API returns current, historical, and future time zone information for a
specified latitude-longitude pair, as well as sunset and sunrise times for a given location.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Bing Maps Find Time Zone API supports coordinates and location place name,
administrative region, and country/region name as location input. Azure Maps Get
Timezone By Coordinates API only supports coordinates. To get the coordinates for
location place name, administrative region, and country/region name, you can use
the Azure Maps Get Geocoding API.
Bing Maps Find Time Zone API supports both XML and JSON response formats,
Azure Maps Get Timezone By Coordinates API only supports JSON.
Bing Maps Find Time Zone API doesn't offer sunrise and sunset values for a given
time zone, the Azure Maps Get Time Zone By Coordinates API does.
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports
specifying a geographic scope, which allows you to limit data residency to the
European (EU) or United States (US) geographic areas (geos). All requests
(including input data) are processed exclusively in the specified geographic area.
For more information, see Azure Maps service geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports
multiple ways to authenticate your API calls, such as a subscription key, Microsoft Entra
ID, or Shared Access Signature (SAS) Token. For more information on security and
authentication in Azure Maps, See Authentication with Microsoft Azure Maps and the
Security section in the Azure Maps Get Time Zone By Coordinates documentation.
Request parameters
The following table lists the Bing Maps Find Time Zone request parameters and the
Azure Maps equivalent:

ノ Expand table

Bing Maps Bing Azure Maps Required Azure Maps Description


Parameter Maps Parameter in Azure Data Type
Parameter Maps
Alias

dateTime dt timeStamp False string date- Alternatively, use


time alias "stamp", or
"s". Reference
time, if omitted,
the API uses the
machine time
serving the
request.

IncludeDstRules None transitionsFrom False string date- The start date


time from which
daylight savings
time (DST)
transitions are
requested, only
applies when
"options" = all or
"options" =
transitions. See
options (Timezone
Options)
parameter for
more info.

output o format True JSONFormat Only JSON format


is supported in
this Azure Maps
API.

point None query True number Coordinates of the


point for which
time zone
information is
requested. This
parameter is a list
of coordinates,
containing a pair
Bing Maps Bing Azure Maps Required Azure Maps Description
Parameter Maps Parameter in Azure Data Type
Parameter Maps
Alias

of coordinate
values (lat, long).
When this
endpoint is called
directly,
coordinates are
passed in as a
single string
containing
coordinates,
separated by
commas.

query q Not supported Not Not Only coordinates


supported supported of the point for
which time zone
information is
requested are
supported.
Location types
such as address,
locality, postal
code, etc. aren't
supported. To get
the coordinates
for location place
name,
administrative
region, and
country/region
name, you can use
the Azure Maps
Get Geocoding
API.

For more information, see the Azure Maps Get Timezone By Coordinates URI
Parameters.

Request examples
Bing Maps Find Time Zone API request:

HTTP
https://dev.virtualearth.net/REST/v1/timezone/37.7800,-122.4201?
key=%7bBingMapsKey%7d

Azure Maps Get Time Zone by Coordinates API request:

HTTP

https://atlas.microsoft.com/timezone/byCoordinates/json?api-
version=1.0&query=37.7800,-122.4201

Response fields
The following table lists the fields that can appear in the HTTP response when running
the Bing Maps Find Time Zone API and the Azure Maps equivalent:

ノ Expand table

Bing Maps Response Azure Maps Response Field


Field

abbreviation (JSON) ReferenceTime (Tag)


Abbreviation (XML)

convertedTime (JSON) ReferenceTime (WallTime)


ConvertedTime (XML)

dstRule (JSON) TimeTransitions


DSTRule (XML)

genericName (JSON) TimezoneNames


GenericName (XML)

ianaTimeZoneId (JSON) ID
IANATimeZoneID (XML)

utcOffset (JSON) ReferenceTime (StandardOffset)


UTCOffset (XML)

windowsTimeZoneID Not supported. Use Azure Maps Get Timezone Enum Windows API to
(JSON) convert to Windows time zone.
WindowsTimeZoneID
(XML)

For more information about the Azure Maps Get Timezone By Coordinates response
fields, see the response Definitions.
Response examples
The following JSON shows a sample of what is returned in the body of the HTTP
response when executing the Bing Maps Find Time Zone API request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri":
"https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights
reserved. This API cannot be accessed and the content and any results may
not be used, reproduced or transmitted in any manner without express written
permission from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal": 1,
"resources": [
{
"__type":
"RESTTimeZone:http://schemas.microsoft.com/search/local/ws/rest/v1",
"timeZone": {
"genericName": "Pacific Standard Time",
"abbreviation": "PST",
"ianaTimeZoneId": "America/Los_Angeles",
"windowsTimeZoneId": "Pacific Standard Time",
"utcOffset": "-8:00",
"convertedTime": {
"localTime": "2024-02-11T14:21:58",
"utcOffsetWithDst": "-8:00",
"timeZoneDisplayName": "Pacific Standard Time",
"timeZoneDisplayAbbr": "PST"
}
}
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "f02637665942c8cb21c8414bd03224aa|MWH0032BEF|0.0.0.1"
}

The following sample shows what is returned in the body of the HTTP response when
executing an Azure Maps Get Time Zone By Coordinates API request:

JSON

{
"Version": "2023d",
"ReferenceUtcTimestamp": "2024-02-11T22:32:29.4282815Z",
"TimeZones": [
{
"Id": "America/Los_Angeles",
"Aliases": [
"US/Pacific"
],
"Countries": [
{
"Name": "United States",
"Code": "US"
}
],
"Names": {
"ISO6391LanguageCode": "en",
"Generic": "Pacific Time",
"Standard": "Pacific Standard Time",
"Daylight": "Pacific Daylight Time"
},
"ReferenceTime": {
"Tag": "PST",
"StandardOffset": "-08:00:00",
"DaylightSavings": "00:00:00",
"WallTime": "2024-02-11T14:32:29.4282815-08:00",
"PosixTzValidYear": 2024,
"PosixTz": "PST+8PDT,M3.2.0,M11.1.0",
"Sunrise": "2024-02-11T07:04:33.6950704-08:00",
"Sunset": "2024-02-11T17:43:15.3679015-08:00"
},
"RepresentativePoint": {
"Latitude": 34.05222222222222,
"Longitude": -118.24277777777777
},
"TimeTransitions": [
{
"Tag": "PST",
"StandardOffset": "-08:00:00",
"DaylightSavings": "00:00:00",
"UtcStart": "2023-11-05T09:00:00Z",
"UtcEnd": "2024-03-10T10:00:00Z"
},
{
"Tag": "PDT",
"StandardOffset": "-08:00:00",
"DaylightSavings": "01:00:00",
"UtcStart": "2024-03-10T10:00:00Z",
"UtcEnd": "2024-11-03T09:00:00Z"
},
{
"Tag": "PST",
"StandardOffset": "-08:00:00",
"DaylightSavings": "00:00:00",
"UtcStart": "2024-11-03T09:00:00Z",
"UtcEnd": "2025-03-09T10:00:00Z"
}
]
}
]
}

Transactions usage
Similar to Bing Maps for Enterprise Find Time Zone API, the Azure Maps Get Timezone
By Coordinates API logs one billable transaction per API request. For more information
on Azure Maps transactions, see Understanding Azure Maps Transactions.

Additional information
More Azure Maps Timezone APIs

Get Timezone By ID
Get Timezone Enum IANA
Get Timezone Enum Windows
Get Timezone IANA Version
Get Timezone Windows To IANA

Support

Microsoft Q&A Forum


Migrate Bing Maps Get Traffic Incidents API
Article • 04/09/2025

This article explains how to migrate the Bing Maps Get Traffic Incidents API to the Azure Maps
Get Traffic Incident Detail API. The Azure Maps Get Traffic Incident Detail API provides data on
construction, road closures, accidents, and other incidents that can affect traffic, and is updated
every minute.

Prerequisites
An Azure Account
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Notable differences
Azure Maps Get Traffic Incident Detail API is designed to display traffic incidents on map
tiles.
Azure Maps requires boundingZoom to be specified in addition to boundingbox .
boundingZoom is the zoom level (0 - 22) for raster and vector tiles.

Azure Maps requires style to be specified. The style that is used to render the tile in
Azure Maps [Traffic Incident Tile] API. This affects the coordinates of traffic incidents in the
reply.
Azure Maps requires a number referencing traffic model ( trafficModelId ), obtained from
the Azure Maps Get Traffic Incident Viewport API. It updates every minute and is valid for
two minutes before it times out. If the wrong Traffic Model ID is specified, the interface
returns the correct value. As an alternative to using the Azure Maps Get Traffic Incident
Viewport API, passing a value of -1 for Traffic Model ID in the Azure Maps Traffic Incident
Tile request always invokes the most recent traffic model.
Bing Maps Get Traffic Incidents API supports specifying traffic incident severity and types
in the request. The Azure Maps Get Traffic Incident Detail API instead returns all traffic
incident severity and types by default in the response.
Azure Maps Get Traffic Incident Detail API generally provides more details regarding
traffic delays than the Bing Maps Get Traffic Incidents API. Specifically, in Azure Maps, the
dl output provides delay time in seconds that the traffic incident caused, and the

DelayMagnitude output provides the magnitude of delay associated with incident (these
values correspond to incident colors in the traffic tiles).
Unlike Bing Maps for Enterprise, Azure Maps is a global service that supports specifying a
geographic scope, which allows you to limit data residency to the European (EU) or
United States (US) geographic areas (geos). All requests (including input data) are
processed exclusively in the specified geographic area. For more information, see Azure
Maps service geographic scope.

Security and authentication


Bing Maps for Enterprise only supports API key authentication. Azure Maps supports multiple
ways to authenticate your API calls, such as a subscription key, Microsoft Entra ID, or Shared
Access Signature (SAS) Token. For more information on security and authentication in Azure
Maps, See Authentication with Azure Maps and the Security section in the Azure Maps Get
Traffic Incident Detail documentation.

Request parameters
The following table lists the Bing Maps Get Traffic Incidents request parameters and the Azure
Maps equivalent:

ノ Expand table

Bing Maps Bing Maps Azure Maps Required Azure Description


request request request in Azure Maps
parameter parameter parameter Maps data
alias type

mapArea boundingbox True number[] The projection used to


specify the boundingbox
coordinates in the request
and response is
EPSG900913 (default) or
EPSG4326. Use
projection=EPSG4326 for
compatibility with the
coordinates projection
used in the Bing Maps Get
Traffic Incidents API.

culture c language False string ISO 639-1 code for the


output language. For
more information,
see Azure Maps
Supported Languages.

includeJamcidents Not Not Not Azure Maps returns


supported supported supported abnormal traffic
conditions by default.
Bing Maps Bing Maps Azure Maps Required Azure Description
request request request in Azure Maps
parameter parameter parameter Maps data
alias type

severity s Not Not Not Azure Maps returns traffic


supported supported supported incidents of all levels of
severity by default.

type t Not Not Not Azure Maps returns traffic


supported supported supported incidents of all types by
default.

For more information about the Azure Maps request parameters, see URI Parameters in the
Azure Maps Get Traffic Incident Detail API documentation.

Request examples
Bing Maps Get Traffic Incidents API request:

HTTP

http://dev.virtualearth.net/REST/v1/Traffic/Incidents/37.8203,-122.2763,37.8321,-1
22.2542?key={Your-Bing-Maps-Key}

Azure Maps Get Traffic Incident Detail API request:

HTTP

http://atlas.microsoft.com/traffic/incident/detail/json?api-
version=1.0&style=s3&boundingbox=37.8203,-122.2763,37.8321,-122.2542&boundingZoom=
11&projection=EPSG4326&trafficmodelid=-1&subscription-key={Your-Azure-Maps-
Subscription-key}

Response fields
The following table lists the fields that can appear in the HTTP response when running the Bing
Maps Get Traffic Incidents API and the Azure Maps equivalent:

ノ Expand table
Bing Maps response Azure Maps Description
field response field

Description (JSON) d This output is in the tm response element of Azure Maps.


Description (XML)

End (JSON) ed This output is in the tm response element of Azure Maps. The
EndTimeUTC (XML) date is described in the ISO8601 format and includes time in
UTC.

eventList (JSON) Not supported


EventList (XML)

icon (JSON) ic This output is in the tm response element of Azure Maps. See
Icon (XML) IconCategory ( ic ) for more info.

incidentId (JSON) id This output is in the tm response element of Azure Maps.


IncidentId (XML)

isEndTimeBackfilled Not supported


(JSON)
IsEndTimeBackfilled
(XML)

isJamcident (JSON) Not supported


IsJamcident (XML)

lastModified (JSON) Not supported


LastModifiedUTC
(XML)

point (JSON) p This output is in the tm response element of Azure Maps. See
Point (XML) point ( p ) for more info.

roadClosed (JSON) See The IconCategory output of the tm response element of Azure
RoadClosed (XML) description Maps can be used to indicate a road closure.

severity (JSON) ty This output is in the tm response element. See DelayMagnitude:


Severity (XML) ( ty ) for more info.

severityScore (JSON) Not supported


SeverityScore (XML)

Start (JSON) sd This output is in the tm response element of Azure Maps. The
StartTimeUTC (XML) date is described in the ISO8601 format and includes time in
UTC.

title (JSON) See The f output in the tm response element of Azure Maps
Title (XML) description provides the name of the intersection or location where the
Bing Maps response Azure Maps Description
field response field

traffic caused by the the incident starts and can serve as an


alternative to the Bing Maps title output.

toPoint (JSON) See The t output in the tm response element of Azure Maps
ToPoint (XML) description provides the name of the intersection or location where the
traffic due to the incident ends and can serve as an alternative
to the Bing Maps toPoint output.

type (JSON) c The c output in the tm response element of Azure Maps


Type (XML) provides the cause of the incident, if available.

For more information about the Azure Maps Get Traffic Incident Detail API response fields, see
Responses.

Response examples
The following JSON sample shows what is returned in the body of the HTTP response when
executing the Bing Maps Get Traffic Incidents request:

JSON

{
"authenticationResultCode": "ValidCredentials",
"brandLogoUri": "https://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright": "Copyright © 2024 Microsoft and its suppliers. All rights
reserved. This API cannot be accessed and the content and any results may not be
used, reproduced or transmitted in any manner without express written permission
from Microsoft Corporation.",
"resourceSets": [
{
"estimatedTotal: 1,
"resources": [
{
"__type":
"TrafficIncident:http://schemas.microsoft.com/search/local/ws/rest/v1",
"point": {
"type": "Point",
"coordinates": [
37.824025,
-122.265829
]
},
"alertCCodes": [
10
],
"delay": 0,
"description": "Flooding on Telegraph Ave from I-580/W
MacArthur Blvd to W MacArthur Blvd.",
"end": "/Date(1711764788159)/",
"eventList": [
907
],
"icon": 0,
"incidentId": 14648704852012000,
"isEndTimeBackfilled": true,
"isJamcident": false,
"lastModified": "/Date(1711757588159)/",
"roadClosed": false,
"severity": 4,
"severityScore": 79,
"source": 5,
"start": "/Date(1711749960000)/",
"title": "Telegraph Ave",
"toPoint": {
"type": "Point",
"coordinates": [
37.824601,
-122.265675
]
},
"type": 5,
"verified": true
}
]
}
],
"statusCode": 200,
"statusDescription": "OK",
"traceId": "35657cf08e01f49cd50543aa7d88c139|MWH0032BF3|0.0.0.0"
}

The following JSON sample shows what is returned in the body of the HTTP response when
executing an Azure Maps Get Traffic Incident Detail request:

JSON

{
"tm": {
"@id": "1711765520",
"poi": [
{
"id": "0043f39aed6a43411b869729bc30cba4",
"p": {
"x": -122.2631419,
"y": 37.8235763
},
"ic": 11,
"ty": 0,
"cs": 0,
"d": "Flooding",
"sd": "2024-03-29T22:06:00Z",
"f": "I-580/W MacArthur Blvd (Telegraph Ave)",
"t": "W MacArthur Blvd (Telegraph Ave)",
"l": 66
}
]
}
}

Transactions usage
Like Bing Maps Get Traffic Incidents API, Azure Maps Get Traffic Incident Detail API logs one
billable transaction per request. For more information on Azure Maps transactions, see
Understanding Azure Maps Transactions.

Additional information
Other Azure Maps Traffic APIs

Get Traffic Flow Segment. Use to get information about the speeds and travel times of the
specified section of road.
Get Traffic Flow Tile. Use to get 256 x 256 pixel tiles showing traffic flow.
Get Traffic Incident Tile. Use to get 256 x 256 pixel tiles showing traffic incidents.
Get Traffic Incident Viewport. Use to get legal and technical information for a viewport.

Support

Microsoft Q&A Forum


Tutorial: Migrate from Google Maps to
Azure Maps
Article • 03/31/2025

This article provides insights on how to migrate web, mobile and server-based
applications from Google Maps to the Microsoft Azure Maps platform. This tutorial
includes comparative code samples, migration suggestions, and best practices for
migrating to Azure Maps. This tutorial demonstrates:

" High-level comparison for equivalent Google Maps features available in Azure


Maps.
" What licensing differences to take into consideration.
" How to plan your migration.
" Where to find technical resources and support.

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

An Azure Maps account


A subscription key

7 Note

For more information on authentication in Azure Maps, see Manage authentication


in Azure Maps.

Azure Maps platform overview


Azure Maps provides developers across various industries with robust geospatial
capabilities. These features include frequently updated map data, offering essential
geographic context for web applications. Azure Maps suite of REST APIs provide services
such as Map Rendering, Search, Routing, Traffic, Time Zones, Geolocation, Geofencing,
Map Data, and Weather. The Web SDK supports these operations, ensuring
development is straightforward, adaptable, and portable across multiple platforms.

High-level platform comparison


The table provides a high-level list of Azure Maps features, which correspond to Google
Maps features. This list doesn't show all Azure Maps features. Other Azure Maps
features include: accessibility, geofencing, isochrones, direct map tile access, batch
services, and data coverage comparisons (that is, imagery coverage).

ノ Expand table

Google Maps feature Azure Maps support

Web SDK ✓

REST Service APIs ✓

Directions (Routing) ✓

Distance Matrix ✓

Geocoding (Forward/Reverse) ✓

Geolocation ✓

Nearest Roads ✓

Places Search ✓

Places Details N/A – website & phone number available

Places Photos N/A

Place Autocomplete ✓

Snap to Road ✓

Speed Limits ✓

Static Maps ✓

Static Street View N/A

Time Zone ✓

Maps Embedded API N/A

Map URLs N/A

Google Maps provides basic key-based authentication. Azure Maps provides both basic
key-based authentication and Microsoft Entra authentication. Microsoft Entra
authentication provides more security features, compared to the basic key-based
authentication.
Licensing considerations
When migrating to Azure Maps from Google Maps, consider the following points about
licensing.

Azure Maps charges for the usage of interactive maps, which is based on the
number of loaded map tiles. On the other hand, Google Maps charges for loading
the map control. In the interactive Azure Maps SDKs, map tiles are automatically
cached to reduce the development cost. One Azure Maps transaction is generated
for every 15 map tiles that are loaded. The interactive Azure Maps SDKs uses 512-
pixel tiles, and on average, it generates one or less transactions per page view.
Often, it's more cost effective to replace static map images from Google Maps web
services with the Azure Maps Web SDK. The Azure Maps Web SDK uses map tiles.
Unless the user pans and zooms the map, the service often generates only a
fraction of a transaction per map load. The Azure Maps web SDK has options for
disabling panning and zooming, if desired. Additionally, the Azure Maps web SDK
provides a lot more visualization options than the static map web service.
Azure Maps allows data from its platform to be stored in Azure. Also, data can be
cached elsewhere for up to six months as per the terms of use .

Here are some related resources for Azure Maps:

Azure Maps pricing page


Azure pricing calculator
Azure Maps term of use - included in the Microsoft Online Services Terms.

Suggested migration plan


A high-level migration plan includes.

1. Take inventory of the Google Maps SDKs and services that your application uses.
Verify that Azure Maps provides alternative SDKs and services.
2. If you don't already have one, create an Azure subscription .
3. Create an Azure Maps account and subscription key or Microsoft Entra
authentication.
4. Migrate your application code.
5. Test your migrated application.
6. Deploy your migrated application to production.

Create an Azure Maps account


To create an Azure Maps account and get access to the Azure Maps platform, follow
these steps:

1. If you don't have an Azure subscription, create a free account before you begin.
2. Sign in to the Azure portal .
3. Create an Azure Maps account.
4. Get your Azure Maps subscription key or Microsoft Entra authentication for
enhanced security.

Azure Maps technical resources


Here's a list of useful technical resources for Azure Maps.

Azure Maps product page


Azure Maps product documentation
Azure Maps Web SDK code samples
Azure Maps developer forums
Microsoft learning center shows
Azure Maps Blog
Azure Maps Q&A

Migration support
Developers can seek migration support through the Azure Maps developer forums or
through one of the many Azure support options .

Clean up resources
No resources to be cleaned up.

Next steps
Learn the details of how to migrate your Google Maps application with these articles:

Migrate a web app

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Tutorial: Migrate a web app from
Google Maps
Article • 09/28/2023

Most web apps, which use Google Maps, are using the Google Maps V3 JavaScript SDK.
The Azure Maps Web SDK is the suitable Azure-based SDK to migrate to. The Azure
Maps Web SDK lets you customize interactive maps with your own content and imagery.
You can run your app on both web or mobile applications. This control makes use of
WebGL, allowing you to render large data sets with high performance. Develop with this
SDK using JavaScript or TypeScript. This tutorial demonstrates:

" Load a map
" Localize a map
" Add markers, polylines, and polygons.
" Display information in a popup or info window
" Load and display KML and GeoJSON data
" Cluster markers
" Overlay a tile layer
" Show traffic data
" Add a ground overlay

Also:

" How to accomplish common mapping tasks using the Azure Maps Web SDK.
" Best practices to improve performance and user experience.
" Tips on how to make your application using more advanced features available in
Azure Maps.

If migrating an existing web application, check to see if it's using an open-source map
control library. Examples of open-source map control library are: Cesium, Leaflet, and
OpenLayers. You can still migrate your application, even if it uses an open-source map
control library, and you don't want to use the Azure Maps Web SDK. In such case,
connect your application to the Azure Maps Render services (road tiles | satellite tiles).
The following points detail on how to use Azure Maps in some commonly used open-
source map control libraries.

Cesium - A 3D map control for the web. Cesium documentation .


Leaflet – Lightweight 2D map control for the web. Leaflet code sample | Leaflet
documentation .
OpenLayers - A 2D map control for the web that supports projections. OpenLayers
documentation .
If developing using a JavaScript framework, one of the following open-source projects
may be useful:

ng-azure-maps - Angular 10 wrapper around Azure Maps.


AzureMapsControl.Components - An Azure Maps Blazor component.
Azure Maps React Component - A react wrapper for the Azure Maps control.
Vue Azure Maps - An Azure Maps component for Vue application.

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

An Azure Maps account


A subscription key

7 Note

For more information on authentication in Azure Maps, see Manage authentication


in Azure Maps.

Key features support


The table lists key API features in the Google Maps V3 JavaScript SDK and the supported
API feature in the Azure Maps Web SDK.

Google Maps feature Azure Maps Web SDK support

Markers ✓

Marker clustering ✓

Polylines & Polygons ✓

Data layers ✓

Ground Overlays ✓

Heat maps ✓

Tile Layers ✓

KML Layer ✓

Drawing tools ✓
Google Maps feature Azure Maps Web SDK support

Geocoder service ✓

Directions service ✓

Distance Matrix service ✓

Notable differences in the web SDKs


The following are some key differences between the Google Maps and Azure Maps Web
SDKs, to be aware of:

In addition to providing a hosted endpoint for accessing the Azure Maps Web SDK,
an npm package is available. For more information on how to Embed the Web SDK
package into apps, see Use the Azure Maps map control. This package also
includes TypeScript definitions.
You first need to create an instance of the Map class in Azure Maps. Wait for the
maps ready or load event to fire before programmatically interacting with the
map. This order ensures that all the map resources have been loaded and are
ready to be accessed.
Both platforms use a similar tiling system for the base maps. The tiles in Google
Maps are 256 pixels in dimension; however, the tiles in Azure Maps are 512 pixels
in dimension. To get the same map view in Azure Maps as Google Maps, subtract
Google Maps zoom level by the number one in Azure Maps.
Coordinates in Google Maps are referred to as latitude,longitude , while Azure
Maps uses longitude,latitude . The Azure Maps format is aligned with the
standard [x, y] , which is followed by most GIS platforms.
Shapes in the Azure Maps Web SDK are based on the GeoJSON schema. Helper
classes are exposed through the atlas.data namespace. There's also the atlas.Shape
class. Use this class to wrap GeoJSON objects, to make it easy to update and
maintain the data bindable way.
Coordinates in Azure Maps are defined as Position objects. A coordinate is
specified as a number array in the format [longitude,latitude] . Or, it's specified
using new atlas.data.Position(longitude, latitude).

 Tip

The Position class has a static helper method for importing coordinates that
are in "latitude, longitude" format. The atlas.data.Position.fromLatLng
method can often be replaced with the new google.maps.LatLng method in
Google Maps code.

Rather than specifying styling information on each shape that is added to the map,
Azure Maps separates styles from the data. Data is stored in a data source, and is
connected to rendering layers. Azure Maps code uses data sources to render the
data. This approach provides enhanced performance benefit. Additionally, many
layers support data-driven styling where business logic can be added to layer style
options. This support changes how individual shapes are rendered within a layer
based on properties defined in the shape.

Web SDK side-by-side examples


This collection has code samples for each platform, and each sample covers a common
use case. It's intended to help you migrate your web application from Google Maps V3
JavaScript SDK to the Azure Maps Web SDK. Code samples related to web applications
are provided in JavaScript. However, Azure Maps also provides TypeScript definitions as
another option through an npm module.

Topics

Load a map
Localizing the map
Setting the map view
Adding a marker
Adding a custom marker
Adding a polyline
Adding a polygon
Display an info window
Import a GeoJSON file
Marker clustering
Add a heat map
Overlay a tile layer
Show traffic data
Add a ground overlay
Add KML data to the map

Load a map
Both SDKs have the same steps to load a map:
Add a reference to the Map SDK.
Add a div tag to the body of the page, which acts as a placeholder for the map.
Create a JavaScript function that gets called when the page has loaded.
Create an instance of the respective map class.

Some key differences

Google Maps requires an account key to be specified in the script reference of the
API. Authentication credentials for Azure Maps are specified as options of the map
class. This credential can be a subscription key or Azure Active Directory
information.
Google Maps accepts a callback function in the script reference of the API, which is
used to call an initialization function to load the map. With Azure Maps, the onload
event of the page should be used.
When referencing the div element in which the map renders, the Map class in
Azure Maps only requires the id value while Google Maps requires a HTMLElement
object.
Coordinates in Azure Maps are defined as Position objects, which can be specified
as a simple number array in the format [longitude, latitude] .
The zoom level in Azure Maps is one level lower than the zoom level in Google
Maps. This discrepancy is because the difference in the sizes of tiling system of the
two platforms.
Azure Maps doesn't add any navigation controls to the map canvas. So, by default,
a map doesn't have zoom buttons and map style buttons. But, there are control
options for adding a map style picker, zoom buttons, compass or rotation control,
and a pitch control.
An event handler is added in Azure Maps to monitor the ready event of the map
instance. This event fires when the map has finished loading the WebGL context
and all the needed resources. Add any code you want to run after the map
completes loading, to this event handler.

The following examples use Google Maps to load a map centered over New York at
coordinates. The longitude: -73.985, latitude: 40.747, and the map is at zoom level of 12.

Before: Google Maps


Display a Google Map centered and zoomed over a location.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;

function initMap() {
map = new google.maps.Map(document.getElementById('myMap'), {
center: new google.maps.LatLng(40.747, -73.985),
zoom: 12
});
}
</script>

<!-- Google Maps Script Reference -->


<script src="https://maps.googleapis.com/maps/api/js?
callback=initMap&key={Your-Google-Maps-Key}" async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:
After: Azure Maps
Load a map with the same view in Azure Maps along with a map style control and zoom
buttons.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;

function initMap() {
map = new atlas.Map('myMap', {
center: [-73.985, 40.747], //Format coordinates as
longitude, latitude.
zoom: 11, //Subtract the zoom level by one.

//Specify authentication information when loading the map.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {
//Add zoom controls to bottom right of map.
map.controls.add(new atlas.control.ZoomControl(), {
position: 'bottom-right'
});

//Add map style control in top left corner of map.


map.controls.add(new atlas.control.StyleControl(), {
position: 'top-left'
});
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:

For more information on how to set up and use the Azure Maps map control in a web
app, see Use the Azure Maps map control.

7 Note

Unlike Google Maps, Azure Maps does not require an initial center and a zoom
level to load the map. If this information is not provided when loading the map,
Azure Maps will try to determine city of the user. It will center and zoom the map
there.

More resources:

For more information on navigation controls for rotating and pitching the map
view, see Add controls to a map.
Localizing the map
If your audience is spread across multiple countries/regions or speak different
languages, localization is important.

Before: Google Maps

To localize Google Maps, add language and region parameters.

HTML

<script type="text/javascript" src="


https://maps.googleapis.com/maps/api/js?callback=initMap&key={api-Key}&
language={language-code}&region={region-code}" async defer></script>

Here's an example of Google Maps with the language set to "fr-FR".

After: Azure Maps

Azure Maps provides two different ways of setting the language and regional view of
the map. The first option is to add this information to the global atlas namespace. It
results in all map control instances in your app defaulting to these settings. The
following sets the language to French ("fr-FR") and the regional view to "Auto":

JavaScript

atlas.setLanguage('fr-FR');
atlas.setView('auto');
The second option is to pass this information into the map options when loading the
map. Like this:

JavaScript

map = new atlas.Map('myMap', {


language: 'fr-FR',
view: 'auto',

authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

7 Note

With Azure Maps, it is possible to load multiple map instances on the same page
with different language and region settings. It is also possible to update these
settings in the map after it has loaded.

For more information on supported languages, see Localization support in Azure Maps.

Here's an example of Azure Maps with the language set to "fr" and the user region set
to "fr-FR".
Setting the map view
Dynamic maps in both Azure and Google Maps can be programmatically moved to new
geographic locations. To do so, call the appropriate functions in JavaScript. The
examples show how to make the map display satellite aerial imagery, center the map
over a location, and change the zoom level to 15 in Google Maps. The following location
coordinates are used: longitude: -111.0225 and latitude: 35.0272.

7 Note

Google Maps uses tiles that are 256 pixels in dimensions, while Azure Maps uses a
larger 512-pixel tile. Thus, Azure Maps requires less number of network requests to
load the same map area as Google Maps. Due to the way tile pyramids work in map
controls, you need to subtract the zoom level used in Google Maps by the number
one when using Azure Maps. This arithmetic operation ensures that larger tiles in
Azure Maps render that same map area as in Google Maps,

Before: Google Maps

Move the Google Maps map control using the setOptions method. This method allows
you to specify the center of the map and a zoom level.

JavaScript

map.setOptions({
mapTypeId: google.maps.MapTypeId.SATELLITE,
center: new google.maps.LatLng(35.0272, -111.0225),
zoom: 15
});
After: Azure Maps
In Azure Maps, change the map position using the setCamera method and change the
map style using the setStyle method. The coordinates in Azure Maps are in "longitude,
latitude" format, and the zoom level value is subtracted by one.

JavaScript

map.setCamera({
center: [-111.0225, 35.0272],
zoom: 14
});

map.setStyle({
style: 'satellite'
});
More resources:

Choose a map style


Supported map styles

Adding a marker
In Azure Maps, there are multiple ways in which point data can be rendered on the map:

HTML Markers – Renders points using traditional DOM elements. HTML Markers
support dragging.
Symbol Layer – Renders points with an icon or text within the WebGL context.
Bubble Layer – Renders points as circles on the map. The radii of the circles can be
scaled based on properties in the data.

Render Symbol layers and Bubble layers within the WebGL context. Both layers can
render large sets of points on the map. These layers require data to be stored in a data
source. Data sources and rendering layers should be added to the map after the ready
event has fired. HTML Markers are rendered as DOM elements within the page, and they
don't use a data source. The more DOM elements a page has, the slower the page
becomes. If rendering more than a few hundred points on a map, it's recommended to
use one of the rendering layers instead.

Let's add a marker to the map at with the number 10 overlaid as a label. Use longitude:
-0.2 and latitude: 51.5.
Before: Google Maps
With Google Maps, add markers to the map using the google.maps.Marker class and
specify the map as one of the options.

JavaScript

//Create a marker and add it to the map.


var marker = new google.maps.Marker({
position: new google.maps.LatLng(51.5, -0.2),
label: '10',
map: map
});

After: Azure Maps using HTML Markers

In Azure Maps, use HTML markers to display a point on the map. HTML markers are
recommended for apps that only need to display a few points on the map. To use an
HTML marker, create an instance of the atlas.HtmlMarker class. Set the text and
position options, and add the marker to the map using the map.markers.add method.

JavaScript

//Create a HTML marker and add it to the map.


map.markers.add(new atlas.HtmlMarker({
text: '10',
position: [-0.2, 51.5]
}));

After: Azure Maps using a Symbol Layer

For a Symbol layer, add the data to a data source. Attach the data source to the layer.
Additionally, the data source and layer should be added to the map after the ready
event has fired. To render a unique text value above a symbol, the text information
needs to be stored as a property of the data point. The property must be referenced in
the textField option of the layer. This approach is a bit more work than using HTML
markers, but it better performance.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map, datasource;

function initMap() {
map = new atlas.Map('myMap', {
center: [-0.2, 51.5],
zoom: 9,

authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a point feature, add a property to store a label


for it, and add it to the data source.
datasource.add(new atlas.data.Feature(new
atlas.data.Point([-0.2, 51.5]), {
label: '10'
}));

//Add a layer for rendering point data as symbols.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null,
{
textOptions: {
//Use the label property to populate the text for
the symbols.
textField: ['get', 'label'],
color: 'white',
offset: [0, -1]
}
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
More resources:

Create a data source


Add a Symbol layer
Add a Bubble layer
Clustering point data in the Web SDK
Add HTML Markers
Use data-driven style expressions
Symbol layer icon options
Symbol layer text option
HTML marker class
HTML marker options

Adding a custom marker


You may use Custom images to represent points on a map. The following map uses a
custom image to display a point on the map. The point is displayed at latitude: 51.5 and
longitude: -0.2. The anchor offsets the position of the marker, so that the point of the
pushpin icon aligns with the correct position on the map.

yellow-pushpin.png
Before: Google Maps
Create a custom marker by specifying an Icon object that contains the url to the
image. Specify an anchor point to align the point of the pushpin image with the
coordinate on the map. The anchor value in Google Maps is relative to the top-left
corner of the image.

JavaScript

var marker = new google.maps.Marker({


position: new google.maps.LatLng(51.5, -0.2),
icon: {
url: 'https://samples.azuremaps.com/images/icons/ylw-pushpin.png',
anchor: new google.maps.Point(5, 30)
},
map: map
});

After: Azure Maps using HTML Markers

To customize an HTML marker, pass an HTML string or HTMLElement to the


htmlContent option of the marker. Use the anchor option to specify the relative position

of the marker, relative to the position coordinate. Assign one of nine defined reference
points to the anchor option. Those defined points are: "center", "top", "bottom", "left",
"right", "top-left", "top-right", "bottom-left", "bottom-right". The content is anchored to
the bottom center of the html content by default. To make it easier to migrate code
from Google Maps, set the anchor to "top-left", and then use the pixelOffset option
with the same offset used in Google Maps. The offsets in Azure Maps move in the
opposite direction of the offsets in Google Maps. So, multiply the offsets by minus one.

 Tip

Add pointer-events:none as a style on the html content to disable the default drag
behavior in Microsoft Edge, which will display an unwanted icon.

JavaScript

map.markers.add(new atlas.HtmlMarker({
htmlContent: '<img src="https://samples.azuremaps.com/images/icons/ylw-
pushpin.png" style="pointer-events: none;" />',
anchor: 'top-left',
pixelOffset: [-5, -30],
position: [-0.2, 51.5]
}));

After: Azure Maps using a Symbol Layer

Symbol layers in Azure Maps support custom images as well. First, load the image to the
map resources and assign it with a unique ID. Reference the image in the symbol layer.
Use the offset option to align the image to the correct point on the map. Use the
anchor option to specify the relative position of the symbol, relative to the position
coordinates. Use one of the nine defined reference points. Those points are: "center",
"top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right". The
content is anchored to the bottom center of the html content by default. To make it
easier to migrate code from Google Maps, set the anchor to "top-left", and then use the
offset option with the same offset used in Google Maps. The offsets in Azure Maps

move in the opposite direction of the offsets in Google Maps. So, multiply the offsets by
minus one.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map, datasource;

function initMap() {
map = new atlas.Map('myMap', {
center: [-0.2, 51.5],
zoom: 9,
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Load the custom image icon into the map resources.


map.imageSprite.add('my-yellow-pin',
'https://samples.azuremaps.com/images/icons/ylw-pushpin.png').then(function
() {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Create a point and add it to the data source.
datasource.add(new atlas.data.Point([-0.2, 51.5]));

//Add a layer for rendering point data as symbols.


map.layers.add(new atlas.layer.SymbolLayer(datasource,
null, {
iconOptions: {
//Set the image option to the id of the custom
icon that was loaded into the map resources.
image: 'my-yellow-pin',
anchor: 'top-left',
offset: [-5, -30]
}
}));
});
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

</

 Tip
To render advanced custom points, use multiple rendering layers together. For
example, let's say you want to have multiple pushpins that have the same icon on
different colored circles. Instead of creating a bunch of images for each color
overlay, add a symbol layer on top of a bubble layer. Have the pushpins reference
the same data source. This approach will be more efficient than creating and
maintaining a bunch of different images.

More resources:

Create a data source


Add a Symbol layer
Add HTML Markers
Use data-driven style expressions
Symbol layer icon options
Symbol layer text option
HTML marker class
HTML marker options

Adding a polyline
Use polylines to represent a line or path on the map. Let's create a dashed polyline on
the map.

Before: Google Maps


The Polyline class accepts a set of options. Pass an array of coordinates in the path
option of the polyline.

JavaScript

//Get the center of the map.


var center = map.getCenter();

//Define a symbol using SVG path notation, with an opacity of 1.


var lineSymbol = {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
};

//Create the polyline.


var line = new google.maps.Polyline({
path: [
center,
new google.maps.LatLng(center.lat() - 0.5, center.lng() - 1),
new google.maps.LatLng(center.lat() - 0.5, center.lng() + 1)
],
strokeColor: 'red',
strokeOpacity: 0,
strokeWeight: 4,
icons: [{
icon: lineSymbol,
offset: '0',
repeat: '20px'
}]
});

//Add the polyline to the map.


line.setMap(map);

After: Azure Maps

Polylines are called LineString or MultiLineString objects. These objects can be added
to a data source and rendered using a line layer. Add LineString to a data source, then
add the data source to a LineLayer to render it.

JavaScript

//Get the center of the map.


var center = map.getCamera().center;

//Create a data source and add it to the map.


var datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Create a line and add it to the data source.
datasource.add(new atlas.data.LineString([
center,
[center[0] - 1, center[1] - 0.5],
[center[0] + 1, center[1] - 0.5]
]));

//Add a layer for rendering line data.


map.layers.add(new atlas.layer.LineLayer(datasource, null, {
strokeColor: 'red',
strokeWidth: 4,
strokeDashArray: [3, 3]
}));

More resources:

Add lines to the map


Line layer options
Use data-driven style expressions

Adding a polygon
Azure Maps and Google Maps provide similar support for polygons. Polygons are used
to represent an area on the map. The following examples show how to create a polygon
that forms a triangle based on the center coordinate of the map.

Before: Google Maps


The Polygon class accepts a set of options. Pass an array of coordinates to the paths
option of the polygon.

JavaScript

//Get the center of the map.


var center = map.getCenter();

//Create a polygon.
var polygon = new google.maps.Polygon({
paths: [
center,
new google.maps.LatLng(center.lat() - 0.5, center.lng() - 1),
new google.maps.LatLng(center.lat() - 0.5, center.lng() + 1),
center
],
strokeColor: 'red',
strokeWeight: 2,
fillColor: 'rgba(0, 255, 0, 0.5)'
});

//Add the polygon to the map


polygon.setMap(map);
After: Azure Maps
Add a Polygon or a MultiPolygon objects to a data source. Render the object on the
map using layers. Render the area of a polygon using a polygon layer. And, render the
outline of a polygon using a line layer.

JavaScript

//Get the center of the map.


var center = map.getCamera().center;

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a polygon and add it to the data source.


datasource.add(new atlas.data.Polygon([
center,
[center[0] - 1, center[1] - 0.5],
[center[0] + 1, center[1] - 0.5],
center
]));

//Add a polygon layer for rendering the polygon area.


map.layers.add(new atlas.layer.PolygonLayer(datasource, null, {
fillColor: 'rgba(0, 255, 0, 0.5)'
}));

//Add a line layer for rendering the polygon outline.


map.layers.add(new atlas.layer.LineLayer(datasource, null, {
strokeColor: 'red',
strokeWidth: 2
}));

More resources:

Add a polygon to the map


Add a circle to the map
Polygon layer options
Line layer options
Use data-driven style expressions

Display an info window


Additional information for an entity can be displayed on the map as a
google.maps.InfoWindow class in Google Maps. In Azure Maps, this functionality can be

achieved using the atlas.Popup class. The next examples add a marker to the map.
When the marker is clicked, an info window or a popup is displayed.

Before: Google Maps


Instantiate an info window using the google.maps.InfoWindow constructor.

JavaScript

//Add a marker in which to display an infowindow for.


var marker = new google.maps.Marker({
position: new google.maps.LatLng(47.6, -122.33),
map: map
});

//Create an infowindow.
var infowindow = new google.maps.InfoWindow({
content: '<div style="padding:5px"><b>Hello World!</b></div>'
});

//Add a click event to the marker to open the infowindow.


marker.addListener('click', function () {
infowindow.open(map, marker);
});

After: Azure Maps


Let's use popup to display additional information about the location. Pass an HTML
string or HTMLElement object to the content option of the popup. If you want, popups

can be displayed independently of any shape. Thus, Popups require a position value to
be specified. Specify the position value. To display a popup, call the open method and
pass the map in which the popup is to be displayed on.
JavaScript

//Add a marker to the map in which to display a popup for.


var marker = new atlas.HtmlMarker({
position: [-122.33, 47.6]
});

//Add the marker to the map.


map.markers.add(marker);

//Create a popup.
var popup = new atlas.Popup({
content: '<div style="padding:5px"><b>Hello World!</b></div>',
position: [-122.33, 47.6],
pixelOffset: [0, -35]
});

//Add a click event to the marker to open the popup.


map.events.add('click', marker, function () {
//Open the popup
popup.open(map);
});

7 Note

You may do the same thing with a symbol, bubble, line or polygon layer by passing
the chosen layer to the maps event code instead of a marker.
More resources:

Add a popup
Popup with Media Content
Popups on Shapes
Reusing Popup with Multiple Pins
Popup class
Popup options

Import a GeoJSON file


Google Maps supports loading and dynamically styling GeoJSON data via the
google.maps.Data class. The functionality of this class aligns more with the data-driven

styling of Azure Maps. But, there's a key difference. With Google Maps, you specify a
callback function. The business logic for styling each feature it processed individually in
the UI thread. But in Azure Maps, layers support specifying data-driven expressions as
styling options. These expressions are processed at render time on a separate thread.
The Azure Maps approach improves rendering performance. This advantage is noticed
when larger data sets need to be rendered quickly.

The following examples load a GeoJSON feed of all earthquakes over the last seven days
from the USGS. Earthquakes data renders as scaled circles on the map. The color and
scale of each circle is based on the magnitude of each earthquake, which is stored in the
"mag" property of each feature in the data set. If the magnitude is greater than or equal

to five, the circle is red. If it's greater or equal to three, but less than five, the circle is
orange. If it's less than three, the circle is green. The radius of each circle is the
exponential of the magnitude multiplied by 0.1.

Before: Google Maps


Specify a single callback function in the map.data.setStyle method. Inside the callback
function, apply business logic to each feature. Load the GeoJSON feed with the
map.data.loadGeoJson method.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson'
;

function initMap() {
map = new google.maps.Map(document.getElementById('myMap'), {
center: new google.maps.LatLng(20, -160),
zoom: 2
});

//Define a callback to style each feature.


map.data.setStyle(function (feature) {

//Extract the 'mag' property from the feature.


var mag = parseFloat(feature.getProperty('mag'));

//Set the color value to 'green' by default.


var color = 'green';

//If the mag value is greater than 5, set the color to


'red'.
if (mag >= 5) {
color = 'red';
}
//If the mag value is greater than 3, set the color to
'orange'.
else if (mag >= 3) {
color = 'orange';
}

return /** @type {google.maps.Data.StyleOptions} */({


icon: {
path: google.maps.SymbolPath.CIRCLE,

//Scale the radius based on an exponential of the


'mag' value.
scale: Math.exp(mag) * 0.1,
fillColor: color,
fillOpacity: 0.75,
strokeWeight: 2,
strokeColor: 'white'
}
});
});

//Load the data feed.


map.data.loadGeoJson(earthquakeFeed);
}
</script>

<!-- Google Maps Script Reference -->


<script src="https://maps.googleapis.com/maps/api/js?
callback=initMap&key={Your-Google-Maps-Key}" async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

After: Azure Maps

GeoJSON is the base data type in Azure Maps. Import it into a data source using the
datasource.importFromUrl method. Use a bubble layer. The bubble layer provides

functionality for rendering scaled circles, based on the properties of the features in a
data source. Instead of having a callback function, the business logic is converted into
an expression and passed into the style options. Expressions define how the business
logic works. Expressions can be passed into another thread and evaluated against the
feature data. Multiple data sources and layers can be added to Azure Maps, each with
different business logic. This feature allows multiple data sets to be rendered on the
map in different ways.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson'
;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-160, 20],
zoom: 1,

//Add your Azure Maps subscription key to the map SDK. Get
an Azure Maps key at https://azure.com/maps
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Load the earthquake data.


datasource.importDataFromUrl(earthquakeFeed);

//Create a layer to render the data points as scaled


circles.
map.layers.add(new atlas.layer.BubbleLayer(datasource, null,
{
//Make the circles semi-transparent.
opacity: 0.75,

color: [
'case',

//If the mag value is greater than 5, return 'red'.


['>=', ['get', 'mag'], 5],
'red',

//If the mag value is greater than 3, return


'orange'.
['>=', ['get', 'mag'], 3],
'orange',

//Return 'green' as a fallback.


'green'
],

//Scale the radius based on an exponential of the 'mag'


value.
radius: ['*', ['^', ['e'], ['get', 'mag']], 0.1]
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources:

Add a Symbol layer


Add a Bubble layer
Clustering point data in the Web SDK
Use data-driven style expressions

Marker clustering
When visualizing many data points on the map, points may overlap each other.
Overlapping makes the map look cluttered, and the map becomes difficult to read and
use. Clustering point data is the process of combining data points that are near each
other and representing them on the map as a single clustered data point. As the user
zooms into the map, the clusters break apart into their individual data points. Cluster
data points to improve user experience and map performance.

In the following examples, the code loads a GeoJSON feed of earthquake data from the
past week and adds it to the map. Clusters are rendered as scaled and colored circles.
The scale and color of the circles depends on the number of points they contain.

7 Note

Google Maps and Azure Maps use slightly different clustering algorithms. As such,
sometimes the point distribution in the clusters varies.

Before: Google Maps

Use the MarkerCluster library to cluster markers. Cluster icons are limited to images,
which have the numbers one through five as their name. They're hosted in the same
directory.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson'
;

function initMap() {
map = new google.maps.Map(document.getElementById('myMap'), {
center: new google.maps.LatLng(20, -160),
zoom: 2
});

//Download the GeoJSON data.


fetch(earthquakeFeed)
.then(function (response) {
return response.json();
}).then(function (data) {
//Loop through the GeoJSON data and create a marker for
each data point.
var markers = [];

for (var i = 0; i < data.features.length; i++) {

markers.push(new google.maps.Marker({
position: new
google.maps.LatLng(data.features[i].geometry.coordinates[1],
data.features[i].geometry.coordinates[0])
}));
}

//Create a marker clusterer instance and tell it where


to find the cluster icons.
var markerCluster = new MarkerClusterer(map, markers,
{ imagePath:
'https://developers.google.com/maps/documentation/javascript/examples/marker
clusterer/m' });
});
}
</script>

<!-- Load the marker cluster library. -->


<script
src="https://developers.google.com/maps/documentation/javascript/examples/ma
rkerclusterer/markerclusterer.js"></script>

<!-- Google Maps Script Reference -->


<script src="https://maps.googleapis.com/maps/api/js?
callback=initMap&key={Your-Google-Maps-Key}" async defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
After: Azure Maps
Add and manage data in a data source. Connect data sources and layers, then render
the data. The DataSource class in Azure Maps provides several clustering options.

cluster – Tells the data source to cluster point data.

clusterRadius - The radius in pixels to cluster points together.


clusterMaxZoom - The maximum zoom level in which clustering occurs. If you zoom

in more than this level, all points are rendered as symbols.


clusterProperties - Defines custom properties that are calculated using

expressions against all the points within each cluster and added to the properties
of each cluster point.

When clustering is enabled, the data source sends clustered and unclustered data points
to layers for rendering. The data source is capable of clustering hundreds of thousands
of data points. A clustered data point has the following properties:

Property name Type Description

cluster boolean Indicates if feature represents a cluster.

cluster_id string A unique ID for the cluster that can be used with the
DataSource getClusterExpansionZoom , getClusterChildren ,
and getClusterLeaves methods.

point_count number The number of points the cluster contains.


Property name Type Description
point_count_abbreviated string A string that abbreviates the point_count value if it's long.
(for example, 4,000 becomes 4K)

The DataSource class has the following helper function for accessing additional
information about a cluster using the cluster_id .

Method Return type Description

getClusterChildren(clusterId: Promise<Array<Feature<Geometry, Retrieves the


number) any> | Shape>> children of the given
cluster on the next
zoom level. These
children may be a
combination of
shapes and
subclusters. The
subclusters are
features with
properties matching
ClusteredProperties.

getClusterExpansionZoom(clusterId: Promise<number> Calculates a zoom


number) level at which the
cluster starts
expanding or break
apart.

getClusterLeaves(clusterId: Promise<Array<Feature<Geometry, Retrieves all points


number, limit: number, offset: any> | Shape>> in a cluster. Set the
number) limit to return a
subset of the points,
and use the offset
to page through the
points.

When rendering clustered data on the map, it's often best to use two or more layers.
The following example uses three layers. A bubble layer for drawing scaled colored
circles based on the size of the clusters. A symbol layer to render the cluster size as text.
And, it uses a second symbol layer for rendering the unclustered points. For more
information on other ways to render clustered data, see Clustering point data in the
Web SDK.

Directly import GeoJSON data using the importDataFromUrl function on the DataSource
class, inside Azure Maps map.

HTML
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map, datasource;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson'
;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-160, 20],
zoom: 1,

//Add your Azure Maps subscription key to the map SDK. Get
an Azure Maps key at https://azure.com/maps
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource(null, {
//Tell the data source to cluster point data.
cluster: true
});
map.sources.add(datasource);

//Create layers for rendering clusters, their counts and


unclustered points and add the layers to the map.
map.layers.add([
//Create a bubble layer for rendering clustered data
points.
new atlas.layer.BubbleLayer(datasource, null, {
//Scale the size of the clustered bubble based on
the number of points inthe cluster.
radius: [
'step',
['get', 'point_count'],
20, //Default of 20 pixel radius.
100, 30, //If point_count >= 100, radius is
30 pixels.
750, 40 //If point_count >= 750, radius is
40 pixels.
],

//Change the color of the cluster based on the value


on the point_cluster property of the cluster.
color: [
'step',
['get', 'point_count'],
'lime', //Default to lime green.
100, 'yellow', //If the point_count >= 100,
color is yellow.
750, 'red' //If the point_count >= 750,
color is red.
],
strokeWidth: 0,
filter: ['has', 'point_count'] //Only rendered data
points which have a point_count property, which clusters do.
}),

//Create a symbol layer to render the count of locations


in a cluster.
new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'none' //Hide the icon image.
},
textOptions: {
textField: ['get', 'point_count_abbreviated'],
offset: [0, 0.4]
}
}),

//Create a layer to render the individual locations.


new atlas.layer.SymbolLayer(datasource, null, {
filter: ['!', ['has', 'point_count']] //Filter out
clustered points from this layer.
})
]);

//Retrieve a GeoJSON data set and add it to the data source.


datasource.importDataFromUrl(earthquakeFeed);
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources:

Add a Symbol layer


Add a Bubble layer
Clustering point data in the Web SDK
Use data-driven style expressions

Add a heat map


Heat maps, also known as point density maps, are a type of data visualization. They're
used to represent the density of data using a range of colors. And, they're often used to
show the data "hot spots" on a map. Heat maps are a great way to render large point
data sets.

The following examples load a GeoJSON feed of all earthquakes over the past month,
from the USGS, and it renders them as a weighted heat map. The "mag" property is used
as the weight.

Before: Google Maps


To create a heat map, load the "visualization" library by adding
&libraries=visualization to the API script URL. The heat map layer in Google Maps

doesn't support GeoJSON data directly. First, download the data and convert it into an
array of weighted data points:

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson
';

function initMap() {

var map = new google.maps.Map(document.getElementById('myMap'),


{
center: new google.maps.LatLng(20, -160),
zoom: 2,
mapTypeId: 'satellite'
});

//Download the GeoJSON data.


fetch(url).then(function (response) {
return response.json();
}).then(function (res) {
var points = getDataPoints(res);

var heatmap = new google.maps.visualization.HeatmapLayer({


data: points
});
heatmap.setMap(map);
});
}

function getDataPoints(geojson, weightProp) {


var points = [];

for (var i = 0; i < geojson.features.length; i++) {


var f = geojson.features[i];

if (f.geometry.type === 'Point') {


points.push({
location: new
google.maps.LatLng(f.geometry.coordinates[1], f.geometry.coordinates[0]),
weight: f.properties[weightProp]
});
}
}

return points;
}
</script>

<!-- Google Maps Script Reference -->


<script src="https://maps.googleapis.com/maps/api/js?
callback=initMap&key={Your-Google-Maps-Key}&libraries=visualization" async
defer></script>
</head>
<body>
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

After: Azure Maps

Load the GeoJSON data into a data source and connect the data source to a heat map
layer. The property that is used for the weight can be passed into the weight option
using an expression. Directly import GeoJSON data to Azure Maps using the
importDataFromUrl function on the DataSource class.
HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;
var earthquakeFeed =
'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson
';

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-160, 20],
zoom: 1,
style: 'satellite',

//Add your Azure Maps subscription key to the map SDK. Get
an Azure Maps key at https://azure.com/maps
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Load the earthquake data.


datasource.importDataFromUrl(earthquakeFeed);

//Create a layer to render the data points as a heat map.


map.layers.add(new atlas.layer.HeatMapLayer(datasource,
null, {
weight: ['get', 'mag'],
intensity: 0.005,
opacity: 0.65,
radius: 10
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources:

Add a heat map layer


Heat map layer class
Heat map layer options
Use data-driven style expressions

Overlay a tile layer


Tile layers in Azure Maps are known as Image overlays in Google Maps. Tile layers allow
you to overlay large images that have been broken up into smaller tiled images, which
align with the maps tiling system. This approach is a commonly used to overlay large
images or large data sets.

The following examples overlay a weather radar tile layer from Iowa Environmental
Mesonet of Iowa State University.

Before: Google Maps

In Google Maps, tile layers can be created by using the google.maps.ImageMapType class.

JavaScript

map.overlayMapTypes.insertAt(0, new google.maps.ImageMapType({


getTileUrl: function (coord, zoom) {
return
"https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/" +
zoom + "/" + coord.x + "/" + coord.y;
},
tileSize: new google.maps.Size(256, 256),
opacity: 0.8
}));

After: Azure Maps


Add a tile layer to the map similarly as any other layer. Use a formatted URL that has in
x, y, zoom placeholders; {x} , {y} , {z} to tell the layer where to access the tiles. Azure
Maps tile layers also support {quadkey} , {bbox-epsg-3857} , and {subdomain}
placeholders.

 Tip

In Azure Maps layers can easily be rendered below other layers, including base map
layers. Often it is desirable to render tile layers below the map labels so that they
are easy to read. The map.layers.add method takes in a second parameter which is
the id of the layer in which to insert the new layer below. To insert a tile layer below
the map labels, use this code: map.layers.add(myTileLayer, "labels");

JavaScript

//Create a tile layer and add it to the map below the label layer.
map.layers.add(new atlas.layer.TileLayer({
tileUrl: 'https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-
n0q-900913/{z}/{x}/{y}.png',
opacity: 0.8,
tileSize: 256
}), 'labels');

 Tip
Tile requests can be captured using the transformRequest option of the map. This
will allow you to modify or add headers to the request if desired.

More resources:

Add tile layers


Tile layer class
Tile layer options

Show traffic data


Traffic data can be overlaid both Azure and Google Maps.

Before: Google Maps

Overlay traffic data on the map using the traffic layer.

JavaScript

var trafficLayer = new google.maps.TrafficLayer();


trafficLayer.setMap(map);

After: Azure Maps


Azure Maps provides several different options for displaying traffic. Display traffic
incidents, such as road closures and accidents as icons on the map. Overlay traffic flow
and color coded roads on the map. The colors can be modified based on the posted
speed limit, relative to the normal expected delay, or absolute delay. Incident data in
Azure Maps updates every minute, and flow data updates every two minutes.

Assign the wanted values for setTraffic options.

JavaScript

map.setTraffic({
incidents: true,
flow: 'relative'
});

If you select one of the traffic icons in Azure Maps, more information is displayed in a
popup.
More resources:

Show traffic on the map


Traffic overlay options

Add a ground overlay


Both Azure and Google Maps support overlaying georeferenced images on the map.
Georeferenced images move and scale as you pan and zoom the map. In Google Maps,
georeferenced images are known as ground overlays while in Azure Maps they're
referred to as image layers. They're great for building floor plans, overlaying old maps,
or imagery from a drone.

Before: Google Maps


Specify the URL to the image you want to overlay and a bounding box to bind the
image on the map. This example overlays a map image of Newark New Jersey from 1922
on the map.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<script type='text/javascript'>
var map, historicalOverlay;

function initMap() {
map = new google.maps.Map(document.getElementById('myMap'), {
center: new google.maps.LatLng(40.740, -74.18),
zoom: 12
});

var imageBounds = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
};

historicalOverlay = new google.maps.GroundOverlay(

'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
imageBounds);
historicalOverlay.setMap(map);
}
</script>

<!-- Google Maps Script Reference -->


<script src="https://maps.googleapis.com/maps/api/js?
callback=initMap&key={Your-Google-Maps-Key}" async defer></script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;">
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:
After: Azure Maps
Use the atlas.layer.ImageLayer class to overlay georeferenced images. This class
requires a URL to an image and a set of coordinates for the four corners of the image.
The image must be hosted either on the same domain or have CORs enabled.

 Tip

If you only have north, south, east, west and rotation information, and you do not
have coordinates for each corner of the image, you can use the static
atlas.layer.ImageLayer.getCoordinatesFromEdges method.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<script type='text/javascript'>
var map;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-74.18, 40.740],
zoom: 12,

//Add your Azure Maps subscription key to the map SDK. Get
an Azure Maps key at https://azure.com/maps
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create an image layer and add it to the map.


map.layers.add(new atlas.layer.ImageLayer({
url: 'newark_nj_1922.jpg',
coordinates: [
[-74.22655, 40.773941], //Top Left Corner
[-74.12544, 40.773941], //Top Right Corner
[-74.12544, 40.712216], //Bottom Right Corner
[-74.22655, 40.712216] //Bottom Left Corner
]
}));
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>
More resources:

Overlay an image
Image layer class

Add KML data to the map


Both Azure and Google Maps can import and render KML, KMZ and GeoRSS data on the
map. Azure Maps also supports GPX, GML, spatial CSV files, GeoJSON, Well Known Text
(WKT), Web-Mapping Services (WMS), Web-Mapping Tile Services (WMTS), and Web
Feature Services (WFS). Azure Maps reads the files locally into memory and in most
cases can handle larger KML files.

Before: Google Maps

JavaScript

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />
<script type='text/javascript'>
var map, historicalOverlay;

function initMap() {
map = new google.maps.Map(document.getElementById('myMap'), {
center: new google.maps.LatLng(0, 0),
zoom: 1
});

var layer = new google.maps.KmlLayer({


url: 'https://googlearchive.github.io/js-v2-
samples/ggeoxml/cta.kml',
map: map
});
}
</script>

<!-- Google Maps Script Reference -->


<script src="https://maps.googleapis.com/maps/api/js?
callback=initMap&key={Your-Google-Maps-Key}" async defer></script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;">
</div>
</body>
</html>

Running this code in a browser displays a map that looks like the following image:

After: Azure Maps


In Azure Maps, GeoJSON is the main data format used in the web SDK, more spatial
data formats can be easily integrated in using the spatial IO module. This module has
functions for both reading and writing spatial data and also includes a simple data layer
that can easily render data from any of these spatial data formats. To read the data in a
spatial data file, pass in a URL, or raw data as string or blob into the atlas.io.read
function. This returns all the parsed data from the file that can then be added to the
map. KML is a bit more complex than most spatial data format as it includes a lot more
styling information. The SpatialDataLayer class supports most of these styles, however
icons images have to be loaded into the map before loading the feature data, and
ground overlays have to be added as layers to the map separately. When loading data
via a URL, it should be hosted on a CORs enabled endpoint, or a proxy service should be
passed in as an option into the read function.

JavaScript

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no" />

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

<!-- Add reference to the Azure Maps Spatial IO module. -->


<script src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.js"></script>

<script type='text/javascript'>
var map, datasource, layer;

function initMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',

//Add your Azure Maps subscription key to the map SDK. Get
an Azure Maps key at https://azure.com/maps
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering the data.


layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);

//Read a KML file from a URL or pass in a raw KML string.


atlas.io.read('https://googlearchive.github.io/js-v2-
samples/ggeoxml/cta.kml').then(async r => {
if (r) {

//Check to see if there are any icons in the data


set that need to be loaded into the map resources.
if (r.icons) {
//For each icon image, create a promise to add
it to the map, then run the promises in parrallel.
var imagePromises = [];

//The keys are the names of each icon image.


var keys = Object.keys(r.icons);

if (keys.length !== 0) {
keys.forEach(function (key) {

imagePromises.push(map.imageSprite.add(key, r.icons[key]));
});

await Promise.all(imagePromises);
}
}

//Load all features.


if (r.features && r.features.length > 0) {
datasource.add(r.features);
}

//Load all ground overlays.


if (r.groundOverlays && r.groundOverlays.length > 0)
{
map.layers.add(r.groundOverlays);
}

//If bounding box information is known for data, set


the map view to it.
if (r.bbox) {
map.setCamera({ bounds: r.bbox, padding: 50 });
}
}
});
});
}
</script>
</head>
<body onload="initMap()">
<div id='myMap' style='position:relative;width:600px;height:400px;'>
</div>
</body>
</html>

More resources:

atlas.io.read function
SimpleDataLayer
SimpleDataLayerOptions

More code samples


The following are some more code samples related to Google Maps migration:

Drawing tools
Limit Map to Two Finger Panning
Limit Scroll Wheel Zoom
Create a Fullscreen Control

Services:

Using the Azure Maps services module


Search for points of interest
Get information from a coordinate (reverse geocode)
Show directions from A to B
Search Autosuggest with JQuery UI

Google Maps V3 to Azure Maps Web SDK class


mapping
The following appendix provides a cross reference of the commonly used classes in
Google Maps V3 and the equivalent Azure Maps Web SDK.

Core Classes

Google Maps Azure Maps

google.maps.Map atlas.Map

google.maps.InfoWindow atlas.Popup

google.maps.InfoWindowOptions atlas.PopupOptions

google.maps.LatLng atlas.data.Position

google.maps.LatLngBounds atlas.data.BoundingBox

google.maps.MapOptions atlas.CameraOptions
atlas.CameraBoundsOptions
atlas.ServiceOptions
atlas.StyleOptions
atlas.UserInteractionOptions

google.maps.Point atlas.Pixel

Overlay Classes
Google Maps Azure Maps

google.maps.Marker atlas.HtmlMarker
atlas.data.Point

google.maps.MarkerOptions atlas.HtmlMarkerOptions
atlas.layer.SymbolLayer
atlas.SymbolLayerOptions
atlas.IconOptions
atlas.TextOptions
atlas.layer.BubbleLayer
atlas.BubbleLayerOptions

google.maps.Polygon atlas.data.Polygon

google.maps.PolygonOptions atlas.layer.PolygonLayer
atlas.PolygonLayerOptions
atlas.layer.LineLayer
atlas.LineLayerOptions

google.maps.Polyline atlas.data.LineString

google.maps.PolylineOptions atlas.layer.LineLayer
atlas.LineLayerOptions

google.maps.Circle See Add a circle to the map

google.maps.ImageMapType atlas.TileLayer

google.maps.ImageMapTypeOptions atlas.TileLayerOptions

google.maps.GroundOverlay atlas.layer.ImageLayer
atlas.ImageLayerOptions

Service Classes
The Azure Maps Web SDK includes a services module, which can be loaded separately.
This module wraps the Azure Maps REST services with a web API and can be used in
JavaScript, TypeScript, and Node.js applications.

Google Maps Azure Maps

google.maps.Geocoder atlas.service.SearchUrl

google.maps.GeocoderRequest atlas.SearchAddressOptions
atlas.SearchAddressRevrseOptions
atlas.SearchAddressReverseCrossStreetOptions
atlas.SearchAddressStructuredOptions
atlas.SearchAlongRouteOptions
Google Maps Azure Maps

atlas.SearchFuzzyOptions
atlas.SearchInsideGeometryOptions
atlas.SearchNearbyOptions
atlas.SearchPOIOptions
atlas.SearchPOICategoryOptions

google.maps.DirectionsService atlas.service.RouteUrl

google.maps.DirectionsRequest atlas.CalculateRouteDirectionsOptions

google.maps.places.PlacesService f

Libraries
Libraries add more functionality to the map. Many of these libraries are in the core SDK
of Azure Maps. Here are some equivalent classes to use in place of these Google Maps
libraries

Google Maps Azure Maps

Drawing library Drawing tools module

Geometry library atlas.math

Visualization library Heat map layer

Clean up resources
No resources to be cleaned up.

Next steps
Learn more about migrating to Azure Maps:

Migrate a web service


Tutorial: Migrate web service from
Google Maps
Article • 09/29/2023

Both Azure and Google Maps provide access to spatial APIs through REST web services.
The API interfaces of these platforms perform similar functionalities. But, they each use
different naming conventions and response objects.

This tutorial demonstrates how to:

" Forward and reverse geocoding


" Search for points of interest
" Calculate routes and directions
" Retrieve a map image
" Calculate a distance matrix
" Get time zone details

You'll also learn:

" Which Azure Maps REST service when migrating from a Google Maps Web Service
" Tips on how to get the most out of the Azure Maps services
" Insights into other related Azure Maps services

The table shows the Azure Maps service APIs, which have a similar functionality to the
listed Google Maps service APIs.

Google Maps service API Azure Maps service API

Directions Route

Distance Matrix Post Route Matrix

Geocoding Search

Places Search Search

Place Autocomplete Search

Snap to Road See Calculate routes and directions section.

Speed Limits See Reverse geocode a coordinate section.

Static Map Render

Time Zone Timezone


The following service APIs aren't currently available in Azure Maps:

Geolocation - Azure Maps does have a service called Geolocation, but it provides
IP Address to location information, but doesn't currently support cell tower or WiFi
triangulation.
Places details and photos - Phone numbers and website URL are available in the
Azure Maps search API.
Map URLs
Nearest Roads - Achievable using the Web SDK as demonstrated in the Basic snap
to road logic sample, but isn't currently available as a service.
Static street view

Azure Maps has several other REST web services that may be of interest:

Spatial operations: Offload complex spatial calculations and operations, such as


geofencing, to a service.
Traffic: Access real-time traffic flow and incident data.

Prerequisites
If you don't have an Azure subscription, create a free account before you begin.

An Azure Maps account


A subscription key

7 Note

For more information on authentication in Azure Maps, see Manage authentication


in Azure Maps.

Geocoding addresses
Geocoding is the process of converting an address into a coordinate. For example, "1
Microsoft way, Redmond, WA" converts to longitude: -122.1298, latitude: 47.64005.
Then, Coordinates can be used for different kind of purposes, such as, positioning a
centering a marker on a map.

Azure Maps provides several methods for geocoding addresses:

Get Search Address: Free-form address geocoding is used to specify a single


address string (like "1 Microsoft way, Redmond, WA" ) and process the request
immediately. This service is recommended if you need to geocode individual
addresses quickly.
Get Search Address Structured: Specify the parts of a single address, such as the
street name, city, country/region, and postal code and process the request
immediately. This API is recommended if you need to geocode individual
addresses quickly and the data is already parsed into its individual address parts.
Post Search Address Batch: Create a request containing up to 10,000 addresses
and have them processed over a period of time. All the addresses are geocoded in
parallel on the server and when completed the full result set can be downloaded.
This is recommended for geocoding large data sets.
Get Search Fuzzy: The fuzzy search API combines address geocoding with point of
interest search. This API takes in a free-form string that can be an address, place,
landmark, point of interest, or point of interest category and process the request
immediately. This API is recommended for applications where users can search for
addresses or points of interest from the same textbox.
Post Search Fuzzy Batch: Use the fuzzy batch search to create a request containing
up to 10,000 addresses, places, landmarks, or point of interests and have them
processed over a period of time. All the data is processed in parallel on the server
and when completed the full result set can be downloaded.

The following table cross-references the Google Maps API parameters with the
comparable API parameters in Azure Maps.

Google Maps API Comparable Azure Maps API parameter


parameter

address query

bounds topLeft and btmRight

components streetNumber
streetName
crossStreet
postalCode
municipality - city / town
municipalitySubdivision – neighborhood, sub / super city
countrySubdivision - state or province
countrySecondarySubdivision - county
countryTertiarySubdivision - district
countryCode - two letter country/region code

key subscription-key – For more information, see Authentication with


Azure Maps.
Google Maps API Comparable Azure Maps API parameter
parameter

language language – For more information, see Localization support in Azure


Maps.

region countrySet

For more information on using the search service, see Search for a location using Azure
Maps Search services. Be sure to review best practices for search.

 Tip

The free-form address geocoding and fuzzy search APIs can be used in
autocomplete mode by adding &typeahead=true to the request URL. This will tell
the server that the input text is likely partial, and the search will go into predictive
mode.

Reverse geocode a coordinate


Reverse geocoding is the process of converting geographic coordinates into an
approximate address. Coordinates with "longitude: -122.1298, latitude: 47.64005"
convert to "1 Microsoft way, Redmond, WA".

Azure Maps provides several reverse geocoding methods:

Get Search Address Reverse: Specify a single geographic coordinate to get the
approximate address corresponding to this coordinate. Processes the request near
real time.
Get Search Address Reverse Cross Street: Specify a single geographic coordinate to
get nearby cross street information and process the request immediately. For
example, you may receive the following cross streets: 1st Ave and Main St.
Post Search Address Reverse Batch: Create a request containing up to 10,000
coordinates and have them processed over a period of time. All data is processed
in parallel on the server. When the request completes, you can download the full
set of results.

This table cross-references the Google Maps API parameters with the comparable API
parameters in Azure Maps.
Google Maps API Comparable Azure Maps API parameter
parameter

key subscription-key – For more information, see Authentication with


Azure Maps.

language language – For more information, see Localization support in Azure


Maps.

latlng query

location_type N/A

result_type entityType

For more information, see best practices for search.

The Azure Maps reverse geocoding API has some other features, which aren't available
in Google Maps. These features might be useful to integrate with your application, as
you migrate your app:

Retrieve speed limit data


Retrieve road use information: local road, arterial, limited access, ramp, and so on
Retrieve the side of street at which a coordinate is located

Search for points of interest


Point of interest data can be searched in Google Maps using the Places Search API. This
API provides three different ways to search for points of interest:

Find place from text: Searches for a point of interest based on its name, address,
or phone number.
Nearby Search: Searches for points of interests that are within a certain distance of
a location.
Text Search: Searches for places using a free-form text, which includes point of
interest and location information. For example, "pizza in New York" or "restaurants
near main st".

Azure Maps provides several search APIs for points of interest:

Get Search POI: Search for points of interests by name. For example, "Starbucks".
Get Search POI Category: Search for points of interests by category. For example,
"restaurant".
Get Search Nearby: Searches for points of interests that are within a certain
distance of a location.
Get Search Fuzzy: The fuzzy search API combines address geocoding with point of
interest search. This API takes in a free-form string that can be an address, place,
landmark, point of interest, or point of interest category and process the request
immediately. This API is recommended for applications where users can search for
addresses or points of interest from the same textbox.
Post Search Inside Geometry: Search for points of interests that are within a
specified geometry. For example, search a point of interest within a polygon.
Post Search Along Route: Search for points of interests that are along a specified
route path.
Post Search Fuzzy Batch: Use the fuzzy batch search to create a request containing
up to 10,000 addresses, places, landmarks, or point of interests and have them
processed over a period of time. All the data is processed in parallel on the server
and when completed the full result set can be downloaded.

Currently Azure Maps doesn't have a comparable API to the Text Search API in Google
Maps.

 Tip

The POI search, POI category search, and fuzzy search APIs can be used in
autocomplete mode by adding &typeahead=true to the request URL. This will tell
the server that the input text is likely partial.The API will conduct the search in
predictive mode.

For more information, see best practices for search.

Find place from text


Use the Azure Maps Get Search POI and Get Search Fuzzy to search for points of
interests by name or address.

The table cross-references the Google Maps API parameters with the comparable Azure
Maps API parameters.

Google Maps API Comparable Azure Maps API parameter


parameter

fields N/A

input query

inputtype N/A
Google Maps API Comparable Azure Maps API parameter
parameter

key subscription-key – For more information, see Authentication with


Azure Maps.

language language – For more information, see Localization support in Azure


Maps.

locationbias lat , lon and radius


topLeft and btmRight
countrySet

Nearby search
Use the Get Search Nearby API to retrieve nearby points of interests, in Azure Maps.

The table shows the Google Maps API parameters with the comparable Azure Maps API
parameters.

Google Maps API Comparable Azure Maps API parameter


parameter

key subscription-key – For more information, see Authentication with


Azure Maps.

keyword categorySet and brandSet

language language – For more information, see Localization support in Azure


Maps.

location lat and lon

maxprice N/A

minprice N/A

name categorySet and brandSet

opennow N/A

pagetoken ofs and limit

radius radius

rankby N/A

type categorySet – For more information, see supported search


categories.
Calculate routes and directions
Calculate routes and directions using Azure Maps. Azure Maps has many of the same
functionalities as the Google Maps routing service, such as:

Arrival and departure times.


Real-time and predictive based traffic routes.
Different modes of transportation. Such as driving, walking and bicycling.

7 Note

Azure Maps requires all waypoints to be coordinates. Addresses must be geocoded


first.

The Azure Maps routing service provides the following APIs for calculating routes:

Get Route Directions: Calculate a route and have the request processed
immediately. This API supports both GET and POST requests. POST requests are
recommended when specifying a large number of waypoints or when using lots of
the route options to ensure that the URL request doesn't become too long and
cause issues. The POST Route Direction in Azure Maps has an option can that take
in thousands of supporting points and use them to recreate a logical route path
between them (snap to road).
Post Route Directions Batch: Create a request containing up to 1,000 route request
and have them processed over a period of time. All the data is processed in
parallel on the server and when completed the full result set can be downloaded.

The table cross-references the Google Maps API parameters with the comparable API
parameters in Azure Maps.

Google Maps API Comparable Azure Maps API parameter


parameter

alternatives maxAlternatives

arrival_time arriveAt

avoid avoid

departure_time departAt

destination query – coordinates in the format "lat0,lon0:lat1,lon1…."

key subscription-key – For more information, see Authentication with


Google Maps API Comparable Azure Maps API parameter
parameter

Azure Maps.

language language – For more information, see Localization support in Azure


Maps.

mode travelMode

optimize computeBestOrder

origin query

region N/A – This feature is geocoding related. Use the countrySet parameter
when using the Azure Maps geocoding API.

traffic_model N/A – Can only specify if traffic data should be used with the traffic
parameter.

units N/A – Azure Maps only uses the metric system.

waypoints query

 Tip

By default, the Azure Maps route API only returns a summary. It returns the
distance and times and the coordinates for the route path. Use the
instructionsType parameter to retrieve turn-by-turn instructions. And, use the

routeRepresentation parameter to filter out the summary and route path.

Azure Maps routing API has other features that aren't available in Google Maps. When
migrating your app, consider using these features:

Support for route type: shortest, fastest, trilling, and most fuel efficient.
Support for other travel modes: bus, motorcycle, taxi, truck and van.
Support for 150 waypoints.
Compute multiple travel times in a single request; historic traffic, live traffic, no
traffic.
Avoid other road types: carpool roads, unpaved roads, already used roads.
Specify custom areas to avoid.
Limit the elevation that the route may ascend.
Route based on engine specifications. Calculate routes for combustion or electric
vehicles based on engine specifications and the remaining fuel or charge.
Support commercial vehicle route parameters. Such as vehicle dimensions, weight,
number of axels and cargo type.
Specify maximum vehicle speed.

In addition, the route service in Azure Maps supports Get Route Range. Calculating
routable ranges is also known as isochrones. It entails generating a polygon covering an
area that can be traveled to in any direction from an origin point. All under a specified
amount of time or amount of fuel or charge.

For more information, see best practices for routing.

Retrieve a map image


Azure Maps provides an API for rendering the static map images with data overlaid. The
Get Map Static Image API in Azure Maps is comparable to the static map API in Google
Maps.

7 Note

Azure Maps requires the center, all the marker, and the path locations to be
coordinates in "longitude,latitude" format. Whereas, Google Maps uses the
"latitude,longitude" format. Addresses will need to be geocoded first.

The table cross-references the Google Maps API parameters with the comparable API
parameters in Azure Maps.

Google Maps API Comparable Azure Maps API parameter


parameter

center center

format format – specified as part of URL path. Currently only PNG supported.

key subscription-key – For more information, see Authentication with Azure


Maps.

language language – For more information, see Localization support in Azure


Maps.

maptype layer and style – For more information, see Supported map styles.

markers pins

path path
Google Maps API Comparable Azure Maps API parameter
parameter

region N/A – A geocoding related feature. Use the countrySet parameter when
using the Azure Maps geocoding API.

scale N/A

size width and height – Max size is 8192 x 8192.

style N/A

visible N/A

zoom zoom

7 Note

In the Azure Maps tile system, tiles are twice the size of map tiles used in Google
Maps. As such the zoom level value in Azure Maps will appear one zoom level
closer in Azure Maps compared to Google Maps. To compensate for this difference,
decrement the zoom level in the requests you are migrating.

For more information, see Render custom data on a raster map.

In addition to being able to generate a static map image, the Azure Maps render service
enables direct access of map tiles in raster (PNG) and vector format:

Get Map Static Image: Retrieve raster (PNG) and vector tiles for the base maps
(roads, boundaries, background).
Get Map Tile: Retrieve aerial and satellite imagery tiles.

 Tip

Many Google Maps applications were switched from interactive map experiences to
static map images a few years ago. This was done as a cost saving method. In Azure
Maps, it is usually more cost effective to use the interactive map control in the Web
SDK. The interactive map control charges based the number of tile loads. Map tiles
in Azure Maps are large. Often, it takes only a few tiles to recreate the same map
view as a static map. Map tiles are cached automatically by the browser. As such,
the interactive map control often generates a fraction of a transaction when
reproducing a static map view. Panning and zooming will load more tiles; however,
there are options in the map control to disable this behavior. The interactive map
control also provides a lot more visualization options than the static map services.

Marker URL parameter format comparison


Before: Google Maps

Add markers using the markers parameter in the URL. The markers parameter takes in a
style and a list of locations to be rendered on the map with that style as shown below:

text

&markers=markerStyles|markerLocation1|markerLocation2|...

To add other styles, use the markers parameters to the URL with a different style and set
of locations.

Specify marker locations with the "latitude,longitude" format.

Add marker styles with the optionName:value format, with multiple styles separated by
pipe (|) characters like this "optionName1:value1|optionName2:value2". Note the option
names and values are separated with a colon (:). Use the following names of style option
to style markers in Google Maps:

color – The color of the default marker icon. Can be a 24-bit hex color ( 0xrrggbb )

or one of the following values; black , brown , green , purple , yellow , blue , gray ,
orange , red , white .
label – A single uppercase alphanumeric character to display on top of the icon.

size - The size of the marker. Can be tiny , mid , or small .

Use the following style options names for Custom icons in Google Maps:

anchor – Specifies how to align the icon image to the coordinate. Can be a pixel

(x,y) value or one of the following values; top , bottom , left , right , center ,
topleft , topright , bottomleft , or bottomright .

icon – A URL pointing to the icon image.

For example, let's add a red, mid-sized marker to the map at longitude: -110, latitude:
45:

text
&markers=color:red|size:mid|45,-110

After: Azure Maps

Add markers to a static map image by specifying the pins parameter in the URL. Like
Google Maps, specify a style and a list of locations in the parameter. The pins
parameter can be specified multiple times to support markers with different styles.

text

&pins=iconType|pinStyles||pinLocation1|pinLocation2|...

To use other styles, add extra pins parameters to the URL with a different style and set
of locations.

In Azure Maps, the pin location needs to be in the "longitude,latitude" format. Google
Maps uses "latitude,longitude" format. A space, not a comma, separates longitude and
latitude in the Azure Maps format.

The iconType specifies the type of pin to create. It can have the following values:

default – The default pin icon.

none – No icon is displayed, only labels are rendered.


custom – Specifies a custom icon is to be used. A URL pointing to the icon image

can be added to the end of the pins parameter after the pin location information.

Add pin styles with the optionNameValue format. Separate multiple styles with the pipe
(|) characters. For example: iconType|optionName1Value1|optionName2Value2 . The option
names and values aren't separated. Use the following style option names to style
markers:

al – Specifies the opacity (alpha) of the marker. Choose a number between 0 and

1.
an – Specifies the pin anchor. Specify X and y pixel values in the "x y" format.

co – The color of the pin. Specify a 24-bit hex color: 000000 to FFFFFF .
la – Specifies the label anchor. Specify X and y pixel values in the "x y" format.

lc – The color of the label. Specify a 24-bit hex color: 000000 to FFFFFF .
ls – The size of the label in pixels. Choose a number greater than 0.

ro – A value in degrees to rotate the icon. Choose a number between -360 and

360.
sc – A scale value for the pin icon. Choose a number greater than 0.

Specify label values for each pin location. This approach is more efficient than applying a
single label value to all markers in the list of locations. The label value can be a string of
multiple characters. Wrap the string with single quotes to ensure that it isn't mistaken as
a style or location value.

Let's add a red ( FF0000 ) default icon, with the label "Space Needle", positioned below
(15 50). The icon is at longitude: -122.349300, latitude: 47.620180:

text

&pins=default|coFF0000|la15 50||'Space Needle' -122.349300 47.620180


Add three pins with the label values '1', '2', and '3':

text

&pins=default||'1'-122 45|'2'-119.5 43.2|'3'-121.67 47.12


Path URL parameter format comparison
Before: Google Maps

Add lines and polygon to a static map image using the path parameter in the URL. The
path parameter takes in a style and a list of locations to be rendered on the map:

text

&path=pathStyles|pathLocation1|pathLocation2|...

Use other styles by adding extra path parameters to the URL with a different style and
set of locations.

Path locations are specified with the latitude1,longitude1|latitude2,longitude2|…


format. Paths can be encoded or contain addresses for points.

Add path styles with the optionName:value format, separate multiple styles by the pipe
(|) characters. Also separate option names and values with a colon (:). For example:
optionName1:value1|optionName2:value2 . The following style option names can be used

to style paths in Google Maps:

color – The color of the path or polygon outline. Can be a 24-bit hex color

( 0xrrggbb ), a 32-bit hex color ( 0xrrggbbbaa ) or one of the following values: black,
brown, green, purple, yellow, blue, gray, orange, red, white.
fillColor – The color to fill the path area with (polygon). Can be a 24-bit hex color

( 0xrrggbb ), a 32-bit hex color ( 0xrrggbbbaa ) or one of the following values: black,
brown, green, purple, yellow, blue, gray, orange, red, white.
geodesic – Indicates if the path should be a line that follows the curvature of the

earth.
weight – The thickness of the path line in pixels.

Add a red line opacity and pixel thickness to the map between the coordinates, in the
URL parameter. For the following example, the line has a 50% opacity and a thickness of
four pixels. The coordinates are longitude: -110, latitude: 45 and longitude: -100,
latitude: 50.

text

&path=color:0xFF000088|weight:4|45,-110|50,-100
After: Azure Maps

Add lines and polygons to a static map image by specifying the path parameter in the
URL. Like Google Maps, specify a style and a list of locations in this parameter. Specify
the path parameter multiple times to render multiple circles, lines, and polygons with
different styles.

text

&path=pathStyles||pathLocation1|pathLocation2|...

When it comes to path locations, Azure Maps requires the coordinates to be in


"longitude,latitude" format. Google Maps uses "latitude,longitude" format. A space, not
a comma, separates longitude and latitude in the Azure Maps format. Azure Maps
doesn't support encoded paths or addresses for points.

Add path styles with the optionNameValue format. Separate multiple styles by pipe (|)
characters, like this optionName1Value1|optionName2Value2 . The option names and values
aren't separated. Use the following style option names to style paths in Azure Maps:

fa - The fill color opacity (alpha) used when rendering polygons. Choose a

number between 0 and 1.


fc - The fill color used to render the area of a polygon.
la – The line color opacity (alpha) used when rendering lines and the outline of

polygons. Choose a number between 0 and 1.


lc – The line color used to render lines and the outline of polygons.

lw – The width of the line in pixels.

ra – Specifies a circles radius in meters.


Add a red line opacity and pixel thickness between the coordinates, in the URL
parameter. For the following example, the line has 50% opacity and a thickness of four
pixels. The coordinates have the following values: longitude: -110, latitude: 45 and
longitude: -100, latitude: 50.

text

&path=lcFF0000|la.5|lw4||-110 45|-100 50

Calculate a distance matrix


Azure Maps provides the distance matrix API. Use this API to calculate the travel times
and the distances between a set of locations, with a distance matrix. It's comparable to
the distance matrix API in Google Maps.

Post Route Matrix: Asynchronously calculates travel times and distances for a set of
origins and destinations. Supports up to 700 cells per request. That's the number
of origins multiplied by the number of destinations. With that constraint in mind,
examples of possible matrix dimensions are: 700x1, 50x10, 10x10, 28x25, 10x70.

7 Note

A request to the distance matrix API can only be made using a POST request with
the origin and destination information in the body of the request. Additionally,
Azure Maps requires all origins and destinations to be coordinates. Addresses will
need to be geocoded first.

This table cross-references the Google Maps API parameters with the comparable Azure
Maps API parameters.

Google Maps API Comparable Azure Maps API parameter


parameter

arrivial_time arriveAt

avoid avoid

depature_time departAt

destinations destination – specify in the POST request body as GeoJSON.

key subscription-key – For more information, see Authentication with


Azure Maps.

language language – For more information, see Localization support in


Azure Maps.

mode travelMode

origins origins – specify in the POST request body as GeoJSON.

region N/A – This feature is geocoding related. Use the countrySet


parameter when using the Azure Maps geocoding API.

traffic_model N/A – Can only specify if traffic data should be used with the
traffic parameter.

transit_mode N/A - Transit-based distance matrices aren't currently supported.

transit_routing_preference N/A - Transit-based distance matrices aren't currently supported.

units N/A – Azure Maps only uses the metric system.

 Tip

All the advanced routing options available in the Azure Maps routing API are
supported in the Azure Maps distance matrix API. Advanced routing options
include: truck routing, engine specifications, and so on.

For more information, see best practices for routing.


Get a time zone
Azure Maps provides an API for retrieving the time zone of a coordinate. The Azure
Maps time zone API is comparable to the time zone API in Google Maps:

Get Timezone By Coordinates: Specify a coordinate and receive the time zone
details of the coordinate.

This table cross-references the Google Maps API parameters with the comparable API
parameters in Azure Maps.

Google Maps API Comparable Azure Maps API parameter


parameter

key subscription-key – For more information, see Authentication with


Azure Maps.

language language – For more information, see Localization support in Azure


Maps.

location query

timestamp timeStamp

In addition to this API, Azure Maps provides many time zone APIs. These APIs convert
the time based on the names or the IDs of the time zone:

Get Timezone By ID: Returns current, historical, and future time zone information
for the specified IANA time zone ID.
Get Timezone Enum IANA: Returns a full list of IANA time zone IDs. Updates to the
IANA service are reflected in the system within one day.
Get Timezone Enum Windows: Returns a full list of Windows Time Zone IDs.
Get Timezone IANA Version: Returns the current IANA version number used by
Azure Maps.
Get Timezone Windows To IANA: Returns a corresponding IANA ID, given a valid
Windows Time Zone ID. Multiple IANA IDs may be returned for a single Windows
ID.

Client libraries
Azure Maps provides client libraries for the following programming languages:

JavaScript, TypeScript, Node.js – Azure Maps services module | npm package

These Open-source client libraries are for other programming languages:


.NET Standard 2.0 – GitHub project | NuGet package

Clean up resources
No resources to be cleaned up.

Next steps
Learn more about Azure Maps REST services:

Best practices for search


The Azure Maps Android SDK migration
guide
Article • 04/01/2025

Migrating from the Azure Maps Android SDK to the Web SDK in a WebView involves
transitioning your existing map view from a native implementation to a web-based map
using the Azure Maps Web SDK. This guide shows you how to migrate your code and
features from the Android SDK to the Web SDK.

7 Note

Azure Maps Android SDK retirement

The Azure Maps Native SDK for Android is now retired and no longer supported.
Use this guide to migrate to the Azure Maps Web SDK.

Prerequisites
To use the Map Control in a web page, you must have one of the following
prerequisites:

An Azure Maps account.


A subscription key or Microsoft Entra credentials. For more information, see
authentication options.

Create a WebView
Add a WebView if your Android application doesn't have one. Do so by adding the
WebView element to your layout XML or programmatically in your Java code. Be sure it's

configured to occupy the desired area of your layout.

XML

<?xml version="1.0" encoding="utf-8"?>


<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Enable internet access by adding permissions in AndroidManifest.xml.

XML

<uses-permission android:name="android.permission.INTERNET" />

In your activity or fragment, initialize the WebView and enable JavaScript by updating the
settings. Load the HTML file that contains the Web SDK code. You can either load it from
the assets folder or from a remote URL.

Java

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {

private WebView webView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);

// Enable JavaScript
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);

// Load local HTML file from /src/main/assets/map.html


webView.loadUrl("file:///android_asset/map.html");
}
}

Set up a map with Azure Maps Web SDK


In your HTML file, initialize a map with your subscription key. Replace
<YOUR_SUBSCRIPTION_KEY> with your actual key.

HTML

<!DOCTYPE html>
<html>
<head>
<title>Azure Maps</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"
/>
<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css"/>
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>
<style>
html,
body,
#map {
margin: 0;
height: 100%;
width: 100%;
}
body {
display: flex;
flex-direction: column;
}
main {
flex: 1 1 auto;
}
</style>
<script type="text/javascript">
// Create an instance of the map control.
function InitMap() {
var map = new atlas.Map("map", {
center: [-122.33, 47.6],
zoom: 12,
authOptions: {
authType: "subscriptionKey",
subscriptionKey: "<YOUR_SUBSCRIPTION_KEY>"
}
});

// Wait until the map resources are ready.


map.events.add("ready", function () {
// Resize the map to fill the container.
map.resize();
});
}
</script>
</head>
<body onload="InitMap()">
<main>
<div id="map"></div>
</main>
</body>
</html>

Save and run the app. A map will appear within a WebView. Add any required features
or functionality from the Web SDK. For more information, see Azure Maps
Documentation and Azure Maps Samples .
Communication between native code and
WebView (optional)
To enable communication between your Android application and the WebView, you can
use the WebView's addJavascriptInterface method to expose a Java object to the
JavaScript running in the WebView. It allows you to call Java methods from your
JavaScript code. For more information, see WebView in the Android documentation.

Clean Up Native Map Implementation


Remove code related to the native Azure Maps Android SDK, including dependencies
and initialization code related to com.azure.android:azure-maps-control .

Testing
Test your application thoroughly to ensure the migration was successful. Check for
issues related to map functionality, user interactions, and performance.

Next steps
Learn how to add maps to web and mobile applications using the Map Control client-
side JavaScript library in Azure Maps:

Use the Azure Maps map control


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


The Azure Maps iOS SDK migration
guide
Article • 04/01/2025

Migrating from the Azure Maps iOS SDK to the Web SDK in a WebView involves
transitioning your existing map view from a native implementation to a web-based map
using the Azure Maps Web SDK. This guide shows you how to migrate your code and
features from the iOS SDK to the Web SDK.

7 Note

Azure Maps iOS SDK retirement

The Azure Maps Native SDK for iOS is now retired and no longer supported. Use
this guide to migrate to the Azure Maps Web SDK.

Prerequisites
To use the Map Control in a web page, you must have one of the following
prerequisites:

An Azure Maps account.


A subscription key or Microsoft Entra credentials. For more information, see
authentication options.

Create a WebView
Add a WebView if your iOS application doesn't have one. Do so by adding the
WKWebView to your storyboard or programmatically in your Swift code. Be sure it's

configured to occupy the desired area of your layout.

Swift

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

var webView: WKWebView!

override func viewDidLoad() {


super.viewDidLoad()

// Create WKWebView instance


webView = WKWebView(frame: view.bounds)
webView.navigationDelegate = self
view.addSubview(webView)

// Load local HTML file


loadLocalHTMLFile()
}

func loadLocalHTMLFile() {
if let htmlPath = Bundle.main.path(forResource: "map", ofType:
"html") {
do {
let htmlString = try String(contentsOfFile: htmlPath,
encoding: .utf8)
webView.loadHTMLString(htmlString, baseURL:
Bundle.main.bundleURL)
} catch {
print("Error loading HTML file: \(error)")
}
} else {
print("HTML file not found.")
}
}
}

Set up a map with Azure Maps Web SDK


In your HTML file, initialize a map with your subscription key. Replace
<YOUR_SUBSCRIPTION_KEY> with your actual key.

HTML

<!DOCTYPE html>
<html>
<head>
<title>Azure Maps</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"
/>
<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css"/>
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>
<style>
html,
body,
#map {
margin: 0;
height: 100%;
width: 100%;
}
body {
display: flex;
flex-direction: column;
}
main {
flex: 1 1 auto;
}
</style>
<script type="text/javascript">
// Create an instance of the map control.
function InitMap() {
var map = new atlas.Map("map", {
center: [-122.33, 47.6],
zoom: 12,
authOptions: {
authType: "subscriptionKey",
subscriptionKey: "<YOUR_SUBSCRIPTION_KEY>"
}
});

// Wait until the map resources are ready.


map.events.add("ready", function () {
// Resize the map to fill the container.
map.resize();
});
}
</script>
</head>
<body onload="InitMap()">
<main>
<div id="map"></div>
</main>
</body>
</html>

Save and run the app. A map should be shown within a WebView. Add any features or
functionalities that you want to use from the Web SDK. You can refer to the Azure Maps
Documentation and the Azure Maps Samples for more use cases.
Communication between native code and
WebView (optional)
To enable communication between your iOS application and the WebView, you can use
the WKScriptMessageHandler protocol provided by the WKWebView class. It allows you to
establish a bridge for communication between JavaScript running in the WebView and
your Swift code. For more information, see WKScriptMessageHandler in the iOS
WebKit documentation.

Clean Up Native Map Implementation


Remove code related to the native Azure Maps iOS SDK from your project, including
dependencies and initialization code related to azure-maps-ios-sdk-distribution .

Testing
Test your application thoroughly to ensure that the migration was successful. Check for
issues related to map functionality, user interactions, and performance.

Next steps
Learn how to add maps to web and mobile applications using the Map Control client-
side JavaScript library in Azure Maps:

Use the Azure Maps map control


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Migrate Azure Maps Route 1.0 APIs
Article • 03/18/2025

This article explains how to migrate the Azure Maps Route v1.0 APIs to Azure Maps
Route v2025-01-01 APIs. The following table shows the Route v1.0 APIs and the
migration options.

ノ Expand table

Azure Maps Route Azure Maps Route v2025-01-01 migration options


v1.0

Get Route Directions Post Route Directions: Get Route Directions is no longer supported.

Get Route Directions Route Directions async batch is currently unavailable. Instead use Post
Batch Route Directions Batch.

Post Route Directions Post Route Directions

Post Route Directions Post Route Directions Batch: Route Directions async batch is currently
Batch unavailable, instead use sync batch.

Post Route Directions Post Route Directions Batch


Batch Sync

Get Route Matrix Get Route Operation Result: Use to get result of Route Matrix async
calls.
Get Route Operations Status: Use to get status of Route Matrix async
calls.

Post Route Matrix Post Route Matrix Async

Post Route Matrix Sync Post Route Matrix

Get Route Range Post Route Range: The GET request is no longer supported.

Notable differences

Route Directions notable differences

ノ Expand table
Feature v1.0 v2025-01-01

Batch Sync and async requests Sync requests


operations

Coordinate Latitude/longitude Longitude/latitude, as defined by


format GeoJSON .

Electric Supported Not supported


consumption
model

Localization Use the "language" parameter to Use the “Accept-Language” request header
localize the language of the to input a localization code to localize the
route instructions. language of the route instructions.

Request type GET, POST POST

Response XML, JSON GeoJSON


format

Travel mode Car, truck, pedestrian. Car, truck, pedestrian.


Beta profiles: Bus, bicycle,
motorcycle, taxi, van.

Waypoint Supported Currently only supported for truck routing.


Optimization

Waypoints Supported Supported. Also supports viaWaypoints for


driving and walking modes.

Route Matrix notable differences

ノ Expand table

Feature v1.0 v2025-01-01

Coordinate format Longitude/latitude Longitude/latitude

Electric Supported Not supported


consumption model

Input coordinates Uses GeoJSON MultiPoint features for A valid GeoJSON MultiPoint
input coordinates, but the request is in geometry type .
JSON.

Matrix: Up to 700 cells Up to 50,000 cells


Asynchronous
requests
Feature v1.0 v2025-01-01

Matrix: Synchronous Up to 100 cells Up to 2,500 cells


requests

Response format JSON GeoJSON (input and


response)

Travel mode Car, truck, pedestrian. Car, truck, pedestrian.


Beta profiles: Bus, bicycle, motorcycle, taxi,
van.

Route Range notable differences

ノ Expand table

Feature V1.0 V2025-01-01

Coordinate format Latitude/Longitude Longitude/latitude, as defined by


GeoJSON .

Electric consumption Supported Not Supported


model

Request type GET, POST POST

Response format XML, JSON GeoJSON (input and response)

Travel modes Car, Truck. Car, Truck


Beta profiles: bus, motorcycle,
taxi, van

Transactions usage
For information on how transactions are calculated, see Understanding Azure Maps
Transactions.

Route service examples


This section provides example requests and responses for both version 1.0 and 2025-01-
01 for the Route Direction, Route Matrix and Route Range API.

Route Directions examples


Route Directions version 1.0 example request
The Route Directions API in version 1.0 is an HTTP GET request. All parameters are
passed as query string parameters.

HTTP

https://atlas.microsoft.com/route/directions/json?api-
version=1.0&query=52.50931,13.42936:52.50895,13.42904&subscription-key=
{Your-Azure-Maps-Subscription-key}

Route Directions version 2025-01-01 example request


The Route Directions API in version 2025-01-01 is an HTTP POST request. Parameters
can be included in the API call as query string parameters, with more parameters
provided in the request body using GeoJSON format.

HTTP

https://atlas.microsoft.com/route/directions/json?api-version=2025-01-
01&subscription-key={Your-Azure-Maps-Subscription-key}

Parameters included in the body of the HTTP POST request are provided as GeoJSON.

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"coordinates": [
13.42936,52.50931
],
"type": "Point"
},
"properties": {
"pointIndex": 0,
"pointType": "waypoint"
}
},
{
"type": "Feature",
"geometry": {
"coordinates": [
13.42904,52.50895
],
"type": "Point"
},
"properties": {
"pointIndex": 1,
"pointType": "waypoint"
}
}
]
}

Route Directions version 1.0 response example

JSON

{
"formatVersion": "0.0.12",
"routes": [
{
"summary": {
"lengthInMeters": 46,
"travelTimeInSeconds": 4,
"trafficDelayInSeconds": 0,
"trafficLengthInMeters": 0,
"departureTime": "2025-02-19T05:40:44+01:00",
"arrivalTime": "2025-02-19T05:40:47+01:00"
},
"legs": [
{
"summary": {
"lengthInMeters": 46,
"travelTimeInSeconds": 4,
"trafficDelayInSeconds": 0,
"trafficLengthInMeters": 0,
"departureTime": "2025-02-19T05:40:44+01:00",
"arrivalTime": "2025-02-19T05:40:47+01:00"
},
"points": [
{
"latitude": 52.50931,
"longitude": 13.42937
},
{
"latitude": 52.50904,
"longitude": 13.42913
},
{
"latitude": 52.50895,
"longitude": 13.42904
}
]
}
],
"sections": [
{
"startPointIndex": 0,
"endPointIndex": 2,
"sectionType": "TRAVEL_MODE",
"travelMode": "car"
}
]
}
]
}

Route Directions version 2025-01-01 response example

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
13.429368,
52.509303
]
},
"properties": {
"routePathPoint": {
"legIndex": 0,
"pointIndex": 0
},
"order": {
"inputIndex": 0
},
"type": "Waypoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
13.429045,
52.50895
]
},
"properties": {
"routePathPoint": {
"legIndex": 0,
"pointIndex": 3
},
"order": {
"inputIndex": 1
},
"type": "Waypoint"
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": [
[
[
13.429368,
52.509302
],
[
13.429225,
52.509145
],
[
13.429128,
52.509038
],
[
13.429044,
52.50895
]
]
],
"bbox": [
13.429044,
52.50895,
13.429368,
52.509302
]
},
"properties": {
"resourceId": "v70,h822083589,i0,a0,cen-
US,dAAAAAAAAAAA1,y0,s1,m1,o1,t0,wTMPwETFBSkDPa-
wS1dsqQA2~~~~~~~~~~v12,wTKYKRiVBSkAIWoEhq9sqQA2~~~~~~~~~~v12,k1,qatt:1",
"trafficCongestion": "Heavy",
"trafficDataUsed": "None",
"distanceInMeters": 44,
"durationInSeconds": 3,
"departureAt": "2025-02-19T05:41:07+00:00",
"arrivalAt": "2025-02-19T05:41:10+00:00",
"type": "RoutePath",
"legs": [
{
"distanceInMeters": 44,
"durationInSeconds": 3,
"departureAt": "2025-02-19T05:41:07+00:00",
"arrivalAt": "2025-02-19T05:41:10+00:00",
"routePathRange": {
"legIndex": 0,
"range": [
0,
3
]
},
"description": "An der Schillingbrücke"
}
]
}
}
]
}

Route Matrix examples

Route Matrix version 1.0 example request


The Post Route Matrix Sync API in version 1.0 is an HTTP POST request. Parameters can
be passed as query string parameters and in the body of the request using the GeoJSON
format.

HTTP

https://atlas.microsoft.com/route/matrix/sync/json?api-
version=1.0&travelMode=car&subscription-key={Your-Azure-Maps-Subscription-
key}

Parameters included in the body of the HTTP POST request are provided as JSON.

JSON

{
"origins": {
"type": "MultiPoint",
"coordinates": [
[
4.85106,
52.36006
],
[
4.85056,
52.36187
]
]
},
"destinations": {
"type": "MultiPoint",
"coordinates": [
[
4.85003,
52.36241
]
]
}
}

Route Matrix version 2025-01-01 example request


The Route Matrix API in version 2025-01-01 is an HTTP POST request. Parameters are
passed as query string parameters and in the body of the request using the GeoJSON
format.

HTTP

https://atlas.microsoft.com/route/matrix/json?api-version=2025-01-
01&subscription-key={Your-Azure-Maps-Subscription-key}

Parameters included in the body of the HTTP POST request are provided as GeoJSON.

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
4.85106,
52.36006
],
[
4.85056,
52.36187
]
]
},
"properties": {
"pointType": "origins"
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
4.85003,
52.36241
]
]
},
"properties": {
"pointType": "destinations"
}
}
],
"travelmode":"driving"
}

Route Matrix version 1.0 response example

JSON

{
"formatVersion": "0.0.1",
"matrix": [
[
{
"statusCode": 200,
"response": {
"routeSummary": {
"lengthInMeters": 494,
"travelTimeInSeconds": 124,
"trafficDelayInSeconds": 0,
"trafficLengthInMeters": 0,
"departureTime": "2025-02-19T06:30:23+01:00",
"arrivalTime": "2025-02-19T06:32:27+01:00"
}
}
}
],
[
{
"statusCode": 200,
"response": {
"routeSummary": {
"lengthInMeters": 337,
"travelTimeInSeconds": 106,
"trafficDelayInSeconds": 0,
"trafficLengthInMeters": 0,
"departureTime": "2025-02-19T06:30:23+01:00",
"arrivalTime": "2025-02-19T06:32:08+01:00"
}
}
}
]
],
"summary": {
"successfulRoutes": 2,
"totalRoutes": 2
}
}

Route Matrix version 2025-01-01 response example

JSON

{
"type": "Feature",
"geometry": null,
"properties": {
"summary": {
"totalCount": 2,
"successfulCount": 2
},
"matrix": [
{
"statusCode": 200,
"originIndex": 0,
"destinationIndex": 0,
"durationTrafficInSeconds": 129,
"durationInSeconds": 129,
"distanceInMeters": 494
},
{
"statusCode": 200,
"originIndex": 1,
"destinationIndex": 0,
"durationTrafficInSeconds": 110,
"durationInSeconds": 110,
"distanceInMeters": 338
}
]
}
}

Route Range examples

Route Range version 1.0 example request


The Route Range API in version 1.0 is an HTTP GET request. All parameters are passed as
query string parameters.
HTTP

https://atlas.microsoft.com/route/range/json?api-
version=1.0&query=50.97452,5.86605&travelmode=car&distanceBudgetInMeters=15&
subscription-key={Your-Azure-Maps-Subscription-key}

Route Range version 2025-01-01 example request


The Route Range API in version 2025-01-01 is an HTTP POST request. Parameters can be
included in the API call as query string parameters, with more parameters provided in
the request body using GeoJSON format.

HTTP

https://atlas.microsoft.com/route/range?api-version=2025-01-01&subscription-
key={Your-Azure-Maps-Subscription-key}

Parameters included in the body of the HTTP POST request are provided as GeoJSON.

JSON

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
5.86605,50.97452
]
},
"properties": {
"distanceBudgetInMeters": 15,
"travelMode": "driving"
}
}

Route Range version 1.0 response example


Response results are truncated for brevity.

JSON

{
"formatVersion": "0.0.1",
"reachableRange": {
"center": {
"latitude": 50.97452,
"longitude": 5.86605
},
"boundary": [
{
"latitude": 50.97452,
"longitude": 5.86605
},
{
"latitude": 50.97452,
"longitude": 5.86605
},
{
"latitude": 50.97452,
"longitude": 5.86605
},
{
"latitude": 50.97452,
"longitude": 5.86605
}
]
}
}

Route Range version 2025-01-01 response example


Response results are truncated for brevity.

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
5.86605,
50.97452
]
},
"properties": {
"type": "center"
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
5.86605,50.97452
],
[
5.8659, 50.97454
],
[
5.86584, 50.9745
],
[
5.86588, 50.97448
]
]
],
"bbox": [
5.86584,
50.97447,
5.86626,
50.97454
]
},
"properties": {
"type": "boundary"
}
}
]
}

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Migrate Azure Maps Traffic 1.0 APIs
Article • 03/24/2025

This article provides guidance on migrating the Azure Maps Traffic v1 service to other
Azure Maps services.

The following table outlines all Traffic service along with their respective migration
options.

ノ Expand table

Azure Maps Traffic Azure Maps migration option


v1.0

Get Traffic Flow No direct replacement.


Segment Map tiles can be used to visualize traffic flow, but speed and travel time
isn't available.

Get Traffic Flow Tile Get Map Tile


- Absolute TilesetID
- Reduced - microsoft.traffic.absolute (vector)
sensitivity - microsoft.traffic.absolute.main (raster)
- Relative - microsoft.traffic.relative (vector)
- Relative delay - microsoft.traffic.relative.dark (raster)
- microsoft.traffic.relative.main (raster)
- microsoft.traffic.delay (vector)
- microsoft.traffic.delay.main (raster)
- microsoft.traffic.reduced.main (raster)

Get Traffic Incident Get Traffic Incident


Detail

Get Traffic Incident Get Map Tile


Tile TilesetID
- microsoft.traffic.incident (vector)

Get Traffic Incident No replacement.


Viewport Returns the traffic model ID used by Traffic v1 service, but isn't required for
the latest traffic or render services.

Notable differences
Unlike the Traffic v1.0 service, the latest Azure Maps Get Traffic Incident API and
the Render service Get Map Tile API don't require a traffic model ID.
The Get Traffic Incident v2025-01-01 input bounding box and response are in the
GeoJSON format.

Traffic Flow Segment v1.0 provides information about vehicle speeds and travel
times of the road segment. This information isn't available in the latest version, but
the traffic data can be visualized using the Render Get Map Tile API.

To assign an icon category to the points returned by Get Traffic Incident v2025-01-
01, use the incidentType enum provided in the response.

Traffic map tiles are available in vector and raster format in the Render service
using the Get Map Tile API.

Transactions usage
For information on how transactions are calculated for the Traffic and Render services,
see Understanding Azure Maps Transactions.

Traffic service examples


This section provides example requests and responses for version 1.0 and 2025-01-01 of
the Traffic Incident API and version 2024-04-01 the Render Map Tile API.

Traffic Incident version 1.0 example


Version 1.0 of the Traffic Incident API is an HTTP GET request that returns all traffic
incidents within the specified bounding box.

HTTP

https://atlas.microsoft.com/traffic/incident/detail/json?api-
version=1.0&style=s3&boundingbox=37,-105,45,-94&boundingZoom=11&trafficmodel
id=1335294634919&projection=EPSG4326&subscription-key={Your-Azure-Maps-
Subscription-key}

The response contains all traffic incidents within the specified bounding box in JSON
format. The results are truncated for brevity.

JSON

{
"tm": {
"@id": "1742459680",
"poi": [
{
"id": "CLUSTER_80251",
"p": {
"x": -105.0012712,
"y": 39.7117135
},
"ic": 8,
"ty": 0,
"cbl": {
"x": -105.0038575,
"y": 39.7096459
},
"ctr": {
"x": -104.99992,
"y": 39.7148278
},
"cs": 4,
"l": 1132
},
{
"id": "CLUSTER_80249",
"p": {
"x": -105.0070862,
"y": 39.7491353
},
"ic": 13,
"ty": 0,
"cbl": {
"x": -105.0214434,
"y": 39.7391984
},
"ctr": {
"x": -104.9985481,
"y": 39.7597951
},
"cs": 12,
"l": 2276
}
]
}
}

Traffic Incident version 2025-01-01 example


Version 2025-01-01 of the Traffic Incident API is an HTTP GET request that returns all
traffic incidents within the specified bounding box.

HTTP
https://atlas.microsoft.com/traffic/incident?api-version=2025-01-
01&bbox=-105,37,-94,45&subscription-key={Your-Azure-Maps-Subscription-key}

The response contains all traffic incidents within the specified bounding box in GeoJSON
format. The following example shows a single traffic incident of type "Accident":

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 18558549332008001,
"geometry": {
"type": "Point",
"coordinates": [
-104.939053,
39.682642
]
},
"properties": {
"startTime": "2025-09-12T09:31:37Z",
"endTime": "2025-09-12T10:21:47Z",
"description": "At CO 2/Colorado Boulevard (Denver) at Mile Point
204. Two right lanes are closed due to a crash.",
"title": "I-25 N / US-87 N",
"incidentType": "Accident",
"severity": 4,
"delay": null,
"lastModified": "2025-09-12T10:21:47Z",
"endPoint": {
"type": "Point",
"coordinates": [
-104.940412,
39.68307
]
},
"isTrafficJam": false,
"isRoadClosed": false
}
}
]
}

Azure Maps Render Get Map Tile v2024-04-01


The Azure Maps Render Get Map Tile API is an HTTP GET request that returns relative
traffic vector tiles.
Example Request

HTTP

https://atlas.microsoft.com/map/tile?api-version=2024-04-
01&tilesetId=microsoft.traffic.relative&zoom=6&x=10&y=22&subscription-key=
{Your-Azure-Maps-Subscription-key}

Example Response

Content-Type: application/vnd.mapbox-vector-tile

"binary image string"

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Create your Azure Maps account using
an ARM template
Article • 03/07/2024

You can create your Azure Maps account using an Azure Resource Manager (ARM)
template. After you have an account, you can implement the APIs in your website or
mobile application.

An Azure Resource Manager template is a JavaScript Object Notation (JSON) file that
defines the infrastructure and configuration for your project. The template uses
declarative syntax. You describe your intended deployment without writing the
sequence of programming commands to create the deployment.

If your environment meets the prerequisites and you're familiar with using ARM
templates, select the Deploy to Azure button. The template opens in the Azure portal.

Prerequisites
To complete this article:

If you don't have an Azure subscription, create a free account before you begin.

Review the template


The template used in this quickstart is from Azure Quickstart Templates .

JSON

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-
01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.25.53.49325",
"templateHash": "695164742048978243"
}
},
"parameters": {
"accountName": {
"type": "string",
"defaultValue": "[uniqueString(resourceGroup().id)]",
"metadata": {
"description": "The name for your Azure Maps account. This value
must be globally unique."
}
},
"location": {
"type": "string",
"allowedValues": [
"westeurope",
"eastus",
"westus2",
"northeurope",
"westcentralus",
"usgovvirginia",
"usgovarizona"
],
"metadata": {
"description": "Specifies the location for all the resources."
}
},
"pricingTier": {
"type": "string",
"defaultValue": "G2",
"allowedValues": [
"G2"
],
"metadata": {
"description": "The pricing tier SKU for the account."
}
},
"kind": {
"type": "string",
"defaultValue": "Gen2",
"allowedValues": [
"Gen2"
],
"metadata": {
"description": "The pricing tier for the account."
}
}
},
"resources": [
{
"type": "Microsoft.Maps/accounts",
"apiVersion": "2023-06-01",
"name": "[parameters('accountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('pricingTier')]"
},
"kind": "[parameters('kind')]"
}
]
}

The Azure Maps account resource is defined in this template:

Microsoft.Maps/accounts: create an Azure Maps account.

Deploy the template


1. Select the following image to sign in to Azure and open a template. The template
creates an Azure Maps account.

2. Select or enter the following values.


Unless it's specified, use the default value to create your Azure Maps account.

Subscription: select an Azure subscription.


Resource group: select Create new, enter a unique name for the resource
group, and then select OK.
Location: select a location.
Account Name: enter a name for your Azure Maps account, which must be
globally unique.
Pricing Tier: select the appropriate pricing tier, the default value for the
template is G2.

3. Select Review + create.


4. Confirm your settings on the review page and select Create. Once deployed
successfully, you get a notification:

The Azure portal is used to deploy your template. You can also use the Azure
PowerShell, Azure CLI, and REST API. To learn other deployment methods, see Deploy
templates.

Review deployed resources


You can use the Azure portal to check your Azure Maps account and view your keys. You
can also use the following Azure CLI script to list your account keys.

Azure CLI

az maps account keys list --name MyMapsAccount --resource-group


MyResourceGroup

Clean up resources
When no longer needed, delete the resource group, which also deletes the Azure Maps
account. To delete the resource group by using Azure CLI:

Azure CLI

az group delete --name MyResourceGroup

Next steps
To learn more about Azure Maps and Azure Resource Manager, see the following
articles:

Create an Azure Maps demo application


Learn more about ARM templates
Manage your Azure Maps account
Article • 04/14/2023

You can manage your Azure Maps account through the Azure portal. After you have an
account, you can implement the APIs in your website or mobile application.

Prerequisites
If you don't already have an Azure account, sign up for a free account before
you continue.
For picking account location, if you're unfamiliar with managed identities for Azure
resources, see managed identities for Azure resources.

Account location
Picking a location for your Azure Maps account that aligns with other resources in your
subscription, like managed identities, may help to improve the level of service for
control-plane operations.

As an example, the managed identity infrastructure notifies the Azure Maps


management services for changes to the identity resource such as credential renewal or
deletion. Sharing the same Azure location enables a consistent infrastructure
provisioning for all resources.

An Azure Maps account, regardless of location, can access any endpoint belonging to
the Azure data-plane, such as atlas.microsoft.com and *.atlas.microsoft.com , when
using Azure Maps REST API.

Read more about data-plane service coverage for Azure Maps services on geographic
coverage.

Create a new account


1. Sign in to the Azure portal .

2. Select Create a resource in the upper-left corner of the Azure portal.

3. Search for and select Maps. Then select Create.

4. Enter the information for your new account.


Delete an account
You can delete an account from the Azure portal. Navigate to the account overview
page and select Delete.

You then see a confirmation page. You can confirm the deletion of your account by
typing its name.

Next steps
Set up authentication with Azure Maps and learn how to get an Azure Maps
subscription key:

Manage authentication

Learn how to manage an Azure Maps account pricing tier:

Manage a pricing tier

Learn how to see the API usage metrics for your Azure Maps account:

View usage metrics


Manage authentication in Azure Maps
Article • 10/12/2023

When you create an Azure Maps account, your client ID and shared keys are created
automatically. These values are required for authentication when using either [Microsoft
Entra ID] or Shared Key authentication.

Prerequisites
Sign in to the Azure portal . If you don't have an Azure subscription, create a free
account before you begin.

A familiarization with managed identities for Azure resources. Be sure to


understand the two Managed identity types and how they differ.
An Azure Maps account.
A familiarization with Azure Maps Authentication.

View authentication details

) Important

We recommend that you use the primary key as the subscription key when you use
Shared Key authentication to call Azure Maps. It's best to use the secondary key in
scenarios like rolling key changes.

To view your Azure Maps authentication details:

1. Sign in to the Azure portal .

2. Select All resources in the Azure services section, then select your Azure Maps
account.
3. Select Authentication in the settings section of the left pane.

Choose an authentication category


Depending on your application needs, there are specific pathways to application
security. Microsoft Entra ID defines specific authentication categories to support a wide
range of authentication flows. To choose the best category for your application, see
application categories.

7 Note

Understanding categories and scenarios will help you secure your Azure Maps
application, whether you use Microsoft Entra ID or shared key authentication.

How to add and remove managed identities


To enable Shared access signature (SAS) token authentication with the Azure Maps REST
API, you need to add a user-assigned managed identity to your Azure Maps account.

Create a managed identity


You can create a user-assigned managed identity before or after creating a map
account. You can add the managed identity through the portal, Azure management
SDKs, or the Azure Resource Manager (ARM) template. To add a user-assigned managed
identity through an ARM template, specify the resource identifier of the user-assigned
managed identity.

JSON

"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/00000000-0000-0000-0000-
000000000000/resourceGroups/example/providers/Microsoft.ManagedIdentity/user
AssignedIdentities/exampleidentity": {}
}
}

Remove a managed identity


You can remove a system-assigned identity by disabling the feature through the portal
or the Azure Resource Manager template in the same way that it was created. User-
assigned identities can be removed individually. To remove all identities, set the identity
type to "None" .

Removing a system-assigned identity in this way also deletes it from Microsoft Entra ID.
System-assigned identities are also automatically removed from Microsoft Entra ID
when the Azure Maps account is deleted.
To remove all identities by using the Azure Resource Manager template, update this
section:

JSON

"identity": {
"type": "None"
}

Choose an authentication and authorization


scenario
This table outlines common authentication and authorization scenarios in Azure Maps.
Each scenario describes a type of app that can be used to access Azure Maps REST API.
Use the links to learn detailed configuration information for each scenario.

) Important

For production applications, we recommend implementing Microsoft Entra ID with


Azure role-based access control (Azure RBAC).

Scenario Authentication Authorization Development Operational


effort effort

Trusted daemon app or Shared Key N/A Medium High


non-interactive client
app

Trusted daemon or non- Microsoft Entra High Low Medium


interactive client app ID

Web single page app Microsoft Entra High Medium Medium


with interactive single- ID
sign-on

Web single page app Microsoft Entra High Medium Medium


with non-interactive ID
sign-on

Web app, daemon app, SAS Token High Medium Low


or non-interactive sign-
on app

Web application with Microsoft Entra High High Medium


interactive single-sign- ID
Scenario Authentication Authorization Development Operational
effort effort

on

IoT device or an input Microsoft Entra High Medium Medium


constrained application ID

View built-in Azure Maps role definitions


To view the built-in Azure Maps role definition:

1. In the left pane, select Access control (IAM).

2. Select the Roles tab.

3. In the search box, enter Azure Maps.

The results display the available built-in role definitions for Azure Maps.

View role assignments


To view users and apps that have been granted access for Azure Maps, go to Access
Control (IAM). There, select Role assignments, and then filter by Azure Maps.

1. In the left pane, select Access control (IAM).

2. Select the Role assignments tab.

3. In the search box, enter Azure Maps.

The results display the current Azure Maps role assignments.


Request tokens for Azure Maps
Request a token from the Microsoft Entra token endpoint. In your Microsoft Entra ID
request, use the following details:

Azure environment Microsoft Entra token endpoint Azure resource ID

Azure public cloud https://login.microsoftonline.com https://atlas.microsoft.com/

Azure Government cloud https://login.microsoftonline.us https://atlas.microsoft.com/

For more information about requesting access tokens from Microsoft Entra ID for users
and service principals, see [Authentication scenarios for Microsoft Entra ID]. To view
specific scenarios, see the table of scenarios.

Manage and rotate shared keys


Your Azure Maps subscription keys are similar to a root password for your Azure Maps
account. Always be careful to protect your subscription keys. Use Azure Key Vault to
securely manage and rotate your keys. Avoid distributing access keys to other users,
hard-coding them, or saving them anywhere in plain text that's accessible to others. If
you believe that your keys may have been compromised, rotate them.

7 Note
If possible, we recommend using Microsoft Entra ID instead of Shared Key to
authorize requests. Microsoft Entra ID has better security than Shared Key, and it's
easier to use.

Manually rotate subscription keys


To help keep your Azure Maps account secure, we recommend periodically rotating your
subscription keys. If possible, use Azure Key Vault to manage your access keys. If you
aren't using Key Vault, you need to manually rotate your keys.

Two subscription keys are assigned so that you can rotate your keys. Having two keys
ensures that your application maintains access to Azure Maps throughout the process.

To rotate your Azure Maps subscription keys in the Azure portal:

1. Update your application code to reference the secondary key for the Azure Maps
account and deploy.
2. In the Azure portal , navigate to your Azure Maps account.
3. Under Settings, select Authentication.
4. To regenerate the primary key for your Azure Maps account, select the Regenerate
button next to the primary key.
5. Update your application code to reference the new primary key and deploy.
6. Regenerate the secondary key in the same manner.

2 Warning

We recommend using the same key in all your applications. If you use the primary
key in some places and the secondary key in others, you won't be able to rotate
your keys without some applications losing access.

Next steps
Find the API usage metrics for your Azure Maps account:

View usage metrics

Explore samples that show how to integrate Microsoft Entra ID with Azure Maps:

[Microsoft Entra authentication samples]


Secure a daemon application
Article • 10/12/2023

This article describes how to host daemon applications in a trusted and secure
environment in Microsoft Azure Maps.

The following are examples of daemon applications:

Azure Web Job


Azure Function App
Windows Service
A running and reliable background service

View Azure Maps authentication details


To view your Azure Maps account authentication details in the Azure portal:

1. Sign in to the Azure portal .

2. Navigate to the Azure portal menu. Select All resources, and then select your
Azure Maps account.

3. Under Settings in the left pane, select Authentication.

Three values are created when the Azure Maps account is created. They're used to
support two types of authentication in Azure Maps:
Microsoft Entra authentication: The Client ID represents the account that is to
be used for REST API requests. The Client ID value should be stored in
application configuration, and then it should be retrieved before making Azure
Maps HTTP requests that use Microsoft Entra authentication.
Shared Key Authentication: The Primary Key and Secondary Key are used as the
subscription key for Shared Key authentication. Shared Key authentication relies on
passing the key generated by the Azure Maps account with each request to Azure
Maps. We recommend that you regularly regenerate your keys. To maintain current
connections during regeneration, two keys are provided. One key can be in use,
while regenerating the other. When you regenerate your keys, you must update
any applications that access this account to use the new keys. For more
information, see Authentication with Azure Maps

) Important

For production applications, we recommend implementing Microsoft Entra ID and


Azure role-based access control (Azure RBAC). For an overview of Microsoft Entra
concepts, see Authentication with Azure Maps.

Scenario: Shared key authentication with Azure


Key Vault
Applications that use Shared Key authentication, should store the keys in a secure store.
This scenario describes how to safely store your application key as a secret in Azure Key
Vault. Instead of storing the shared key in application configuration, the application can
retrieve the shared key as an Azure Key Vault secret. To simplify key regeneration, we
recommend that applications use one key at a time. Applications can then regenerate
the unused key and deploy the regenerated key to Azure Key Vault while still
maintaining current connections with one key. To understand how to configure Azure
Key Vault, see Azure Key Vault developer guide.

) Important

This scenario indirectly accesses Microsoft Entra ID through Azure Key Vault.
However, we recommend that you use Microsoft Entra authentication directly.
Using Microsoft Entra ID directly avoids the additional complexity and operational
requirements of using shared key authentication and setting up Key Vault.

The following steps outline this process:


1. Create an Azure Key Vault.
2. Create an Microsoft Entra service principal by creating an App registration or
managed identity. The created principal is responsible for accessing the Azure Key
Vault.
3. Assign the service principal access to Azure Key secrets get permission. For details
about how to set permissions, see Assign a Key Vault access policy using the Azure
portal.
4. Temporarily assign access to secrets set permission for you as the developer.
5. Set the shared key in the Key Vault secrets and reference the secret ID as
configuration for the daemon application.
6. Remove your secrets set permission.
7. To retrieve the shared key secret from Azure Key Vault, implement Microsoft Entra
authentication in the daemon application.
8. Create an Azure Maps REST API request with the shared key. Now, the daemon
application can retrieve the shared key from the Key Vault.

 Tip

If the app is hosted in the Azure environment, we recommend that you use a
managed identity to reduce the cost and complexity of managing a secret for
authentication. To learn how to set up a managed identity, see Tutorial: Use a
managed identity to connect Key Vault to an Azure web app in .NET.

Scenario: Microsoft Entra role-based access


control
After an Azure Maps account is created, the Azure Maps Client ID value is present in
the Azure portal authentication details page. This value represents the account that is to
be used for REST API requests. This value should be stored in application configuration
and retrieved before making HTTP requests. The goal of the scenario is to enable the
daemon application to authenticate to Microsoft Entra ID and call Azure Maps REST
APIs.

 Tip

To enable benefits of managed identity components, we recommend that you host


on Azure Virtual Machines, Virtual Machine Scale Sets, or App Services.
Host a daemon on Azure resources
When running on Azure resources, you can configure Azure-managed identities to
enable low cost, minimal credential management effort.

To enable application access to a managed identity, see Overview of managed identities.

Some managed identity benefits are:

Azure system-managed X509 certificate public key cryptography authentication.


Microsoft Entra security with X509 certificates instead of client secrets.
Azure manages and renews all certificates associated with the Managed Identity
resource.
Credential operational management is simplified because managed identity
removes the need for a secured secret store service, such as Azure Key Vault.

Host a daemon on non-Azure resources


Managed identities are only available when running on an Azure environment. As such,
you must configure a service principal through a Microsoft Entra application registration
for the daemon application.

Create new application registration


If you have already created your application registration, go to Assign delegated API
permissions.

To create a new application registration:

1. Sign in to the Azure portal .

2. Select Microsoft Entra ID.

3. Under Manage in the left pane, select App registrations.

4. Select the + New registration tab.


5. Enter a Name, and then select a Support account type.
6. Select Register.

Assign delegated API permissions


To assign delegated API permissions to Azure Maps:

1. If you haven't done so already, sign in to the Azure portal .

2. Select Microsoft Entra ID.

3. Under Manage in the left pane, select App registrations.

4. Select your application.

5. Under Manage in the left pane, select API permissions.

6. Select Add a permission.


7. Select the APIs my organization uses tab.

8. In the search box, enter Azure Maps.

9. Select Azure Maps.

10. Select the Access Azure Maps check box.

11. Select Add permissions.


Create a client secret or configure certificate

To implement server or application-based authentication into your application, you can


choose one of two options:

Upload a public key certificate.


Create a client secret.

Upload a public key certificate

To upload a public key certificate:

1. Under Manage in the left pane, select Certificates & secrets.


2. Select Upload certificate.

3. To the right of the text box, select the file icon.

4. Select a .crt, .cer, or .pem file, and then select Add.


Create a client secret

To create a client secret:

1. Under Manage in the left pane, select Certificates & secrets.

2. Select + New client secret.

3. Enter a description for the client secret.

4. Select Add.
5. Copy the secret and store it securely in a service such as Azure Key Vault. Also, use
the secret in the Request token with Managed Identity section of this article.

) Important

To securely store the certificate or secret, see the Azure Key Vault Developer
Guide. You'll use this secret to get tokens from Microsoft Entra ID.
Grant role-based access for users to Azure
Maps
You can grant Azure role-based access control (Azure RBAC) by assigning a Microsoft
Entra group or security principal to one or more Azure Maps role definitions.

To view the available Azure role definitions for Azure Maps, see View built-in Azure
Maps role definitions.

For detailed steps about how to assign an available Azure Maps role to the created
managed identity or the service principal, see Assign Azure roles using the Azure portal

To efficiently manage the Azure Maps app and resource access of a large amount of
users, see Microsoft Entra groups.

) Important

For users to be allowed to authenticate to an application, the users must first be


created in Microsoft Entra ID. For more information, see Add or delete users using
Microsoft Entra ID.

To learn about how to effectively manage a large directory for users, see Microsoft Entra
ID.

2 Warning

Azure Maps built-in role definitions provide a very large authorization access to
many Azure Maps REST APIs. To restrict APIs access to a minimum, see create a
custom role definition and assign the system-assigned identity to the custom role
definition. This enables the least privilege necessary for the application to access
Azure Maps.

Request a token with managed identity


After a managed identity is configured for the hosting resource, you can use Azure SDK
or REST API to acquire a token for Azure Maps. To learn how to acquire an access token,
see Acquire an access token.

Request token with application registration


After you register your app and associate it with Azure Maps, you'll need to request an
access token.

To acquire the access token:

1. If you haven't done so already, sign in to the Azure portal .

2. Select Microsoft Entra ID.

3. Under Manage in the left pane, select App registrations.

4. Select your application.

5. You should see the Overview page. Copy the Application (client) ID and the
Directory (tenant) ID.

This article uses the Postman application to create the token request, but you can use
a different API development environment.

1. In the Postman app, select New.

2. In the Create New window, select HTTP Request.

3. Enter a Request name for the request, such as POST Token Request.

4. Select the POST HTTP method.

5. Enter the following URL to address bar (replace {Tenant-ID} with the Directory
(Tenant) ID, the {Client-ID} with the Application (Client) ID, and {Client-Secret}
with your client secret:

HTTP

https://login.microsoftonline.com/{Tenant-ID}/oauth2/v2.0/token?
response_type=token&grant_type=client_credentials&client_id={Client-
ID}&client_secret={Client-
Secret}%3D&scope=https://atlas.microsoft.com/.default

6. Select Send

7. You should see the following JSON response:

JSON

{
"token_type": "Bearer",
"expires_in": 86399,
"ext_expires_in": 86399,
"access_token":
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFq..."
}

For more information about authentication flow, see OAuth 2.0 client credentials flow on
the Microsoft identity platform

Next steps
For more detailed examples:

Authentication scenarios for Microsoft Entra ID

Find the API usage metrics for your Azure Maps account:

View usage metrics

Explore samples that show how to integrate Microsoft Entra ID with Azure Maps:

Azure Maps samples


Secure a single page application with
user sign-in
Article • 10/12/2023

The following guide pertains to an application that is hosted on a content server or has
minimal web server dependencies. The application provides protected resources secured
only to Microsoft Entra users. The objective of the scenario is to enable the web
application to authenticate to Microsoft Entra ID and call Azure Maps REST APIs on
behalf of the user.

To view your Azure Maps account authentication details in the Azure portal:

1. Sign in to the Azure portal .

2. Navigate to the Azure portal menu. Select All resources, and then select your
Azure Maps account.

3. Under Settings in the left pane, select Authentication.

Three values are created when the Azure Maps account is created. They're used to
support two types of authentication in Azure Maps:

Microsoft Entra authentication: The Client ID represents the account that is to


be used for REST API requests. The Client ID value should be stored in
application configuration, and then it should be retrieved before making Azure
Maps HTTP requests that use Microsoft Entra authentication.
Shared Key Authentication: The Primary Key and Secondary Key are used as the
subscription key for Shared Key authentication. Shared Key authentication relies on
passing the key generated by the Azure Maps account with each request to Azure
Maps. We recommend that you regularly regenerate your keys. To maintain current
connections during regeneration, two keys are provided. One key can be in use,
while regenerating the other. When you regenerate your keys, you must update
any applications that access this account to use the new keys. For more
information, see Authentication with Azure Maps

Create an application registration in Microsoft


Entra ID
Create the web application in Microsoft Entra ID for users to sign in. The web application
delegates user access to Azure Maps REST APIs.

1. In the Azure portal, in the list of Azure services, select Microsoft Entra ID > App
registrations > New registration.

2. Enter a Name, choose a Support account type, provide a redirect URI that
represents the url which Microsoft Entra ID issues the token and is the url where
the map control is hosted. For a detailed sample, see Azure Maps Microsoft Entra
ID samples . Then select Register.
3. To assign delegated API permissions to Azure Maps, go to the application. Then
under App registrations, select API permissions > Add a permission. Under APIs
my organization uses, search for and select Azure Maps.

4. Select the check box next to Access Azure Maps, and then select Add permissions.
5. Enable oauth2AllowImplicitFlow . To enable it, in the Manifest section of your app
registration, set oauth2AllowImplicitFlow to true .

6. Copy the Microsoft Entra app ID and the Microsoft Entra tenant ID from the app
registration to use in the Web SDK. Add the Microsoft Entra app registration
details and the x-ms-client-id from the Azure Map account to the Web SDK.

JavaScript

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.
js" />
<script>
var map = new atlas.Map("map", {
center: [-122.33, 47.64],
zoom: 12,
language: "en-US",
authOptions: {
authType: "aad",
clientId: "<insert>", // azure map account client id
aadAppId: "<insert>", // azure ad app registration id
aadTenant: "<insert>", // azure ad tenant id
aadInstance: "https://login.microsoftonline.com/"
}
});
</script>

7. Configure Azure role-based access control (Azure RBAC) for users or groups. See
the following sections to enable Azure RBAC.

Grant role-based access for users to Azure


Maps
You can grant Azure role-based access control (Azure RBAC) by assigning a Microsoft
Entra group or security principal to one or more Azure Maps role definitions.

To view the available Azure role definitions for Azure Maps, see View built-in Azure
Maps role definitions.

For detailed steps about how to assign an available Azure Maps role to the created
managed identity or the service principal, see Assign Azure roles using the Azure portal
To efficiently manage the Azure Maps app and resource access of a large amount of
users, see Microsoft Entra groups.

) Important

For users to be allowed to authenticate to an application, the users must first be


created in Microsoft Entra ID. For more information, see Add or delete users using
Microsoft Entra ID.

To learn about how to effectively manage a large directory for users, see Microsoft Entra
ID.

2 Warning

Azure Maps built-in role definitions provide a very large authorization access to
many Azure Maps REST APIs. To restrict APIs access to a minimum, see create a
custom role definition and assign the system-assigned identity to the custom role
definition. This enables the least privilege necessary for the application to access
Azure Maps.

Next steps
Further understanding of single page application scenario:

Single-page application

Find the API usage metrics for your Azure Maps account:

View usage metrics

Explore samples that show how to integrate Microsoft Entra ID with Azure Maps:

Azure Maps Samples


Secure a web application with user sign-
in
Article • 10/12/2023

The following guide pertains to an application that is hosted on web servers, maintains
multiple business scenarios, and deploys to web servers. The application has the
requirement to provide protected resources secured only to Microsoft Entra users. The
objective of the scenario is to enable the web application to authenticate to Microsoft
Entra ID and call Azure Maps REST APIs on behalf of the user.

To view your Azure Maps account authentication details in the Azure portal:

1. Sign in to the Azure portal .

2. Navigate to the Azure portal menu. Select All resources, and then select your
Azure Maps account.

3. Under Settings in the left pane, select Authentication.

Three values are created when the Azure Maps account is created. They're used to
support two types of authentication in Azure Maps:

Microsoft Entra authentication: The Client ID represents the account that is to


be used for REST API requests. The Client ID value should be stored in
application configuration, and then it should be retrieved before making Azure
Maps HTTP requests that use Microsoft Entra authentication.
Shared Key Authentication: The Primary Key and Secondary Key are used as the
subscription key for Shared Key authentication. Shared Key authentication relies on
passing the key generated by the Azure Maps account with each request to Azure
Maps. We recommend that you regularly regenerate your keys. To maintain current
connections during regeneration, two keys are provided. One key can be in use,
while regenerating the other. When you regenerate your keys, you must update
any applications that access this account to use the new keys. For more
information, see Authentication with Azure Maps

Create an application registration in Microsoft


Entra ID
You must create the web application in Microsoft Entra ID for users to sign in. This web
application then delegates user access to Azure Maps REST APIs.

1. In the Azure portal, in the list of Azure services, select Microsoft Entra ID > App
registrations > New registration.

2. Enter a Name, choose a Support account type, provide a redirect URI that
represents the url to which Microsoft Entra ID issues the token, which is the url
where the map control is hosted. For more information, see Microsoft Entra ID
Scenario: Web app that signs in users. Complete the provided steps from the
Microsoft Entra scenario.

3. Once the application registration is complete, confirm that application sign-in


works for users. Once sign-in works, the application can be granted delegated
access to Azure Maps REST APIs.

4. To assign delegated API permissions to Azure Maps, go to the application and


select API permissions > Add a permission. select Azure Maps in the APIs my
organization uses list.

5. Select the check box next to Access Azure Maps, and then select Add permissions.

6. Enable the web application to call Azure Maps REST APIs by configuring the app
registration with an application secret, For detailed steps, see A web app that calls
web APIs: App registration. A secret is required to authenticate to Microsoft Entra
on-behalf of the user. The app registration certificate or secret should be stored in
a secure store for the web application to retrieve to authenticate to Microsoft Entra
ID.

This step may be skipped if the application already has a Microsoft Entra app
registration and secret configured.

 Tip

If the application is hosted in an Azure environment, we recommend using


Managed identities for Azure resources and an Azure Key Vault instance to
access secrets by acquiring an access token for accessing Azure Key Vault
secrets or certificates. To connect to Azure Key Vault to retrieve secrets, see
tutorial to connect through managed identity.

7. Implement a secure token endpoint for the Azure Maps Web SDK to access a
token.
For a sample token controller, see Azure Maps Microsoft Entra ID Samples .
For a non-AspNetCore implementation or other, see Acquire token for the
app from Microsoft Entra documentation.
The secured token endpoint is responsible to return an access token for the
authenticated and authorized user to call Azure Maps REST APIs.

8. To configure Azure role-based access control (Azure RBAC) for users or groups, see
grant role-based access for users.

9. Configure the web application page with the Azure Maps Web SDK to access the
secure token endpoint.

JavaScript

var map = new atlas.Map("map", {


center: [-122.33, 47.64],
zoom: 12,
language: "en-US",
authOptions: {
authType: "anonymous",
clientId: "<insert>", // azure map account client id
getToken: function (resolve, reject, map) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "/api/token", true); // the url path maps
to the token endpoint.
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
resolve(this.responseText);
} else if (this.status !== 200) {
reject(this.responseText);
}
};

xhttp.send();
}
}
});
map.events.add("tokenacquired", function () {
console.log("token acquired");
});
map.events.add("error", function (err) {
console.log(JSON.stringify(err.error));
});

Grant role-based access for users to Azure


Maps
You can grant Azure role-based access control (Azure RBAC) by assigning a Microsoft
Entra group or security principal to one or more Azure Maps role definitions.

To view the available Azure role definitions for Azure Maps, see View built-in Azure
Maps role definitions.

For detailed steps about how to assign an available Azure Maps role to the created
managed identity or the service principal, see Assign Azure roles using the Azure portal

To efficiently manage the Azure Maps app and resource access of a large amount of
users, see Microsoft Entra groups.

) Important

For users to be allowed to authenticate to an application, the users must first be


created in Microsoft Entra ID. For more information, see Add or delete users using
Microsoft Entra ID.

To learn about how to effectively manage a large directory for users, see Microsoft Entra
ID.

2 Warning

Azure Maps built-in role definitions provide a very large authorization access to
many Azure Maps REST APIs. To restrict APIs access to a minimum, see create a
custom role definition and assign the system-assigned identity to the custom role
definition. This enables the least privilege necessary for the application to access
Azure Maps.

Next steps
Further understanding of web application scenario:

Scenario: Web app that signs in users

Find the API usage metrics for your Azure Maps account:

View usage metrics

Explore samples that show how to integrate Microsoft Entra ID with Azure Maps:
Azure Maps Microsoft Entra Web App Samples
Secure an Azure Maps account with a
SAS token
Article • 08/14/2024

This article describes how to create an Azure Maps account with a securely stored SAS
token you can use to call the Azure Maps REST API.

Prerequisites
An Azure subscription. If you don't already have an Azure account, sign up for a
free one .

Owner role permission on the Azure subscription. You need the Owner
permissions to:
Create a key vault in Azure Key Vault.
Create a user-assigned managed identity.
Assign the managed identity a role.
Create an Azure Maps account.

Azure CLI installed to deploy the resources.

Example scenario: SAS token secure storage


A SAS token credential grants the access level it specifies to anyone who holds it, until
the token expires or access is revoked. Applications that use SAS token authentication
should store the keys securely.

This scenario safely stores a SAS token as a secret in Key Vault, and distributes the token
into a public client. Application lifecycle events can generate new SAS tokens without
interrupting active connections that use existing tokens.

For more information about configuring Key Vault, see the Azure Key Vault developer's
guide.

The following example scenario uses two Azure Resource Manager (ARM) template
deployments to do the following steps:

1. Create a key vault.


2. Create a user-assigned managed identity.
3. Assign Azure role-based access control (RBAC) Azure Maps Data Reader role to
the user-assigned managed identity.
4. Create an Azure Maps account with a Cross Origin Resource Sharing (CORS)
configuration, and attach the user-assigned managed identity.
5. Create and save a SAS token in the Azure key vault.
6. Retrieve the SAS token secret from the key vault.
7. Create an Azure Maps REST API request that uses the SAS token.

When you finish, you should see Azure Maps Search Address (Non-Batch) REST API
results on PowerShell with Azure CLI. The Azure resources deploy with permissions to
connect to the Azure Maps account. There are controls for maximum rate limit, allowed
regions, localhost configured CORS policy, and Azure RBAC.

Azure resource deployment with Azure CLI


The following steps describe how to create and configure an Azure Maps account with
SAS token authentication. In this example, Azure CLI runs in a PowerShell instance.

1. Sign in to your Azure subscription with az login .

2. Register Key Vault, Managed Identities, and Azure Maps for your subscription.

Azure CLI

az provider register --namespace Microsoft.KeyVault


az provider register --namespace Microsoft.ManagedIdentity
az provider register --namespace Microsoft.Maps

3. Retrieve your Microsoft Entra object ID.

Azure CLI

$id = $(az rest --method GET --url


'https://graph.microsoft.com/v1.0/me?$select=id' --headers 'Content-
Type=application/json' --query "id")

4. Create a template file named prereq.azuredeploy.json with the following content:

JSON

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-
01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Specifies the location for all the
resources."
}
},
"keyVaultName": {
"type": "string",
"defaultValue": "[concat('vault',
uniqueString(resourceGroup().id))]",
"metadata": {
"description": "Specifies the name of the key vault."
}
},
"userAssignedIdentityName": {
"type": "string",
"defaultValue": "[concat('identity',
uniqueString(resourceGroup().id))]",
"metadata": {
"description": "The name for your managed identity
resource."
}
},
"objectId": {
"type": "string",
"metadata": {
"description": "Specifies the object ID of a user,
service principal, or security group in the Azure AD tenant for the
vault. The object ID must be unique for the set of access policies. Get
it by using Get-AzADUser or Get-AzADServicePrincipal cmdlets."
}
},
"secretsPermissions": {
"type": "array",
"defaultValue": [
"list",
"get",
"set"
],
"metadata": {
"description": "Specifies the permissions to secrets in
the vault. Valid values are: all, get, list, set, delete, backup,
restore, recover, and purge."
}
}
},
"resources": [
{
"type": "Microsoft.ManagedIdentity/userAssignedIdentities",
"name": "[parameters('userAssignedIdentityName')]",
"apiVersion": "2018-11-30",
"location": "[parameters('location')]"
},
{
"apiVersion": "2021-04-01-preview",
"type": "Microsoft.KeyVault/vaults",
"name": "[parameters('keyVaultName')]",
"location": "[parameters('location')]",
"properties": {
"tenantId": "[subscription().tenantId]",
"sku": {
"name": "Standard",
"family": "A"
},
"enabledForTemplateDeployment": true,
"accessPolicies": [
{
"objectId": "[parameters('objectId')]",
"tenantId": "[subscription().tenantId]",
"permissions": {
"secrets": "
[parameters('secretsPermissions')]"
}
}
]
}
}
],
"outputs": {
"userIdentityResourceId": {
"type": "string",
"value": "
[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',
parameters('userAssignedIdentityName'))]"
},
"userAssignedIdentityPrincipalId": {
"type": "string",
"value": "
[reference(parameters('userAssignedIdentityName')).principalId]"
},
"keyVaultName": {
"type": "string",
"value": "[parameters('keyVaultName')]"
}
}
}

5. Deploy the prerequisite resources you created in the previous step. Supply your
own value for <group-name> . Make sure to use the same location as the Azure
Maps account.

Azure CLI
az group create --name <group-name> --location "East US"
$outputs = $(az deployment group create --name ExampleDeployment --
resource-group <group-name> --template-file "./prereq.azuredeploy.json"
--parameters objectId=$id --query "
[properties.outputs.keyVaultName.value,
properties.outputs.userAssignedIdentityPrincipalId.value,
properties.outputs.userIdentityResourceId.value]" --output tsv)

6. Create a template file azuredeploy.json to provision the Azure Maps account, role
assignment, and SAS token.

7 Note

Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2
pricing tier replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps
account has Gen1 pricing tier selected, you can switch to Gen2 pricing before
it’s retired, otherwise it will automatically be updated. For more information,
see Manage the pricing tier of your Azure Maps account.

JSON

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-
01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Specifies the location for all the
resources."
}
},
"keyVaultName": {
"type": "string",
"metadata": {
"description": "Specifies the resourceId of the key
vault."
}
},
"accountName": {
"type": "string",
"defaultValue": "[concat('map',
uniqueString(resourceGroup().id))]",
"metadata": {
"description": "The name for your Azure Maps account."
}
},
"userAssignedIdentityResourceId": {
"type": "string",
"metadata": {
"description": "Specifies the resourceId for the user
assigned managed identity resource."
}
},
"userAssignedIdentityPrincipalId": {
"type": "string",
"metadata": {
"description": "Specifies the resourceId for the user
assigned managed identity resource."
}
},
"pricingTier": {
"type": "string",
"allowedValues": [
"S0",
"S1",
"G2"
],
"defaultValue": "G2",
"metadata": {
"description": "The pricing tier for the account. Use
S0 for small-scale development. Use S1 or G2 for large-scale
applications."
}
},
"kind": {
"type": "string",
"allowedValues": [
"Gen1",
"Gen2"
],
"defaultValue": "Gen2",
"metadata": {
"description": "The pricing tier for the account. Use
Gen1 for small-scale development. Use Gen2 for large-scale
applications."
}
},
"guid": {
"type": "string",
"defaultValue": "[guid(resourceGroup().id)]",
"metadata": {
"description": "Input string for new GUID associated
with assigning built in role types."
}
},
"startDateTime": {
"type": "string",
"defaultValue": "[utcNow('u')]",
"metadata": {
"description": "Current Universal DateTime in ISO 8601
'u' format to use as the start of the SAS token."
}
},
"duration" : {
"type": "string",
"defaultValue": "P1Y",
"metadata": {
"description": "The duration of the SAS token. P1Y is
maximum, ISO 8601 format is expected."
}
},
"maxRatePerSecond": {
"type": "int",
"defaultValue": 500,
"minValue": 1,
"maxValue": 500,
"metadata": {
"description": "The approximate maximum rate per second
the SAS token can be used."
}
},
"signingKey": {
"type": "string",
"defaultValue": "primaryKey",
"allowedValues": [
"primaryKey",
"seconaryKey"
],
"metadata": {
"description": "The specified signing key which will be
used to create the SAS token."
}
},
"allowedOrigins": {
"type": "array",
"defaultValue": [],
"maxLength": 10,
"metadata": {
"description": "The specified application's web host
header origins (example: https://www.azure.com) which the Azure Maps
account allows for CORS."
}
},
"allowedRegions": {
"type": "array",
"defaultValue": [],
"metadata": {
"description": "The specified SAS token allowed
locations where the token may be used."
}
}
},
"variables": {
"accountId": "[resourceId('Microsoft.Maps/accounts',
parameters('accountName'))]",
"Azure Maps Data Reader": "
[subscriptionResourceId('Microsoft.Authorization/roleDefinitions',
'423170ca-a8f6-4b0f-8487-9e4eb8f49bfa')]",
"sasParameters": {
"signingKey": "[parameters('signingKey')]",
"principalId": "
[parameters('userAssignedIdentityPrincipalId')]",
"maxRatePerSecond": "[parameters('maxRatePerSecond')]",
"start": "[parameters('startDateTime')]",
"expiry": "[dateTimeAdd(parameters('startDateTime'),
parameters('duration'))]",
"regions": "[parameters('allowedRegions')]"
}
},
"resources": [
{
"name": "[parameters('accountName')]",
"type": "Microsoft.Maps/accounts",
"apiVersion": "2023-06-01",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('pricingTier')]"
},
"kind": "[parameters('kind')]",
"properties": {
"cors": {
"corsRules": [
{
"allowedOrigins": "
[parameters('allowedOrigins')]"
}
]
}
},
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[parameters('userAssignedIdentityResourceId')]":
{}
}
}
},
{
"apiVersion": "2020-04-01-preview",
"name": "[concat(parameters('accountName'),
'/Microsoft.Authorization/', parameters('guid'))]",
"type":
"Microsoft.Maps/accounts/providers/roleAssignments",
"dependsOn": [
"[parameters('accountName')]"
],
"properties": {
"roleDefinitionId": "[variables('Azure Maps Data
Reader')]",
"principalId": "
[parameters('userAssignedIdentityPrincipalId')]",
"principalType": "ServicePrincipal"
}
},
{
"apiVersion": "2021-04-01-preview",
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('keyVaultName'), '/',
parameters('accountName'))]",
"dependsOn": [
"[variables('accountId')]"
],
"tags": {
"signingKey": "
[variables('sasParameters').signingKey]",
"start" : "[variables('sasParameters').start]",
"expiry" : "[variables('sasParameters').expiry]"
},
"properties": {
"value": "[listSas(variables('accountId'), '2023-06-
01', variables('sasParameters')).accountSasToken]"
}
}
]
}

7. Deploy the template with the ID parameters from the Key Vault and managed
identity resources you created in the previous step. Supply your own value for
<group-name> . When creating the SAS token, you set the allowedRegions

parameter to eastus , westus2 , and westcentralus . You can then use these
locations to make HTTP requests to the us.atlas.microsoft.com endpoint.

) Important

You save the SAS token in the key vault to prevent its credentials from
appearing in the Azure deployment logs. The SAS token secret's tags also
contain the start, expiry, and signing key name, to show when the SAS token
will expire.

Azure CLI

az deployment group create --name ExampleDeployment --resource-group


<group-name> --template-file "./azuredeploy.json" --parameters
keyVaultName="$($outputs[0])"
userAssignedIdentityPrincipalId="$($outputs[1])"
userAssignedIdentityResourceId="$($outputs[2])" allowedOrigins="
['http://localhost']" allowedRegions="['eastus', 'westus2',
'westcentralus']" maxRatePerSecond="10"

8. Locate and save a copy of the single SAS token secret from Key Vault.

Azure CLI

$secretId = $(az keyvault secret list --vault-name $outputs[0] --query


"[? contains(name,'map')].id" --output tsv)
$sasToken = $(az keyvault secret show --id "$secretId" --query "value"
--output tsv)

9. Test the SAS token by making a request to an Azure Maps endpoint. This example
specifies the us.atlas.microsoft.com to ensure your request routes to US
geography. Your SAS token allows regions within the US geography.

Azure CLI

az rest --method GET --url


'https://us.atlas.microsoft.com/search/address/json?api-
version=1.0&query=1 Microsoft Way, Redmond, WA 98052' --headers
"Authorization=jwt-sas $($sasToken)" --query "results[].address"

Complete script example


To run the complete example, the following template files must be in the same directory
as the current PowerShell session:

prereq.azuredeploy.json to create the key vault and managed identity.


azuredeploy.json to create the Azure Maps account, configure the role assignment
and managed identity, and store the SAS token in the key vault.

PowerShell

az login
az provider register --namespace Microsoft.KeyVault
az provider register --namespace Microsoft.ManagedIdentity
az provider register --namespace Microsoft.Maps

$id = $(az rest --method GET --url 'https://graph.microsoft.com/v1.0/me?


$select=id' --headers 'Content-Type=application/json' --query "id")
az group create --name <group-name> --location "East US"
$outputs = $(az deployment group create --name ExampleDeployment --resource-
group <group-name> --template-file "./prereq.azuredeploy.json" --parameters
objectId=$id --query "[properties.outputs.keyVaultName.value,
properties.outputs.userAssignedIdentityPrincipalId.value,
properties.outputs.userIdentityResourceId.value]" --output tsv)
az deployment group create --name ExampleDeployment --resource-group <group-
name> --template-file "./azuredeploy.json" --parameters
keyVaultName="$($outputs[0])"
userAssignedIdentityPrincipalId="$($outputs[1])"
userAssignedIdentityResourceId="$($outputs[2])" allowedOrigins="
['http://localhost']" allowedRegions="['eastus', 'westus2',
'westcentralus']" maxRatePerSecond="10"
$secretId = $(az keyvault secret list --vault-name $outputs[0] --query "[?
contains(name,'map')].id" --output tsv)
$sasToken = $(az keyvault secret show --id "$secretId" --query "value" --
output tsv)

az rest --method GET --url


'https://us.atlas.microsoft.com/search/address/json?api-version=1.0&query=1
Microsoft Way, Redmond, WA 98052' --headers "Authorization=jwt-sas
$($sasToken)" --query "results[].address"

Real-world example
You can run requests to Azure Maps APIs from most clients, like C#, Java, or JavaScript.
API development platforms like bruno or Postman can convert an API request into a
basic client code snippet in almost any programming language or framework you
choose. You can use the generated code snippets in your front-end applications.

The following small JavaScript code example shows how you could use your SAS token
with the JavaScript Fetch API to get and return Azure Maps information. The example
uses Get Search Address API version 1.0. Supply your own value for <your SAS token> .

For this sample to work, make sure to run it from within the same origin as the
allowedOrigins for the API call. For example, if you provide https://contoso.com as the
allowedOrigins in the API call, the HTML page that hosts the JavaScript script should be

https://contoso.com .

JavaScript

async function getData(url =


'https://us.atlas.microsoft.com/search/address/json?api-version=1.0&query=1
Microsoft Way, Redmond, WA 98052') {
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': 'jwt-sas <your SAS token>',
}
});
return response.json(); // parses JSON response into native JavaScript
objects
}

postData('https://us.atlas.microsoft.com/search/address/json?api-
version=1.0&query=1 Microsoft Way, Redmond, WA 98052')
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});

Clean up resources
When you no longer need the Azure resources, you can delete them:

Azure CLI

az group delete --name {group-name}

Next steps
Deploy a quickstart ARM template to create an Azure Maps account that uses a SAS
token:

Create an Azure Maps account

For more detailed examples, see:

Authentication scenarios for Microsoft Entra ID

Find the API usage metrics for your Azure Maps account:

View usage metrics

Explore samples that show how to integrate Microsoft Entra ID with Azure Maps:

Azure Maps samples

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


How to secure a single-page web
application with non-interactive sign-in
Article • 10/12/2023

Secure a single-page web application with Microsoft Entra ID, even when the user isn't
able to sign in to Microsoft Entra ID.

To create this non-interactive authentication flow, first create an Azure Function secure
web service that's responsible for acquiring access tokens from Microsoft Entra ID. This
web service is exclusively available only to your single-page web application.

To view your Azure Maps account authentication details in the Azure portal:

1. Sign in to the Azure portal .

2. Navigate to the Azure portal menu. Select All resources, and then select your
Azure Maps account.

3. Under Settings in the left pane, select Authentication.

Three values are created when the Azure Maps account is created. They're used to
support two types of authentication in Azure Maps:

Microsoft Entra authentication: The Client ID represents the account that is to


be used for REST API requests. The Client ID value should be stored in
application configuration, and then it should be retrieved before making Azure
Maps HTTP requests that use Microsoft Entra authentication.
Shared Key Authentication: The Primary Key and Secondary Key are used as the
subscription key for Shared Key authentication. Shared Key authentication relies on
passing the key generated by the Azure Maps account with each request to Azure
Maps. We recommend that you regularly regenerate your keys. To maintain current
connections during regeneration, two keys are provided. One key can be in use,
while regenerating the other. When you regenerate your keys, you must update
any applications that access this account to use the new keys. For more
information, see Authentication with Azure Maps

 Tip

Azure Maps can support access tokens from user sign-on or interactive flows. You
can use interactive flows for a more restricted scope of access revocation and
secret management.

Create an Azure function


To create a secured web service application that's responsible for authentication to
Microsoft Entra ID:

1. Create a function in the Azure portal. For more information, see Getting started
with Azure Functions.

2. Configure CORS policy on the Azure function to be accessible by the single-page


web application. The CORS policy secures browser clients to the allowed origins of
your web application. For more information, see Add CORS functionality.

3. Add a system-assigned identity on the Azure function to enable creation of a


service principal to authenticate to Microsoft Entra ID.

4. Grant role-based access for the system-assigned identity to the Azure Maps
account. For more information, see Grant role-based access.

5. Write code for the Azure function to obtain Azure Maps access tokens using
system-assigned identity with one of the supported mechanisms or the REST
protocol. For more information, see Obtain tokens for Azure resources.

Here's an example REST protocol:

HTTP
GET /MSI/token?resource=https://atlas.microsoft.com/&api-version=2019-
08-01 HTTP/1.1
Host: localhost:4141

And here's an example response:

HTTP

HTTP/1.1 200 OK
Content-Type: application/json

{
"access_token": "eyJ0eXAi…",
"expires_on": "1586984735",
"resource": "https://atlas.microsoft.com/",
"token_type": "Bearer",
"client_id": "..."
}

6. Configure security for the Azure function HttpTrigger:


a. Create a function access key
b. Secure HTTP endpoint for the Azure function in production.

7. Configure a web application Azure Maps Web SDK.

JavaScript

//URL to custom endpoint to fetch Access token


var url = 'https://{App-Name}.azurewebsites.net/api/{Function-Name}?
code={API-Key}';

var map = new atlas.Map('myMap', {


center: [-122.33, 47.6],
zoom: 12,
language: 'en-US',
view: "Auto",
authOptions: {
authType: "anonymous",
clientId: "<insert>", // azure map account client id
getToken: function(resolve, reject, map) {
fetch(url).then(function(response) {
return response.text();
}).then(function(token) {
resolve(token);
});
}
}
});

// use the following events to debug, you can remove them at any
time.
map.events.add("tokenacquired", function () {
console.log("token acquired");
});
map.events.add("error", function (err) {
console.log(JSON.stringify(err.error));
});

Grant role-based access for users to Azure


Maps
You can grant Azure role-based access control (Azure RBAC) by assigning a Microsoft
Entra group or security principal to one or more Azure Maps role definitions.

To view the available Azure role definitions for Azure Maps, see View built-in Azure
Maps role definitions.

For detailed steps about how to assign an available Azure Maps role to the created
managed identity or the service principal, see Assign Azure roles using the Azure portal

To efficiently manage the Azure Maps app and resource access of a large amount of
users, see Microsoft Entra groups.

) Important

For users to be allowed to authenticate to an application, the users must first be


created in Microsoft Entra ID. For more information, see Add or delete users using
Microsoft Entra ID.

To learn about how to effectively manage a large directory for users, see Microsoft Entra
ID.

2 Warning

Azure Maps built-in role definitions provide a very large authorization access to
many Azure Maps REST APIs. To restrict APIs access to a minimum, see create a
custom role definition and assign the system-assigned identity to the custom role
definition. This enables the least privilege necessary for the application to access
Azure Maps.
Next steps
Further understanding of a single-page application scenario:

Single-page application

Find the API usage metrics for your Azure Maps account:

View usage metrics

Explore other samples that show how to integrate Microsoft Entra ID with Azure Maps:

Azure Maps Samples


Secure an input constrained device by
using Microsoft Entra ID and Azure
Maps REST APIs
Article • 10/12/2023

This guide discusses how to secure public applications or devices that can't securely
store secrets or accept browser input. These types of applications fall under the internet
of things (IoT) category. Examples include Smart TVs and sensor data emitting
applications.

To view your Azure Maps account authentication details in the Azure portal:

1. Sign in to the Azure portal .

2. Navigate to the Azure portal menu. Select All resources, and then select your
Azure Maps account.

3. Under Settings in the left pane, select Authentication.

Three values are created when the Azure Maps account is created. They're used to
support two types of authentication in Azure Maps:

Microsoft Entra authentication: The Client ID represents the account that is to


be used for REST API requests. The Client ID value should be stored in
application configuration, and then it should be retrieved before making Azure
Maps HTTP requests that use Microsoft Entra authentication.
Shared Key Authentication: The Primary Key and Secondary Key are used as the
subscription key for Shared Key authentication. Shared Key authentication relies on
passing the key generated by the Azure Maps account with each request to Azure
Maps. We recommend that you regularly regenerate your keys. To maintain current
connections during regeneration, two keys are provided. One key can be in use,
while regenerating the other. When you regenerate your keys, you must update
any applications that access this account to use the new keys. For more
information, see Authentication with Azure Maps

Create an application registration in Microsoft


Entra ID

7 Note

Prerequisite Reading: Scenario: Desktop app that calls web APIs


The following scenario uses the device code flow, which does not involve a
web browser to acquire a token.

Create the device based application in Microsoft Entra ID to enable Microsoft Entra sign-
in, which is granted access to Azure Maps REST APIs.

1. In the Azure portal, in the list of Azure services, select Microsoft Entra ID > App
registrations > New registration.
2. Enter a Name, choose Accounts in this organizational directory only as the
Supported account type. In Redirect URIs, specify Public client / native (mobile &
desktop) then add
https://login.microsoftonline.com/common/oauth2/nativeclient to the value. For

more information, see Microsoft Entra ID Desktop app that calls web APIs: App
registration. Then Register the application.
3. Navigate to Authentication and enable Treat application as a public client to
enable device code authentication with Microsoft Entra ID.

4. To assign delegated API permissions to Azure Maps, go to the application. Then


select API permissions > Add a permission. Under APIs my organization uses,
search for and select Azure Maps.
5. Select the check box next to Access Azure Maps, and then select Add permissions.

6. Configure Azure role-based access control (Azure RBAC) for users or groups. For
more information, see Grant role-based access for users to Azure Maps.
7. Add code for acquiring token flow in the application, for implementation details
see Device code flow. When acquiring tokens, reference the scope:
user_impersonation that was selected on earlier steps.

 Tip

Use Microsoft Authentication Library (MSAL) to acquire access tokens. For


more information, see Desktop app that calls web APIs: Code configuration
in the active directory documentation.

8. Compose the HTTP request with the acquired token from Microsoft Entra ID, and
sent request with a valid HTTP client.

Sample request
Here's a sample request body for uploading a simple Geofence represented as a circle
geometry using a center point and a radius.

HTTP

POST /mapData?api-version=2.0&dataFormat=geojson
Host: us.atlas.microsoft.com
x-ms-client-id: 30d7cc….9f55
Authorization: Bearer eyJ0e….HNIVN

The following sample request body is in GeoJSON:

JSON

{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.126986, 47.639754]
},
"properties": {
"geometryId": "001",
"radius": 500
}
}]
}
Sample response header
HTTP

Operation-Location:
https://us.atlas.microsoft.com/mapData/operations/{udid}?api-version=2.0
Access-Control-Expose-Headers: Operation-Location

Grant role-based access for users to Azure


Maps
You can grant Azure role-based access control (Azure RBAC) by assigning a Microsoft
Entra group or security principal to one or more Azure Maps role definitions.

To view the available Azure role definitions for Azure Maps, see View built-in Azure
Maps role definitions.

For detailed steps about how to assign an available Azure Maps role to the created
managed identity or the service principal, see Assign Azure roles using the Azure portal

To efficiently manage the Azure Maps app and resource access of a large amount of
users, see Microsoft Entra groups.

) Important

For users to be allowed to authenticate to an application, the users must first be


created in Microsoft Entra ID. For more information, see Add or delete users using
Microsoft Entra ID.

To learn about how to effectively manage a large directory for users, see Microsoft Entra
ID.

2 Warning

Azure Maps built-in role definitions provide a very large authorization access to
many Azure Maps REST APIs. To restrict APIs access to a minimum, see create a
custom role definition and assign the system-assigned identity to the custom role
definition. This enables the least privilege necessary for the application to access
Azure Maps.
Next steps
Find the API usage metrics for your Azure Maps account:

View usage metrics


Manage the pricing tier of your Azure
Maps account
Article • 07/29/2024

You can manage the pricing tier of your Azure Maps account through the Azure portal
or an Azure Resource Manager (ARM) template.

For information related to calculating costs, see Azure Maps pricing and
Understanding Azure Maps Transactions.

7 Note

Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2 pricing
tier replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps account has
Gen1 pricing tier selected, you can switch to Gen2 pricing tier before it’s retired,
otherwise it will automatically be updated.

After 9/14/23, Gen1 pricing tier will no longer be available when creating new
Azure Maps accounts via the Azure Portal. After 10/12/23, Gen1 pricing tier will no
longer be available when creating new Azure Maps accounts when using an ARM
template.

You don't have to generate new subscription keys, client ID (for Microsoft Entra
authentication) or shared access signature (SAS) tokens if you change the pricing
tier for your Azure Maps account.

For more information on Gen2 pricing tier, see Azure Maps pricing .

Change a pricing tier

Azure portal
To change your pricing tier from Gen1 to Gen2 in the Azure Portal, navigate to the
Pricing tier option in the settings menu of your Azure Maps account. Select Gen2 from
the Pricing tier drop-down list then the Save button.

7 Note
You don't have to generate new subscription keys, client ID (for Microsoft Entra
authentication) or shared access signature (SAS) tokens if you change the pricing
tier for your Azure Maps account.

ARM template
To change your pricing tier from Gen1 to Gen2 in the ARM template, update
pricingTier to G2 and kind to Gen2. For more info on using ARM templates, see

Create account with ARM template.

JSON

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-
01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.25.53.49325",
"templateHash": "695164742048978243"
}
},
"parameters": {
"accountName": {
"type": "string",
"defaultValue": "[uniqueString(resourceGroup().id)]",
"metadata": {
"description": "The name for your Azure Maps account. This value
must be globally unique."
}
},
"location": {
"type": "string",
"allowedValues": [
"westeurope",
"eastus",
"westus2",
"northeurope",
"westcentralus",
"usgovvirginia",
"usgovarizona"
],
"metadata": {
"description": "Specifies the location for all the resources."
}
},
"pricingTier": {
"type": "string",
"defaultValue": "G2",
"allowedValues": [
"G2"
],
"metadata": {
"description": "The pricing tier SKU for the account."
}
},
"kind": {
"type": "string",
"defaultValue": "Gen2",
"allowedValues": [
"Gen2"
],
"metadata": {
"description": "The pricing tier for the account."
}
}
},
"resources": [
{
"type": "Microsoft.Maps/accounts",
"apiVersion": "2023-06-01",
"name": "[parameters('accountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('pricingTier')]"
},
"kind": "[parameters('kind')]"
}
]
}
Next steps
Learn how to see the API usage metrics for your Azure Maps account:

View usage metrics

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


View Azure Maps API usage metrics
Article • 04/18/2025

This article guides you on how to view API usage metrics for your Azure Maps account in the
Azure portal . The metrics are displayed in an easy-to-read graph format over a customizable
time period.

View metric snapshot


The Overview page of your Maps account displays key metrics such as Total Requests, Total
Errors, and Availability over a selectable time period.

Proceed to the next section to customize these graphs for your specific analysis needs.

View detailed metrics


1. Sign in to the Azure portal .

2. Select the All resources menu item on the left-hand side and navigate to your Azure
Maps Account.

3. Once your Maps account is open, select the Metrics menu on the left.

4. In the Metrics pane, choose one of the following options:

a. Availability - displays the Average API availability over a specified time period.
b. Usage - displays the usage count for your account.

5. The default time range is Last 24 hours (Automatic). To change this, select the default
value to open the Time Range pop-up, which displays all available settings. You can
change the Time granularity and show the time as local or GMT. Once the desired options
are chosen, select Apply.
7 Note

Metrics are stored for 93 days, but you can only query up to 30 days' worth of data
at a time. If you encounter a blank chart or partial metric data, ensure the start and
end dates in the time picker don't exceed a 30-day interval. Once you've selected a
30-day interval, you can pan the chart to view other metrics. For more information,
see Troubleshooting metrics charts.

6. After adding your metric, you can apply a filter based on the properties relevant to that
metric. Then, choose the value of the property you want to display on the graph.
7. You can also Apply splitting for your metric based on your selected metric property. This
feature allows the graph to be divided into multiple graphs, each representing a different
value of that property. In the following example, the color of each graph corresponds to
the property value displayed at the bottom.
8. You can also view multiple metrics on the same graph by selecting the Add metric
button.

Next steps
Discover more about the Azure Maps APIs you wish to monitor:

Azure Maps Web SDK How-To

Azure Maps REST API documentation


Create indoor map with the onboarding
tool
Article • 09/24/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

This article demonstrates how to create an indoor map using the Azure Maps Creator
onboarding tool.

Prerequisites
A basic understanding of Creator. For an overview, see Creator for indoor maps.
A drawing package. For more information, see Drawing package requirements.

7 Note

The drawing package used in this article is the Sample - Contoso Drawing
Package .

Get started
The following steps demonstrate how to create an indoor map in your Azure Maps
account using the Azure Maps Creator onboarding tool. The MapConfigurationId
property is created during the onboarding process and is used to reference the map in
your application. For more information, see The Map Configuration ID.

1. Import the drawing package into your Azure Maps account using the Azure Maps
Creator onboarding tool.
 Tip

If your drawing package doesn't contain a manifest, The Drawing Package


Guide describes how to create one.

2. Once your drawing package has been processed, select the Create + Download
button to begin creating the indoor map.
3. The first step in this process uploads the package into the Azure Maps account.
4. Once the package is uploaded, the onboarding tool uses the Conversion service to
validate the data then convert the geometry and data from the drawing package
into a digital indoor map. For more information about the conversion process, see
Convert a drawing package in the Creator concepts article.

5. The next step in the process is to create the dataset. Datasets contain a collection
of features within the facility.
6. The dataset is used to create a tileset. Tilesets are a lightweight storage format
used by Azure Maps when rendering map data.

) Important

The MapConfigurationId is created as a part of the tileset creation process and


is required to reference the indoor map in your applications. Make sure to
make a copy of it for future reference.

7. The indoor map is created and displayed as a preview.


Your indoor map is created and stored in your Azure Maps account and is now ready to
be used in your applications.

The Map Configuration ID


The MapConfigurationId property created as a part of the tileset creation process in step
6. This property is required to reference the indoor map in your application code. Make
sure to make a copy of it for future reference.

Next steps
Integrate the indoor map into your applications using the Web SDK.

Use the Azure Maps Indoor Maps module

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Manage Azure Maps Creator
Article • 09/24/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

You can use Azure Maps Creator to create private indoor map data. Using the Azure
Maps API and the Indoor Maps module, you can develop interactive and dynamic
indoor map web applications. For pricing information, see the Creator section in Azure
Maps pricing .

This article takes you through the steps to create and delete a Creator resource in an
Azure Maps account.

Create Creator resource


1. Sign in to the Azure portal .

2. Navigate to the Azure portal menu. Select All resources, and then select your
Azure Maps account.

3. In the navigation pane, select Creator, then select the Create button.
4. Enter the name, location, and map provisioning storage units for your Creator
resource, then select Review + create.

5. Review your settings, and then select Create. After the deployment completes,
you'll see a page with a success or a failure message.
6. Select Go to resource. Your Creator resource view page shows the status of your
Creator resource and the chosen demographic region.

7 Note

To return to the Azure Maps account, select Azure Maps Account in the
navigation pane.

Delete Creator resource


To delete the Creator resource:

1. In your Azure Maps account, select Creator.

2. Select Delete.

2 Warning

When you delete the Creator resource of your Azure Maps account, you also
delete the conversions, datasets and tilesets that were created using Creator
services. Once a Creator resource is deleted, it cannot be undone.
3. You're prompted to confirm deletion by typing in the name of your Creator
resource. After the resource is deleted, you see a confirmation page that looks like
the following example:

Authentication
Creator inherits Azure Maps Access Control (IAM) settings. All API calls for data access
must be sent with authentication and authorization rules.

Creator usage data is incorporated in your Azure Maps usage charts and activity log. For
more information, see Manage authentication in Azure Maps.

) Important

We recommend using:

Microsoft Entra ID in all solutions that are built with an Azure Maps account
using Creator services. For more information, on Microsoft Entra ID, see
Microsoft Entra authentication.

Role-based access control settings (RBAC). Using these settings, map makers
can act as the Azure Maps Data Contributor role, and Creator map data users
can act as the Azure Maps Data Reader role. For more information, see
Authorization with role-based access control.

Access to Creator services


Creator services and services that use data hosted in Creator (for example, Render
service), are accessible at a geographical URL. The geographical URL determines the
location selected during creation. For example, if Creator is created in a region in the
United States geographical location, all calls to the Conversion service must be
submitted to us.atlas.microsoft.com/conversions . To view mappings of region to
geographical location, see Creator service geographic scope.

Next steps
Introduction to Creator services for indoor mapping:

Upload a drawing package

Data conversion

Dataset

Tileset

Learn how to use the Creator services to render indoor maps in your application:

Use the Indoor Maps module

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Conversion drawing package guide
Article • 10/20/2023

This guide shows you how to prepare your Drawing Package for the Azure Maps
Conversion service using specific CAD commands to correctly prepare your DWG files
and manifest file for the Conversion service.

To start with, make sure your Drawing Package is in .zip format, and contains the
following files:

One or more drawing files in DWG format.


A Manifest file describing DWG files and facility metadata.

If you don't have your own package to reference along with this guide, you may
download the sample drawing package .

You may choose any CAD software to open and prepare your facility drawing files.
However, this guide is created using Autodesk's AutoCAD® software. Any commands
referenced in this guide are meant to be executed using Autodesk's AutoCAD®
software.

 Tip

For more information about drawing package requirements that aren't covered in
this guide, see Drawing Package Requirements.

Glossary of terms
For easy reference, here are some terms and definitions that are important as you read
this guide.

Term Definition

Layer An AutoCAD DWG layer from the drawing file.

Entity An AutoCAD DWG entity from the drawing file.

Level An area of a building at a set elevation. For example, the floor of a building.

Feature An object that combines a geometry with more metadata information.

Feature A common blueprint for features. For example, a unit is a feature class, and an
classes office is a feature.
Step 1: DWG file requirements
When preparing your facility drawing files for the Conversion service, make sure to
follow these preliminary requirements and recommendations:

Facility drawing files must be saved in DWG format, which is the native file format
for Autodesk's AutoCAD® software.

The Conversion service works with the AutoCAD DWG file format. AC1032 is the
internal format version for the DWG files, and it's a good idea to select AC1032 for
the internal DWG file format version.

A DWG file can only contain a single floor. A floor of a facility must be provided in
its own separate DWG file. So, if you have five floors in a facility, you must create
five separate DWG files.

Step 2: Prepare the DWG files


This part of the guide shows you how to use CAD commands to ensure that your DWG
files meet the requirements of the Conversion service.

You may choose any CAD software to open and prepare your facility drawing files.
However, this guide is created using Autodesk's AutoCAD® software. Any commands
referenced in this guide are meant to be executed using Autodesk's AutoCAD®
software.

Bind External References


Each floor of a facility must be provided as one DWG file. If there are no external
references, then nothing more needs to be done. However, if there are any external
references, they must be bound to a single drawing. To bind an external reference, you
may use the XREF command. Each external reference drawing will be added as a block
reference after binding. If you need to make changes to any of these layers, remember
to explode the block references by using the XPLODE command.

Unit of measurement
The drawings can be created using any unit of measurement. However, all drawings
must use the same unit of measurement. So, if one floor of the facility is using
millimeters, then all other floors (drawings) must also be in millimeters. You can verify or
modify the measurement unit by using the UNITS command.
The following image shows the Drawing Units window within Autodesk's AutoCAD®
software that you can use to verify the unit of measurement.

Alignment
Each floor of a facility is provided as an individual DWG file. As a result, it's possible that
the floors aren't perfectly aligned when stacked on top of each other. Azure Maps
Conversion service requires that all drawings be aligned with the physical space. To
verify alignment, use a reference point that can span across floors, such as an elevator or
column that spans multiple floors. you can view all the floors by opening a new drawing,
and then use the XATTACH command to load all floor drawings. If you need to fix any
alignment issues, you can use the reference points and the MOVE command to realign
the floors that require it.

Layers
Ensure that each layer of a drawing contains entities of one feature class. If a layer
contains entities for walls, then it can't have other features such as units or doors.
However, a feature class can be split up over multiple layers. For example, you can have
three layers in the drawing that contain wall entities.

Furthermore, each layer has a list of supported entity types and any other types are
ignored. For example, if the Unit Label layer only supports single-line text, a multiline
text or Polyline on the same layer is ignored.

For a better understanding of layers and feature classes, see Drawing Package
Requirements.

Exterior layer
A single level feature is created from each exterior layer or layers. This level feature
defines the level's perimeter. It's important to ensure that the entities in the exterior
layer meet the requirements of the layer. For example, a closed Polyline is supported;
but an open Polyline isn't. If your exterior layer is made of multiple line segments, they
must be provided as one closed Polyline. To join multiple line segments together, select
all line segments and use the JOIN command.

The following image is taken from the sample package, and shows the exterior layer of
the facility in red. The unit layer is turned off to help with visualization.

Unit layer
Units are navigable spaces in the building, such as offices, hallways, stairs, and
elevators. A closed entity type such as Polygon, closed Polyline, Circle, or closed Ellipse is
required to represent each unit. So, walls and doors alone don't create a unit because
there isn’t an entity that represents the unit.

The following image is taken from the sample drawing package and shows the unit
label layer and unit layer in red. All other layers are turned off to help with visualization.
Also, one unit is selected to help show that each unit is a closed Polyline.

Unit label layer


If you'd like to add a name property to a unit, add a separate layer for unit labels. Labels
must be provided as single-line text entities that fall inside the bounds of a unit. A
corresponding unit property must be added to the manifest file where the unitName
matches the Contents of the Text. To learn about all supported unit properties, see
unitProperties.

Door layer
Doors are optional. However, doors may be used if you'd like to specify the entry
point(s) for a unit. Doors can be drawn in any way if it's a supported entity type by the
door layer. The door must overlap the boundary of a unit and the overlapping edge of
the unit is then be treated as an opening to the unit.

The following image is taken from the sample drawing package and shows a unit with
a door (in red) drawn on the unit boundary.

Wall layer
The wall layer is meant to represent the physical extents of a facility such as walls and
columns. The Azure Maps Conversion service perceives walls as physical structures that
are an obstruction to routing. With that in mind, a wall should be thought as a physical
structure that one can see, but not walk through. Anything that can’t be seen won't
captured in this layer. If a wall has inner walls or columns inside, then only the exterior
should be captured.
Step 3: Prepare the manifest
The drawing package Manifest is a JSON file. The Manifest tells the Azure Maps
Conversion service how to read the facility DWG files and metadata. Some examples of
this information could be the specific information each DWG layer contains, or the
geographical location of the facility.

To achieve a successful conversion, all “required” properties must be defined. A sample


manifest file can be found inside the sample drawing package . This guide doesn't
cover properties supported by the manifest. For more information about manifest
properties, see Manifest file requirements.

Building levels
The building level specifies which DWG file to use for which level. A level must have a
level name and ordinal that describes that vertical order of each level. Every facility must
have an ordinal 0, which is the ground floor of a facility. An ordinal 0 must be provided
even if the drawings occupy a few floors of a facility. For example, floors 15-17 can be
defined as ordinal 0-2, respectively.

The following example is taken from the sample drawing package . The facility has
three levels: basement, ground, and level 2. The filename contains the full file name and
path of the file relative to the manifest file within the .zip drawing package.

JSON

"buildingLevels": {
"levels": [
{
"levelName": "Basement",
"ordinal": -1,
"filename": "./Basement.dwg"
}, {

"levelName": "Ground",
"ordinal": 0,
"filename": "./Ground.dwg"
}, {

"levelName": "Level 2",


"ordinal": 1,
"filename": "./Level_2.dwg"
}
]
},
georeference
The georeference object is used to specify where the facility is located geographically
and how much to rotate the facility. The origin point of the drawing should match the
latitude and longitude provided with the georeference object. The clockwise angle, in
degrees, between true north and the drawing's vertical (Y) axis.

dwgLayers
The dwgLayers object is used to specify that DWG layer names where feature classes can
be found. To receive a property converted facility, it's important to provide the correct
layer names. For example, a DWG wall layer must be provided as a wall layer and not as
a unit layer. The drawing can have other layers such as furniture or plumbing; but, the
Azure Maps Conversion service ignores them if they're not specified in the manifest.

The following example of the dwgLayers object in the manifest.

JSON

"dwgLayers": {
"exterior": [
"OUTLINE"
],
"unit": [
"UNITS"
],
"wall": [
"WALLS"
],
"door": [
"DOORS"
],
"unitLabel": [
"UNITLABELS"
],
"zone": [
"ZONES"
],
"zoneLabel": [
"ZONELABELS"
]
}

The following image shows the layers from the corresponding DWG drawing viewed in
Autodesk's AutoCAD® software.
unitProperties
The unitProperties object allows you to define other properties for a unit that you can’t
do in the DWG file. Examples could be directory information of a unit or the category
type of a unit. A unit property is associated with a unit by having the unitName object
match the label in the unitLabel layer.

The following image is taken from the sample drawing package . It displays the unit
label that's associated to the unit property in the manifest.
The following snippet shows the unit property object that is associated with the unit.

JSON

"unitProperties": [
{
"unitName": "B01",
"categoryName": "room.office",
"navigableBy": ["pedestrian", "wheelchair", "machine"],
"routeThroughBehavior": "disallowed",
"occupants": [
{
"name": "Joe's Office",
"phone": "1 (425) 555-1234"
}
],
"nameAlt": "Basement01",
"nameSubtitle": "01",
"addressRoomNumber": "B01",
"nonPublic": true,
"isRoutable": true,
"isOpenArea": true
},

Step 4: Prepare the Drawing Package


You should now have all the DWG drawings prepared to meet Azure Maps Conversion
service requirements. A manifest file has also been created to help describe the facility.
All files need to be zipped into a single archive file, with the .zip extension. It's
important that the manifest file is named manifest.json and is placed in the root
directory of the zipped package. All other files can be in any directory of the zipped
package if the filename includes the relative path to the manifest. For an example of a
drawing package, see the sample drawing package .

Next steps
Tutorial: Creating a Creator indoor map
Query datasets using the Web Feature
Service
Article • 09/24/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

This article describes how to query Azure Maps Creator datasets using Web Feature
Service (WFS). You can use the WFS API to query for all feature collections or a specific
collection within a dataset. For example, you can use WFS to find all mid-size meeting
rooms in a specific building and floor level.

Prerequisites
A dataset

) Important

This article uses the us.atlas.microsoft.com geographical URL. If your Creator


service wasn't created in the United States, you must use a different
geographical URL. For more information, see Access to Creator Services.
In the URL examples in this article you will need to replace:
{Azure-Maps-Subscription-key} with your Azure Maps subscription key.

Query for feature collections


To query all collections in your dataset, create a new HTTP GET Request:

Enter the following URL to WFS API. The request should look like the following URL:

HTTP
https://us.atlas.microsoft.com/wfs/datasets/{datasetId}/collections?
subscription-key={Your-Azure-Maps-Subscription-key}&api-version=2.0

The response body is returned in GeoJSON format and contains all collections in the
dataset. For simplicity, the example here only shows the unit collection. To see an
example that contains all collections, see WFS Describe Collections API. To learn more
about any collection, you can select any of the URLs inside the links element.

JSON

{
"collections": [
{
"name": "unit",
"description": "A physical and non-overlapping area which might be
occupied and traversed by a navigating agent. Can be a hallway, a room, a
courtyard, etc. It is surrounded by physical obstruction (wall), unless the
is_open_area attribute is equal to true, and one must add openings where the
obstruction shouldn't be there. If is_open_area attribute is equal to true,
all the sides are assumed open to the surroundings and walls are to be added
where needed. Walls for open areas are represented as a line_element or
area_element with is_obstruction equal to true.",
"links": [
{
"href":
"https://atlas.microsoft.com/wfs/datasets/{datasetId}/collections/unit/defin
ition?api-version=1.0",
"rel": "describedBy",
"title": "Metadata catalogue for unit"
},
{
"href":
"https://atlas.microsoft.com/wfs/datasets/{datasetId}/collections/unit/items
?api-version=1.0",
"rel": "data",
"title": "unit"
}
{
"href":
"https://atlas.microsoft.com/wfs/datasets/{datasetId}/collections/unit?api-
version=1.0",
"rel": "self",
"title": "Metadata catalogue for unit"
}
]
},

Query for unit feature collection


This section demonstrates querying WFS API for the unit feature collection.

To query the unit collection in your dataset, create a new HTTP GET Request:

HTTP

https://us.atlas.microsoft.com/wfs/datasets/{datasetId}/collections/unit/ite
ms?subscription-key={Your-Azure-Maps-Subscription-key}&api-version=2.0

After the response returns, copy the feature id for one of the unit features. In the
following example, the feature id is "UNIT26".

JSON

{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": ["..."]
},
"properties": {
"original_id": "b7410920-8cb0-490b-ab23-b489fd35aed0",
"category_id": "CTG8",
"is_open_area": true,
"navigable_by": [
"pedestrian"
],
"route_through_behavior": "allowed",
"level_id": "LVL14",
"occupants": [],
"address_id": "DIR1",
"name": "157"
},
"id": "UNIT26",
"featureType": ""
}, {"..."}
]
}

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Create custom styles for indoor maps
(preview)
Article • 08/23/2023

When you create an indoor map using Azure Maps Creator, default styles are applied.
This article discusses how to customize these styling elements.

Prerequisites
Understanding of Creator concepts.
An Azure Maps Creator tileset. If you have never used Azure Maps Creator to
create an indoor map, you might find the Use Creator to create indoor maps
tutorial helpful.

Create custom styles using Creators visual


editor
While it's possible to modify your indoor maps styles using Creators Rest API, Creator
also offers a visual style editor to create custom styles that doesn't require coding.
This article focuses exclusively on creating custom styles using this style editor.

Open style
When an indoor map is created in your Azure Maps Creator service, default styles are
automatically created for you. In order to customize the styling elements of your indoor
map, open that default style.

Open the style editor and select the Open toolbar button.

The Open Style dialog box opens.

Enter your subscription key in the Enter your Azure Maps subscription key field.

Next, select the geography associated with your subscription key in the drop-down list.
Select the Get map configuration list button to get a list of every map configuration
associated with the active Creator resource.

7 Note

If the map configuration was created as part of a custom style and has a user
provided alias, that alias appears in the map configuration drop-down list,
otherwise just the mapConfigurationId appears. The default map configuration ID
for any given tileset can be found by using the tileset get HTTP request and
passing in the tileset ID:

HTTP

https://{geography}.atlas.microsoft.com/tilesets/{tilesetId}?2023-03-
01-preview

The mapConfigurationId is returned in the body of the response, for example:

JSON

"defaultMapConfigurationId": "68d74ad9-4f84-99ce-06bb-19f487e8e692"

Once the desired map configuration is selected, the drop-down list of styles appears.

Once you've selected the desired style, select the Load selected style button.

About the open style dialog

# Description

1 Your Azure Maps account subscription key


# Description

2 Select the geography of the Azure Maps account.

3 A list of map configuration IDs and aliases.

4 A list of styles associated with the selected map configuration.

Modify style
Once your style is open in the visual editor, you can begin to modify the various
elements of your indoor map such as changing the background colors of conference
rooms, offices or restrooms. You can also change the font size for labels such as office
numbers and define what appears at different zoom levels.

Change background color

To change the background color for all units in the specified layer, put your mouse
pointer over the desired unit and select it using the left mouse button. You’re presented
with a popup menu showing the layers that are associated with the categories the unit is
associated with. Once you select the layer that you wish to update the style properties
on, that layer is ready to be updated in the left pane.

Open the color palette and select the color you wish to change the selected unit to.

Base map
The base map drop-down list on the visual editor toolbar presents a list of base map
styles that affect the style attributes of the base map that your indoor map is part of. It
doesn't affect the style elements of your indoor map but enables you to see how your
indoor map looks with the various base maps.

Save custom styles

Once you have made the desired changes to your styles, save the changes to your
Creator resource. You can overwrite your style with the changes or create a new style.

To save your changes, select the Save button on the toolbar.


This brings up the Upload style & map configuration dialog box:

The following table describes the four fields you're presented with.

Property Description

Style description A user-defined description for this style.

Map configuration A user-defined description for this map configuration.


description

Map configuration An alias used to reference this map configuration.


alias When referencing programmatically, the map configuration is referenced
by the map configuration ID if no alias is provided.

Some important things to know about aliases:

1. Can be named using alphanumeric characters (0-9, a-z, A-Z), hyphens (-) and
underscores (_).
2. Can be used to reference the underlying map configuration, in place of that
object's ID. This is especially important since the map configuration can't be
updated, meaning every time any changes are saved, a new ID is generated, but
the alias can remain the same, making referencing it less error prone after it has
been modified multiple times.
2 Warning

Duplicate aliases are not allowed. If the alias of an existing map configuration is
used, the map configuration that alias points to will be overwritten and the existing
map configuration will be deleted and references to that ID will result in errors. For
more information, see map configuration in the concepts article.

Once you have entered values into each required field, select the Upload map
configuration button to save the style and map configuration data to your Creator
resource.

Once you have successfully uploaded your custom styles you'll see the Upload
complete dialog showing you the values for Style ID, Map configuration ID and the map
configuration alias. For more information, see custom styling and map configuration.

 Tip

Make a note of the map configuration alias value, it will be required when you
Instantiate the Indoor Manager of a Map object when developing applications in
Azure Maps. Also, make a note of the Style ID, it can be reused for other tilesets.

Custom categories
Azure Maps Creator has defined a list of categories . When you create your manifest,
you associate each unit in your facility to one of these categories in the unitProperties
object.

There may be times when you want to create a new category. For example, you may
want the ability to apply different styling attributes to all rooms with special
accommodations for people with disabilities like a phone room with phones that have
screens showing what the caller is saying for people with hearing impairments.

To do this, enter the desired value in the categoryName for the desired unitName in the
manifest JSON before uploading your drawing package.

The category name isn't associated with any layer when viewed in a visual editor and has
no default styling. In order to apply styling to it, create a new layer and add the new
category to it.

To create a new layer, select the duplicate button on an existing layer. This creates a
copy of the selected layer that you can modify as needed. Next, rename the layer by
typing a new name into the ID field. For this example, we entered
indoor_unit_room_accessible.
Once you've created a new layer, you need to associate your new category name with it.
This is done by editing the copied layer to remove the existing categories and add the
new one.

For example, the JSON might look something like this:

JSON

{
"id": "indoor_unit_room_accessible",
"type": "fill",
"filter": [
"all",
["has", "floor0"],
[
"any",
[
"case",
[
"==",
[
"typeof",
["get", "categoryName"]
],
"string"
],
[
"==",
["get", "categoryName"],
"room.accessible.phone"
],
false
]
]
],
"layout": {"visibility": "visible"},
"metadata": {
"microsoft.maps:layerGroup": "unit"
},
"minzoom": 16,
"paint": {
"fill-antialias": true,
"fill-color": [
"string",
["feature-state", "color"],
"rgba(230, 230, 230, 1)"
],
"fill-opacity": 1,
"fill-outline-color": "rgba(120, 120, 120, 1)"
},
"source-layer": "Indoor unit",
"source": "{tilesetId}"
}

Only features that match the filter are displayed on the map. You need to edit the filter
to remove any categories that you don't want to appear on the map and add the new
category.

For example, the filter JSON might look something like this:

JSON

[
"all",
["has", "floor0"],
[
"any",
[
"case",
[
"==",
[
"typeof",
["get", "categoryName"]
],
"string"
],
[
"==",
["get", "categoryName"],
"room.accessible.phone"
],
false
]
]
]
Now when you select that unit in the map, the pop-up menu has the new layer ID, which
if following this example would be indoor_unit_room_accessible . Once selected you can
make style edits.

Next steps
Use the Azure Maps Indoor Maps module
Indoor maps wayfinding service
(preview)
Article • 07/17/2024

The Azure Maps Creator wayfinding service allows you to navigate from place to place
anywhere within your indoor map. The service utilizes stairs and elevators to navigate
between floors and provides guidance to help you navigate around physical
obstructions. This article describes how to generate a path from a starting point to a
destination point in a sample indoor map.

Prerequisites
Understanding of Creator concepts.
An Azure Maps Creator dataset and tileset.

) Important

This article uses the us.atlas.microsoft.com geographical URL. If your Creator


service wasn't created in the United States, you must use a different
geographical URL. For more information, see Access to Creator services.
In the URL examples in this article you will need to:
Replace {Your-Azure-Maps-Subscription-key} with your Azure Maps
subscription key.
Replace {datasetId } with your datasetId .

Create a routeset
A routeset is a collection of indoor map data that is used by the wayfinding service.

A routeset is created from a dataset. The routeset is independent from the dataset,
meaning if the dataset is deleted, the routeset continues to exist.

Once you've created a routeset, you can then use the wayfinding API to get a path from
the starting point to the destination point within the facility.

To create a routeset:

1. Execute the following HTTP POST request:


HTTP

https://us.atlas.microsoft.com/routesets?api-version=2023-03-01-
preview&datasetID={datasetId}&subscription-key={Your-Azure-Maps-
Subscription-key}

2. Copy the value of the Operation-Location key from the response header.

The Operation-Location key is the status URL used to check the status of the routeset
creation as demonstrated in the next section.

Check the routeset creation status and retrieve the


routesetId
To check the status of the routeset creation process and retrieve the routesetId:

1. Execute the following HTTP GET request:

HTTP

https://us.atlas.microsoft.com/routesets/operations/{operationId}?api-
version=2023-03-01-preview&subscription-key={Your-Azure-Maps-
Subscription-key}

7 Note

Get the operationId from the Operation-Location key in the response header
when creating a new routeset.

2. Copy the value of the Resource-Location key from the responses header. It's the
resource location URL and contains the routesetId :

https://us.atlas.microsoft.com/routesets/**675ce646-f405-03be-302e-
0d22bcfe17e8**?api-version=2023-03-01-preview

Make a note of the routesetId . It's required in all wayfinding requests and when you
Get the facility ID.

Get the facility ID


The facilityId , a property of the routeset, is a required parameter when searching for a
wayfinding path. Get the facilityId by querying the routeset.

1. Execute the following HTTP GET request:

HTTP

https://us.atlas.microsoft.com/routesets/{routesetId}?api-version=2023-
03-01-preview&subscription-key={Your-Azure-Maps-Subscription-key}

2. The facilityId is a property of the facilityDetails object, which you can find in
the response body of the routeset request, which is FCL43 in the following
example:

JSON

{
"routeSetId": "675ce646-f405-03be-302e-0d22bcfe17e8",
"dataSetId": "eec3825c-620f-13e1-b469-85d2767c8a41",
"created": "10/10/2022 6:58:32 PM +00:00",
"facilityDetails": [
{
"facilityId": "FCL43",
"levelOrdinals": [
0,
1
]
}
],
"creationMode": "Wall",
"ontology": "facility-2.0"
}

Get a wayfinding path


Use the wayfinding API to generate a path from the routeset you created in the previous
section. The wayfinding API requires a query that contains start and end points in an
indoor map, along with floor level ordinal numbers. For more information about Creator
wayfinding, see wayfinding in the concepts article.

To create a wayfinding query:

1. Execute the following HTTP GET request (replace {routesetId} with the routesetId
obtained in the Check the routeset creation status section and the {facilityId} with
the facilityId obtained in the Get the facility ID section):
HTTP

https://us.atlas.microsoft.com/wayfinding/path?api-version=2023-03-01-
preview&subscription-key={Your-Azure-Maps-Subscription-key}&routesetid=
{routeset-ID}&facilityid={facility-ID}&fromPoint={lat,lon}&fromLevel=
{from-level}&toPoint={lat,lon}&toLevel={to-level}&minWidth={minimun-
width}

 Tip

The AvoidFeatures parameter can be used to specify something for the


wayfinding service to avoid when determining the path, such as elevators or
stairs.

2. The details of the path and legs are displayed in the Body of the response.

The summary displays the estimated travel time in seconds for the total journey. In
addition, the estimated time for each section of the journey is displayed at the
beginning of each leg.

The wayfinding service calculates the path through specific intervening points. Each
point is displayed, along with its latitude and longitude details.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Work with datasets using the QGIS
plugin
Article • 09/24/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

QGIS is an open-source geographic information system (GIS) application that


supports viewing, editing, and analysis of geospatial data.

The Azure Maps QGIS plugin is used to view and edit datasets in QGIS . It enables
you to navigate floors using a custom floor-picker and perform CRUD operations for
multiple features simultaneously. All QGIS functionalities, such as copying features,
rotating, resizing, flipping, can be used to for advanced editing. The plugin also supports
error handling for data editing. Logs created by the plugin are useful to understand the
APIs and debug errors.

Prerequisites
Understanding of Creator concepts
A dataset
A basic working knowledge of QGIS

Get started
This section provides information on how to install QGIS and the Azure Maps QGIS
plugin , then how to open and view a dataset.

Install QGIS
If you don't already have QGIS installed, see Download QGIS . You can use the latest
version, however, it's recommended using the most stable version, which can be found
on the same page, by selecting "Looking for the most stable version?".
Install the Azure Maps QGIS plugin
To install the Azure Maps QGIS plugin:

1. Select Manage and Install Plugins from the Plugins menu to open the Plugin
Manager.

2. In the dialog that opens, select the Azure Maps plugin then the Install plugin:

For detailed instructions on installing a plugin in QGIS, see Installing New Plugins in
the QGIS Documentation.

Once you have the plugin installed, the AzureMaps symbol appears on the plugins
toolbar.
Working with datasets in the QGIS plugin
Your Azure Maps dataset contains the data describing your indoor map. A dataset
consists of layers that define a building. Each layer contains entries called features. Each
feature is a row in the dataset. A feature usually has a geometry associated with it. Each
geometry consists of a set of properties that describe it.

A featureClass is a collection of similar features. A building has facility and level feature
classes, containing features such as rooms and furniture. For example, a building has a
facility featureClass , containing facility features. It also has a levels featureClass that
defines the levels of the building, each level is a feature with its own set of properties
that describe that level. Another featureClass could be furniture, with each individual
piece of furniture described as a feature of the featureClass with its own unique set of
properties.

Open dataset
The following steps describe how to open your dataset in QGIS using the Azure Maps
QGIS plugin.

1. Select the Azure Maps symbol on the QGIS toolbar to open the Azure Maps
plugin dialog box.

2. Select your location, the United States or Europe, from the Geography drop down
list.

3. Enter your subscription key.

4. To get a list of all the dataset IDs associated with your Azure Maps account, select
the List Datasets button.

5. Select the desired datasetId from the DatasetId drop down list.

6. (Optional) Change the location where your logs are saved if you don't want them
saved to the default location.
7. Select the Get Features button to load your indoor map data into QGIS, once
loaded your map appears in the Map canvas.


View dataset
Once the dataset has been loaded, you can view the different feature classes it contains
in the Layers panel. The ordering of the layers determines how features are shown on
the map; layers at a higher order in the list are displayed on top.

Some layers have a drop-down containing multiple layers within it, followed by the
geometry of the layer, as the following image shows:

This happens in the case when the layer definition shows that the layer can hold features
of different geometries. Since QGIS only supports one geometry per layer, the plugin
splits these layers by their possible geometries.

7 Note

The geometry geometryCollection is not supported by QGIS.

You can navigate to different floor by using the Level drop-down list in the plugins
toolbar, located next to the Azure Maps plugin symbol as sown in the following image:

Edit dataset
You can add, edit and delete the features of your dataset using QGIS.

 Tip

You will be using the digitizing toolbar when editing the features of your dataset in
QGIS, for more information, see Digitizing an existing layer .

Add features
Dataset additions involve adding features to a layer.

1. In the Layers panel, select the layer that you want to add the new feature to.

2. Toggle edit mode to on in the digitizing toolbar. To view the digitizing toolbar,
navigate to View > Toolbar > Digitizing Toolbar.

3. Select any add feature options from the digitizing toolbar and make the desired
changes.

4. Select the save button in the digitizing toolbar to save changes

Edit features
Dataset edits involve editing feature geometries and properties.

Edit a feature geometry

1. In the Layers panel, select the layer containing the feature you want to edit.

2. Toggle edit mode to on in the digitizing toolbar.

3. Select the Vertex tool from the digitizing toolbar.


4. Once you're done with your changes, select the save button in the digitizing
toolbar.

Edit a feature property

To edit a feature property using the attribute table

1. Open the attribute table for the layer containing the feature you want to edit.

7 Note

The attribute table shows each feature, with their properties, in a tabular form.
Right-click to access any layer in the Layers panel then select Open Attribute
Table.

2. Toggle edit mode on.

3. Edit the desired property.

4. Select the save button to save changes.

Delete feature
1. Select the feature you want to delete.

2. Select the delete feature option from the digitizing toolbar.

3. Select the save button in the digitizing toolbar to save changes.


Advanced editing
To learn more about advance editing features offered in QGIS, such as moving, scaling,
copying and rotating features, see Advanced digitizing in the QGIS Documentation.

Logs
Azure Maps QGIS plugin logs information related to the requests made to Azure Maps.
You can set the location of log file in the Azure Maps plugin Dialog box. By default, log
files are stored in the folder containing your downloaded plugin.

You can view your log files in two ways:

1. QGIS. You can view the Logs in QGIS by activating the Logs Message Panel:
Logs contain:

Information about server requests and response.


Errors received from the server or QGIS.
Statistics about the number of features loaded

Error logs for edits


Error logs for edits are also stored in a separate folder called "AzureMaps_ErrorLogs".
They contain more detailed information about the request made, including headers and
body, and the response received from the server.

Python Logs
Any errors received from the QGIS framework are displayed in the Python Logs tab.

Additional information
If you have question related to Azure Maps, see MICROSOFT Q&A. Be sure and tag your
questions with "Azure Maps".

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Create a dataset using a GeoJSON package
(Preview)
Article • 04/09/2025

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired on
9/30/25. For more information, see End of Life Announcement of Azure Maps Creator .

Azure Maps Creator enables users to import their indoor map data in GeoJSON format with
Facility Ontology 2.0, which can then be used to create a dataset.

Prerequisites
An Azure Maps account
A Subscription key
An Azure Maps Creator resource
An Azure storage account
Basic understanding of Creator for indoor maps
Basic understanding of Facility Ontology 2.0
Zip package containing all required GeoJSON files. If you don't have GeoJSON files, you
can download the Contoso building sample .

) Important

This article uses the us.atlas.microsoft.com geographical URL. If your Creator


service wasn't created in the United States, you must use a different geographical
URL. For more information, see Access to Creator services.
In the URL examples in this article you will need to replace {Your-Azure-Maps-
Subscription-key} with your Azure Maps subscription key.

Create dataset using the GeoJSON package


For more information on the GeoJSON package, see the GeoJSON zip package requirements
section.
Upload the GeoJSON package
Follow the steps outlined in the How to create data registry article to upload the GeoJSON
package into your Azure storage account then register it in your Azure Maps account.

) Important

Make sure to make a note of the unique identifier ( udid ) value, you will need it. The udid
is how you reference the GeoJSON package you uploaded into your Azure storage
account from your source code and HTTP requests.

Create a dataset
A dataset is a collection of map features, such as buildings, levels, and rooms. To create a
dataset from your GeoJSON, use the new Dataset Create API. The Dataset Create API takes the
udid you got in the previous section and returns the datasetId of the new dataset.

) Important

This is different from the previous version of the Dataset Create API in that it doesn't
require a conversionId from a converted drawing package.

To create a dataset:

1. Enter the following URL to the dataset service. The request should look like the following
URL (replace {udid} with the udid obtained in Upload the GeoJSON package section):

HTTP

https://us.atlas.microsoft.com/datasets?api-version=2023-03-01-preview&udid=
{udid}&subscription-key={Your-Azure-Maps-Subscription-key}

1. Copy the value of the Operation-Location key in the response header. The Operation-
Location key is also known as the status URL and is required to check the status of the

dataset creation process and to get the datasetId , which is required to create a tileset.

Check the dataset creation status


To check the status of the dataset creation process and retrieve the datasetId :
1. Enter the status URL you copied in Create a dataset. The request should look like the
following URL:

HTTP

https://us.atlas.microsoft.com/datasets/operations/{operationId}?api-
version=2023-03-01-preview&subscription-key={Your-Azure-Maps-Subscription-
key}

2. In the Header of the HTTP response, copy the value of the unique identifier contained in
the Resource-Location key.

https://us.atlas.microsoft.com/datasets/**c9c15957-646c-13f2-611a-

1ea7adc75174**?api-version=2023-03-01-preview

Add data to an existing dataset


Data can be added to an existing dataset by providing the datasetId parameter to the Dataset
Create API along with the unique identifier of the data you wish to add. The unique identifier
can be either a udid or conversionId . This creates a new dataset consisting of the data
(facilities) from both the existing dataset and the new data being imported. Once the new
dataset has been created successfully, the old dataset can be deleted.

One thing to consider when adding to an existing dataset is how the feature IDs are created. If
a dataset is created from a converted drawing package, the feature IDs are generated
automatically. When a dataset is created from a GeoJSON package, feature IDs must be
provided in the GeoJSON file. When appending to an existing dataset, the original dataset
drives the way feature IDs are created. If the original dataset was created using a udid , it uses
the IDs from the GeoJSON, and will continue to do so with all GeoJSON packages appended to
that dataset in the future. If the dataset was created using a conversionId , IDs will be internally
generated, and will continue to be internally generated with all GeoJSON packages appended
to that dataset in the future.

Add to dataset created from a GeoJSON source


If your original dataset was created from a GoeJSON source and you wish to add another
facility created from a drawing package, you can append it to your existing dataset by
referencing its conversionId , as demonstrated by this HTTP POST request:

shttp
https://us.atlas.microsoft.com/datasets?api-version=2023-03-01-
preview&conversionId={conversionId}&outputOntology=facility-2.0&datasetId=
{datasetId}

ノ Expand table

Identifier Description

conversionId The ID returned when converting your drawing package.

datasetId The dataset ID returned when creating the original dataset from a GeoJSON package.

GeoJSON zip package requirements


The GeoJSON zip package consists of one or more RFC 7946 compliant GeoJSON files, one
for each feature class, all in the root directory (subdirectories aren't supported), compressed
with standard Zip compression and named using the .ZIP extension.

Each feature class file must match its definition in the Facility Ontology 2.0 and each feature
must have a globally unique identifier.

Feature IDs can only contain alpha-numeric (a-z, A-Z, 0-9), hyphen (-), dot (.) and underscore
(_) characters.

 Tip

If you want to be certain you have a globally unique identifier (GUID), consider creating it
by running a GUID generating tool such as the Guidgen.exe command line program
(Available with Visual Studio ). Guidgen.exe never produces the same number twice, no
matter how many times it is run or how many different machines it runs on.

Facility ontology 2.0 validations in the Dataset


Facility Ontology 2.0 defines how Azure Maps Creator internally stores facility data, divided into
feature classes, in a Creator dataset. When importing a GeoJSON package, anytime a feature is
added or modified, a series of validations run. This includes referential integrity checks and
geometry and attribute validations. These validations are described in more detail in the
following list.

The maximum number of features that can be imported into a dataset at a time is
150,000.
The facility area can be between 4 and 4,000 Sq Km.
The top level element is facility, which defines each building in the file facility.geojson.
Each facility has one or more levels, which are defined in the file levels.goejson.
Each level must be inside the facility.
Each level contains units, structures, verticalPenetrations and openings. All items defined
in the level must be fully contained within the Level geometry.
unit can consist of an array of items such as hallways, offices and courtyards, which

are defined by area, line or point elements. Units are defined in the file unit.goejson.
All unit elements must be fully contained within their level and intersect with their
children.
structure defines physical, non-overlapping areas that can't be navigated through,

such as a wall. Structures are defined in the file structure.goejson.


verticalPenetration represents a method of navigating vertically between levels, such

as stairs and elevators and are defined in the file verticalPenetration.geojson.


verticalPenetrations can't intersect with other verticalPenetrations on the same level.
openings define traversable boundaries between two units, or a unit and
verticalPenetration and are defined in the file opening.geojson.

Openings can't intersect with other openings on the same level.


Every opening must be associated with at least one verticalPenetration or unit .
Search for a location using Azure Maps
Search services
Article • 08/09/2024

The Search service is a set of RESTful APIs designed to help developers search addresses,
places, and business listings by name, category, and other geographic information. In
addition to supporting traditional geocoding, services can also reverse geocode
addresses and cross streets based on latitudes and longitudes. Latitude and longitude
values returned by the search can be used as parameters in other Azure Maps services,
such as Route and Weather.

This article demonstrates how to:

Request latitude and longitude coordinates for an address (geocode address


location) by using Search Address.
Search for an address or Point of Interest (POI) using Fuzzy Search.
Use Reverse Address Search to translate coordinate location to street address.
Translate coordinate location into a human understandable cross street using
Search Address Reverse Cross Street, most often needed in tracking applications
that receive a GPS feed from a device or asset, and wish to know where the
coordinate is located.

Prerequisites
An Azure Maps account
A subscription key

) Important

In the URL examples in this article you will need to replace {Your-Azure-Maps-
Subscription-key} with your Azure Maps subscription key.

This article uses the bruno application, but you can choose a different API
development environment.

Request latitude and longitude for an address


(geocoding)
The example in this section uses Get Search Address to convert an address into latitude
and longitude coordinates. This process is also called geocoding. In addition to returning
the coordinates, the response also returns detailed address properties such as street,
postal code, municipality, and country/region information.

 Tip

If you have a set of addresses to geocode, you can use Post Search Address Batch
to send a batch of queries in a single request.

1. Open the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/search/address/json?&subscription-key=
{Your-Azure-Maps-Subscription-key}&api-version=1.0&language=en-
US&query=400 Broad St, Seattle, WA 98109

3. Select the Create button.

4. Select the run button.

This request searches for a specific address: 400 Broad St, Seattle, WA 98109 .
Next, search an address that has more than one possible location.

5. In the Params section, change the query key to 400 Broad, Seattle , then select
the run button.

6. Next, try setting the query key to 400 Broa , then select the run button.
The response includes results from multiple countries/regions. To geobias results
to the relevant area for your users, always add as many location details as possible
to the request.

Fuzzy Search
Fuzzy Search supports standard single line and free-form searches. We recommend that
you use the Azure Maps Search Fuzzy API when you don't know your user input type for
a search request. The query input can be a full or partial address. It can also be a Point
of Interest (POI) token, like a name of POI, POI category or name of brand. Furthermore,
to improve the relevance of your search results, constrain the query results using a
coordinate location and radius, or by defining a bounding box.

 Tip

Most Search queries default to maxFuzzyLevel=1 to improve performance and


reduce unusual results. Adjust fuzziness levels by using the maxFuzzyLevel or
minFuzzyLevel parameters. For more information on maxFuzzyLevel and a complete

list of all optional parameters, see Fuzzy Search URI Parameters.

Search for an address using Fuzzy Search


The example in this section uses Fuzzy Search to search the entire world for pizza, then
searches over the scope of a specific country/region. Finally, it demonstrates how to use
a coordinate location and radius to scope a search over a specific area, and limit the
number of returned results.

) Important

To geobias results to the relevant area for your users, always add as many location
details as possible. For more information, see Best Practices for Search.

1. Open the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP
https://atlas.microsoft.com/search/fuzzy/json?api-
version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&language=en-US&query=pizza

7 Note

The json attribute in the URL path determines the response format. This article
uses json for ease of use and readability. To find other supported response
formats, see the format parameter definition in the URI Parameter reference
documentation.

3. Select the run button, then review the response body.

The ambiguous query string for "pizza" returned 10 point of interest (POI) results
in both the "pizza" and "restaurant" categories. Each result includes details such as
street address, latitude and longitude values, view port, and entry points for the
location. The results are now varied for this query, and aren't tied to any reference
location.

In the next step, you'll use the countrySet parameter to specify only the
countries/regions for which your application needs coverage. For a complete list of
supported countries/regions, see Azure Maps geocoding coverage.

4. The default behavior is to search the entire world, potentially returning


unnecessary results. Next, search for pizza only in the United States. Add the
countrySet key to the Params section, and set its value to US . Setting the

countrySet key to US bounds the results to the United States.


The results are now bounded by the country code and the query returns pizza
restaurants in the United States.

5. To get an even more targeted search, you can search over the scope of a lat/lon
coordinate pair. The following example uses the lat/lon coordinates of the Seattle
Space Needle. Since we only want to return results within a 400-meters radius, we
add the radius parameter. Also, we add the limit parameter to limit the results to
the five closest pizza places.

In the Params section, add the following key/value pairs:

ノ Expand table

Key Value

lat 47.620525

lon -122.349274

radius 400

limit 5

6. Select run. The response includes results for pizza restaurants near the Seattle
Space Needle.

Search for a street address using Reverse


Address Search
Get Search Address Reverse translates coordinates into human readable street
addresses. This API is often used for applications that consume GPS feeds and want to
discover addresses at specific coordinate points.

) Important

To geobias results to the relevant area for your users, always add as many location
details as possible. For more information, see Best Practices for Search.

 Tip

If you have a set of coordinate locations to reverse geocode, you can use Post
Search Address Reverse Batch to send a batch of queries in a single request.
This example demonstrates making reverse searches using a few of the optional
parameters that are available. For the full list of optional parameters, see Reverse Search
Parameters.

1. Open the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/search/address/reverse/json?api-
version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&language=en-US&query=47.591180,-122.332700

3. Select the run button, and review the response body. You should see one query
result. The response includes key address information about Safeco Field.

4. Next, add the following key/value pairs to the Params section:

ノ Expand table

Key Value Returns

number 1 The response can include the side of the street (Left/Right) and
also an offset position for the number.

returnSpeedLimit true Returns the speed limit at the address.

returnRoadUse true Returns road use types at the address. For all possible road use
types, see Road Use Types.

returnMatchType true Returns the type of match. For all possible values, see Reverse
Address Search Results.
5. Select the run button, and review the response body.

6. Next, add the entityType key, and set its value to Municipality . The entityType
key overrides the returnMatchType key in the previous step. returnSpeedLimit and
returnRoadUse also need removed since you're requesting information about the

municipality. For all possible entity types, see Entity Types.

7. Select the run button. Compare the results to the results returned in step 5.
Because the requested entity type is now municipality , the response doesn't
include street address information. Also, the returned geometryId can be used to
request boundary polygon through Azure Maps Get Search Polygon API.

 Tip
For more information on these as well as other parameters, see Reverse Search
Parameters.

Search for cross street using Reverse Address


Cross Street Search
This example demonstrates how to search for a cross street based on the coordinates of
an address.

1. Open the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/search/address/reverse/crossstreet/json?
api-version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&language=en-US&query=47.591180,-122.332700

3. Select the run button, and review the response body. Notice that the response
contains a crossStreet value of South Atlantic Street .

Next steps
Azure Maps Search service

Best practices for Azure Maps Search service

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Best practices for Azure Maps Search
service
Article • 03/22/2023

Azure Maps Search service includes API that offers various capabilities to help
developers to search addresses, places, business listings by name or category, and other
geographic information. For example, Search Fuzzy allows users to search for an address
or Point of Interest (POI).

This article explains how to apply sound practices when you call data from Azure Maps
Search service. You'll learn how to:

" Build queries to return relevant matches


" Limit search results
" Learn the differences between result types
" Read the address search-response structure

Prerequisites
An Azure Maps account
A subscription key

This article uses the Postman application to build REST calls, but you can choose any
API development environment.

Best practices to geocode addresses


When you search for a full or partial address by using Azure Maps Search service, the
API reads keywords from your search query. Then it returns the longitude and latitude
coordinates of the address. This process is called geocoding.

The ability to geocode in a country/region depends on the availability of road data and
the precision of the geocoding service. For more information about Azure Maps
geocoding capabilities by country or region, see Geocoding coverage.

Limit search results


Azure Maps Search API can help you limit search results appropriately. You limit results
so that you can display relevant data to your users.
7 Note

The search APIs support more parameters than just the ones that this article
discusses.

Geobiased search results


To geobias results to the relevant area for your user, always add as many location details
as possible. You might want to restrict the search results by specifying some input types:

Set the countrySet parameter. You can set it to US,FR , for example. By default, the
API searches the entire world, so it can return unnecessary results. If your query has
no countrySet parameter, then the search might return inaccurate results. For
example, a search for a city named Bellevue returns results from the USA and
France because both countries/regions contain a city named Bellevue.

You can use the btmRight and topleft parameters to set the bounding box. These
parameters restrict the search to a specific area on the map.

To influence the area of relevance for the results, define the lat and lon
coordinate parameters. Use the radius parameter to set the radius of the search
area.

Fuzzy search parameters

We recommend that you use Search Fuzzy when you don't know your user inputs for a
search query. For example, input from the user could be an address or the type of Point
of Interest (POI), like shopping mall. The API combines POI searching and geocoding
into a canonical single-line search:

The minFuzzyLevel and maxFuzzyLevel parameters help return relevant matches


even when query parameters don't exactly match the information that the user
wants. To maximize performance and reduce unusual results, set search queries to
defaults of minFuzzyLevel=1 and maxFuzzyLevel=2 .

For example, when the maxFuzzyLevel parameter is set to 2, the search term
restrant is matched to restaurant. You can override the default fuzzy levels when
you need to.

Use the idxSet parameter to prioritize the exact set of result types. To prioritize an
exact set of results, you can submit a comma-separated list of indexes. In your list,
the item order doesn't matter. Azure Maps supports the following indexes:

Addr - Address ranges: Address points that are interpolated from the beginning
and end of the street. These points are represented as address ranges.

Geo - Geographies: Administrative divisions of land. A geography can be a


country/region, state, or city, for example.

PAD - Point addresses: Addresses that include a street name and number. Point

addresses can be found in an index. An example is Soquel Dr 2501. A point address


provides the highest level of accuracy available for addresses.

POI - Points of interest: Points on a map that are considered to be worth attention
or that might be interesting. Search Address doesn't return POIs.

Str - Streets: Streets on the map.

XStr - Cross streets or intersections: Junctions or places where two streets


intersect.

Usage examples
idxSet=POI - Search POIs only.

idxSet=PAD,Addr - Search addresses only. PAD indicates the point address, and
Addr indicates the address range.

Reverse-geocode and filter for a geography entity type


When you do a reverse-geocode search using Search Address Reverse, the service can
return polygons for administrative areas. For example, you might want to fetch the area
polygon for a city. To narrow the search to specific geography entity types, include the
entityType parameter in your requests.

The resulting response contains the geography ID and the entity type that was matched.
If you provide more than one entity, then the endpoint returns the smallest entity
available. You can use the returned geometry ID to get the geography's geometry
through the Search Polygon service.

Sample request

HTTP
https://atlas.microsoft.com/search/address/reverse/json?api-
version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&query=47.6394532,-122.1304551&language=en-US&entityType=Municipality

Response

JSON

{
"summary": {
"queryTime": 14,
"numResults": 1
},
"addresses": [
{
"address": {
"routeNumbers": [],
"countryCode": "US",
"countrySubdivision": "WA",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle East",
"municipality": "Redmond",
"country": "United States",
"countryCodeISO3": "USA",
"countrySubdivisionName": "Washington"
},
"position": "47.639454,-122.130455",
"dataSources": {
"geometry": {
"id": "00005557-4100-3c00-0000-0000596ae571"
}
},
"entityType": "Municipality"
}
]
}

Set the results language


Use the language parameter to set the language for the returned search results. If the
request doesn't set the language, then by default Search service uses the most common
language in the country or region. When no data is available in the specified language,
the default language is used.

For more information, see Azure Maps supported languages.


Use predictive mode (automatic suggestions)
To find more matches for partial queries, set the typeahead parameter to true . This
query is interpreted as a partial input, and the search enters predictive mode. If you
don't set the typeahead parameter to true , then the service assumes that all relevant
information has been passed in.

In the following sample query, the Search Address service is queried for Microso. Here,
the typeahead parameter set to true . The response shows that the search service
interpreted the query as partial query. The response contains results for an automatically
suggested query.

Sample query

HTTP

https://atlas.microsoft.com/search/address/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1.0&typeahead=true&countrySet=US&lat=47.6370891183&lon=-122.12373617
2&query=Microsoft

Response

JSON

{
"summary": {
"query": "microsoft",
"queryType": "NON_NEAR",
"queryTime": 18,
"numResults": 7,
"offset": 0,
"totalResults": 7,
"fuzzyLevel": 1,
"geoBias": {
"lat": 47.6370891183,
"lon": -122.123736172
}
},
"results": [
{
"type": "Street",
"id": "US/STR/p0/9438784",
"score": 2.594099998474121,
"dist": 314.0590106663596,
"address": {
"streetName": "Microsoft Way",
"municipalitySubdivision": "Redmond",
"municipality": "Redmond",
},
"position": {
"lat": 47.63988,
"lon": -122.12438
},
"viewport": {
"topLeftPoint": {
"lat": 47.64223,
"lon": -122.1256,
"valid": true
},
"btmRightPoint": {
"lat": 47.63748,
"lon": -122.12309,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/1756074",
"score": 2.592679977416992,
"dist": 876.0272035824189,
"address": {
"streetName": "Microsoft Road",
"municipalitySubdivision": "Redmond",
"municipality": "Redmond",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle East",
"countrySubdivision": "WA",
"countrySubdivisionName": "Washington",
"postalCode": "98052",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "Microsoft Road, Redmond, WA 98052"
},
"position": {
"lat": 47.64032,
"lon": -122.1344
},
"viewport": {
"topLeftPoint": {
"lat": 47.64253,
"lon": -122.13535,
"valid": true
},
"btmRightPoint": {
"lat": 47.63816,
"lon": -122.13305,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/1470668",
"score": 2.5290400981903076,
"dist": 2735.4883918101486,
"address": {
"streetName": "Microsoft West Campus Road",
"municipalitySubdivision": "Redmond",
"municipality": "Bellevue",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle East",
"countrySubdivision": "WA",
"countrySubdivisionName": "Washington",
"postalCode": "98007",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "Microsoft West Campus Road, Bellevue, WA
98007"
},
"position": {
"lat": 47.65784,
"lon": -122.14335
},
"viewport": {
"topLeftPoint": {
"lat": 47.65785,
"lon": -122.14335,
"valid": true
},
"btmRightPoint": {
"lat": 47.65784,
"lon": -122.14325,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/12812615",
"score": 2.527509927749634,
"dist": 2870.9579016916873,
"address": {
"streetName": "Microsoft West Campus Road",
"municipalitySubdivision": "Redmond",
"municipality": "Redmond",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle East",
"countrySubdivision": "WA",
"countrySubdivisionName": "Washington",
"postalCode": "98052",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "Microsoft West Campus Road, Redmond, WA
98052"
},
"position": {
"lat": 47.66034,
"lon": -122.1404
},
"viewport": {
"topLeftPoint": {
"lat": 47.66039,
"lon": -122.14325,
"valid": true
},
"btmRightPoint": {
"lat": 47.65778,
"lon": -122.13749,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/197588",
"score": 2.4630401134490967,
"dist": 878.1404663812472,
"address": {
"streetName": "157th Avenue Northeast",
"municipalitySubdivision": "Redmond",
"municipality": "Redmond",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle East",
"countrySubdivision": "WA",
"countrySubdivisionName": "Washington",
"postalCode": "98052",
"extendedPostalCode": "980525344, 980525398, 980525399",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "157th Avenue Northeast, Redmond, WA
98052"
},
"position": {
"lat": 47.64351,
"lon": -122.13056
},
"viewport": {
"topLeftPoint": {
"lat": 47.64473,
"lon": -122.13058,
"valid": true
},
"btmRightPoint": {
"lat": 47.6425,
"lon": -122.13016,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/3033991",
"score": 2.0754499435424805,
"dist": 3655467.8844475765,
"address": {
"streetName": "Microsoft Way",
"municipalitySubdivision": "Yorkmount, Charlotte",
},
"position": {
"lat": 35.14267,
"lon": -80.91824
},
"viewport": {
"topLeftPoint": {
"lat": 35.14287,
"lon": -80.91839,
"valid": true
},
"btmRightPoint": {
"lat": 35.14267,
"lon": -80.91814,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/8395877",
"score": 2.0754499435424805,
"dist": 3655437.0037482483,
"address": {
"streetName": "Microsoft Way",
"municipalitySubdivision": "Charlotte",
"municipality": "Charlotte",
"countrySecondarySubdivision": "Mecklenburg",
"countryTertiarySubdivision": "Township 1 Charlotte",
"countrySubdivision": "NC",
"countrySubdivisionName": "North Carolina",
"postalCode": "28273",
"extendedPostalCode": "282738105, 282738106, 282738108,
2827382, 282738200",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "Microsoft Way, Charlotte, NC 28273"
},
"position": {
"lat": 35.14134,
"lon": -80.9198
},
"viewport": {
"topLeftPoint": {
"lat": 35.14274,
"lon": -80.92159,
"valid": true
},
"btmRightPoint": {
"lat": 35.14002,
"lon": -80.91824,
"valid": true
}
}
}
]
}

Encode a URI to handle special characters


To find cross street addresses, you must encode the URI to handle special characters in
the address. Consider this address example: 1st Avenue & Union Street, Seattle. Here,
encode the ampersand character ( & ) before you send the request.

We recommend that you encode character data in a URI. In a URI, you encode all
characters by using a percentage sign ( % ) and a two-character hexadecimal value that
corresponds to the characters' UTF-8 code.

Usage examples

Start with this address:

query=1st Avenue & E 111th St, New York

Encode the address:

query=1st%20Avenue%20%26%20E%20111th%20St%2C%20New%20York

You can use the following methods.

JavaScript or TypeScript:

JavaScript
encodeURIComponent(query)

C# or Visual Basic:

C#

Uri.EscapeDataString(query)

Java:

Java

URLEncoder.encode(query, "UTF-8")

Python:

Python

import urllib.parse
urllib.parse.quote(query)

C++:

C++

#include <curl/curl.h>
curl_easy_escape(query)

PHP:

PHP

urlencode(query)

Ruby:

Ruby

CGI::escape(query)

Swift:

Swift
query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedChar
acterSet())

Go:

Go

import ("net/url")
url.QueryEscape(query)

Best practices for POI searching


In a POI search, you can request POI results by name. For example, you can search for a
business by name.

We strongly recommend that you use the countrySet parameter to specify


countries/regions where your application needs coverage. The default behavior is to
search the entire world. This broad search might return unnecessary results, and the
search might take a long time.

Brand search
To improve the relevance of the results and the information in the response, a POI
search response includes brand information. You can use this information to further to
parse the response.

In a request, you can submit a comma-separated list of brand names. Use the list to
restrict the results to specific brands by setting the brandSet parameter. In your list, item
order doesn't matter. When you provide multiple brand lists, the results that are
returned must belong to at least one of your lists.

To explore brand searching, let's make a POI category search request. In the following
example, we look for gas stations near the Microsoft campus in Redmond, Washington.
The response shows brand information for each POI that was returned.

Sample query

HTTP

https://atlas.microsoft.com/search/poi/json?subscription-key={Your-Azure-
Maps-Subscription-key}&api-
version=1.0&query=gas%20station&limit=3&lat=47.6413362&lon=-122.1327968
Response

JSON

{
"summary": {
"query": "gas station",
"queryType": "NON_NEAR",
"queryTime": 276,
"numResults": 3,
"offset": 0,
"totalResults": 762680,
"fuzzyLevel": 1,
"geoBias": {
"lat": 47.6413362,
"lon": -122.1327968
}
},
"results": [
{
"type": "POI",
"id": "US/POI/p0/8831765",
"score": 5.6631999015808105,
"dist": 1037.0280221303253,
"info": "search:ta:840531000004190-US",
"poi": {
"name": "Chevron",
"phone": "+(1)-(425)-6532200",
"brands": [
{
"name": "Chevron"
}
],
"categorySet": [
{
"id": 7311
}
],
"url": "www.chevron.com",
"categories": [
"petrol station"
],
"classifications": [
{
"code": "PETROL_STATION",
"names": [
{
"nameLocale": "en-US",
"name": "petrol station"
}
]
}
]
},
"address": {
"streetNumber": "2444",
"streetName": "Bel Red Rd",
"municipalitySubdivision": "Northeast Bellevue, Bellevue",
},
"position": {
"lat": 47.63201,
"lon": -122.13281
},
"viewport": {
"topLeftPoint": {
"lat": 47.63291,
"lon": -122.13414,
"valid": true
},
"btmRightPoint": {
"lat": 47.63111,
"lon": -122.13148,
"valid": true
}
},
"entryPoints": [
{
"type": "main",
"position": {
"lat": 47.63222,
"lon": -122.13312,
"valid": true
}
}
]
},
{
"type": "POI",
"id": "US/POI/p0/8831752",
"score": 5.662710189819336,
"dist": 1330.1278248163273,
"info": "search:ta:840539001100326-US",
"poi": {
"name": "76",
"phone": "+(1)-(425)-7472126",
"brands": [
{
"name": "76"
}
],
"categorySet": [
{
"id": 7311
}
],
"url": "www.76.com",
"categories": [
"petrol station"
],
"classifications": [
{
"code": "PETROL_STATION",
"names": [
{
"nameLocale": "en-US",
"name": "petrol station"
}
]
}
]
},
"address": {
"streetNumber": "2421",
"streetName": "148Th Ave Ne",
"municipalitySubdivision": "Redmond, Bridle Trails,
Bellevue",
"municipality": "Redmond, Bellevue",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle East",
"countrySubdivision": "WA",
"countrySubdivisionName": "Washington",
"postalCode": "98007",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "2421 148Th Ave Ne, Bellevue, WA 98007",
"localName": "Bellevue"
},
"position": {
"lat": 47.63187,
"lon": -122.14365
},
"viewport": {
"topLeftPoint": {
"lat": 47.63277,
"lon": -122.14498,
"valid": true
},
"btmRightPoint": {
"lat": 47.63097,
"lon": -122.14232,
"valid": true
}
},
"entryPoints": [
{
"type": "minor",
"position": {
"lat": 47.63187,
"lon": -122.14374,
"valid": true
}
},
{
"type": "main",
"position": {
"lat": 47.63186,
"lon": -122.14313,
"valid": true
}
}
]
},
{
"type": "POI",
"id": "US/POI/p0/8831764",
"score": 5.662449836730957,
"dist": 1458.645407416307,
"info": "search:ta:840539000488527-US",
"poi": {
"name": "BROWN BEAR CAR WASH",
"phone": "+(1)-(425)-6442868",
"brands": [
{
"name": "Texaco"
}
],
"categorySet": [
{
"id": 7311
}
],
"url": "www.texaco.com/",
"categories": [
"petrol station"
],
"classifications": [
{
"code": "PETROL_STATION",
"names": [
{
"nameLocale": "en-US",
"name": "petrol station"
}
]
}
]
},
"address": {
"streetNumber": "15248",
"streetName": "Bel Red Rd",
"municipalitySubdivision": "Redmond",
},
"position": {
"lat": 47.62843,
"lon": -122.13628
},
"viewport": {
"topLeftPoint": {
"lat": 47.62933,
"lon": -122.13761,
"valid": true
},
"btmRightPoint": {
"lat": 47.62753,
"lon": -122.13495,
"valid": true
}
},
"entryPoints": [
{
"type": "main",
"position": {
"lat": 47.62827,
"lon": -122.13628,
"valid": true
}
}
]
}
]
}

Airport search
By using the Search POI API, you can look for airports by using their official code. For
example, you can use SEA to find the Seattle-Tacoma International Airport:

HTTP

https://atlas.microsoft.com/search/poi/json?subscription-key={Your-Azure-
Maps-Subscription-key}&api-version=1.0&query=SEA

Nearby search
To retrieve POI results around a specific location, you can try using Search Nearby. The
endpoint returns only POI results. It doesn't take in a search query parameter.

To limit the results, we recommend that you set the radius.

Understanding the responses


Let's find an address in Seattle by making an address-search request to the Azure Maps
Search service. In the following request URL, we set the countrySet parameter to US to
search for the address in the USA.

Sample query
HTTP

https://atlas.microsoft.com/search/address/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1&query=400%20Broad%20Street%2C%20Seattle%2C%20WA&countrySet=US

Supported types of results


Point Address: Points on a map that have a specific address with a street name and
number. Point Address provides the highest level of accuracy for addresses.

Address Range: The range of address points that are interpolated from the
beginning and end of the street.

Geography: Areas on a map that represent administrative divisions of a land, for


example, country/region, state, or city.

POI: Points on a map that are worth attention and that might be interesting.

Street: Streets on the map. Addresses are resolved to the latitude and longitude
coordinates of the street that contains the address. The house number might not
be processed.

Cross Street: Intersections. Cross streets represent junctions where two streets
intersect.

Response
Let's look at the response structure. In the response that follows, the types of the result
objects are different. If you look carefully, you see three types of result objects:

Point Address
Street
Cross Street

Notice that the address search doesn't return POIs.


The Score parameter for each response object indicates how the matching score relates
to the scores of other objects in the same response. For more information about
response object parameters, see Get Search Address.

JSON

{
"summary": {
"query": "400 broad street seattle wa",
"queryType": "NON_NEAR",
"queryTime": 146,
"numResults": 6,
"offset": 0,
"totalResults": 7,
"fuzzyLevel": 1
},
"results": [
{
"type": "Point Address",
"id": "US/PAD/p0/28725082",
"score": 9.893799781799316,
"address": {
"streetNumber": "400",
"streetName": "Broad Street",
},
"position": {
"lat": 47.62039,
"lon": -122.34928
},
"viewport": {
"topLeftPoint": {
"lat": 47.62129,
"lon": -122.35061,
"valid": true
},
"btmRightPoint": {
"lat": 47.61949,
"lon": -122.34795,
"valid": true
}
},
"entryPoints": [
{
"type": "main",
"position": {
"lat": 47.61982,
"lon": -122.34886,
"valid": true
}
}
]
},
{
"type": "Street",
"id": "US/STR/p0/6700384",
"score": 8.129190444946289,
"address": {
"streetName": "Broad Street",
},
"position": {
"lat": 47.61724,
"lon": -122.35207
},
"viewport": {
"topLeftPoint": {
"lat": 47.61825,
"lon": -122.35336,
"valid": true
},
"btmRightPoint": {
"lat": 47.61626,
"lon": -122.35078,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/9701953",
"score": 8.129190444946289,
"address": {
"streetName": "Broad Street",
},
"position": {
"lat": 47.61965,
"lon": -122.349
},
"viewport": {
"topLeftPoint": {
"lat": 47.62066,
"lon": -122.35041,
"valid": true
},
"btmRightPoint": {
"lat": 47.61857,
"lon": -122.34761,
"valid": true
}
}
},
{
"type": "Street",
"id": "US/STR/p0/11721297",
"score": 8.129190444946289,
"address": {
"streetName": "Broad Street",
"municipalitySubdivision": "Seattle, Downtown Seattle, Denny
Regrade, Belltown",
"municipality": "Seattle",
"countrySecondarySubdivision": "King",
"countryTertiarySubdivision": "Seattle",
"countrySubdivision": "WA",
"countrySubdivisionName": "Washington",
"postalCode": "98121",
"extendedPostalCode": "981211237",
"countryCode": "US",
"country": "United States",
"countryCodeISO3": "USA",
"freeformAddress": "Broad Street, Seattle, WA 98121"
},
"position": {
"lat": 47.61825,
"lon": -122.35078
},
"viewport": {
"topLeftPoint": {
"lat": 47.61857,
"lon": -122.35078,
"valid": true
},
"btmRightPoint": {
"lat": 47.61825,
"lon": -122.35041,
"valid": true
}
}
},
{
"type": "Cross Street",
"id": "US/XSTR/p1/232144",
"score": 6.754479885101318,
"address": {
"streetName": "Broad Street & Valley Street",
"municipalitySubdivision": "South Lake Union, Seattle",
},
"position": {
"lat": 47.62545,
"lon": -122.33974
},
"viewport": {
"topLeftPoint": {
"lat": 47.62635,
"lon": -122.34107,
"valid": true
},
"btmRightPoint": {
"lat": 47.62455,
"lon": -122.33841,
"valid": true
}
}
}
]
}

Geometry
A response type of Geometry can include the geometry ID that's returned in the
dataSources object under geometry and id . For example, you can use the Search

Polygon service to request the geometry data in a GeoJSON format. By using this
format, you can get a city or airport outline for a set of entities. You can then use this
boundary data to Set up a geofence or Search POIs inside the geometry.

Responses for Search Address or the Search Fuzzy can include the geometry ID that's
returned in the dataSources object under geometry and id :

JSON

"dataSources": {
"geometry": {
"id": "00005557-4100-3c00-0000-000059690938" // The geometry ID
is returned in the dataSources object under "geometry" and "id".
}
}

Next steps
To learn more, please see:

How to build Azure Maps Search service requests

Search service API documentation


Best practices for Azure Maps Route
service
Article • 03/22/2023

The Route Directions and Route Matrix APIs in Azure Maps Route service can be used to
calculate the estimated arrival times (ETAs) for each requested route. Route APIs
consider factors such as real-time traffic information and historic traffic data, like the
typical road speeds on the requested date and time. The APIs return the shortest or
fastest routes available to multiple destinations at a time in sequence or in optimized
order, based on time or distance. Users can also request specialized routes and details
for walkers, bicyclists, and commercial vehicles like trucks. This article discusses best
practices for calling the Azure Maps Route service, including how-to:

Choose between the Route Directions APIs and the Matrix Routing API
Request historic and predicted travel times, based on real-time and historical traffic
data
Request route details, like time and distance, for the entire route and each leg of
the route
Request route for a commercial vehicle, like a truck
Request traffic information along a route, like jams and toll information
Request a route that consists of one or more stops (waypoints)
Optimize a route of one or more stops to obtain the best order to visit each stop
(waypoint)
Optimize alternative routes using supporting points. For example, offer alternative
routes that pass an electric vehicle charging station.
Use the Route service with the Azure Maps Web SDK

Prerequisites
An Azure Maps account
A subscription key

For more information about the coverage of the Route service, see the Routing
Coverage.

This article uses the Postman application to build REST calls, but you can choose any
API development environment.
Choose between Route Directions and Matrix
Routing
The Route Directions APIs return instructions including the travel time and the
coordinates for a route path. The Route Matrix API lets you calculate the travel time and
distances for a set of routes defined by origin and destination locations. For every given
origin, the Matrix API calculates the cost (travel time and distance) of routing from that
origin to every given destination. These API allow you to specify parameters such as the
desired departure time, arrival times, and the vehicle type, like car or truck. They all use
real-time or predictive traffic data accordingly to return the most optimal routes.

Consider calling Route Directions APIs if your scenario is to:

Request the shortest or fastest driving route between two or more known
locations, to get precise arrival times for your delivery vehicles.
Request detailed route guidance, including route geometry, to visualize routes on
the map
Given a list of customer locations, calculate the shortest possible route to visit each
customer location and return to the origin. This scenario is commonly known as
the traveling salesman problem. You can pass up to 150 waypoints (stops) in one
request.
Send batches of queries to the Route Directions Batch API using just a single API
call.

Consider calling Matrix Routing API if your scenario is to:

Calculate the travel time or distance between a set of origins and destinations. For
example, you have 12 drivers and you need to find the closest available driver to
pick up the food delivery from the restaurant.
Sort potential routes by their actual travel distance or time. The Matrix API returns
only travel times and distances for each origin and destination combination.
Cluster data based on travel time or distances. For example, your company has 50
employees, find all employees that live within 20 minute Drive Time from your
office.

Here's a comparison to show some capabilities of the Route Directions and Matrix APIs:

Azure Max number of Avoid Truck and Waypoints and Supporting


Maps API queries in the areas electric Traveling Salesman points
request vehicle optimization
routing
Azure Max number of Avoid Truck and Waypoints and Supporting
Maps API queries in the areas electric Traveling Salesman points
request vehicle optimization
routing

Get Route 1 ✔ ✔
Directions

Post Route 1 ✔ ✔ ✔ ✔
Directions

Post Route 700 ✔ ✔


Directions
Batch

Post Route 700 ✔


Matrix

To learn more about electric vehicle routing capabilities, see our tutorial on how to route
electric vehicles using Azure Notebooks with Python.

Request historic and real-time data


By default, the Route service assumes the traveling mode is a car and the departure time
is now. It returns route based on real-time traffic conditions unless a route calculation
request specifies otherwise. The routing engine factors fixed time-dependent traffic
restrictions, like 'Left turns aren't allowed between 4:00 PM to 6:00 PM'. Road closures,
like roadworks, are considered unless you specifically request a route that ignores the
current live traffic. To ignore the current traffic, set traffic to false in your API request.

The route calculation travelTimeInSeconds value includes the delay due to traffic. It's
generated by using the current and historic travel time data, when departure time is set
to now. If your departure time is set in the future, the APIs return predicted travel times
based on historical data.

If you include the computeTravelTimeFor=all parameter in your request, then the


summary element in the response has the following fields including historical traffic
conditions:

Element Description

noTrafficTravelTimeInSeconds Estimated travel time calculated as if there are no delays


on the route because of traffic conditions, for example,
because of congestion
Element Description

historicTrafficTravelTimeInSeconds Estimated travel time calculated using time-dependent


historic traffic data

liveTrafficIncidentsTravelTimeInSeconds Estimated travel time calculated using real-time speed


data

The next sections demonstrate how to make calls to the Route APIs using the discussed
parameters.

Sample query
In the first example below the departure time is set to the future, at the time of writing.

HTTP

https://atlas.microsoft.com/route/directions/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1.0&query=51.368752,-0.118332:51.385426,-0.128929&travelMode=car&tra
ffic=true&departAt=2025-03-29T08:00:20&computeTravelTimeFor=all

The response contains a summary element, like the following example. Because the
departure time is set to the future, the trafficDelayInSeconds value is zero. The
travelTimeInSeconds value is calculated using time-dependent historic traffic data. So,
in this case, the travelTimeInSeconds value is equal to the
historicTrafficTravelTimeInSeconds value.

JSON

"summary": {
"lengthInMeters": 2131,
"travelTimeInSeconds": 248,
"trafficDelayInSeconds": 0,
"departureTime": "2025-03-29T08:00:20Z",
"arrivalTime": "2025-03-29T08:04:28Z",
"noTrafficTravelTimeInSeconds": 225,
"historicTrafficTravelTimeInSeconds": 248,
"liveTrafficIncidentsTravelTimeInSeconds": 248
},

Sample query
In the next example, we have a real-time routing request, where departure time is now.
It's not explicitly specified in the URL because it's the default value.
HTTP

https://atlas.microsoft.com/route/directions/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1.0&query=47.6422356,-122.1389797:47.6641142,-122.3011268&travelMode
=car&traffic=true&computeTravelTimeFor=all

The response contains a summary as shown in the following example. Because of


congestion, the trafficDelaysInSeconds value is greater than zero. It's also greater than
historicTrafficTravelTimeInSeconds.

JSON

"summary": {
"lengthInMeters": 16637,
"travelTimeInSeconds": 2905,
"trafficDelayInSeconds": 1604,
"departureTime": "2020-02-28T01:00:20+00:00",
"arrivalTime": "2020-02-28T01:48:45+00:00",
"noTrafficTravelTimeInSeconds": 872,
"historicTrafficTravelTimeInSeconds": 1976,
"liveTrafficIncidentsTravelTimeInSeconds": 2905
},

Request route and leg details


By default, the Route service returns an array of coordinates. The response contains the
coordinates that make up the path in a list named points . Route response also includes
the distance from the start of the route and the estimated elapsed time. These values
can be used to calculate the average speed for the entire route.

The following image shows the points element.


Expand the point element to see the list of coordinates for the path:
The Route Directions APIs support different formats of instructions that can be used by
specifying the instructionsType parameter. To format instructions for easy computer
processing, use instructionsType=coded. Use instructionsType=tagged to display
instructions as text for the user. Also, instructions can be formatted as text where some
elements of the instructions are marked, and the instruction is presented with special
formatting. For more information, see the list of supported instruction types.

When instructions are requested, the response returns a new element named guidance .
The guidance element holds two pieces of information: turn-by-turn directions and
summarized instructions.
The instructions element holds turn-by-turn directions for the trip, and the
instructionGroups has summarized instructions. Each instruction summary covers a

segment of the trip that could cover multiple roads. The APIs can return details for
sections of a route. such as, the coordinate range of a traffic jam or the current speed of
traffic.
Request a route for a commercial vehicle
Azure Maps Routing APIs support commercial vehicle routing, covering commercial
trucks routing. The APIs consider specified limits. Such as, the height and weight of the
vehicle, and if the vehicle is carrying hazardous cargo. For example, if a vehicle is
carrying flammable, the routing engine avoid certain tunnels that are near residential
areas.

Sample query
The sample request below queries a route for a commercial truck. The truck is carrying
class 1 hazardous waste material.

HTTP

https://atlas.microsoft.com/route/directions/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1.0&vehicleWidth=2&vehicleHeight=2&vehicleCommercial=true&vehicleLoa
dType=USHazmatClass1&travelMode=truck&instructionsType=text&query=51.368752,
-0.118332:41.385426,-0.128929

The Route API returns directions that accommodate the dimensions of the truck and the
hazardous waste. You can read the route instructions by expanding the guidance
element.
Sample query
Changing the US Hazmat Class, from the above query, results in a different route to
accommodate this change.

HTTP

https://atlas.microsoft.com/route/directions/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1.0&vehicleWidth=2&vehicleHeight=2&vehicleCommercial=true&vehicleLoa
dType=USHazmatClass9&travelMode=truck&instructionsType=text&query=51.368752,
-0.118332:41.385426,-0.128929

The following response is for a truck carrying a class 9 hazardous material, which is less
dangerous than a class 1 hazardous material. When you expand the guidance element
to read the directions, notice that the directions aren't the same. There are more route
instructions for the truck carrying class 1 hazardous material.
Request traffic information along a route
With the Azure Maps Route Direction APIs, developers can request details for each
section type by including the sectionType parameter in the request. For example, you
can request the speed information for each traffic jam segment. Refer to the list of
values for the sectionType key to learn about the various details that you can request.

Sample query
The following query sets the sectionType to traffic . It requests the sections that
contain traffic information from Seattle to San Diego.

HTTP

https://atlas.microsoft.com/route/directions/json?subscription-key={Your-
Azure-Maps-Subscription-key}&api-
version=1.0&sectionType=traffic&query=47.6062,-122.3321:32.7157,-117.1611

The response contains the sections that are suitable for traffic along the given
coordinates.
This option can be used to color the sections when rendering the map, as in The
following image:
Calculate and optimize a multi-stop route
Azure Maps currently provides two forms of route optimizations:

Optimizations based on the requested route type, without changing the order of
waypoints. For more information, see RouteType.

Traveling salesman optimization, which changes the order of the waypoints to


obtain the best order to visit each stop

For multi-stop routing, up to 150 waypoints may be specified in a single route request.
The starting and ending coordinate locations can be the same, as would be the case
with a round trip. But you need to provide at least one more waypoint to make the
route calculation. Waypoints can be added to the query in-between the origin and
destination coordinates.

If you want to optimize the best order to visit the given waypoints, then you need to
specify computeBestOrder=true. This scenario is also known as the traveling salesman
optimization problem.

Sample query
The following query requests the path for six waypoints, with the computeBestOrder
parameter set to false . It's also the default value for the computeBestOrder parameter.

HTTP

https://atlas.microsoft.com/route/directions/json?api-
version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&computeBestOrder=false&query=47.606544,-122.336502:47.759892,-122.20482
1:47.670682,-122.120415:47.480133,-122.213369:47.615556,-122.193689:47.67650
8,-122.206054:47.495472,-122.360861

The response describes the path length to be 140,851 meters, and that it would take
9,991 seconds to travel that path.

The following image illustrates the path resulting from this query. This path is one
possible route. It's not the optimal path based on time or distance.
This route waypoint order is: 0, 1, 2, 3, 4, 5, and 6.

Sample query
The following query requests the path for the same six waypoints, as in the above
sample. This time, the computeBestOrder parameter set to true (the traveling salesman
optimization).

HTTP

https://atlas.microsoft.com/route/directions/json?api-
version=1.0&subscription-key={Your-Azure-Maps-Subscription-
key}&computeBestOrder=true&query=47.606544,-122.336502:47.759892,-122.204821
:47.670682,-122.120415:47.480133,-122.213369:47.615556,-122.193689:47.676508
,-122.206054:47.495472,-122.360861

The response describes the path length to be 91,814 meters, and that it would take
7,797 seconds to travel that path. The travel distance and the travel time are both lower
here because the API returned the optimized route.
The following image illustrates the path resulting from this query.

The optimal route has the following waypoint order: 0, 5, 1, 2, 4, 3, and 6.


 Tip

The optimized waypoint order information from the Routing service provides a set
of indices. These exclude the origin and the destination indices. You need to
increment these values by 1 to account for the origin. Then, add your destination to
the end to get the complete ordered waypoint list.

Calculate and bias alternative routes using


supporting points
You might have situations where you want to reconstruct a route to calculate zero or
more alternative routes for a reference route. For example, you may want to show
customers alternative routes that pass your retail store. In this case, you need to bias a
location using supporting points. Here are the steps to bias a location:

1. Calculate a route as-is and get the path from the route response
2. Use the route path to find the desired locations along or near the route path. For
example, you can use the Point of Interest request or query your own data in your
database.
3. Order the locations based on the distance from the start of the route
4. Add these locations as supporting points in a new route request to Post Route
Directions. To learn more about the supporting points, see the Post Route
Directions API documentation.

When calling Post Route Directions, you can set the minimum deviation time or the
distance constraints, along with the supporting points. Use these parameters if you want
to offer alternative routes, but you also want to limit the travel time. When these
constraints are used, the alternative routes follow the reference route from the origin
point for the given time or distance. In other words, the other routes diverge from the
reference route per the given constraints.

The following image is an example of rendering alternative routes with specified


deviation limits for the time and the distance.
Use the Routing service in a web app
The Azure Maps Web SDK provides a Service module. This module is a helper library
that makes it easy to use the Azure Maps REST APIs in web or Node.js applications,
using JavaScript or TypeScript. The Service module can be used to render the returned
routes on the map. The module automatically determines which API to use with GET and
POST requests.

Next steps
To learn more, please see:

Azure Maps Route service

How to use the Service module


Show route on the map

Azure Maps npm Package


Create multi-itinerary optimization
service
Article • 06/07/2024

​This guide explains how to use Azure Maps and NVIDIA cuOpt to create an itinerary
optimization service. This service automates the process of building itineraries for
multiple agents and mixed fleets, utilizing the NVIDIA cuOpt route optimization engine
to optimize routes across multiple destinations.​​

This is a two-step process that requires a cost matrix for the travel time and a solver to
optimize the problem and generate an outcome. A cost matrix represents the cost of
traveling between every two sets of locations in the problem, which includes the travel
time cost and other costs of travel.

This article describes how to:

Get started with NVIDIA cuOpt on Azure Marketplace.


Use Azure Maps Route Matrix API to get the travel cost.
How to map the problem to cuOpt API calls.
How to use the cuOpt response.
Call Azure Maps Route Directions API for routing.

Refer to the Multi Itinerary Optimization code sample for a quick start.

Prerequisites
An Azure Maps account
A subscription key or other form of Authentication with Azure Maps

Service support
This service can support the following features and constraints.

ノ Expand table

Route Optimization capabilities Supported?

Truck and automobiles Yes

Multi-itinerary Yes

Multi driver Yes

Multi day Yes

Mixed fleet Yes

Vehicle time window Yes

Time limits Yes

Priority Yes

Agent breaks Yes

Pickup deliveries Yes

Cost per vehicle Yes

Min and max vehicles Yes

For the full list of supported capabilities, see cuOpt Supported Features .

Get started with NVIDIA cuOpt on Azure


Marketplace
NVIDIA cuOpt uses GPU accelerated logistics solver and optimizations to calculate
complex vehicle routing problems with a wide range of constraints. For more
information, see the List of cuOpt supported features .

cuOpt is included with NVIDIA AI Enterprise. Visit Azure Marketplace to get started.

Get the travel cost


Itinerary optimization requires a square matrix of some travel metric that is passed to
the cuOpt solver. This could include travel time or distance cost. A cost matrix is a
square matrix that represents the cost of traveling between every pair of locations in the
problem.

The Azure Maps Route Matrix API calculates the time and distance cost of routing from
origin to every destination. The set of origins and the set of destinations can be thought
of as the column and row headers of a table and each cell in the table contains the costs
of routing from the origin to the destination for that cell.

For example, a restaurant has two drivers that need to deliver food to four locations. To
solve this case, call the Route Matrix API to get the travel times between all locations.
This example assumes that the drivers’ start, and end location is the restaurant. If the
start and end locations are different from the depot, they must be included in the cost
matrices.

Number of origins = Number of destinations = 1 (restaurant also known as depot) + 4


(deliveries)

Matrix size = 5 origins x 5 destinations = 25

7 Note

Azure Maps Route Matrix can support up to 700 matrix cells which approximate to
a square matrix of 26x26. You can use it to plan the itinerary for 26 locations
including depots and deliveries.

The Route Matrix POST request:

HTML

https://atlas.microsoft.com/route/matrix/json?api-
version=1.0&routeType=shortest

JSON

{
"origins": {
"type": "MultiPoint",
"coordinates": [
[4.85106, 52.36006], //restaurant or depot
[4.85056, 52.36187], //delivery location 1
[4.85003, 52.36241], //delivery location 2
[4.42937, 52.50931], //delivery location 3
[4.42940, 52.50843] //delivery location 4
]
},
"destinations": {
"type": "MultiPoint",
[4.85106, 52.36006], //restaurant or depot
[4.85056, 52.36187], //delivery location 1
[4.85003, 52.36241], //delivery location 2
[4.42937, 52.50931], //delivery location 3
[4.42940, 52.50843] //delivery location 4
]
}
}

The Route Matrix response returns a 5x5 multi-dimensional array where each row
represents the origins and columns represent the destinations. Use the field
travelTimeInSeconds to get the time cost for each location pair. The time unit should be

consistent across the solution. Once the preprocessing stage is complete, the order,
depot, fleet info and the cost matrix, are sent over and imported to the cuOpt Server via
API calls.

The following JSON sample shows what is returned in the body of the HTTP response of
the cost matrix sample:

JSON

cost_matrix_data = [
[ 0, 10, 8, 6, 10],
[10, 0, 12, 8, 6],
[ 8, 16, 0, 8, 4],
[ 2, 8, 6, 0, 8],
[ 6, 6, 10, 12, 0],
]

7 Note

The cost of going from a location to itself is typically 0, and the cost of going from
location A to location B is not necessarily equal to going from location B to location
A.

Map the problem to cuOpt API calls


This section describes how to build request data for cuOpt calls. For more examples, see
cuOpt best practices .

1. Set Cost Matrix


2. Set Fleet Data
3. Set Task Data
4. Set Solver Config (optional)

Set Cost Matrix


Parse the Azure Maps Route Matrix API response to get the travel time between
locations to construct the cost matrix. In the following example, “0” represents the key
that represents a specific vehicle type.

JSON

"data": {" cost_matrix_data ": {


"data": {
"0": [
[0, 5, 4, 3, 5],
[5, 0, 6, 4, 3],
[4, 8, 0, 4, 2],
[1, 4, 3, 0, 4],
[3, 3, 5, 6, 0]
]
}}}

Multiple cost matrices can optionally be provided depending on the types of vehicles.
Some vehicles can travel faster while others might incur more costs when traveling
through certain areas. This can be modeled using more cost matrices one for each
vehicle type. The next example has two matrices, “0” represents first vehicle, which could
be a car and “1” represents second vehicle, which could be a truck. Note, if your fleet
has vehicles with similar profiles you need to specify the cost matrix only once.

JSON

"data": {" cost_matrix_data ": {


"data": {
"0": [
[0, 5, 4, 3, 5],
[5, 0, 6, 4, 3],
[4, 8, 0, 4, 2],
[1, 4, 3, 0, 4],
[3, 3, 5, 6, 0]
],
"1": [
[0, 4, 2, 3, 3],
[2, 0, 6, 5, 3],
[3, 8, 0, 3, 2],
[1, 5, 3, 0, 4],
[3, 4, 5, 7, 0]
],
}}}
Set Fleet Data
Fleet data could describe the fleet description such as the number of vehicles, their
start/end location, and vehicle capacity that are used by the solver to determine which
vehicles are available to carry out the task within the constraints.

JSON

{
"fleet_data": {
"vehicle_locations": [
[0,1], [0,1]
],
"capacities": [[2,3]],
"vehicle_time_windows": [
[0, 80],
[1, 40]
],
"vehicle_break_time_windows":[
[
[20, 25],
[20, 25]
]
],
"vehicle_break_durations": [[1, 1, 1, 1, 1]]
}
}

Vehicle locations: In the above example, fleet data indicates two vehicles, one
array for each vehicle. Both vehicles start at location 0 and end trip at location 1. In
the context of a cost matrix description of the environment, these vehicle locations
correspond to row (or column) indices in the cost matrix.
Capacities: The capacity array indicates the vehicle capacity; the first vehicle has a
capacity of two and second vehicle has a capacity of three. Capacity could
represent various things, for example package weight, service skills and their
amounts transported by each vehicle. In the next section, you'll create a task json
that will require a demand dimension for each task location and the count of
demand dimension will correspond to the number of capacity dimensions in the
fleet data. ​For example, if a truck is delivering goods, the capacity would be how
much weight in total each vehicle can carry, and the demand would be the weight
of each order. Make sure the same unit is used for both (such as pounds or
kilograms).​
Vehicle time windows: Time windows specify the operating time of the vehicle to
complete the tasks. This could be the agent’s shift start and end time. Raw data
can include Universal Time Stamp (UTC) date/time format or string format that
must be converted to floating value. (Example: 9:00 am - 6:00 pm converted to
minutes in a 24-hour period starting at 12:00 am, would be [540, 1080]). All
time/cost units provided to the cuOpt solver should be in the same unit.
Vehicle breaks: Vehicle break windows and duration can also be specified. This
could represent the agent’s lunch break, or other breaks as needed. The break
window format would be same as the vehicle time window format. All time/cost
units provided to the cuOpt solver should be in the same unit.

Set task data


Tasks define the objective that must be fulfilled within the constraints. In the context of
the last mile delivery this could include the delivery locations, demand quantity at each
location, delivery window and dwell time for each location.

JSON

"task_data": {
"task_locations": [1, 2, 3, 4],
"demand": [[3, 4, 4, 3]],
"task_time_windows": [[8, 17], [8, 17], [8, 17], [17, 20]],
"service_times": [0, 0, 0, 0]
}

Task location: In the above example, task_locations indicate the delivery location
located at positions 1, 2, 3 and 4. These locations correspond to row (or column)
indices in the cost matrix.
Demand: The demand array indicates the demand quantity at each location; the
first location has a demand of 3, second and third location has 4 and the last
location has 3. The count of demand dimensions should correspond to the number
of capacity dimensions for each vehicle.
Task time window: Time window constraints specify when a task should be
completed. Each task is assigned a start and end time window, and the task must
be completed within that. Raw data can include Universal Time Stamp (UTC)
date/time format or string format that must be converted to floating value.
(Example: 9:00 am - 6:00 pm converted to minutes in a 24-hour period starting at
12:00 am, would be [540, 1080]). All time/cost units provided to the cuOpt solver
should be in the same unit.
Service times: This represents the duration required to complete the tasks. The
service_times array specifies the time duration for each task location. All time/cost
units provided to the cuOpt solver should be in the same unit.

Set Solver config (optional)


You can optionally specify solver configuration to allot a maximum time to find a
solution. This depends on the use case, and setting a higher time limit returns better
results.

JSON

"solver_config": {
"time_limit": 1
}

7 Note

You may have additional constraints depending on the problem, such as order
priorities or vehicle cost, see cuOpt supported features. Other features would be
preprocessed similarly to the features covered in the examples.

How to use the cuOpt response


The cuOpt solver returns the optimized stop for each vehicle and the travel itinerary.
Parse the response and convert each location to a coordinate point before calling the
Azure Maps Route Directions API to get the routes. These optimized routes include the
route path and driving directions for each agent.

Sample request data

JSON

{
"requestBody": {
"data": {"cost_matrix_data": {"data": {"1": [[0, 5, 4, 3, 5], [5, 0, 6, 4,
3], [4, 8, 0, 4, 2], [1, 4, 3, 0, 4], [3, 3, 5, 6, 0]]}},
"fleet_data": {
"vehicle_locations": [[0, 0], [0, 0]],
"vehicle_ids": ["Car-A", "Car-B"],
"vehicle_types": [1, 1],
"capacities": [[75, 75]],
"vehicle_time_windows": [[8, 18], [8, 17]],
"vehicle_break_time_windows": [[[12, 14], [12, 14]]],
"vehicle_break_durations": [[0, 0]]
},
"task_data": {
"task_locations": [1, 2, 3, 4],
"demand": [[30, 40, 40, 30]],
"task_time_windows": [[8, 17], [8, 17], [8, 17], [17, 15]],
"service_times": [0, 0, 0, 0]
},
"solver_config": {
"time_limit": 1
}},
"client_version": ""
}
}

Sample response

JSON

"reqId": "4bdc2610-d821-48dc-b53f-57698015bb2e",
"status": "fulfilled",
"percentComplete": 100,
"response": {
"response": {
"solver_response": {
"status": 0,
"num_vehicles": 2,
"solution_cost": 19.0,
"vehicle_data": {
"Car-A": {
"task_id": [
"Depot",
"Break",
"0",
"2",
"Depot"
],
"arrival_stamp": [
8.0,
13.0,
13.0,
17.0,
18.0
],
"route": [
0,
1,
1,
3,
0
],
"type": [
"Depot",
"Break",
"Delivery",
"Delivery",
"Depot"
]
},
"Car-B": {
"task_id": [
"Depot",
"Break",
"1",
"3",
"Depot"
],
"arrival_stamp": [
8.0,
12.0,
12.0,
14.0,
17.0
],
"route": [
0,
2,
2,
4,
0
],
"type": [
"Depot",
"Break",
"Delivery",
"Delivery",
"Depot"
]
}
},
"msg": ""
}
}
}
}

Call Azure Maps Route Directions API for


routing
After the locations in the cuOpt response are mapped to the corresponding coordinates,
the cuOpt service can be used with the Azure Maps Route Directions API and web SDK
to create a web app that displays the assigned itineraries and optimized routes on the
map. You can color code the route path for individual vehicles based on the assigned
stops and display it on the Azure Maps base data.
Next steps
Azure Maps code samples

Azure Maps Route Directions API

Azure Maps Route Matrix API


Render custom data on a raster map
Article • 06/21/2024

This article describes how to use the Get Map Static Image command with image
composition functionality. Image composition functionality supports the retrieval of
static raster tiles that contain custom data and different styles.

The following are examples of custom data:

Custom pushpins
Labels
Geometry overlays

 Tip

To show a simple map on a web page, it's often more cost effective to use the
Azure Maps Web SDK, rather than to use the static image service. The web SDK
uses map tiles; and unless the user pans and zooms the map, they will often
generate only a fraction of a transaction per map load using browser caching. The
Azure Maps Web SDK has options for disabling panning and zooming. Also, the
Azure Maps Web SDK provides a richer set of data visualization options than a
static map web service does.

Prerequisites
Azure Maps account
Subscription key

) Important

In the URL examples, replace {Your-Azure-Maps-Subscription-key} with your Azure


Maps subscription key.

This article uses the Bruno application, but you can use a different API development
environment.

7 Note

The examples in this article require an Azure Maps account in the Gen2 pricing tier.
Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2 pricing
tier replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps account has
Gen1 pricing tier selected, you can switch to Gen2 pricing before it’s retired,
otherwise it will automatically be updated. For more information, see Manage the
pricing tier of your Azure Maps account.

Get static image with custom pins and labels


To get a static image with custom pins and labels:

1. In the Bruno app, select New Request.

2. Set type to HTTP.

3. Enter a Name for the request, such as Get Map Static Image.

4. Select the GET HTTP URL method.

5. Enter the following URL:

HTTP

https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=13&tilesetId=microsoft.base.road&api-
version=2024-04-01&language=en-us&center=-73.964085,
40.78477&path=lcFF0000|lw2|la0.60|ra700||-122.13230609893799
47.64599069048016&pins=custom%7Cla15+50%7Cls12%7Clc003b61%7C%7C%27Centr
al Park%27-
73.9657974+40.781971%7C%7Chttps%3A%2F%2Fsamples.azuremaps.com%2Fimages%
2Ficons%2Fylw-pushpin.png

6. Select Create.

7. Select the Send Request arrow that appears to the right of the request URL.

The following image is returned:


Render a polygon with color and opacity
You can modify the appearance of a polygon by using style modifiers with the path
parameter.

To render a polygon with color and opacity:

1. In the Bruno app, select New Request.

2. Set type to HTTP.

3. Enter a Name for the request, such as GET Polygon.

4. Select the GET HTTP URL method.

5. Enter the following URL to the Render service:

HTTP
https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=15&tilesetId=microsoft.base.road&api-
version=2024-04-01&language=en-
us&path=lc0000FF|fc0000FF|lw3|la0.80|fa0.50||-74.03995513916016
40.70090237454063|-74.04082417488098
40.70028420372218|-74.04113531112671
40.70049568385827|-74.04298067092896
40.69899904076542|-74.04271245002747
40.69879568992435|-74.04367804527283
40.6980961582905|-74.04364585876465
40.698055487620714|-74.04368877410889
40.698022951066996|-74.04168248176573
40.696444909137|-74.03901100158691 40.69837271818651|-74.03824925422668
40.69837271818651|-74.03809905052185
40.69903971085914|-74.03771281242369
40.699340668780984|-74.03940796852112
40.70058515602143|-74.03948307037354
40.70052821920425|-74.03995513916016
40.70090237454063&pins=custom%7Cla15+50%7Cls12%7Clc003b61%7C%7C%27Centr
al Park%27-
73.9657974+40.781971%7C%7Chttps%3A%2F%2Fsamples.azuremaps.com%2Fimages%
2Ficons%2Fylw-pushpin.png&center=-74.040701,
40.698666&height=500&Width=500

The following image is returned:


Render a circle and pushpins with custom
labels
You can modify the appearance of the pins by adding style modifiers. For example, to
make pushpins and their labels larger or smaller, use the sc "scale style" modifier. This
modifier takes a value that's greater than zero. A value of 1 is the standard scale. Values
larger than 1 makes the pins larger, and values smaller than 1 makes them smaller. For
more information about style modifiers, see the Path parameter of the Get Map Static
Image command.

To render a circle and pushpins with custom labels:

1. In the Bruno app, select New Request.

2. Set type to HTTP.

3. Enter a Name for the request, such as GET Polygon.


4. Select the GET HTTP URL method.

5. Enter the following URL to the Render service:

HTTP

https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=14&tilesetId=microsoft.base.road&api-
version=2024-04-01&language=en-
us&center=-122.13230609893799,47.64599069048016&path=lcFF0000|lw2|la0.6
0|ra1000||-122.13230609893799
47.64599069048016&pins=default|la15+50|sc1|al0.66|lc003C62|co002D62||'M
icrosoft Corporate Headquarters'-122.14131832122801
47.64690503939462|'Microsoft Visitor Center'-122.136828
47.642224|'Microsoft Conference Center'-122.12552547454833
47.642940335653996|'Microsoft The Commons'-122.13687658309935
47.64452336193245&height=700&Width=700

6. Select Create.

7. Select the Send Request arrow that appears to the right of the request URL.

The following image is returned:


8. Next, change the color of the pushpins by modifying the co style modifier. If you
look at the value of the pins parameter
( pins=default|la15+50|al0.66|lc003C62|co002D62| ), notice that the current color is
#002D62 . To change the color to #41d42a , replace #002D62 with #41d42a . Now the

pins parameter is pins=default|la15+50|al0.66|lc003C62|co41D42A| . The request

looks like the following URL:

HTTP

https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=14&tilesetId=microsoft.base.road&api-
version=2024-04-01&language=en-
us&center=-122.13230609893799,47.64599069048016&path=lcFF0000|lw2|la0.6
0|ra1000||-122.13230609893799
47.64599069048016&pins=default|la15+50|al0.66|lc003C62|co41D42A||'Micro
soft Corporate Headquarters'-122.14131832122801
47.64690503939462|'Microsoft Visitor Center'-122.136828
47.642224|'Microsoft Conference Center'-122.12552547454833
47.642940335653996|'Microsoft The Commons'-122.13687658309935
47.64452336193245&height=700&Width=700

9. Select Create.

10. Select the Send Request arrow that appears to the right of the request URL.

The following image is returned:

Similarly, you can change, add, and remove other style modifiers.

Add a traffic layer


To get a static image with a traffic layer rendered on a roads basemap, use the
trafficLayer parameter. The following example shows a map with a traffic layer and a

pin with a label:

1. In the Bruno app, select New Request.


2. Set type to HTTP.

3. Enter a Name for the request, such as Get Map Static Image - traffic layer.

4. Select the GET HTTP URL method.

5. Enter the following URL:

HTTP

https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=14&tilesetId=microsoft.base.road&api-
version=2024-04-01&language=en-us&center= -0.122427,
51.500867&pins=custom%7Cla15+50%7Cls12%7Clc003b61%7C%7C%27Westminster
Bridge%27-
0.122427+51.500867%7C%7Chttps%3A%2F%2Fsamples.azuremaps.com%2Fimages%2F
icons%2Fylw-
pushpin.png&height=700&Width=700&trafficLayer=microsoft.traffic.relativ
e.main

6. Select Create.

7. Select the Send Request arrow that appears to the right of the request URL.

The following image is returned:


Create a map using the dark gray style
To get a static image with the dark gray style applied, set the TilesetId parameter to
microsoft.base.darkgrey :

1. In the Bruno app, select New Request.

2. Set type to HTTP.

3. Enter a Name for the request, such as Get Map Static Image - dark gray style.

4. Select the GET HTTP URL method.

5. Enter the following URL:

HTTP

https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=16&tilesetId=microsoft.base.darkgrey&api-
version=2024-04-01&language=en-
us&center=-95.360200,29.753452&pins=custom%7Cla15+50%7Cls12%7Clc003b61%
7C%7C%27Westminster Bridge%27-
0.122427+51.500867%7C%7Chttps%3A%2F%2Fsamples.azuremaps.com%2Fimages%2F
icons%2Fylw-pushpin.png&height=700&Width=700

6. Select Create.

7. Select the Send Request arrow that appears to the right of the request URL.

The following image is returned:

For more information the different styles available using the TilesetId parameter, see
TilesetId in the Render - Get Map Tileset REST API documentation.

Create a map using the imagery style


To get a static image with the imagery style applied, set the TilesetId parameter to
microsoft.imagery :

1. In the Bruno app, select New Request.

2. Set type to HTTP.

3. Enter a Name for the request, such as Get Map Static Image - imagery style.

4. Select the GET HTTP URL method.

5. Enter the following URL:

HTTP

https://atlas.microsoft.com/map/static?subscription-key={Your-Azure-
Maps-Subscription-key}&zoom=16&tilesetId=microsoft.imagery&api-
version=2024-04-01&language=en-
us&center=-43.176141,-22.965458&height=700&Width=700

6. Select Create.

7. Select the Send Request arrow that appears to the right of the request URL.

The following image is returned:


For more information the different styles available using the TilesetId parameter, see
TilesetId in the Render - Get Map Tileset REST API documentation.

Next steps
Render - Get Map Static Image

Feedback
Was this page helpful?  Yes  No

Provide product feedback


Request real-time and forecasted
weather data using Azure Maps
Weather services
Article • 08/09/2024

Azure Maps Weather services are a set of RESTful APIs that allows developers to
integrate highly dynamic historical, real-time, and forecasted weather data and
visualizations into their solutions.

This article demonstrates how to request both real-time and forecasted weather data:

Request real-time (current) weather data using the Get Current Conditions API.
Request severe weather alerts using the Get Severe Weather Alerts API.
Request daily forecasts using the Get Daily Forecast API.
Request hourly forecasts using the Get Hourly Forecast API.
Request minute by minute forecasts using the Get Minute Forecast API.

This video provides examples for making REST calls to Azure Maps Weather services.

https://learn.microsoft.com/Shows/Internet-of-Things-Show/Azure-Maps-Weather-
services-for-developers/player?format=ny

Prerequisites
An Azure Maps account
A subscription key

) Important

In the URL examples in this article you will need to replace {Your-Azure-Maps-
Subscription-key} with your Azure Maps subscription key.

This tutorial uses the bruno application, but you can choose a different API
development environment.

Request real-time weather data


The Get Current Conditions API returns detailed weather conditions such as
precipitation, temperature, and wind for a given coordinate location. Also, observations
from the past 6 or 24 hours for a particular location can be retrieved. The response
includes details like observation date and time, description of weather conditions,
weather icon, precipitation indicator flags, and temperature. RealFeel™ Temperature and
ultraviolet(UV) index are also returned.

In this example, you use the Get Current Conditions API to retrieve current weather
conditions at coordinates located in Seattle, WA.

1. Open the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/weather/currentConditions/json?api-
version=1.0&query=47.60357,-122.32945&subscription-key={Your-Azure-
Maps-Subscription-key}

3. Select the blue Create button.

4. Select the run button.

The response body contains current weather information.

JSON

{
"results": [
{
"dateTime": "2024-08-08T09:22:00-07:00",
"phrase": "Sunny",
"iconCode": 1,
"hasPrecipitation": false,
"isDayTime": true,
"temperature": {
"value": 19.5,
"unit": "C",
"unitType": 17
},
"realFeelTemperature": {
"value": 23.7,
"unit": "C",
"unitType": 17
},
"realFeelTemperatureShade": {
"value": 19.4,
"unit": "C",
"unitType": 17
},
"relativeHumidity": 81,
"dewPoint": {
"value": 16.2,
"unit": "C",
"unitType": 17
},
"wind": {
"direction": {
"degrees": 0,
"localizedDescription": "N"
},
"speed": {
"value": 2,
"unit": "km/h",
"unitType": 7
}
},
"windGust": {
"speed": {
"value": 3.8,
"unit": "km/h",
"unitType": 7
}
},
"uvIndex": 4,
"uvIndexPhrase": "Moderate",
"visibility": {
"value": 16.1,
"unit": "km",
"unitType": 6
},
"obstructionsToVisibility": "",
"cloudCover": 5,
"ceiling": {
"value": 12192,
"unit": "m",
"unitType": 5
},
"pressure": {
"value": 1015.9,
"unit": "mb",
"unitType": 14
},
"pressureTendency": {
"localizedDescription": "Steady",
"code": "S"
},
"past24HourTemperatureDeparture": {
"value": 3,
"unit": "C",
"unitType": 17
},
"apparentTemperature": {
"value": 20,
"unit": "C",
"unitType": 17
},
"windChillTemperature": {
"value": 19.4,
"unit": "C",
"unitType": 17
},
"wetBulbTemperature": {
"value": 17.5,
"unit": "C",
"unitType": 17
},
"precipitationSummary": {
"pastHour": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"past3Hours": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"past6Hours": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"past9Hours": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"past12Hours": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"past18Hours": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"past24Hours": {
"value": 0,
"unit": "mm",
"unitType": 3
}
},
"temperatureSummary": {
"past6Hours": {
"minimum": {
"value": 16,
"unit": "C",
"unitType": 17
},
"maximum": {
"value": 19.5,
"unit": "C",
"unitType": 17
}
},
"past12Hours": {
"minimum": {
"value": 16,
"unit": "C",
"unitType": 17
},
"maximum": {
"value": 20.4,
"unit": "C",
"unitType": 17
}
},
"past24Hours": {
"minimum": {
"value": 16,
"unit": "C",
"unitType": 17
},
"maximum": {
"value": 26.4,
"unit": "C",
"unitType": 17
}
}
}
}
]
}

Request severe weather alerts


Azure Maps Get Severe Weather Alerts API returns the severe weather alerts that are
available worldwide from both official Government Meteorological Agencies and
leading global to regional weather alert providers. The service returns details like alert
type, category, level. The service also returns detailed descriptions about the active
severe alerts for the requested location, such as hurricanes, thunderstorms, lightning,
heat waves, or forest fires. As an example, logistics managers can visualize severe
weather conditions on a map, along with business locations and planned routes, and
coordinate further with drivers and local workers.

In this example, you use the Get Severe Weather Alerts API to retrieve current weather
conditions at coordinates located in Cheyenne, WY.

7 Note

This example retrieves severe weather alerts at the time of this writing. It is likely
that there are no longer any severe weather alerts at the requested location. To
retrieve actual severe alert data when running this example, you'll need to retrieve
data at a different coordinate location.

1. In the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/weather/severe/alerts/json?api-
version=1.0&query=41.161079,-104.805450&subscription-key={Your-Azure-
Maps-Subscription-key}

3. Select the blue Create button.

4. Select the run button.

If there are no severe weather alerts, the response body contains an empty
results[] array. If there are severe weather alerts, the response body contains

something like the following JSON response:

JSON

{
"results": [
{
"countryCode": "US",
"alertId": 2194734,
"description": {
"localized": "Red Flag Warning",
"english": "Red Flag Warning"
},
"category": "FIRE",
"priority": 54,
"source": "U.S. National Weather Service",
"sourceId": 2,
"alertAreas": [
{
"name": "Platte/Goshen/Central and Eastern Laramie",
"summary": "Red Flag Warning in effect until 7:00 PM
MDT. Source: U.S. National Weather Service",
"startTime": "2020-10-05T15:00:00+00:00",
"endTime": "2020-10-06T01:00:00+00:00",
"latestStatus": {
"localized": "Continue",
"english": "Continue"
},
"alertDetails": "...RED FLAG WARNING REMAINS IN EFFECT
FROM 9 AM THIS MORNING TO\n7 PM MDT THIS EVENING FOR STRONG GUSTY WINDS
AND LOW HUMIDITY...\n\n* WHERE...Fire weather zones 303, 304, 305, 306,
307, 308, 309,\n and 310 in southeast Wyoming. Fire weather zone 313
in Nebraska.\n\n* WIND...West to northwest 15 to 30 MPH with gusts
around 40 MPH.\n\n* HUMIDITY...10 to 15 percent.\n\n* IMPACTS...Any
fires that develop will likely spread rapidly.\n Outdoor burning is
not recommended.\n\nPRECAUTIONARY/PREPAREDNESS ACTIONS...\n\nA Red Flag
Warning means that critical fire weather conditions\nare either
occurring now...or will shortly. A combination of\nstrong winds...low
relative humidity...and warm temperatures can\ncontribute to extreme
fire behavior.\n\n&&",
"alertDetailsLanguageCode": "en"
}
]
},...
]
}

Request daily weather forecast data


The Get Daily Forecast API returns detailed daily weather forecast such as temperature
and wind. The request can specify how many days to return: 1, 5, 10, 15, 25, or 45 days
for a given coordinate location. The response includes details such as temperature, wind,
precipitation, air quality, and UV index. In this example, we request for five days by
setting duration=5 .

) Important

In the S0 pricing tier, you can request daily forecast for the next 1, 5, 10, and 15
days. In either Gen1 (S1) or Gen2 pricing tier, you can request daily forecast for the
next 25 days, and 45 days.
Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2 pricing
tier replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps account has
Gen1 pricing tier selected, you can switch to Gen2 pricing before it’s retired,
otherwise it will automatically be updated. For more information, see Manage the
pricing tier of your Azure Maps account.

In this example, you use the Get Daily Forecast API to retrieve the five-day weather
forecast for coordinates located in Seattle, WA.

1. In the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/weather/forecast/daily/json?api-
version=1.0&query=47.60357,-122.32945&duration=5&subscription-key=
{Your-Azure-Maps-Subscription-key}

3. Select the blue Create button.

4. Select the run button.

The response body contains the five-day weather forecast data. For the sake of
brevity, the following JSON response shows the forecast for the first day.

JSON

{
"summary": {
"startDate": "2024-08-09T08:00:00-07:00",
"endDate": "2024-08-09T20:00:00-07:00",
"severity": 7,
"phrase": "Very warm tomorrow",
"category": "heat"
},
"forecasts": [
{
"date": "2024-08-08T07:00:00-07:00",
"temperature": {
"minimum": {
"value": 16.2,
"unit": "C",
"unitType": 17
},
"maximum": {
"value": 28.9,
"unit": "C",
"unitType": 17
}
},
"realFeelTemperature": {
"minimum": {
"value": 16.3,
"unit": "C",
"unitType": 17
},
"maximum": {
"value": 29.8,
"unit": "C",
"unitType": 17
}
},
"realFeelTemperatureShade": {
"minimum": {
"value": 16.3,
"unit": "C",
"unitType": 17
},
"maximum": {
"value": 27.3,
"unit": "C",
"unitType": 17
}
},
"hoursOfSun": 12.9,
"degreeDaySummary": {
"heating": {
"value": 0,
"unit": "C",
"unitType": 17
},
"cooling": {
"value": 5,
"unit": "C",
"unitType": 17
}
},
"airAndPollen": [
{
"name": "AirQuality",
"value": 56,
"category": "Moderate",
"categoryValue": 2,
"type": "Nitrogen Dioxide"
},
{
"name": "Grass",
"value": 2,
"category": "Low",
"categoryValue": 1
},
{
"name": "Mold",
"value": 0,
"category": "Low",
"categoryValue": 1
},
{
"name": "Ragweed",
"value": 5,
"category": "Low",
"categoryValue": 1
},
{
"name": "Tree",
"value": 0,
"category": "Low",
"categoryValue": 1
},
{
"name": "UVIndex",
"value": 7,
"category": "High",
"categoryValue": 3
}
],
"day": {
"iconCode": 2,
"iconPhrase": "Mostly sunny",
"hasPrecipitation": false,
"shortPhrase": "Mostly sunny",
"longPhrase": "Mostly sunny; wildfire smoke will cause the sky
to be hazy",
"precipitationProbability": 0,
"thunderstormProbability": 0,
"rainProbability": 0,
"snowProbability": 0,
"iceProbability": 0,
"wind": {
"direction": {
"degrees": 357,
"localizedDescription": "N"
},
"speed": {
"value": 11.1,
"unit": "km/h",
"unitType": 7
}
},
"windGust": {
"direction": {
"degrees": 354,
"localizedDescription": "N"
},
"speed": {
"value": 29.6,
"unit": "km/h",
"unitType": 7
}
},
"totalLiquid": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"rain": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"snow": {
"value": 0,
"unit": "cm",
"unitType": 4
},
"ice": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"hoursOfPrecipitation": 0,
"hoursOfRain": 0,
"hoursOfSnow": 0,
"hoursOfIce": 0,
"cloudCover": 10
},
"night": {
"iconCode": 35,
"iconPhrase": "Partly cloudy",
"hasPrecipitation": false,
"shortPhrase": "Partly cloudy",
"longPhrase": "Partly cloudy; wildfire smoke will cause the sky
to be hazy",
"precipitationProbability": 1,
"thunderstormProbability": 0,
"rainProbability": 1,
"snowProbability": 0,
"iceProbability": 0,
"wind": {
"direction": {
"degrees": 7,
"localizedDescription": "N"
},
"speed": {
"value": 9.3,
"unit": "km/h",
"unitType": 7
}
},
"windGust": {
"direction": {
"degrees": 3,
"localizedDescription": "N"
},
"speed": {
"value": 20.4,
"unit": "km/h",
"unitType": 7
}
},
"totalLiquid": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"rain": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"snow": {
"value": 0,
"unit": "cm",
"unitType": 4
},
"ice": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"hoursOfPrecipitation": 0,
"hoursOfRain": 0,
"hoursOfSnow": 0,
"hoursOfIce": 0,
"cloudCover": 26
},
"sources": [
"AccuWeather"
]
}
]
}

Request hourly weather forecast data


The Get Hourly Forecast API returns detailed weather forecast by the hour for the next 1,
12, 24 (1 day), 72 (3 days), 120 (5 days), and 240 hours (10 days) for the given coordinate
location. The API returns details such as temperature, humidity, wind, precipitation, and
UV index.

) Important

In the Gen1 (S0) pricing tier, you can request hourly forecast for the next 1, 12, 24
hours (1 day), and 72 hours (3 days). In either Gen1 (S1) or Gen2 pricing tier, you
can request hourly forecast for the next 120 (5 days) and 240 hours (10 days).

In this example, you use the Get Hourly Forecast API to retrieve the hourly weather
forecast for the next 12 hours at coordinates located in Seattle, WA.

1. In the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/weather/forecast/hourly/json?api-
version=1.0&query=47.60357,-122.32945&duration=12&subscription-key=
{Your-Azure-Maps-Subscription-key}

3. Select the blue Create button.

4. Select the run button.

The response body contains weather forecast data for the next 12 hours. The
following example JSON response only shows the first hour:

JSON

{
"forecasts": [
{
"date": "2024-08-07T15:00:00-07:00",
"iconCode": 2,
"iconPhrase": "Mostly sunny",
"hasPrecipitation": false,
"isDaylight": true,
"temperature": {
"value": 24.6,
"unit": "C",
"unitType": 17
},
"realFeelTemperature": {
"value": 26.4,
"unit": "C",
"unitType": 17
},
"wetBulbTemperature": {
"value": 18.1,
"unit": "C",
"unitType": 17
},
"dewPoint": {
"value": 14.5,
"unit": "C",
"unitType": 17
},
"wind": {
"direction": {
"degrees": 340,
"localizedDescription": "NNW"
},
"speed": {
"value": 14.8,
"unit": "km/h",
"unitType": 7
}
},
"windGust": {
"speed": {
"value": 24.1,
"unit": "km/h",
"unitType": 7
}
},
"relativeHumidity": 53,
"visibility": {
"value": 16.1,
"unit": "km",
"unitType": 6
},
"cloudCover": 11,
"ceiling": {
"value": 10211,
"unit": "m",
"unitType": 5
},
"uvIndex": 5,
"uvIndexPhrase": "Moderate",
"precipitationProbability": 0,
"rainProbability": 0,
"snowProbability": 0,
"iceProbability": 0,
"totalLiquid": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"rain": {
"value": 0,
"unit": "mm",
"unitType": 3
},
"snow": {
"value": 0,
"unit": "cm",
"unitType": 4
},
"ice": {
"value": 0,
"unit": "mm",
"unitType": 3
}
}
]
}

Request minute-by-minute weather forecast


data
The Get Minute Forecast API returns minute-by-minute forecasts for a given location for
the next 120 minutes. Users can request weather forecasts in intervals of 1, 5 and 15
minutes. The response includes details such as the type of precipitation (including rain,
snow, or a mixture of both), start time, and precipitation intensity value (dBZ).

In this example, you use the Get Minute Forecast API to retrieve the minute-by-minute
weather forecast at coordinates located in Seattle, WA. The weather forecast is given for
the next 120 minutes. Our query requests that the forecast is given at 15-minute
intervals, but you can adjust the parameter to be either 1 or 5 minutes.

1. In the bruno app, select NEW REQUEST to create the request. In the NEW
REQUEST window, set Type to HTTP. Enter a Name for the request.

2. Select the GET HTTP method in the URL drop-down list, then enter the following
URL:

HTTP

https://atlas.microsoft.com/weather/forecast/minute/json?api-
version=1.0&query=47.60357,-122.32945&interval=15&subscription-key=
{Your-Azure-Maps-Subscription-key}
3. Select the blue Create button.

4. Select the run button.

The response body contains weather forecast data for the next 120 minutes, in 15-
minute intervals.

JSON

{
"summary": {
"briefPhrase60": "No precipitation for at least 60 min",
"shortPhrase": "No precip for 120 min",
"briefPhrase": "No precipitation for at least 120 min",
"longPhrase": "No precipitation for at least 120 min",
"iconCode": 1
},
"intervalSummaries": [
{
"startMinute": 0,
"endMinute": 119,
"totalMinutes": 120,
"shortPhrase": "No precip for %MINUTE_VALUE min",
"briefPhrase": "No precipitation for at least %MINUTE_VALUE min",
"longPhrase": "No precipitation for at least %MINUTE_VALUE min",
"iconCode": 1
}
],
"intervals": [
{
"startTime": "2024-08-08T05:58:00-07:00",
"minute": 0,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 7
},
{
"startTime": "2024-08-08T06:13:00-07:00",
"minute": 15,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 3
},
{
"startTime": "2024-08-08T06:28:00-07:00",
"minute": 30,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 2
},
{
"startTime": "2024-08-08T06:43:00-07:00",
"minute": 45,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 2
},
{
"startTime": "2024-08-08T06:58:00-07:00",
"minute": 60,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 1
},
{
"startTime": "2024-08-08T07:13:00-07:00",
"minute": 75,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 1
},
{
"startTime": "2024-08-08T07:28:00-07:00",
"minute": 90,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 0
},
{
"startTime": "2024-08-08T07:43:00-07:00",
"minute": 105,
"dbz": 0,
"shortPhrase": "No Precipitation",
"iconCode": 1,
"cloudCover": 0
}
]
}

Next steps
Weather service concepts

Weather services
Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


REST SDK Developer Guide
Article • 11/19/2024

You can call the Azure Maps Rest API directly from any programming language, however
that can be error prone work requiring extra effort. To make incorporating Azure Maps
in your applications easier and less error prone, the Azure Maps team has encapsulated
their REST API in SDKs for C# (.NET), Python, JavaScript/TypeScript, and Java.

This article lists the libraries currently available for each SDK with links to how-to articles
to help you get started.

C# SDK
Azure Maps C# SDK supports any .NET version that is compatible with .NET standard
2.0 .

ノ Expand table

Service name NuGet package Samples

Search Azure.Maps.Search search samples

Routing Azure.Maps.Routing routing samples

Rendering Azure.Maps.Rendering rendering sample

Geolocation Azure.Maps.Geolocation geolocation sample

For more information, see the C# SDK Developers Guide.

Python SDK
Azure Maps Python SDK supports Python version 3.7 or later. Check the Azure SDK for
Python policy planning for more details on future Python versions.

ノ Expand table

Service name PyPi package Samples

Search azure-maps-search search samples

Route azure-maps-route route samples


Service name PyPi package Samples

Render azure-maps-render render sample

Geolocation azure-maps-geolocation geolocation sample

For more information, see the python SDK Developers Guide.

JavaScript/TypeScript
Azure Maps JavaScript/TypeScript SDK supports LTS versions of Node.js including
versions in Active status and Maintenance status.

ノ Expand table

Service name npm packages Samples

Search @azure-rest/maps-search search samples

Route @azure-rest/maps-route route samples

Render @azure-rest/maps-render render sample

Geolocation @azure-rest/maps-geolocation geolocation sample

For more information, see the JavaScript/TypeScript SDK Developers Guide.

Java
Azure Maps Java SDK supports Java 8 or above.

ノ Expand table

Service name Maven package Samples

Search azure-maps-search search samples

Routing azure-maps-routing routing samples

Rendering azure-maps-rendering rendering sample

Geolocation azure-maps-geolocation geolocation sample

Timezone azure-maps-timezone timezone samples

For more information, see the Java SDK Developers Guide.


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


C# REST SDK Developers Guide
Article • 08/27/2024

The Azure Maps C# SDK supports functionality available in the Azure Maps Rest API, like
searching for an address, routing between different coordinates, and getting the geo-
location of a specific IP address. This article introduces the C# REST SDK with examples
to help you get started building location-aware applications in C# that incorporates the
power of Azure Maps.

7 Note

Azure Maps C# SDK supports any .NET version that is compatible with .NET
standard version 2.0 or higher. For an interactive table, see .NET Standard
versions .

Prerequisites
Azure Maps account.
Subscription key or other form of Authentication with Azure Maps.
.NET standard version 2.0 or higher.

 Tip

You can create an Azure Maps account programmatically, Here's an example using
the Azure CLI:

Azure CLI

az maps account create --kind "Gen2" --account-name "myMapAccountName"


--resource-group "<resource group>" --sku "G2"

Create a .NET project


The following PowerShell code snippet demonstrates how to use PowerShell to create a
console program MapsDemo with .NET 7.0. You can use any .NET standard 2.0-compatible
version as the framework.

PowerShell
dotnet new console -lang C# -n MapsDemo -f net7.0
cd MapsDemo

Install required packages


To use Azure Maps C# SDK, we need to install the required packages. Each of the Azure
Maps services including search, routing, rendering and geolocation are each in their
own package. Since the Azure Maps C# SDK is in public preview, you need to add the --
prerelease flag:

PowerShell

dotnet add package Azure.Maps.Rendering --prerelease


dotnet add package Azure.Maps.Routing --prerelease
dotnet add package Azure.Maps.Search --prerelease
dotnet add package Azure.Maps.Geolocation --prerelease

Azure Maps services

ノ Expand table

Service name NuGet package Samples

Search Azure.Maps.Search search samples

Routing Azure.Maps.Routing routing samples

Rendering Azure.Maps.Rendering rendering sample

Geolocation Azure.Maps.Geolocation geolocation sample

Create and authenticate a MapsSearchClient


The client object used to access the Azure Maps Search APIs require either an
AzureKeyCredential object to authenticate when using an Azure Maps subscription key

or a TokenCredential object with the Azure Maps client ID when authenticating using
Microsoft Entra ID. For more information on authentication, see Authentication with
Azure Maps.

Using a Microsoft Entra credential


You can authenticate with Microsoft Entra ID using the Azure Identity library. To use the
DefaultAzureCredential provider, you need to install the Azure Identity client library for
.NET:

PowerShell

dotnet add package Azure.Identity

You need to register the new Microsoft Entra application and grant access to Azure
Maps by assigning the required role to your service principal. For more information, see
Host a daemon on non-Azure resources. The Application (client) ID, a Directory (tenant)
ID, and a client secret are returned. Copy these values and store them in a secure place.
You need them in the following steps.

Set the values of the Application (client) ID, Directory (tenant) ID, and client secret of
your Microsoft Entra application, and the map resource’s client ID as environment
variables:

ノ Expand table

Environment Variable Description

AZURE_CLIENT_ID Application (client) ID in your registered application

AZURE_CLIENT_SECRET The value of the client secret in your registered application

AZURE_TENANT_ID Directory (tenant) ID in your registered application

MAPS_CLIENT_ID The client ID in your Azure Map resource

Now you can create environment variables in PowerShell to store these values:

PowerShell

$Env:AZURE_CLIENT_ID="Application (client) ID"


$Env:AZURE_CLIENT_SECRET="your client secret"
$Env:AZURE_TENANT_ID="your Directory (tenant) ID"
$Env:MAPS_CLIENT_ID="your Azure Maps client ID"

After setting up the environment variables, you can use them in your program to
instantiate the AzureMapsSearch client:

C#

using System;
using Azure.Identity;
using Azure.Maps.Search;

var credential = new DefaultAzureCredential();


var clientId = Environment.GetEnvironmentVariable("MAPS_CLIENT_ID");
var client = new MapsSearchClient(credential, clientId);

) Important

The other environment variables created in the previous code snippet, while not
used in the code sample, are required by DefaultAzureCredential() . If you do not
set these environment variables correctly, using the same naming conventions, you
will get run-time errors. For example, if your AZURE_CLIENT_ID is missing or invalid
you will get an InvalidAuthenticationTokenTenant error.

Using a subscription key credential


You can authenticate with your Azure Maps subscription key. Your subscription key can
be found in the Authentication section in the Azure Maps account as shown in the
following screenshot:


Now you can create environment variables in PowerShell to store the subscription key:

PowerShell

$Env:SUBSCRIPTION_KEY="your subscription key"

Once your environment variable is created, you can access it in your code:

C#

using System;
using Azure;
using Azure.Maps.Search;

// Use Azure Maps subscription key authentication


var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY")
?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential);

Geocode an address
Call the GetGeocoding method to get the coordinate of an address.

C#

using System;
using Azure;
using Azure.Maps.Search;
using Azure.Maps.Search.Models;

// Use Azure Maps subscription key authentication


var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY")
?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential);

Response<GeocodingResponse> searchResult = client.GetGeocoding(


"1 Microsoft Way, Redmond, WA 98052");

for (int i = 0; i < searchResult.Value.Features.Count; i++)


{
Console.WriteLine("Coordinate:" + string.Join(",",
searchResult.Value.Features[i].Geometry.Coordinates));
}

Batch geocode addresses


This sample demonstrates how to perform batch search address.

C#

using System;
using Azure;
using Azure.Maps.Search;
using System.Collections.Generic;
using Azure.Maps.Search.Models;
using Azure.Maps.Search.Models.Queries;

// Use Azure Maps subscription key authentication


var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY")
?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential);

List<GeocodingQuery> queries = new List<GeocodingQuery>


{
new GeocodingQuery()
{
Query ="15171 NE 24th St, Redmond, WA 98052, United States"
},
new GeocodingQuery()
{
AddressLine = "400 Broad St"
},
};
Response<GeocodingBatchResponse> results =
client.GetGeocodingBatch(queries);

//Print coordinates
for (var i = 0; i < results.Value.BatchItems.Count; i++)
{
for (var j = 0; j < results.Value.BatchItems[i].Features.Count; j++)
{
Console.WriteLine("Coordinates: " + string.Join(",",
results.Value.BatchItems[i].Features[j].Geometry.Coordinates));
}
}

Reverse geocode a coordinates


You can translate coordinates into human-readable street addresses. This process is also
called reverse geocoding.

C#

using System;
using Azure;
using Azure.Maps.Search;
using Azure.Core.GeoJson;
using Azure.Maps.Search.Models;

// Use Azure Maps subscription key authentication


var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY")
?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential);

GeoPosition coordinates = new GeoPosition(-122.138685, 47.6305637);


Response<GeocodingResponse> result =
client.GetReverseGeocoding(coordinates);

//Print addresses
for (int i = 0; i < result.Value.Features.Count; i++)
{

Console.WriteLine(result.Value.Features[i].Properties.Address.FormattedAddre
ss);
}

Batch reverse geocode a set of coordinates


Azure Maps Search also provides some batch query APIs. The Reverse Geocoding Batch
API sends batches of queries to Reverse Geocoding API using just a single API call. The
API allows caller to batch up to 100 queries.

C#

using System;
using Azure;
using Azure.Maps.Search;
using System.Collections.Generic;
using Azure.Core.GeoJson;
using Azure.Maps.Search.Models;
using Azure.Maps.Search.Models.Queries;

// Use Azure Maps subscription key authentication


var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY")
?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential);

List<ReverseGeocodingQuery> items = new List<ReverseGeocodingQuery>


{
new ReverseGeocodingQuery()
{
Coordinates = new GeoPosition(-122.349309, 47.620498)
},
new ReverseGeocodingQuery()
{
Coordinates = new GeoPosition(-122.138679, 47.630356),
ResultTypes = new List<ReverseGeocodingResultTypeEnum>(){
ReverseGeocodingResultTypeEnum.Address,
ReverseGeocodingResultTypeEnum.Neighborhood }
},
};
Response<GeocodingBatchResponse> result =
client.GetReverseGeocodingBatch(items);
//Print addresses
for (var i = 0; i < result.Value.BatchItems.Count; i++)
{

Console.WriteLine(result.Value.BatchItems[i].Features[0].Properties.Address.
AddressLine);

Console.WriteLine(result.Value.BatchItems[i].Features[0].Properties.Address.
Neighborhood);
}

Get polygons for a given location


This sample demonstrates how to search polygons.

C#

using System;
using Azure;
using Azure.Maps.Search;
using Azure.Core.GeoJson;
using Azure.Maps.Search.Models;
using Azure.Maps.Search.Models.Options;

// Use Azure Maps subscription key authentication


var subscriptionKey = Environment.GetEnvironmentVariable("SUBSCRIPTION_KEY")
?? string.Empty;
var credential = new AzureKeyCredential(subscriptionKey);
var client = new MapsSearchClient(credential);

GetPolygonOptions options = new GetPolygonOptions()


{
Coordinates = new GeoPosition(-122.204141, 47.61256),
ResultType = BoundaryResultTypeEnum.Locality,
Resolution = ResolutionEnum.Small,
};
Response<Boundary> result = client.GetPolygon(options);

var count = ((GeoJsonPolygon)


((GeoJsonGeometryCollection)result.Value.Geometry).Geometries[0]).Coordinate
s.Count;
for (var i = 0; i < count; i++)
{
var coorCount = ((GeoJsonPolygon)
((GeoJsonGeometryCollection)result.Value.Geometry).Geometries[0]).Coordinate
s[i].Count;
for (var j = 0; j < coorCount; j++)
{
Console.WriteLine(string.Join(",",((GeoJsonPolygon)
((GeoJsonGeometryCollection)result.Value.Geometry).Geometries[0]).Coordinate
s[i][j]));
}
}

Using V1 SDKs for Search and Render


For more information on using Search v1, see Azure Maps Search client library for
.NET . For more information on using Render v1, see Azure Maps Render client library
for .NET .

Additional information
The Azure.Maps Namespace in the .NET documentation.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Python REST SDK Developers Guide
(preview)
Article • 08/16/2024

The Azure Maps Python SDK can be integrated with Python applications and libraries to
build map-related and location-aware applications. The Azure Maps Python SDK
contains APIs for Search, Route, Render and Geolocation. These APIs support operations
such as searching for an address, routing between different coordinates, obtaining the
geo-location of a specific IP address.

Prerequisites
Azure Maps account.
Subscription key or other form of Authentication with Azure Maps.
Python on 3.8 or later. It's recommended to use the latest release . For more
information, see Azure SDK for Python version support policy .

 Tip

You can create an Azure Maps account programmatically, Here's an example using
the Azure CLI:

Azure CLI

az maps account create --kind "Gen2" --account-name "myMapAccountName"


--resource-group "<resource group>" --sku "G2"

Create a python project


The following example shows how to create a console program named demo with
Python:

PowerShell

mkdir mapsDemo
cd mapsDemo
New-Item demo.py
Install needed python packages
Each service in Azure Maps is contained in its own package. When using the Azure Maps
Python SDK, you can install just the packages of the services you need.

Here we install the Azure Maps Search package. Since it’s still in public preview, you
need to add the --pre flag:

PowerShell

pip install azure-maps-search --pre

Azure Maps services


Azure Maps Python SDK supports Python version 3.8 or later. For more information on
future Python versions, see Azure SDK for Python version support policy .

ノ Expand table

Service name PyPi package Samples

Search azure-maps-search search samples

Route azure-maps-route route samples

Render azure-maps-render render sample

Geolocation azure-maps-geolocation geolocation sample

Create and authenticate a MapsSearchClient


You need a credential object for authentication when creating the MapsSearchClient
object used to access the Azure Maps search APIs. You can use either a Microsoft Entra
credential or an Azure subscription key to authenticate. For more information on
authentication, see Authentication with Azure Maps.

 Tip

The MapsSearchClient is the primary interface for developers using the Azure Maps
search library. See Azure Maps Search package client library to learn more about
the search methods available.
Using a Microsoft Entra credential
You can authenticate with Microsoft Entra ID using the Azure Identity package . To use
the DefaultAzureCredential provider, you need to install the Azure Identity client
package:

PowerShell

pip install azure-identity

You need to register the new Microsoft Entra application and grant access to Azure
Maps by assigning the required role to your service principal. For more information, see
Host a daemon on non-Azure resources. The Application (client) ID, a Directory (tenant)
ID, and a client secret are returned. Copy these values and store them in a secure place.
You need them in the following steps.

Next you need to specify the Azure Maps account you intend to use by specifying
the maps’ client ID. The Azure Maps account client ID can be found in the Authentication
sections of the Azure Maps account. For more information, see View authentication
details.

Set the values of the Application (client) ID, Directory (tenant) ID, and client secret of
your Microsoft Entra application, and the map resource’s client ID as environment
variables:

ノ Expand table

Environment Variable Description

AZURE_CLIENT_ID Application (client) ID in your registered application

AZURE_CLIENT_SECRET The value of the client secret in your registered application

AZURE_TENANT_ID Directory (tenant) ID in your registered application

MAPS_CLIENT_ID The client ID in your Azure Map account

Now you can create environment variables in PowerShell to store these values:

PowerShell

$Env:AZURE_CLIENT_ID="Application (client) ID"


$Env:AZURE_CLIENT_SECRET="your client secret"
$Env:AZURE_TENANT_ID="your Directory (tenant) ID"
$Env:MAPS_CLIENT_ID="your Azure Maps client ID"
After setting up the environment variables, you can use them in your program to
instantiate the AzureMapsSearch client. Create a file named demo.py and add the
following code:

Python

import os
from azure.identity import DefaultAzureCredential
from azure.maps.search import MapsSearchClient

credential = DefaultAzureCredential()
maps_client_id = os.getenv("MAPS_CLIENT_ID")
maps_search_client = MapsSearchClient(
client_id=maps_client_id,
credential=credential
)

) Important

The other environment variables created in the previous code snippet, while not
used in the code sample, are required by DefaultAzureCredential() . If you do not
set these environment variables correctly, using the same naming conventions, you
will get run-time errors. For example, if your AZURE_CLIENT_ID is missing or invalid
you will get an InvalidAuthenticationTokenTenant error.

Using a subscription key credential


You can authenticate with your Azure Maps subscription key. Your subscription key can
be found in the Authentication section in the Azure Maps account as shown in the
following screenshot:

Now you can create environment variables in PowerShell to store the subscription key:

PowerShell

$Env:SUBSCRIPTION_KEY="your subscription key"

Once your environment variable is created, you can access it in your code. Create a file
named demo.py and add the following code:

Python

import os

from azure.core.credentials import AzureKeyCredential


from azure.maps.search import MapsSearchClient

# Use Azure Maps subscription key authentication


subscription_key = os.getenv("SUBSCRIPTION_KEY")
maps_search_client = MapsSearchClient(
credential=AzureKeyCredential(subscription_key)
)

Geocode an address
The following code snippet demonstrates how, in a simple console application, to obtain
longitude and latitude coordinates for a given address. This example uses subscription
key credentials to authenticate MapsSearchClient. In demo.py :

Python

import os

from azure.core.exceptions import HttpResponseError

subscription_key = os.getenv("AZURE_SUBSCRIPTION_KEY", "your subscription


key")

def geocode():
from azure.core.credentials import AzureKeyCredential
from azure.maps.search import MapsSearchClient

maps_search_client =
MapsSearchClient(credential=AzureKeyCredential(subscription_key))
try:
result = maps_search_client.get_geocoding(query="15127 NE 24th
Street, Redmond, WA 98052")
if result.get('features', False):
coordinates = result['features'][0]['geometry']['coordinates']
longitude = coordinates[0]
latitude = coordinates[1]

print(longitude, latitude)
else:
print("No results")

except HttpResponseError as exception:


if exception.error is not None:
print(f"Error Code: {exception.error.code}")
print(f"Message: {exception.error.message}")

if __name__ == '__main__':
geocode()

This sample code instantiates AzureKeyCredential with the Azure Maps subscription key,
then uses it to instantiate the MapsSearchClient object. The methods provided by
MapsSearchClient forward the request to the Azure Maps REST endpoints. In the end,

the program iterates through the results and prints the coordinates for each result.

Batch geocode addresses


This sample demonstrates how to perform batch search address:

Python
import os

from azure.core.exceptions import HttpResponseError

subscription_key = os.getenv("AZURE_SUBSCRIPTION_KEY", "your subscription


key")

def geocode_batch():
from azure.core.credentials import AzureKeyCredential
from azure.maps.search import MapsSearchClient

maps_search_client =
MapsSearchClient(credential=AzureKeyCredential(subscription_key))
try:
result = maps_search_client.get_geocoding_batch({
"batchItems": [
{"query": "400 Broad St, Seattle, WA 98109"},
{"query": "15127 NE 24th Street, Redmond, WA 98052"},
],
},)

if not result.get('batchItems', False):


print("No batchItems in geocoding")
return

for item in result['batchItems']:


if not item.get('features', False):
print(f"No features in item: {item}")
continue

coordinates = item['features'][0]['geometry']['coordinates']
longitude, latitude = coordinates
print(longitude, latitude)

except HttpResponseError as exception:


if exception.error is not None:
print(f"Error Code: {exception.error.code}")
print(f"Message: {exception.error.message}")

if __name__ == '__main__':
geocode_batch()

Make a Reverse Address Search to translate


coordinate location to street address
You can translate coordinates into human-readable street addresses. This process is also
called reverse geocoding. This is often used for applications that consume GPS feeds
and want to discover addresses at specific coordinate points.
Python

import os

from azure.core.exceptions import HttpResponseError

subscription_key = os.getenv("AZURE_SUBSCRIPTION_KEY", "your subscription


key")

def reverse_geocode():
from azure.core.credentials import AzureKeyCredential
from azure.maps.search import MapsSearchClient

maps_search_client =
MapsSearchClient(credential=AzureKeyCredential(subscription_key))
try:
result = maps_search_client.get_reverse_geocoding(coordinates=
[-122.138679, 47.630356])
if result.get('features', False):
props = result['features'][0].get('properties', {})
if props and props.get('address', False):
print(props['address'].get('formattedAddress', 'No formatted
address found'))
else:
print("Address is None")
else:
print("No features available")
except HttpResponseError as exception:
if exception.error is not None:
print(f"Error Code: {exception.error.code}")
print(f"Message: {exception.error.message}")

if __name__ == '__main__':
reverse_geocode()

Batch request for reverse geocoding


This sample demonstrates how to perform reverse search by given coordinates in batch.

Python

import os
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.maps.search import MapsSearchClient

subscription_key = os.getenv("AZURE_SUBSCRIPTION_KEY", "your subscription


key")

def reverse_geocode_batch():
maps_search_client =
MapsSearchClient(credential=AzureKeyCredential(subscription_key))
try:
result = maps_search_client.get_reverse_geocoding_batch({
"batchItems": [
{"coordinates": [-122.349309, 47.620498]},
{"coordinates": [-122.138679, 47.630356]},
],
},)

if result.get('batchItems', False):
for idx, item in enumerate(result['batchItems']):
features = item['features']
if features:
props = features[0].get('properties', {})
if props and props.get('address', False):
print(
props['address'].get('formattedAddress', f'No
formatted address for item {idx + 1} found'))
else:
print(f"Address {idx + 1} is None")
else:
print(f"No features available for item {idx + 1}")
else:
print("No batch items found")
except HttpResponseError as exception:
if exception.error is not None:
print(f"Error Code: {exception.error.code}")
print(f"Message: {exception.error.message}")

if __name__ == '__main__':
reverse_geocode_batch()

Get polygons for a given location


This sample demonstrates how to search polygons.

Python

import os

from azure.core.exceptions import HttpResponseError


from azure.maps.search import Resolution
from azure.maps.search import BoundaryResultType

subscription_key = os.getenv("AZURE_SUBSCRIPTION_KEY", "your subscription


key")

def get_polygon():
from azure.core.credentials import AzureKeyCredential
from azure.maps.search import MapsSearchClient

maps_search_client =
MapsSearchClient(credential=AzureKeyCredential(subscription_key))
try:
result = maps_search_client.get_polygon(
coordinates=[-122.204141, 47.61256],
result_type=BoundaryResultType.LOCALITY,
resolution=Resolution.SMALL,
)

if not result.get('geometry', False):


print("No geometry found")
return

print(result["geometry"])
except HttpResponseError as exception:
if exception.error is not None:
print(f"Error Code: {exception.error.code}")
print(f"Message: {exception.error.message}")

if __name__ == '__main__':
get_polygon()

Using V1 SDKs for Search and Render


To use Search V1 and Render V1 SDK, please refer to Search V1 SDK package page
and Render V1 SDK package for more information.

Additional information
The Azure Maps Search package client library in the Azure SDK for Python Preview
documentation.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


JavaScript/TypeScript REST SDK
Developers Guide (preview)
Article • 01/26/2024

The Azure Maps JavaScript/TypeScript REST SDK (JavaScript SDK) supports searching
using the Azure Maps Search service, like searching for an address, searching for
boundary of a city or country, and searching by coordinates. This article helps you get
started building location-aware applications that incorporate the power of Azure Maps.

7 Note

Azure Maps JavaScript SDK supports the LTS version of Node.js. For more
information, see Node.js Release Working Group .

Prerequisites
Azure Maps account.
Subscription key or other form of Authentication with Azure Maps.
Node.js .

 Tip

You can create an Azure Maps account programmatically, Here's an example using
the Azure CLI:

Azure CLI

az maps account create --kind "Gen2" --account-name "myMapAccountName"


--resource-group "<resource group>" --sku "G2"

Create a Node.js project


The following example creates a new directory then a Node.js program named
mapsDemo using npm:

PowerShell
mkdir mapsDemo
cd mapsDemo
npm init

Install the search package


To use Azure Maps JavaScript SDK, you need to install the search package. Each of the
Azure Maps services including search, routing, rendering and geolocation are each in
their own package.

PowerShell

npm install @azure-rest/maps-search

Once the package is installed, create a search.js file in the mapsDemo directory:

text

mapsDemo
+-- package.json
+-- package-lock.json
+-- node_modules/
+-- search.js

Azure Maps services

ノ Expand table

Service name npm packages Samples

Search @azure-rest/maps-search search samples

Route @azure-rest/maps-route route samples

Render @azure-rest/maps-render render sample

Geolocation @azure-rest/maps-geolocation geolocation sample

Create and authenticate a MapsSearchClient


You need a credential object for authentication when creating the MapsSearchClient
object used to access the Azure Maps search APIs. You can use either a Microsoft Entra
credential or an Azure subscription key to authenticate. For more information on
authentication, see Authentication with Azure Maps.

 Tip

The MapsSearchClient is the primary interface for developers using the Azure Maps
search library. See Azure Maps Search client library to learn more about the search
methods available.

Using a Microsoft Entra credential


You can authenticate with Microsoft Entra ID using the Azure Identity library. To use the
DefaultAzureCredential provider, you need to install the @azure/identity package:

PowerShell

npm install @azure/identity

You need to register the new Microsoft Entra application and grant access to Azure
Maps by assigning the required role to your service principal. For more information, see
Host a daemon on non-Azure resources. The Application (client) ID, a Directory (tenant)
ID, and a client secret are returned. Copy these values and store them in a secure place.
You need them in the following steps.

Set the values of the Application (client) ID, Directory (tenant) ID, and client secret of
your Microsoft Entra application, and the map resource’s client ID as environment
variables:

ノ Expand table

Environment Variable Description

AZURE_CLIENT_ID Application (client) ID in your registered application

AZURE_CLIENT_SECRET The value of the client secret in your registered application

AZURE_TENANT_ID Directory (tenant) ID in your registered application

MAPS_CLIENT_ID The client ID in your Azure Map account

You can use a .env file for these variables. You need to install the dotenv package:

PowerShell
npm install dotenv

Next, add a .env file in the mapsDemo directory and specify these properties:

text

AZURE_CLIENT_ID="<client-id>"
AZURE_CLIENT_SECRET="<client-secret>"
AZURE_TENANT_ID="<tenant-id>"
MAPS_CLIENT_ID="<maps-client-id>"

Once your environment variables are created, you can access them in your JavaScript
code:

JavaScript

const MapsSearch = require("@azure-rest/maps-search").default;


const { DefaultAzureCredential } = require("@azure/identity");
require("dotenv").config();

const credential = new DefaultAzureCredential();


const client = MapsSearch(credential, process.env.MAPS_CLIENT_ID);

Using a subscription key credential


You can authenticate with your Azure Maps subscription key. Your subscription key can
be found in the Authentication section in the Azure Maps account as shown in the
following screenshot:

You need to pass the subscription key to the AzureKeyCredential class provided by the
Azure Core Authentication Package. For security reasons, it's better to specify the key as
an environment variable than to include it in your source code.

Use a .env file to store the subscription key variable to accomplish this. You need to
install the dotenv package to retrieve the value:

PowerShell

npm install dotenv

Next, add a .env file in the mapsDemo directory and specify the property:

text

MAPS_SUBSCRIPTION_KEY="<subscription-key>"

Once your environment variable is created, you can access it in your JavaScript code:

JavaScript

const MapsSearch = require("@azure-rest/maps-search").default;


const { AzureKeyCredential } = require("@azure/core-auth");
require("dotenv").config();

const credential = new


AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY);
const client = MapsSearch(credential);

Using a Shared Access Signature (SAS) Token Credential


Shared access signature (SAS) tokens are authentication tokens created using the JSON
Web token (JWT) format and are cryptographically signed to prove authentication for an
application to the Azure Maps REST API.

You can get the SAS token using AzureMapsManagementClient.accounts.listSas


package. Follow the section Create and authenticate a AzureMapsManagementClient
to setup first.

Second, follow Managed identities for Azure Maps to create a managed identity for
your Azure Maps account. Copy the principal ID (object ID) of the managed identity.

Next, install Azure Core Authentication Package package to use AzureSASCredential :

Bash

npm install @azure/core-auth

Finally, you can use the SAS token to authenticate the client:

JavaScript

const MapsSearch = require("@azure-rest/maps-search").default;


const { AzureSASCredential } = require("@azure/core-auth");
const { DefaultAzureCredential } = require("@azure/identity");
const { AzureMapsManagementClient } = require("@azure/arm-maps");

const subscriptionId = "<subscription ID of the map account>"


const resourceGroupName = "<resource group name of the map account>";
const accountName = "<name of the map account>";
const mapsAccountSasParameters = {
start: "<start time in ISO format>", // e.g. "2023-11-24T03:51:53.161Z"
expiry: "<expiry time in ISO format>", // maximum value to start + 1 day
maxRatePerSecond: 500,
principalId: "<principle ID (object ID) of the managed identity>",
signingKey: "primaryKey",
};
const credential = new DefaultAzureCredential();
const managementClient = new AzureMapsManagementClient(credential,
subscriptionId);
const {accountSasToken} = await managementClient.accounts.listSas(
resourceGroupName,
accountName,
mapsAccountSasParameters
);
if (accountSasToken === undefined) {
throw new Error("No accountSasToken was found for the Maps Account.");
}
const sasCredential = new AzureSASCredential(accountSasToken);
const client = MapsSearch(sasCredential);

Geocoding
The following code snippet demonstrates how, in a simple console application, to
import the @azure-rest/maps-search package and get the coordinates of an address
using GetGeocoding query:

JavaScript

const MapsSearch = require("@azure-rest/maps-search").default;


const { isUnexpected } = require("@azure-rest/maps-search");
const { AzureKeyCredential } = require("@azure/core-auth");
require("dotenv").config();

async function main() {


const credential = new AzureKeyCredential(
process.env. MAPS_SUBSCRIPTION_KEY
);
const client = MapsSearch(credential);

const response = await client.path("/geocode", "json").get({


queryParameters: {
query: "1301 Alaskan Way, Seattle, WA 98101, US",
},
});
if (isUnexpected(response)) {
throw response.body.error;
}
const [ lon, lat ] = response.body.features[0].geometry.coordinates;
console.log(`The coordinate is: (${lat}, ${lon})`);
}

main().catch((err) => {
console.error(err);
});

This code snippet shows how to use the MapsSearch method from the Azure Maps
Search client library to create a client object with your Azure credentials. You can use
either your Azure Maps subscription key or the Microsoft Entra credential. The path
parameter specifies the API endpoint, which in this case is "/geocode". The get method
sends an HTTP GET request with the query parameters. The query searches for the
coordinate of "1301 Alaskan Way, Seattle, WA 98101, US". The SDK returns the results as
a GeocodingResponseOutput object and writes them to the console. The results are
ordered by confidence score in this example and only the first result is displayed to the
screen. For more information, see GetGeocoding.

Run search.js with Node.js:

PowerShell

node search.js

Batch reverse geocoding


Azure Maps Search also provides some batch query methods. The following example
demonstrates how to call batched reverse search method:

JavaScript

const batchItems = [
// This is an invalid query
{ coordinates: [2.294911, 148.858561] },
{
coordinates: [-122.34255, 47.6101],
},
{ coordinates: [-122.33817, 47.6155] },
];
const response = await client.path("/reverseGeocode:batch").post({
body: { batchItems },
});

In this example, three coordinates are included in the batchItems of the request body.
The first item is invalid, see Handling failed requests for an example showing how to
handle the invalid item.

Once you get the response, you can log it:

JavaScript

function logResponseBody(resBody) {
const { summary, batchItems } = resBody;

const { totalRequests, successfulRequests } = summary;


console.log(`${successfulRequests} out of ${totalRequests} requests are
successful.`);

batchItems.forEach(({ response }, idx) => {


if (response.error) {
console.log(`Error in ${idx + 1} request: ${response.error.message}`);
} else {
console.log(`Results in ${idx + 1} request:`);
response.features.forEach((feature) => {
console.log(` ${feature.properties.address.freeformAddress}`);
});
}
});
}

Handling failed requests


Handle failed requests by checking for the error property in the response batch item.
See the logResponseBody function in the completed batch reverse search following
example.

Completed batch reverse search example


The complete code for the reverse address batch search example:

JavaScript

const MapsSearch = require("@azure-rest/maps-search").default,


{ isUnexpected } = require("@azure-rest/maps-search");
const { AzureKeyCredential } = require("@azure/core-auth");
require("dotenv").config();

async function main() {


const credential = new
AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY);
const client = MapsSearch(credential);

const batchItems = [
// This is an invalid query
{ coordinates: [2.294911, 148.858561] },
{
coordinates: [-122.34255, 47.6101],
},
{ coordinates: [-122.33817, 47.6155] },
];

const response = await client.path("/reverseGeocode:batch").post({


body: { batchItems },
});
if (isUnexpected(response)) {
throw response.body.error;
}

logResponseBody(resumeResponse.body);
}

function logResponseBody(resBody) {
const { summary, batchItems } = resBody;

const { totalRequests, successfulRequests } = summary;


console.log(`${successfulRequests} out of ${totalRequests} requests are
successful.`);

batchItems.forEach(({ response }, idx) => {


if (response.error) {
console.log(`Error in ${idx + 1} request: ${response.error.message}`);
} else {
console.log(`Results in ${idx + 1} request:`);
response.features.forEach((feature) => {
console.log(` ${feature.properties.address.freeformAddress}`);
});
}
});
}

main().catch(console.error);

Use V1 SDK
We are working to make all V1 features available in V2, until then, install the following
V1 SDK packages if needed:

Bash

npm install @azure-rest/map-search-v1@npm:@azure-rest/map-search@^1.0.0


npm install @azure-rest/map-search-v2@npm:@azure-rest/map-search@^2.0.0

Then, you can import the two packages:

JavaScript

const MapsSearchV1 = require("@azure-rest/map-search-v1").default;


const MapsSearchV2 = require("@azure-rest/map-search-v2").default;
The following example demonstrates creating a function that accepts an address and
search POIs around it. Use V2 SDK to get the coordinates of the address(/geocode) and
V1 SDK to search POIs around it(/search/nearby).

JavaScript

const MapsSearchV1 = require("@azure-rest/map-search-v1").default;


const MapsSearchV2 = require("@azure-rest/map-search-v2").default;
const { AzureKeyCredential } = require("@azure/core-auth");
const { isUnexpected: isUnexpectedV1 } = require("@azure-rest/maps-search-
v1");
const { isUnexpected: isUnexpectedV2 } = require("@azure-rest/maps-search-
v2");
require("dotenv").config();

/** Initialize the MapsSearchClient */


const clientV1 = MapsSearchV1(new
AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY));
const clientV2 = MapsSearchV2(new
AzureKeyCredential(process.env.MAPS_SUBSCRIPTION_KEY));

async function searchNearby(address) {


/** Make a request to the geocoding API */
const geocodeResponse = await clientV2
.path("/geocode")
.get({ queryParameters: { query: address } });
/** Handle error response */
if (isUnexpectedV2(geocodeResponse)) {
throw geocodeResponse.body.error;
}

const [lon, lat] = geocodeResponse.body.features[0].geometry.coordinates;

/** Make a request to the search nearby API */


const nearByResponse = await clientV1.path("/search/nearby/{format}",
"json").get({
queryParameters: { lat, lon },
});
/** Handle error response */
if (isUnexpectedV1(nearByResponse)) {
throw nearByResponse.body.error;
}
/** Log response body */
for(const results of nearByResponse.body.results) {
console.log(
`${result.poi ? result.poi.name + ":" : ""}
${result.address.freeformAddress}. (${
result.position.lat
}, ${result.position.lon})\n`
);
}
}
async function main(){
searchNearBy("15127 NE 24th Street, Redmond, WA 98052");
}

main().catch((err) => {
console.log(err);
})

Additional information
The Azure Maps Search client library for JavaScript/TypeScript.
Java REST SDK Developers Guide
(preview)
Article • 10/12/2023

The Azure Maps Java SDK can be integrated with Java applications and libraries to build
maps-related and location-aware applications. The Azure Maps Java SDK contains APIs
for Search, Route, Render, Geolocation, Traffic, Timezone, and Weather. These APIs
support operations such as searching for an address, routing between different
coordinates, obtaining the geo-location of a specific IP address etc.

7 Note

Azure Maps Java SDK is baselined on Java 8, with testing and forward support up
until the latest Java long-term support release (currently Java 18). For the list of
Java versions for download, see Java Standard Versions .

Prerequisites
An Azure Maps account
A Subscription key or other form of authentication
Java Version 8 or above
Maven (any version). For more information, see Get started with Azure SDK and
Apache Maven.

 Tip

You can create an Azure Maps account programmatically, Here's an example using
the Azure CLI:

Azure CLI

az maps account create --kind "Gen2" --account-name "myMapAccountName"


--resource-group "<resource group>" --sku "G2"

Create a Maven project


The following PowerShell code snippet demonstrates how to use PowerShell to create a
maven project. First, run the maven command to create a maven project:

PowerShell

mvn archetype:generate "-DgroupId=groupId" "-DartifactId=DemoProject" "-


DarchetypeArtifactId=maven-archetype-quickstart" "-DarchetypeVersion=1.4" "-
DinteractiveMode=false"

Parameter Description

-DGroupId Group ID uniquely identifies your project across all projects

-DartifactId Project name. It's created as a new folder.

-DarchetypeArtifactId project type. maven-archetype-quickstart results in a sample project.

-DinteractiveMode Setting to false results in a blank Java project with default options.

Install the packages


To use the Azure Maps Java SDK, you need to install all required packages. Each service
in Azure Maps is available in its own package. The Azure Maps services include Search,
Render, Traffic, Weather, etc. You only need to install the packages for the service or
services used in your project.

Once the maven project is created, there should be a pom.xml file with basic information
such as group ID, name, artifact ID. Next, add a dependency for each of the Azure Maps
services, as the following example demonstrates:

XML

<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-maps-search</artifactId>
<version>1.0.0-beta.1</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-maps-route</artifactId>
<version>1.0.0-beta.1</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-maps-render</artifactId>
<version>1.0.0-beta.1</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-maps-traffic</artifactId>
<version>1.0.0-beta.1</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-maps-weather</artifactId>
<version>1.0.0-beta.1</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-maps-timezone</artifactId>
<version>1.0.0-beta.1</version>
</dependency>

Run mvn clean install on your project, then create a java file named demo.java and
import what you need from Azure maps into the file:

PowerShell

cd DemoProject
New-Item demo.java

 Tip

If running mvn clean install results in an error, try running mvn clean install -U .

Azure Maps services

Service name Maven package Samples

Search azure-maps-search search samples

Routing azure-maps-routing routing samples

Rendering azure-maps-rendering rendering sample

Geolocation azure-maps-geolocation geolocation sample

Timezone azure-maps-timezone timezone samples

Create and authenticate a MapsSearchClient


The client object used to access the Azure Maps Search APIs require either an
AzureKeyCredential object to authenticate when using an Azure Maps subscription key
or a TokenCredential object with the Azure Maps client ID when authenticating using
Microsoft Entra ID. For more information on authentication, see Authentication with
Azure Maps.

Using a Microsoft Entra credential


You can authenticate with Microsoft Entra ID using the Azure Identity library. To use the
DefaultAzureCredential provider, you need to add the mvn dependency in the pom.xml
file:

XML

<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
</dependency>

You need to register the new Microsoft Entra application and grant access to Azure
Maps by assigning the required role to your service principal. For more information, see
Host a daemon on non-Azure resources. The Application (client) ID, a Directory (tenant)
ID, and a client secret are returned. Copy these values and store them in a secure place.
You need them in the following steps.

Set the values of the Application (client) ID, Directory (tenant) ID, and client secret of
your Microsoft Entra application, and the map resource's client ID as environment
variables:

Environment Variable Description

AZURE_CLIENT_ID Application (client) ID in your registered application

AZURE_CLIENT_SECRET The value of the client secret in your registered application

AZURE_TENANT_ID Directory (tenant) ID in your registered application

MAPS_CLIENT_ID The client ID in your Azure Map account

Now you can create environment variables in PowerShell to store these values:

PowerShell

$Env:AZURE_CLIENT_ID="<client-id>"
A$Env:AZURE_CLIENT_SECRET="<client-secret>"
$Env:AZURE_TENANT_ID="<tenant-id>"
$Env:MAPS_CLIENT_ID="<maps-client-id>"
After setting up the environment variables, you can use them in your program to
instantiate the AzureMapsSearch client:

Java

import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.maps.search.MapsSearchClient;
import com.azure.maps.search.MapsSearchClientBuilder;

public class Demo {


public static void main( String[] args) {
MapsSearchClientBuilder builder = new MapsSearchClientBuilder();
DefaultAzureCredential tokenCredential = new
DefaultAzureCredentialBuilder().build();
builder.credential(tokenCredential);
builder.mapsClientId(System.getenv("MAPS_CLIENT_ID"));
MapsSearchClient client = builder.buildClient();
}
}

) Important

The other environment variables created in the previous code snippet, while not
used in the code sample, are required by are required by
DefaultAzureCredential() . If you do not set these environment variables correctly,

using the same naming conventions, you will get run-time errors. For example, if
your AZURE_CLIENT_ID is missing or invalid you will get an
InvalidAuthenticationTokenTenant error.

Using a subscription key credential


You can authenticate with your Azure Maps subscription key. Your subscription key can
be found in the Authentication section in the Azure Maps account as shown in the
following screenshot:

Now you can create environment variables in PowerShell to store the subscription key:

PowerShell

$Env:SUBSCRIPTION_KEY="<subscription-key>"

Once your environment variable is created, you can access it in your code:

Java

import com.azure.core.credential.AzureKeyCredential;
import com.azure.maps.search.MapsSearchClient;
import com.azure.maps.search.MapsSearchClientBuilder;

public class Demo {


public static void main( String[] args) {

// Use Azure Maps subscription key authentication


MapsSearchClientBuilder builder = new MapsSearchClientBuilder();
AzureKeyCredential keyCredential = new
AzureKeyCredential(System.getenv("SUBSCRIPTION_KEY"));
builder.credential(keyCredential);
MapsSearchClient client = builder.buildClient();
}
}

Fuzzy search an entity


The following code snippet demonstrates how, in a simple console application, to
import the azure-maps-search package and perform a fuzzy search on "Starbucks" near
Seattle:

Java

import java.io.IOException;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.models.GeoPosition;
// Enable the 2 imports below if you want to use AAD authentication
// import com.azure.identity.DefaultAzureCredential;
// import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.maps.search.MapsSearchClient;
import com.azure.maps.search.MapsSearchClientBuilder;
import com.azure.maps.search.models.FuzzySearchOptions;
import com.azure.maps.search.models.SearchAddressResult;
import com.azure.maps.search.models.SearchAddressResultItem;

public class Demo {


public static void main( String[] args) throws IOException {
MapsSearchClientBuilder builder = new MapsSearchClientBuilder();

// Instantiate with key credential. Get SUBSCRIPTION_KEY from


environment variable:
AzureKeyCredential keyCredential = new
AzureKeyCredential(System.getenv("SUBSCRIPTION_KEY"));
builder.credential(keyCredential);

// Or you can also instantiate with token credential:


// DefaultAzureCredential tokenCredential = new
DefaultAzureCredentialBuilder().build();
// builder.credential(tokenCredential);
// builder.mapsClientId(System.getenv("MAPS_CLIENT_ID"));
MapsSearchClient client = builder.buildClient();

// Fuzzy search with options:


SearchAddressResult results = client.fuzzySearch(new
FuzzySearchOptions("starbucks", new GeoPosition(-122.34255, 47.61010)));

// Print the search results:


for (SearchAddressResultItem item : results.getResults()) {
MapsSearchAddress address = item.getAddress();
GeoPosition coordinate = item.getPosition();
System.out.format(
"* %s, %s\\n" +
" %s %s %s\\n" +
" Coordinate: (%.4f, %.4f)\\n",
address.getStreetNumber(), address.getStreetName(),
address.getMunicipality(), address.getCountryCode(),
address.getPostalCode(),
coordinate.getLatitude(), coordinate.getLongitude());
}
}
}

This code snippet demonstrates how to create a MapsSearchClient object using Azure
credentials. Start by instantiating AzureKeyCredential using your Azure Maps
subscription key, then passes the credentials to instantiate MapsSearchClient .
MapsSearchClient methods such as FuzzySearch can use the point of interest (POI)

name "Starbucks" and coordinates GeoPosition(-122.31, 47.61).

Execute the program from the project folder in the command line:

PowerShell

java .\demo.java

You should see a list of Starbucks address and coordinate results:

text

* 1912, Pike Place


Seattle US 98101
Coordinate: (47.6102, -122.3425)
* 2118, Westlake Avenue
Seattle US 98121
Coordinate: (47.6173, -122.3378)
* 2601, Elliott Avenue
Seattle US 98121
Coordinate: (47.6143, -122.3526)
* 1730, Howell Street
Seattle US 98101
Coordinate: (47.6172, -122.3298)
* 220, 1st Avenue South
Seattle US 98104
Coordinate: (47.6003, -122.3338)
* 400, Occidental Avenue South
Seattle US 98104
Coordinate: (47.5991, -122.3328)
* 1600, East Olive Way
Seattle US 98102
Coordinate: (47.6195, -122.3251)
* 500, Mercer Street
Seattle US 98109
Coordinate: (47.6250, -122.3469)
* 505, 5Th Ave S
Seattle US 98104
Coordinate: (47.5977, -122.3285)
* 425, Queen Anne Avenue North
Seattle US 98109
Coordinate: (47.6230, -122.3571)
Search an address
Call the SearchAddress method to get the coordinate of an address. Modify the Main
program from the sample as follows:

Java

import java.io.IOException;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.models.GeoPosition;
// Enable the 2 imports below if you want to use AAD authentication
// import com.azure.identity.DefaultAzureCredential;
// import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.maps.search.MapsSearchClient;
import com.azure.maps.search.MapsSearchClientBuilder;
import com.azure.maps.search.models.SearchAddressOptions;
import com.azure.maps.search.models.SearchAddressResult;
import com.azure.maps.search.models.SearchAddressResultItem;

public class Demo {


public static void main( String[] args) throws IOException {
MapsSearchClientBuilder builder = new MapsSearchClientBuilder();

// Instantiate with key credential:


AzureKeyCredential keyCredential = new
AzureKeyCredential(System.getenv("SUBSCRIPTION_KEY"));
builder.credential(keyCredential);

// Or you can also instantiate with token credential:


// DefaultAzureCredential tokenCredential = new
DefaultAzureCredentialBuilder().build();
// builder.credential(tokenCredential);
// builder.mapsClientId(System.getenv("MAPS_CLIENT_ID"));

MapsSearchClient client = builder.buildClient();


client.searchAddress(new SearchAddressOptions("15127 NE 24th Street,
Redmond, WA 98052"));

// Search address with options and return top 5 results:


SearchAddressResult results = client.searchAddress(new
SearchAddressOptions("1
Main Street").setCoordinates(new GeoPosition(-74.011454,
40.706270)).setRadiusInMeters(40000).setTop(5));

// Print results:
if (results.getResults().size() > 0) {
SearchAddressResultItem item = results.getResults().get(0);
System.out.format("The coordinates is (%.4f, %.4f)",
item.getPosition().getLatitude(),
item.getPosition().getLongitude());
}
}
}

In this sample, the client.SearchAddress method returns results ordered by confidence


score and prints the coordinates of the first result.

Batch reverse search


Azure Maps Search also provides some batch query methods. These methods return
Long Running Operations (LRO) objects. The requests might not return all the results
immediately, so users can choose to wait until completion or query the result
periodically as demonstrated in the batch reverse search method:

Java

import java.util.ArrayList;
import java.util.List;
import com.azure.core.credential.AzureKeyCredential;
import com.azure.core.models.GeoPosition;
// Enable the 2 imports below if you want to use AAD authentication
// import com.azure.identity.DefaultAzureCredential;
// import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.maps.search.MapsSearchClient;
import com.azure.maps.search.MapsSearchClientBuilder;
import com.azure.maps.search.models.BatchReverseSearchResult;
import com.azure.maps.search.models.ReverseSearchAddressBatchItem;
import com.azure.maps.search.models.ReverseSearchAddressOptions;
import com.azure.maps.search.models.ReverseSearchAddressResultItem;

public class Demo{


public static void main( String[] args) throws IOException {
MapsSearchClientBuilder builder = new MapsSearchClientBuilder();

// Instantiate with key credential:


AzureKeyCredential keyCredential = new
AzureKeyCredential(System.getenv("SUBSCRIPTION_KEY"));
builder.credential(keyCredential);

// Or you can also instantiate with token credential:


// DefaultAzureCredential tokenCredential = new
DefaultAzureCredentialBuilder().build();
// builder.credential(tokenCredential);
// builder.mapsClientId(System.getenv("MAPS_CLIENT_ID"));

MapsSearchClient client = builder.buildClient();


List<ReverseSearchAddressOptions> reverseOptionsList = new
ArrayList<>();
reverseOptionsList.add(new ReverseSearchAddressOptions(new
GeoPosition(2.294911, 48.858561)));
reverseOptionsList.add(new ReverseSearchAddressOptions(new
GeoPosition(-122.34255, 47.61010)));
reverseOptionsList.add(new ReverseSearchAddressOptions(new
GeoPosition(-122.33817, 47.61559)).setRadiusInMeters(5000));
BatchReverseSearchResult batchReverseSearchResult =

client.beginReverseSearchAddressBatch(reverseOptionsList).getFinalResult();
for (ReverseSearchAddressBatchItem item :
batchReverseSearchResult.getBatchItems()) {
for (ReverseSearchAddressResultItem result :
item.getResult().getAddresses()) {

System.out.println(result.getAddress().getFreeformAddress());
}
}
}
}
The Azure Maps Web SDK migration
guide
Article • 03/05/2024

Thank you for choosing the Azure Maps Web SDK for your mapping needs. This
migration guide helps you transition from v1 and v2 to v3, allowing you to take
advantage of the latest features and enhancements.

Understand the changes


Before you start the migration process, it's important to familiarize yourself with the key
changes and improvements introduced in Web SDK v3. Review the release notes to
grasp the scope of the new features.

Updating the Web SDK version

CDN
If you're using CDN (content delivery network), update the references to the v3
stylesheet and JavaScript in the head element of your HTML files.

v1

HTML

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/css/atlas.min.css?api-version=1"
type="text/css" />
<script src="https://atlas.microsoft.com/sdk/js/atlas.min.js?api-version=1">
</script>

v2

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>

v3

HTML

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>

npm
If you're using npm , update to the latest Azure Maps control by running the following
command:

shell

npm install azure-maps-control@latest

Review authentication methods (optional)


To enhance security, more authentication methods are included in the Web SDK starting
in v2. The new methods include Microsoft Entra authentication and Shared Key
Authentication. For more information about Azure Maps web application security, see
Manage Authentication in Azure Maps.

Testing
Comprehensive testing is essential during migration. Conduct thorough testing of your
application's functionality, performance, and user experience in different browsers and
devices.

Gradual Rollout
Consider a gradual rollout strategy for the updated version. Release the migrated
version to a smaller group of users or in a controlled environment before making it
available to your entire user base.

By following these steps and considering best practices, you can successfully migrate
your application from Azure Maps Web SDK v1 and v2 to v3. Embrace the new
capabilities and improvements offered by the latest version while ensuring a smooth
and seamless transition for your users. For more information, see Azure Maps Web SDK
best practices.

Next steps
Learn how to add maps to web and mobile applications using the Map Control client-
side JavaScript library in Azure Maps:

Use the Azure Maps map control


Use the Azure Maps map control
Article • 02/11/2025

The Azure Maps Web SDK provides a Map Control that enables the customization of
interactive maps with your own content and imagery for display in your web or mobile
applications. This module is a helper library that makes it easy to use the Azure Maps
REST services in web or Node.js applications by using JavaScript or TypeScript.

7 Note

Azure Maps Web SDK Map Control v1 retirement

Version 1 of the Web SDK Map Control is now deprecated and will be retired on
9/19/26. To avoid service disruptions, migrate to version 3 of the Web SDK Map
Control by 9/19/26. Version 3 is backwards compatible and has several benefits
including WebGL 2 Compatibility, increased performance and support for 3D
terrain tiles. For more information, see The Azure Maps Web SDK v1 migration
guide.

Prerequisites
To use the Map Control in a web page, you must have one of the following
prerequisites:

An Azure Maps account


A subscription key or Microsoft Entra credentials. For more information, see
authentication options.

Create a new map in a web page


You can embed a map in a web page by using the Map Control client-side JavaScript
library.

1. Create a new HTML file.

2. Load in the Azure Maps Web SDK. You can choose one of two options:

Use the globally hosted CDN version of the Azure Maps Web SDK by adding
references to the JavaScript and stylesheet in the <head> element of the
HTML file:
HTML

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atla
s.min.css" type="text/css">
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas
.min.js"></script>

Load the Azure Maps Web SDK source code locally using the azure-maps-
control npm package and host it with your app. This package also includes
TypeScript definitions.

npm install azure-maps-control

Then add references to the Azure Maps stylesheet to the <head> element of the
file:

HTML

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css" />

7 Note

TypeScript definitions can be imported into your application by adding the


following code:

JavaScript

import * as atlas from 'azure-maps-control';

3. To render the map so that it fills the full body of the page, add the following
<style> element to the <head> element.

HTML

<style>
html, body {
margin: 0;
}

#myMap {
height: 100vh;
width: 100vw;
}
</style>

4. In the body of the page, add a <div> element and give it an id of myMap.

HTML

<body onload="InitMap()">
<div id="myMap"></div>
</body>

5. Next, initialize the map control. In order to authenticate the control, use an Azure
Maps subscription key or Microsoft Entra credentials with authentication options.

If you're using a subscription key for authentication, copy and paste the following
script element inside the <head> element, and below the first <script> element.
Replace <Your Azure Maps Key> with your Azure Maps subscription key.

HTML

<script type="text/javascript">
function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-122.33, 47.6],
zoom: 12,
language: 'en-US',
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});
}
</script>

If you're using Microsoft Entra ID for authentication, copy and paste the following
script element inside the <head> element, and below the first <script> element.

HTML

<script type="text/javascript">
function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-122.33, 47.6],
zoom: 12,
language: 'en-US',
authOptions: {
authType: 'aad',
clientId: '<Your Microsoft Entra Client Id>',
aadAppId: '<Your Microsoft Entra App Id>',
aadTenant: '<Your Microsoft Entra tenant Id>'
}
});
}
</script>

For more information about authentication with Azure Maps, see the
Authentication with Azure Maps document. For a list of samples showing how to
integrate Azure AD with Azure Maps, see Azure Maps & Azure Active Directory
Samples in GitHub.

 Tip

In this example, we've passed in the id of the map <div> . Another way to do
this is to pass in the HTMLElement object by
passing document.getElementById('myMap') as the first parameter.

6. Optionally, you may find it helpful to add the following meta elements to the head
element of the page:

HTML

<!-- Ensures that Internet Explorer and Edge uses the latest version
and doesn't emulate an older version -->
<meta http-equiv="x-ua-compatible" content="IE=Edge">

<!-- Ensures the web page looks good on all screen sizes. -->
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

7. Your HTML file should now look something like the following code snippet:

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>

<meta charset="utf-8">

<!-- Ensures that Internet Explorer and Edge uses the latest
version and doesn't emulate an older version -->
<meta http-equiv="x-ua-compatible" content="IE=Edge">

<!-- Ensures the web page looks good on all screen sizes. -->
<meta name="viewport" content="width=device-width, initial-
scale=1, shrink-to-fit=no">

<!-- Add references to the Azure Maps Map control JavaScript and
CSS files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css">
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.
js"></script>

<script type="text/javascript">
//Create an instance of the map control and set some options.
function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-122.33, 47.6],
zoom: 12,
language: 'en-US',
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});
}
</script>

<style>
html, body {
margin: 0;
}

#myMap {
height: 100vh;
width: 100vw;
}
</style>
</head>
<body onload="InitMap()">
<div id="myMap"></div>
</body>
</html>

8. Open the file in your web browser and view the rendered map. It should look like
the following image:

Localizing the map


Azure Maps provides two different ways of setting the language and regional view for
the rendered map. The first option is to add this information to the global atlas
namespace, which results in all map control instances in your app defaulting to these
settings. The following sets the language to French ("fr-FR") and the regional view to
"Auto":

JavaScript

atlas.setLanguage('fr-FR');
atlas.setView('Auto');

The second option is to pass this information into the map options when loading the
map like this:

JavaScript

map = new atlas.Map('myMap', {


language: 'fr-FR',
view: 'Auto',

authOptions: {
authType: 'aad',
clientId: '<Your AAD Client Id>',
aadAppId: '<Your AAD App Id>',
aadTenant: '<Your AAD Tenant Id>'
}
});
7 Note

It is possible to load multiple map instances on the same page with different
language and region settings. Additionally, these settings can be updated after the
map loads using the setStyle function of the map.

Here's an example of Azure Maps with the language set to "fr-FR" and the regional view
set to Auto .

For a list of supported languages and regional views, see Localization support in Azure
Maps.

WebGL 2 Compatibility
Beginning with Azure Maps Web SDK 3.0, the Web SDK includes full compatibility with
WebGL 2 , a powerful graphics technology that enables hardware-accelerated
rendering in modern web browsers. By using WebGL 2, developers can harness the
capabilities of modern GPUs to render complex maps and visualizations more efficiently,
resulting in improved performance and visual quality.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no"
/>
<title>WebGL2 - Azure Maps Web SDK Samples</title>
<link
href=https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css
rel="stylesheet"/>
<script
src=https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js>
</script>
<script src="https://unpkg.com/deck.gl@^8/dist.min.js"></script>
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = new atlas.Map("map", {
center: [-122.44, 37.75],
bearing: 36,
pitch: 45,
zoom: 12,
style: "grayscale_light",
// Get an Azure Maps key at https://azuremaps.com/.
authOptions: {
authType: "subscriptionKey",
subscriptionKey: " <Your Azure Maps Key> "
}
});

// Wait until the map resources are ready.


map.events.add("ready", (event) => {
// Create a custom layer to render data points using deck.gl
map.layers.add(
new DeckGLLayer({
id: "grid-layer",
data:
"https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/sf-
bike-parking.json",
cellSize: 200,
extruded: true,
elevationScale: 4,
getPosition: (d) => d.COORDINATES,
// GPUGridLayer leverages WebGL2 to perform
aggregation on the GPU.
// For more details, see https://deck.gl/docs/api-
reference/aggregation-layers/gpu-grid-layer
type: deck.GPUGridLayer
})
);
});

// A custom implementation of WebGLLayer


class DeckGLLayer extends atlas.layer.WebGLLayer {
constructor(options) {
super(options.id);
// Create an instance of deck.gl MapboxLayer which is
compatible with Azure Maps
// https://deck.gl/docs/api-reference/mapbox/mapbox-
layer
this._mbLayer = new deck.MapboxLayer(options);

// Create a renderer
const renderer = {
renderingMode: "3d",
onAdd: (map, gl) => {
this._mbLayer.onAdd?.(map["map"], gl);
},
onRemove: (map, gl) => {
this._mbLayer.onRemove?.(map["map"], gl);
},
prerender: (gl, matrix) => {
this._mbLayer.prerender?.(gl, matrix);
},
render: (gl, matrix) => {
this._mbLayer.render(gl, matrix);
}
};
this.setOptions({ renderer });
}
}
</script>
</body>
</html>

3D terrain tiles
Beginning with Azure Maps Web SDK 3.0, developers can take advantage of 3D terrain
visualizations. This feature allows you to incorporate elevation data into your maps,
creating a more immersive experience for your users. Whether it's visualizing mountain
ranges, valleys, or other geographical features, the 3D terrain support brings a new level
of realism to your mapping applications.

The following code example demonstrates how to implement 3D terrain tiles.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no"
/>
<title>Elevation - Azure Maps Web SDK Samples</title>
<link
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css
rel="stylesheet" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js>
</script>
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>

<body>
<div id="map"></div>
<script>
var map = new atlas.Map("map", {
center: [-121.7269, 46.8799],
maxPitch: 85,
pitch: 60,
zoom: 12,
style: "road_shaded_relief",
// Get an Azure Maps key at https://azuremaps.com/.
authOptions: {
authType: "subscriptionKey",
subscriptionKey: "<Your Azure Maps Key>"
}
});

// Create a tile source for elevation data. For more information


on creating
// elevation data & services using open data, see
https://aka.ms/elevation
var elevationSource = new
atlas.source.ElevationTileSource("elevation", {
url: "<tileSourceUrl>"
});

// Wait until the map resources are ready.


map.events.add("ready", (event) => {

// Add the elevation source to the map.


map.sources.add(elevationSource);

// Enable elevation on the map.


map.enableElevation(elevationSource);
});
</script>
</body>
</html>

Azure Government cloud support


The Azure Maps Web SDK supports the Azure Government cloud. All JavaScript and CSS
URLs used to access the Azure Maps Web SDK remain the same. The following tasks
need to be done to connect to the Azure Government cloud version of the Azure Maps
platform.

When using the interactive map control, add the following line of code before creating
an instance of the Map class.
JavaScript

atlas.setDomain('atlas.azure.us');

Be sure to use Azure Maps authentication details from the Azure Government cloud
platform when authenticating the map and services.

JavaScript frameworks
If developing using a JavaScript framework, one of the following open-source projects
may be useful:

ng-azure-maps - Angular 10 wrapper around Azure maps.


AzureMapsControl.Components - An Azure Maps Blazor component.
Azure Maps React Component - A react wrapper for the Azure Maps control.
Vue Azure Maps - An Azure Maps component for Vue application.

Next steps
Learn how to create and interact with a map:

Create a map

Learn how to style a map:

Choose a map style

Learn best practices and see samples:

Best practices

Code samples

For a list of samples showing how to integrate Microsoft Entra ID with Azure Maps, see:

Microsoft Entra authentication samples

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Use the azure-maps-control npm
package
Article • 07/14/2023

The azure-maps-control npm package is a client-side library that allows you to embed
the Azure Maps map control into your node.js applications using JavaScript or
TypeScript. This library makes it easy to use the Azure Maps REST services and lets you
customize interactive maps with your content and imagery.

Prerequisites
To use the npm package in an application, you must have the following prerequisites:

An Azure Maps account


A subscription key or Azure Active Directory (Azure AD) credentials. For more
information, see authentication options.

Installation
Install the latest azure-maps-control package.

PowerShell

npm install azure-maps-control

This package includes a minified version of the source code, CSS Style Sheet, and the
TypeScript definitions for the Azure Maps map control.

You would also need to embed the CSS Style Sheet for various controls to display
correctly. If you're using a JavaScript bundler to bundle the dependencies and package
your code, refer to your bundler's documentation on how it's done. For Webpack , it's
commonly done via a combination of style-loader and css-loader with
documentation available at style-loader .

To begin, install style-loader and css-loader :

PowerShell

npm install --save-dev style-loader css-loader


Inside your source file, import atlas.min.css:

JavaScript

import "azure-maps-control/dist/atlas.min.css";

Then add loaders to the module rules portion of the Webpack config:

JavaScript

module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"]
}
]
}
};

Refer to the following section for a complete example.

Create a map in a node.js application


Embed a map in a web page using the map control npm package.

1. Create a new project

PowerShell

npm init

npm init is a command that helps you create a package.json file for your node

project. It asks you some questions and generates the file based on your answers.
You can also use -y or –yes to skip the questions and use the default values. The
package.json file contains information about your project, such as its name, version,
dependencies, scripts, etc.

2. Install the latest azure-maps-control package.

PowerShell

npm install azure-maps-control


3. Install Webpack and other dev dependencies.

PowerShell

npm install --save-dev webpack webpack-cli style-loader css-loader

4. Update package.json by adding a new script for "build": "webpack" . The file
should now look something like the following:

JavaScript

{
"name": "azure-maps-npm-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "",
"license": "ISC",
"dependencies": {
"azure-maps-control": "^2.3.1"
},
"devDependencies": {
"css-loader": "^6.8.1",
"style-loader": "^3.3.3",
"webpack": "^5.88.1",
"webpack-cli": "^5.1.4"
}
}

5. Create a Webpack config file named webpack.config.js in the project's root folder.
Include these settings in the config file.

JavaScript

module.exports = {
entry: "./src/js/main.js",
mode: "development",
output: {
path: `${__dirname}/dist`,
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"]
}
]
}
};

6. Add a new JavaScript file at ./src/js/main.js with this code.

JavaScript

import * as atlas from "azure-maps-control";


import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
authType: "subscriptionKey",
subscriptionKey: "<Your Azure Maps Key>"
}
});
};

document.body.onload = onload;

7. Add a new HTML file named index.html in the project's root folder with this
content:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Azure Maps demo</title>
<script src="./dist/bundle.js" async></script>
<style>
html,
body,
#map {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
</html>

Your project should now have the following files:

├───node_modules
├───index.html
├───package-lock.json
├───package.json
├───webpack.config.js
└───src
└───js
└───main.js

8. Run the following command to generate a JavaScript file at ./dist/bundle.js

PowerShell

npm run build

9. Open the file index.html in your web browser and view the rendered map. It should
look like the following image:

Use other Azure Maps npm packages


Azure Maps offers other modules as npm packages that can be integrated into your
application. These modules include:

azure-maps-drawing-tools
azure-maps-indoor
azure-maps-spatial-io

The following sample shows how to import a module and use it in your application. This
sample uses azure-maps-spatial-io to read a POINT(-122.34009 47.60995) string as
GeoJSON and renders it on the map using a bubble layer.

1. Install the npm package.

PowerShell

npm install azure-maps-spatial-io

2. Then, use an import declaration to add the module to a source file:

JavaScript

import * as spatial from "azure-maps-spatial-io";

3. Use spatial.io.ogc.WKT.read() to parse the text.

JavaScript

import * as atlas from "azure-maps-control";


import * as spatial from "azure-maps-spatial-io";
import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
center: [-122.34009, 47.60995],
zoom: 12,
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
authType: "subscriptionKey",
subscriptionKey: "<Your Azure Maps Key>"
}
});

// Wait until the map resources are ready.


map.events.add("ready", () => {
// Create a data source and add it to the map.
const datasource = new atlas.source.DataSource();
map.sources.add(datasource);

// Create a layer to render the data


map.layers.add(new atlas.layer.BubbleLayer(datasource));

// Parse the point string.


var point = spatial.io.ogc.WKT.read("POINT(-122.34009 47.60995)");

// Add the parsed data to the data source.


datasource.add(point);
});
};

document.body.onload = onload;

4. Webpack 5 may throw errors about not being able to resolve some node.js core
modules. Add these settings to your Webpack config file to fix the problem.

JavaScript

module.exports = {
// ...
resolve: {
fallback: { "crypto": false, "worker_threads": false }
}
};

This image is a screenshot of the sample’s output.


Next steps
Learn how to create and interact with a map:

Create a map

Learn how to style a map:

Choose a map style

Learn best practices and see samples:

Best practices

Code samples
Create a map
Article • 07/03/2023

This article shows you ways to create a map and animate a map.

Loading a map
To load a map, create a new instance of the Map class. When initializing the map, pass a
DIV element ID to render the map and pass a set of options to use when loading the
map. If default authentication information isn't specified on the atlas namespace, this
information needs to be specified in the map options when loading the map. The map
loads several resources asynchronously for performance. As such, after creating the map
instance, attach a ready or load event to the map and then add more code that
interacts with the map to the event handler. The ready event fires as soon as the map
has enough resources loaded to be interacted with programmatically. The load event
fires after the initial map view has finished loading completely.

You can also load multiple maps on the same page, for sample code that demonstrates
loading multiple maps on the same page, see Multiple Maps in the Azure Maps
Samples . For the source code for this sample, see Multiple Maps source code .

 Tip
You can use the same or different authentication and language settings when using
multiple maps on the same page.

Show a single copy of the world


When the map is zoomed out on a wide screen, multiple copies of the world appear
horizontally. This option is great for some scenarios, but for other applications it's
desirable to see a single copy of the world. This behavior is implemented by setting the
maps renderWorldCopies option to false .

JavaScript

//Only allow one copy of the world be rendered when zoomed out.
renderWorldCopies: false

Map options
When creating a map there, are several different types of options that can be passed in
to customize how the map functions:

CameraOptions and CameraBoundOptions are used to specify the area the map
should display.
ServiceOptions are used to specify how the map should interact with services that
power the map.
StyleOptions are used to specify the map should be styled and rendered.
UserInteractionOptions are used to specify how the map should reach when the
user is interacting with the map.

These options can also be updated after the map has been loaded using the setCamera ,
setServiceOptions , setStyle , and setUserInteraction functions.

Controlling the map camera


There are two ways to set the displayed area of the map using the camera of a map. You
can set the camera options when loading the map. Or, you can call the setCamera
option anytime after the map has loaded to programmatically update the map view.

Set the camera


The map camera controls what is displayed in the viewport of the map canvas. Camera
options can be passed into the map options when being initialized or passed into the
maps setCamera function.

JavaScript

// Set the camera options when creating the map.


// Map properties, such as center and zoom level, are part of the
CameraOptions
var map = new atlas.Map('map', {
center: [-122.33, 47.6],
zoom: 12

//Additional map options.


};

//Update the map camera at anytime using setCamera function.


map.setCamera({
center: [-110, 45],
zoom: 5
});

Map properties, such as center and zoom level, are part of the CameraOptions
properties.

Set the camera bounds


A bounding box can be used to update the map camera. If the bounding box was
calculated from point data, it's often useful to specify a pixel padding value in the
camera options to account for the icon size. This pixel padding helps ensure that points
don't fall off the edge of the map viewport.

JavaScript

map.setCamera({
bounds: [-122.4, 47.6, -122.3, 47.7],
padding: 10
});

In the following code, a Map object is constructed via new atlas.Map() . Map properties
such as CameraBoundsOptions can be defined via setCamera function of the Map class.
Bounds and padding properties are set using setCamera .

Animate map view


When setting the camera options of the map, animation options can also be set. These
options specify the type of animation and duration it should take to move the camera.

JavaScript

map.setCamera({
center: [-122.33, 47.6],
zoom: 12,
duration: 1000,
type: 'fly'
});

In the following code, the first code block creates a map and sets the enter and zoom
map styles. In the second code block, a click event handler is created for the animate
button. When this button is selected, the setCamera function is called with some random
values for the CameraOptions and AnimationOptions.

HTML

<!DOCTYPE html>
<html>
<head>

<!-- Add references to the Azure Maps Map control JavaScript and CSS
files. -->
<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>

<script type="text/javascript">
var map;

function InitMap()
{
map = new atlas.Map('myMap', {
center: [-122.33, 47.6],
zoom: 12,
view: 'Auto',
style: 'road',

// Add authentication details for connecting to Azure Maps.


authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});
}

/* Animate map view to set camera location


to random points on the map*/
function animateMap() {
map.setCamera({
zoom: Math.random() *2 + 12,
duration: 1000,
type: 'fly'
});
}
</script>

<style>
button {
position: absolute;
top: 10px;
left: 10px;
}
</style>

</head>

<html style='width:100%;height:100%;'>
<body onload="InitMap()"
style='width:100%;height:100%;padding:0;margin:0;'>
<div id='myMap' style='position:relative;width:100%;height:100%;'></div>
<button onclick="animateMap()">Animate Maps</button>
<div id="my-text-box"></div>
</body>
</html>
Request transforms
Sometimes it's useful to be able to modify HTTP requests made by the map control. For
example:

Add more headers to tile requests for password protected services.


Modify URLs to run requests through a proxy service.

The service options of the map has a transformRequest that can be used to modify all
requests made by the map before they're made. The transformRequest option is a
function that takes in two parameters; a string URL, and a resource type string that
indicates what the request is used for. This function must return a RequestParameters
result.

JavaScript

transformRequest: (url: string, resourceType: string) => RequestParameters

When using a request transform, you must return a RequestParameters object that
contains a url property at a minimum. The following are the properties that can be
included in a RequestParameters object.

Option Type Description

body string A POST request body.

credentials 'same-origin' | Used to specify the cross-origin request (CORs) credentials


'include' setting. Use 'include' to send cookies with cross-origin
requests.

headers object The headers to be sent with the request. The object is a
key value pair of string values.

method 'GET' | 'POST' | 'PUT' The type of request to be made. Default is 'GET' .

type 'string' | 'json' | The format of POST response body.


'arrayBuffer'

url string The url to be requested.

The resource types most relevant to content you add to the map are listed in the
following table:

Resource Type Description

Image A request for an image for use with either a SymbolLayer or ImageLayer.
Resource Type
Source Description
A request for source information, such as a TileJSON request. Some requests
from the base map styles also use this resource type when loading source
information.

Tile A request from a tile layer (raster or vector).

WFS A request from a WfsClient in the Spatial IO module to an OGC Web Feature
Service. For more information, see Connect to a WFS service.

WebMapService A request from the OgcMapLayer in the Spatial IO module to a WMS or WMTS
service. For more information, see Add a map layer from the Open Geospatial
Consortium (OGC).

Here are some resource types, typically ignored, that are passed through the request
transform and are related to the base map styles: StyleDefinitions, Style, SpriteImage,
SpriteJSON, Glyphs, Attribution.

The following example shows how to modify all requests to the size
https://example.com by adding a username and password as headers to the request.

JavaScript

var map = new atlas.Map('myMap', {


transformRequest: function (url, resourceType) {
//Check to see if the request is to the specified endpoint.
if (url.indexOf('https://examples.com') > -1) {
//Add custom headers to the request.
return {
url: url,
header: {
username: 'myUsername',
password: 'myPassword'
}
};
}

//Return the URL unchanged by default.


return { url: url };
},

authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

Next steps
Learn more about the classes and methods used in this article:

Map

CameraOptions

AnimationOptions

See code examples to add functionality to your app:

Change style of the map

Add controls to the map

Code samples
Change the style of the map
Article • 02/28/2025

The map control supports several different map style options and base map styles. All
styles can be set when the map control is being initialized. Or, you can set styles by
using the map control's setStyle function. This article shows you how to use these style
options to customize the map's appearance and how to implement the style picker
control in your map. The style picker control allows the user to toggle between different
base styles.

Set map style options


Style options can be set during web control initialization. Or, you can update style
options by calling the map control's setStyle function. To see all available style options,
see style options.

JavaScript

//Set the style options when creating the map.


var map = new atlas.Map('map', {
renderWorldCopies: false,
showLogo: true,
showFeedbackLink: true,
style: 'road'

//Additional map options.


});

//Update the style options at anytime using `setStyle` function.


map.setStyle({
renderWorldCopies: true,
showLogo: false,
showFeedbackLink: false
});

Set a base map style


You can also initialize the map control with one of the base map styles that are available
in the Web SDK. You can then use the setStyle function to update the base style with a
different map style.

Set a base map style on initialization


Base styles of the map control can be set during initialization. In the following code, the
style option of the map control is set to the grayscale_dark base map style.

JavaScript

var map = new atlas.Map('map', {


style: 'grayscale_dark',

//Additional map options


});

Update the base map style


The base map style can be updated by using the setStyle function and setting the
style option to either change to a different base map style or add more style options.

In the following code, after a map instance is loaded, the map style is updated from
grayscale_dark to satellite using the setStyle function.

JavaScript

map.setStyle({ style: 'satellite' });


Customize the base map
The styleOverrides options enable users to streamline the base map by turning off
specific map elements like country/region borders, administrative district borders,
building footprints, and road detail layers. This allows for a cleaner and simpler map
view, making it easier to visualize geometry data.

The following code shows how to disable country/region borders and building
footprints on the map.

JavaScript

var map = new atlas.Map('map', {


styleOverrides: {
countryRegion: { borderVisible: false },
buildingFootprint: { visible: false },
},

//Additional map options


});

Here are examples of all five available styleOverrides options:

Country/region borders

JavaScript

styleOverrides: {
countryRegion: { borderVisible: false }
}

Admin district borders

JavaScript

styleOverrides: {
adminDistrict: { borderVisible: false }
}

Second admin district borders


JavaScript

styleOverrides: {
adminDistrict2: { borderVisible: false }
}

Building footprints

JavaScript

styleOverrides: {
buildingFootprint: { visible: false }
}
Road details

JavaScript

styleOverrides: {
roadDetails: { visible: false }
}

7 Note
For more information on the supported map styles on each styleOverrides option,
see the styleOverrides API documentation.

For a sample showing the different styles and how they affect how the map is rendered,
see Map style options in the Azure Maps Samples . For this sample's source code,
see Map style options source code .

Add the style picker control


The style picker control provides an easy to use button with flyout panel that can be
used by the end user to switch between base styles.

The style picker has two different layout options: icon and list . Also, the style picker
allows you to choose two different style picker control style options: light and dark .
In this example, the style picker uses the icon layout and displays a select list of base
map styles in the form of icons. The style control picker includes the following base set
of styles: ["road", "grayscale_light", "grayscale_dark", "night",
"road_shaded_relief"] . For more information on style picker control options, see Style

Control Options.

The following image shows the style picker control displayed in icon layout.

The following image shows the style picker control displayed in list layout.
) Important

By default the style picker control lists all the styles available under the Gen1 (S0)
pricing tier of Azure Maps. If you want to reduce the number of styles in this list,
pass an array of the styles you want to appear in the list into the mapStyle option
of the style picker. If you are using Gen1 (S1) or Gen2 pricing tier and want to show
all available styles, set the mapStyles option of the style picker to "all" .

Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2 pricing
tier replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps account has
Gen1 pricing tier selected, you can switch to Gen2 pricing tier before it’s retired,
otherwise it will automatically be updated. For more information, see Manage the
pricing tier of your Azure Maps account.

The following code shows you how to override the default mapStyles base style list. In
this example, we're setting the mapStyles option to list the base styles to display in the
style picker control.

JavaScript

/*Add the Style Control to the map*/


map.controls.add(new atlas.control.StyleControl({
mapStyles: ['road', 'grayscale_dark', 'night', 'road_shaded_relief',
'satellite', 'satellite_road_labels'],
layout: 'list'
}), {
position: 'top-right'
});

Next steps
To learn more about the classes and methods used in this article:

Map
StyleOptions

StyleControl

StyleControlOptions

See the following articles for more code samples to add to your maps:

Add map controls

Add a symbol layer

Add a bubble layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add controls to a map
Article • 11/08/2024

This article shows you how to add controls to a map, including how to create a map with
all controls and a style picker.

Add zoom control


A zoom control adds buttons for zooming the map in and out. The following code
sample creates an instance of the ZoomControl class, and adds it the bottom-right
corner of the map.

JavaScript

//Construct a zoom control and add it to the map.


map.controls.add(new atlas.control.ZoomControl(), {
position: 'bottom-right'
});

Add pitch control


A pitch control adds buttons for tilting the pitch to map relative to the horizon. The
following code sample creates an instance of the PitchControl class. It adds the
PitchControl to top-right corner of the map.

JavaScript

//Construct a pitch control and add it to the map.


map.controls.add(new atlas.control.PitchControl(), {
position: 'top-right'
});

Add compass control


A compass control adds a button for rotating the map. The following code sample
creates an instance of the CompassControl class and adds it the bottom-left corner of
the map.

JavaScript
//Construct a compass control and add it to the map.
map.controls.add(new atlas.control.CompassControl(), {
position: 'bottom-left'
});

Add scale control


A scale control adds a scale bar to the map. The following code sample creates an
instance of the ScaleControl class and adds it to the bottom-left corner of the map.

JavaScript

//Construct a scale control and add it to the map.


map.controls.add(new atlas.control.ScaleControl(), {
position: 'bottom-left'
});

Add fullscreen control


A fullscreen control adds a button to toggle the map or specified HTML element
between fullscreen and normal view. The following code sample creates an instance of
the FullscreenControl class and adds it to the top-right corner of the map.

JavaScript

//Construct a fullscreen control and add it to the map.


map.controls.add(new atlas.control.FullscreenControl(), {
position: 'top-right'
});

A Map with all controls


Multiple controls can be put into an array and added to the map all at once and
positioned in the same area of the map to simplify development. The following code
snippet adds the standard navigation controls to the map using this approach.

JavaScript

map.controls.add(
[
new atlas.control.ZoomControl(),
new atlas.control.PitchControl(),
new atlas.control.CompassControl(),
new atlas.control.StyleControl(),
new atlas.control.FullscreenControl(),
new atlas.control.ScaleControl(),
],
{
position: 'top-right',
}
);

The following image shows a map with the zoom, pitch, compass, style, fullscreen, and
scale controls in the top-right corner of the map. Notice how they automatically stack.
The order of the control objects in the script dictates the order in which they appear on
the map. To change the order of the controls on the map, you can change their order in
the array.

The style picker control is defined by the StyleControl class. For more information on
using the style picker control, see choose a map style.

Customize controls
The Navigation Control Options sample is a tool to test out the various options for
customizing the controls. For the source code for this sample, see Navigation Control
Options source code .

The Fullscreen Control Options sample provides a tool to test out the options for
customizing the fullscreen control. For the source code for this sample, see Fullscreen
Control Options source code .

If you want to create customized navigation controls, create a class that extends from
the atlas.Control class or create an HTML element and position it above the map div.
Have this UI control call the maps setCamera function to move the map.

Next steps
Learn more about the classes and methods used in this article:

ZoomControl

CompassControl

PitchControl

StyleControl

ScaleControl

FullscreenControl

See the following articles for full code:

Add a pin

Add a popup

Add a line layer

Add a polygon layer

Add a bubble layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Create a data source
Article • 06/26/2023

The Azure Maps Web SDK stores data in data sources. Using data sources optimizes the
data operations for querying and rendering. Currently there are two types of data
sources:

GeoJSON source: Manages raw location data in GeoJSON format locally. Good for
small to medium data sets (upwards of hundreds of thousands of shapes).
Vector tile source: Loads data formatted as vector tiles for the current map view,
based on the maps tiling system. Ideal for large to massive data sets (millions or
billions of shapes).

GeoJSON data source


A GeoJSON based data source load and store data locally using the DataSource class.
GeoJSON data can be manually created or created using the helper classes in the
atlas.data namespace. The DataSource class provides functions to import local or remote
GeoJSON files. Remote GeoJSON files must be hosted on a CORs enabled endpoint. The
DataSource class provides functionality for clustering point data. And, data can easily be

added, removed, and updated with the DataSource class. The following code shows how
GeoJSON data can be created in Azure Maps.

JavaScript

//Create raw GeoJSON object.


var rawGeoJson = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-100, 45]
},
"properties": {
"custom-property": "value"
}
};

//Create GeoJSON using helper classes (less error prone and less typing).
var geoJsonClass = new atlas.data.Feature(new atlas.data.Point([-100, 45]),
{
"custom-property": "value"
});
Once created, data sources can be added to the map through the map.sources property,
which is a SourceManager. The following code shows how to create a DataSource and
add it to the map.

JavaScript

//Create a data source and add it to the map.


var source = new atlas.source.DataSource();
map.sources.add(source);

The following code shows the different ways GeoJSON data can be added to a
DataSource .

JavaScript

//GeoJsonData in the following code can be a single or array of GeoJSON


features or geometries, a GeoJSON feature colleciton, or a single or array
of atlas.Shape objects.

//Add geoJSON object to data source.


source.add(geoJsonData);

//Load geoJSON data from URL. URL should be on a CORs enabled endpoint.
source.importDataFromUrl(geoJsonUrl);

//Overwrite all data in data source.


source.setShapes(geoJsonData);

 Tip

Lets say you want to overwrite all data in a DataSource . If you make calls to the
clear then add functions, the map might re-render twice, which might cause a bit

of a delay. Instead use the setShapes function, which will remove and replace all
data in the data source and only trigger a single re-render of the map.

Vector tile source


A vector tile source describes how to access a vector tile layer. Use the VectorTileSource
class to instantiate a vector tile source. Vector tile layers are similar to tile layers, but
they aren't the same. A tile layer is a raster image. Vector tile layers are a compressed
file, in PBF format. This compressed file contains vector map data, and one or more
layers. The file can be rendered and styled on the client, based on the style of each layer.
The data in a vector tile contain geographic features in the form of points, lines, and
polygons. There are several advantages of using vector tile layers instead of raster tile
layers:

A file size of a vector tile is typically much smaller than an equivalent raster tile. As
such, less bandwidth is used. It means lower latency, a faster map, and a better
user experience.
Since vector tiles are rendered on the client, they adapt to the resolution of the
device they're being displayed on. As a result, the rendered maps appear more well
defined, with crystal clear labels.
Changing the style of the data in the vector maps doesn't require downloading the
data again, since the new style can be applied on the client. In contrast, changing
the style of a raster tile layer typically requires loading tiles from the server then
applying the new style.
Since the data is delivered in vector form, there's less server-side processing
required to prepare the data. As a result, the newer data can be made available
faster.

Azure Maps adheres to the Mapbox Vector Tile Specification , an open standard. Azure
Maps provides the following vector tiles services as part of the platform:

Road tiles
Traffic incidents
Traffic flow
Azure Maps Creator also allows custom vector tiles to be created and accessed
through the Render V2-Get Map Tile API

 Tip

When using vector or raster image tiles from the Azure Maps render service with
the web SDK, you can replace atlas.microsoft.com with the placeholder
{azMapsDomain} . This placeholder will be replaced with the same domain used by
the map and will automatically append the same authentication details as well. This
greatly simplifies authentication with the render service when using Azure Active
Directory authentication.

To display data from a vector tile source on the map, connect the source to one of the
data rendering layers. All layers that use a vector source must specify a sourceLayer
value in the options. The following code loads the Azure Maps traffic flow vector tile
service as a vector tile source, then displays it on a map using a line layer. This vector tile
source has a single set of data in the source layer called "Traffic flow". The line data in
this data set has a property called traffic_level that is used in this code to select the
color and scale the size of lines.

JavaScript

//Create a vector tile source and add it to the map.


var source = new atlas.source.VectorTileSource(null, {
tiles: ['https://{azMapsDomain}/traffic/flow/tile/pbf?api-
version=1.0&style=relative&zoom={z}&x={x}&y={y}'],
maxZoom: 22
});
map.sources.add(source);

//Create a layer for traffic flow lines.


var flowLayer = new atlas.layer.LineLayer(source, null, {
//The name of the data layer within the data source to pass into this
rendering layer.
sourceLayer: 'Traffic flow',

//Color the roads based on the traffic_level property.


strokeColor: [
'interpolate',
['linear'],
['get', 'traffic_level'],
0, 'red',
0.33, 'orange',
0.66, 'green'
],

//Scale the width of roads based on the traffic_level property.


strokeWidth: [
'interpolate',
['linear'],
['get', 'traffic_level'],
0, 6,
1, 1
]
});

//Add the traffic flow layer below the labels to make the map clearer.
map.layers.add(flowLayer, 'labels');

For a complete working sample of how to display data from a vector tile source on the
map, see Vector tile line layer in the Azure Maps Samples . For the source code for
this sample, see Vector tile line layer sample code .
Connecting a data source to a layer
Data is rendered on the map using rendering layers. One or more rendering layers can
reference a single data source. The following rendering layers require a data source:

Bubble layer - renders point data as scaled circles on the map.


Symbol layer- renders point data as icons or text.
Heat map layer - renders point data as a density heat map.
Line layer - render a line and or render the outline of polygons.
Polygon layer - fills the area of a polygon with a solid color or image pattern.

The following code shows how to create a data source, add it to the map, and connect it
to a bubble layer. And then, import GeoJSON point data from a remote location into the
data source.

JavaScript

//Create a data source and add it to the map.


var source = new atlas.source.DataSource();
map.sources.add(source);

//Create a layer that defines how to render points in the data source and
add it to the map.
map.layers.add(new atlas.layer.BubbleLayer(source));

//Load the earthquake data.


source.importDataFromUrl('https://earthquake.usgs.gov/earthquakes/feed/v1.0/
summary/significant_month.geojson');
There are other rendering layers that don't connect to these data sources, but they
directly load the data for rendering.

Image layer - overlays a single image on top of the map and binds its corners to a
set of specified coordinates.
Tile layer - superimposes a raster tile layer on top of the map.

One data source with multiple layers


Multiple layers can be connected to a single data source. There are many different
scenarios in which this option is useful. For example, consider the scenario in which a
user draws a polygon. We should render and fill the polygon area as the user adds
points to the map. Adding a styled line to outline the polygon makes it easier see the
edges of the polygon, as the user draws. To conveniently edit an individual position in
the polygon, we may add a handle, like a pin or a marker, above each position.

In most mapping platforms, you would need a polygon object, a line object, and a pin
for each position in the polygon. As the polygon is modified, you would need to
manually update the line and pins, which can quickly become complex.

With Azure Maps, all you need is a single polygon in a data source as shown in the
following code.

JavaScript

//Create a data source and add it to the map.


var source = new atlas.source.DataSource();
map.sources.add(source);

//Create a polygon and add it to the data source.


source.add(new atlas.data.Feature(
new atlas.data.Polygon([[[/* Coordinates for polygon */]]]));
//Create a polygon layer to render the filled in area of the polygon.
var polygonLayer = new atlas.layer.PolygonLayer(source, 'myPolygonLayer', {
fillColor: 'rgba(255,165,0,0.2)'
});

//Create a line layer for greater control of rendering the outline of the
polygon.
var lineLayer = new atlas.layer.LineLayer(source, 'myLineLayer', {
strokeColor: 'orange',
strokeWidth: 2
});

//Create a bubble layer to render the vertices of the polygon as scaled


circles.
var bubbleLayer = new atlas.layer.BubbleLayer(source, 'myBubbleLayer', {
color: 'orange',
radius: 5,
strokeColor: 'white',
strokeWidth: 2
});

//Add all layers to the map.


map.layers.add([polygonLayer, lineLayer, bubbleLayer]);

 Tip

When adding layers to the map using the map.layers.add function, the ID or
instance of an existing layer can be passed in as a second parameter. This would
tell that map to insert the new layer being added below the existing layer. In
addition to passing in a layer ID this method also supports the following values.

"labels" - Inserts the new layer below the map label layers.

"transit" - Inserts the new layer below the map road and transit layers.

Next steps
Learn more about the classes and methods used in this article:

DataSource

DataSourceOptions

VectorTileSource

VectorTileSourceOptions
See the following articles for more code samples to add to your maps:

Add a popup

Use data-driven style expressions

Add a symbol layer

Add a bubble layer

Add a line layer

Add a polygon layer

Add a heat map

Code samples
Add a symbol layer to a map
Article • 11/21/2024

Connect a symbol to a data source, and use it to render an icon or a text at a given
point.

Symbol layers are rendered using WebGL. Use a symbol layer to render large collections
of points on the map. Compared to HTML marker, the symbol layer renders a large
number of point data on the map, with better performance. However, the symbol layer
doesn't support traditional CSS and HTML elements for styling.

 Tip

Symbol layers by default will render the coordinates of all geometries in a data
source. To limit the layer such that it only renders point geometry features set the
filter property of the layer to ['==', ['geometry-type'], 'Point'] or ['any',
['==', ['geometry-type'], 'Point'], ['==', ['geometry-type'], 'MultiPoint']] if

you want, you can include MultiPoint features as well.

The maps image sprite manager loads custom images used by the symbol layer. It
supports the following image formats:

JPEG
PNG
SVG
BMP
GIF (no animations)

Add a symbol layer


Before you can add a symbol layer to the map, you need to take a couple of steps. First,
create a data source, and add it to the map. Create a symbol layer. Then, pass in the
data source to the symbol layer, to retrieve the data from the data source. Finally, add
data into the data source, so that there's something to be rendered.

The following code demonstrates what should be added to the map after it has loaded.
This sample renders a single point on the map using a symbol layer.

JavaScript
//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

//Create a symbol layer to render icons and/or text at points on the map.
var layer = new atlas.layer.SymbolLayer(dataSource);

//Add the layer to the map.


map.layers.add(layer);

//Create a point and add it to the data source.


dataSource.add(new atlas.data.Point([0, 0]));

There are four different types of point data that can be added to the map:

GeoJSON Point geometry - This object only contains a coordinate of a point and
nothing else. The atlas.data.Point helper class can be used to easily create these
objects.
GeoJSON MultiPoint geometry - This object contains the coordinates of multiple
points and nothing else. The atlas.data.MultiPoint helper class can be used to
easily create these objects.
GeoJSON Feature - This object consists of any GeoJSON geometry and a set of
properties that contain metadata associated to the geometry. The
atlas.data.Feature helper class can be used to easily create these objects.
atlas.Shape class is similar to the GeoJSON feature. Both consist of a GeoJSON

geometry and a set of properties that contain metadata associated to the


geometry. If a GeoJSON object is added to a data source, it can easily be rendered
in a layer. However, if the coordinates property of that GeoJSON object is updated,
the data source and map don't change. That's because there's no mechanism in
the JSON object to trigger an update. The shape class provides functions for
updating the data it contains. When a change is made, the data source and map
are automatically notified and updated.

The following code sample creates a GeoJSON Point geometry and passes it into the
atlas.Shape class to make it easy to update. The center of the map is initially used to

render a symbol. A click event is added to the map such that when it fires, the
coordinates of the mouse are used with the shapes setCoordinates function. The mouse
coordinates are recorded at the time of the click event. Then, the setCoordinates
updates the location of the symbol on the map.

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-122.33, 47.64],
zoom: 13,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

/*Create a data source and add it to the map*/


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
var point = new atlas.Shape(new atlas.data.Point([-122.33, 47.64]));
//Add the symbol to the data source.
dataSource.add([point]);

/* Gets co-ordinates of clicked location*/


map.events.add('click', function(e){
/* Update the position of the point feature to where the user
clicked on the map. */
point.setCoordinates(e.position);
});

//Create a symbol layer using the data source and add it to the map
map.layers.add(new atlas.layer.SymbolLayer(dataSource, null));
});
}
 Tip

By default, symbol layers optimize the rendering of symbols by hiding symbols that
overlap. As you zoom in, the hidden symbols become visible. To disable this feature
and render all symbols at all times, set the allowOverlap property of the
iconOptions options to true .

Add a custom icon to a symbol layer


Symbol layers are rendered using WebGL. As such all resources, such as icon images,
must be loaded into the WebGL context. This sample shows how to add a custom icon
to the map resources. This icon is then used to render point data with a custom symbol
on the map. The textField property of the symbol layer requires an expression to be
specified. In this case, we want to render the temperature property. Since temperature is
a number, it needs to be converted to a string. Additionally we want to append "°F" to it.
An expression can be used to do this concatenation; ['concat', ['to-string', ['get',
'temperature']], '°F'] .

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-73.985708, 40.75773],
zoom: 12,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

map.events.add('ready', function () {

//Load the custom image icon into the map resources.


map.imageSprite.add('my-custom-icon',
'/images/icons/showers.png').then(function () {

//Create a data source and add it to the map.


var datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a point feature and add it to the data source.


datasource.add(new atlas.data.Feature(new
atlas.data.Point([-73.985708, 40.75773]), {
temperature: 64
}));

//Add a layer for rendering point data as symbols.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
//Pass in the id of the custom icon that was loaded into the map
resources.
image: 'my-custom-icon',

//Optionally scale the size of the icon.


size: 0.5
},
textOptions: {
//Convert the temperature property of each feature into a string
and concatenate "°F".
textField: ['concat', ['to-string', ['get', 'temperature']],
'°F'],

//Offset the text so that it appears on top of the icon.


offset: [0, -2]
}
}));
});
});
}

7 Note

For a copy of the image file used in the above sample, see showers.png in
GitHub.
 Tip

The Azure Maps web SDK provides several customizable image templates you can
use with the symbol layer. For more information, see the How to use image
templates document.

Customize a symbol layer


The symbol layer has many styling options available. The Symbol Layer Options
sample shows how the different options of the symbol layer that affects rendering. For
the source code for this sample, see Symbol Layer Options source code .

 Tip

When you want to render only text with a symbol layer, you can hide the icon by
setting the image property of the icon options to 'none' .

Next steps
Learn more about the classes and methods used in this article:

SymbolLayer

SymbolLayerOptions
IconOptions

TextOptions

See the following articles for more code samples to add to your maps:

Create a data source

Add a popup

Use data-driven style expressions

How to use image templates

Add a line layer

Add a polygon layer

Add a bubble layer

Add HTML Makers

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a bubble layer to a map
Article • 08/27/2024

This article shows you how to render point data from a data source as a bubble layer on
a map. Bubble layers render points as circles on the map with a fixed pixel radius.

 Tip

Bubble layers by default will render the coordinates of all geometries in a data
source. To limit the layer such that it only renders point geometry features set the
filter property of the layer to ['==', ['geometry-type'], 'Point'] or ['any',

['==', ['geometry-type'], 'Point'], ['==', ['geometry-type'], 'MultiPoint']] if

you want to include MultiPoint features as well.

Add a bubble layer


The following code loads an array of points into a data source. Then, it connects the
data points are to a bubble layer. The bubble layer renders each bubble with a radius of
six pixels and a stroke width of three pixels.

JavaScript

/*Ensure that the map is fully loaded*/


map.events.add("load", function () {

/*Add point locations*/


var points = [
new atlas.data.Point([-73.985708, 40.75773]),
new atlas.data.Point([-73.985600, 40.76542]),
new atlas.data.Point([-73.985550, 40.77900]),
new atlas.data.Point([-73.975550, 40.74859]),
new atlas.data.Point([-73.968900, 40.78859])]

/*Create a data source and add it to the map*/


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
/*Add the points to the data source*/
dataSource.add(points);

//Create a bubble layer to render the filled in area of the circle, and
add it to the map.*/
map.layers.add(new atlas.layer.BubbleLayer(dataSource, null, {
radius: 6,
strokeColor: "LightSteelBlue",
strokeWidth: 3,
color: "DodgerBlue",
blur: 0.5
}));
});

Show labels with a bubble layer


This code shows you how to use a bubble layer to render a point on the map and a
symbol layer to render a label. To hide the icon of the symbol layer, set the image
property of the icon options to none .

JavaScript

//Create an instance of the map control and set some options.


function InitMap() {

var map = new atlas.Map('myMap', {


center: [-122.336641, 47.627631],
zoom: 16,
view: "Auto",
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

/*Ensure that the map is fully loaded*/


map.events.add("load", function () {

/*Create point object*/


var point = new atlas.data.Point([-122.336641,47.627631]);
/*Create a data source and add it to the map*/
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
dataSource.add(point);

map.layers.add(new atlas.layer.BubbleLayer(dataSource, null, {


radius: 5,
strokeColor: "#4288f7",
strokeWidth: 6,
color: "white"
}));

//Add a layer for rendering point data.


map.layers.add(new atlas.layer.SymbolLayer(dataSource, null, {
iconOptions: {
//Hide the icon image.
image: "none"
},

textOptions: {
textField: "Museum of History & Industry (MOHAI)",
color: "#005995",
offset: [0, -2.2]
},
}));
});
}

Customize a bubble layer


The Bubble layer only has a few styling options. Use the Bubble Layer Options sample
to try them out. For the source code for this sample, see Bubble Layer Options source
code .

Next steps
Learn more about the classes and methods used in this article:

BubbleLayer

BubbleLayerOptions

See the following articles for more code samples to add to your maps:

Create a data source

Add a symbol layer

Use data-driven style expressions

Code samples

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a popup to the map
Article • 10/22/2023

This article shows you how to add a popup to a point on a map.

Understand the code


The following code adds a point feature with name and description properties to the
map using a symbol layer. An instance of the Popup class is created but not displayed.
Mouse events are added to the symbol layer to trigger opening and closing the popup.
When the marker symbol is hovered, the popup's position property is updated with
position of the marker, and the content option is updated with some HTML that wraps
the name and description properties of the point feature being hovered. The popup is
then displayed on the map using its open function.

JavaScript

//Define an HTML template for a custom popup content laypout.


var popupTemplate = '<div class="customInfobox"><div class="name">{name}
</div>{description}</div>';

//Create a data source and add it to the map.


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

dataSource.add(new atlas.data.Feature(new atlas.data.Point([-122.1333,


47.63]), {
name: 'Microsoft Building 41',
description: '15571 NE 31st St, Redmond, WA 98052'
}));

//Create a layer to render point data.


var symbolLayer = new atlas.layer.SymbolLayer(dataSource);

//Add the polygon and line the symbol layer to the map.
map.layers.add(symbolLayer);

//Create a popup but leave it closed so we can update it and display it


later.
popup = new atlas.Popup({
pixelOffset: [0, -18],
closeButton: false
});

//Add a hover event to the symbol layer.


map.events.add('mouseover', symbolLayer, function (e) {
//Make sure that the point exists.
if (e.shapes && e.shapes.length > 0) {
var content, coordinate;
var properties = e.shapes[0].getProperties();
content = popupTemplate.replace(/{name}/g,
properties.name).replace(/{description}/g, properties.description);
coordinate = e.shapes[0].getCoordinates();

popup.setOptions({
//Update the content of the popup.
content: content,

//Update the popup's position with the symbol's coordinate.


position: coordinate

});
//Open the popup.
popup.open(map);
}
});

map.events.add('mouseleave', symbolLayer, function (){


popup.close();
});

Reusing a popup with multiple points


There are cases in which the best approach is to create one popup and reuse it. For
example, you might have a large number of points and want to show only one popup at
a time. By reusing the popup, the number of DOM elements created by the application
is greatly reduced, which can provide better performance. The following sample creates
3-point features. If you select on any of them, a popup is displayed with the content for
that point feature.

For a fully functional sample that shows how to create one popup and reuse it rather
than creating a popup for each point feature, see Reusing Popup with Multiple Pins in
the Azure Maps Samples . For the source code for this sample, see Reusing Popup with
Multiple Pins source code .

Customizing a popup
By default, the popup has a white background, a pointer arrow on the bottom, and a
close button in the top-right corner. The following sample changes the background
color to black using the fillColor option of the popup. The close button is removed by
setting the CloseButton option to false. The HTML content of the popup uses padded of
10 pixels from the edges of the popup. The text is made white, so it shows up nicely on
the black background.

For a fully functional sample that shows how to customize the look of a popup, see
Customize a popup in the Azure Maps Samples . For the source code for this
sample, see Customize a popup source code .


Add popup templates to the map
Popup templates make it easy to create data driven layouts for popups. The following
sections demonstrate the use of various popup templates to generate formatted
content using properties of features.

7 Note

By default, all content rendered use the popup template will be sandboxed inside
of an iframe as a security feature. However, there are limitations:

All scripts, forms, pointer lock and top navigation functionality is disabled.
Links are allowed to open up in a new tab when clicked.
Older browsers that don't support the srcdoc parameter on iframes will be
limited to rendering a small amount of content.

If you trust the data being loaded into the popups and potentially want these
scripts loaded into popups be able to access your application, you can disable this
by setting the popup templates sandboxContent option to false.

String template
The String template replaces placeholders with values of the feature properties. The
properties of the feature don't have to be assigned a value of type String. For example,
value1 holds an integer. These values are then passed to the content property of the
popupTemplate .

The numberFormat option specifies the format of the number to display. If the
numberFormat isn't specified, then the code uses the popup templates date format. The
numberFormat option formats numbers using the Number.toLocaleString function. To
format large numbers, consider using the numberFormat option with functions from
NumberFormat.format . For instance, the code following snippet uses
maximumFractionDigits to limit the number of fraction digits to two.

7 Note

There's only one way in which the String template can render images. First, the
String template needs to have an image tag in it. The value being passed to the
image tag should be a URL to an image. Then, the String template needs to have
isImage set to true in the HyperLinkFormatOptions . The isImage option specifies
that the hyperlink is for an image, and the hyperlink will be loaded into an image
tag. When the hyperlink is clicked, the image will open.

JavaScript

var templateOptions = {
content: 'This template uses a string template with placeholders.<br/>
<br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array
value [2] = {arrayValue/2}',
numberFormat: {
maximumFractionDigits: 2
}
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {


title: 'Template 1 - String template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6]
});

var popup = new atlas.Popup({


content: atlas.PopupTemplate.applyTemplate(feature.properties,
templateOptions),
position: feature.geometry.coordinates
});

PropertyInfo template
The PropertyInfo template displays available properties of the feature. The label option
specifies the text to display to the user. If label isn't specified, then the hyperlink is
displayed. And, if the hyperlink is an image, the value assigned to the "alt" tag is
displayed. The dateFormat specifies the format of the date, and if the date format isn't
specified, then the date renders as a string. The hyperlinkFormat option renders
clickable links, similarly, the email option can be used to render clickable email
addresses.

Before the PropertyInfo template display the properties to the end user, it recursively
checks that the properties are indeed defined for that feature. It also ignores displaying
style and title properties. For example, it doesn't display color , size , anchor ,
strokeOpacity , and visibility . So, once property path checking is complete in the

back-end, the PropertyInfo template shows the content in a table format.

JavaScript
var templateOptions = {
content: [
{
propertyPath: 'createDate',
label: 'Created Date'
},
{
propertyPath: 'dateNumber',
label: 'Formatted date from number',
dateFormat: {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC',
timeZoneName: 'short'
}
},
{
propertyPath: 'url',
label: 'Code samples',
hideLabel: true,
hyperlinkFormat: {
lable: 'Go to code samples!',
target: '_blank'
}
},
{
propertyPath: 'email',
label: 'Email us',
hideLabel: true,
hyperlinkFormat: {
target: '_blank',
scheme: 'mailto:'
}
}
]
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {


title: 'Template 2 - PropertyInfo',
createDate: new Date(),
dateNumber: 1569880860542,
url: 'https://samples.azuremaps.com/',
email: 'info@microsoft.com'
}),

var popup = new atlas.Popup({


content: atlas.PopupTemplate.applyTemplate(feature.properties,
templateOptions),
position: feature.geometry.coordinates
});
Multiple content templates
A feature might also display content using a combination of the String template and the
PropertyInfo template. In this case, the String template renders placeholders values on a
white background. And, the PropertyInfo template renders a full width image inside a
table. The properties in this sample are similar to the properties we explained in the
previous samples.

JavaScript

var templateOptions = {
content: [
'This template has two pieces of content; a string template with
placeholders and a array of property info which renders a full width image.
<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> -
Array value [2] = {arrayValue/2}',
[{
propertyPath: 'imageLink',
label: 'Image',
hideImageLabel: true,
hyperlinkFormat: {
isImage: true
}
}]
],
numberFormat: {
maximumFractionDigits: 2
}
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {


title: 'Template 3 - Multiple content template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6],
imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg'
});

var popup = new atlas.Popup({


content: atlas.PopupTemplate.applyTemplate(feature.properties,
templateOptions),
position: feature.geometry.coordinates
});

Points without a defined template


When the Popup template isn't defined to be a String template, a PropertyInfo template,
or a combination of both, then it uses the default settings. When the title and
description are the only assigned properties, the popup template shows a white

background, a close button in the top-right corner. And, on small and medium screens,
it shows an arrow at the bottom. The default settings show inside a table for all
properties other than the title and the description . Even when falling back to the
default settings, the popup template can still be manipulated programmatically. For
example, users can turn off hyperlink detection and the default settings would still apply
to other properties.

Once running, you can select the points on the map to see the popup. There's a point
on the map for each of the following popup templates: String template, PropertyInfo
template, and Multiple content template. There are also three points to show how
templates render using the defaulting settings.

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
zoom: 2,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function() {
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add sample data.


datasource.add([
new atlas.data.Feature(new atlas.data.Point([-20, 20]), {
title: 'No template - title/description',
description: 'This point doesn\'t have a template defined, fallback
to title and description properties.'
}),

new atlas.data.Feature(new atlas.data.Point([20, 20]), {


title: 'No template - property table',
message: 'This point doesn\'t have a template defined, fallback to
title and table of properties.',
randomValue: 10,
url: 'https://samples.azuremaps.com/',
imageLink:
'https://azuremapscodesamples.azurewebsites.net/common/images/Pike_Market.jp
g',
email: 'info@microsoft.com'
}),

new atlas.data.Feature(new atlas.data.Point([40, 0]), {


title: 'No template - hyperlink detection disabled',
message: 'This point doesn\'t have a template defined, fallback to
title and table of properties.',
randomValue: 10,
url: 'https://samples.azuremaps.com/',
email: 'info@microsoft.com',
popupTemplate: {
detectHyperlinks: false
}
}),

new atlas.data.Feature(new atlas.data.Point([-20, -20]), {


title: 'Template 1 - String template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6],
popupTemplate: {
content: 'This template uses a string template with placeholders.
<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> -
Array value [2] = {arrayValue/2}',
numberFormat: {
maximumFractionDigits: 2
}
}
}),

new atlas.data.Feature(new atlas.data.Point([20, -20]), {


title: 'Template 2 - PropertyInfo',
createDate: new Date(),
dateNumber: 1569880860542,
url: 'https://samples.azuremaps.com/',
email: 'info@microsoft.com',
popupTemplate: {
content: [{
propertyPath: 'createDate',
label: 'Created Date'
},
{
propertyPath: 'dateNumber',
label: 'Formatted date from number',
dateFormat: {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC',
timeZoneName: 'short'
}
},
{
propertyPath: 'url',
label: 'Code samples',
hideLabel: true,
hyperlinkFormat: {
lable: 'Go to code samples!',
target: '_blank'
}
},
{
propertyPath: 'email',
label: 'Email us',
hideLabel: true,
hyperlinkFormat: {
target: '_blank',
scheme: 'mailto:'
}
}
]
}
}),

new atlas.data.Feature(new atlas.data.Point([0, 0]), {


title: 'Template 3 - Multiple content template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6],
imageLink:
'https://azuremapscodesamples.azurewebsites.net/common/images/Pike_Market.jp
g',
popupTemplate: {
content: [
'This template has two pieces of content; a string template with
placeholders and a array of property info which renders a full width image.
<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> -
Array value [2] = {arrayValue/2}',
[{
propertyPath: 'imageLink',
label: 'Image',
hideImageLabel: true,
hyperlinkFormat: {
isImage: true
}
}]
],
numberFormat: {
maximumFractionDigits: 2
}
}
}),
]);

//Create a layer that defines how to render the points on the map.
var layer = new atlas.layer.BubbleLayer(datasource);
map.layers.add(layer);

//Create a popup but leave it closed so we can update it and display it


later.
popup = new atlas.Popup();

//Add a click event to the layer.


map.events.add('click', layer, showPopup);
});

function showPopup(e) {
if (e.shapes && e.shapes.length > 0) {
var properties = e.shapes[0].getProperties();

popup.setOptions({
//Update the content of the popup.
content: atlas.PopupTemplate.applyTemplate(properties,
properties.popupTemplate),

//Update the position of the popup with the pins coordinate.


position: e.shapes[0].getCoordinates()
});

//Open the popup.


popup.open(map);
}
}
}


Reuse popup template
Similar to reusing a popup, you can reuse popup templates. This approach is useful
when you only want to show one popup template at a time, for multiple points. Reusing
popup templates reduces the number of DOM elements created by the application,
improving your applications performance. The following sample uses the same popup
template for three points. If you select on any of them, a popup is displayed with the
content for that point feature.

For a fully functional sample that shows hot to reuse a single popup template with
multiple features that share a common set of property fields, see Reuse a popup
template in the Azure Maps Samples . For the source code for this sample, see
Reuse a popup template source code .

Popup events
Popups can be opened, closed, and dragged. The popup class provides events to help
developers react to these events. The following sample highlights which events fire
when the user opens, closes, or drags the popup.

For a fully functional sample that shows how to add events to popups, see Popup
events in the Azure Maps Samples . For the source code for this sample, see Popup
events source code .

Next steps
Learn more about the classes and methods used in this article:

Popup

PopupOptions

PopupTemplate )

See the following great articles for full code samples:

Add a symbol layer

Add an HTML marker

Add a line layer

Add a polygon layer


Add HTML markers to the map
Article • 08/27/2024

This article shows you how to add a custom HTML such as an image file to the map as
an HTML Marker.

7 Note

HTML Markers do not connect to data sources. Instead position information is


added directly to the marker and the marker is added to the maps markers
property which is a HtmlMarkerManager.

) Important

Unlike most layers in the Azure Maps Web control which use WebGL for rendering,
HTML Markers use traditional DOM elements for rendering. As such, the more
HTML markers added to a page, the more DOM elements there are. Performance
can degrade after adding a few hundred HTML markers. For larger data sets
consider either clustering your data or using a Symbol or Bubble layer.

Add an HTML marker


The HtmlMarker class has a default style. You can customize the marker by setting the
color and text options of the marker. The default style of the HTML marker class is an
SVG template that has a {color} and {text} placeholder. Set the color and text
properties in the HTML marker options for a quick customization.

The following code creates an HTML marker, and sets the color property to DodgerBlue
and the text property to 10 . A popup is attached to the marker and click event is used
to toggle the visibility of the popup.

JavaScript

//Create an HTML marker and add it to the map.


var marker = new atlas.HtmlMarker({
color: 'DodgerBlue',
text: '10',
position: [0, 0],
popup: new atlas.Popup({
content: '<div style="padding:10px">Hello World</div>',
pixelOffset: [0, -30]
})
});

map.markers.add(marker);

//Add a click event to toggle the popup.


map.events.add('click',marker, () => {
marker.togglePopup();
});

For a complete working sample of how to add an HTML marker, see Simple HTML
Marker in the Azure Maps Samples . For the source code for this sample, see Simple
HTML Marker source code .

Create SVG templated HTML marker


The default htmlContent of an Html marker is an SVG template with place folders
{color} and {text} in it. You can create custom SVG strings and add these same

placeholders into your SVG such that setting the color and text options of the marker
update these placeholders in your SVG.

For a complete working sample of how to create a custom SVG template and use it with
the HtmlMarker class, see HTML Marker with Custom SVG Template in the Azure
Maps Samples . When running this sample, select the button in the upper left hand
side of the window labeled Update Marker Options to change the color and text
options from the SVG template used in the HtmlMarker. For the source code for this
sample, see HTML Marker with Custom SVG Template source code .

 Tip

The Azure Maps web SDK provides several SVG image templates that can be used
with HTML markers. For more information, see the How to use image templates
document.

Add a CSS styled HTML marker


One of the benefits of HTML markers is that there are many great customizations that
can be achieved using CSS. In the following sample, the content of the HtmlMarker
consists of HTML and CSS that create an animated pin that drops into place and pulses.

JavaScript

//Wait until the map resources are ready.


map.events.add('ready', function () {
//Create a HTML marker and add it to the map.
map.markers.add(new atlas.HtmlMarker({
htmlContent: "<div><div class='pin bounce'></div><div class='pulse'>
</div></div>",
position: [-0.1406, 51.5018],
pixelOffset: [5, -18]
}));
});

The CSS:
css

<style>
.pin {
width: 30px;
height: 30px;
border-radius: 50% 50% 50% 0;
background: #00cae9;
position: absolute;
transform: rotate(-45deg);
left: 50%;
top: 50%;
margin: -20px 0 0 -20px;
}

.pin:after {
content: "";
width: 14px;
height: 14px;
margin: 8px 0 0 8px;
background: #e6e6e6;
position: absolute;
border-radius: 50%;
}

.bounce {
animation-name: bounce;
animation-fill-mode: both;
animation-duration: 1s;
}

.pulse {
background: #d6d4d4;
border-radius: 50%;
height: 14px;
width: 14px;
position: absolute;
left: 50%;
top: 50%;
margin: 11px 0px 0px -12px;
transform: rotateX(55deg);
z-index: -2;
}

.pulse:after {
content: "";
border-radius: 50%;
height: 40px;
width: 40px;
position: absolute;
margin: -13px 0 0 -13px;
animation: pulsate 1s ease-out;
animation-iteration-count: infinite;
opacity: 0;
box-shadow: 0 0 1px 2px #00cae9;
animation-delay: 1.1s;
}

@keyframes pulsate {
0% {
transform: scale(0.1, 0.1);
opacity: 0;
}

50% {
opacity: 1;
}

100% {
transform: scale(1.2, 1.2);
opacity: 0;
}
}

@keyframes bounce {
0% {
opacity: 0;
transform: translateY(-2000px) rotate(-45deg);
}

60% {
opacity: 1;
transform: translateY(30px) rotate(-45deg);
}

80% {
transform: translateY(-10px) rotate(-45deg);
}

100% {
transform: translateY(0) rotate(-45deg);
}
}
</style>

For a complete working sample of how to use CSS and HTML to create a marker on the
map, see CSS Styled HTML Marker in the Azure Maps Samples . For the source code
for this sample, see CSS Styled HTML Marker source code .

Draggable HTML markers


This sample shows how to make an HTML marker draggable. HTML markers support
drag , dragstart , and dragend events.

For a complete working sample of how to use CSS and HTML to create a marker on the
map, see Draggable HTML Marker in the Azure Maps Samples . For the source code
for this sample, see Draggable HTML Marker source code .


Add mouse events to HTML markers
For a complete working sample of how to add mouse and drag events to an HTML
marker, see HTML Marker events in the Azure Maps Samples . For the source code
for this sample, see HTML Marker events source code .

Next steps
Learn more about the classes and methods used in this article:

HtmlMarker

HtmlMarkerOptions

HtmlMarkerManager

For more code examples to add to your maps, see the following articles:

How to use image templates

Add a symbol layer

Add a bubble layer


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a line layer to the map
Article • 08/28/2024

A line layer can be used to render LineString and MultiLineString features as paths or
routes on the map. A line layer can also be used to render the outline of Polygon and
MultiPolygon features. A data source is connected to a line layer to provide it with data

to render.

 Tip

Line layers by default will render the coordinates of polygons as well as lines in a
data source. To limit the layer such that it only renders LineString features set the
filter property of the layer to ['==', ['geometry-type'], 'LineString'] or
['any', ['==', ['geometry-type'], 'LineString'], ['==', ['geometry-type'],

'MultiLineString']] if you want to include MultiLineString features as well.

The following code shows how to create a line. Add the line to a data source, then
render it with a line layer using the LineLayer class.

JavaScript

//Create a data source and add it to the map.


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

//Create a line and add it to the data source.


dataSource.add(new atlas.data.LineString([[-73.972340, 40.743270],
[-74.004420, 40.756800]]));

//Create a line layer to render the line to the map.


map.layers.add(new atlas.layer.LineLayer(dataSource, null, {
strokeColor: 'blue',
strokeWidth: 5
}));

The following screenshot shows a sample of the above functionality.


Line layers can be styled using LineLayerOptions and Use data-driven style expressions.

Add symbols along a line


The following sample demonstrates how to add arrow icons along a line on the map.
When using a symbol layer, set the placement option to line . This option renders the
symbols along the line and rotates the icons (0 degrees = right).

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-122.135, 47.65],
zoom: 11,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

var datasource;

//Wait until the map resources are ready.


map.events.add('ready', function () {

//Load the custom image icon into the map resources.


map.imageSprite.add('arrow-icon', 'https://s3-us-west-
2.amazonaws.com/s.cdpn.io/1717245/purpleArrowRight.png').then(function () {
//Create a data source and add it to the map.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a line and add it to the data source.


datasource.add(new atlas.data.Feature(new atlas.data.LineString([
[-122.18822, 47.63208],
[-122.18204, 47.63196],
[-122.17243, 47.62976],
[-122.16419, 47.63023],
[-122.15852, 47.62942],
[-122.15183, 47.62988],
[-122.14256, 47.63451],
[-122.13483, 47.64041],
[-122.13466, 47.64422],
[-122.13844, 47.65440],
[-122.13277, 47.66515],
[-122.12779, 47.66712],
[-122.11595, 47.66712],
[-122.11063, 47.66735],
[-122.10668, 47.67035],
[-122.10565, 47.67498]
])));

//Add a layers for rendering data.


map.layers.add([
//Add a line layer for displaying the line.
new atlas.layer.LineLayer(datasource, null, {
strokeColor: 'DarkOrchid',
strokeWidth: 3
}),

//Add a symbol layer for rendering the arrow along the line.
new atlas.layer.SymbolLayer(datasource, null, {
//Specify how much space should be between the symbols in pixels.
lineSpacing: 100,

//Tell the symbol layer that the symbols are being rendered along
a line.
placement: 'line',
iconOptions: {
image: 'arrow-icon',
allowOverlap: true,
anchor: 'center',
size: 0.8
}
})
]);
});
});
}

This code creates a map that appears as follows:


 Tip

The Azure Maps web SDK provides several customizable image templates you can
use with the symbol layer. For more information, see the How to use image
templates document.

Add a stroke gradient to a line


You may apply a single stroke color to a line. You can also fill a line with a gradient of
colors to show transition from one line segment to the next line segment. For example,
line gradients can be used to represent changes over time and distance, or different
temperatures across a connected line of objects. In order to apply this feature to a line,
the data source must have the lineMetrics option set to true , and then a color
gradient expression can be passed to the strokeColor option of the line. The stroke
gradient expression has to reference the ['line-progress'] data expression that
exposes the calculated line metrics to the expression.

For a fully functional sample that shows how to apply a stroke gradient to a line on the
map, see Line with Stroke Gradient in the Azure Maps Samples . For the source code
for this sample, see Line with Stroke Gradient source code .
Customize a line layer
The Line layer has several styling options. For a fully functional sample that interactively
demonstrates the line options, see Line Layer Options in the Azure Maps Samples .
For the source code for this sample, see Line Layer Options source code .

Next steps
Learn more about the classes and methods used in this article:
LineLayer

LineLayerOptions

See the following articles for more code samples to add to your maps:

Create a data source

Add a popup

Use data-driven style expressions

How to use image templates

Add a polygon layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a polygon layer to the map
Article • 08/28/2024

This article shows you how to render the areas of Polygon and MultiPolygon feature
geometries on the map using a polygon layer. The Azure Maps Web SDK also supports
the creation of Circle geometries as defined in the extended GeoJSON schema. These
circles are transformed into polygons when rendered on the map. All feature geometries
can easily be updated when wrapped with the atlas.Shape class.

Use a polygon layer


When a polygon layer is connected to a data source and loaded on the map, it renders
the area with Polygon and MultiPolygon features. To create a polygon, add it to a data
source, and render it with a polygon layer using the PolygonLayer class.

The following sample code demonstrates creating a polygon layer that covers New York
City's Central Park with a red polygon.

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-73.97, 40.78],
zoom: 11,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

/*Create a data source and add it to the map*/


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

/*Create a rectangle*/
dataSource.add(new atlas.Shape(new atlas.data.Feature(
new atlas.data.Polygon([[
[-73.98235, 40.76799],
[-73.95785, 40.80044],
[-73.94928, 40.7968],
[-73.97317, 40.76437],
[-73.98235, 40.76799]
]])
)));

/*Create and add a polygon layer to render the polygon to the map*/
map.layers.add(new atlas.layer.PolygonLayer(dataSource, null,{
fillColor: "red",
fillOpacity: 0.7
}), 'labels')
});
}

Use a polygon and line layer together


A line layer is used to render the outline of polygons. The following code sample
renders a polygon like the previous example, but now adds a line layer. This line layer is
a second layer connected to the data source.

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-73.97, 40.78],
zoom: 11,
view: "Auto",
//Add authentication details for connecting to Azure Maps.
authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: 'subscriptionKey',
subscriptionKey: '{subscription key}'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

/*Create a data source and add it to the map*/


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

/*Create a rectangle*/
dataSource.add(new atlas.data.Polygon([[
[-73.98235, 40.76799],
[-73.95785, 40.80045],
[-73.94928, 40.7968],
[-73.97317, 40.76437],
[-73.98235, 40.76799]
]])
);

//Create a polygon layer to render the filled in area of the polygon.


var polygonLayer = new atlas.layer.PolygonLayer(dataSource,
'myPolygonLayer', {
fillColor: 'rgba(0, 200, 200, 0.5)'
});

//Create a line layer for greater control of rendering the outline of


the polygon.
var lineLayer = new atlas.layer.LineLayer(dataSource, 'myLineLayer', {
strokeColor: 'red',
strokeWidth: 2
});

/*Create and add a polygon layer to render the polygon to the map*/
map.layers.add([polygonLayer, lineLayer])
});
}

Fill a polygon with a pattern


In addition to filling a polygon with a color, you may use an image pattern to fill the
polygon. Load an image pattern into the maps image sprite resources and then
reference this image with the fillPattern property of the polygon layer.

For a fully functional sample that shows how to use an image template as a fill pattern in
a polygon layer, see Fill polygon with built-in icon template in the Azure Maps
Samples . For the source code for this sample, see Fill polygon with built-in icon
template source code .


 Tip

The Azure Maps web SDK provides several customizable image templates you can
use as fill patterns. For more information, see the How to use image templates
document.

Customize a polygon layer


The Polygon layer only has a few styling options. See the Polygon Layer Options
sample map in the Azure Maps Samples to try them out. For the source code for this
sample, see Polygon Layer Options source code .

Add a circle to the map


Azure Maps uses an extended version of the GeoJSON schema that provides a definition
for circles. A circle is rendered on the map by creating a Point feature. This Point has a
subType property with a value of "Circle" and a radius property with a number that

represents the radius in meters.

JavaScript

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.126986, 47.639754]
},
"properties": {
"subType": "Circle",
"radius": 100
}
}

The Azure Maps Web SDK converts these Point features into Polygon features. Then,
these features are rendered on the map using polygon and line layers as shown in the
following code sample.

JavaScript

function InitMap()
{
var map = new atlas.Map('myMap', {
center: [-73.985708, 40.75773],
zoom: 12,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function () {

/*Create a data source and add it to the map*/


var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

//Create a circle
dataSource.add(new atlas.data.Feature(new atlas.data.Point([-73.985708,
40.75773]),
{
subType: "Circle",
radius: 1000
}));

// Create a polygon layer to render the filled in area


// of the circle polygon, and add it to the map.
map.layers.add(new atlas.layer.PolygonLayer (dataSource, null, {
fillColor: 'rgba(0, 200, 200, 0.8)'
}));
});
}

Make a geometry easy to update


A Shape class wraps a Geometry or Feature and makes it easy to update and maintain
these features. To instantiate a shape variable, pass a geometry or a set of properties to
the shape constructor.

JavaScript

//Creating a shape by passing in a geometry and a object containing


properties.
var shape1 = new atlas.Shape(new atlas.data.Point[0,0], { myProperty: 1 });

//Creating a shape using a feature.


var shape2 = new atlas.Shape(new atlas.data.Feature(new
atlas.data.Point[0,0], { myProperty: 1 });

The Make a geometry easy to update sample shows how to wrap a circle GeoJSON
object with a shape class. As the value of the radius changes in the shape, the circle
renders automatically on the map. For the source code for this sample, see Make a
geometry easy to update source code .
Next steps
Learn more about the classes and methods used in this article:

Polygon

PolygonLayer

PolygonLayerOptions

For more code examples to add to your maps, see the following articles:

Create a data source

Add a popup

Use data-driven style expressions

How to use image templates

Add a line layer

More resources:

Azure Maps GeoJSON specification extension


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a polygon extrusion layer to the
map
Article • 08/28/2024

This article shows you how to use the polygon extrusion layer to render areas of
Polygon and MultiPolygon feature geometries as extruded shapes. The Azure Maps

Web SDK supports rendering of Circle geometries as defined in the extended GeoJSON
schema. These circles can be transformed into polygons when rendered on the map. All
feature geometries may be updated easily when wrapped with the atlas.Shape class.

Use a polygon extrusion layer


Connect the polygon extrusion layer to a data source. Then, loaded it on the map. The
polygon extrusion layer renders the areas of a Polygon and MultiPolygon features as
extruded shapes. The height and base properties of the polygon extrusion layer define
the base distance from the ground and height of the extruded shape in meters. The
following code shows how to create a polygon, add it to a data source, and render it
using the Polygon extrusion layer class.

7 Note

The base value defined in the polygon extrusion layer should be less than or equal
to that of the height .

JavaScript

var map, datasource, polygonLayer;

function InitMap()
{
map = new atlas.Map('myMap', {
center: [-73.985708, 40.75773],
zoom: 12,
//Pitch the map so that the extrusion of the polygons is visible.
pitch: 45,
view: 'Auto',

//Add authentication details for connecting to Azure Maps.


authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
},
styleDefinitionsVersion: "2023-01-01"
});

//Wait until the map resources are ready.


map.events.add('ready', function () {
/*Create a data source and add it to the map*/
datasource = new atlas.source.DataSource();
map.sources.add(datasource);

datasource.add(new atlas.data.Polygon([
[
[
-73.95838379859924,
40.80027995478159
],
[
-73.98154735565186,
40.76845986171129
],
[
-73.98124694824219,
40.767761062136955
],
[
-73.97361874580382,
40.76461637311633
],
[
-73.97306084632874,
40.76512830937617
],
[
-73.97259950637817,
40.76490890860481
],
[
-73.9494466781616,
40.79658450499243
],
[
-73.94966125488281,
40.79708807289436
],
[
-73.95781517028809,
40.80052360358227
],
[
-73.95838379859924,
40.80027995478159
]
]
]));
//Create and add a polygon extrusion layer to the map below the labels
so that they are still readable.
map.layers.add(new atlas.layer.PolygonExtrusionLayer(datasource, null, {
fillColor: "#fc0303",
fillOpacity: 0.7,
height: 500
}), "labels");
});
}

Add data driven polygons


A choropleth map can be rendered using the polygon extrusion layer. Set the height
and fillColor properties of the extrusion layer to the measurement of the statistical
variable in the Polygon and MultiPolygon feature geometries.

The Create a Choropleth Map sample shows an extruded choropleth map of the
United States based on the measurement of the population density by state. For the
source code for this sample, see Create a Choropleth Map source code .

Add a circle to the map


Azure Maps uses an extended version of the GeoJSON schema that provides a definition
for circles. An extruded circle can be rendered on the map by creating a point feature
with a subType property of Circle and a numbered Radius property representing the
radius in meters. For example:

JavaScript

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-105.203135, 39.664087]
},
"properties": {
"subType": "Circle",
"radius": 1000
}
}

The Azure Maps Web SDK converts these Point features into Polygon features under
the hood. These Point features can be rendered on the map using polygon extrusion
layer as shown in the following code sample.

JavaScript

var map, datasource;


function InitMap()
{
map = new atlas.Map('myMap', {
center: [-105.2, 39.7],
zoom: 10.5,
pitch: 60,
view: 'Auto',

//Add authentication details for connecting to Azure Maps.


authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
},
});

//Wait until the map resources are ready.


map.events.add('ready', function () {
/*Create a data source and add it to the map*/
datasource = new atlas.source.DataSource();
map.sources.add(datasource);

datasource.add(new atlas.data.Feature(new atlas.data.Point([-105.2,


39.7]), {
subType: "Circle",
radius: 1000
}));

/*Create and add a polygon Extrusion layer to render the extruded


polygon to the map*/
map.layers.add(new atlas.layer.PolygonExtrusionLayer(datasource, null, {
base: 5000,
fillColor: "#02fae1",
fillOpacity: 0.7,
height: 5500
}));
});
}
Customize a polygon extrusion layer
The Polygon Extrusion layer has several styling options. The Polygon Extrusion Layer
Options sample is a tool to try them out. For the source code for this sample, see
Polygon Extrusion Layer Options source code .

Next steps
Learn more about the classes and methods used in this article:
Polygon

polygon extrusion layer

More resources:

Azure Maps GeoJSON specification extension

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a heat map layer to a map
Article • 08/28/2024

Heat maps, also known as point density maps, are a type of data visualization. They're
used to represent the density of data using a range of colors and show the data "hot
spots" on a map. Heat maps are a great way to render datasets with large number of
points.

Rendering tens of thousands of points as symbols can cover most of the map area. This
case likely results in many symbols overlapping. Making it difficult to gain a better
understanding of the data. However, visualizing this same dataset as a heat map makes
it easy to see the density and the relative density of each data point.

You can use heat maps in many different scenarios, including:

Temperature data: Provides approximations for what the temperature is between


two data points.
Data for noise sensors: Shows not only the intensity of the noise where the sensor
is, but it can also provide insight into the dissipation over a distance. The noise
level at any one site might not be high. If the noise coverage area from multiple
sensors overlaps, it's possible that this overlapping area might experience higher
noise levels. As such, the overlapped area would be visible in the heat map.
GPS trace: Includes the speed as a weighted height map, where the intensity of
each data point is based on the speed. For example, this functionality provides a
way to see where a vehicle was speeding.

 Tip

Heat map layers by default render the coordinates of all geometries in a data
source. To limit the layer so that it only renders point geometry features, set the
filter property of the layer to ['==', ['geometry-type'], 'Point'] . If you want to

include MultiPoint features as well, set the filter property of the layer to ['any',
['==', ['geometry-type'], 'Point'], ['==', ['geometry-type'], 'MultiPoint']] .

https://learn.microsoft.com/Shows/Internet-of-Things-Show/Heat-Maps-and-Image-
Overlays-in-Azure-Maps/player?format=ny

Add a heat map layer


To render a data source of points as a heat map, pass your data source into an instance
of the HeatMapLayer class, and add it to the map.

In the following code, each heat point has a radius of 10 pixels at all zoom levels. To
ensure a better user experience, the heat map is below the label layer. The labels stay
clearly visible. The data in this sample is from the USGS Earthquake Hazards Program .
It is for significant earthquakes that have occurred in the last 30 days.

JavaScript

//Create a data source and add it to the map.


var datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Load a dataset of points, in this case earthquake data from the USGS.
datasource.importDataFromUrl('https://earthquake.usgs.gov/earthquakes/feed/v
1.0/summary/all_week.geojson');

//Create a heat map and add it to the map.


map.layers.add(new atlas.layer.HeatMapLayer(datasource, null, {
radius: 10,
opacity: 0.8
}), 'labels');

The Simple Heat Map Layer sample demonstrates how to create a simple heat map
from a data set of point features. For the source code for this sample, see Simple Heat
Map Layer source code .

Customize the heat map layer


The previous example customized the heat map by setting the radius and opacity
options. The heat map layer provides several options for customization, including:

radius : Defines a pixel radius in which to render each data point. You can set the

radius as a fixed number or as an expression. By using an expression, you can scale


the radius based on the zoom level, and represent a consistent spatial area on the
map (for example, a 5-mile radius).

color : Specifies how the heat map is colorized. A color gradient is a common

feature of heat maps. You can achieve the effect with an interpolate expression.
You can also use a step expression for colorizing the heat map, breaking up the
density visually into ranges that resemble a contour or radar style map. These color
palettes define the colors from the minimum to the maximum density value.

You specify color values for heat maps as an expression on the heatmap-density
value. The color of area where there's no data is defined at index 0 of the
"Interpolation" expression, or the default color of a "Stepped" expression. You can
use this value to define a background color. Often, this value is set to transparent,
or a semi-transparent black.

Here are examples of color expressions:

ノ Expand table

Interpolation color expression Stepped color expression

[ [
'interpolate', 'step',
['linear'], ['heatmap-density'],
['heatmap-density'], 'transparent',
0, 'transparent', 0.01, 'navy',
0.01, 'purple', 0.25, 'green',
0.5, '#fb00fb', 0.50, 'yellow',
1, '#00c3ff' 0.75, 'red'
] ]

opacity : Specifies how opaque or transparent the heat map layer is.

intensity : Applies a multiplier to the weight of each data point to increase the

overall intensity of the heatmap. It causes a difference in the weight of data points,
making it easier to visualize.

weight : By default, all data points have a weight of 1, and are weighted equally.

The weight option acts as a multiplier, and you can set it as a number or an
expression. If a number is set as the weight, it's the equivalence of placing each
data point on the map twice. For instance, if the weight is 2, then the density
doubles. Setting the weight option to a number renders the heat map in a similar
way to using the intensity option.

However, if you use an expression, the weight of each data point can be based on
the properties of each data point. For example, suppose each data point
represents an earthquake. The magnitude value has been an important metric for
each earthquake data point. Earthquakes happen all the time, but most have a low
magnitude, and aren't noticed. Use the magnitude value in an expression to assign
the weight to each data point. By using the magnitude value to assign the weight,
you get a better representation of the significance of earthquakes within the heat
map.

source and source-layer : Enable you to update the data source.

The Heat Map Layer Options sample shows how the different options of the heat map
layer that affects rendering. For the source code for this sample, see Heat Map Layer
Options source code .

Consistent zoomable heat map


By default, the radii of data points rendered in the heat map layer have a fixed pixel
radius for all zoom levels. As you zoom the map, the data aggregates together and the
heat map layer looks different.

Use a zoom expression to scale the radius for each zoom level, such that each data point
covers the same physical area of the map. This expression makes the heat map layer
look more static and consistent. Each zoom level of the map has twice as many pixels
vertically and horizontally as the previous zoom level.

Scaling the radius so that it doubles with each zoom level creates a heat map that looks
consistent on all zoom levels. To apply this scaling, use zoom with a base 2 exponential
interpolation expression, with the pixel radius set for the minimum zoom level and a

scaled radius for the maximum zoom level calculated as 2 * Math.pow(2, minZoom -
maxZoom) as shown in the following sample. Zoom the map to see how the heat map

scales with the zoom level.

The Consistent zoomable Heat Map sample shows how to create a heat map where
the radius of each data point covers the same physical area on the ground, creating a
more consistent user experience when zooming the map. The heat map in this sample
scales consistently between zoom levels 10 and 22. Each zoom level of the map has
twice as many pixels vertically and horizontally as the previous zoom level. Doubling the
radius with each zoom level creates a heat map that looks consistent across all zoom
levels. For the source code for this sample, see Consistent zoomable Heat Map source
code .

The zoom expression can only be used in step and interpolate expressions. The
following expression can be used to approximate a radius in meters. This expression
uses a placeholder radiusMeters , which you should replace with your desired radius.
This expression calculates the approximate pixel radius for a zoom level at the equator
for zoom levels 0 and 24, and uses an exponential interpolation expression to scale
between these values the same way the tiling system in the map works.

JSON
[
`'interpolate',
['exponential', 2],
['zoom'],
0, ['*', radiusMeters, 0.000012776039596366526],
24, [`'*', radiusMeters, 214.34637593279402]
]

 Tip

When you enable clustering on the data source, points that are close to one
another are grouped together as a clustered point. You can use the point count of
each cluster as the weight expression for the heat map. This can significantly reduce
the number of points to be rendered. The point count of a cluster is stored in a
point_count property of the point feature:

JavaScript

var layer = new atlas.layer.HeatMapLayer(datasource, null, {


weight: ['get', 'point_count']
});

If the clustering radius is only a few pixels, there would be a small visual difference
in the rendering. A larger radius groups more points into each cluster, and
improves the performance of the heatmap.

Next steps
Learn more about the classes and methods used in this article:

HeatMapLayer

HeatMapLayerOptions

For more code examples to add to your maps, see the following articles:

Create a data source

Use data-driven style expressions


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add an image layer to a map
Article • 08/28/2024

This article shows you how to overlay an image to a fixed set of coordinates. Here are a
few examples of different images types that can be overlaid on maps:

Images captured from drones


Building floorplans
Historical or other specialized map images
Blueprints of job sites
Weather radar images

 Tip

An ImageLayer is an easy way to overlay an image on a map. Note that browsers


might have difficulty loading a large image. In this case, consider breaking your
image up into tiles, and loading them into the map as a TileLayer.

The image layer supports the following image formats:

JPEG
PNG
BMP
GIF (no animations)

Add an image layer


The following code overlays an image of a map of Newark, New Jersey, from 1922 on
the map. An ImageLayer is created by passing a URL to an image, and coordinates for
the four corners in the format [Top Left Corner, Top Right Corner, Bottom Right
Corner, Bottom Left Corner] .

JavaScript

//Create an image layer and add it to the map.


map.layers.add(new atlas.layer.ImageLayer({
url: 'newark_nj_1922.jpg',
coordinates: [
[-74.22655, 40.773941], //Top Left Corner
[-74.12544, 40.773941], //Top Right Corner
[-74.12544, 40.712216], //Bottom Right Corner
[-74.22655, 40.712216] //Bottom Left Corner
]
}));

For a fully functional sample that shows how to overlay an image of a map of Newark
New Jersey from 1922 as an Image layer, see Simple Image Layer in the Azure Maps
Samples . For the source code for this sample, see Simple Image Layer source code .

Import a KML file as ground overlay


This sample demonstrates how to add KML ground overlay information as an image
layer on the map. KML ground overlays provide north, south, east, and west coordinates,
and a counter-clockwise rotation. But, the image layer expects coordinates for each
corner of the image. The KML ground overlay in this sample is for the Chartres
cathedral, and it's sourced from Wikimedia .

The code uses the static getCoordinatesFromEdges function from the ImageLayer class. It
calculates the four corners of the image using the north, south, east, west, and rotation
information of the KML ground overlay.

For a fully functional sample that shows how to use a KML Ground Overlay as Image
Layer, see KML Ground Overlay as Image Layer in the Azure Maps Samples . For the
source code for this sample, see KML Ground Overlay as Image Layer source code .

 Tip

Use the getPixels and getPositions functions of the image layer class to convert
between geographic coordinates of the positioned image layer and the local image
pixel coordinates.

Customize an image layer


The image layer has many styling options. For a fully functional sample that shows how
the different options of the image layer affect rendering, see Image Layer Options in
the Azure Maps Samples . For the source code for this sample, see Image Layer
Options source code .

Next steps
Learn more about the classes and methods used in this article:

ImageLayer

ImageLayerOptions

See the following articles for more code samples to add to your maps:

Add a tile layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a tile layer to a map
Article • 08/28/2024

This article shows you how to overlay a Tile layer on the map. Tile layers allow you to
superimpose images on top of Azure Maps base map tiles. For more information on
Azure Maps tiling system, see Zoom levels and tile grid.

A Tile layer loads in tiles from a server. These images can either be prerendered or
dynamically rendered. Prerendered images are stored like any other image on a server
using a naming convention that the tile layer understands. Dynamically rendered images
use a service to load the images close to real time. There are three different tile service
naming conventions supported by Azure Maps TileLayer class:

X, Y, Zoom notation - X is the column, Y is the row position of the tile in the tile
grid, and the Zoom notation a value based on the zoom level.
Quadkey notation - Combines x, y, and zoom information into a single string value.
This string value becomes a unique identifier for a single tile.
Bounding Box - Specify an image in the Bounding box coordinates format: {west},
{south},{east},{north} . This format is commonly used by web-mapping Services

(WMS) .

 Tip

A TileLayer is a great way to visualize large data sets on the map. Not only can a
tile layer be generated from an image, vector data can also be rendered as a tile
layer too. By rendering vector data as a tile layer, map control only needs to load
the tiles which are smaller in file size than the vector data they represent. This
technique is commonly used to render millions of rows of data on the map.

The tile URL passed into a Tile layer must be an http or an https URL to a TileJSON
resource or a tile URL template that uses the following parameters:

{x} - X position of the tile. Also needs {y} and {z} .

{y} - Y position of the tile. Also needs {x} and {z} .


{z} - Zoom level of the tile. Also needs {x} and {y} .

{quadkey} - Tile quadkey identifier based on the Bing Maps tile system naming

convention.
{bbox-epsg-3857} - A bounding box string with the format {west},{south},{east},

{north} in the EPSG 3857 Spatial Reference System.


{subdomain} - A placeholder for the subdomain values, if specified the subdomain

is added.
{azMapsDomain} - A placeholder to align the domain and authentication of tile

requests with the same values used by the map.

Add a tile layer


This sample shows how to create a tile layer that points to a set of tiles. This sample uses
the x, y, zoom tiling system. The source of this tile layer is the OpenSeaMap project ,
which contains crowd sourced nautical charts. Ideally users would clearly see the labels
of cities as they navigate the map when viewing radar data. This behavior can be
implemented by inserting the tile layer below the labels layer.

JavaScript

//Create a tile layer and add it to the map below the label layer.
map.layers.add(new atlas.layer.TileLayer({
tileUrl: 'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
opacity: 0.8,
tileSize: 256,
minSourceZoom: 7,
maxSourceZoom: 17
}), 'labels');

For a fully functional sample that shows how to create a tile layer that points to a set of
tiles using the x, y, zoom tiling system, see the Tile Layer using X, Y, and Z sample in
the Azure Maps Samples . The source of the tile layer in this sample is a nautical chart
from the OpenSeaMap project , an OpenStreetMaps project licensed under ODbL. For
the source code for this sample, see Tile Layer using X, Y, and Z source code .

Add an OGC web-mapping service (WMS)


A web-mapping service (WMTS) is an Open Geospatial Consortium (OGC) standard for
serving images of map data. There are many open data sets available in this format that
you can use with Azure Maps. This type of service can be used with a tile layer if the
service supports the EPSG:3857 coordinate reference system (CRS). When using a WMS
service, set the width and height parameters to the value supported by the service, be
sure to set this value in the tileSize option. In the formatted URL, set the BBOX
parameter of the service with the {bbox-epsg-3857} placeholder.

For a fully functional sample that shows how to create a tile layer that points to a Web
Mapping Service (WMS), see the WMS Tile Layer sample in the Azure Maps
Samples . For the source code for this sample, see WMS Tile Layer source code .

The following screenshot shows the WMS Tile Layer sample that overlays a web-
mapping service of geological data from the U.S. Geological Survey (USGS) on top of
the map and below the labels.

Add an OGC web-mapping tile service (WMTS)


A web-mapping tile service (WMTS) is an Open Geospatial Consortium (OGC) standard
for serving tiled based overlays for maps. There are many open data sets available in this
format that you can use with Azure Maps. This type of service can be used with a tile
layer if the service supports the EPSG:3857 or GoogleMapsCompatible coordinate
reference system (CRS). When using a WMTS service, set the width and height
parameters to the same value supported by the service, be sure to also set this value in
the tileSize option. In the formatted URL, replace the following placeholders
accordingly:

{TileMatrix} => {z}


{TileRow} => {y}

{TileCol} => {x}


For a fully functional sample that shows how to create a tile layer that points to a Web
Mapping Tile Service (WMTS), see the WMTS Tile Layer sample in the Azure Maps
Samples . For the source code for this sample, see WMTS Tile Layer source code .

The following screenshot shows the WMTS Tile Layer sample overlaying a web-mapping
tile service of imagery from the U.S. Geological Survey (USGS) National Map on top of a
map, below roads and labels.

Customize a tile layer


The tile layer class has many styling options. The Tile Layer Options sample is a tool to
try them out. For the source code for this sample, see Tile Layer Options source code .

Next steps
Learn more about the classes and methods used in this article:

TileLayer

TileLayerOptions
See the following articles for more code samples to add to your maps:

Add an image layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a custom WebGL layer to a map
Article • 08/29/2024

The Azure Maps Web SDK supports creating custom layers using WebGL . WebGL is
based on OpenGL ES and enables rendering 2D and 3D graphics in web browsers.

Using WebGL, you can build high-performance interactive graphics that render in the
browser in real-time that support scenarios like simulations, data visualization,
animations and 3D modeling.

Developers can access the WebGL context of the map during rendering and use custom
WebGL layers to integrate with other libraries such as three.js and deck.gl to
provide enriched and interactive content on the map.

Add a WebGL layer


Before you can add a WebGL layer to a map, you need to have an object that
implements the WebGLRenderer interface. First, create a WebGL layer by providing an id
and renderer object to the constructor, then add the layer to the map to have it
rendered.

The following sample code demonstrates how to add a WebGL layer to a map:

JavaScript

var myRenderer = {
/**
* Either "2d" or "3d". Defaults to "2d".
* - "3d" to use the depth buffer and share it with other layers
* - "2d" to add a layer with no depth. If you need to use the depth
buffer for a "2d"
* layer you must use an offscreen framebuffer and the prerender
method.
*/
renderingMode: "2d",

/**
* Optional method called when the layer has been added to the Map.
* This gives the layer a chance to initialize gl resources and register
event listeners.
* @param map The Map this custom layer was just added to.
* @param gl The gl context for the map.
*/
onAdd: function (map, gl) {},

/**
* Optional method called when the layer has been removed from the Map.
* This gives the layer a chance to clean up gl resources and event
listeners.
* @param map The Map this custom layer was just added to.
* @param gl The gl context for the map.
*/
onRemove: function (map, gl) {},

/**
* Optional method called during a render frame to allow a layer to
prepare resources
* or render into a texture.
*
* The layer cannot make any assumptions about the current GL state and
must bind a framebuffer before rendering.
*
* @param gl The map's gl context.
* @param matrix The map's camera matrix.
*/
prerender: function (gl, matrix) {},

/**
* Required. Called during a render frame allowing the layer to draw
into the GL context.
*
* The layer can assume blending and depth state is set to allow the
layer to
* properly blend and clip other layers. The layer cannot make any other
* assumptions about the current GL state.
*
* If the layer needs to render to a texture, it should implement the
prerender
* method to do this and only use the render method for drawing directly
into the
* main framebuffer.
*
* The blend function is set to gl.blendFunc(gl.ONE,
gl.ONE_MINUS_SRC_ALPHA).
* This expects colors to be provided in premultiplied alpha form where
the r, g and b
* values are already multiplied by the a value. If you are unable to
provide colors in
* premultiplied form you may want to change the blend function to
* gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE,
gl.ONE_MINUS_SRC_ALPHA).
*
* @param gl The map's gl context.
* @param matrix The map's camera matrix.
*/
render: function (gl, matrix) {}
};

//Add the layer to the map.


map.layers.add(new atlas.layer.WebGLLayer("layerId", { renderer: myRenderer
}));
7 Note

The WebGLLayer class supports the minZoom , maxZoom , and visible layer options.

JavaScript

//Add the layer to the map with layer options.


map.layers.add(new atlas.layer.WebGLLayer("layerId",
{
renderer: myRenderer,
minZoom: 10,
maxZoom: 22,
visible: true
}
));

This sample renders a triangle on the map using a WebGL layer.

For a fully functional sample with source code, see Simple 2D WebGL layer in the
Azure Maps Samples.

The map's camera matrix is used to project spherical Mercator point to gl coordinates.
Mercator point [0, 0] represents the top left corner of the Mercator world and [1, 1]
represents the bottom right corner. When renderingMode is "3d" , the z coordinate is
conformal. A box with identical x, y, and z lengths in Mercator units would be rendered
as a cube.
The MercatorPoint class has fromPosition , fromPositions , and toFloat32Array static
methods that can be used to convert a geospatial Position to a Mercator point. Similarly
the toPosition and toPositions methods can be used to project a Mercator point to a
Position.

Render a 3D model
Use a WebGL layer to render 3D models. The following example shows how to load a
glTF file and render it on the map using three.js .

You need to add the following script files.

HTML

<script src="https://unpkg.com/three@latest/build/three.min.js"></script>
<script
src="https://unpkg.com/three@latest/examples/js/loaders/GLTFLoader.js">
</script>

This sample renders an animated 3D parrot on the map.

For a fully functional sample with source code, see Three custom WebGL layer in the
Azure Maps Samples.

The onAdd function loads a .glb file into memory and instantiates three.js objects
such as Camera, Scene, Light, and a THREE.WebGLRenderer .
The render function calculates the projection matrix of the camera and renders the
model to the scene.

 Tip

To have a continuous and smooth animation, you can trigger the repaint of a
single frame by calling map.triggerRepaint() in the render function.
To enable anti-aliasing simply set antialias to true as one of the style
options while creating the map.

Render a 3D model using babylon.js


Babylon.js is one of the world's leading WebGL-based graphics engines. The following
example shows how to load a GLTF file and render it on the map using babylon.js.

You need to add the following script files.

HTML

<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js">
</script>

This sample renders a satellite tower on the map.

The onAdd function instantiates a BABYLON engine and a scene. It then loads a .gltf
file using BABYLON.SceneLoader.

The render function calculates the projection matrix of the camera and renders the
model to the scene.

For a fully functional sample with source code, see Babylon custom WebGL layer in
the Azure Maps Samples.

Render a deck.gl layer


A WebGL layer can be used to render layers from the deck.gl library. The following
sample demonstrates the data visualization of people migration flow in the United
States from county to county within a certain time range.

You need to add the following script file.

HTML

<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>

Define a layer class that extends atlas.layer.WebGLLayer .

JavaScript

class DeckGLLayer extends atlas.layer.WebGLLayer {

constructor(options) {
super(options.id);

//Create an instance of deck.gl layer


this._mbLayer = new deck.MapboxLayer(options);

//Create a renderer
const deckGLRenderer = {
renderingMode: "3d",
onAdd: (map, gl) => {
this._mbLayer.onAdd?.(map["map"], gl);
},
onRemove: (map, gl) => {
this._mbLayer.onRemove?.(map["map"], gl);
},
prerender: (gl, matrix) => {
this._mbLayer.prerender?.(gl, matrix);
},
render: (gl, matrix) => {
this._mbLayer.render(gl, matrix);
}
};
this.setOptions({ renderer: deckGLRenderer });
}
}

This sample renders an arc-layer google the deck.gl library.

For a fully functional sample with source code, see Deck GL custom WebGL layer in
the Azure Maps Samples.

Next steps
Learn more about the classes and methods used in this article:

WebGLLayer

WebGLLayerOptions
WebGLRenderer interface

MercatorPoint

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Show traffic on the map
Article • 04/14/2025

There are two types of traffic data available in Azure Maps:

Incident data - consists of point and line-based data for things such as construction, road
closures, and accidents.

Flow data - provides metrics on the flow of traffic on the roads. Often, traffic flow data is
used to color the roads. The colors are based on how much traffic is slowing down the
flow, relative to the speed limit, or another metric. There are four values that can be
passed into the traffic flow option of the map.

ノ Expand table

Flow Value Description

none Doesn't display traffic data on the map

relative Shows traffic data that's relative to the free-flow speed of the road

relative-delay Displays areas that are slower than the average expected delay

absolute Shows the absolute speed of all vehicles on the road

The following code shows how to display traffic data on the map.

JavaScript

//Show traffic on the map using the traffic options.


map.setTraffic({
incidents: true,
flow: 'relative'
});

The Traffic Overlay sample demonstrates how to display the traffic overlay on a map. For the
source code for this sample, see Traffic Overlay source code .

Traffic overlay options


The Traffic Overlay Options tool lets you switch between the different traffic overlay settings
to see how the rendering changes. For the source code for this sample, see Traffic Overlay
Options source code .


Add traffic controls
There are two different traffic controls that can be added to the map. The first control,
TrafficControl , adds a toggle button that can be used to turn traffic on and off. The options in

this control allow you to specify which parameters to use when displaying traffic. By default,
this control displays relative traffic flow and incident data, but you can change this behavior to
display absolute traffic flow and no incidents if desired. The second control,
TrafficLegendControl , adds a traffic legend to the map to help the user understand what the

color highlighted roads mean. This control appears on the map only when traffic flow data is
displayed, and is hidden in all other cases.

The following code shows how to add the traffic controls to the map.

JavaScript

//Add the traffic control toggle button to the top right corner of the map.
map.controls.add(new atlas.control.TrafficControl(), { position: 'top-right' });

//Add the traffic legend control to the bottom left corner of the map.
map.controls.add(new atlas.control.TrafficLegendControl(), { position: 'bottom-
left' });

The Traffic controls sample is a fully functional map that shows how to display traffic data on
a map. For the source code for this sample, see Traffic controls source code .


Next steps
Learn more about the classes and methods used in this article:

Map

TrafficOptions

Enhance your user experiences:

Map interaction with mouse events

Building an accessible map

Code sample page


Clustering point data in the Web SDK
Article • 08/29/2024

When there are many data points on the map, some may overlap over each other. The
overlap may cause the map may become unreadable and difficult to use. Clustering
point data is the process of combining point data that are near each other and
representing them on the map as a single clustered data point. As the user zooms into
the map, the clusters break apart into their individual data points. When you work with a
large number of data points, the clustering processes can improve the user experience.

https://learn.microsoft.com/Shows/Internet-of-Things-Show/Clustering-point-data-in-
Azure-Maps/player?format=ny

Enabling clustering on a data source


Enable clustering in the DataSource class by setting the cluster option to true . Set
clusterRadius to select nearby points and combines them into a cluster. The value of
clusterRadius is in pixels. Use clusterMaxZoom to specify a zoom level at which to

disable the clustering logic. Here's an example of how to enable clustering in a data
source.

JavaScript

//Create a data source and enable clustering.


var datasource = new atlas.source.DataSource(null, {
//Tell the data source to cluster point data.
cluster: true,

//The radius in pixels to cluster points together.


clusterRadius: 45,

//The maximum zoom level in which clustering occurs.


//If you zoom in more than this, all points are rendered as symbols.
clusterMaxZoom: 15
});

 Tip

If two data points are close together on the ground, it's possible the cluster will
never break apart, no matter how close the user zooms in. To address this, you can
set the clusterMaxZoom option to disable the clustering logic and simply display
everything.

The DataSource class provides the following methods related to clustering as well.

ノ Expand table

Method Return type Description

getClusterChildren(clusterId: Promise<Array<Feature<Geometry, Retrieves the


number) any> | Shape>> children of the given
cluster on the next
zoom level. These
children may be a
combination of
shapes and
subclusters. The
subclusters are
features with
properties matching
ClusteredProperties.

getClusterExpansionZoom(clusterId: Promise<number> Calculates a zoom


number) level at which the
cluster starts
expanding or break
apart.

getClusterLeaves(clusterId: number, Promise<Array<Feature<Geometry, Retrieves the points


limit: number, offset: number) any> | Shape>> in a cluster. By
default the first 10
points are returned.
To page through the
points, use limit to
specify the number
of points to return,
and offset to step
through the index of
points. To return all
points, set limit to
Infinity and don't
set offset .

Display clusters using a bubble layer


A bubble layer is a great way to render clustered points. Use expressions to scale the
radius and change the color based on the number of points in the cluster. If you display
clusters using a bubble layer, then you should use a separate layer to render unclustered
data points.

To display the size of the cluster on top of the bubble, use a symbol layer with text, and
don't use an icon.

For a complete working sample of how to implement displaying clusters using a bubble
layer, see Point Clusters in Bubble Layer in the Azure Maps Samples . For the source
code for this sample, see Point Clusters in Bubble Layer source code .

Display clusters using a symbol layer


When visualizing data points, the symbol layer automatically hides symbols that overlap
each other to ensure a cleaner user interface. This default behavior might be undesirable
if you want to show the data points density on the map. However, these settings can be
changed. To display all symbols, set the allowOverlap option of the Symbol layers
iconOptions property to true .

Use clustering to show the data points density while keeping a clean user interface. The
following sample shows you how to add custom symbols and represent clusters and
individual data points using the symbol layer.

For a complete working sample of how to implement displaying clusters using a symbol
layer, see Display clusters with a Symbol Layer in the Azure Maps Samples . For the
source code for this sample, see Display clusters with a Symbol Layer source code .

Clustering and the heat maps layer


Heat maps are a great way to display the density of data on the map. This visualization
method can handle a large number of data points on its own. If the data points are
clustered and the cluster size is used as the weight of the heat map, then the heat map
can handle even more data. To achieve this option, set the weight option of the heat
map layer to ['get', 'point_count'] . When the cluster radius is small, the heat map
looks nearly identical to a heat map using the unclustered data points, but it performs
better. However, the smaller the cluster radius, the more accurate the heat map is, but
with fewer performance benefits.

For a complete working sample that demonstrates how to create a heat map that uses
clustering on the data source, see Cluster weighted Heat Map in the Azure Maps
Samples . For the source code for this sample, see Cluster weighted Heat Map source
code .

Mouse events on clustered data points


When mouse events occur on a layer that contains clustered data points, the clustered
data point return to the event as a GeoJSON point feature object. This point feature has
the following properties:

ノ Expand table

Property name Type Description

cluster boolean Indicates if feature represents a cluster.

cluster_id string A unique ID for the cluster that can be used with the
DataSource getClusterExpansionZoom , getClusterChildren ,
and getClusterLeaves methods.

point_count number The number of points the cluster contains.

point_count_abbreviated string A string that abbreviates the point_count value if it's long.
(for example, 4,000 becomes 4K)

The Point Clusters in Bubble Layer example takes a bubble layer that renders cluster
points and adds a click event. When the click event triggers, the code calculates and
zooms the map to the next zoom level, at which the cluster breaks apart. This
functionality is implemented using the getClusterExpansionZoom method of the
DataSource class and the cluster_id property of the clicked clustered data point.
The following code snippet shows the code in the Point Clusters in Bubble Layer
example that adds the click event functionality to the clustered data points:

JavaScript

//Add a click event to the layer so we can zoom in when a user clicks a
cluster.
map.events.add('click', clusterBubbleLayer, clusterClicked);

//Add mouse events to change the mouse cursor when hovering over a cluster.
map.events.add('mouseenter', clusterBubbleLayer, function () {
map.getCanvasContainer().style.cursor = 'pointer';
});

map.events.add('mouseleave', clusterBubbleLayer, function () {


map.getCanvasContainer().style.cursor = 'grab';
});

function clusterClicked(e) {
if (e && e.shapes && e.shapes.length > 0 &&
e.shapes[0].properties.cluster) {
//Get the clustered point from the event.
var cluster = e.shapes[0];

//Get the cluster expansion zoom level. This is the zoom level at
which the cluster starts to break apart.

datasource.getClusterExpansionZoom(cluster.properties.cluster_id).then(funct
ion (zoom) {

//Update the map camera to be centered over the cluster.


map.setCamera({
center: cluster.geometry.coordinates,
zoom: zoom,
type: 'ease',
duration: 200
});
});
}
}

Display cluster area


The point data that a cluster represents is spread over an area. In this sample when the
mouse is hovered over a cluster, two main behaviors occur. First, the individual data
points contained in the cluster are used to calculate a convex hull. Then, the convex hull
is displayed on the map to show an area. A convex hull is a polygon that wraps a set of
points like an elastic band and can be calculated using the atlas.math.getConvexHull
method. All points contained in a cluster can be retrieved from the data source using
the getClusterLeaves method.

For a complete working sample that demonstrates how to do this, see Display cluster
area with Convex Hull in the Azure Maps Samples . For the source code for this
sample, see Display cluster area with Convex Hull source code .


Aggregating data in clusters
Often clusters are represented using a symbol with the number of points that are within
the cluster. But, sometimes it's desirable to customize the style of clusters with more
metrics. With cluster aggregates, custom properties can be created and populated using
an aggregate expression calculation. Cluster aggregates can be defined in
clusterProperties option of the DataSource .

The Cluster aggregates sample uses an aggregate expression. The code calculates a
count based on the entity type property of each data point in a cluster. When a user
selects a cluster, a popup shows with additional information about the cluster. For the
source code for this sample, see Cluster aggregates source code .

Next steps
Learn more about the classes and methods used in this article:

DataSource class

DataSourceOptions object

atlas.math namespace

See code examples to add functionality to your app:


Add a bubble layer

Add a symbol layer

Add a heat map layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Data-driven style expressions (Web
SDK)
Article • 03/31/2025

Expressions enable you to apply business logic to styling options that observe the
properties defined in each shape in a data source. Expressions can filter data in a data
source or a layer. Expressions might consist of conditional logic, like if-statements. And,
they can be used to manipulate data using: string operators, logical operators, and
mathematical operators.

Data-driven styles reduce the amount of code needed to implement business logic
around styling. When used with layers, expressions are evaluated at render time on a
separate thread. This functionality provides increased performance compared to
evaluating business logic on the UI thread.

This video provides an overview of data-driven styling in the Azure Maps Web SDK.

https://learn.microsoft.com/Shows/Internet-of-Things-Show/Data-Driven-Styling-with-
Azure-Maps/player?format=ny

Expressions are represented as JSON arrays. The first element of an expression in the
array is a string that specifies the name of the expression operator. For example, "+" or
"case". The next elements (if any) are the arguments to the expression. Each argument is
either a literal value (a string, number, boolean, or null ), or another expression array.
The following pseudocode defines the basic structure of an expression.

JavaScript

[
expression_operator,
argument0,
argument1,

]

The Azure Maps Web SDK supports many types of expressions. Expressions can be used
on their own or in combination with other expressions.

ノ Expand table
Type of Description
expressions

Aggregate An expression that defines a calculation that is processed over a set of data
expression and can be used with the clusterProperties option of a DataSource .

Boolean Boolean expressions provide a set of boolean operators expressions for


expressions evaluating boolean comparisons.

Color expressions Color expressions make it easier to create and manipulate color values.

Conditional Conditional expressions provide logic operations that are like if-statements.
expressions

Data expressions Provides access to the property data in a feature.

Interpolate and Interpolate and step expressions can be used to calculate values along an
Step expressions interpolated curve or step function.

Layer specific Special expressions that are only applicable to a single layer.
expressions

Math expressions Provides mathematical operators to perform data-driven calculations within


the expression framework.

String operator String operator expressions perform conversion operations on strings such
expressions as concatenating and converting the case.

Type expressions Type expressions provide tools for testing and converting different data
types like strings, numbers, and boolean values.

Variable binding Variable binding expressions store the results of a calculation in a variable
expressions and referenced elsewhere in an expression multiple times without having to
recalculate the stored value.

Zoom expression Retrieves the current zoom level of the map at render time.

All examples in this document use the following feature to demonstrate different ways
in which the different types of expressions can be used.

JSON

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.13284, 47.63699]
},
"properties": {
"id": 123,
"entityType": "restaurant",
"revenue": 12345,
"subTitle": "Building 40",
"temperature": 64,
"title": "Cafeteria",
"zoneColor": "purple",
"abcArray": ["a", "b", "c"],
"array2d": [["a", "b"], ["x", "y"]],
"_style": {
"fillColor": "red"
}
}
}

Data expressions
Data expressions provide access to the property data in a feature.

ノ Expand table

Expression Return Description


type

['at', number, array] value Retrieves an item from an array.

['geometry-type'] string Gets the feature's geometry type: Point, MultiPoint,


LineString, MultiLineString, Polygon, MultiPolygon.

['get', string] value Gets the property value from the current feature's
properties. Returns null if the requested property is
missing.

['get', string, value Gets the property value from the properties of the
object] provided object. Returns null if the requested property is
missing.

['has', string] boolean Determines if the properties of a feature have the specified
property.

['has', string, boolean Determines if the properties of the object have the
object] specified property.

['id'] value Gets the feature's ID if it has one.

['in', boolean | boolean Determines whether an item exists in an array


string | number,
array]

['in', substring, boolean Determines whether a substring exists in a string


string]
Expression Return Description
type

['index-of', boolean | number Returns the first position at which an item can be found in
string | number, array an array or a substring can be found in a string, or -1 if
| string] the input can't be found. Accepts an optional index from
where to begin the search.
['index-of', boolean |
string | number, array
| string, number]

['length', string | number Gets the length of a string or an array.


array]

['slice', array | string | Returns an item from an array or a substring from a string
string, number] array from a specified start index, or between a start index and
an end index if set. The return value is inclusive of the start
['slice', array | index but not of the end index.
string, number,
number]

Examples

Properties of a feature can be accessed directly in an expression by using a get


expression. This example uses the zoneColor value of the feature to specify the color
property of a bubble layer.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: ['get', 'zoneColor'] //Get the zoneColor value.
});

The above example works fine, if all the point features have the zoneColor property. If
they don't, the color defaults to "black". To modify the fallback color, use a case
expression in combination with the has expression to check if the property exists. If the
property doesn't exist, return a fallback color.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'case', //Use a conditional case expression.

['has', 'zoneColor'], //Check to see if feature has a "zoneColor"


property
['get', 'zoneColor'], //If it does, use it.
'blue' //If it doesn't, default to blue.
]
});

Bubble and symbol layers render the coordinates of all shapes in a data source, by
default. This behavior can highlight the vertices of a polygon or a line. The filter
option of the layer can be used to limit the geometry type of the features it renders, by
using a ['geometry-type'] expression within a boolean expression. The following
example limits a bubble layer so that only Point features are rendered.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


filter: ['==', ['geometry-type'], 'Point']
});

The following example allows both Point and MultiPoint features to be rendered.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


filter: ['any', ['==', ['geometry-type'], 'Point'], ['==', ['geometry-
type'], 'MultiPoint']]
});

Similarly, the outline of Polygons render in line layers. To disable this behavior in a line
layer, add a filter that only allows LineString and MultiLineString features.

Here are some more examples of how to use data expressions:

JavaScript

//Get item [2] from an array "properties.abcArray[1]" = "c"


['at', 2, ['get', 'abcArray']]

//Get item [0][1] from a 2D array "properties.array2d[0][1]" = "b"


['at', 1, ['at', 0, ['get', 'array2d']]]

//Check to see if a value is in an array "properties.abcArray.indexOf('a')


!== -1" = true
['in', 'a', ['get', 'abcArray']]

//Gets the index of the value 'b' in an array


"properties.abcArray.indexOf('b')" = 1
['index-of', 'b', ['get', 'abcArray']]

//Get the length of an array "properties.abcArray.length" = 3


['length', ['get', 'abcArray']]

//Get the value of a subproperty "properties._style.fillColor" = "red"


['get', 'fillColor', ['get', '_style']]

//Check that "fillColor" exists as a subproperty of "_style".


['has', 'fillColor', ['get', '_style']]

//Slice an array starting at index 2 "properties.abcArray.slice(2)" = ['c']


['slice', ['get', 'abcArray'], 2]

//Slice a string from index 0 to index 4 "properties.entityType.slice(0, 4)"


= 'rest'
['slice', ['get', 'entityType'], 0, 4]

Math expressions
Math expressions provide mathematical operators to perform data-driven calculations
within the expression framework.

ノ Expand table

Expression Return Description


type

['+', number, number, …] number Calculates the sum of the specified numbers.

['-', number] number Subtracts 0 by the specified number.

['-', number, number] number Subtracts the first numbers by the second
number.

['*', number, number, …] number Multiplies the specified numbers together.

['/', number, number] number Divides the first number by the second
number.

['%', number, number] number Calculates the remainder when dividing the
first number by the second number.

['^', number, number] number Calculates the value of the first value raised to
the power of the second number.

['abs', number] number Calculates the absolute value of the specified


number.

['acos', number] number Calculates the arccosine of the specified


number.
Expression Return Description
type

['asin', number] number Calculates the arcsine of the specified number.

['atan', number] number Calculates the arctangent of the specified


number.

['ceil', number] number Rounds the number up to the next whole


integer.

['cos', number] number Calculates the cos of the specified number.

['distance', Point \| MultiPoint number Calculates the shortest distance in meters


\| LineString \| MultiLineString \| between the evaluated feature and the input
Polygon \| MultiPolygon \| Feature geometry. Distance values returned might vary
\| FeatureCollection] in precision due to loss in precision from
encoding geometries, particularly below zoom
level 13.

['e'] number Returns the mathematical constant e .

['floor', number] number Rounds the number down to the previous


whole integer.

['ln', number] number Calculates the natural logarithm of the


specified number.

['ln2'] number Returns the mathematical constant ln(2) .

['log10', number] number Calculates the base-ten logarithm of the


specified number.

['log2', number] number Calculates the base-two logarithm of the


specified number.

['max', number, number, …] number Calculates the maximum number in the


specified set of numbers.

['min', number, number, …] number Calculates the minimum number in the


specified set of numbers.

['pi'] number Returns the mathematical constant PI .

['round', number] number Rounds the number to the nearest integer.


Halfway values are rounded away from zero.
For example, ['round', -1.5] evaluates to -2 .

['sin', number] number Calculates the sine of the specified number.

['sqrt', number] number Calculates the square root of the specified


number.
Expression Return Description
type

['tan', number] number Calculates the tangent of the specified number.

Aggregate expression
An aggregate expression defines a calculation that's processed over a set of data and
can be used with the clusterProperties option of a DataSource . The output of these
expressions must be a number or a boolean.

An aggregate expression takes in three values: an operator value, and initial value, and
an expression to retrieve a property from each feature in a data to apply the aggregate
operation on. This expression has the following format:

JavaScript

[operator: string, initialValue: boolean | number, mapExpression:


Expression]

operator: An expression function that's then applied to against all values calculated
by the mapExpression for each point in the cluster. Supported operators:
For numbers: + , * , max , min
For Booleans: all , any
initialValue: An initial value in which the first calculated value is aggregated against.
mapExpression: An expression that's applied against each point in the data set.

Examples

If all features in a data set have a revenue property, which is a number. Then, the total
revenue of all points in a cluster, which are created from the data set, can be calculated.
This calculation is done using the following aggregate expression: ['+', 0, ['get',
'revenue']]

Accumulated expression
The accumulated expression gets the value of a cluster property accumulated so far,
used in the clusterProperties option of a clustered DataSource source.

Usage

JavaScript
["accumulated"]

Boolean expressions
Boolean expressions provide a set of boolean operators expressions for evaluating
boolean comparisons.

The comparison is strictly typed when values are compared. Values of different types are
always considered unequal. Cases where the types are known to be different at parse
time are considered invalid and produces a parse error.

ノ Expand table

Expression Return Description


type

['!', boolean] boolean Logical negation. Returns true if the input is false , and
false if the input is true .

['!=', value, value] boolean Returns true if the input values aren't equal, false
otherwise.

['<', value, value] boolean Returns true if the first input is strictly less than the
second, false otherwise. The arguments are required to
be either both strings or both numbers.

['<=', value, value] boolean Returns true if the first input is less than or equal to the
second, false otherwise. The arguments are required to
be either both strings or both numbers.

['==', value, value] boolean Returns true if the input values are equal, false
otherwise. The arguments are required to be either both
strings or both numbers.

['>', value, value] boolean Returns true if the first input is strictly greater than the
second, false otherwise. The arguments are required to
be either both strings or both numbers.

['>=' value, value] boolean Returns true if the first input is greater than or equal to
the second, false otherwise. The arguments are required
to be either both strings or both numbers.

['all', boolean, boolean Returns true if all the inputs are true , false otherwise.
boolean, …]
Expression Return Description
type

['any', boolean, boolean Returns true if any of the inputs are true , false
boolean, …] otherwise.

['within', Polygon | boolean Returns true if the evaluated feature is fully contained
MultiPolygon | inside a boundary of the input geometry, false otherwise.
Feature<Polygon | The input value can be a valid GeoJSON of type Polygon ,
MultiPolygon>] MultiPolygon , Feature , or FeatureCollection . Supported
features for evaluation:

- Point: Returns false if a point is on the boundary or


falls outside the boundary.
- LineString: Returns false if any part of a line falls
outside the boundary, the line intersects the boundary, or
a line's endpoint is on the boundary.

Conditional expressions
Conditional expressions provide logic operations that are like if-statements.

The following expressions perform conditional logic operations on the input data. For
example, the case expression provides "if/then/else" logic while the match expression is
like a "switch-statement".

Case expression
A case expression is a type of conditional expression that provides "if/then/else" logic.
This type of expression steps through a list of boolean conditions. It returns the output
value of the first boolean condition to evaluate to true.

The following pseudocode defines the structure of the case expression.

JavaScript

[
'case',
condition1: boolean,
output1: value,
condition2: boolean,
output2: value,
...,
fallback: value
]
Example

The following example steps through different boolean conditions until it finds one that
evaluates to true , and then returns that associated value. If no boolean condition
evaluates to true , a fallback value is returned.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'case',

//Check to see if the first boolean expression is true, and if it


is, return its assigned result.
['has', 'zoneColor'],
['get', 'zoneColor'],

//Check to see if the second boolean expression is true, and if it


is, return its assigned result.
['all', ['has', ' temperature '], ['>', ['get', 'temperature'],
100]],
'red',

//Specify a default value to return.


'green'
]
});

Match expression
A match expression is a type of conditional expression that provides switch-statement
like logic. The input can be any expression such as ['get', 'entityType'] that returns a
string or a number. Each label must be either a single literal value or an array of literal
values, whose values must be all strings or all numbers. The input matches if any of the
values in the array match. Each label must be unique. If the input type doesn't match the
type of the labels, the result is the fallback value.

The following pseudocode defines the structure of the match expression.

JavaScript

[
'match',
input: number | string,
label1: number | string | (number | string)[],
output1: value,
label2: number | string | (number | string)[],
output2: value,
...,
fallback: value
]

Examples

The following example looks at the entityType property of a Point feature in a bubble
layer searches for a match. If it finds a match, that specified value is returned or it
returns the fallback value.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'match',

//Get the property to match.


['get', 'entityType'],

//List the values to match and the result to return for each match.
'restaurant', 'red',
'park', 'green',

//Specify a default value to return if no match is found.


'black'
]
});

The following example uses an array to list a set of labels that should all return the same
value. This approach is much more efficient than listing each label individually. In this
case, if the entityType property is "restaurant" or "grocery_store", the color "red" is
returned.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'match',

//Get the property to match.


['get', 'entityType'],

//List the values to match and the result to return for each match.
['restaurant', 'grocery_store'], 'red',

'park', 'green',

//Specify a default value to return if no match is found.


'black'
]
});

Coalesce expression
A coalesce expression steps through a set of expressions until the first non-null value is
obtained and returns that value.

The following pseudocode defines the structure of the coalesce expression.

JavaScript

[
'coalesce',
value1,
value2,

]

Example

The following example uses a coalesce expression to set the textField option of a
symbol layer. If the title property is missing from the feature or set to null , the
expression tries looking for the subTitle property, if it's missing or null , it falls back to
an empty string.

JavaScript

var layer = new atlas.layer.SymbolLayer(datasource, null, {


textOptions: {
textField: [
'coalesce',

//Try getting the title property.


['get', 'title'],

//If there is no title, try getting the subTitle.


['get', 'subTitle'],

//Default to an empty string.


''
]
}
});
The following example uses a coalesce expression to retrieve the first available image
icon available in the map sprite from a list of specified image names.

JavaScript

var layer = new atlas.layer.SymbolLayer(datasource, null, {


iconOptions: {
image: [
'coalesce',

//Try getting the image with id 'missing-image'.


['image', 'missing-image'],

//Specify an image id to fallback to.


'marker-blue'
]
}
});

Type expressions
Type expressions provide tools for testing and converting different data types like
strings, numbers, and boolean values.

ノ Expand table

Expression Return Description


type

['array', value] | Object[] Asserts that the input is an array.


['array', type:
"string" | "number"
| "boolean", value]

['boolean', value] | boolean Asserts that the input value is a boolean. If multiple values are
["boolean", value, provided, each one is evaluated in order until a boolean is
fallback: value, obtained. If none of the inputs are booleans, the expression is
fallback: value, an error.
...]

['collator', { collator Returns a collator for use in locale-dependent comparison


'case-sensitive': operations. The case-sensitive and diacritic-sensitive options
boolean, 'diacritic- default to false. The locale argument specifies the IETF
sensitive': boolean, language tag of the locale to use. If none is provided, the
'locale': string }] default locale is used. If the requested locale isn't available,
the collator uses a system-defined fallback locale. Use
resolved-locale to test the results of locale fallback behavior.
Expression Return Description
type

['literal', array] array | Returns a literal array or object value. Use this expression to
object prevent an array or object from being evaluated as an
['literal', object] expression, necessary when an array or object is returned by
an expression.

['image', string] string Checks to see if a specified image ID is loaded into the maps
image sprite. If it is, the ID is returned, otherwise null is
returned.

['number', value] | number Asserts that the input value is a number. If multiple values are
["number", value, provided, each one is evaluated in order until a number is
fallback: value, obtained. If none of the inputs are numbers, the expression is
fallback: value, an error.
...]

['object', value] | Object Asserts that the input value is an object. If multiple values are
["object", value, provided, each one is evaluated in order until an object is
fallback: value, obtained. If none of the inputs are objects, the expression is
fallback: value, an error.
...]

['string', value] | string Asserts that the input value is a string. If multiple values are
["string", value, provided, each one is evaluated in order until a string is
fallback: value, obtained. If none of the inputs are strings, the expression is an
fallback: value, error.
...]

['to-boolean', boolean Converts the input value to a boolean. The result is false
value] when the input is an empty string, 0 , false , null , or NaN ;
otherwise its true .

['to-color', value] color Converts the input value to a color. If multiple values are
provided, each one is evaluated in order until the first
['to-color', value1, successful conversion is obtained. If none of the inputs can be
value2…] converted, the expression is an error.

['to-number', number Converts the input value to a number, if possible. If the input
value] is null or false , the result is 0. If the input is true , the result
is 1. If the input is a string, it's converted to a number using
['to-number', the ToNumber string function of the ECMAScript Language
value1, value2, …] Specification. If multiple values are provided, each one is
evaluated in order until the first successful conversion is
obtained. If none of the inputs can be converted, the
expression is an error.
Expression Return Description
type

['to-string', string Converts the input value to a string. If the input is null , the
value] result is "" . If the input is a boolean, the result is "true" or
"false" . If the input is a number, it's converted to a string
using the ToString number function of the ECMAScript
Language Specification. If the input is a color, it's converted to
CSS RGBA color string "rgba(r,g,b,a)" . Otherwise, the input
is converted to a string using the JSON.stringify function of
the ECMAScript Language Specification.

['typeof', value] string Returns a string describing the type of the given value.

 Tip

If an error message similar to Expression name must be a string, but found number
instead. If you wanted a literal array, use ["literal", [...]]. appears in the

browser console, then it means that there is an expression somewhere in your code
that has an array that doesn't have a string for its first value. If you want the
expression to return an array, wrap the array with the literal expression. The
following example sets the icon offset option of a symbol layer, which needs to be
an array containing two numbers, by using a match expression to choose between
two offset values based on the value of the entityType property of the point
feature.

JavaScript

var layer = new atlas.layer.SymbolLayer(datasource, null, {


iconOptions: {
offset: [
'match',

//Get the entityType value.


['get', 'entityType'],

//If the entity type is 'restaurant', return a different


pixel offset.
'restaurant', ['literal', [0, -10]],

//Default to value.
['literal', [0, 0]]
]
}
});
Color expressions
Color expressions make it easier to create and manipulate color values.

ノ Expand table

Expression Return Description


type

['interpolate-hcl', interpolation: color Produces continuous, smooth results by


["linear"] \| ["exponential", base] \| interpolating between pairs of input
["cubic-bezier", x1, y1, x2, y2], and output values ("stops"). Works like
input: number, stop_input_1: number, interpolate , but the output type must

stop_output_1: Color, stop_input_n: be a color, and the interpolation is


number, stop_output_n: Color, ...] performed in the Hue-Chroma-
Luminance color space.

['interpolate-lab', interpolation: color Produces continuous, smooth results by


["linear"] \| ["exponential", base] \| interpolating between pairs of input
["cubic-bezier", x1, y1, x2, y2], and output values ("stops"). Works like
input: number, stop_input_1: number, interpolate , but the output type must

stop_output_1: Color, stop_input_n: be a color, and the interpolation is


number, stop_output_n: Color, ...] performed in the CIELAB color space.

['rgb', number, number, number] color Creates a color value from red, green,
and blue components ranging between
0 and 255 , and an alpha component of
1 . If any component is out of range,
the expression is an error.

['rgba', number, number, number, color Creates a color value from red, green,
number] blue components ranging between 0
and 255 , and an alpha component
within a range of 0 and 1 . If any
component is out of range, the
expression is an error.

['to-rgba'] [number, Returns a four-element array containing


number, the input color's red, green, blue, and
number, alpha components, in that order.
number]

Example

The following example creates an RGB color value that has a red value of 255 , and green
and blue values calculated by multiplying 2.5 by the value of the temperature property.
As the temperature changes, the color changes to different shades of red.
JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'rgb', //Create a RGB color value.

255, //Set red value to 255.

['*', 2.5, ['get', 'temperature']], //Multiple the temperature by


2.5 and set the green value.

['*', 2.5, ['get', 'temperature']] //Multiple the temperature by


2.5 and set the blue value.
]
});

String operator expressions


String operator expressions perform conversion operations on strings such as
concatenating and converting the case.

ノ Expand table

Expression Return Description


type

['concat', string, string Concatenates multiple strings together. Each value must
string, …] be a string. Use the to-string type expression to
convert other value types to string if needed.

['downcase', string] string Converts the specified string to lowercase.

['is-supported-script', boolean Determines if the input string uses a character set


string] | ['is-supported- supported by the current font stack. For example: ['is-
script', Expression] supported-script', 'ಗೌರವಾರ್ಥವಾಗಿ']

['resolved-locale', string Returns the IETF language tag of the locale being used
string] by the provided collator that can be used to determine
the default system locale or to determine if a requested
locale was successfully loaded.

['upcase', string] string Converts the specified string to uppercase.

Example

The following example converts the temperature property of the point feature into a
string and then concatenates "°F" to the end of it.
JavaScript

var layer = new atlas.layer.SymbolLayer(datasource, null, {


textOptions: {
textField: ['concat', ['to-string', ['get', 'temperature']], '°F'],

//Some additional style options.


offset: [0, -1.5],
size: 12,
color: 'white'
}
});

The above expression renders a pin on the map with the text "64°F" overlaid on top of it
as shown in the following image.

Interpolate and Step expressions


Interpolate and step expressions can be used to calculate values along an interpolated
curve or step function. These expressions take in an expression that returns a numeric
value as their input, for example ['get', 'temperature'] . The input value is evaluated
against pairs of input and output values, to determine the value that best fits the
interpolated curve or step function. The output values are called "stops". The input
values for each stop must be a number and be in ascending order. The output values
must be a number, and array of numbers, or a color.

Interpolate expression
An interpolate expression can be used to calculate a continuous, smooth set of values
by interpolating between stop values. An interpolate expression that returns color
values produces a color gradient in which result values are selected from.

There are three types of interpolation methods that can be used in an interpolate
expression:

['linear'] - Interpolates linearly between the pair of stops.


['exponential', base] - Interpolates exponentially between the stops. The base

value controls the rate at which the output increases. Higher values make the
output increase more towards the high end of the range. A base value close to 1
produces an output that increases more linearly.
['cubic-bezier', x1, y1, x2, y2] - Interpolates using a cubic Bezier curve

defined by the given control points.

Here's an example of what these different types of interpolations look like.

ノ Expand table

Linear Exponential Cubic Bezier

The following pseudocode defines the structure of the interpolate expression.

JavaScript

[
'interpolate',
interpolation: ['linear'] | ['exponential', base] | ['cubic-bezier', x1,
y1, x2, y2],
input: number,
stopInput1: number,
stopOutput1: value1,
stopInput2: number,
stopOutput2: value2,
...
]
Example

The following example uses a linear interpolate expression to set the color property
of a bubble layer based on the temperature property of the point feature. If the
temperature value is less than 60, "blue" is returned. If it's between 60 and less than 70,

yellow is returned. If it's between 70 and less than 80, "orange" is returned. If it's 80 or
greater, "red" is returned.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'interpolate',
['linear'],
['get', 'temperature'],
50, 'blue',
60, 'yellow',
70, 'orange',
80, 'red'
]
});

The following image demonstrates how the colors are chosen for the above expression.

Step expression
A step expression can be used to calculate discrete, stepped result values by evaluating
a piecewise-constant function defined by stops.

The following pseudocode defines the structure of the step expression.

JavaScript

[
'step',
input: number,
output0: value0,
stop1: number,
output1: value1,
stop2: number,
output2: value2,
...
]
Step expressions return the output value of the stop just before the input value, or the
first input value if the input is less than the first stop.

Example

The following example uses a step expression to set the color property of a bubble
layer based on the temperature property of the point feature. If the temperature value is
less than 60, "blue" is returned. If it's between 60 and less than 70, "yellow" is returned.
If it's between 70 and less than 80, "orange" is returned. If it's 80 or greater, "red" is
returned.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
'step',
['get', 'temperature'],
'blue',
60, 'yellow',
70, 'orange',
80, 'red'
]
});

The following image demonstrates how the colors are chosen for the above expression.

Layer-specific expressions
Special expressions that only apply to specific layers.

Heat map density expression


A heat map density expression retrieves the heat map density value for each pixel in a
heat map layer and is defined as ['heatmap-density'] . This value is a number between
0 and 1 . It's used in combination with a interpolation or step expression to define

the color gradient used to colorize the heat map. This expression can only be used in
the color option of the heat map layer.

 Tip
The color at index 0, in an interpolation expression or the default color of a step
color, defines the color of the area where there's no data. The color at index 0 can
be used to define a background color. Many prefer to set this value to transparent
or a semi-transparent black.

Example

This example uses a liner interpolation expression to create a smooth color gradient for
rendering the heat map.

JavaScript

var layer = new atlas.layer.HeatMapLayer(datasource, null, {


color: [
'interpolate',
['linear'],
['heatmap-density'],
0, 'transparent',
0.01, 'purple',
0.5, '#fb00fb',
1, '#00c3ff'
]
});

In addition to using a smooth gradient to colorize a heat map, colors can be specified
within a set of ranges by using a step expression. Using a step expression for colorizing
the heat map visually breaks up the density into ranges that resembles a contour or
radar style map.

JavaScript

var layer = new atlas.layer.HeatMapLayer(datasource, null, {


color: [
'step',
['heatmap-density'],
'transparent',
0.01, 'navy',
0.25, 'navy',
0.5, 'green',
0.75, 'yellow',
1, 'red'
]
});

For more information, see the Add a heat map layer documentation.
Line progress expression
A line progress expression retrieves the progress along a gradient line in a line layer and
is defined as ['line-progress'] . This value is a number between 0 and 1. It's used in
combination with an interpolation or step expression. This expression can only be
used with the strokeGradient option of the line layer.

7 Note

The strokeGradient option of the line layer requires the lineMetrics option of the
data source to be set to true .

Example

This example uses the ['line-progress'] expression to apply a color gradient to the
stroke of a line.

JavaScript

var layer = new atlas.layer.LineLayer(datasource, null, {


strokeGradient: [
'interpolate',
['linear'],
['line-progress'],
0, "blue",
0.1, "royalblue",
0.3, "cyan",
0.5, "lime",
0.7, "yellow",
1, "red"
]
});

For an interactive working example, see Add a stroke gradient to a line.

Text field format expression


The text field format expression can be used with the textField option of the symbol
layers textOptions property to provide mixed text formatting. This expression allows a
set of input strings and formatting options to be specified. The following options can be
specified for each input string in this expression.

'font-scale' - Specifies the scaling factor for the font size. If specified, this value

overrides the size property of the textOptions for the individual string.
'text-font' - Specifies one or more font families that should be used for this

string. If specified, this value overrides the font property of the textOptions for
the individual string.

The following pseudocode defines the structure of the text field format expression.

JavaScript

[
'format',
input1: string,
options1: {
'font-scale': number,
'text-font': string[]
},
input2: string,
options2: {
'font-scale': number,
'text-font': string[]
},

]

Example

The following example formats the text field by adding a bold font and scaling up the
font size of the title property of the feature. This example also adds the subTitle
property of the feature on a newline, with a scaled down font size.

JavaScript

var layer = new atlas.layer.SymbolLayer(datasource, null, {


textOptions: {
textField: [
'format',

//Bold the title property and scale its font size up.
['get', 'title'],
{
'text-font': ['literal', ['StandardFont-Bold']],
'font-scale': 1.25
},

'\n', {}, //Add a new line without any formatting.

//Scale the font size down of the subTitle property.


['get', 'subTitle'],
{
'font-scale': 0.75
}
]
}
});

This layer renders the point feature as shown in the following image:

Number format expression


The number-format expression can only be used with the textField option of a symbol
layer. This expression converts the provided number into a formatted string. This
expression wraps JavaScript's Number.toLocalString function and supports the
following set of options.

locale - Specify this option for converting numbers to strings in a way that aligns

with the specified language. Pass a BCP 47 language tag into this option.
currency - To convert the number into a string representing a currency. Possible

values are the ISO 4217 currency codes , such as "USD" for the US dollar, "EUR"
for the euro, or "CNY" for the Chinese RMB.
'min-fraction-digits' - Specifies the minimum number of decimal places to

include in the string version of the number.


'max-fraction-digits' - Specifies the maximum number of decimal places to

include in the string version of the number.

The following pseudocode defines the structure of the text field format expression.

JavaScript

[
'number-format',
input: number,
options: {
locale: string,
currency: string,
'min-fraction-digits': number,
'max-fraction-digits': number
}
]

Example

The following example uses a number-format expression to modify how the revenue
property of the point feature is rendered in the textField option of a symbol layer such
that it appears a US dollar value.

JavaScript

var layer = new atlas.layer.SymbolLayer(datasource, null, {


textOptions: {
textField: [
'number-format',
['get', 'revenue'],
{ 'currency': 'USD' }
],

offset: [0, 0.75]


}
});

This layer renders the point feature as shown in the following image:

Image expression
An image expression can be used with the image and textField options of a symbol
layer, and the fillPattern option of the polygon layer. This expression checks that the
requested image exists in the style and returns either the resolved image name or null ,
depending on whether or not the image is currently in the style. This validation process
is synchronous and requires the image to have been added to the style before
requesting it in the image argument.

Example

The following example uses an image expression to add an icon inline with text in a
symbol layer.

JavaScript

//Load the custom image icon into the map resources.


map.imageSprite.add('wifi-icon', 'wifi.png').then(function () {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Create a point feature and add it to the data source.


datasource.add(new atlas.data.Point(map.getCamera().center));

//Add a layer for rendering point data as symbols.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'none'
},
textOptions: {
//Create a formatted text string that has an icon in it.
textField: ["format", 'Ricky\'s ', ["image", "wifi-icon"], '
Palace']
}
}));
});

This layer renders the text field in the symbol layer as shown in the following image:
Zoom expression
A zoom expression is used to retrieve the current zoom level of the map at render time
and is defined as ['zoom'] . This expression returns a number between the minimum
and maximum zoom level range of the map. The Azure Maps interactive map controls
support 25 zoom levels, numbered 0 through 24. Using the zoom expression allows
styles to be modified dynamically as the zoom level of the map is changed. The zoom
expression can only be used with interpolate and step expressions.

Example

By default, the radii of data points rendered in the heat map layer have a fixed pixel
radius for all zoom levels. As the map is zoomed, the data aggregates together and the
heat map layer looks different. A zoom expression can be used to scale the radius for
each zoom level such that each data point covers the same physical area of the map. It
makes the heat map layer look more static and consistent. Each zoom level of the map
has twice as many pixels vertically and horizontally as the previous zoom level. Scaling
the radius, such that it doubles with each zoom level, creates a heat map that looks
consistent on all zoom levels. It can be accomplished using the zoom expression with a
base 2 exponential interpolation expression, with the pixel radius set for the minimum

zoom level and a scaled radius for the maximum zoom level calculated as 2 *
Math.pow(2, minZoom - maxZoom) as demonstrated in the following example.

JavaScript

var layer = new atlas.layer.HeatMapLayer(datasource, null, {


radius: [
'interpolate',
['exponential', 2],
['zoom'],

//For zoom level 1 set the radius to 2 pixels.


1, 2,

//Between zoom level 1 and 19, exponentially scale the radius from 2
pixels to 2 * Math.pow(2, 19 - 1) pixels (524,288 pixels).
19, 2 * Math.pow(2, 19 - 1)
]
};

For an interactive working example, see Consistent zoomable heat map.

Variable binding expressions


Variable binding expressions store the results of a calculation in a variable. So, that the
calculation results can be referenced elsewhere in an expression multiple times. It's a
useful optimization for expressions that involve many calculations.

ノ Expand table

Expression Return Description


type

[ Stores one or more values as variables for use by the var


'let', expression in the child expression that returns the result.
name1: string,
value1: any,
name2: string,
value2: any,

childExpression
]

['var', name: any References a variable that was created using the let
string] expression.

Example

This example uses an expression that calculates the revenue relative to temperature
ratio and then uses a case expression to evaluate different boolean operations on this
value. The let expression is used to store the revenue relative to temperature ratio, so
that it only needs to be calculated once. The var expression references this variable as
often as needed without having to recalculate it.

JavaScript

var layer = new atlas.layer.BubbleLayer(datasource, null, {


color: [
//Divide the point features `revenue` property by the `temperature`
property and store it in a variable called `ratio`.
'let', 'ratio', ['/', ['get', 'revenue'], ['get', 'temperature']],
//Evaluate the child expression in which the stored variable is
used.
[
'case',

//Check to see if the ratio is less than 100, return 'red'.


['<', ['var', 'ratio'], 100],
'red',

//Check to see if the ratio is less than 200, return 'green'.


['<', ['var', 'ratio'], 200],
'green',
//Return `blue` for values greater or equal to 200.
'blue'
]
]
});

Next steps
See the following articles for more code samples that implement expressions:

Add a symbol layer

Add a bubble layer

Add a line layer

Add a polygon layer

Add a heat map layer

Learn more about the layer options that support expressions:

BubbleLayerOptions

HeatMapLayerOptions

LineLayerOptions

PolygonLayerOptions

SymbolLayerOptions

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add custom protocol PMTiles
Article • 10/29/2024

The Azure Maps Web SDK supports custom protocols such as PMTiles . The
pmtiles:// protocol is used to reference PMTiles archives, which are single-file formats

for storing tiled data such as vector and raster maps. This protocol allows Azure Maps to
access specific tiles within a PMTiles archive using an HTTP request, fetching only the
necessary data on demand.

Add custom protocol


By using the addProtocol function, which registers a callback triggered before any AJAX
request made by the library, you can intercept, modify, and return the request for
further processing and rendering. This enables the implementation of a custom callback
function to load resources when a URL starts with the designated custom schema.

The first step is to add a reference to the protocol. The following example references the
pmtiles library:

HTML

<script src="https://unpkg.com/pmtiles@3.2.0/dist/pmtiles.js"></script>

Next, initialize the MapLibre PMTiles protocol.

JavaScript

//Initialize the plugin.


const protocol = new pmtiles.Protocol();
atlas.addProtocol("pmtiles", protocol.tile);

Add PMTiles as a map source


The following sample uses the Overture building dataset to add building data over
the basemap.

PMTiles are added as a map source during the map event. Once added, the specified
URI scheme is available to the Azure Maps Web SDK. In the following sample, the
PMTiles URL is added as a VectorTileSource .
JavaScript

const PMTILES_URL = "https://overturemaps-tiles-us-west-2-


beta.s3.amazonaws.com/2024-07-22/buildings.pmtiles";
//Add the source to the map.
map.sources.add(
new atlas.source.VectorTileSource("my_source", {
type: "vector",
url: `pmtiles://${PMTILES_URL}`,
})
);

7 Note

Using the pmtiles:// protocol automatically creates the minzoom and maxzoom
properties for the source.

Enhance map with Overture data


Overture provides a unified and comprehensive data schema designed to organize
and structure geospatial data effectively. This schema is divided into different themes,
each representing a specific type of geospatial information.

The following sample uses the building theme's properties (for example, building type
and height) to demonstrate building extrusion and differentiate between building
categories on the basemap, rather than just showing building footprints.

JavaScript

//Create a polygon extrusion layer.


layer = new atlas.layer.PolygonExtrusionLayer(
"my_source",
"building",
{
sourceLayer: "building",
height: ["get", "height"],
fillOpacity: 0.5,
fillColor: [
"case",
['==', ['get', 'subtype'], 'agricultural'],
"wheat",
['==', ['get', 'subtype'], 'civic'],
"teal",
['==', ['get', 'subtype'], 'commercial'],
"blue",
['==', ['get', 'subtype'], 'education'],
"aqua",
['==', ['get', 'subtype'], 'entertainment'],
"pink",
['==', ['get', 'subtype'], 'industrial'],
"yellow",
['==', ['get', 'subtype'], 'medical'],
"red",
['==', ['get', 'subtype'], 'military'],
"darkgreen",
['==', ['get', 'subtype'], 'outbuilding'],
"white",
['==', ['get', 'subtype'], 'religious'],
"khaki",
['==', ['get', 'subtype'], 'residential'],
"green",
['==', ['get', 'subtype'], 'service'],
"gold",
['==', ['get', 'subtype'], 'transportation'],
"orange",
"grey",
],
filter: ['any', ['==', ['geometry-type'], 'Polygon'], ['==', ['geometry-
type'], 'MultiPolygon']]
}
);

The following image shows a screenshot displaying the extrusion of buildings of


different types near Central Park in New York City.

For a fully functional sample with source code, see Azure Maps Samples GitHub Repo .
Next Steps
The following articles are related to custom protocol PMTiles:

Create Data Source

Data Driven Style Expressions

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


How to use image templates
Article • 08/30/2024

Images can be used with HTML markers and various layers within the Azure Maps web
SDK:

Symbol layers can render points on the map with an image icon. Symbols can also
be rendered along a lines path.
Polygon layers can be rendered with a fill pattern image.
HTML markers can render points using images and other HTML elements.

In order to ensure good performance with layers, load the images into the map image
sprite resource before rendering. The IconOptions, of the SymbolLayer, preloads a
couple of marker images in a handful of colors into the map image sprite, by default.
These marker images and more are available as SVG templates. They can be used to
create images with custom scales, or used as a customer primary and secondary color. In
total there are 42 image templates provided: 27 symbol icons and 15 polygon fill
patterns.

Image templates can be added to the map image sprite resources by using the
map.imageSprite.createFromTemplate function. This function allows up to five

parameters to be passed in;

JavaScript

createFromTemplate(id: string, templateName: string, color?: string,


secondaryColor?: string, scale?: number): Promise<void>

The id is a unique identifier you create. The id is assigned to the image when it's
added to the maps image sprite. Use this identifier in the layers to specify which image
resource to render. The templateName specifies which image template to use. The color
option sets the primary color of the image and the secondaryColor options sets the
secondary color of the image. The scale option scales the image template before
applying it to the image sprite. When the image is applied to the image sprite, it
converts into a PNG. To ensure crisp rendering, it's better to scale up the image
template before adding it to the sprite, than to scale it up in a layer.

This function asynchronously loads the image into the image sprite. Thus, it returns a
Promise that you can wait for this function to complete.

The following code shows how to create an image from one of the built-in templates,
then use it with a symbol layer.
JavaScript

map.imageSprite.createFromTemplate('myTemplatedIcon', 'marker-flat', 'teal',


'#fff').then(function () {

//Add a symbol layer that uses the custom created icon.


map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'myTemplatedIcon'
}
}));
});

Use an image template with a symbol layer


Once an image template is loaded into the map image sprite, it can be rendered as a
symbol in a symbol layer by referencing the image resource ID in the image option of
the iconOptions .

The Symbol layer with built-in icon template sample demonstrates how to do this by
rendering a symbol layer using the marker-flat image template with a teal primary
color and a white secondary color, as shown in the following screenshot.

For the source code for this sample, see Symbol layer with built-in icon template sample
code .

Use an image template along a lines path


Once an image template is loaded into the map image sprite, it can be rendered along
the path of a line by adding a LineString to a data source and using a symbol layer with
a lineSpacing option and by referencing the ID of the image resource in the image
option of th iconOptions .

The Line layer with built-in icon template demonstrates how to do this. As show in the
following screenshot, it renders a red line on the map and uses a symbol layer using the
car image template with a dodger blue primary color and a white secondary color. For

the source code for this sample, see Line layer with built-in icon template sample
code .

 Tip

If the image template points up, set the rotation icon option of the symbol layer
to 90 if you want it to point in the same direction as the line.

Use an image template with a polygon layer


Once an image template is loaded into the map image sprite, it can be rendered as a fill
pattern in a polygon layer by referencing the image resource ID in the fillPattern
option of the layer.

The Fill polygon with built-in icon template sample demonstrates how to render a
polygon layer using the dot image template with a red primary color and a transparent
secondary color, as shown in the following screenshot. For the source code for this
sample, see Fill polygon with built-in icon template sample code .

 Tip

Setting the secondary color of fill patterns makes it easier to see the underlying
map will still providing the primary pattern.

Use an image template with an HTML marker


An image template can be retrieved using the altas.getImageTemplate function and
used as the content of an HTML marker. The template can be passed into the
htmlContent option of the marker, and then customized using the color ,

secondaryColor , and text options.

The HTML Marker with built-in icon template sample demonstrates this using the
marker-arrow template with a red primary color, a pink secondary color, and a text value

of "00", as shown in the following screenshot. For the source code for this sample, see
HTML Marker with built-in icon template sample code .

 Tip

Image templates can be used outside of the map too. The getImageTemplate
funciton returns an SVG string that has placeholders; {color} , {secondaryColor} ,
{scale} , {text} . Replace these placeholder values to create a valid SVG string. You

can then either add the SVG string directly to the HTML DOM or convert it into a
data URI and insert it into an image tag. For example:

JavaScript

//Retrieve an SVG template and replace the placeholder values.


var svg = atlas.getImageTemplate('marker').replace(/{color}/,
'red').replace(/{secondaryColor}/, 'white').replace(/{text}/,
'').replace(/{scale}/, 1);

//Convert to data URI for use in image tags.


var dataUri = 'data:image/svg+xml;base64,' + btoa(svg);

Create custom reusable templates


If your application uses the same icon within different modules or if you're creating a
module that adds more image templates, you can easily add and retrieve these icons
from the Azure Maps web SDK. Use the following static functions on the atlas
namespace.
ノ Expand table

Name Return Description


Type

addImageTemplate(templateName: string, template: Adds a custom SVG image


string, override: boolean) template to the atlas
namespace.

getImageTemplate(templateName: string, scale?: string Retrieves an SVG template by


number) name.

getAllImageTemplateNames() string[] Retrieves an SVG template by


name.

SVG image templates support the following placeholder values:

ノ Expand table

Placeholder Description

{color} The primary color.

{secondaryColor} The secondary color.

{scale} The SVG image is converted to an png image when added to the map image
sprite. This placeholder can be used to scale a template before it's converted
to ensure it renders clearly.

{text} The location to render text when used with an HTML Marker.

The Add custom icon template to atlas namespace sample demonstrates how to take
an SVG template, and add it to the Azure Maps web SDK as a reusable icon template, as
shown in the following screenshot. For the source code for this sample, see Add custom
icon template to atlas namespace sample code .

List of image templates


This table lists all image templates currently available within the Azure Maps web SDK.
The template name is above each image. By default, the primary color is blue and the
secondary color is white. To make the secondary color easier to see on a white
background, the following images have the secondary color set to black.

Symbol icon templates

marker

marker-thick

marker-circle

marker-flat
marker-square

marker-square-cluster

marker-arrow

marker-ball-pin

marker-square-rounded

marker-square-rounded-cluster

flag

flag-triangle

triangle

triangle-thick
triangle-arrow-up

triangle-arrow-left

hexagon

hexagon-thick

hexagon-rounded

hexagon-rounded-thick

pin

pin-round

rounded-square

rounded-square-thick
arrow-up

arrow-up-thin

car

Polygon fill pattern templates

checker

checker-rotated

circles

circles-spaced
diagonal-lines-up

diagonal-lines-down

diagonal-stripes-up

diagonal-stripes-down

grid-lines

rotated-grid-lines

rotated-grid-stripes

x-fill
zig-zag

zig-zag-vertical

dots

Preloaded image icons

The map preloads a set of icons into the maps image sprite using the marker , pin , and
pin-round templates. These icon names and their color values are listed in the following

table.
ノ Expand table

icon name color secondaryColor

marker-black #231f20 #ffffff

marker-blue #1a73aa #ffffff

marker-darkblue #003963 #ffffff

marker-red #ef4c4c #ffffff

marker-yellow #f2c851 #ffffff

pin-blue #2072b8 #ffffff

pin-darkblue #003963 #ffffff

pin-red #ef4c4c #ffffff

pin-round-blue #2072b8 #ffffff

pin-round-darkblue #003963 #ffffff

pin-round-red #ef4c4c #ffffff

Try it now tool


With the following tool, you can render the different built-in image templates in various
ways and customize the primary and secondary colors and scale.

Next steps
Learn more about the classes and methods used in this article:

ImageSpriteManager

atlas namespace

See the following articles for more code samples where image templates can be used:

Add a symbol layer

Add a line layer


Add a polygon layer

Add HTML Makers

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Handle map events
Article • 08/30/2024

This article shows you how to use map events class. The property highlight events on
the map and on different layers of the map. You can also highlight events when you
interact with an HTML marker.

Interact with the map


The Map Events sample highlights the name of the events that are firing as you
interact with the map. For the source code for this sample, see Map Events source
code .

Interact with map layers


The Layer Events sample highlights the name of the events that are firing as you
interact with the Symbol Layer. The symbol, bubble, line, and polygon layer all support
the same set of events. The heat map and tile layers don't support any of these events.
For the source code for this sample, see Layer Events source code .

Interact with HTML Marker


The HTML marker layer events sample highlights the name of the events that are
firing as you interact with the HTML marker layer. For the source code for this sample,
see HTML marker layer Events source code .

The following table lists all supported map class events.

ノ Expand table

Event Description

boxzoomend Fired when a "box zoom" interaction ends.


Event Description

boxzoomstart Fired when a "box zoom" interaction starts.

click Fired when a pointing device is pressed and released at the same point on
the map.

close Fired when the popup is closed manually or programmatically.

contextmenu Fired when the right button of the mouse is clicked.

data Fired when any map data loads or changes.

dataadded Fired when shapes are added to the DataSource .

dataremoved Fired when shapes are removed from the DataSource .

datasourceupdated Fired when the DataSource object is updated.

dblclick Fired when a pointing device is clicked twice at the same point on the map.

drag Fired repeatedly during a "drag to pan" interaction on the map, popup, or
HTML marker.

dragend Fired when a "drag to pan" interaction ends on the map, popup, or HTML
marker.

dragstart Fired when a "drag to pan" interaction starts on the map, popup, or HTML
marker.

error Fired when an error occurs.

idle Fired after the last frame rendered before the map enters an "idle" state:

No camera transitions are in progress.


All currently requested tiles have loaded.
All fade/transition animations have completed.

keydown Fired when a key is pressed down.

keypress Fired when a key that produces a typeable character (an ANSI key) is
pressed.

keyup Fired when a key is released.

layeradded Fired when a layer is added to the map.

layerremoved Fired when a layer is removed from the map.

load Fired immediately after all necessary resources have been downloaded and
the first visually complete rendering of the map has occurred.
Event Description

mousedown Fired when a pointing device is pressed within the map or when on top of an
element.

mouseenter Fired when a pointing device is initially moved over the map or an element.

mouseleave Fired when a pointing device is moved out the map or an element.

mousemove Fired when a pointing device is moved within the map or an element.

mouseout Fired when a point device leaves the map's canvas our leaves an element.

mouseover Fired when a pointing device is moved over the map or an element.

mouseup Fired when a pointing device is released within the map or when on top of
an element.

move Fired repeatedly during an animated transition from one view to another, as
the result of either user interaction or methods.

moveend Fired just after the map completes a transition from one view to another, as
the result of either user interaction or methods.

movestart Fired just before the map begins a transition from one view to another, as
the result of either user interaction or methods.

open Fired when the popup is opened manually or programmatically.

pitch Fired whenever the map's pitch (tilt) changes as the result of either user
interaction or methods.

pitchend Fired immediately after the map's pitch (tilt) finishes changing as the result
of either user interaction or methods.

pitchstart Fired whenever the map's pitch (tilt) begins a change as the result of either
user interaction or methods.

ready Fired when the minimum required map resources are loaded before the map
is ready to be programmatically interacted with.

render Fired whenever the map is drawn to the screen, as the result of:

A change to the map's position, zoom, pitch, or bearing.


A change to the map's style.
A change to a DataSource source.
The loading of a vector tile, GeoJSON file, glyph, or sprite.

resize Fired immediately after the map has been resized.

rotate Fired repeatedly during a "drag to rotate" interaction.


Event Description

rotateend Fired when a "drag to rotate" interaction ends.

rotatestart Fired when a "drag to rotate" interaction starts.

shapechanged Fired when a shape object property is changed.

sourcedata Fired when one of the map's sources loads or changes, including if a tile
belonging to a source loads or changes.

sourceadded Fired when a DataSource or VectorTileSource is added to the map.

sourceremoved Fired when a DataSource or VectorTileSource is removed from the map.

styledata Fired when the map's style loads or changes.

styleimagemissing Fired when a layer tries to load an image from the image sprite that doesn't
exist

tokenacquired Fired when a Microsoft Entra access token is obtained.

touchcancel Fired when a touchcancel event occurs within the map.

touchend Fired when a touchend event occurs within the map.

touchmove Fired when a touchmove event occurs within the map.

touchstart Fired when a touchstart event occurs within the map.

wheel Fired when a mouse wheel event occurs within the map.

zoom Fired repeatedly during an animated transition from one zoom level to
another, as the result of either user interaction or methods.

zoomend Fired just after the map completes a transition from one zoom level to
another, as the result of either user interaction or methods.

zoomstart Fired just before the map begins a transition from one zoom level to
another, as the result of either user interaction or methods.

Next steps
See the following articles for full code examples:

Using the Azure Maps Services module

Code samples
Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Building an accessible application
Article • 05/15/2023

Upwards of 20% of internet users have a need for accessible web applications. As such,
it's important to make sure your application is designed such that any user can easily
use it. Rather than thinking of accessibility as a set of tasks to complete, think of it as
part of your overall user experience. The more accessible your application, the more
people who can use it.

When it comes to rich interactive content like a map, some common accessibility
considerations are:

Support the screen reader for users who have difficulty seeing the web application.
Have multiple methods for interacting with and navigating the web application
such as mouse, touch, and keyboard.
Ensure color contrast is such that colors don't blend together and become hard to
distinguish from each other.

The Azure Maps Web SDK comes prebuilt with accessibility features such as:

Screen reader descriptions when the map moves and when the user focuses on a
control or popup.
Mouse, touch, and keyboard support.
Accessible color contrast support in the road map style.
High contrast support.

For accessibility conformance details for all Microsoft products, see Accessibility
Conformance Reports . Search for "Azure Maps web" to find the document specifically
for the Azure Maps Web SDK.

Navigating the map


There are several different ways in which the map can be zoomed, panned, rotated, and
pitched. The following details all the different ways to navigate the map.

Zoom the map

Using a mouse, double-click the map to zoom in one level.


Using a mouse, scroll the wheel to zoom the map.
Using a touch screen, touch the map with two fingers and pinch together to zoom
out or spread the fingers apart to zoom in.
Using a touch screen, double tap the map to zoom in one level.
With the map focused, use the Plus sign ( + ) or Equals sign ( = ) to zoom in one
level.
With the map focused, use the Minus sign, Hyphen ( - ), or Underscore ( _ ) to zoom
out one level.
Using the zoom control with a mouse, touch or keyboard tab/enter keys.
Press and hold the Shift button and press the left mouse button down on the
map and drag to draw out an area to zoom the map into.
Using some multi-touch pads, dragging two fingers up to zoom out, or down to
zoom in.

Pan the map

Using a mouse, press down with the left mouse button on the map and drag in any
direction.
Using a touch screen, touch the map and drag in any direction.
With the map focused, use the arrow keys to move the map.

Rotate the map

Using a mouse, press down with the right mouse button on the map and drag left
or right.
Using a touch screen, touch the map with two fingers and rotate.
With the map focused, use the shift key and the left or right arrow keys.
Using the rotation control with a mouse, touch or keyboard tab/enter keys.

Pitch the map

Using the mouse, press down with the right mouse button on the map and drag
up or down.
Using a touch screen, touch the map with two fingers and drag them up or down
together.
With the map focused, use the shift key plus the up or down arrow keys.
Using the pitch control with a mouse, touch or keyboard tab/enter keys.

Change the Map Style


Not all developers want all possible map styles to be available in their application. If the
developer displays the style picker control of the map, then the user may change the
map style using the mouse, a touch, or the keyboard with the tab or enter key. The
developer can specify which map styles they want to make available in the map style
picker control. Also, the developer can programmatically set and change the map style.

Use high contrast


When the map control is loaded, it checks to see if high contrast is enabled and
the browser supports it.
The map control doesn't monitor the high contrast mode of the device. If the
device mode changes, the map won't. Thus, the user needs to reload the map by
refreshing the page.
When high contrast is detected the map style automatically switches to high
contrast, and all built-in controls use a high contrast style. For example,
ZoomControl, PitchControl, CompassControl, StyleControl, and other built-in
controls, use a high contrast style.
There are two types of high contrast, light and dark. If the type of high contrast can
be detected by the map controls, then the behavior of the map adjusts
accordingly. If light, then the grayscale_light map style is loaded. If the type can't
be detected or is dark, then the high_contrast_dark style is loaded.
If creating custom controls, it's useful to know if the built-in controls are using a
high contrast style. Developers can add a css class on the map container div to
check. The css classes that would be added are high-contrast-dark and high-
contrast-light . To check using JavaScript, use:

JavaScript

map.getMapContainer().classList.contains("high-contrast-dark")

or, use:

JavaScript

map.getMapContainer().classList.contains("high-contrast-light")

Keyboard shortcuts
The map has keyboard shortcuts built in that make it easier to use the map. These
keyboard shortcuts work when the map has focus.

Key Action

Tab Navigate across the controls and popups in the map.

ESC Move focus from any element in the map to the top-level
map element.

Ctrl + Shift + D Toggle screen reader detail level.


Key Action

Left arrow key Pan the map left 100 pixels

Right arrow key Pan the map right 100 pixels

Down arrow key Pan the map down 100 pixels

Up arrow key Pan the map up 100 pixels

Shift + up arrow Increase map pitch by 10 degrees

Shift + down arrow Decrease map pitch by 10 degrees

Shift + right arrow Rotate the map 15 degrees clockwise

Shift + left arrow Rotate the map 15 degrees counterclockwise

Plus sign ( + ) or *Equals sign ( = ) Zoom in

Minus sign, Hyphen ( - ), or Zoom out


*Underscore ( _ )

Shift + mouse drag on map to Zoom into area


draw area

* These key shortcuts usually share the same key on a keyboard. These shortcuts were
added to improve the user experience. It also doesn't matter if the user uses the shift
key or not for these shortcuts.

Screen Reader support


Users can navigate the map using the keyboard. If a screen reader is running, the map
notifies the user of changes to its state. For example, users are notified of map changes
when the map is panned or zoomed. By default, the map provides simplified
descriptions that exclude the zoom level and coordinates of the center of the map. The
user can toggle the detail level of these descriptions by using the keyboard short cut
Ctrl + Shift + D .

Any additional information that is placed on the base map should have corresponding
textual information for screen reader users. Be sure to add Accessible Rich Internet
Applications (ARIA) , alt, and title attributes where appropriate.

Make popups keyboard accessible


A marker or symbol is often used to represent a location on the map. Additional
information about the location is typically displayed in a popup when the user interacts
with the marker. In most applications, popups appear when a user selects a marker.
However, clicking and tapping require the user to use a mouse and a touch screen,
respectively. A good practice is to make popups accessible when using a keyboard. This
functionality can be achieved by creating a popup for each data point and adding it to
the map.

The Accessible popups example loads points of interests on the map using a symbol
layer and adds a popup to the map for each point of interest. A reference to each popup
is stored in the properties of each data point. It can also be retrieved for a marker, such
as when a marker is selected. When focused on the map, pressing the tab key allows the
user to step through each popup on the map.

More accessibility tips


Here are some more tips to make your web-mapping application more accessible.

If displaying many interactive point data on the map, consider reducing the clutter
and use clustering.
Ensure color contrast ratio between text/symbols and background colors is 4.5:1 or
more.
Keep your screen reader (ARIA, alt, and title attributes) messages short, descriptive,
and meaningful. Avoid unnecessary jargon and acronyms.
Try to optimize messages sent to the screen reader to provide short meaningful
information that is easy for the user to digest. For example, if you want to update
the screen reader at a high frequency, such as when the map is moving, consider
doing the following points:
Wait until the map has finished moving to update the screen reader.
Throttle the updates to once every few seconds.
Combine messages together in a logical way.
Avoid using color as the only means of conveying information. Use text, icons, or
patterns to supplement or replace the color. Some considerations:
If using a bubble layer to show the relative value between data points, consider
scaling the radius of each bubble, coloring the bubble, or both.
Consider using a symbol layer with different icons for different metric
categories, such as triangles, stars, and squares. The symbol layer also supports
scaling the size of the icon. A text label can also be displayed.
If displaying line data, the width can be used to represent weight or size. A
dash-array pattern can be used to represent different categories of lines. A
symbol layer can be used in combination with a line to overlay icons along the
line. Using an arrow icon is useful for showing the flow or direction of the line.
If displaying polygon data, a pattern, such as stripes, can be used as an
alternative to color.
Some visualizations such as heatmaps, tile layers, and image layers aren't
accessible for users with vision impairments. Some considerations:
Have the screen reader describe what the layer is displaying when added to the
map. For example, if a weather radar tile layer is displayed, then have the screen
reader say "Weather radar data is overlaid on the map."
Limit the amount of functionality that requires a mouse hover. These functionalities
are inaccessible to users who are using a keyboard or touch device to interact with
your application. Note, it's still a good practice to have a hover style for interactive
content such as clickable icons, links, and buttons.
Try navigating your application using the keyboard. Make sure tab ordering is
logical.
If creating keyboard shortcuts, try to limit it to two keys or less.

Next steps
Learn about accessibility in the Web SDK modules.

Drawing tools accessibility

Learn about developing accessible apps:

Accessibility in Action Digital Badge learning path


Take a look at these useful accessibility tools:

Developing accessible apps

WAI-ARIA Overview

Web Accessibility Evaluation Tool (WAVE)

WebAim color contrast checker

No Coffee Vision Simulator


Use the drawing tools module
Article • 06/30/2023

The Azure Maps Web SDK provides a drawing tools module . This module makes it
easy to draw and edit shapes on the map using an input device such as a mouse or
touch screen. The core class of this module is the drawing manager. The drawing
manager provides all the capabilities needed to draw and edit shapes on the map. It can
be used directly, and it's integrated with a custom toolbar UI. You can also use the built-
in drawing toolbar class.

Loading the drawing tools module in a


webpage
1. Create a new HTML file and implement the map as usual.
2. Load the Azure Maps drawing tools module. You can load it in one of two ways:

Use the globally hosted, Azure Content Delivery Network version of the Azure
Maps services module. Add reference to the JavaScript and CSS stylesheet in
the <head> element of the file:

HTML

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-
drawing.min.css" type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/drawing/1/atlas-
drawing.min.js"></script>

Or, you can load the drawing tools module for the Azure Maps Web SDK
source code locally by using the azure-maps-drawing-tools npm package,
and then host it with your app. This package also includes TypeScript
definitions. Use this command:

npm install azure-maps-drawing-tools

Then, import the JavaScript in a source file:

JavaScript

import * as drawing from "azure-maps-drawing-tools";


You would also need to embed the CSS Style Sheet for various controls to
display correctly. If you're using a JavaScript bundler to bundle the
dependencies and package your code, refer to your bundler's documentation
on how it's done. For Webpack , it's commonly done via a combination of
style-loader and css-loader with documentation available at style-

loader .

To begin, install style-loader and css-loader:

PowerShell

npm install --save-dev style-loader css-loader

Inside your source file, import atlas-drawing.min.css:

JavaScript

import "azure-maps-drawing-tools/dist/atlas-drawing.min.css";

Then add loaders to the module rules portion of the Webpack config:

JavaScript

module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"]
}
]
}
};

Use the drawing manager directly


Once the drawing tools module is loaded in your application, you can enable drawing
and editing capabilities using the drawing manager. You can specify options for the
drawing manager while instantiating it or alternatively use the
drawingManager.setOptions() function.

Set the drawing mode


The following code creates an instance of the drawing manager and sets the drawing
mode option.

JavaScript

//Create an instance of the drawing manager and set drawing mode.


drawingManager = new atlas.drawing.DrawingManager(map,{
mode: "draw-polygon"
});

The following image is an example of drawing mode of the DrawingManager . Select any
place on the map to start drawing a polygon.

Set the interaction type


The drawing manager supports three different ways of interacting with the map to draw
shapes.

click - Coordinates are added when the mouse or touch is clicked.

freehand - Coordinates are added when the mouse or touch is dragged on the
map.
hybrid - Coordinates are added when the mouse or touch is clicked or dragged.

The following code enables the polygon drawing mode and sets the type of drawing
interaction that the drawing manager should adhere to freehand .

JavaScript
//Create an instance of the drawing manager and set drawing mode.
drawingManager = new atlas.drawing.DrawingManager(map,{
mode: "draw-polygon",
interactionType: "freehand"
});

Customizing drawing options


The previous examples demonstrated how to customize drawing options while
instantiating the Drawing Manager. You can also set the Drawing Manager options by
using the drawingManager.setOptions() function.

The Drawing manager options can be used to test out customization of all options for
the drawing manager using the setOptions function. For the source code for this
sample, see Drawing manager options source code .

Put a shape into edit mode


Programmatically put an existing shape into edit mode by passing it into the drawing
managers edit function. If the shape is a GeoJSON feature, wrap it with the atls.Shape
class before passing it in.

To programmatically take a shape out of edit mode, set the drawing managers mode to
idle .

JavaScript
//If you are starting with a GeoJSON feature, wrap it with the atlas.Shape
class.
var feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0,0]
},
"properties": {}
};

var shape = new atlas.Shape(feature);

//Pass the shape into the edit function of the drawing manager.
drawingManager.edit(shape);

//Later, to programmatically take shape out of edit mode, set mode to idle.
drawingManager.setOptions({ mode: 'idle' });

7 Note

When a shape is passed into the edit function of the drawing manager, it is added
to the data source maintained by the drawing manager. If the shape was previously
in another data source, it will be removed from that data source.

To add shapes to the drawing manager so the end user can view and edit, but don't
want to programmatically put them into edit mode, retrieve the data source from the
drawing manager and add your shapes to it.

JavaScript

//The shape(s) you want to add to the drawing manager so


var shape = new atlas.Shape(feature);

//Retrieve the data source from the drawing manager.


var source = drawingManager.getSource();

//Add your shape.


source.add(shape);

//Alternatively, load in a GeoJSON feed using the sources importDataFromUrl


function.
source.importDataFromUrl('yourFeatures.json');

The following table lists the type of editing supported by different types of shape
features.
Shape feature Edit points Rotate Delete shape

Point ✓ ✓

LineString ✓ ✓ ✓

Polygon ✓ ✓ ✓

MultiPoint ✓ ✓

MultiLineString ✓ ✓

MultiPolygon ✓ ✓

Circle ✓ ✓

Rectangle ✓ ✓ ✓

Next steps
Learn how to use additional features of the drawing tools module:

Add a drawing toolbar

Get shape data

React to drawing events

Interaction types and keyboard shortcuts

Learn more about the classes and methods used in this article:

Map

Drawing manager

Drawing toolbar
Add a drawing tools toolbar to a map
Article • 08/30/2024

This article shows you how to use the Drawing Tools module and display the drawing
toolbar on the map. The Drawing toolbar control adds the drawing toolbar on the map.
You learn how to create maps with only one and all drawing tools and how to customize
the rendering of the drawing shapes in the drawing manager.

Add drawing toolbar


The following code creates an instance of the drawing manager and displays the toolbar
on the map.

JavaScript

//Create an instance of the drawing manager and display the drawing toolbar.
drawingManager = new atlas.drawing.DrawingManager(map, {
toolbar: new atlas.control.DrawingToolbar({
position: 'top-right',
style: 'dark'
})
});

For a complete working sample that demonstrates how to add a drawing toolbar to
your map, see Add drawing toolbar to map in the Azure Maps Samples . For the
source code for this sample, see Add drawing toolbar to map source code .


Limit displayed toolbar options
The following code creates an instance of the drawing manager and displays the toolbar
with just a polygon drawing tool on the map.

JavaScript

//Create an instance of the drawing manager and display the drawing toolbar
with polygon drawing tool.
drawingManager = new atlas.drawing.DrawingManager(map, {
toolbar: new atlas.control.DrawingToolbar({
position: 'top-right',
style: 'light',
buttons: ["draw-polygon"]
})
});

The following screenshot shows a sample of an instance of the drawing manager that
displays the toolbar with just a single drawing tool on the map:

Change drawing rendering style


The style of the shapes that are drawn can be customized by retrieving the underlying
layers of the drawing manager by using the drawingManager.getLayers() and
drawingManager.getPreviewLayers() functions and then setting options on the individual

layers. The drag handles that appear for coordinates when editing a shape are HTML
markers. The style of the drag handles can be customized by passing HTML marker
options into the dragHandleStyle and secondaryDragHandleStyle options of the drawing
manager.

The following code gets the rendering layers from the drawing manager and modifies
their options to change rendering style for drawing. In this case, points are rendered
with a blue marker icon. Lines are red and four pixels wide. Polygons have a green fill
color and an orange outline. It then changes the styles of the drag handles to be square
icons.

JavaScript

//Get rendering layers of drawing manager.


var layers = drawingManager.getLayers();

//Change the icon rendered for points.


layers.pointLayer.setOptions({
iconOptions: {
image: 'marker-blue'
}
});

//Change the color and width of lines.


layers.lineLayer.setOptions({
strokeColor: 'red',
strokeWidth: 4
});

//Change fill color of polygons.


layers.polygonLayer.setOptions({
fillColor: 'green'
});

//Change the color of polygon outlines.


layers.polygonOutlineLayer.setOptions({
strokeColor: 'orange'
});

//Get preview rendering layers from the drawing manager and modify line
styles to be dashed.
var previewLayers = drawingManager.getPreviewLayers();
previewLayers.lineLayer.setOptions({ strokeColor: 'red', strokeWidth: 4,
strokeDashArray: [3,3] });
previewLayers.polygonOutlineLayer.setOptions({ strokeColor: 'orange',
strokeDashArray: [3, 3] });

//Update the style of the drag handles that appear when editing.
drawingManager.setOptions({
//Primary drag handle that represents coordinates in the shape.
dragHandleStyle: {
anchor: 'center',
htmlContent: '<svg width="15" height="15" viewBox="0 0 15 15"
xmlns="http://www.w3.org/2000/svg" style="cursor:pointer"><rect x="0" y="0"
width="15" height="15" style="stroke:black;fill:white;stroke-width:4px;"/>
</svg>',
draggable: true
},

//Secondary drag handle that represents mid-point coordinates that users


can grab to add new coordinates in the middle of segments.
secondaryDragHandleStyle: {
anchor: 'center',
htmlContent: '<svg width="10" height="10" viewBox="0 0 10 10"
xmlns="http://www.w3.org/2000/svg" style="cursor:pointer"><rect x="0" y="0"
width="10" height="10" style="stroke:white;fill:black;stroke-width:4px;"/>
</svg>',
draggable: true
}
});

For a complete working sample that demonstrates how to customize the rendering of
the drawing shapes in the drawing manager by accessing the rendering layers, see
Change drawing rendering style in the Azure Maps Samples . For the source code
for this sample, see Change drawing rendering style source code .

7 Note

When in edit mode, shapes can be rotated. Rotation is supported from MultiPoint,
LineString, MultiLineString, Polygon, MultiPolygon, and Rectangle geometries. Point
and Circle geometries can not be rotated.

Next steps
Learn how to use more features of the drawing tools module:

Get shape data

React to drawing events

Interaction types and keyboard shortcuts

Learn more about the classes and methods used in this article:

Map

Drawing toolbar

Drawing manager

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Get shape data
Article • 09/03/2024

This article shows you how to get data of shapes that are drawn on the map. We use the
drawingManager.getSource() function inside drawing manager. There are various
scenarios when you want to extract geojson data of a drawn shape and use it elsewhere.

Get data from drawn shape


The following function gets the drawn shape's source data and outputs it to the screen.

JavaScript

function getDrawnShapes() {
var source = drawingManager.getSource();

document.getElementById('CodeOutput').value =
JSON.stringify(source.toJson(), null, ' ');
}

The Get drawn shapes from drawing manager code sample allows you to draw a
shape on a map and then get the code used to create those drawings by using the
drawing managers drawingManager.getSource() function. For the source code for this
sample, see Get drawn shapes from drawing manager sample code .

Next steps
Learn how to use other features of the drawing tools module:

React to drawing events


Interaction types and keyboard shortcuts

Learn more about the classes and methods used in this article:

Map

Drawing manager

Drawing toolbar

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a snap grid to the map
Article • 09/05/2024

A snap grid makes it easier to draw shapes with shared edges and nodes, and straighter
lines. Snapping shapes to a grid is useful when drawing building outlines or network
paths on the map.

The resolution of the snapping grid is in pixels. The grid is square and relative to the
nearest integer zoom level. The grid scales by a factor of two relative to physical real-
world area with each zoom level.

Use a snap grid


Create a snap grid using the atlas.drawing.SnapGridManager class and pass in a
reference to the map you want to connect the manager to. Set the showGrid option to
true if you want to make the grid visible. To snap a shape to the grid, pass it into the

snap grid managers snapShape function. If you want to snap an array of positions, pass it
into the snapPositions function.

The Use a snapping grid sample snaps an HTML marker to a grid when dragged.
Drawing tools are used to snap drawn shapes to the grid when the drawingcomplete
event fires. For the source code for this sample, see Use a snapping grid source code .

Snap grid options


The Snap grid options sample shows the different customization options available for
the snap grid manager. The grid line styles can be customized by retrieving the
underlying line layer using the snap grid managers getGridLayer function. For the
source code for this sample, see Snap grid options source code .

Next steps
Learn how to use other features of the drawing tools module:

Get shape data

React to drawing events

Interaction types and keyboard shortcuts

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Drawing tools events
Article • 09/05/2024

When using drawing tools on a map, it's useful to react to certain events as the user
draws on the map. This table lists all events supported by the DrawingManager class.

ノ Expand table

Event Description

drawingchanged Fired when any coordinate in a shape is added or changed.

drawingchanging Fired when any preview coordinate for a shape is being displayed. For
example, this event fires multiple times as a coordinate is dragged.

drawingcomplete Fired when a shape completes drawing or is taken out of edit mode.

drawingerased Fired when a shape is erased from the drawing manager when in erase-
geometry mode.

drawingmodechanged Fired when the drawing mode changes. The new drawing mode is passed
into the event handler.

drawingstarted Fired when the user starts drawing a shape or puts a shape into edit mode.

For a complete working sample of how to display data from a vector tile source on the
map, see Drawing tools events in the Azure Maps Samples . This sample enables you
to draw shapes on the map and watch as the events fire. For the source code for this
sample, see Drawing tools events sample code .

The following image shows a screenshot of the complete working sample that
demonstrates how the events in the Drawing Tools module work.

Examples
Let's see some common scenarios that use the drawing tools events.

Select points in polygon area


This code demonstrates how to monitor an event of a user drawing shapes. For this
example, the code monitors shapes of polygons, rectangles, and circles. Then, it
determines which data points on the map are within the drawn area. The
drawingcomplete event is used to trigger the select logic. In the select logic, the code

loops through all the data points on the map. It checks if there's an intersection of the
point and the area of the drawn shape. This example makes use of the open-source
Turf.js library to perform a spatial intersection calculation.

For a complete working sample of how to use the drawing tools to draw polygon areas
on the map with points within them that can be selected, see Select data in drawn
polygon area in the Azure Maps Samples . For the source code for this sample, see
Select data in drawn polygon area sample code .

Draw and search in polygon area


This code searches for points of interests inside the area of a shape after the user
finished drawing the shape. The drawingcomplete event is used to trigger the search
logic. If the user draws a rectangle or polygon, a search inside geometry is performed. If
a circle is drawn, the radius and center position is used to perform a point of interest
search. The drawingmodechanged event is used to determine when the user switches to
the drawing mode, and this event clears the drawing canvas.

For a complete working sample of how to use the drawing tools to search for points of
interests within drawn areas, see Draw and search polygon area in the Azure Maps
Samples . For the source code for this sample, see [Draw and search polygon area
sample code].

Create a measuring tool


The following code shows how the drawing events can be used to create a measuring
tool. The drawingchanging is used to monitor the shape, as it's being drawn. As the user
moves the mouse, the dimensions of the shape are calculated. The drawingcomplete
event is used to do a final calculation on the shape after drawing completes. The
drawingmodechanged event is used to determine when the user is switching into a

drawing mode. Also, the drawingmodechanged event clears the drawing canvas and clears
old measurement information.

For a complete working sample of how to use the drawing tools to measure distances
and areas, see Create a measuring tool in the Azure Maps Samples . For the source
code for this sample, see Create a measuring tool sample code .


Next steps
Learn how to use other features of the drawing tools module:

Get shape data

Interaction types and keyboard shortcuts

Learn more about the services module:

Services module

Check out more code samples:

Code sample page

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Interaction types and keyboard
shortcuts in the drawing tools module
Article • 04/13/2023

This article outlines all the different ways to draw and edit shapes using a mouse, touch
screen, or keyboard shortcuts.

The drawing manager supports three different ways of interacting with the map, to draw
shapes.

click - Coordinates are added when the mouse or touch is clicked.

freehand - Coordinates are added when the mouse or touch is dragged on the
map.
hybrid - Coordinates are added when the mouse or touch is clicked or dragged.

How to draw shapes


Before any shape can be drawn, set the drawingMode option of the drawing manager to
a supported drawing setting. This setting can be programmed, or invoked by pressing
one of the drawing buttons on the toolbar. The drawing mode stays enabled, even after
a shape has been drawn, making it easy to draw more shapes of the same type.
Programmatically set the drawing mode to an idle state. Or, switch to an idle state by
clicking the current drawing modes button on the toolbar.

The next sections outline all the different ways that shapes can be drawn on the map.

How to draw a point


When the drawing manager is in draw-point drawing mode, the following actions can
be done to draw points on the map. These methods work with all interaction modes.

Start drawing

Select the left mouse button, or touch the map to add a point to the map.
If the mouse is over the map, press the F key, and a point is added at the
coordinate of the mouse pointer. This method provides higher accuracy for adding
a point to the map. There's less movement on the mouse due to the pressing
motion of the left mouse button.
Keep clicking, touching, or pressing F to add more points to the map.
Finish drawing

Select any button in the drawing toolbar.


Programmatically set the drawing mode.
Press the C key.

Cancel drawing

Press the Escape key.

How to draw a line


When the drawing manager is in draw-line mode, the following actions can be done to
draw points on the map, depending on the interaction mode.

Start drawing

Click mode
Select left mouse button, or touch the map to add each point of a line on the
map. A coordinate is added to the line for each click or touch.
If the mouse is over the map, press the F key, and a point is added at the
coordinate of the mouse pointer. This method provides higher accuracy for
adding a point to the map. There's less movement on the mouse due to the
pressing motion of the left mouse button.
Keep clicking until all the desired points have been added to the line.
Freehand mode
Press down the left mouse button, or touch-down on the map and drag the
mouse, or touch point around. Coordinates are added to the line as the mouse
or touch point moves around the map. As soon as the mouse or touch-up event
is triggered, the drawing is completed. The drawing managers freehandInterval
option defines the frequency at which coordinates are added.
Hybrid mode
Alternate between click and freehand methods, as desired, while drawing a
single line. For example, click a few points, then hold and drag the mouse to
add a bunch of points, then click a few more.

Finish drawing

Hybrid/Click mode
Double-click the map at the last point.
Click on any button in the drawing toolbar.
Programmatically set the drawing mode.
Freehand mode
Release the mouse button or touch point.
Press the C key.

Cancel drawing

Press the Escape key.

How to draw a polygon


When the drawing manager is in draw-polygon mode, the following actions can be done
to draw points on the map, depending on the interaction mode.

Start drawing

Click mode
Select the left mouse button, or touch the map to add each point of a polygon
on the map. A coordinate is added to the polygon for each click or touch.
If the mouse is over the map, press the F key, and a point is added at the
coordinate of the mouse pointer. This method provides higher accuracy for
adding a point to the map. There's less movement on the mouse due to the
pressing motion of the left mouse button.
Keep clicking until all the desired points have been added to the polygon.
Freehand mode
Press down the left mouse button, or touch-down on the map and drag the
mouse, or touch point around. Coordinates are added to the polygon as the
mouse or touch point moves around the map. As soon as the mouse or touch-
up event is triggered, the drawing is completed. The drawing managers
freehandInterval option defines the frequency at which coordinates are added.
Hybrid mode
Alternate between click and freehand methods, as desired, while drawing a
single polygon. For example, click a few points, then hold and drag the mouse
to add a bunch of points, then click a few more.

Finish drawing

Hybrid/Click mode
Double-click the map at the last point.
Click on the first point in the polygon.
Click on any button in the drawing toolbar.
Programmatically set the drawing mode.
Freehand mode
Release the mouse button or touch point.
Press the C key.

Cancel drawing

Press the Escape key.

How to draw a rectangle


When the drawing manager is in draw-rectangle mode, the following actions can be
done to draw points on the map, depending on the interaction mode. The generated
shape follows the extended GeoJSON specification for rectangles.

Start drawing

Press down the left mouse button, or touch-down on the map to add the first
corner of the rectangle and drag to create the rectangle.

Finish drawing

Release the mouse button or touch point.


Programmatically set the drawing mode.
Press the C key.

Cancel drawing

Press the Escape key.

How to draw a circle


When the drawing manager is in draw-circle mode, the following actions can be done
to draw points on the map, depending on the interaction mode. The generated shape
follows the extended GeoJSON specification for circles.

Start drawing

Press down the left mouse button, or touch-down on the map to add the center of
the circle and drag give the circles a radius.

Finish drawing

Release the mouse button or touch point.


Programmatically set the drawing mode.
Press the C key.

Cancel drawing
Press the Escape key.

Keyboard shortcuts
The drawing tools support keyboard shortcuts. These keyboard shortcuts are functional
when the map is in focus.

Key Action

C Completes any drawing that is in progress and sets the drawing mode to idle. Focus
moves to top-level map element.

Escape Cancels any drawing that is in progress and sets the drawing mode to idle. Focus
moves to top-level map element.

F Adds a coordinate to a point, line, or polygon if the mouse is over the map.
Equivalent action of clicking the map when in click or hybrid mode. This shortcut
allows for more precise and faster drawings. You can use one hand to position the
mouse and other to press the button without moving the mouse from the press
gesture.

Delete or If shapes are selected while the edit mode, delete them.
Backspace

Next steps
Learn more about the classes in the drawing tools module:

Drawing manager

Drawing toolbar
Use Azure Maps TypeScript REST SDK
Article • 10/12/2023

Azure Maps provides a collection of npm modules for the Azure TypeScript REST SDK.
These modules consist of client libraries that make it easy to use the Azure Maps REST
services in web or Node.js applications by using JavaScript or TypeScript. For a complete
list of the available modules, see JavaScript/TypeScript REST SDK Developers Guide.

Use the REST SDK in a web application


1. Using @azure-rest/maps-search as an example, install the package with npm
install @azure-rest/maps-search .

2. Create and authenticate a MapsSearch client. To create a client to access the Azure
Maps Search APIs, you need a credential object. The client supports an [Microsoft
Entra credential] or an Azure Key credential for authentication. You may need to
install either @azure/identity or @azure/core-auth for different authentication
methods.

If you use a subscription key for authentication, install the package with npm
install @azure/core-auth :

JavaScript

import MapsSearch from "@azure-rest/maps-search";


import { AzureKeyCredential } from "@azure/core-auth";

// Get an Azure Maps key at https://azure.com/maps.


const subscriptionKey = "<Your Azure Maps Key>";

// Use AzureKeyCredential with a subscription key.


const credential = new AzureKeyCredential(subscriptionKey);

// Use the credential to create a client


const client = MapsSearch(credential);

If you use Microsoft Entra ID for authentication, install the package with npm
install @azure/identity :

JavaScript

import MapsSearch from "@azure-rest/maps-search";


import { InteractiveBrowserCredential } from "@azure/identity";
// Enter your Azure AD client and tenant ID.
const clientId = "<Your Azure Active Directory Client Id>";
const tenantId = "<Your Azure Active Directory Tenant Id>";

// Enter your Azure Maps client ID.


const mapsClientId = "<Your Azure Maps Client Id>";

// Use InteractiveBrowserCredential with Azure AD client and tenant ID.


const credential = new InteractiveBrowserCredential({
clientId,
tenantId
});

// Use the credential to create a client


const client = MapsSearch(credential, mapsClientId);

For more information, see Authentication with Azure Maps.

3. The following code uses the newly created Azure Maps Search client to geocode
an address: "1 Microsoft Way, Redmond, WA". The code makes a GET request and
displays the results as a table in the body of the page.

JavaScript

// Search for "1 microsoft way, redmond, wa".


const html = [];
const response = await client
.path("/search/address/{format}", "json")
.get({ queryParameters: { query: "1 microsoft way, redmond, wa" } });

// Display the total results.


html.push("Total results: ", response.body.summary.numResults, "<br/>
<br/>");

// Create a table of the results.


html.push("<table><tr><td>Result</td><td>Latitude</td>
<td>Longitude</td></tr>");
response.body.results.forEach((result) => {
html.push(
"<tr><td>",
result.address.freeformAddress,
"</td><td>",
result.position.lat,
"</td><td>",
result.position.lon,
"</td></tr>"
);
});

html.push("</table>");
// Add the resulting HTML to the body of the page.
document.body.innerHTML = html.join("");

The following image is a screenshot showing the results of this sample code, a table
with the address searched for, along with the resulting coordinates.

Azure Government cloud support


The Azure Maps Web SDK supports the Azure Government cloud. All JavaScript and CSS
URLs used to access the Azure Maps Web SDK remain the same, however the following
tasks need to be done to connect to the Azure Government cloud version of the Azure
Maps platform.

When using the interactive map control, add the following line of code before creating
an instance of the Map class.

JavaScript

atlas.setDomain('atlas.azure.us');

Be sure to use an Azure Maps authentication details from the Azure Government cloud
platform when authenticating the map and services.

When using the TypeScript REST SDK, the domain for the services needs to be set when
creating an instance of the client. For example, the following code creates an instance of
the MapsSearch class and points the domain to the Azure Government cloud.

JavaScript

const client = MapsSearch(credential, { baseUrl: 'https://atlas.azure.us'});

If directly accessing the Azure Maps REST services, change the URL domain to
atlas.azure.us . For example, if using the search API service, change the URL domain
from https://atlas.microsoft.com/search/ to https://atlas.azure.us/search/ .

Next steps
Learn more about the classes and methods used in this article:

MapsSearch

AzureKeyCredential

InteractiveBrowserCredential

For more code samples that use the TypeScript REST SDK with Web SDK integration, see
these articles:

Show search results on the map

Get information from a coordinate

Show directions from A to B


Show search results on the map
Article • 04/14/2025

This article shows you how to search for location of interest and show the search results on the
map.

There are two ways to search for a location of interest. One way is to use the TypeScript REST
SDK, @azure-rest/maps-search to make a search request. The other way is to make a search
request to Azure Maps Fuzzy search API through the Fetch API . Both approaches are
described in this article.

Make a search request via REST SDK


JavaScript

import * as atlas from "azure-maps-control";


import MapsSearch from "@azure-rest/maps-search";
import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use Azure Active Directory authentication.
authType: "aad",
clientId: "<Your Azure Maps Client ID>",
aadAppId: "<Your Azure Active Directory Client ID>",
aadTenant: "<Your Azure Active Directory Tenant ID>"
}
});

map.events.add("load", async () => {


// Use the access token from the map and create an object that implements the
TokenCredential interface.
const credential = {
getToken: () => {
return {
token: map.authentication.getToken()
};
}
};

// Create a Search client.


const client = MapsSearch(credential, "<Your Azure Maps Client ID>");

// Create a data source and add it to the map.


const datasource = new atlas.source.DataSource();
map.sources.add(datasource);
// Add a layer for rendering point data.
const resultLayer = new atlas.layer.SymbolLayer(datasource);
map.layers.add(resultLayer);

// Search for gas stations near Seattle.


const response = await client.path("/search/fuzzy/{format}", "json").get({
queryParameters: {
query: "gasoline station",
lat: 47.6101,
lon: -122.34255
}
});

// Arrays to store bounds for results.


const bounds = [];

// Convert the response into Feature and add it to the data source.
const searchPins = response.body.results.map((result) => {
const position = [result.position.lon, result.position.lat];
bounds.push(position);
return new atlas.data.Feature(new atlas.data.Point(position), {
position: result.position.lat + ", " + result.position.lon
});
});

// Add the pins to the data source.


datasource.add(searchPins);

// Set the camera to the bounds of the pins


map.setCamera({
bounds: new atlas.data.BoundingBox.fromLatLngs(bounds),
padding: 40
});
});
};

document.body.onload = onload;

In the previous code example, the first block constructs a map object and sets the
authentication mechanism to use Microsoft Entra ID. For more information, see Create a map.

The second block of code creates an object that implements the TokenCredential interface to
authenticate HTTP requests to Azure Maps with the access token. It then passes the credential
object to MapsSearch and creates an instance of the client.

The third block of code creates a data source object using the DataSource class and add search
results to it. A symbol layer uses text or icons to render point-based data wrapped in the
DataSource as symbols on the map. A symbol layer is then created. The data source is added to
the symbol layer, which is then added to the map.
The fourth code block makes a GET request in the MapsSearch client. It allows you to perform
a free form text search via the Get Search Fuzzy REST API to search for point of interest. Get
requests to the Search Fuzzy API can handle any combination of fuzzy inputs. The response is
then converted to Feature objects and added to the data source, which automatically results in
the data being rendered on the map via the symbol layer.

The last block of code adjusts the camera bounds for the map using the Map's setCamera
property.

The search request, data source, symbol layer, and camera bounds are inside the event listener
of the map. We want to ensure that the results are displayed after the map fully loads.

Make a search request via Fetch API


JavaScript

import * as atlas from "azure-maps-control";


import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use Azure Active Directory authentication.
authType: "aad",
clientId: "<Your Azure Maps Client ID>",
aadAppId: "<Your Azure Active Directory Client ID>",
aadTenant: "<Your Azure Active Directory Tenant ID>"
}
});

map.events.add("load", () => {
// Create a data source and add it to the map.
const datasource = new atlas.source.DataSource();
map.sources.add(datasource);

// Add a layer for rendering point data.


const resultLayer = new atlas.layer.SymbolLayer(datasource);
map.layers.add(resultLayer);

// Send a request to Azure Maps Search API


let url = "https://atlas.microsoft.com/search/fuzzy/json?";
url += "&api-version=1";
url += "&query=gasoline%20station";
url += "&lat=47.6101";
url += "&lon=-122.34255";
url += "&radius=100000";
// Parse the API response and create a pin on the map for each result
fetch(url, {
headers: {
Authorization: "Bearer " + map.authentication.getToken(),
"x-ms-client-id": "<Your Azure Maps Client ID>"
}
})
.then((response) => response.json())
.then((response) => {
// Arrays to store bounds for results.
const bounds = [];

// Convert the response into Feature and add it to the data source.
const searchPins = response.results.map((result) => {
const position = [result.position.lon, result.position.lat];
bounds.push(position);
return new atlas.data.Feature(new atlas.data.Point(position), {
position: result.position.lat + ", " + result.position.lon
});
});

// Add the pins to the data source.


datasource.add(searchPins);

// Set the camera to the bounds of the pins


map.setCamera({
bounds: new atlas.data.BoundingBox.fromLatLngs(bounds),
padding: 40
});
});
});
};

document.body.onload = onload;

In the previous code example, the first block of code constructs a map object. It sets the
authentication mechanism to use Microsoft Entra ID. For more information, see Create a map.

The second block of code creates a data source object using the DataSource class and add
search results to it. A symbol layer uses text or icons to render point-based data wrapped in
the DataSource as symbols on the map. A symbol layer is then created. The data source is
added to the symbol layer, which is then added to the map.

The third block of code creates a URL to make a search request to.

The fourth block of code uses the Fetch API . The Fetch API is used to make a request to
Azure Maps Fuzzy search API to search for the points of interest. The Fuzzy search API can
handle any combination of fuzzy inputs. It then handles and parses the search response and
adds the result pins to the searchPins array.
The last block of code creates a BoundingBox object. It uses the array of results, and then it
adjusts the camera bounds for the map using the Map's setCamera. It then renders the result
pins.

The search request, the data source, symbol layer, and the camera bounds are set within the
map's event listener to ensure that the results are displayed after the map loads fully.

The following image is a screenshot showing the results of the two code samples.

Next steps
Best practices for using the search service

Learn more about Fuzzy Search:

Azure Maps Fuzzy Search API

Learn more about the classes and methods used in this article:

Map

See the following articles for full code examples:

Get information from a coordinate


Show directions from A to B
Get information from a coordinate
Article • 07/19/2023

This article shows how to make a reverse address search that shows the address of a
selected popup location.

There are two ways to make a reverse address search. One way is to query the Reverse
Address Search API through the TypeScript REST SDK @azure-rest/maps-search . The
other way is to use the Fetch API to make a request to the Reverse Address Search API
to find an address. Both approaches are described in this article.

Make a reverse search request via REST SDK


JavaScript

import * as atlas from "azure-maps-control";


import MapsSearch from "@azure-rest/maps-search";
import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use Azure Active Directory authentication.
authType: "aad",
clientId: "<Your Azure Maps Client Id>",
aadAppId: "<Your Azure Active Directory Client Id>",
aadTenant: "<Your Azure Active Directory Tenant Id>"
}
});

map.events.add("load", async () => {


// Use the access token from the map and create an object that
implements the TokenCredential interface.
const credential = {
getToken: () => {
return {
token: map.authentication.getToken()
};
}
};

// Create a Search client.


const client = MapsSearch(credential, "<Your Azure Maps Client Id>");

// Update the style of mouse cursor to a pointer


map.getCanvasContainer().style.cursor = "pointer";

// Create a popup
const popup = new atlas.Popup();

// Upon a mouse click, open a popup at the selected location and render
in the popup the address of the selected location
map.events.add("click", async (e) => {
const position = [e.position[1], e.position[0]];

// Execute the reverse address search query and open a popup once a
response is received
const response = await client.path("/search/address/reverse/{format}",
"json").get({
queryParameters: { query: position }
});

// Get address data from response


const data = response.body.addresses;

// Construct the popup


var popupContent = document.createElement("div");
popupContent.classList.add("popup-content");
popupContent.innerHTML = data.length !== 0 ?
data[0].address.freeformAddress : "No address for that location!";
popup.setOptions({
position: e.position,
content: popupContent
});

// Render the popup on the map


popup.open(map);
});
});
};

document.body.onload = onload;

In the previous code example, the first block constructs a map object and sets the
authentication mechanism to use Azure Active Directory. For more information, see
Create a map.

The second block of code creates an object that implements the TokenCredential
interface to authenticate HTTP requests to Azure Maps with the access token. It then
passes the credential object to MapsSearch and creates an instance of the client.

The third code block updates the style of mouse cursor to a pointer and creates a
popup object. For more information, see Add a popup on the map.

The fourth block of code adds a mouse click event listener. When triggered, it creates a
search query with the coordinates of the selected point. It then makes a GET request to
query the Get Search Address Reverse API for the address of the coordinates.

The fifth block of code sets up the HTML popup content to display the response address
for the selected coordinate position.

The change of cursor, the popup object, and the click event are all created in the
map's load event listener. This code structure ensures map fully loads before retrieving
the coordinates information.

Make a reverse search request via Fetch API


Select a location on the map to make a reverse geocode request for that location using
fetch.

JavaScript

import * as atlas from "azure-maps-control";


import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use Azure Active Directory authentication.
authType: "aad",
clientId: "<Your Azure Maps Client Id>",
aadAppId: "<Your Azure Active Directory Client Id>",
aadTenant: "<Your Azure Active Directory Tenant Id>"
}
});

map.events.add("load", async () => {


// Update the style of mouse cursor to a pointer
map.getCanvasContainer().style.cursor = "pointer";

// Create a popup
const popup = new atlas.Popup();

// Upon a mouse click, open a popup at the selected location and render
in the popup the address of the selected location
map.events.add("click", async (e) => {
//Send a request to Azure Maps reverse address search API
let url = "https://atlas.microsoft.com/search/address/reverse/json?";
url += "&api-version=1.0";
url += "&query=" + e.position[1] + "," + e.position[0];

// Process request
fetch(url, {
headers: {
Authorization: "Bearer " + map.authentication.getToken(),
"x-ms-client-id": "<Your Azure Maps Client Id>"
}
})
.then((response) => response.json())
.then((response) => {
const popupContent = document.createElement("div");
popupContent.classList.add("popup-content");
const address = response["addresses"];
popupContent.innerHTML =
address.length !== 0 ? address[0]["address"]["freeformAddress"]
: "No address for that location!";
popup.setOptions({
position: e.position,
content: popupContent
});
// render the popup on the map
popup.open(map);
});
});
});
};

document.body.onload = onload;

In the previous code example, the first block of code constructs a map object and sets
the authentication mechanism to use Azure Active Directory. You can see Create a map
for instructions.

The second block of code updates the style of the mouse cursor to a pointer. It
instantiates a popup object. For more information, see Add a popup on the map.

The third block of code adds an event listener for mouse clicks. Upon a mouse click, it
uses the Fetch API to query the Azure Maps Reverse Address Search API for the
selected coordinates address. For a successful response, it collects the address for the
selected location. It defines the popup content and position using the setOptions
function of the popup class.

The change of cursor, the popup object, and the click event are all created in the
map's load event listener. This code structure ensures the map fully loads before
retrieving the coordinates information.

The following image is a screenshot showing the results of the two code samples.
Next steps
Best practices for using the search service

Learn more about the classes and methods used in this article:

Map

Popup

See the following articles for full code examples:

Show directions from A to B

Show traffic
Show directions from A to B
Article • 07/19/2023

This article shows you how to make a route request and show the route on the map.

There are two ways to do so. The first way is to query the Get Route Directions API using
the TypeScript REST SDK @azure-rest/maps-route . The second way is to use the Fetch
API to make a search request to the Get Route Directions API. Both approaches are
described in this article.

Query the route via REST SDK


JavaScript

import * as atlas from "azure-maps-control";


import MapsRoute, { toColonDelimitedLatLonString } from "@azure-rest/maps-
route";
import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use Azure Active Directory authentication.
authType: "aad",
clientId: "<Your Azure Maps Client Id>",
aadAppId: "<Your Azure Active Directory Client Id>",
aadTenant: "<Your Azure Active Directory Tenant Id>"
}
});

map.events.add("load", async () => {


// Use the access token from the map and create an object that
implements the TokenCredential interface.
const credential = {
getToken: () => {
return {
token: map.authentication.getToken()
};
}
};

// Create a Route client.


const client = MapsRoute(credential, "<Your Azure Maps Client Id>");

// Create a data source and add it to the map.


const dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

// Create the GeoJSON objects which represent the start and end points
of the route.
const startPoint = new atlas.data.Feature(new
atlas.data.Point([-122.130137, 47.644702]), {
title: "Redmond",
icon: "pin-blue"
});

const endPoint = new atlas.data.Feature(new atlas.data.Point([-122.3352,


47.61397]), {
title: "Seattle",
icon: "pin-round-blue"
});

// Add the data to the data source.


dataSource.add([startPoint, endPoint]);

// Create a layer for rendering the route line under the road labels.
map.layers.add(
new atlas.layer.LineLayer(dataSource, null, {
strokeColor: "#2272B9",
strokeWidth: 5,
lineJoin: "round",
lineCap: "round"
}),
"labels"
);

// Create a layer for rendering the start and end points of the route as
symbols.
map.layers.add(
new atlas.layer.SymbolLayer(dataSource, null, {
iconOptions: {
image: ["get", "icon"],
allowOverlap: true,
ignorePlacement: true
},
textOptions: {
textField: ["get", "title"],
offset: [0, 1.2]
},
filter: ["any", ["==", ["geometry-type"], "Point"], ["==",
["geometry-type"], "MultiPoint"]] //Only render Point or MultiPoints in this
layer.
})
);

// Get the coordinates of the start and end points.


const coordinates = [
[startPoint.geometry.coordinates[1],
startPoint.geometry.coordinates[0]],
[endPoint.geometry.coordinates[1], endPoint.geometry.coordinates[0]]
];
// Get the route directions between the start and end points.
const response = await client.path("/route/directions/{format}",
"json").get({
queryParameters: {
query: toColonDelimitedLatLonString(coordinates)
}
});

// Get the GeoJSON feature collection of the route.


const data = getFeatures(response.body.routes);

// Add the route data to the data source.


dataSource.add(data);

// Update the map view to center over the route.


map.setCamera({
bounds: data.bbox,
padding: 40
});
});
};

/**
* Helper function to convert a route response into a GeoJSON
FeatureCollection.
*/
const getFeatures = (routes) => {
const bounds = [];
const features = routes.map((route, index) => {
const multiLineCoords = route.legs.map((leg) => {
return leg.points.map((coord) => {
const position = [coord.longitude, coord.latitude];
bounds.push(position);
return position;
});
});

// Include all properties on the route object except legs.


// Legs is used to create the MultiLineString, so we only need the
summaries.
// The legSummaries property replaces the legs property with just
summary data.
const props = {
...route,
legSummaries: route.legs.map((leg) => leg.summary),
resultIndex: index
};
delete props.legs;

return {
type: "Feature",
geometry: {
type: "MultiLineString",
coordinates: multiLineCoords
},
properties: props
};
});

return {
type: "FeatureCollection",
features: features,
bbox: new atlas.data.BoundingBox.fromLatLngs(bounds)
};
};

document.body.onload = onload;

In the previous code example, the first block constructs a map object and sets the
authentication mechanism to use Azure Active Directory. You can see Create a map for
instructions.

The second block of code creates an object that implements the TokenCredential
interface to authenticate HTTP requests to Azure Maps with the access token. It then
passes the credential object to MapsRoute and creates an instance of the client.

The third block of code creates and adds a DataSource object to the map.

The fourth block of code creates start and end points objects and adds them to the
dataSource object.

A line is a Feature for LineString. A LineLayer renders line objects wrapped in the
DataSource as lines on the map. The fourth block of code creates and adds a line layer
to the map. See properties of a line layer at LinestringLayerOptions.

A symbol layer uses texts or icons to render point-based data wrapped in the
DataSource. The texts or the icons render as symbols on the map. The fifth block of
code creates and adds a symbol layer to the map.

The sixth block of code queries the Azure Maps routing service, which is part of the
MapsRoute client. A GET request is used to get a route between the start and end
points. A GeoJSON feature collection from the response is then extracted using a
getFeatures() helper function and is added to the datasource. It then renders the

response as a route on the map. For more information about adding a line to the map,
see Add a line on the map.

The last block of code sets the bounds of the map using the Map's setCamera property.

The route query, data source, symbol, line layers, and camera bounds are created inside
the event listener. This code structure ensures the results are displayed only after the
map fully loads.

Query the route via Fetch API


JavaScript

import * as atlas from "azure-maps-control";


import "azure-maps-control/dist/atlas.min.css";

const onload = () => {


// Initialize a map instance.
const map = new atlas.Map("map", {
view: "Auto",
// Add authentication details for connecting to Azure Maps.
authOptions: {
// Use Azure Active Directory authentication.
authType: "aad",
clientId: "<Your Azure Maps Client Id>",
aadAppId: "<Your Azure Active Directory Client Id>",
aadTenant: "<Your Azure Active Directory Tenant Id>"
}
});

map.events.add("load", async () => {


// Create a data source and add it to the map.
const dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

// Create the GeoJSON objects which represent the start and end points
of the route.
const startPoint = new atlas.data.Feature(new
atlas.data.Point([-122.130137, 47.644702]), {
title: "Redmond",
icon: "pin-blue"
});

const endPoint = new atlas.data.Feature(new atlas.data.Point([-122.3352,


47.61397]), {
title: "Seattle",
icon: "pin-round-blue"
});

// Add the data to the data source.


dataSource.add([startPoint, endPoint]);

// Create a layer for rendering the route line under the road labels.
map.layers.add(
new atlas.layer.LineLayer(dataSource, null, {
strokeColor: "#2272B9",
strokeWidth: 5,
lineJoin: "round",
lineCap: "round"
}),
"labels"
);

// Create a layer for rendering the start and end points of the route as
symbols.
map.layers.add(
new atlas.layer.SymbolLayer(dataSource, null, {
iconOptions: {
image: ["get", "icon"],
allowOverlap: true,
ignorePlacement: true
},
textOptions: {
textField: ["get", "title"],
offset: [0, 1.2]
},
filter: ["any", ["==", ["geometry-type"], "Point"], ["==",
["geometry-type"], "MultiPoint"]] //Only render Point or MultiPoints in this
layer.
})
);

// Send a request to the route API


let url = "https://atlas.microsoft.com/route/directions/json?";
url += "&api-version=1.0";
url +=
"&query=" +
startPoint.geometry.coordinates[1] +
"," +
startPoint.geometry.coordinates[0] +
":" +
endPoint.geometry.coordinates[1] +
"," +
endPoint.geometry.coordinates[0];

// Process request
fetch(url, {
headers: {
Authorization: "Bearer " + map.authentication.getToken(),
"x-ms-client-id": "<Your Azure Maps Client Id>"
}
})
.then((response) => response.json())
.then((response) => {
const bounds = [];
const route = response.routes[0];

// Create an array to store the coordinates of each turn


let routeCoordinates = [];
route.legs.forEach((leg) => {
const legCoordinates = leg.points.map((point) => {
const position = [point.longitude, point.latitude];
bounds.push(position);
return position;
});
// Add each turn coordinate to the array
routeCoordinates = routeCoordinates.concat(legCoordinates);
});

// Add route line to the dataSource


dataSource.add(new atlas.data.Feature(new
atlas.data.LineString(routeCoordinates)));

// Update the map view to center over the route.


map.setCamera({
bounds: new atlas.data.BoundingBox.fromLatLngs(bounds),
padding: 40
});
});
});
};

document.body.onload = onload;

In the previous code example, the first block of code constructs a map object and sets
the authentication mechanism to use Azure Active Directory. You can see Create a map
for instructions.

The second block of code creates and adds a DataSource object to the map.

The third code block creates the start and destination points for the route. Then, it adds
them to the data source. For more information, see Add a pin on the map.

A LineLayer renders line objects wrapped in the DataSource as lines on the map. The
fourth block of code creates and adds a line layer to the map. See properties of a line
layer at LineLayerOptions.

A symbol layer uses text or icons to render point-based data wrapped in the DataSource
as symbols on the map. The fifth block of code creates and adds a symbol layer to the
map. See properties of a symbol layer at SymbolLayerOptions.

The next block of code uses the Fetch API to make a search request to Get Route
Directions. The response is then parsed. If the response was successful, the latitude and
longitude information is used to create an array a line by connecting those points. The
line data is then added to data source to render the route on the map. For more
information, see Add a line on the map.

The last block of code sets the bounds of the map using the Map's setCamera property.

The route query, data source, symbol, line layers, and camera bounds are created inside
the event listener. Again, we want to ensure that results are displayed after the map
loads fully.
The following image is a screenshot showing the results of the two code samples.

Next steps
Best practices for using the routing service

Learn more about the classes and methods used in this article:

Map

See the following articles for full code examples:

Show traffic on the map

Interacting with the map - mouse events


Use the Azure Maps Indoor Maps
module with custom styles (preview)
Article • 07/10/2024

The Azure Maps Web SDK includes an Indoor Maps module, enabling you to render
indoor maps created in Azure Maps Creator services.

When you create an indoor map using Azure Maps Creator, default styles are applied.
Azure Maps Creator now also supports customizing the styles of the different elements
of your indoor maps using the Style Rest API, or the visual style editor .

Prerequisites
Azure Maps account
Azure Maps Creator resource
Subscription key
A map configuration alias or ID. For more information, see map configuration API.

 Tip

If you have never used Azure Maps Creator to create an indoor map, you might
find the Use Creator to create indoor maps tutorial helpful.

The map configuration alias (or mapConfigurationId ) is required to render indoor maps
with custom styles via the Azure Maps Indoor Maps module.

Embed the Indoor Maps module


You can install and embed the Azure Maps Indoor module in one of two ways.

To use the globally hosted Azure Content Delivery Network version of the Azure Maps
Indoor module, reference the following script and stylesheet references in the <head>
element of the HTML file:

HTML

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/indoor/0.2/atlas-
indoor.min.css" type="text/css"/>
<script src="https://atlas.microsoft.com/sdk/javascript/indoor/0.2/atlas-
indoor.min.js"></script>

Or, you can download the Azure Maps Indoor module. The Azure Maps Indoor module
contains a client library for accessing Azure Maps services. The following steps
demonstrate how to install and load the Indoor module into your web application.

1. Install the latest azure-maps-indoor package .

PowerShell

>npm install azure-maps-indoor

2. Import the Azure Maps Indoor module JavaScript in a source file:

JavaScript

import * as indoor from "azure-maps-indoor";

You would also need to embed the CSS Style Sheet for various controls to display
correctly. If you're using a JavaScript bundler to bundle the dependencies and
package your code, refer to your bundler's documentation on how it's done. For
Webpack , it's commonly done via a combination of style-loader and css-
loader with documentation available at style-loader .

To begin, install style-loader and css-loader:

PowerShell

npm install --save-dev style-loader css-loader

Inside your source file, import atlas-indoor.min.css:

JavaScript

import "azure-maps-indoor/dist/atlas-indoor.min.css";

Then add loaders to the module rules portion of the Webpack config:

JavaScript

module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"]
}
]
}
};

To learn more, see How to use the Azure Maps map control npm package.

Set the domain and instantiate the Map object


Set the map domain with a prefix matching the location of your Creator resource, US or
EU , for example:

atlas.setDomain('us.atlas.microsoft.com');

For more information, see Azure Maps service geographic scope.

Next, instantiate a Map object with the map configuration object set to the alias or
mapConfigurationId property of your map configuration, then set your styleAPIVersion

to 2023-03-01-preview .

The Map object will be used in the next step to instantiate the Indoor Manager object.
The following code shows you how to instantiate the Map object with mapConfiguration ,
styleAPIVersion and map domain set:

JavaScript

const subscriptionKey = "<Your Azure Maps Subscription Key>";


const region = "<Your Creator resource region: us or eu>"
const mapConfiguration = "<map configuration alias or ID>"
atlas.setDomain(`${region}.atlas.microsoft.com`);

const map = new atlas.Map("map-id", {


//use your facility's location
center: [-122.13315, 47.63637],
//or, you can use bounds: [# west, # south, # east, # north] and replace #
with your Map bounds
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: subscriptionKey
},
zoom: 19,

mapConfiguration: mapConfiguration,
styleAPIVersion: '2023-03-01-preview'
});

Instantiate the Indoor Manager


To load the indoor map style of the tiles, you must instantiate the Indoor Manager.
Instantiate the Indoor Manager by providing the Map object. Your code should look like
the following JavaScript code snippet:

JavaScript

const indoorManager = new atlas.indoor.IndoorManager(map, {


});

Indoor level picker control


The Indoor Level Picker control allows you to change the level of the rendered map. You
can optionally initialize the Indoor Level Picker control via the Indoor Manager. Here's the
code to initialize the level control picker:

JavaScript

const levelControl = new atlas.control.LevelControl({ position: "top-right"


});
indoorManager.setOptions({ levelControl });

Indoor events
The Azure Maps Indoor module supports Map object events. The Map object event
listeners are invoked when a level or facility has changed. If you want to run code when
a level or a facility have changed, place your code inside the event listener. The code
below shows how event listeners can be added to the Map object.

JavaScript

map.events.add("levelchanged", indoorManager, (eventData) => {

//code that you want to run after a level has been changed
console.log("The level has changed: ", eventData);
});

map.events.add("facilitychanged", indoorManager, (eventData) => {


//code that you want to run after a facility has been changed
console.log("The facility has changed: ", eventData);
});

The eventData variable holds information about the level or facility that invoked the
levelchanged or facilitychanged event, respectively. When a level changes, the

eventData object contains the facilityId , the new levelNumber , and other metadata.

When a facility changes, the eventData object contains the new facilityId , the new
levelNumber , and other metadata.

Example: custom styling: consume map


configuration in WebSDK (preview)
When you create an indoor map using Azure Maps Creator, default styles are applied.
Azure Maps Creator now also supports customizing your indoor styles. For more
information, see Create custom styles for indoor maps. Creator also offers a visual style
editor .

1. Follow the Create custom styles for indoor maps how-to article to create your
custom styles. Make a note of the map configuration alias after saving your
changes.

2. Use the Azure Content Delivery Network option to install the Azure Maps Indoor
module.

3. Create a new HTML file

4. In the HTML header, reference the Azure Maps Indoor module JavaScript and style
sheet.

5. Set the map domain with a prefix matching a location of your Creator resource:
atlas.setDomain('us.atlas.microsoft.com'); if your Creator resource has been

created in US region, or atlas.setDomain('eu.atlas.microsoft.com'); if your


Creator resource has been created in EU region.

6. Initialize a Map object. The Map object supports the following options:

Subscription key is your Azure Maps subscription key.


center defines a latitude and longitude for your indoor map center location.

Provide a value for center if you don't want to provide a value for bounds .
Format should appear as center : [-122.13315, 47.63637].
bounds is the smallest rectangular shape that encloses the tileset map data.

Set a value for bounds if you don't want to set a value for center . You can
find your map bounds by calling the Tileset List API. The Tileset List API
returns the bbox , which you can parse and assign to bounds . Format should
appear as bounds : [# west, # south, # east, # north].
mapConfiguration the ID or alias of the map configuration that defines the

custom styles you want to display on the map, use the map configuration ID
or alias from step 1.
style allows you to set the initial style from your map configuration that is

displayed. If not set, the style matching map configuration's default


configuration is used.
zoom allows you to specify the min and max zoom levels for your map.

styleAPIVersion : pass '2023-03-01-preview' (which is required while Custom

Styling is in public preview)

7. Next, create the Indoor Manager module with Indoor Level Picker control
instantiated as part of Indoor Manager options.

8. Add Map object event listeners.

 Tip

The map configuration is referenced using the mapConfigurationId or alias . Each


time you edit or change a map configuration, its ID changes but its alias remains
the same. It is recommended to reference the map configuration by its alias in your
applications. For more information, See map configuration in the concepts article.

Your file should now look similar to the following HTML:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Indoor Maps App</title>

<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css"
type="text/css" />
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/indoor/0.2/atlas-
indoor.min.css" type="text/css"/>
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js">
</script>
<script
src="https://atlas.microsoft.com/sdk/javascript/indoor/0.2/atlas-
indoor.min.js"></script>

<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}

#map-id {
width: 100%;
height: 100%;
}
</style>
</head>

<body>
<div id="map-id"></div>
<script>
const subscriptionKey = "<Your Azure Maps Subscription Key>";
const mapConfig = "<Your map configuration id or alias>";
const region = "<Your Creator resource region: us or eu>"
atlas.setDomain(`${region}.atlas.microsoft.com`);

const map = new atlas.Map("map-id", {


//use your facility's location
center: [-122.13315, 47.63637],
//or, you can use bounds: [# west, # south, # east, # north] and
replace # with your Map bounds
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: subscriptionKey
},
zoom: 19,

mapConfiguration: mapConfig,
styleAPIVersion: '2023-03-01-preview'
});

const levelControl = new atlas.control.LevelControl({


position: "top-right",
});

const indoorManager = new atlas.indoor.IndoorManager(map, {


levelControl: levelControl, //level picker
});
map.events.add("levelchanged", indoorManager, (eventData) => {
//put code that runs after a level has been changed
console.log("The level has changed:", eventData);
});

map.events.add("facilitychanged", indoorManager, (eventData) => {


//put code that runs after a facility has been changed
console.log("The facility has changed:", eventData);
});
</script>
</body>
</html>

To see your indoor map, load it into a web browser. It should appear like the following
image. If you select the stairwell feature, the level picker appears in the upper right-hand
corner.

For a live demo of an indoor map with available source code, see Creator Indoor
Maps in the [Azure Maps Samples].

Next steps
Read about the APIs that are related to the Azure Maps Indoor module:
Drawing package requirements

Creator for indoor maps

Learn more about how to add more data to your map:

Code samples

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Use the Azure Maps Spatial IO module
Article • 02/06/2025

The Azure Maps Spatial IO module integrates spatial data with the Azure Maps Web
SDK by using JavaScript or TypeScript. This guide demonstrates how to integrate and
use the Spatial IO module in a web application.

You can use the robust features in this module to:

Read and write spatial data. You can use file formats that include:
Keyhole Markup Language (KML).
Compressed KML (KMZ).
GPS Exchange Format (GPX).
Geographic Really Simple Syndication (GeoRSS).
Geography Markup Language (GML).
Geographic JavaScript Object Notation (GeoJSON).
Well-Known Text (WKT).
Comma-Separated Values (CSV) when columns include spatial information.
Connect to Open Geospatial Consortium (OGC) services and integrate with the
Azure Maps Web SDK. You can also overlay Web Map Services (WMS) and Web
Map Tile Services (WMTS) as layers on the map. For more information, see Add a
map layer from the Open Geospatial Consortium (OGC).
Query data in a Web Feature Service (WFS). For more information, see Connect to
a WFS service.
Overlay complex data sets that contain style information, which can render
automatically. For more information, see Add a simple data layer.
Use high-speed XML and delimited file reader and writer classes. For more
information, see Core IO operations.

The following video provides an overview of the Spatial IO module in the Azure Maps
Web SDK.

https://learn.microsoft.com/Shows/Internet-of-Things-Show/Easily-integrate-spatial-
data-into-the-Azure-Maps/player?format=ny

2 Warning

Use data and services only from a source that you trust, especially if the data is
referenced from another domain. The Spatial IO module takes steps to minimize
risk, but you should not allow any dangerous data into your application regardless.
Prerequisites
An Azure Maps account
A subscription key

Install the Spatial IO module


You can load the Azure Maps Spatial IO module by using one of the following two
options:

The first option is to use the globally hosted Azure content delivery network for
the Azure Maps Spatial IO module. Use the following script tag in the <head>
element of the HTML file to add the reference:

HTML

<script
src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.js"></script>

With the second option, you can load the source code for azure-maps-spatial-io
locally, and host it with your app. This package also includes TypeScript definitions.
Use the following command to install the package:

sh

npm install azure-maps-spatial-io

Use an import declaration to add the module into a source file:

JavaScript

import * as spatial from "azure-maps-spatial-io";

To learn more, see How to use the Azure Maps map control npm package.

Implement the Spatial IO module


1. Create a new HTML file.

2. Load the Azure Maps Web SDK and initialize the map control. See the Azure Maps
map control guide for details. Your HTML file should look like this:
HTML

<!DOCTYPE html>
<html>

<head>
<title></title>

<meta charset="utf-8">

<!-- Ensure that Internet Explorer and Edge use the latest version
and don't emulate an older version. -->
<meta http-equiv="x-ua-compatible" content="IE=Edge">

<!-- Ensure that the web page looks good on all screen sizes. -->
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Add references to the Azure Maps Map control JavaScript and
CSS files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.js">
</script>

<script type='text/javascript'>

var map;

function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',

//Add your Azure Maps subscription key to the map SDK.


Get an Azure Maps key at https://azure.com/maps.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function() {

// Write your code here to make sure it runs once the


map resources are ready.

});
}
</script>
</head>
<body onload="GetMap()">
<div id="myMap" style="position:relative;width:100%;min-
width:290px;height:600px;"></div>
</body>

</html>

3. Load the Azure Maps Spatial IO module and use the content delivery network for
the Azure Maps Spatial IO module. Add the following reference to the <head>
element of your HTML file:

HTML

<script
src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.js"></script>

4. Initialize a data source and add it to the map.

5. Initialize a simple data layer and add the data source to it.

6. Render the data layer.

7. Before you scroll down to see the full code in the next step, determine the best
places to put the data source and layer code snippets. Wait until the map
resources are ready before you programmatically manipulate the map.

JavaScript

var datasource, layer;

Find the best places to put the code snippets.

JavaScript

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering the data.


layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);

8. Your HTML code should look like the following. The sample code shows you how
to display an XML file's feature data on a map.
7 Note

This example uses Route66Attractions.xml .

HTML

<!DOCTYPE html>
<html>
<head>
<title>Spatial IO Module Example</title>

<meta charset="utf-8">

<!-- Ensure that Internet Explorer and Edge use the latest version
and don't emulate an older version. -->
<meta http-equiv="x-ua-compatible" content="IE=Edge">

<!-- Ensure that the web page looks good on all screen sizes. -->
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Add references to the Azure Maps map control JavaScript and
CSS files. -->
<link rel="stylesheet"
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min
.css" type="text/css" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.js">
</script>

<!-- Add reference to the Azure Maps Spatial IO module. -->


<script
src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.js"></script>

<script type='text/javascript'>
var map, datasource, layer;

function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',

//Add your Azure Maps subscription key to the map SDK.


Get an Azure Maps key at https://azure.com/maps.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
}
});

//Wait until the map resources are ready.


map.events.add('ready', function() {

//Create a data source and add it to the map.


datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering the data.


layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);

//Read an XML file from a URL or pass in a raw XML


string.
atlas.io.read('Route66Attractions.xml').then(r => {
if (r) {
//Add the feature data to the data source.
datasource.add(r);

//If bounding box information is known for


data, set the map view to it.
if (r.bbox) {
map.setCamera({
bounds: r.bbox,
padding: 50
});
}
}
});
});
}
</script>
</head>
<body onload='GetMap()'>
<div id="myMap" style="position:relative;width:100%;min-
width:290px;height:600px;"></div>
</body>
</html>

9. Remember to replace <Your Azure Maps Key> with your subscription key. Your
HTML file should include an image that looks like this:


Related content
This article describes only one of the many features available in the Spatial IO module.
To learn about others, read the following guides:

Add a simple data layer


Read and write spatial data
Add a map layer from the Open Geospatial Consortium (OGC)
Connect to a WFS service
Core IO operations
Supported data format details
Get documentation for the Azure Maps Spatial IO package

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a simple data layer
Article • 02/06/2025

The Azure Maps Web SDK provides a Spatial IO module that includes a SimpleDataLayer
class. This class makes it easy to render styled features on a map. It can even render data
sets that have style properties and data sets that contain mixed geometry types.

The simple data layer achieves this functionality by wrapping multiple rendering layers
and by using style expressions. The style expressions search wrapped layers for common
style properties. The atlas.io.read and atlas.io.write functions use these properties
to read and write styles into a supported file format. When you add properties to a
supported file format, you can use the file for purposes like displaying styled features on
a map.

The SimpleDataLayer class also provides a built-in popup feature with a popup
template. The popup appears when a feature is selected. This layer also supports
clustered data. When a cluster is selected, the map zooms in to the cluster and expands
it into individual points and subclusters. You can disable the popup feature if you don't
need it.

The SimpleDataLayer class is intended to be used on large data sets that include
features with many applied geometry types and styles. When you use this class, it adds
an overhead of six layers that contain style expressions. If you only need to render a few
geometry types and styles on a feature, it might be more efficient to use a core
rendering layer. For more information, see Add a bubble layer to the map, Add a line
layer to the map, and Add a polygon layer to the map.

Use a simple data layer


You can use the SimpleDataLayer class like the other rendering layers. The following
code shows how to use a simple data layer in a map:

JavaScript

//Create a data source and add it to the map.


var datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering data.


var layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);
The following code snippet demonstrates how to use a simple data layer that references
data from an online source:

JavaScript

<script src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.min.js"></script>

<script>
function InitMap() {
var map = new atlas.Map("myMap", {
center: [-73.967605, 40.780452],
zoom: 12,
view: "Auto",

//Add authentication details to connect to Azure Maps.


authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: "subscriptionKey",
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});

//Wait until the map resources are ready.


map.events.add("ready", function () {
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering data.


var layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);

//Load an initial data set.


const dataSet = {
type: "FeatureCollection",
bbox: [0, 0, 0, 0],
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [0, 0]
},
properties: {
color: "red"
}
}
]
};

loadDataSet(dataSet);

function loadDataSet(r) {
//Update the features in the data source.
datasource.setShapes(r);

//If bounding box information is known for data, set the map
view to it.
if (r.bbox) {
map.setCamera({
bounds: r.bbox,
padding: 50
});
}
}
});
}
</script>

When you add features to the data source, the simple data layer renders them in the
most appropriate way. You can set styles as properties for each individual feature.

The preceding sample code shows a Geographic JavaScript Object Notation (GeoJSON)
point feature with a color property set to red .

The sample code renders the point feature by using the simple data layer, and the result
appears as follows.

7 Note
The value from the data source "coordinates": [0, 0] overrides the coordinates
center: [-73.967605, 40.780452] that you set when the map was initialized.

The simple data layer is a powerful tool in the following scenarios:

A data source includes several feature types.


Features in the data set have several style properties that are individually set.
You're not sure what the data set contains.

For example, when you're parsing XML data feeds, you might not know the features'
style and geometry types. The Simple data layer options sample shows how the
simple data layer renders the features of a Keyhole Markup Language (KML) file. You can
also see the options in the SimpleDataLayer class. For the source code for this sample,
see Simple data layer options.html in the Azure Maps code samples in GitHub.

7 Note

This simple data layer uses the popup template class to display KML balloons or
feature properties as a table. By default, all content rendered in the popup is
sandboxed inside an iFrame as a security feature. However, there are limitations:

All pointer lock functionality, top navigation functionality, scripts, and forms
are disabled. Links can open in a new tab when they're selected.
Older browsers that don't support the srcdoc parameter on iFrames can
render only a small amount of content.

If you trust the data loaded into the popups, and want the popup scripts to be able
to access your application, you can disable this feature. Just set the sandboxContent
option in the popup template to false .

Default supported style properties


The simple data layer wraps several of the core rendering layers: bubble, symbol, line,
polygon, and extruded polygon. It uses expressions to search for valid style properties
on individual features.

The two main sets of supported property names are Azure Maps and GitHub. Most
property names of Azure Maps layer options are supported in the simple data layer as
style properties of features. Some layer options include expressions that support style
property names that GitHub commonly uses.

GitHub's GeoJSON map support defines these property names, which are used to
style GeoJSON files that are stored and rendered within the platform. Most of GitHub's
styling properties are supported in the simple data layer, except the marker-symbol
styling properties.

If the reader comes across a less common style property, it converts it to the most
similar Azure Maps style property. Additionally, you can override the default style
expressions by using the getLayers function of the simple data layer and updating the
options on any of the layers.

The following sections provide details on the default style properties that the simple
data layer supports. The order of the supported property names is also the priority. If
two style properties are defined for the same layer option, the first one in the list takes
precedence. Colors can be any CSS3 color value (HEX, RGB, RGBA, HSL, HSLA) or named
color value.

Bubble layer style properties


If a feature is a Point or a MultiPoint , and doesn't have an image property to use as a
custom icon to render the point as a symbol, it's rendered with a BubbleLayer .

ノ Expand table

Layer option Supported property names Default value

color color , marker-color '#1A73AA'

radius size 1, marker-size 2, scale 1 8


Layer option Supported property names Default value

strokeColor strokeColor , stroke '#FFFFFF'

1
The size and scale values are considered scalar values, and are multiplied by 8.

2
If the GitHub marker-size option is specified, the radius uses the following values:

ノ Expand table

Marker size Radius

small 6

medium 8

large 12

Clusters are also rendered in the bubble layer. By default, the radius of a cluster is set to
16. The color of the cluster varies depending on the number of points in the cluster, as
defined in the following table:

ノ Expand table

Number of points Color

>= 100 red

>= 10 yellow

< 10 green

Symbol style properties


If a feature is a Point or MultiPoint , with an image property used as a custom icon to
render the point as a symbol, then it's rendered with a SymbolLayer .

ノ Expand table

Layer option Supported property names Default value

image image none

size size , marker-size 1 1

rotation rotation 0
Layer option Supported property names Default value

offset offset [0, 0]

anchor anchor 'bottom'

1
If the GitHub marker-size option is specified, the following values are used for the
icon size option:

ノ Expand table

Marker size Symbol size

small 0.5

medium 1

large 2

If the point feature is a cluster, the point_count_abbreviated property is rendered as a


text label. No image is rendered.

Line style properties


If the feature is a LineString , MultiLineString , Polygon , or MultiPolygon , it's rendered
with a LineLayer .

ノ Expand table

Layer option Supported property names Default value

strokeColor strokeColor , stroke '#1E90FF'

strokeWidth strokeWidth , stroke-width , stroke-thickness 3

strokeOpacity strokeOpacity , stroke-opacity 1

Polygon style properties


If the feature is a Polygon or a MultiPolygon , and doesn't have a height property, or if
the height property is zero, it's rendered with a PolygonLayer .

ノ Expand table
Layer option Supported property names Default value

fillColor fillColor , fill '#1E90FF'

fillOpacity fillOpacity , ' fill-opacity 0.5

Extruded polygon style properties


If the feature is a Polygon or a MultiPolygon , and has a height property with a value
greater than zero, it's rendered with a PolygonExtrusionLayer .

ノ Expand table

Layer option Supported property names Default value

base base 0

fillColor fillColor , fill '#1E90FF'

height height 0

Related content
Learn more about the classes and methods in this article:

SimpleDataLayer
SimpleDataLayerOptions

See the following articles to get more code samples to add to your maps:

Read and write spatial data


Add a map layer from the Open Geospatial Consortium
Connect to a WFS service
Core IO operations
Supported data format details

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Read and write spatial data
Article • 09/24/2024

The following table lists the spatial file formats that are supported for reading and
writing operations with the Spatial IO module.

ノ Expand table

Data Format Read Write

GeoJSON ✓ ✓

GeoRSS ✓ ✓

GML ✓ ✓

GPX ✓ ✓

KML ✓ ✓

KMZ ✓ ✓

Spatial CSV ✓ ✓

Well-Known Text ✓ ✓

These next sections outline all the different tools for reading and writing spatial data
using the Spatial IO module.

Read spatial data


The atlas.io.read function is the main function used to read common spatial data
formats such as KML, GPX, GeoRSS, GeoJSON, and CSV files with spatial data. This
function can also read compressed versions of these formats, as a zip file or a KMZ file.
The KMZ file format is a compressed version of KML that can also include assets such as
images. Alternatively, the read function can take in a URL that points to a file in any of
these formats. URLs should be hosted on a CORS enabled endpoint, or a proxy service
should be provided in the read options. The proxy service is used to load resources on
domains that aren't CORS enabled. The read function returns a promise to add the
image icons to the map, and processes data asynchronously to minimize impact to the
UI thread.

When reading a compressed file, either as a zip or a KMZ, once unzipped it looks for the
first valid file. For example, doc.kml, or a file with other valid extension, such as: .kml,
.xml, geojson, .json, .csv, .tsv, or .txt. Then, images referenced in KML and GeoRSS files
are preloaded to ensure they're accessible. Inaccessible image data can load an
alternative fallback image or removed from the styles. Images extracted from KMZ files
are converted to data URIs.

The result from the read function is a SpatialDataSet object. This object extends the
GeoJSON FeatureCollection class. It can easily be passed into a DataSource as-is to
render its features on a map. The SpatialDataSet not only contains feature information,
but it can also include KML ground overlays, processing metrics, and other details as
outlined in the following table.

ノ Expand table

Property Type Description


name

bbox BoundingBox Bounding box of all the data in the


data set.

features Feature[] GeoJSON features within the data set.

groundOverlays (atlas.layer.ImageLayer | An array of KML GroundOverlays.


atlas.layers.OgcMapLayer)[]

icons Record<string, string> A set of icon URLs. Key = icon name,


Value = URL.

properties any Property information provided at the


document level of a spatial data set.

stats SpatialDataSetStats Statistics about the content and


processing time of a spatial data set.

type 'FeatureCollection' Read-only GeoJSON type value.

Examples of reading spatial data


The Load spatial data sample shows how to read a spatial data set, and renders it on
the map using the SimpleDataLayer class. The code uses a GPX file pointed to by a URL.
For the source code of this sample, see Load spatial data source code .
 

The next code demo shows how to read and load KML, or KMZ, to the map. KML can
contain ground overlays, which is in the form of an ImageLyaer or OgcMapLayer . These
overlays must be added on the map separately from the features. Additionally, if the
data set has custom icons, those icons need to be loaded to the maps resources before
the features are loaded.

The Load KML onto map sample shows how to load KML or KMZ files onto the map.
For the source code of this sample, see Load KML onto map source code .

You can optionally provide a proxy service for accessing cross domain assets that don't
have CORS enabled. The read function tries to access files on another domain using
CORS first. The first time it fails to access any resource on another domain using CORS it
only requests more files if a proxy service is provided. The read function appends the file
URL to the end of the proxy URL provided. This snippet of code shows how to pass a
proxy service into the read function:

JavaScript

//Read a file from a URL or pass in a raw data as a string.


atlas.io.read('https://nonCorsDomain.example.com/mySuperCoolData.xml', {
//Provide a proxy service
proxyService: window.location.origin +
'/YourCorsEnabledProxyService.ashx?url='
}).then(async r => {
if (r) {
// Some code goes here . . .
}
});

The following code snippet shows how to read a delimited file and render it on the map.
In this case, the code uses a CSV file that has spatial data columns. You must add a
reference to the Azure Maps Spatial IO module.

JavaScript

<!-- Add reference to the Azure Maps Spatial IO module. -->


<script src="https://atlas.microsoft.com/sdk/javascript/spatial/0/atlas-
spatial.min.js"></script>

<script type="text/javascript">
var map, datasource, layer;

//a URL pointing to the CSV file


var delimitedFileUrl = "https://s3-us-west-
2.amazonaws.com/s.cdpn.io/1717245/earthquakes_gt7_alltime.csv";

function InitMap()
{
map = new atlas.Map('myMap', {
center: [-73.985708, 40.75773],
zoom: 12,
view: "Auto",

//Add authentication details for connecting to Azure Maps.


authOptions: {
// Get an Azure Maps key at https://azuremaps.com/.
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
},
});

//Wait until the map resources are ready.


map.events.add('ready', function () {
//Create a data source and add it to the map.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);

//Add a simple data layer for rendering the data.


layer = new atlas.layer.SimpleDataLayer(datasource);
map.layers.add(layer);

//Read a CSV file from a URL or pass in a raw string.


atlas.io.read(delimitedFileUrl).then(r => {
if (r) {
//Add the feature data to the data source.
datasource.add(r);

//If bounding box information is known for data, set the map view to
it.
if (r.bbox) {
map.setCamera({
bounds: r.bbox,
padding: 50
});
}
}
});
});
}
</script>

Write spatial data


There are two main write functions in the spatial IO module. The atlas.io.write
function generates a string, while the atlas.io.writeCompressed function generates a
compressed zip file. The compressed zip file would contain a text-based file with the
spatial data in it. Both of these functions return a promise to add the data to the file.
And, they both can write any of the following data: SpatialDataSet , DataSource ,
ImageLayer , OgcMapLayer , feature collection, feature, geometry, or an array of any
combination of these data types. When writing using either functions, you can specify
the wanted file format. If the file format isn't specified, then the data is written as KML.

The Spatial data write options sample is a tool that demonstrates most the write
options that can be used with the atlas.io.write function. For the source code of this
sample, see Spatial data write options source code .

Example of writing spatial data


The Drag and drop spatial files onto map sample allows you to drag and drop one or
more KML, KMZ, GeoRSS, GPX, GML, GeoJSON or CSV files onto the map. For the source
code of this sample, see Drag and drop spatial files onto map source code .

You can optionally provide a proxy service for accessing cross domain assets that don't
have CORS enabled. This snippet of code shows you could incorporate a proxy service:

JavaScript
atlas.io.read(data, {
//Provide a proxy service
proxyService: window.location.origin +
'/YourCorsEnabledProxyService.ashx?url='
}).then(
//Success
function(r) {
//some code goes here ...
}
);

Read and write Well-Known Text (WKT)


Well-Known Text (WKT) is an Open Geospatial Consortium (OGC) standard for
representing spatial geometries as text. Many geospatial systems support WKT, such as
Azure SQL and Azure PostgreSQL using the PostGIS plugin. Like most OGC standards,
coordinates are formatted as "longitude latitude" to align with the "x y" convention. As
an example, a point at longitude -110 and latitude 45 can be written as POINT(-110 45)
using the WKT format.

Well-known text can be read using the atlas.io.ogc.WKT.read function, and written
using the atlas.io.ogc.WKT.write function.

Examples of reading and writing Well-Known


Text (WKT)
The Read Well Known Text sample shows how to read the well-known text string
POINT(-122.34009 47.60995) and render it on the map using a bubble layer. For the

source code of this sample, see Read Well Known Text source code .

The Read and write Well Known Text sample demonstrates how to read and write Well
Known Text (WKT) strings as GeoJSON. For the source code of this sample, see Read and
write Well Known Text source code .

Read and write GML


GML is a spatial XML file specification often used as an extension to other XML
specifications. GeoJSON data can be written as XML with GML tags using the
atlas.io.core.GmlWriter.write function. The XML that contains GML can be read using

the atlas.io.core.GmlReader.read function. The read function has two options:

The isAxisOrderLonLat option - The axis order of coordinates "latitude, longitude"


or "longitude, latitude" can vary between data sets, and it isn't always well defined.
By default the GML reader reads the coordinate data as "latitude, longitude", but
setting this option to true reads it as "longitude, latitude".
The propertyTypes option - This option is a key value lookup table where the key
is the name of a property in the data set. The value is the object type to cast the
value to when parsing. The supported type values are: string , number , boolean ,
and date . If a property isn't in the lookup table or the type isn't defined, the
property is parsed as a string.

The atlas.io.read function defaults to the atlas.io.core.GmlReader.read function


when it detects that the input data is XML, but the data isn't one of the other support
spatial XML formats.

The GmlReader parses coordinates that have one of the following SRIDs:

EPSG:4326 (Preferred)
EPSG:4269, EPSG:4283, EPSG:4258, EPSG:4308, EPSG:4230, EPSG:4272, EPSG:4271,
EPSG:4267, EPSG:4608, EPSG:4674 possibly with a small margin of error.
EPSG:3857, EPSG:102100, EPSG:3785, EPSG:900913, EPSG:102113, EPSG:41001,
EPSG:54004

More resources
Learn more about the classes and methods used in this article:

atlas.io static functions

SpatialDataSet

SpatialDataSetStats

GmlReader

GmlWriter

atlas.io.ogc.WKT functions

Connect to a WFS service

Leverage core operations

Supported data format details

Next steps
See the following articles for more code samples to add to your maps:

Add an OGC map layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a map layer from the Open
Geospatial Consortium (OGC)
Article • 06/29/2023

The atlas.layer.OgcMapLayer class can overlay Web Map Services (WMS) imagery and
Web Map Tile Services (WMTS) imagery on the map. WMS is a standard protocol
developed by OGC for serving georeferenced map images over the internet. Image
georeferencing is the processes of associating an image to a geographical location.
WMTS is also a standard protocol developed by OGC. It's designed for serving pre-
rendered and georeferenced map tiles.

The following sections outline the web map service features that are supported by the
OgcMapLayer class.

Web Map Service (WMS)

Supported versions: 1.0.0 , 1.1.0 , 1.1.1 , and 1.3.0

The service must support the EPSG:3857 projection system, or handle


reprojections.

GetFeatureInfo requires the service to support EPSG:4326 or handle reprojections.

Supported operations:

Operation Description

GetCapabilities Retrieves metadata about the service with the supported capabilities

GetMap Retrieves a map image for a specified region

GetFeatureInfo Retrieves feature_info , which contains underlying data about the feature

Web Map Tile Service (WMTS)

Supported versions: 1.0.0

Tiles must be square, such that TileWidth == TileHeight .

CRS supported: EPSG:3857 or GoogleMapsCompatible

TileMatrix identifier must be an integer value that corresponds to a zoom level on


the map. On an azure map, the zoom level is a value between "0" and "22" . So,
"0" is supported, but "00" isn't supported.

Supported operations:

Operation Description

GetCapabilities Retrieves the supported operations and features

GetTile Retrieves imagery for a particular tile

Overlay an OGC map layer


The url can be the base URL for the service or a full URL with the query for getting the
capabilities of the service. Depending on the details provided, the WFS client may try
several standard URL formats to determine how to initially access the service.

The OGC map layer sample shows how to overlay an OGC map layer on the map. For
the source code for this sample, see OGC map layer source code .

OGC map layer options


The OGC map layer options sample demonstrates the different OGC map layer
options. For the source code for this sample, see OGC map layer options source code .
OGC Web Map Service explorer
The OGC Web Map Service explorer sample overlays imagery from the Web Map
Services (WMS) and Web Map Tile Services (WMTS) as layers. You may select which
layers in the service are rendered on the map. You may also view the associated legends
for these layers. For the source code for this sample, see OGC Web Map Service explorer
source code .

You may also specify the map settings to use a proxy service. The proxy service lets you
load resources that are hosted on domains that don't have CORS enabled.
Next steps
Learn more about the classes and methods used in this article:

OgcMapLayer

OgcMapLayerOptions

See the following articles, which contain code samples you could add to your maps:

Connect to a WFS service

Leverage core operations

Supported data format details


Connect to a WFS service
Article • 10/17/2024

A Web Feature Service (WFS) is a web service for querying spatial data that has a
standardized API defined by the Open Geospatial Consortium (OGC). The WfsClient
class in the spatial IO module lets developers connect to a WFS service and query data
from the service.

The WfsClient class supports the following features:

Supported versions: 1.0.0 , 1.1.0 , and 2.0.0

Supported filter operators: binary comparisons, logic, math, value, and bbox .

Requests are made using HTTP GET only.

Supported operations:

ノ Expand table

Operation Description

GetCapabilities Generates a metadata document with valid WFS operations and


parameters

GetFeature Returns a selection of features from a data source

DescribeFeatureType Returns the supported feature types

Using the WFS client


The atlas.io.ogc.WfsClient class in the spatial IO module makes it easy to query a WFS
service and convert the responses into GeoJSON objects. This GeoJSON object can then
be used for other mapping purposes.

Supported filters
The specification for the WFS standard makes use of OGC filters. The WFS client
supports the following filters, assuming that the service being called also supports these
filters. Custom filter strings can be passed into the CustomFilter class.

Logical operators
And
Or

Not

Value operators

GmlObjectId

ResourceId

Math operators

Add
Sub

Mul

Div

Comparison operators

PropertyIsEqualTo
PropertyIsNotEqualTo

PropertyIsLessThan

PropertyIsGreaterThan
PropertyIsLessThanOrEqualTo

PropertyIsGreaterThanOrEqualTo
PropertyIsLike

PropertyIsNull

PropertyIsNil
PropertyIsBetween

WFS service explorer


The WFS service explorer sample is a simple tool for exploring WFS services on Azure
Maps. For the source code for this sample, see WFS service explorer source code .
To access WFS services hosted on non-CORS enabled endpoints, a CORS enabled proxy
service can be passed into the proxyService option of the WFS client as shown in the
following example.

JavaScript

//Create the WFS client to access the service and use the proxy service
settings
client = new atlas.io.ogc.WfsClient({
url: url,
proxyService: window.location.origin +
'/YourCorsEnabledProxyService.ashx?url='
});

Next steps
Learn more about the classes and methods used in this article:

WfsClient

WfsServiceOptions

See the following articles for more code samples to add to your maps:

Leverage core operations

Supported data format details

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Core IO operations
Article • 09/25/2024

In addition to providing tools to read spatial data files, the spatial IO module exposes
core underlying libraries to read and write XML and delimited data fast and efficiently.

The atlas.io.core namespace contains two low-level classes that can quickly read and
write CSV and XML data. These base classes power the spatial data readers and writers
in the Spatial IO module. Feel free to use them to add more reading and writing support
for CSV or XML files.

Read delimited files


The atlas.io.core.CsvReader class reads strings that contain delimited data sets. This
class provides two methods for reading data:

The read function reads the full data set and return a two-dimensional array of
strings representing all cells of the delimited data set.
The getNextRow function reads each line of text in a delimited data set and returns
an array of string representing all cells in that line of data set. The user can process
the row and dispose any unneeded memory from that row before processing the
next row. So, function is more memory efficient.

By default, the reader uses the comma character as the delimiter. However, the delimiter
can be changed to any single character or set to 'auto' . When set to 'auto' , the reader
analyzes the first line of text in the string. Then, it selects the most common character
from the following table to use as the delimiter.

ノ Expand table

Delimiter Character

Comma ,

Tab \t

Pipe |

This reader also supports text qualifiers that are used to handle cells that contain the
delimiter character. The quote ( '"' ) character is the default text qualifier, but it can be
changed to any single character.
Write delimited files
The atlas.io.core.CsvWriter writes an array of objects as a delimited string. Any single
character can be used as a delimiter or a text qualifier. The default delimiter is comma
( ',' ) and the default text qualifier is the quote ( '"' ) character.

Follow the steps to use this class:

Create an instance of the class and optionally set a custom delimiter or text
qualifier.
Write data to the class using the write function or the writeRow function. For the
write function, pass a two-dimensional array of objects representing multiple

rows and cells. To use the writeRow function, pass an array of objects representing
a row of data with multiple columns.
Call the toString function to retrieve the delimited string.
Optionally, call the clear method to make the writer reusable and reduce its
resource allocation, or call the delete method to dispose of the writer instance.

7 Note

The number of columns written will be constrained to the number of cells in the
first row of the data passed to the writer.

Read XML files


The atlas.io.core.SimpleXmlReader class is faster at parsing XML files than DOMParser .
However, the atlas.io.core.SimpleXmlReader class requires XML files to be well
formatted. XML files that aren't well formatted, for example missing closing tags, may
result in an error.

The following code demonstrates how to use the SimpleXmlReader class to parse an XML
string into a JSON object and serialize it into a desired format.

JavaScript

//Create an instance of the SimpleXmlReader and parse an XML string into a


JSON object.
var xmlDoc = new atlas.io.core.SimpleXmlReader().parse(xmlStringToParse);

//Verify that the root XML tag name of the document is the file type your
code is designed to parse.
if (xmlDoc && xmlDoc.root && xmlDoc.root.tagName && xmlDoc.root.tagName ===
'<Your desired root XML tag name>') {

var node = xmlDoc.root;

//Loop through the child node tree to navigate through the parsed XML
object.
for (var i = 0, len = node.childNodes.length; i < len; i++) {
childNode = node.childNodes[i];

switch (childNode.tagName) {
//Look for tag names, parse and serialized as desired.
}
}
}

Write XML files


The atlas.io.core.SimpleXmlWriter class writes well-formatted XML in a memory
efficient way.

The following code demonstrates how to use the SimpleXmlWriter class to generate a
well-formatted XML string.

JavaScript

//Create an instance of the SimpleXmlWriter class.


var writer = new atlas.io.core.SimpleXmlWriter();

//Start writing the document. All write functions return a reference to the
writer, making it easy to chain the function calls to reduce the code size.
writer.writeStartDocument(true)
//Specify the root XML tag name, in this case 'root'
.writeStartElement('root', {
//Attributes to add to the root XML tag.
'version': '1.0',
'xmlns': 'http://www.example.com',
//Example of a namespace.
'xmlns:abc': 'http://www.example.com/abc'
});

//Start writing an element that has the namespace abc and add other XML
elements as children.
writer.writeStartElement('abc:parent');

//Write a simple XML element like <title>Azure Maps is awesome!</title>


writer.writeElement('title', 'Azure Maps is awesome!');

//Close the element that we have been writing children to.


writer.writeEndElement();
//Finish writing the document by closing the root tag and the document.
writer.writeEndElement().writeEndDocument();

//Get the generated XML string from the writer.


var xmlString = writer.toString();

The generated XML from the above code would look like the following.

XML

<?xml version="1.0" encoding="UTF-8"?>


<root version="1.0" xmlns="http://www.example.com"
xmlns:abc="http://www.example.com/abc">
<abc:parent>
<title>Azure Maps is awesome!</title>
</abc:parent>
</root>

Next steps
Learn more about the classes and methods used in this article:

CsvReader

CsvWriter

SimpleXmlReader

SimpleXmlWriter

See the following articles for more code samples to add to your maps:

Supported data format details

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Supported data format details
Article • 07/25/2023

This article provides specifics on the read and write support for all XML tags and Well-
Known Text geometry types. It also details how the delimited spatial data is parsed in
the spatial IO module.

Supported XML namespaces


The spatial IO module supports XML tags from the following namespaces.

Namespace Namespace URI Notes


Prefix

atom http://www.w3.org/2005/Atom

geo http://www.w3.org/2003/01/geo/wgs84_pos# Read only support in


GeoRSS files.

georss http://www.georss.org/georss

geourl http://geourl.org/rss/module/ Read only support in


GeoRSS files.

gml http://www.opengis.net/gml

gpx http://www.topografix.com/GPX/1/1

gpxx http://www.garmin.com/xmlschemas/GpxExtensions/v3 Read only support in GPX


files. Parses and uses
DisplayColor. All other
properties added to shape
metadata.

gpx_style http://www.topografix.com/GPX/gpx_style/0/2 Supported in GPX files.


Uses line color.

gx http://www.google.com/kml/ext/2.2

kml http://www.opengis.net/kml/2.2

rss Read only. GeoRSS writes


using Atom format.

Supported XML elements


The spatial IO module supports the following XML elements. Any XML tags that aren't
supported are converted into a JSON object. Then, each tag is added as a property in
the properties field of the parent shape or layer.

KML elements
The spatial IO module supports the following KML elements.

Element Name Read Write Notes

address partial yes Object is parsed but isn't used for positioning shape.

AddressDetails partial no Object is parsed but isn't used for positioning shape.

atom:author yes yes

atom:link yes yes

atom:name yes yes

BalloonStyle partial partial displayMode isn't supported. Converted to a


PopupTemplate . To write, add a popupTemplate property as
a property of the feature you want to write it for.

begin yes yes

color yes yes Includes #AABBGGRR and #BBGGRR . Parsed into a CSS color
string

colorMode yes no

coordinates yes yes

Data yes yes

description yes yes

displayName yes yes

Document yes yes

drawOrder partial no Read for ground overlays and used to sort them.

east yes yes

end yes yes

ExtendedData yes yes Supports untyped Data , SimpleData or Schema , and entity
replacements of the form $[dataName] .
Element Name Read Write Notes

extrude partial partial Only supported for polygons. MultiGeometry that have
polygons of different heights are broken out into
individual features. Line styles aren't supported. Polygons
with an altitude of 0 is rendered as a flat polygon. When
reading, the altitude of the first coordinate in the exterior
ring is added as a height property of the polygon. Then,
the altitude of the first coordinate is used to render the
polygon on the map.

fill yes yes

Folder yes yes

GroundOverlay yes yes color isn't supported

heading partial no Parsed but not rendered by SimpleDataLayer . Only writes


if data is stored in the property of the shape.

hotSpot yes partial Only writes if data is stored in the property of the shape.
Units are outputted as "pixels" only.

href yes yes

Icon partial partial Parsed but not rendered by SimpleDataLayer . Only writes
the icon property of the shape if it contains a URI data.
Only href is supported.

IconStyle partial partial icon , heading , colorMode , and hotspots values are
parsed, but not rendered by SimpleDataLayer

innerBoundaryIs yes yes

kml yes yes

LabelStyle no no

LatLonBox yes yes

gx:LatLonQuad yes yes

LinearRing yes yes

LineString yes yes

LineStyle yes yes colorMode isn't supported.

Link yes no Only the href property is supported for network links.

MultiGeometry partial partial May be broken out into individual features when read.
Element Name Read Write Notes

name yes yes

NetworkLink yes no Links need to be on the same domain as the document.

NetworkLinkControl no no

north yes yes

open yes yes

outerBoundaryIs yes yes

outline yes yes

overlayXY no no

Pair partial no Only the normal style in a StyleMap is supported.


highlight isn't supported.

phoneNumber yes yes

PhotoOverlay no no

Placemark yes yes

Point yes yes

Polygon yes yes

PolyStyle yes yes

Region partial partial LatLongBox is supported at the document level.

rotation no no

rotationXY no no

scale no no

Schema yes yes

SchemaData yes yes

schemaUrl partial yes Doesn't support loading styles from external documents
that aren't included in a KMZ.

ScreenOverlay no no

screenXY no no

SimpleData yes yes


Element Name Read Write Notes
SimpleField yes yes

size no no

Snippet partial partial maxLines attribute is ignored.

south yes yes

Style yes yes

StyleMap partial no Only the normal style in a StyleMap is supported.

styleUrl partial yes External style URLs aren't supported.

text yes yes Replacement of $[geDirections] isn't supported

textColor yes yes

TimeSpan yes yes

TimeStamp yes yes

value yes yes

viewRefreshMode partial no If pointing to a WMS service, then only onStop is


supported for ground overlays. Appends BBOX=
{bboxWest},{bboxSouth},{bboxEast},{bboxNorth} to the
URL and update as the map moves.

visibility yes yes

west yes yes

when yes yes

width yes yes

GeoRSS elements
The spatial IO module supports the following GeoRSS elements.

Element Name Read Write Notes

atom:author yes yes

atom:category yes yes

atom:content yes yes

atom:contributor yes yes


Element Name Read Write Notes
atom:email yes yes

atom:entry yes yes

atom:feed yes yes

atom:icon yes yes

atom:id yes yes

atom:link yes yes

atom:logo yes yes

atom:name yes yes

atom:published yes yes

atom:rights yes yes

atom:source yes yes

atom:subtitle yes yes

atom:summary yes yes

atom:title yes yes

atom:updated yes yes

atom:uri yes yes

geo:lat yes no Written as a georss:point .

geo:lon yes no Written as a georss:point .

geo:long yes no Written as a georss:point .

georss:box yes no Read as a polygon and given a subType property of


"Rectangle"

georss:circle yes yes

georss:elev yes yes

georss:featurename yes yes

georss:featuretypetag yes yes

georss:floor yes yes

georss:line yes yes


Element Name Read Write Notes

georss:point yes yes

georss:polygon yes yes

georss:radius yes yes

georss:relationshiptag yes yes

georss:where yes yes

geourl:latitude yes no Written as a georss:point .

geourl:longitude yes no Written as a georss:point .

position yes no Some XML feeds wrap GML with a position tag instead
of wrapping it with a georss:where tag. Read this tag,
but writes using a georss:where tag.

rss yes no GeoRSS written in ATOM format.

rss:author yes partial Written as an atom:author .

rss:category yes partial Written as an atom:category .

rss:channel yes no

rss:cloud yes no

rss:comments yes no

rss:copyright yes partial Written as an atom:rights if shape doesn't have a


rights properties property already.

rss:description yes partial Written as an atom:content if shape doesn't have a


content properties property already.

rss:docs yes no

rss:enclosure yes no

rss:generator yes no

rss:guid yes partial Written as an atom:id if shape doesn't have an id


properties property already.

rss:image yes partial Written as an atom:logo if shape doesn't have a logo


properties property already.

rss:item yes partial Written as an atom:entry .


Element Name Read Write Notes

rss:language yes no

rss:lastBuildDate yes partial Written as an atom:updated if shape doesn't have an


updated properties property already.

rss:link yes partial Written as an atom:link .

rss:managingEditor yes partial Written as an atom:contributor .

rss:pubDate yes partial Written as an atom:published if shape doesn't have a


published properties property already.

rss:rating yes no

rss:skipDays yes no

rss:skipHours yes no

rss:source yes partial Written as an atom:source containing an atom:link .

rss:textInput yes no

rss:title yes partial Written as an atom:title .

rss:ttl yes no

rss:webMaster yes no

GML elements
The spatial IO module supports the following GML elements.

Element Name Read Write Notes

gml:coordinates yes no Written as gml:posList .

gml:curveMember yes no

gml:curveMembers yes no

gml:Box yes no Written as gml:Envelope .

gml:description yes yes

gml:Envelope yes yes

gml:exterior yes yes


Element Name Read Write Notes

gml:Feature yes no Written as a shape.

gml:FeatureCollection yes no Written as a geometry collection.

gml:featureMember yes no Written as a geometry collection.

gml:geometry yes no Written as a shape.

gml:geometryMember yes yes

gml:geometryMembers yes yes

gml:identifier yes yes

gml:innerBoundaryIs yes no Written using gml.interior .

gml:interior yes yes

gml:LinearRing yes yes

gml:LineString yes yes

gml:lineStringMember yes yes

gml:lineStringMembers yes no

gml:MultiCurve yes no Only reads gml:LineString members. Written as


gml.MultiLineString

gml:MultiGeometry partial partial Only read as a FeatureCollection.

gml:MultiLineString yes yes

gml:MultiPoint yes yes

gml:MultiPolygon yes yes

gml:MultiSurface yes no Only reads gml:Polygon members. Written as


gml.MultiPolygon

gml:name yes yes

gml:outerBoundaryIs yes no Written using gml.exterior .

gml:Point yes yes

gml:pointMember yes yes

gml:pointMembers yes no

gml:Polygon yes yes


Element Name Read Write Notes
gml:polygonMember yes yes

gml:polygonMembers yes no

gml:pos yes yes

gml:posList yes yes

gml:surfaceMember yes yes

More notes
Member elements are searched for a geometry that may be buried within child
elements. This search operation is necessary as many XML formats that extend
from GML may not place a geometry as a direct child of a member element.
srsName is partially supported for WGS84 coordinates and the following

codes:EPSG:4326 ), and web Mercator (EPSG:3857 or one of its alternative


codes. Any other coordinate system is parsed as WGS84 as-is.
Unless specified when reading an XML feed, the axis order is determined based on
hints in the XML feed. A preference is given for the "latitude, longitude" axis order.
Unless a custom GML namespace is specified for the properties when writing to a
GML file, other property information isn't added.

GPX elements
The spatial IO module supports the following GPX elements.

Element Name Read Write Notes

gpx:ageofdgpsdata yes yes

gpx:author yes yes

gpx:bounds yes yes Converted into a LocationRect when read.

gpx:cmt yes yes

gpx:copyright yes yes

gpx:desc yes yes Copied into a description property when read to


align with other XML formats.

gpx:dgpsid yes yes

gpx:ele yes yes


Element Name Read Write Notes

gpx:extensions partial partial When read, style information is extracted. All other
extensions are flattened into a simple JSON object.
Only shape style information is written.

gpx:geoidheight yes yes

gpx:gpx yes yes

gpx:hdop yes yes

gpx:link yes yes

gpx:magvar yes yes

gpx:metadata yes yes

gpx:name yes yes

gpx:pdop yes yes

gpx:rte yes yes

gpx:rtept yes yes

gpx:sat yes yes

gpx:src yes yes

gpx:sym yes yes Value is captured, but it isn't used to alter the
pushpin icon.

gpx:text yes yes

gpx:time yes yes

gpx:trk yes yes

gpx:trkpt yes yes

gpx:trkseg yes yes

gpx:type yes yes

gpx:vdop yes yes

gpx:wpt yes yes

gpx_style:color yes yes

gpx_style:line partial partial color , opacity , width , lineCap are supported.


Element Name Read Write Notes

gpx_style:opacity yes yes

gpx_style:width yes yes

gpxx:DisplayColor yes no Used to specify the color of a shape. If writing,


gpx_style:line color is used instead.

gpxx:RouteExtension partial no All properties are read into properties . Only


DisplayColor is used.

gpxx:TrackExtension partial no All properties are read into properties . Only


DisplayColor is used.

gpxx:WaypointExtension partial no All properties are read into properties . Only


DisplayColor is used.

gpx:keywords yes yes

gpx:fix yes yes

More notes

When writing;

MultiPoints is broken up into individual waypoints.


Polygons and MultiPolygons are written as tracks.

Supported Well-Known Text geometry types


Geometry type Read Write

POINT x x

POINT Z x x

POINT M x x[2]

POINT ZM x[1][2]

LINESTRING x x

LINESTRING Z x x

LINESTRING M x x[2]

LINESTRING ZM x[1][2]
Geometry type Read Write

POLYGON x x

POLYGON Z x x

POLYGON M x x[2]

POLYGON ZM x[1][2]

MULTIPOINT x x

MULTIPOINT Z x x

MULTIPOINT M x x[2]

POMULTIPOINTINT ZM x[1][2]

MULTILINESTRING x x

MULTILINESTRING Z x x

MULTILINESTRING M x x[2]

MULTILINESTRING ZM x[1][2]

MULTIPOLYGON x x

MULTIPOLYGON Z x x

MULTIPOLYGON M x x[2]

MULTIPOLYGON ZM x[1][2]

GEOMETRYCOLLECTION x x

GEOMETRYCOLLECTION Z x x

GEOMETRYCOLLECTION M x x[2]

GEOMETRYCOLLECTION ZM x[1][2] x

[1] Only Z parameter is captured and added as a third value in the Position value.

[2] M parameter isn't captured.

Delimited spatial data support


Delimited spatial data, such as comma-separated value files (CSV), often have columns
that contain spatial data. For example, there could be columns that contain latitude and
longitude information. In Well-Known Text format, there could be a column that
contains spatial geometry data.

Spatial data column detection


When reading a delimited file that contains spatial data, the header is analyzed to
determine which columns contain location fields. If the header contains type
information, it's used to cast the cell values to the appropriate type. If no header is
specified, the first row is analyzed to generate a header. When analyzing the first row, a
check is executed to match column names with the following names in a case-
insensitive way. The order of the names is the priority, in case two or more names exist
in a file.

Latitude
latitude

lat

latdd
lat_dd

latitude83
latdecdeg

ycenter
point-y

Longitude
longitude

lon
lng

long

longdd
long_dd

longitude83
longdecdeg

xcenter
point-x
Elevation
elevation

elv
altitude

alt

Geography

The first row of data is scanned for strings that are in Well-Known Text format.

Delimited data column types


When scanning the header row, any type information that is in the column name is
extracted and used to cast the cells in that column. Here's an example of a column name
that has a type value: "ColumnName (typeName)". The following case-insensitive type
names are supported:

Numbers
edm.int64
int
long
edm.double
float
double
number

Booleans

edm.boolean
bool
boolean

Dates
edm.datetime
date
datetime
Geography
edm.geography
geography

Strings
edm.string
varchar
text
string

If no type information can be extracted from the header, and the dynamic typing option
is enabled when reading, then each cell is individually analyzed to determine what data
type it's best suited to be cast as.

Next steps
See the following articles for more code samples to add to your maps:

Read and write spatial data


Web SDK supported browsers
Article • 03/31/2025

The Azure Maps Web SDK provides a helper function called atlas.isSupported. This
function detects whether a web browser has the minimum set of WebGL features
required to support loading and rendering the map control. Here's an example of how
to use the function:

JavaScript

if (!atlas.isSupported()) {
alert('Your browser is not supported by Azure Maps');
} else if (!atlas.isSupported(true)) {
alert('Your browser is supported by Azure Maps, but may have major
performance caveats.');
} else {
// Your browser is supported. Add your map code here.
}

Desktop
The Azure Maps Web SDK supports the following desktop browsers:

Microsoft Edge (current and previous version)


Google Chrome (current and previous version)
Mozilla Firefox (current and previous version)
Apple Safari (macOS X) (current and previous version)

See also Target legacy browsers later in this article.

Node.js
The following Web SDK modules are also supported in Node.js:

Services module (documentation | npm module )

Target legacy browsers


You might want to target older browsers that don't support WebGL or that have only
limited support for it. In such cases, you can use Azure Maps services together with an
open-source map control like Leaflet .
The Render Azure Maps in Leaflet Azure Maps sample shows how to render Azure
Maps Raster Tiles in the Leaflet JS map control. This sample uses the open source Azure
Maps Leaflet plugin . For the source code for this sample, see Render Azure Maps in
Leaflet sample source code .

For more code samples using Azure Maps in Leaflet, see Azure Maps Samples .

Next steps
Learn more about the Azure Maps Web SDK:

Map control

Services module

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Azure Maps Web SDK best practices
Article • 06/23/2023

This document focuses on best practices for the Azure Maps Web SDK, however, many
of the best practices and optimizations outlined can be applied to all other Azure Maps
SDKs.

The Azure Maps Web SDK provides a powerful canvas for rendering large spatial data
sets in many different ways. In some cases, there are multiple ways to render data the
same way, but depending on the size of the data set and the desired functionality, one
method may perform better than others. This article highlights best practices and tips
and tricks to maximize performance and create a smooth user experience.

Generally, when looking to improve performance of the map, look for ways to reduce
the number of layers and sources, and the complexity of the data sets and rendering
styles being used.

Security best practices


For more information on security best practices, see Authentication and authorization
best practices.

Use the latest versions of Azure Maps


The Azure Maps SDKs go through regular security testing along with any external
dependency libraries used by the SDKs. Any known security issue is fixed in a timely
manner and released to production. If your application points to the latest major version
of the hosted version of the Azure Maps Web SDK, it automatically receives all minor
version updates that include security related fixes.

If self-hosting the Azure Maps Web SDK via the npm module, be sure to use the caret
(^) symbol to in combination with the Azure Maps npm package version number in your
package.json file so that it points to the latest minor version.

JSON

"dependencies": {
"azure-maps-control": "^2.2.6"
}
 Tip

Always use the latest version of the npm Azure Maps Control. For more
information, see azure-maps-control in the npm documentation.

Optimize initial map load


When a web page is loading, one of the first things you want to do is start rendering
something as soon as possible so that the user isn't staring at a blank screen.

Watch the maps ready event


Similarly, when the map initially loads often it's desired to load data on it as quickly as
possible, so the user isn't looking at an empty map. Since the map loads resources
asynchronously, you have to wait until the map is ready to be interacted with before
trying to render your own data on it. There are two events you can wait for, a load
event and a ready event. The load event will fire after the map has finished completely
loading the initial map view and every map tile has loaded. The ready event fires when
the minimal map resources needed to start interacting with the map. The ready event
can often fire in half the time of the load event and thus allow you to start loading your
data into the map sooner.

Lazy load the Azure Maps Web SDK


If the map isn't needed right away, lazy load the Azure Maps Web SDK until it's needed.
This delays the loading of the JavaScript and CSS files used by the Azure Maps Web SDK
until needed. A common scenario where this occurs is when the map is loaded in a tab
or flyout panel that isn't displayed on page load.

The Lazy Load the Map code sample shows how to delay the loading the Azure Maps
Web SDK until a button is pressed. For the source code, see Lazy Load the Map sample
code .

Add a placeholder for the map


If the map takes a while to load due to network limitations or other priorities within your
application, consider adding a small background image to the map div as a placeholder
for the map. This fills the void of the map div while it's loading.
Set initial map style and camera options on initialization
Often apps want to load the map to a specific location or style. Sometimes developers
wait until the map has loaded (or wait for the ready event), and then use the setCamera
or setStyle functions of the map. This often takes longer to get to the desired initial
map view since many resources end up being loaded by default before the resources
needed for the desired map view are loaded. A better approach is to pass in the desired
map camera and style options into the map when initializing it.

Optimize data sources


The Web SDK has two data sources,

GeoJSON source: The DataSource class, manages raw location data in GeoJSON
format locally. Good for small to medium data sets (upwards of hundreds of
thousands of features).
Vector tile source: The VectorTileSource class, loads data formatted as vector tiles
for the current map view, based on the maps tiling system. Ideal for large to
massive data sets (millions or billions of features).

Use tile-based solutions for large datasets


If working with larger datasets containing millions of features, the recommended way to
achieve optimal performance is to expose the data using a server-side solution such as
vector or raster image tile service.
Vector tiles are optimized to load only the data that is in view with the geometries
clipped to the focus area of the tile and generalized to match the resolution of the map
for the zoom level of the tile.

The Azure Maps Creator platform retrieves data in vector tile format. Other data formats
can be using tools such as Tippecanoe . For more information on working with vector
tiles, see the Mapbox awesome-vector-tiles readme in GitHub.

It's also possible to create a custom service that renders datasets as raster image tiles on
the server-side and load the data using the TileLayer class in the map SDK. This provides
exceptional performance as the map only needs to load and manage a few dozen
images at most. However, there are some limitations with using raster tiles since the raw
data isn't available locally. A secondary service is often required to power any type of
interaction experience, for example, find out what shape a user clicked on. Additionally,
the file size of a raster tile is often larger than a compressed vector tile that contains
generalized and zoom level optimized geometries.
For more information about data sources, see Create a data source.

Combine multiple datasets into a single vector tile source


The less data sources the map has to manage, the faster it can process all features to be
displayed. In particular, when it comes to tile sources, combining two vector tile sources
together cuts the number of HTTP requests to retrieve the tiles in half, and the total
amount of data would be slightly smaller since there's only one file header.

Combining multiple data sets in a single vector tile source can be achieved using a tool
such as Tippecanoe . Data sets can be combined into a single feature collection or
separated into separate layers within the vector tile known as source-layers. When
connecting a vector tile source to a rendering layer, you would specify the source-layer
that contains the data that you want to render with the layer.

Reduce the number of canvas refreshes due to data


updates
There are several ways data in a DataSource class can be added or updated. The
following list shows the different methods and some considerations to ensure good
performance.

The data sources add function can be used to add one or more features to a data
source. Each time this function is called it triggers a map canvas refresh. If adding
many features, combine them into an array or feature collection and passing them
into this function once, rather than looping over a data set and calling this function
for each feature.
The data sources setShapes function can be used to overwrite all shapes in a data
source. Under the hood, it combines the data sources clear and add functions
together and does a single map canvas refresh instead of two, which is faster. Be
sure to use this function when you want to update all data in a data source.
The data sources importDataFromUrl function can be used to load a GeoJSON file
via a URL into a data source. Once the data has been downloaded, it's passed into
the data sources add function. If the GeoJSON file is hosted on a different domain,
be sure that the other domain supports cross domain requests (CORs). If it doesn't
consider copying the data to a local file on your domain or creating a proxy service
that has CORs enabled. If the file is large, consider converting it into a vector tile
source.
If features are wrapped with the Shape class, the addProperty , setCoordinates , and
setProperties functions of the shape all trigger an update in the data source and
a map canvas refresh. All features returned by the data sources getShapes and
getShapeById functions are automatically wrapped with the Shape class. If you
want to update several shapes, it's faster to convert them to JSON using the data
sources toJson function, editing the GeoJSON, then passing this data into the data
sources setShapes function.

Avoid calling the data sources clear function


unnecessarily
Calling the clear function of the DataSource class causes a map canvas refresh. If the
clear function is called multiple times in a row, a delay can occur while the map waits

for each refresh to occur.

This is a common scenario in applications that clear the data source, download new
data, clear the data source again, then adds the new data to the data source. Depending
on the desired user experience, the following alternatives would be better.

Clear the data before downloading the new data, then pass the new data into the
data sources add or setShapes function. If this is the only data set on the map, the
map is empty while the new data is downloading.
Download the new data, then pass it into the data sources setShapes function. This
replaces all the data on the map.

Remove unused features and properties


If your dataset contains features that aren't going to be used in your app, remove them.
Similarly, remove any properties on features that aren't needed. This has several
benefits:

Reduces the amount of data that has to be downloaded.


Reduces the number of features that need to be looped through when rendering
the data.
Can sometimes help simplify or remove data-driven expressions and filters, which
mean less processing required at render time.

When features have numerous properties or content, it's much more performant to limit
what gets added to the data source to just those needed for rendering and to have a
separate method or service for retrieving the other property or content when needed.
For example, if you have a simple map displaying locations on a map when clicked a
bunch of detailed content is displayed. If you want to use data driven styling to
customize how the locations are rendered on the map, only load the properties needed
into the data source. When you want to display the detailed content, use the ID of the
feature to retrieve the other content separately. If the content is stored on the server,
you can reduce the amount of data that needs to be downloaded when the map is
initially loaded by using a service to retrieve it asynchronously.

Additionally, reducing the number of significant digits in the coordinates of features can
also significantly reduce the data size. It isn't uncommon for coordinates to contain 12
or more decimal places; however, six decimal places have an accuracy of about 0.1
meter, which is often more precise than the location the coordinate represents (six
decimal places is recommended when working with small location data such as indoor
building layouts). Having any more than six decimal places will likely make no difference
in how the data is rendered and requires the user to download more data for no added
benefit.

Here's a list of useful tools for working with GeoJSON data .

Use a separate data source for rapidly changing data


Sometimes there's a need to rapidly update data on the map for things such as showing
live updates of streaming data or animating features. When a data source is updated,
the rendering engine loops through and render all features in the data source. Improve
overall performance by separating static from rapidly changing data into different data
sources, reducing the number of features re-rendered during each update.

If using vector tiles with live data, an easy way to support updates is to use the expires
response header. By default, any vector tile source or raster tile layer will automatically
reload tiles when the expires date. The traffic flow and incident tiles in the map use this
feature to ensure fresh real-time traffic data is displayed on the map. This feature can be
disabled by setting the maps refreshExpiredTiles service option to false .

Adjust the buffer and tolerance options in GeoJSON data


sources
The DataSource class converts raw location data into vector tiles local for on-the-fly
rendering. These local vector tiles clip the raw data to the bounds of the tile area with a
bit of buffer to ensure smooth rendering between tiles. The smaller the buffer option is,
the fewer overlapping data is stored in the local vector tiles and the better performance,
however, the greater the change of rendering artifacts occurring. Try tweaking this
option to get the right mix of performance with minimal rendering artifacts.
The DataSource class also has a tolerance option that is used with the Douglas-Peucker
simplification algorithm when reducing the resolution of geometries for rendering
purposes. Increasing this tolerance value reduces the resolution of geometries and in
turn improve performance. Tweak this option to get the right mix of geometry
resolution and performance for your data set.

Set the max zoom option of GeoJSON data sources


The DataSource class converts raw location data into vector tiles local for on-the-fly
rendering. By default, it does this until zoom level 18, at which point, when zoomed in
closer, it samples data from the tiles generated for zoom level 18. This works well for
most data sets that need to have high resolution when zoomed in at these levels.
However, when working with data sets that are more likely to be viewed when zoomed
out more, such as when viewing state or province polygons, setting the minZoom option
of the data source to a smaller value such as 12 reduces the amount computation, local
tile generation that occurs, and memory used by the data source and increase
performance.

Minimize GeoJSON response


When loading GeoJSON data from a server either through a service or by loading a flat
file, be sure to have the data minimized to remove unneeded space characters that
makes the download size larger than needed.

Access raw GeoJSON using a URL


It's possible to store GeoJSON objects inline inside of JavaScript, however this uses more
memory as copies of it are stored across the variable you created for this object and the
data source instance, which manages it within a separate web worker. Expose the
GeoJSON to your app using a URL instead and the data source loads a single copy of
data directly into the data sources web worker.

Optimize rendering layers


Azure maps provides several different layers for rendering data on a map. There are
many optimizations you can take advantage of to tailor these layers to your scenario the
increase performances and the overall user experience.

Create layers once and reuse them


The Azure Maps Web SDK is data driven. Data goes into data sources, which are then
connected to rendering layers. If you want to change the data on the map, update the
data in the data source or change the style options on a layer. This is often faster than
removing, then recreating layers with every change.

Consider bubble layer over symbol layer


The bubble layer renders points as circles on the map and can easily have their radius
and color styled using a data-driven expression. Since the circle is a simple shape for
WebGL to draw, the rendering engine is able to render these faster than a symbol layer,
which has to load and render an image. The performance difference of these two
rendering layers is noticeable when rendering tens of thousands of points.

Use HTML markers and Popups sparingly


Unlike most layers in the Azure Maps Web control that use WebGL for rendering, HTML
Markers and Popups use traditional DOM elements for rendering. As such, the more
HTML markers and Popups added a page, the more DOM elements there are.
Performance can degrade after adding a few hundred HTML markers or popups. For
larger data sets, consider either clustering your data or using a symbol or bubble layer.

The Reusing Popup with Multiple Pins code sample shows how to create a single
popup and reuse it by updating its content and position. For the source code, see
Reusing Popup with Multiple Pins sample code .

That said, if you only have a few points to render on the map, the simplicity of HTML
markers may be preferred. Additionally, HTML markers can easily be made draggable if
needed.

Combine layers
The map is capable of rendering hundreds of layers, however, the more layers there are,
the more time it takes to render a scene. One strategy to reduce the number of layers is
to combine layers that have similar styles or can be styled using data-driven styles.

For example, consider a data set where all features have a isHealthy property that can
have a value of true or false . If creating a bubble layer that renders different colored
bubbles based on this property, there are several ways to do this as shown in the
following list, from least performant to most performant.

Split the data into two data sources based on the isHealthy value and attach a
bubble layer with a hard-coded color option to each data source.
Put all the data into a single data source and create two bubble layers with a hard-
coded color option and a filter based on the isHealthy property.
Put all the data into a single data source, create a single bubble layer with a case
style expression for the color option based on the isHealthy property. Here's a
code sample that demonstrates this.

JavaScript

var layer = new atlas.layer.BubbleLayer(source, null, {


color: [
'case',

//Get the 'isHealthy' property from the feature.


['get', 'isHealthy'],

//If true, make the color 'green'.


'green',

//If false, make the color red.


'red'
]
});

Create smooth symbol layer animations


Symbol layers have collision detection enabled by default. This collision detection aims
to ensure that no two symbols overlap. The icon and text options of a symbol layer have
two options,
allowOverlap - specifies if the symbol is visible when it collides with other symbols.

ignorePlacement - specifies if the other symbols are allowed to collide with the
symbol.

Both of these options are set to false by default. When animating a symbol, the
collision detection calculations run on each frame of the animation, which can slow
down the animation and make it look less fluid. To smooth out the animation, set these
options to true .

The Simple Symbol Animation code sample demonstrates a simple way to animate a
symbol layer. For the source code to this sample, see Simple Symbol Animation sample
code .

Specify zoom level range


If your data meets one of the following criteria, be sure to specify the min and max
zoom level of the layer so that the rendering engine can skip it when outside of the
zoom level range.

If the data is coming from a vector tile source, often source layers for different data
types are only available through a range of zoom levels.
If using a tile layer that doesn't have tiles for all zoom levels 0 through 24 and you
want it to only rendering at the levels it has tiles, and not try to fill in missing tiles
with tiles from other zoom levels.
If you only want to render a layer at certain zoom levels. All layers have a minZoom
and maxZoom option where the layer is rendered when between these zoom levels
based on this logic maxZoom > zoom >= minZoom .
Example

JavaScript

//Only render this layer between zoom levels 1 and 9.


var layer = new atlas.layer.BubbleLayer(dataSource, null, {
minZoom: 1,
maxZoom: 10
});

Specify tile layer bounds and source zoom range


By default, tile layers load tiles across the whole globe. However, if the tile service only
has tiles for a certain area the map tries to load tiles when outside of this area. When
this happens, a request for each tile is made and wait for a response that can block
other requests being made by the map and thus slow down the rendering of other
layers. Specifying the bounds of a tile layer results in the map only requesting tiles that
are within that bounding box. Also, if the tile layer is only available between certain
zoom levels, specify the min and max source zoom for the same reason.

Example

JavaScript

var tileLayer = new atlas.layer.TileLayer({


tileUrl: 'myTileServer/{z}/{y}/{x}.png',
bounds: [-101.065, 14.01, -80.538, 35.176],
minSourceZoom: 1,
maxSourceZoom: 10
});

Use a blank map style when base map not visible


If a layer is overlaid on the map that completely covers the base map, consider setting
the map style to blank or blank_accessible so that the base map isn't rendered. A
common scenario for doing this is when overlaying a full globe tile at has no opacity or
transparent area above the base map.

Smoothly animate image or tile layers


If you want to animate through a series of image or tile layers on the map. It's often
faster to create a layer for each image or tile layer and to change the opacity than to
update the source of a single layer on each animation frame. Hiding a layer by setting
the opacity to zero and showing a new layer by setting its opacity to a value greater
than zero is faster than updating the source in the layer. Alternatively, the visibility of the
layers can be toggled, but be sure to set the fade duration of the layer to zero,
otherwise it animates the layer when displaying it, which causes a flicker effect since the
previous layer would have been hidden before the new layer is visible.

Tweak Symbol layer collision detection logic


The symbol layer has two options that exist for both icon and text called allowOverlap
and ignorePlacement . These two options specify if the icon or text of a symbol can
overlap or be overlapped. When these are set to false , the symbol layer does
calculations when rendering each point to see if it collides with any other already
rendered symbol in the layer, and if it does, don't render the colliding symbol. This is
good at reducing clutter on the map and reducing the number of objects rendered. By
setting these options to false , this collision detection logic is skipped, and all symbols
are rendered on the map. Tweak this option to get the best combination of performance
and user experience.

Cluster large point data sets


When working with large sets of data points you may find that when rendered at certain
zoom levels, many of the points overlap and are only partial visible, if at all. Clustering is
process of grouping points that are close together and representing them as a single
clustered point. As the user zooms in the map, clusters break apart into their individual
points. This can significantly reduce the amount of data that needs to be rendered,
make the map feel less cluttered, and improve performance. The DataSource class has
options for clustering data locally. Additionally, many tools that generate vector tiles
also have clustering options.

Additionally, increase the size of the cluster radius to improve performance. The larger
the cluster radius, the less clustered points there's to keep track of and render. For more
information, see Clustering point data in the Web SDK.

Use weighted clustered heat maps


The heat map layer can render tens of thousands of data points easily. For larger data
sets, consider enabling clustering on the data source and using a small cluster radius
and use the clusters point_count property as a weight for the height map. When the
cluster radius is only a few pixels in size, there's little visual difference in the rendered
heat map. Using a larger cluster radius improves performance more but may reduce the
resolution of the rendered heat map.

JavaScript

var layer = new atlas.layer.HeatMapLayer(source, null, {


weight: ['get', 'point_count']
});

For more information, see Clustering and the heat maps layer.

Keep image resources small


Images can be added to the maps image sprite for rendering icons in a symbol layer or
patterns in a polygon layer. Keep these images small to minimize the amount of data
that has to be downloaded and the amount of space they take up in the maps image
sprite. When using a symbol layer that scales the icon using the size option, use an
image that is the maximum size your plan to display on the map and no bigger. This
ensures the icon is rendered with high resolution while minimizing the resources it uses.
Additionally, SVGs can also be used as a smaller file format for simple icon images.

Optimize expressions
Data-driven style expressions provide flexibility and power for filtering and styling data
on the map. There are many ways in which expressions can be optimized. Here are a few
tips.

Reduce the complexity of filters


Filters loop over all data in a data source and check to see if each filter matches the
logic in the filter. If filters become complex, this can cause performance issues. Some
possible strategies to address this include the following.

If using vector tiles, break up the data into different source layers.
If using the DataSource class, break up that data into separate data sources. Try to
balance the number of data sources with the complexity of the filter. Too many
data sources can cause performance issues too, so you might need to do some
testing to find out what works best for your scenario.
When using a complex filter on a layer, consider using multiple layers with style
expressions to reduce the complexity of the filter. Avoid creating a bunch of layers
with hardcoded styles when style expressions can be used as a large number of
layers can also cause performance issues.

Make sure expressions don't produce errors


Expressions are often used to generate code to perform calculations or logical
operations at render time. Just like the code in the rest of your application, be sure the
calculations and logical make sense and aren't error prone. Errors in expressions cause
issues in evaluating the expression, which can result in reduced performance and
rendering issues.

One common error to be mindful of is having an expression that relies on a feature


property that might not exist on all features. For example, the following code uses an
expression to set the color property of a bubble layer to the myColor property of a
feature.

JavaScript

var layer = new atlas.layer.BubbleLayer(source, null, {


color: ['get', 'myColor']
});

The above code functions fine if all features in the data source have a myColor property,
and the value of that property is a color. This may not be an issue if you have complete
control of the data in the data source and know for certain all features have a valid color
in a myColor property. That said, to make this code safe from errors, a case expression
can be used with the has expression to check that the feature has the myColor property.
If it does, the to-color type expression can then be used to try to convert the value of
that property to a color. If the color is invalid, a fallback color can be used. The following
code demonstrates how to do this and sets the fallback color to green.

JavaScript

var layer = new atlas.layer.BubbleLayer(source, null, {


color: [
'case',

//Check to see if the feature has a 'myColor' property.


['has', 'myColor'],

//If true, try validating that 'myColor' value is a color, or


fallback to 'green'.
['to-color', ['get', 'myColor'], 'green'],

//If false, return a fallback value.


'green'
]
});

Order boolean expressions from most specific to least


specific
Reduce the total number of conditional tests required when using boolean expressions
that contain multiple conditional tests by ordering them from most to least specific.

Simplify expressions
Expressions can be powerful and sometimes complex. The simpler an expression is, the
faster it's evaluated. For example, if a simple comparison is needed, an expression like
['==', ['get', 'category'], 'restaurant'] would be better than using a match

expression like ['match', ['get', 'category'], 'restaurant', true, false] . In this


case, if the property being checked is a boolean value, a get expression would be even
simpler ['get','isRestaurant'] .

Web SDK troubleshooting


The following are some tips to debugging some of the common issues encountered
when developing with the Azure Maps Web SDK.

Why doesn't the map display when I load the web control?

Things to check:

Ensure that you complete your authentication options in the map. Without
authentication, the map loads a blank canvas and returns a 401 error in the
network tab of the browser's developer tools.
Ensure that you have an internet connection.
Check the console for errors of the browser's developer tools. Some errors may
cause the map not to render. Debug your application.
Ensure you're using a supported browser.

All my data is showing up on the other side of the world, what's going on?

Coordinates, also referred to as positions, in the Azure Maps SDKs aligns with the
geospatial industry standard format of [longitude, latitude] . This same format is also
how coordinates are defined in the GeoJSON schema; the core data formatted used
within the Azure Maps SDKs. If your data is appearing on the opposite side of the world,
it's most likely due to the longitude and latitude values being reversed in your
coordinate/position information.

Why are HTML markers appearing in the wrong place in the web control?

Things to check:

If using custom content for the marker, ensure the anchor and pixelOffset
options are correct. By default, the bottom center of the content is aligned with the
position on the map.
Ensure that the CSS file for Azure Maps has been loaded.
Inspect the HTML marker DOM element to see if any CSS from your app has
appended itself to the marker and is affecting its position.

Why are icons or text in the symbol layer appearing in the wrong place?

Check that the anchor and the offset options are configured correctly to align with the
part of your image or text that you want to have aligned with the coordinate on the
map. If the symbol is only out of place when the map is rotated, check the
rotationAlignment option. By default, symbols rotate with the maps viewport, appearing

upright to the user. However, depending on your scenario, it may be desirable to lock
the symbol to the map's orientation by setting the rotationAlignment option to map .

If the symbol is only out of place when the map is pitched/tilted, check the
pitchAlignment option. By default, symbols stay upright in the maps viewport when the

map is pitched or tilted. However, depending on your scenario, it may be desirable to


lock the symbol to the map's pitch by setting the pitchAlignment option to map .

Why isn't any of my data appearing on the map?

Things to check:

Check the console in the browser's developer tools for errors.


Ensure that a data source has been created and added to the map, and that the
data source has been connected to a rendering layer that has also been added to
the map.
Add break points in your code and step through it. Ensure data is added to the
data source and the data source and layers are added to the map.
Try removing data-driven expressions from your rendering layer. It's possible that
one of them may have an error in it that is causing the issue.

Can I use the Azure Maps Web SDK in a sandboxed iframe?


Yes.

Get support
The following are the different ways to get support for Azure Maps depending on your
issue.

How do I report a data issue or an issue with an address?

Report issues using the Azure Maps feedback site. Detailed instructions on reporting
data issues are provided in the Provide data feedback to Azure Maps article.

7 Note

Each issue submitted generates a unique URL to track it. Resolution times vary
depending on issue type and the time required to verify the change is correct. The
changes will appear in the render services weekly update, while other services such
as geocoding and routing are updated monthly.

How do I report a bug in a service or API?

Report issues on Azure's Help + support page by selecting the Create a support
request button.

Where do I get technical help for Azure Maps?

For questions related to the Azure Maps Power BI visual, contact Power BI
support .

For all other Azure Maps services, contact Azure support .

For question or comments on specific Azure Maps Features, use the Azure Maps
developer forums.

Next steps
See the following articles for more tips on improving the user experience in your
application.

Make your application accessible

Learn more about the terminology used by Azure Maps and the geospatial industry.
Azure Maps glossary
Convert Map and Filled map visuals to
an Azure Maps visual
Article • 01/23/2025

The Azure Maps visual is now Generally Available, providing a streamlined and intuitive
experience for working with your data.

How to convert your existing Map and Filled


map visuals
A conversion function is available in Power BI desktop to convert any existing Map and
Filled map visuals to the new Azure Maps visual.

When opening a report with Map and Filled map visuals, you'll see the following dialog
giving you the option to upgrade to the new Azure Maps visual:

When selecting the Upgrade maps button, all Map and Filled map visuals in the current
report are converted. You can also convert a specific Map or Filled Map Visual to an
Azure Maps visual in the Visual gallery.

All settings associated with the original visuals are carried over to the new Azure Maps
visual, ensuring consistency in the migrated report.
7 Note

Due to differences in supported bubble size ranges between the two platforms, you
may notice that some bubbles appear smaller on the converted Azure Maps visual
compared to their original size in the Maps visual. This is because the maximum
bubble size in Azure Maps is smaller than the maximum bubble size in Bing Maps.
Bubble size differences can vary based on the visual dimension and the report's
zoom level.

The migration function streamlines the process of converting Map and Filled map
visuals to Azure Maps visuals, providing users with an efficient and easy-to-use solution.

Next steps
Get started with Azure Maps Power BI visual

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Get started with Azure Maps Power BI
visual
Article • 05/09/2025

This article shows how to use the Microsoft Azure Maps Power BI visual.

APPLIES TO: Power BI service for consumers Power BI service for designers &
developers Power BI Desktop Requires Pro or Premium license

7 Note

This visual can be created and viewed in both Power BI Desktop and the Power BI service.
The steps and illustrations in this article are from Power BI Desktop.

The Azure Maps Power BI visual provides a rich set of data visualizations for spatial data on top
of a map. It's estimated that over 80% of business data has a location context. The Azure Maps
Power BI visual can be used to gain insights into how this location context relates to and
influences your business data.


7 Note

Power BI ensures that no Personal Identifiable Information (PII) is sent to Azure Maps.
Additionally, IP addresses are truncated in the Power BI diagnostic logs.

What is sent to Azure?


The Azure Maps Power BI visual connects to cloud service hosted in Azure to retrieve location
data such as map images and coordinates that are used to create the map visualization.

Details about the area the map is focused on are sent to Azure to retrieve images needed
to render the map canvas (also known as map tiles).
Data in the Location, Latitude, and Longitude buckets may be sent to Azure to retrieve
map coordinates (a process called geocoding).
Telemetry data may be collected on the health of the visual (for example, crash reports), if
the telemetry option in Power BI is enabled.

Other than the scenarios previously described, no other data overlaid on the map is sent to the
Azure Maps servers. All rendering of data happens locally within the client.

 Tip

If using the Azure Maps Geographic API endpoints, your firewall may need to be updated
to allow access to the Azure Maps platform using either or all of the following URLs:

https://atlas.microsoft.com

https://us.atlas.microsoft.com

https://eu.atlas.microsoft.com

) Important

The selection tool within the Azure Maps Power BI visual relies on TomTom data,
consequently user data may not always remain within the user’s geographical boundary.

For more information about privacy and terms of use related to the Azure Maps Power BI
visual, see Microsoft Azure Legal Information .

Use the Azure Maps Power BI visual


Once the Azure Maps Power BI visual is enabled, select the Azure Maps icon from the
Visualizations pane.

Power BI creates an empty Azure Maps visual design canvas.

Take the following steps to load the Azure Maps visual:


1. Performing one of the two following actions in the Fields pane provides the minimal data
needed to load the Azure Maps visual:
a. Drag data fields containing latitude and longitude coordinate information into the
Latitude and/or Longitude buckets.
b. Drag data fields containing geospatial data to the Location bucket.

2. To color the data based on categorization, drag a categorical field into the Legend bucket
of the Fields pane. In this example, we're using the BussinessName column.

3. To scale the data relatively, drag a measure into the Size bucket of the Fields pane. In this
example, we're using Avg Weekly Sales column.

7 Note

Unlike the other screenshots in this section, this screenshot demonstrates


Geocoding in Azure Maps Power BI Visual, using coordinate fields (lat/lon) instead
of providing a physical address.

4. Use the options in the Format pane to customize how data is rendered. The following
image is the same map as shown previously, but with the bubble layers fill transparency
option set to 25%, smaller radius, and a black border.

5. You can also show or hide labels in the Format pane. The following two images show
maps with the Labels setting turned on and off:

6. You can also show or hide country borders, state or province borders, county borders,
building, and road details in the Format pane. The following two images show maps with
the Country borders settings turned on and off:


Fields pane buckets


The following data buckets are available in the Fields pane of the Azure Maps visual.

ノ Expand table

Field Description

Location Used to enter easily understandable geographical data such as country/region, state, and
city.

Latitude The field used to specify the latitude value of the data points. Latitude values should be
between -90 and 90 in decimal degrees format.

Longitude The field used to specify the longitude value of the data points. Longitude values should be
between -180 and 180 in decimal degrees format.

Legend The field used to categorize the data and assign a unique color for data points in each
category. When this bucket is filled, a Data colors section appears in the Format pane that
allows adjustments to the colors.

Size The measure used for relative sizing of data points on the map.

Tooltips Other data fields to display in tooltips when shapes are hovered.

Map settings
The Map settings section of the Format pane provide options for customizing how the map is
displayed and reacts to updates.

The Map settings section is divided into three subsections: style, view and controls.
Style
The following settings are available in the Style section:

ノ Expand table

Setting Description

Style The style of the map. The dropdown list contains blank and blank accessible, grayscale
dark, grayscale light, high contrast dark, high contrast light, night, road, road shaded
relief, satellite and satellite road labels.

Labels A toggle switch that allows you to show or hide map labels. For more information, see
item number five in the previous section titled Use the Azure Maps Power BI visual.

Country A toggle switch that controls the visibility of country borders.


borders

State or A toggle switch that controls the visibility of the borders for the first-level administrative
province divisions, such as state or province borders.
borders

County A toggle switch that controls the visibility of the borders for the second-level
borders administrative divisions, such as county borders.

Buildings A toggle switch that controls the visibility of building footprints

Road details A toggle switch that adjusts the level of detail for visible roads. Turning this off will
reduce the number of roads shown on the map.

The availability of the above toggles depends on the selected style. Below is a table showing
the supported options for different styles:

ノ Expand table

Map styles Labels Country State or province County Buildings Road


borders borders borders details

blank and blank ❌ ❌ ❌ ❌ ❌ ❌


accessible

grayscale dark ✅ ✅ ✅ ❌ ✅ ✅

grayscale light ✅ ✅ ✅ ❌ ✅ ✅

high contrast dark ✅ ✅ ✅ ✅ ✅ ✅

high contrast light ✅ ✅ ✅ ✅ ✅ ✅


Map styles Labels Country State or province County Buildings Road
borders borders borders details

night ✅ ✅ ✅ ✅ ✅ ✅

road ✅ ✅ ✅ ✅ ✅ ✅

road shaded relief ✅ ✅ ✅ ✅ ✅ ✅

satellite ❌ ❌ ❌ ❌ ❌ ❌

satellite road ✅ ✅ ✅ ✅ ❌ ❌
labels

If an option is not supported by the currently selected style, it will have no effect until you
choose a style that supports it.

View
The following settings available in the View section enable the user to specify the default map
view information when the Auto zoom setting is set to Off.

ノ Expand table

Setting Description

Auto zoom Automatically zooms the map into the data loaded through the Fields pane of the visual.
As the data changes, the map updates its position accordingly. When Auto zoom is set to
Off, the remaining settings in this section become active that enable to user to define the
default map view.

Include Includes reference layer data when the map automatically zooms. This option is only
reference available when Auto zoom is set to On.
layer

Zoom The default zoom level of the map. Can be a number between 0 and 22.

Center The default latitude of the center of the map.


latitude

Center The default longitude of the center of the map.


longitude

Heading The default orientation of the map in degrees, where 0 is north, 90 is east, 180 is south,
and 270 is west. Can be any number between 0 and 360.

Pitch The default tilt of the map in degrees between 0 and 60, where 0 is looking straight down
at the map.
Controls
The following settings are available in the Controls section:

ノ Expand table

Setting Description

World wrap Allows the user to pan the map horizontally infinitely.

Style picker Adds a button to the map that allows the report readers to change the style of the map.

Navigation Adds buttons to the map as another method to allow the report readers to zoom, rotate,
and change the pitch of the map. See this document on Navigating the map for details on
all the different ways users can navigate the map.

Selection Adds a button that allows the user to choose between different modes to select data on
the map; circle, rectangle, polygon (lasso), or travel time or distance. To complete drawing
a polygon; select the first point, or double-click on the last point on the map, or press the
c key.

Geocoding The default, Auto, refers to the Western Address System. The only other option, JA, refers
culture to the Japanese address system. In the western address system, you begin with the
address details and then proceed to the larger categories such as city, state and postal
code. In the Japanese address system, the larger categories are listed first and finish with
the address details.

Considerations and Limitations


The Azure Maps Power BI visual is available in the following services and applications:

ノ Expand table

Service/App Availability

Power BI Desktop Yes

Power BI service (app.powerbi.com) Yes

Power BI mobile applications Yes

Power BI publish to web Yes

Power BI Embedded Yes

Power BI service embedding (PowerBI.com) Yes

Power BI export No
Service/App Availability

Power BI subscriptions No

Where is Azure Maps Visual for Power BI available?

At this time, Azure Maps is currently available in all countries and regions except:

China
South Korea
Azure Government (GCC + GCC High)

For coverage details for the different Azure Maps services that power this visual, see
Geographic coverage information.

Which web browsers are supported by the Azure Maps Power BI visual?

For a list of supported browsers, see Azure Maps Web SDK supported browsers.

How many data points can I visualize?

This visual supports up to 30,000 data points.

Can addresses or other location strings be used in this visual?

Yes, addresses and other location strings can be used in the Azure Maps Power BI visual. For
more information on addresses and other location strings, see The location field in the
Geocoding in Azure Maps Power BI Visual article.

Next steps
Learn more about the Azure Maps Power BI visual:

Understanding layers in the Azure Maps Power BI visual

Manage the Azure Maps Power BI visual within your organization

Customize the visual:

Tips and tricks for color formatting in Power BI

Customize visualization titles, backgrounds, and legends


Geocoding in Azure Maps Power BI
Visual
Article • 01/23/2025

Azure Maps uses the latitude and longitude coordinate system to locate places on the
map. The Azure Maps Power BI Visual provides latitude and longitude fields to pinpoint
a specific location on the map, however most data sources use an address to pinpoint a
location as opposed to latitude and longitude values.

The Azure Maps Power BI Visual now provides a Location field that accepts address
values that can be used to pinpoint a location on the map using geocoding.

Geocoding is the process of taking an address and returning the corresponding


latitude/longitude coordinate. The address determines the granularity it's possible to
geocode, such as a city as opposed to a specific street address.
The location field
The Location field in the Azure Maps Power BI Visual can accept multiple values, such as
country/region, state, city, street address, and zip code. Providing multiple sources of
location information in the Location field enhances the accuracy of results and removes
any ambiguity that might limit the identification of a specific location. For example,
there are over 20 different cities in the United States named Franklin.
Use geo-hierarchies to drill down
When entering multiple values into the Location field, you create a geo-hierarchy. Geo-
hierarchies enable the hierarchical drill-down features in the map, allowing you to drill
down to different "levels" of location.

ノ Expand table

Button Description

1 The drill button called "Drill Mode", allows you to select a map Location and drill down
into that specific location one level at a time. For example, if you turn on the drill-down
option and select North America, you move down in the hierarchy to the next level--
states in North America. For geocoding, Power BI sends Azure Maps country and state
data for North America only. The button on its left goes up one level.

2 The double arrow drills to the next level of the hierarchy for all locations at once. For
example, if you're currently looking at countries/regions and then use this option to
move to the next level, states, Power BI displays state data for all countries/regions. For
geocoding, Power BI sends Azure Maps state data (no country/region data) for all
locations. This option is useful if each level of your hierarchy is unrelated to the level
above it.

3 Similar to the drill-down option, except that you don't need to select the map. It
expands down to the next level of the hierarchy remembering the current level's
context. For example, if you're currently looking at countries/regions and select this
icon, you move down in the hierarchy to the next level--states. For geocoding, Power BI
sends data for each state and its corresponding country/region to help Azure Maps
geocode more accurately. In most maps, either use this option or the drill-down option
on the far right. This sends Azure as much information as possible and result in more
accurate location information.
Categorize geographic fields in Power BI
To ensure fields are correctly geocoded, you can set the Data Category on the data
fields in Power BI. In Data view, select the desired column. From the ribbon, select the
Modeling tab and then set the Data Category to one of the following properties:
Address, Place, City, County, State or Province, Postal Code, Country, Continent, Latitude,
or Longitude. These data categories help Azure correctly encode the data. To learn
more, see Data categorization in Power BI Desktop. If you're live connecting to SQL
Server Analysis Services, set the data categorization outside of Power BI using SQL
Server Data Tools (SSDT).

7 Note

When categorizing geographic fields in Power BI, be sure to enter State and
County data separately for accurate geocoding. Incorrect categorization, such as
entering both State and County data into either category, might work currently but
can lead to issues in the future.

For instance:

Correct Usage: State = GA, County = Decatur County


Incorrect Usage: State = Decatur County, GA, or County = Decatur County, GA

Next steps
Learn more about the Azure Maps Power BI visual:
Get started with Azure Maps Power BI visual

Understanding layers in the Azure Maps Power BI visual

Learn about the Azure Maps Power BI visual Pie Chart layer that uses geocoding:

Add a pie chart layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Layers in Azure Maps Power BI visual
06/09/2025

There are two types of layers available in an Azure Maps Power BI visual. The first type focuses
on rendering data that is passed into the Fields pane of the visual and consist of the following
layers, let's call these data rendering layers.

Bubble layer

Renders points as scaled circles on the map.

3D column layer

Renders points as 3D columns on the map.

Filled map layer


Provides a visual display to shows differences in values across a geography or region.

Heat map layer

Shows data "hot spots" on a map.

The second type of layer connects addition external sources of data to map to provide more
context and consists of the following layers.

Reference layer

Overlay an uploaded GeoJSON file on top of the map.

Tile layer
Overlay a custom tile layer on top of the map.

Traffic layer

Overlay real-time traffic information on the map.

All the data rendering layers and the Tile layer, have options for min and max zoom levels that
are used to specify a zoom level range these layers should be displayed at. These options allow
one type of rendering layer to be used at one zoom level and a transition to another rendering
layer at another zoom level.

These layers can also be positioned relative to other layers in the map. When multiple data
rendering layers are used, the order in which they're added to the map determines their
relative layering order when they have the same Layer position value.

General layer settings


The general layer section of the Format pane are common settings that apply to the layers that
are connected to the Power BI dataset in the Fields pane (Bubble layer, 3D column layer).

ノ Expand table

Setting Description

Unselected The transparency of shapes that aren't selected, when one or more shapes are
transparency selected.

Min data value The minimum value of the input data to scale against. Good for clipping
outliers.

Max data value The maximum value of the input data to scale against. Good for clipping
outliers.

Layer positions
In the Azure Maps visual, certain layers are fixed, meaning they're set at a predefined level and
can't be repositioned. Other layers are adjustable, giving users the flexibility to choose from
three positioning options: "Above Labels," "Below Labels," or "Below Roads."

Within each Layer position, the order of layers remains consistent. For instance, the 3D bar
chart layer always appears above the bubble layer due to its higher layer order, regardless of
whether they're placed in "Below Labels" or "Above Labels."

Layer order
The following table outlines the layer order from top to bottom along with their respective
layer position types. Layers marked as "Adjustable" can have their position changed using the
Layer position dropdown, as shown in the previous screenshot. Layers marked as "Fixed" don't
offer this option.
ノ Expand table

Layer Name Layer Position Description


Order type

Category 1 Fixed The Category Labels is fixed as the top-most layer. You can
Labels consider this layer as "fixed" at the highest position.

Selection 2 Fixed The Selection tool layer is fixed as the second-highest layer,
Tools overlaying all other map layers. "Fixed" means it remains in the
second level.

3D Bar chart 3 Adjustable


Layer

Pie chart 4 Adjustable These layers share the same "Layer position" as the bubble
Layer layer, and their relative order within this group remains fixed.
Bubble Layer
Cluster
Bubble Layer
Path Layer

Heat Map 5 Adjustable


Layer

Reference 6 Fixed The Reference Layer is fixed at "Below labels".


Layer

Filled Map 7 Adjustable


Layer

Tile Layer 8 Adjustable

Map Tiles 9 Fixed The Map Tiles layer is fixed as the bottom-most map layer. It's
the base map layer of the Azure Maps visual.

Next steps
Change how your data is displayed on the map:

Add a bubble layer

Add a 3D column layer

Add more context to the map:

Add a reference layer


Add a tile layer

Show real-time traffic


Add a bubble layer
Article • 01/17/2025

The Bubble layer renders location data as scaled circles on the map.

Initially all bubbles have the same fill color. If a field is passed into the Legend bucket of
the Fields pane, the bubbles are colored based on their categorization.

The outline of the bubbles is white be default but can be changed to a new color or by
enabling the high-contrast outline option. The High-contrast outline option
dynamically assigns an outline color that is a high-contrast variant of the fill color. This
helps to ensure the bubbles are clearly visible regardless of the style of the map. The
following are the primary settings in the Format pane that are available in the Bubble
layer section.

ノ Expand table
Setting Description

Size The size of each bubble. This option is hidden when a field is passed into the Size
bucket of the Fields pane. More options appear as outlined in the Bubble size scaling
section further down in this article.

Range Used to define how the bubble layer scales the bubbles.
scaling
• Magnitude: Bubble size scales by magnitude. Negative values are automatically
converted to positive values.
• DataRange: Bubble size scales from min-of-data to max-of-data. There's no
anchoring to zero.
• Automatic: Bubble size scales automatically into one of the two types, as follows:
• Magnitude: Positive or negative only data.
• DataRange: data that contains both positive and negative values.
• (Deprecated): Applies to reports created prior to the range scaling property, to
provide backward-compatibility. It's recommended that you change this to use any
one of the three preceding options.

Shape Transparency. The fill transparency of each bubble.

Color Fill color of each bubble. This option is hidden when a field is passed into the Legend
bucket of the Fields pane and a separate Data colors section appears in the Format
pane.

Border Settings for the border include color, width, transparency and blur.
• Color specifies the color that outlines the bubble. This option is hidden when the
High-contrast outline option is enabled.
• Width specifies the width of the outline in pixels.
• Transparency specifies the transparency of each bubble.
• Blur specifies the amount of blur applied to the outline of the bubble. A value of
one blurs the bubbles such that only the center point has no transparency. A value of
0 apply any blur effect.

Zoom Settings for the zoom property include scale, maximum and minimum.
• Maximum zoom level tiles are available.
• Minimum zoom level tiles are available.

Options Settings for the options property include pitch alignment and layer position.
• Pitch alignment specifies how the bubbles look when the map is pitched.
• layer position specifies the position of the layer relative to other map layers.

Bubble size scaling


If a field is passed into the Size bucket of the Fields pane, the bubbles are scaled
relatively to the measure value of each data point. The Size option in the Bubble layer
section of the Format pane disappears when a field is passed into the Size bucket, as
the bubbles have their radius scaled between a min and max value. The following
options appear in the Bubble layer section of the Format pane when a Size bucket has a
field specified.

ノ Expand table

Setting Description

Min size Minimum bubble size when scaling the data.

Max size Maximum bubble size when scaling the data.

Category labels
When the bubble layer displays on a map, the Category labels settings become active
in the Format visual pane.

The Category labels settings enable you to customize font setting such as font type, size
and color as well as the category labels background color and transparency.

Next steps
Change how your data is displayed on the map:

Add a cluster bubble layer

Add a 3D column layer

Add more context to the map:


Add a reference layer

Add a tile layer

Customize the visual:

Tips and tricks for color formatting in Power BI

Customize visualization titles, backgrounds, and legends

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a cluster bubble layer
Article • 01/17/2025

Cluster bubble layers enable you to use enhanced data aggregation capabilities based
on different zoom levels. Cluster bubble layers are designed to optimize the
visualization and analysis of data by allowing dynamic adjustments to granularity as
users zoom in or out on the map.

Azure Maps Power BI visual offers a range of configuration options to provide flexibility
when customizing the appearance of cluster bubbles. With parameters like cluster
bubble size, color, text size, text color, border color, and border width, you can tailor the
visual representation of clustered data to align with your reporting needs.
ノ Expand table
Setting Description Values

Bubble Size The size of each cluster bubble. Default: 12 px 1-50


px

Cluster Fill color of each cluster bubble.


Color

Text Size The size of the number indicating the quantity of clustered bubbles. 1-60
Default: 18 px. px

Text Color Text color of the number displayed in the cluster bubbles.

Border The color of the bubbles outline.


Color

Border The width of the border in pixels. Default: 2 px 1-20


Width px

Next steps
Change how your data is displayed on the map:

Add a 3D column layer

Add a heat map layer

Add more context to the map:

Add a reference layer

Add a tile layer

Show real-time traffic

Customize the visual:

Tips and tricks for color formatting in Power BI

Customize visualization titles, backgrounds, and legends

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a pie chart layer
Article • 01/17/2025

This article describes how to add a pie chart layer to an Azure Maps Power BI visual.

A pie chart is a visual representation of data in the form of a circular chart or pie where
each slice represents an element of the dataset that is shown as a percentage of the
whole. A list of numerical variables along with categorical (location) variables are
required to represent data in the form of a pie chart.

Prerequisites
Get started with Azure Maps Power BI visual.
Understand Layers in the Azure Maps Power BI visual.

Add the pie chart layer


The pie chart layer is added automatically based on what fields in the Visualizations
pane have values, these fields include location, size and legend.
The following steps walk you through creating a pie chart layer.

1. Select two location sources from the Fields pane, such as city/state, to add to the
Location field.
2. Select a numerical field from your table, such as sales, and add it to the Size field in
the Visualizations pane. This field must contain the numerical values used in the
pie chart.
3. Select a data field from your table that can be used as the category that the
numerical field applies to, such as manufacturer, and add it to the Legend field in
the Visualizations pane. This appears as the slices of the pie, the size of each slice
is a percentage of the whole based on the value in the size field, such as the
number of sales broken out by manufacturer.
4. Next, in the Format tab of the Visualizations pane, switch the Bubbles toggle to
On.

The pie chart layer should now appear. Next you can adjust the Pie chart settings such
as size and transparency.

Pie chart layer settings


Pie Chart layer is an extension of the bubbles layer, so all settings are made in the
Bubbles section. If a field is passed into the Legend bucket of the Fields pane, the pie
charts are populated and colored based on their categorization. The outline of the pie
chart is white by default but can be changed to a new color. The following are the
settings in the Format tab of the Visualizations pane that are available to a Pie Chart
layer.
ノ Expand table

Setting Description

Size The size of each bubble.

Fill transparency Transparency of each pie chart.

Outline color Color that outlines the pie chart.

Outline transparency Transparency of the outline.

Outline width Width of the outline in pixels.

Min zoom Minimum zoom level tiles are available.

Max zoom Maximum zoom level tiles are available.

Layer position Specifies the position of the layer relative to other map layers.

Next steps
Change how your data is displayed on the map:

Add a 3D column layer

Add a heat map layer

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a 3D column layer
Article • 01/17/2025

The 3D column layer is useful for taking data to the next dimension by allowing
visualization of location data as 3D cylinders on the map. Similar to the bubble layer, the
3D column chart can easily visualize two metrics at the same time using color and
relative height. In order for the columns to have height, a measure needs to be added to
the Size bucket of the Fields pane. If a measure isn't provided, columns with no height
show as flat squares or circles depending on the Shape option.

Users can tilt and rotate the map to view your data from different perspectives. The map
can be tilted or pitched using one of the following methods.

Turn on the Navigation controls option in the Map settings of the Format pane to
add a button that tilts the map.
Hold down the right mouse button and drag the mouse up or down.
Using a touch screen, touch the map with two fingers and drag them up or down
together.
With the map focused, hold the Shift key, and press the Up or Down arrow keys.

The map can be rotated using one of the following methods.

Turn on the Navigation controls option in the Map settings of the Format pane to
add a button that rotates the map.
Hold down the right mouse button and drag the mouse left or right.
Using a touch screen, touch the map with two fingers and rotate.
With the map focused, hold the Shift key, and press the Left or Right arrow keys.
The following are all settings in the Format pane that are available in the 3D column
layer section.

ノ Expand table

Setting Description

Column shape The shape of the 3D column.

• Box – columns rendered as rectangular boxes.


• Cylinder – columns rendered as cylinders.

Height The height of each column. If a field is passed into the Size bucket of the
Fields pane, columns are scaled relative to this height value.

Scale height on Specifies if the height of the columns should scale relative to the zoom level.
zoom

Width The width of each column.

Scale width on Specifies if the width of the columns should scale relative to the zoom level.
zoom

Fill color Color of each column. This option is hidden when a field is passed into the
Legend bucket of the Fields pane and a separate Data colors section appears
in the Format pane.

Transparency Transparency of each column.

Min zoom Minimum zoom level tiles are available.

Max zoom Maximum zoom level tiles are available.

Layer position Specifies the position of the layer relative to other map layers.

7 Note

If the columns have a small width value and the Scale width on zoom option is
disabled, they can disappear when zoomed out a lot as their rendered width would
be less than a pixel in size. However, when the Scale width on zoom option is
enabled, more calculations are performed when the zoom level changes which can
affect performance of large data sets.

Next steps
Change how your data is displayed on the map:
Add a bubble layer

Add a heat map layer

Add more context to the map:

Add a reference layer

Add a tile layer

Show real-time traffic

Customize the visual:

Tips and tricks for color formatting in Power BI

Customize visualization titles, backgrounds, and legends

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a heat map layer
Article • 01/17/2025

This article describes how to add a heat map layer to an Azure Maps Power BI visual.

Heat maps, also known as density maps, are a type of overlay on a map used to
represent the density of data using different colors. Heat maps are often used to show
the data "hot spots" on a map. Heat maps are a great way to render datasets with large
number of points. Displaying a large number of data points on a map results in a
degradation in performance and can cover it with overlapping symbols, making it
unusable. Rendering the data as a heat map results not only in better performance, it
helps you make better sense of the data by making it easy to see the relative density of
each data point.

A heat map is useful when users want to visualize vast comparative data:

Comparing customer satisfaction rates or shop performance among


countries/regions.
Measuring the frequency which customers visit shopping malls in different
locations.
Visualizing vast statistical and geographical data sets.

Prerequisites
Get started with Azure Maps Power BI visual.
Understand layers in the Azure Maps Power BI visual.
Add the heat map layer
1. In Power BI Desktop, select the Azure map that you created.
2. In the Format pane, switch the Heat map toggle to On.

Now you can adjust all the Heat map layer settings to suit your report.

Heat map layer settings


The Heat map section of the Format pane provides flexibility to customize and design
the heat map visualizations to meet your specific requirements. The Heat map section
enables you to:

Configure the radius of each data point using either pixels or meters as unit of
measurement.
Customize the opacity and intensity of the heat map layer.
Specify if the value in size field should be used as the weight of each data point.
Pick different colors from color pickers.
Set the minimum and maximum zoom level for heat map layer to be visible.
Decide the heat map layer position among different layers, such as the 3D column
and bubble layer.

The following table shows the primary settings that are available in the Heat map
section of the Format pane:

ノ Expand table

Setting Description

Size The radius of each data point in the heat map.

Valid values when Unit = ‘pixels’: 1 - 200. Default: 20


Valid values when Unit = ‘meters’: 1 - 4,000,000

ノ Expand table

Setting Description

Radius The radius of each data point in the heat map.

Valid values when Unit = ‘pixels’: 1 - 200. Default: 20


Valid values when Unit = ‘meters’: 1 - 4,000,000
Setting Description

Units The distance units of the radius. Possible values are:

pixels. When set to pixels the size of each data point is the same, regardless of
zoom level.
meters. When set to meters, the size of the data points scale based on zoom
level based on the equivalent pixel distance at the equator, providing better
relativity between neighboring points. However, due to the Mercator projection,
the actual radius of coverage in meters at a given latitude are smaller than this
specified radius.

Default: pixels

Transparency Sets the Transparency of the heat map layer. Default: 1


Value should be from 0% to 100%.

Intensity The intensity of each heat point. Intensity is a decimal value between 0 and 1,
used to specify how "hot" a single data point should be. Default: 0.5

Use size as A boolean value that determines if the size field value should be used as the
weight weight of each data point. When On , the layer renders as a weighted heat map.
Default: Off

Gradient A color picker for users to pick three colors for low (0%), center (50%) and high
(100%) gradient colors.

Min zoom Minimum zoom level the layer is visible at. Valid values are 1 to 22. Default: 0

Max zoom Maximum zoom level the layer is visible at. Valid values are 1 to 22. Default: 22

Layer position Specify the position of the layer relative to other map layers. Valid values include
Above labels, Below labels and Below roads

Next steps
Change how your data is displayed on the map:

Add a 3D column layer

Add more context to the map:

Add a reference layer

Add a tile layer

Show real-time traffic


Customize the visual:

Tips and tricks for color formatting in Power BI

Customize visualization titles, backgrounds, and legends

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a reference layer
Article • 01/17/2025

Reference layers enable the enhancement of spatial visualizations by overlaying a


secondary spatial dataset on the map to provide more context. Power BI hosts this
dataset in various formats, including:

GeoJSON files with a .json or .geojson extension


WKT (Well-Known Text) files with a .wkt extension
KML (Keyhole Markup Language) files with a .kml extension
SHP (Shapefile) files with a .shp extension
CSV (Comma-separated values) files with a .csv extension. The Azure Maps
Power BI visual parses the column containing WKT (Well-Known Text) strings from
the sheet.

Add a spatial dataset as a reference layer


You have two options to add a spatial dataset as a reference layer. You can either
reference a hosted file by providing the URL, or select a file to upload.

Upload file

To upload a spatial dataset as a reference layer:

1. Navigate to the Format pane.

2. Expand the Reference Layer section.

3. Select File Upload from the Type drop-down list.

4. Select Browse. The file selection dialog opens, allowing you to choose a file
with a .json , .geojson , .wkt , .kml , .shp , or .csv extension.
Once the file is added to the reference layer, the file name appears in the Browse
field. An 'X' button is added that removes the data from the visual and deletes the
associated file from Power BI when selected.

The following map displays 2016 census tracts for Colorado . The areas are colored,
based on population, using the reference layer.

The following are all settings in the Format pane that are available in the Reference
layer section.

ノ Expand table

Setting Description

Reference The data file to upload to the visual as another layer within the map. Selecting
layer data Browse shows a list of files with a .json , .geojson , .wkt , .kml , .shp , or .csv file
extension that can be opened.

Styling data in a reference layer


Properties can be added to each feature within the GeoJSON file to customize styling.
This feature uses the simple data layer feature in the Azure Maps Web SDK. For more
information, see this document on supported style properties. Custom icon images
aren't supported within the Azure Maps Power BI visual as a security precaution.

The following are examples showing how to set a point features color property to red .

GeoJSON
JSON

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.13284, 47.63699]
},
"properties": {
"color": "red"
}
}

WKT

wkt

POINT(-122.13284 47.63699)

KML

XML

<?xml version="1.0" encoding="UTF-8"?>


<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
<Point>
<coordinates>-122.13284,47.63699</coordinates>
</Point>
<Style>
<IconStyle>
<color>ff0000ff</color> <!-- Red color in KML format (Alpha, Blue,
Green, Red) -->
</IconStyle>
</Style>
</Placemark>
</kml>

Custom style for reference layer via format


pane
The Custom style for reference layer via format pane feature in Azure Maps enables you
to personalize the appearance of reference layers. You can define the color, border
width, and transparency of points, lines, and polygons directly in the Azure Maps Power
BI visual interface, to enhance the visual clarity and impact of your geospatial data.

Enabling custom styles


To use the custom styling options for reference layers, follow these steps:

1. Upload Geospatial Files: Start by uploading your supported geospatial files


(GeoJSON, KML, WKT, CSV, or Shapefile) to Azure Maps as a reference layer.
2. Access Format Settings: Navigate to the Reference Layer blade within the Azure
Maps Power BI visual settings.
3. Customize Styles: Use to adjust the appearance of your reference layer by setting
the fill color, border color, border width, and transparency for points, lines, and
polygons.

7 Note

If your geospatial files (GeoJSON, KML) include predefined style properties, Power
BI utilizes those styles rather than the settings configured in the format pane. Make
sure your files are styled according to your requirements before uploading if you
intend to use custom properties defined within them.

Style configuration

ノ Expand table
Setting name Description Setting values

Fill color Fill color of points and polygons. Set colors for different data category or
gradient for numeric data.

Border color The color of the points, lines, and Color picker
polygons outline.

Border width The width of the border in Width 1-20 pixels


pixels. Default: 3 px

Border The transparency of the borders. Transparency 0-100%


transparency Default: 0%

The Points section of the format visual pane:

The Lines section of the format visual pane:


The Polygons section of the format visual pane:
Data-bound reference layer
The data-bound reference layer enables the association of data with specific shapes in
the reference layer based on common attributes.

To use the data-bound reference layer, drag the column containing unique identifiers
(can be location data or not) to the Location field of the Azure Maps visual.
Azure Maps matches these identifiers with the corresponding properties in the
uploaded spatial file, automatically linking your data to the shapes on the map.

In scenarios with multiple properties, Azure Maps identifies a common property in each
shape and compares its value with the selected data column in the Location field. It then
uses the property that has the highest number of matches with the selected data
column.

If one or more shapes in the reference layer can't be automatically mapped to any data
point, you can manage these unmapped objects by following these steps:

1. Select the Format visual tab in the Visualizations pane.


2. Select Reference layer.
3. Select Unmapped Objects.
4. Select the Show toggle switch to toggle On/Off. This highlights shapes that aren't
mapped to any data points.

Optionally, select the Use custom colors toggle switch to toggle On/Off custom fill and
border colors for unmapped objects to make them visually distinct on the map.

Conditional formatting
Conditional formatting can be applied to data to dynamically change the appearance of
shapes on a map based on the provided data. For instance, gradient colors can visualize
various data values such as population density, sales performance, or other metrics. This
is a powerful tool for combining spatial and business data to create interactive and
visually compelling reports.

There are several ways to set colors to the shapes. The following table shows the
priorities used:

ノ Expand table

Priority Source Description

1 Preset style in spatial Color and style as defined in the spatial file
Priority Source Description

files

2 Unmapped object Custom colors used when the geometry isn’t data-bound
colors

3 Legend colors Colors provided by Legend/Series

4 Conditional formatting Colors provided by conditional formatting


colors

5 Custom formatting User defined custom styles in the Reference Layer options in
colors the formatting pane

6 Default colors Default colors defined in the Azure Maps visual

 Tip

The Azure Maps Power BI Visual can only perform geocoding on valid location data
such as geographical coordinates, addresses, or place names. If no valid location
data is uploaded, data layers that depend on geocoded locations, such as heat
maps or bubble layers, don’t display on the map.

The data-bound reference layer appears on the map as long as the data column
contains unique identifiers that match properties in the spatial file, but to ensure
correct results, your data column must include valid geographic information.

Next steps
Add more context to the map:

Add a tile layer

Show real-time traffic

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Add a tile layer
Article • 01/17/2025

The tile layer feature, like the reference layer feature, allows other data to be overlaid on
the map to provide more context. Tile layers allow you to superimpose images on top of
the Azure Maps base map tiles. Superimposing images is a great way to overlay large or
complex datasets such as imagery from drones, or millions of rows of data.

A tile layer loads in tiles from a server. These images can either be prerendered or
dynamically rendered. Prerendered images are stored like any other image on a server
using a naming convention that the tile layer understands. Dynamically rendered images
use a service to load the images close to real time. Tile layers are a great way to visualize
large datasets on the map. Not only can a tile layer be generated from an image, vector
data can also be rendered as a tile layer too.

The bounding box and zoom range of where a tile service is available can be passed as
settings to limit where tiles are requested, a performance enhancement for both the
visual and the tile service. The following table gives an overview of all settings available
in the Format pane available in the Tile layer section.

ノ Expand table

Setting Description

Url A formatted URL pointing to a tile service.

Tile size An integer value that specifies both the width and height dimensions of the tiles.

North bound Northern latitude of the bounding box where tiles are available.
Setting Description

South bound Southern latitude of the bounding box where tiles are available.

East bound Eastern longitude of the bounding box where tiles are available.

West bound Western longitude of the bounding box where tiles are available.

Transparency Transparency of the tile layer.

Is TMS Tile Map Services, a specification that reverses the Y coordinate axis of the tile
layer.

Min zoom Minimum zoom level tiles are available.

Max zoom Maximum zoom level tiles are available.

Layer Specifies the position of the layer relative to other map layers.
position

Tile URL formatting


There are three different tile service naming conventions supported by the Azure Maps
Power BI visual:

X, Y, Zoom notation - X is the column, Y is the row position of the tile in the tile
grid, and the Zoom notation a value based on the zoom level.
Quadkey notation - Combines x, y, and zoom information into a single string
value. This string value becomes a unique identifier for a single tile.
Bounding Box - Specify an image in the Bounding box coordinates format:
{west},{south},{east},{north} .

The tile URL an https URL to a tile URL template that uses the following parameters:

{x} - X position of the tile. Also needs {y} and {z} .


{y} - Y position of the tile. Also needs {x} and {z} .

{z} - Zoom level of the tile. Also needs {x} and {y} .
{quadkey} - Tile quadkey identifier based on the Bing Maps tile system naming

convention.
{bbox-epsg-3857} - A bounding box string with the format {west},{south},{east},

{north} in the EPSG 3857 spatial reference system.

As an example, here's a formatted tile URL for the weather radar tile service in Azure
Maps.
HTML

https://atlas.microsoft.com/map/tile?zoom={z}&x={x}&y=
{y}&tilesetId=microsoft.weather.radar.main&api-version=2.0&subscription-key=
{Your-Azure-Maps-Subscription-key}

For more information on Azure Maps tiling system, see Zoom levels and tile grid.

Next steps
Add more context to the map:

Show real-time traffic

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


The path layer in Azure Maps Power BI
visual
Article • 11/27/2024

The path layer feature in the Azure Maps Power BI Visual enables the visualization of
connections between multiple geographic points.

The path layer feature can be used in multiple scenarios, such as:

Route Visualization: Showing vehicle, ship, or flight paths between locations.


Network Analysis: Examines connections between nodes in a network, like supply
chain routes or communication networks.
Movement Tracking: Monitoring assets or individuals over time and space.

This guide explains how to use this feature effectively.

Add a path layer


This section describes how to add data and configure the path layer. Before starting, you
need to open your Azure Maps Visual in Power BI. For more information on adding an
Azure Maps Visual to your Power BI report, see Use the Azure Maps Power BI visual.

ノ Expand table

Setting Description

Apply Settings to Path you want the settings to apply to

Color The color of the line

Transparency The transparency of the line

Width The width of the line

Maximum Zoom Maximum zoom level the layer is visible at

Minimum Zoom Minimum zoom level the layer is visible at

Add data to the path layer


To draw paths, provide data for "Path ID" and "Point Order":
1. Add the column that best identifies each path to the Path ID field. The Path ID is
used to identify which line each geospatial data point belongs to. If there are
multiple paths, each path requires a unique Path ID.

2. Add the column that specifies the order of points along the path to the Point
Order field. The Point Order dictates the sequence of points to form a path.

Configure a path layer


After adding your data, you can adjust the path layer's color, line width, and opacity.
Apply settings by legend or path ID, coloring paths, and locations with the same legend
identically.

After adding your data, you can configure the path layer according to your
requirements. The style of the paths can be customized by adjusting the line color,
width, and opacity. These settings can be applied based on legend or path ID. If a
legend is provided, paths and locations associated with the same legend share the same
color.

Interact with a path layer


The path layer feature offers several interactive options:

Hover and Select: Hover over a path to select points; clicking on a path selects the
nearest point. The selected point also selects other reports by legend, path ID,
location, and point order.
Tooltips: Tooltips show information for the nearest point when hovering over a
line.

Explore and customize a path layer


Examine the connections and insights revealed by the path layer visualization. Further
customize the settings to suit your specific requirements and derive more profound
insights from your geospatial data.

Legends in a path layer

Adding a field to the legend field well creates a higher level of grouping. So, paths and
locations associated with the same legend are colored identically. Here's the process:

Grouping by Legend: When a legend is provided, the paths and locations are
grouped based on the legend. For instance, if visualizing flight paths with the
airline as the legend, all paths and locations associated with the same airline share
the same color. Moreover, if there are two rows, one with legend "Contoso" and
path ID "A123" and another with legend "MSAirline" and path ID "A123" the path
layer interprets these as two distinct paths: "Contoso-A123" and "MSAirline-A123".
Styling by Legend: Configure the style (color, line width, opacity) using the legend
to visually differentiate path groups.
Interaction by Legend: When interacting with the path layer, selecting a path or
point also selects other reports based on legend, path ID, location, and point
order. This ensures all related data points are highlighted together.

Handle origin-destination data


To use origin-destination data in the path layer, you must first transform it, as Azure
Maps Visual doesn't directly support such data. Use the Unpivot function in Power
Query to do this. Here’s how:

1. Import Data: Import your origin-destination data into Power BI.

2. Apply Unpivot Function: Use the following Power Query to transform the data:

C#

let
// Importing the source.
Source = …
// Create "path_id" to set in the "Path ID" field well later in the
visual.
// Since each row represents a line here, we can simply use the row
index as path ID
#"Added Index" = Table.AddIndexColumn(Source, "path_id", 0, 1,
Int64.Type),
// This is the key point of the transformation.
// We transform the original rows into two: one for the origin and
one for the destination.
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added
Index", {"path_id"}, "point_order", "city"),
// We only support timestamp and number for the point order. So,
convert the "origin" as 0 and "destination" as 1
#"Replaced Values" =
Table.ReplaceValue(Table.ReplaceValue(#"Unpivoted Other Columns",
"origin", "0", Replacer.ReplaceText, {"point_order"}), "destination",
"1", Replacer.ReplaceText, {"point_order"})
in
#"Replaced Values"

Before transformation

ノ Expand table

origin destination

New York Los Angeles

Chicago Houston

Miami Atlanta

Seattle Denver

Boston San Francisco

After transformation
ノ Expand table

path_id point_order city

0 0 New York

0 1 Los Angeles

1 0 Chicago

1 1 Houston

2 0 Miami

2 1 Atlanta

3 0 Seattle

3 1 Denver

4 0 Boston

4 1 San Francisco

Current limitations
The path layer is only compatible with specific map data layers, including the
Bubble, Reference, Traffic, and Tile layers.
The data-bound reference layer isn't available when the path layer is enabled.
Location hierarchy (drill down) is disabled when a Path ID is provided.

Conclusion
The path layer feature in Azure Maps Visual is a tool for visualizing and analyzing spatial
connections. This new capability can be utilized to enhance reports.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Filled map in Azure Maps Power BI
visual
Article • 01/17/2025

Filled maps use varying degrees of shading, tinting, or different patterns to provide a
visual display that quickly shows differences in values across a geography or region.
Showing these relative differences with shading that ranges from light (less-
frequent/lower) to dark (more-frequent/more) is a useful way to quickly convey
pertinent information to viewers.

This image shows an example of a filled map. The map of America shows each state with
a different shade that represents the sales by state. A viewer can immediately see that
California has the most sales followed by Texas, then Florida.

When to use a filled map


Filled maps can be a great choice:

To display quantitative information on a map.


To show spatial patterns and relationships.
When your data is standardized.
When working with socioeconomic data.
When defined regions are important.
To get an overview of the distribution across geographic locations.

Some common uses for filled maps include:

Visualize sales or revenue results by country/region or state.


Visualize election results where the color represents the party that won and the
shading represent the margin of victory.
Visualize unemployment rates by region, state, or county.

Prerequisites
This article uses Sales and Marketing Sample PBIX as the data source for
demonstration purposes. You can create a new report using this data before continuing
if you wish to follow along.

7 Note

To ensure the highest level of accuracy in geocoding results within Filled Map, it's
crucial to correctly set the data category. See Categorize geographic fields in
Power BI.

Filled map settings


There are two places where you can adjust filled maps settings: Build and format visuals.
Both are located in the Visualizations pane.

Build visuals

ノ Expand table

Setting Description Setting values


Name

Shape Configure fill transparency in a 0-100%


geometry on the map

Colors Use meters or pixels as unit to visualize Set colors for different data category or
the data. Default: Pixels gradient for numeric data.

Border Sets the border color, width, and Color picker


transparency Width 1-10 pixels
Transparency 0-100%
Setting Description Setting values
Name

Min zoom Minimum zoom level the layer is visible Integer (0 - 22)
at. Default: 0

Max zoom Maximum zoom level the layer is visible Integer (0 - 22)
at. Default: 22

Options Specify the position of the layer relative Drop down menu:
to other map layers Above labels
Below labels
Below roads

 Tip

You can use Conditional formatting in the Colors setting to set the field that your
map is based on, as demonstrated in the Create a filled map section.

Format visuals

ノ Expand table

Bucket Description

Location Geospatial area with a boundary, such as country/region, state, city, county, or
postal code. Street and address aren't supported in filled map.

Legend Categorical data that is used to shade the map.

Tool Tips Determined the data/columns that would be shown in tool tips.
(optional)

Create a filled map


1. From the Fields pane, select the Geo > State field. Notice that it populates the
Location field in the Visualizations pane.
2. Select Sales $ from the SalesFact table and drag it to the Tooltips field in the
Visualizations pane.

3. In the Visualizations pane, select Format your visual

4. Set Filled map to On


5. Select Filled maps to expand that section then select Colors.

6. Select Conditional formatting.


7. The Default color - Filled map dialog should appear, select the What field should
we base this on? Drop down, then select Sales $ from the SalesFact table.

8. Set the Minimum color to white then select the OK button.

The map should appear with varying degrees of shading depicting the relative
sales. Since this data only includes numbers for the continental United States,
you can filter out Alaska if you wish.

9. Filter the map to display only the continental United States.


a. To the left of the "Visualizations" pane, look for the "Filters" pane. Expand it if it's
minimized.

b. Hover over State and select the expand chevron.

c. Place a check mark next to Select all and remove the check mark next to AK.

Next steps
Change how your data is displayed on the map:

Add a 3D column layer

Add a heat map layer

Add more context to the map:

Add a reference layer

Add a tile layer

Show real-time traffic

Customize the visual:

Tips and tricks for color formatting in Power BI

Customize visualization titles, backgrounds, and legends


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Contextual on-object interaction with
Azure Maps Power BI visual (preview)
Article • 01/27/2025

The Azure Maps Power BI Visual now features on-object interaction, an intuitive and
efficient way to update the formatting of any element on the map. With on-object
interaction, you can interact with the Azure Maps Power BI Visual like you interact with
other Microsoft products or web applications.

Use on-object interaction in your Power BI


Visual
On-object interaction can be used to edit chart titles, legends, bubble layers, Map style,
and Map controls.

) Important

Since the on-object feature is in preview, you need to turn it on. For more
information, see Turn on preview features in the Power BI documentation.

Formatting objects on the map


A context sensitive menu appears when you right-click an object in the map, with
formatting options for that object, which eliminates the need to search for the correct
setting in the Format pane.

To exit edit mode, select the Esc key or select anywhere on the canvas outside of the
Azure Maps Visual.

Edit a chart tile or legend


To edit chart tile or legend, you can right-click on the text to edit title or font style/size.

The format pane


While you're using on-object interaction, the format pane is expanded, and the
corresponding card appears to enable a review of the completed settings.

On-object interaction is also available on the bubble layer. By selecting bubbles, you can
set bubble layer's position or its formatting such as size or color.

Select Map styles


You can also select the map background to bring up a context menu showing all
available map styles such as road, satellite, hybrid, etc.
On-object interaction applies to the Map control as well.

The on-object interaction feature available in Azure Maps Visual is a user-friendly and
innovative method for adjusting map settings. Additionally, other Power BI Visuals also
offer on-object interaction capabilities, providing users with efficient tools to personalize
their Power BI reports.

Next steps
Change how your data is displayed on the map:

Add a bubble layer


Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Show real-time traffic
Article • 01/17/2025

The traffic layer feature overlays real-time traffic data on top of the map. To enable this
feature, move the Traffic layer slider in the Format pane to the On position. This
overlays traffic flow data as color coded roads.

The following settings are available in the Traffic layer section.

ノ Expand table

Setting Description

Show Specifies if traffic incidents, such as road closures and construction, should be
incidents displayed on the map.

Traffic control Adds a button to the map that allows report readers to turn the traffic layer on or
off.

Next steps
Learn more about the Azure Maps Power BI visual:

Understanding layers in the Azure Maps Power BI visual

Manage the Azure Maps Power BI visual within your organization

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Azure Maps Power BI visual Data
Residency
Article • 03/21/2024

The Azure Maps Power BI visual can get a users' tenant location and use it to call the
correct Azure Maps geographic endpoints. For instance, if a user's tenant is located in
Europe, Power BI calls the Azure Maps' eu endpoint eu.atlas.microsoft.com , ensuring
that their data doesn't leave the Europe region. Similarly if users' tenant is in the US,
us.atlas.microsoft.com is called and users' data doesn't leave the US region.

Tenent location
To discover your tenant's location in Power BI:

1. Open the Help menu drop-down list by selecting the ?

2. Select About Power BI

3. Once the About Power BI dialog box opens, notice the your data is stored in
followed by the tenent location, which is, in this example, Ireland.
The previous example would use the eu.atlas.microsoft.com endpoint.

7 Note

The region used for Power BI premium capacity is currently not taken into
consideration when determining which Azure Maps geographic endpoints are
called.

Next steps
Learn more about specifying a geographic scope and why it matters.

Azure Maps service geographic scope


Manage Azure Maps Power BI visual within
your organization
06/13/2025

Power BI provides the ability for designers and tenant administrators to manage the use of the
Azure Maps visual.

Tenant admin options


Tenant administrators can manage Azure Maps visuals via Settings > Admin Portal > Tenant
settings. These settings control access and data processing for the entire organization.

Enable the Azure Maps visual


When enabled, users in the organization can create and view reports that use the Azure Maps
visual.

Microsoft temporarily stores and processes your data for essential services like translating
locations into latitudes and longitudes.
If Azure Maps services are unavailable in your region, your data can be processed outside
your tenant's geographic region, compliance boundary, or national cloud instance.
Process data outside your region or boundary
When enabled, data sent to Azure Maps can be processed outside your tenant’s geographic
region, compliance boundary, or national cloud instance. This is required because Azure Maps
services aren't available in all geographic regions or national clouds.

Enable this setting to access more capabilities provided by Microsoft Online Services
subprocessors.
Disabling this setting can limit Azure Maps features if services are unavailable in your
compliance region.
Allow Microsoft subprocessors to process data
Some Azure Maps features, like the selection tool, can utilize third-party mapping capabilities
provided by Microsoft Online Services subprocessors.

Only essential data is shared with these subprocessors, and is used solely to support
Azure Maps services.
Data can be stored and processed in the United States or other countries where Microsoft
or its subprocessors operate.
To enable this setting, "Data sent to Azure Maps can be processed outside your tenant’s
geographic region, compliance boundary, or national cloud instance" must also be
enabled.
7 Note

Azure Maps and subprocessors don't handle personally identifiable information (PII). The
data sent to Azure Maps only includes location-related information, such as coordinates
or place names, and doesn't include user identities or report consumer information.

Next steps
Learn more about Azure Maps Power BI visual:

Understanding layers in Azure Maps Power BI visual


Interactive map control
Article • 03/15/2023

Easily add an interactive map to your canvas apps. Plot markers from a data source containing
addresses or latitude and longitude pairs. As you zoom out, the markers will optionally cluster
to condense groups of data. On mobile devices and web experiences, a map can show the
user's current position and calculate a route to the user's destination. Maps can be switched
between road and satellite views.

Interactive map features


Use a data source to insert pins
Display information about map pins
Show routes between waypoints
Draw and insert shapes

Prerequisites
You'll need to satisfy a few prerequisites before you can use maps in your canvas apps. Refer to
the privacy and security table for more details on how different map features use data.

Add a map to an app screen


With your app open for editing in Power Apps Studio :

1. Select the Insert tab and expand Media.


2. Select Map to place a map in the app screen, or drag the control to the screen to position
it more precisely.
Adding pins, routes, and shapes
Pins, routes, and shapes are data set properties that need to both identify a data source, which
is a table from a collection or connector, and the relevant columns. The data source is set in the
Items property (Items for pins, RouteWaypoints_Items for routes, Shape_Items for shapes) and
the relevant columns are set in the related properties (e.g. ItemLatitudes, ItemLongitudes, etc
for pins). The Properties section contains additional information about these data sets and their
related properties.

For example, if you had a table collection named Locations with Name, Longitude, and
Latitude columns:

ノ Expand table

Name Longitude Latitude

Fourth Coffee (sample) -98.29277 26.2774

Litware, Inc. (sample) -96.85572 32.55253

Adventure Works (sample) -96.99952 32.72058

To display these as labeled pins on the map:

1. Set the Items property to Locations

2. Set the ItemLabels property to "Name"

3. Set the ItemLongitude property to "Longitude"

4. Set the ItemLatitude property to "Latitude"

) Important

The relevant column names need to be in quotation marks in the related properties.
The data source should not have quotation marks.

You can see how to do display pins from an Excel sheet or build an app that uses the address
input control to populate pins on the map control as additional examples.

7 Note

Each map control can display up to 5000 pins from latitude or longitude and 50 pins
from addresses. The pin limit is lower for addresses as the map needs to geocode
these addresses into latitude or longitude to display them. We recommend not using
addresses where possible. You can save geocoded addresses back to your data
source.
When both latitude or longitude and an address is given for a single pin, the map
control will prioritize using the latitude or longitude to avoid geocoding the address.
The maximum number of shapes that can be drawn in a map control is limited to
500.

Properties
Change a map's behavior and appearance using properties. Some properties are only available
on the Advanced tab.
The map control has six different types of properties:

1. Styling properties
2. Behavioral properties
3. Pin properties
4. Route properties
5. Shape properties
6. Output properties

Styling properties

ノ Expand table
Property Description Type Tab

Satellite view Displays the map in satellite view. Leave this Boolean Properties; Advanced:
property off to display the map in road view. SatelliteView

Map style Sets the map style. Options: Road, Night, Enum Properties
Road shaded relief, Satellite, Satellite road
labels, High contrast light, High contrast
dark, Grayscale light, Grayscale dark.

Transparency Determines the map's transparency, from 0 Integer Properties; Advanced:


(opaque) to 100 (transparent). Transparency

Visible Shows or hides the map. Boolean Properties; Advanced:


Visible

Position Places the upper-left corner of the map at Floating Properties; Advanced: X, Y
the screen coordinates specified in x and y. point
number

Size Determines the size of the map using the Integer Properties; Advanced:
pixel values provided in Width and Height. Width, Height

Border Determines the corner radius of the map Floating Properties; Advanced:
radius border. point BorderRadius
number

Border Determines the style, width, and color of the Not Properties; Advanced:
map border. applicable BorderStyle,
BorderThickness,
BorderColor

DisplayMode Determines whether the control allows user Enum Advanced


input (Edit), only displays data (View), or is
disabled (Disabled).

Behavioral properties

ノ Expand table

Property Description Type Tab

Show info cards Shows information about a mapped Enum Properties; Advanced:
location when the user selects it (On InfoCards
click) or points to it (On hover). If None,
no information is shown.

Use default Initializes the map at a default location. Boolean Properties; Advanced:
location DefaultLocation
Property Description Type Tab

Default latitude Sets the latitude coordinate the map Floating Properties; Advanced:
shows if Use default location is point DefaultLatitude
enabled. number

Default longitude Sets the longitude coordinate the map Floating Properties; Advanced:
shows if Use default location is point DefaultLongitude
enabled. number

Default zoom level Sets the zoom level if Use default Integer Properties; Advanced:
location is enabled, from 0 to 22. DefaultZoomLevel

Show current Displays the user's current location. Boolean Properties; Advanced:
location CurrentLocation

Current location Sets the latitude coordinate of the Floating Properties; Advanced:
latitude current location pin that the map shows point CurrentLocationLatitude
if Show current location is enabled. To number
place the pin at the user's current
location, set this property to
Location.Latitude.

Current location Sets the longitude coordinate of the Floating Properties; Advanced:
longitude current location pin that the map shows point CurrentLocationLongitude
if Show current location is enabled. To number
place the pin at the user's current
location, set this property to
Location.Longitude.

Zoom control Shows the zoom control. Boolean Properties; Advanced: Zoom

Compass control Shows the compass control. Boolean Properties; Advanced:


Compass

Pitch control Shows the pitch (tilt) control. Boolean Properties; Advanced: Pitch

TabIndex Specifies the order the map is selected Integer Properties; Advanced: Tab
if the user navigates the app using the index
Tab key.

Tooltip Determines the text to display when the String Advanced


user hovers over a visual.

ContentLanguage Determines the display language of the String Advanced


map, if it's different from the language
used in the app.

OnLoad Contains code that runs when the map Event Advanced
is loaded.
Property Description Type Tab

OnMapClick Contains code that runs when the user Event Advanced
selects the map. The latitude and
longitude of the clicked point is in the
ClickedLocation output property.

OnChange Contains code that runs when any Event Advanced


aspect of the map is changed.

OnSelect Contains code that runs when the user Event Advanced
selects something on the map.

Pin properties

ノ Expand table

Property Description Type Tab

Locations(Items) Identifies a data source (Items) in the form of a table Not Properties;
from which to get locations to show on the map. The applicable Advanced:
table lists sets of longitudes and latitudes, or physical Items
addresses, to display as pins. Using latitude or
longitude is recommended as addresses need to be
geocoded and so have a more restrictive pin limit. The
table can be a collection or from a data source like
Excel Online. Each row must have an entry for label,
longitude, and latitude, or a physical address, and
optionally the pin color and icon.

ItemsLabels Identifies the column in Items that contains the labels ColumnName Advanced
for the pins.

ItemsLatitudes Identifies the column in Items that contains the ColumnName Advanced
latitude position of the pins.

ItemsLongitudes Identifies the column in Items that contains the ColumnName Advanced
longitude position of the pins.

ItemsAddresses Identifies the column in Items that contains addresses ColumnName Advanced
that represent the location of the pins. There is a limit
to how many pins can be displayed from addresses.
We recommend geocoding your addresses to latitude,
longitude pairs and using those to display pins when
possible.

ItemsColors Identifies the column in Items that contains the colors ColumnName Advanced
of the pins.
Property Description Type Tab

ItemsIcons Identifies the column in Items that contains the icons ColumnName Advanced
of the pins.

Cluster pins Groups nearby map pins instead of displaying them Boolean Properties;
individually. Advanced:
Clustering

Pin color Determines the default color of pins shown on the Color picker Properties;
map. This color is overridden by the ItemsColors Advanced:
property if set PinColor

OnItemsChange Contains code that runs when pins on the map are Event Advanced
changed.

Route properties

ノ Expand table

Property Description Type Tab

Enable routing Determines whether the user Boolean Properties; Advanced:


can request directions to a UseRouting
specified location.

Route waypoints(Items) Shows route waypoints, as Enum Properties; Advanced:


provided in a data source RouteWaypoints_Items
(RouteWaypoints_Items) in the
form of a table. The table can
be a collection or from a data
source like Excel Online. If None,
no waypoints are shown.

RouteWaypointsLabels Identifies the column in ColumnName Advanced


RouteWaypoints_Items that
contains the labels for the
waypoints.

RouteWaypointsLatitudes Identifies the column in ColumnName Advanced


RouteWaypoints_Items that
contains the latitude position of
the waypoints.

RouteWaypointsLongitudes Identifies the column in ColumnName Advanced


RouteWaypoints_Items that
contains the longitude position
of the waypoints.
Property Description Type Tab

RouteWaypointsAddresses Identifies the column in ColumnName Advanced


RouteWaypoints_Items that
contains addresses that
represent the location of
waypoints.

Maintain waypoint order Determines whether a Boolean Properties; Advanced:


calculated route maintains RouteMaintainOrder
waypoints in the order
provided.

Optimize route Determines whether a Enum Properties; Advanced:


calculated route is optimized for RouteOptimization
distance, time, or isn't
optimized.

Route travel mode Determines whether a route is Enum Properties; Advanced:


calculated for a car or a truck, RouteTravelMode
which may require avoiding
bridges with certain height or
weight restrictions.

OnRouteDirectionChange Contains code that runs when Event Advanced


the app detects the user has
changed direction while on a
computed route.

Shape properties

ノ Expand table

Property Description Type Tab

Show shapes Shows the shapes in Shapes_Items. Boolean Properties; Advanced:


ShowShapes

Shapes_Items Identifies a data source TableName Advanced


(Shapes_Items) in the form of a
table from which to get shapes to
show on the map. The table can be
a collection or from a data source
like Excel Online. Each row must
have an entry for the shape
(GeoJSON object) and (optionally) a
label and color.
Property Description Type Tab

ShapeGeoJSONObjects Identifies the column in ColumnName Advanced


Shapes_Items with strings that
represent the GeoJSON objects of
the shapes, in shape collection or
single shape GeoJSON format.

ShapeLabels Identifies the column in ColumnName Advanced


Shapes_Items that contains the
labels for the shapes.

ShapeColors Identifies the column in ColumnName Advanced


Shapes_Items that contains the
colors of the shapes.

Show shape labels Shows the shape labels, if provided. Boolean Properties; Advanced:
ShowShapeLabels

Enable shape drawing Shows drawing tools on the map. Boolean Properties; Advanced:
ShapeDrawing

Enable shape deleting Determines whether the user can Boolean Properties; Advanced:
and label editing delete shapes and edit their labels. ShapeEditingDeleting

OnShapeCreated Contains code that runs when the Event Advanced


user adds a shape to the map.

OnShapeSelected Contains code that runs when the Event Advanced


user selects a shape on the map.

OnShapeEdited Contains code that runs when the Event Advanced


user modifies a shape on the map.

OnShapeDeleted Contains code that runs when the Event Advanced


user deletes a shape on the map.

Output properties
Other properties become available when a user interacts with a map. You can use these output
properties in other controls or to customize the app experience.

ノ Expand table

Property Description Type

CenterLocation Captures the map's center point. Not


Applicable
Property Description Type

ClickedLocation Captures the last location the user selected, either Record
.Latitude or .Longitude.

Selected Captures the selected pin. Record

SelectedItems Captures the selected pin or pins in the selected cluster. Table

GeocodedItems Captures the geocoded locations of the pins. Table

RouteWaypoints_Selected Corresponds to the record of the selected shape in Record


RouteWaypoints_Items.

RouteWaypoints_SelectedItems Corresponds to the records of the selected overlapping Table


shapes in RouteWaypoints_Items.

Shapes_Selected Corresponds to the record of the selected shape in Record


Shapes_Items.

Shapes_SelectedItems Corresponds to the records of the selected overlapping Table


shapes in Shapes_Items.

SelectedShape Captures the .Perimeter and .Area of the selected shape. Record

DeletedShape Captures the .Perimeter and .Area of the last deleted Record
shape.

GeoJSON Captures the list of shapes in Feature Collection String


GeoJSON format.

Other geospatial controls


To see dynamic address suggestions as you type, use the Address input control.

Known limitations
Requires internet connection

See also
Create an app with address input and map controls
How to create data registry
Article • 09/16/2024

7 Note

Azure Maps Data registry service retirement

The Azure Maps Data registry service is now deprecated and will be retired on
9/30/25. For more information, see End of Life Announcement of Azure Maps
Data Registry .

The data registry service enables you to register data content in an Azure Storage
Account with your Azure Maps account. An example of data might include a collection
of Geofences used in the Azure Maps Geofencing service. Another example is ZIP files
containing drawing packages (DWG) or GeoJSON files that Azure Maps Creator uses to
create or update indoor maps.

Prerequisites
An Azure Maps account
A Subscription key
An Azure storage account

) Important

This article uses the us.atlas.microsoft.com geographical URL. If your


account wasn't created in the United States, you must use a different
geographical URL. For more information, see Access to Creator services.
In the URL examples in this article you will need to replace:
{Azure-Maps-Subscription-key} with your Azure Maps subscription key.

{udid} with the user data ID of your data registry. For more information,

see The user data ID.

Prepare to register data in Azure Maps


Before you can register data in Azure Maps, you need to create an environment
containing all required components. You need a storage account with one or more
containers that hold the files you wish to register and managed identities for
authentication. This section explains how to prepare your Azure environment to register
data in Azure Maps.

Create managed identities


There are two types of managed identities: system-assigned and user-assigned.
System-assigned managed identities have their lifecycle tied to the resource that
created them. User-assigned managed identities can be used on multiple resources. For
more information, see managed identities for Azure resources.

Use the following steps to create a managed identity, add it to your Azure Maps
account.

system-assigned

Create a system assigned managed identity:

1. Go to your Azure Maps account in the Azure portal .


2. Select Identity from the Settings section in the left menu.
3. Toggle the Status to On.

For more information, see managed identities for Azure resources.

Create a container and upload data files


Before adding files to a data registry, you must upload them into a container in your
Azure storage account. Containers are similar to a directory in a file system, they're how
your files are organized in your Azure storage account.

To create a container in the Azure portal , follow these steps:

1. From within your Azure storage account, select Containers from the Data storage
section in the navigation pane.

2. Select + Container in the Containers pane to bring up the New container pane.

3. Select Create to create the container.


Once your container has been created, you can upload files into it.

4. Once the container is created, select it.

5. Select Upload from the toolbar, select one or more files

6. Select the Upload button.


Add a datastore
Once you've created an Azure storage account with files uploaded into one or more
containers, you're ready to create the datastore that links the storage accounts to your
Azure Maps account.

) Important

All storage accounts linked to an Azure Maps account must be in the same
geographic location. For more information, see Azure Maps service geographic
scope.

7 Note

If you do not have a storage account see Create a storage account.

1. Select Datastore from the left menu in your Azure Maps account.

2. Select the Add button. An Add datastore screen appears on the right side.

3. Enter the desired Datastore ID then select the Subscription name and Storage
account from the drop-down lists.

4. Select Add.

The new datastore now appears in the list of datastores.


Assign roles to managed identities and add them to the
datastore
Once your managed identities and datastore are created, you can add the managed
identities to the datastore, and simultaneously assign them the Contributor and Storage
Blob Data Reader roles. While it's possible to add roles to your managed identities
directly in your managed identities or storage account, which you can easily do while
simultaneously associating them with your Azure Maps datastore directly in the
datastore pane.

7 Note

Each managed identity associated with the datastore will need the Contributor and
Storage Blob Data Reader roles granted to them. If you do not have the required
permissions to grant roles to managed identities, consult your Azure administrator.
To assign roles to your managed identities and associate them with a datastore:

1. Select Datastore from the left menu in your Azure Maps account.

2. Select one or more datastores from the list, then Assign roles.

3. Select the Managed identity to associate to the selected datastore(s) from the
drop-down list.

4. Select both Contributor and Storage Blob Data Reader in the Roles to assign
drop-down list.

5. Select the Assign button.


Data registry properties
With a datastore created in your Azure Maps account, you're ready to gather the
properties required to create the data registry.

There are the AzureBlob properties that you pass in the body of the HTTP request, and
The user data ID passed in the URL.

The AzureBlob
The AzureBlob is a JSON object that defines properties required to create the data
registry.

ノ Expand table

Property Description

kind Defines what type of object being registered. Currently AzureBlob is the only
kind that is supported.

dataFormat The data format of the file located in blobUrl. Its format can either be GeoJSON
for the spatial service (Deprecated1) or ZIP for the conversion service
(Deprecated1).

msiClientId The ID of the managed identity being used to create the data registry.

linkedResource The ID of the datastore registered in the Azure Maps account.


The datastore contains a link to the file being registered.

blobUrl A URL pointing to the Location of the AzurebBlob, the file imported into your
container.

1
Azure Maps Creator, and the Data registry and Spatial services are now deprecated
and will be retired on 9/30/25.

The following two sections provide you with details how to get the values to use for the
msiClientId, blobUrl properties.

The msiClientId property


The msiClientId property is the ID of the managed identity used to create the data
registry. There are two types of managed identities: system-assigned and user-
assigned. System-assigned managed identities have their lifecycle tied to the resource
that created them. User-assigned managed identities can be used on multiple resources.
For more information, see managed identities for Azure resources.
system-assigned

When using System-assigned managed identities, you don't need to provide a


value for the msiClientId property. The data registry service automatically uses the
system assigned identity of the Azure Maps account when msiClientId is null.

The blobUrl property

The blobUrl property is the path to the file being registered. You can get this value from
the container that it was added to. data registry

1. Select your storage account in the Azure portal.

2. Select Containers from the left menu.

3. A list of containers appear. Select the container that contains the file you wish to
register.

4. The container opens, showing a list of the files previously uploaded.

5. Select the desired file, then copy the URL.

The user data ID


The user data ID ( udid ) of the data registry is a user-defined GUID that must conform to
the following Regex pattern:

Azure PowerShell

^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]
{12}$
 Tip

The udid is a user-defined GUID that must be supplied when creating a data
registry. If you want to be certain you have a globally unique identifier (GUID),
consider creating it by running a GUID generating tool such as the Guidgen.exe
command line program (Available with Visual Studio ).

Create a data registry


Now that you have your storage account with the desired files linked to your Azure
Maps account through the datastore and have gathered all required properties, you're
ready to use the data registry API to register those files. If you have multiple files in your
Azure storage account that you want to register, you need to run the register request
for each file ( udid ).

7 Note

The maximum size of a file that can be registered with an Azure Maps datastore is
one gigabyte.

To create a data registry:

system-assigned

1. Provide the information needed to reference the storage account that is being
added to the data registry in the body of your HTTP request. The information
must be in JSON format and contain the following fields:

JSON

{
"kind": "AzureBlob",
"azureBlob": {
"dataFormat": "geojson",
"linkedResource": "{datastore ID}",
"blobUrl":
"https://teststorageaccount.blob.core.windows.net/testcontainer/tes
t.geojson"
}
}
7 Note

When using System-assigned managed identities, you will get an error if


you provide a value for the msiClientId property in your HTTP request.

For more information on the properties required in the HTTP request body,
see Data registry properties.

2. Once you have the body of your HTTP request ready, execute the following
HTTP PUT request:

HTTP

https://us.atlas.microsoft.com/dataRegistries/{udid}?api-
version=2023-06-01&subscription-key={Your-Azure-Maps-Subscription-
key}

For more information on the udid property, see The user data ID.

3. Copy the value of the Operation-Location key from the response header.

 Tip

If the contents of a previously registered file is modified, it will fail its data
validation and won't be usable in Azure Maps until it's re-registered. To re-register
a file, rerun the register request, passing in the same AzureBlob used to create the
original registration. The value of the Operation-Location key is the status URL that
you'll use to check the status of the data registry creation in the next section, it
contains the operation ID used by the Get operation API.

7 Note

The value of the Operation-Location key will not contain the subscription-key ,
you will need to add that to the request URL when using it to check the data
registry creation status.

Check the data registry creation status


To (optionally) check the status of the data registry creation process, enter the status
URL you copied in the Create a data registry section, and add your subscription key as a
query string parameter. The request should look similar to the following URL:

HTTP

https://us.atlas.microsoft.com/dataRegistries/operations/{udid}?api-
version=2023-06-01&subscription-key={Your-Azure-Maps-Primary-Subscription-
key}

Get a list of all files in the data registry


Use the List request to get a list of all files registered in an Azure Maps account:

HTTP

https://us.atlas.microsoft.com/dataRegistries?api-version=2023-06-
01&subscription-key={Azure-Maps-Subscription-key}

The following sample demonstrates three possible statuses, completed, running and
failed:

JSON

{
"value": [
{
"udid": "f6495f62-94f8-0ec2-c252-45626f82fcb2",
"description": "Contoso Indoor Design",
"kind": "AzureBlob",
"azureBlob": {
"dataFormat": "zip",
"msiClientId": "3263cad5-ed8b-4829-b72b-3d1ba556e373",
"linkedResource": "my-storage-account",
"blobUrl": "https://mystorageaccount.blob.core.windows.net/my-
container/my/blob/path1.zip",
"sizeInBytes": 29920,
"contentMD5": "CsFxZ2YSfxw3cRPlqokV0w=="
},
"status": "Completed"
},
{
"udid": "8b1288fa-1958-4a2b-b68e-13a7i5af7d7c",
"kind": "AzureBlob",
"azureBlob": {
"dataFormat": "geojson",
"msiClientId": "3263cad5-ed8b-4829-b72b-3d1ba556e373",
"linkedResource": "my-storage-account",
"blobUrl": "https://mystorageaccount.blob.core.windows.net/my-
container/my/blob/path2.geojson",
"sizeInBytes": 1339
},
"status": "Running"
},
{
"udid": "7c1288fa-2058-4a1b-b68f-13a6h5af7d7c",
"description": "Contoso Geofence GeoJSON",
"kind": "AzureBlob",
"azureBlob": {
"dataFormat": "geojson",
"linkedResource": "my-storage-account",
"blobUrl": "https://mystorageaccount.blob.core.windows.net/my-
container/my/blob/path3.geojson",
"sizeInBytes": 1650,
"contentMD5": "rYpEfIeLbWZPyaICGEGy3A=="
},
"status": "Failed",
"error": {
"code": "ContentMD5Mismatch",
"message": "Actual content MD5: sOJMJvFParkSxBsvvrPOMQ== doesn't
match expected content MD5: CsFxZ2YSfxw3cRPlqokV0w==."
}
}
]
}

The data returned when running the list request is similar to the data provided when
creating a registry with a few additions:

ノ Expand table

property description

contentMD5 MD5 hash created from the contents of the file being registered. For more
information, see Data validation

sizeInBytes The size of the content in bytes.

Replace a data registry


If you need to replace a previously registered file with another file, rerun the register
request, passing in the same AzureBlob used to create the original registration, except
for the blobUrl. The BlobUrl needs to be modified to point to the new file.

Data validation
When you register a file in Azure Maps using the data registry API, an MD5 hash is
created from the contents of the file, encoding it into a 128-bit fingerprint and saving it
in the AzureBlob as the contentMD5 property. The MD5 hash stored in the contentMD5
property is used to ensure the data integrity of the file. Since the MD5 hash algorithm
always produces the same output given the same input, the data validation process can
compare the contentMD5 property of the file when it was registered against a hash of
the file in the Azure storage account to check that it's intact and unmodified. If the hash
isn't the same, the validation fails. If the file in the underlying storage account changes,
the validation fails. If you need to modify the contents of a file that has been registered
in Azure Maps, you need to register it again.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Provide data feedback to Azure Maps
Article • 03/19/2024

Azure Maps is a set of mapping and geospatial APIs and a Web SDK that enables
developers and organizations to build intelligent location-based experiences for
applications across many different industries and use cases. While Azure Maps
continually updates its underlying map data to ensure the most current and accurate
map content possible, the Azure Maps feedback tool is a useful resource for customers
to report issues with the map data. The feedback tool empowers both Azure Maps and
Bing Maps customers to communicate map data corrections to Microsoft. All suggested
map data corrections submitted via the feedback tool are carefully evaluated and
promptly addressed.

How to access the feedback tool


There are three ways to access the feedback tool.

Azure Maps Account. You can access the feedback tool in your Azure Maps
Account from a link in the Provide Map Data Feedback tab of the Overview
section.

Web SDK map control. You can access the feedback tool from a link in the lower
right-hand side of the map.

URL. You can access the feedback tool directly from the Azure Maps feedback
tool URL.

Providing feedback
You can provide feedback on any issue you find in an Azure Maps map using the
feedback tool. The following example demonstrates how to provide feedback when you
encounter a road recently changed to become a two-way road.

1. Navigate to the Azure Maps feedback tool .

2. Zoom in to the problem area on the map.


3. Select The map in the Select the problem area drop-down list.

4. Select Roads in the Give us a little more information drop-down list.


5. Select Road should be two way in the Tell us the specific issue drop-down list.

6. A pushpin appears with the message Drag the pushpin to the location of the
issue on the map. Move the pushpin to the desired location.

7. Enter relevant details about the issue in the Tell us more about the problem text
box.

Using the search bar


If the map doesn't appear in the desired location when bringing up the feedback tool,
you can pan the map to the desired location using your mouse. Another option is to use
the search bar, just type in the desired location and select search icon or press the
Enter key. Once done, select the X in the upper right-hand side of the search results
view to return to the feedback tool.

Next steps
For any technical questions related to Azure Maps, see Microsoft Q & A.
Show the correct copyright attribution
Article • 03/31/2025

When using the Azure Maps Render service, either as a basemap or layer, you're
required to display the appropriate data provider copyright attribution on the map. This
information should be displayed in the lower right-hand corner of the map.

The above image is an example of a map from the Render service, displaying the road
style. It shows the copyright attribution in the lower right-hand corner of the map.
The above image is an example of a map from the Render service, displaying the
satellite style. note that there's another data provider listed.

The Get Map Attribution API


The Get Map Attribution API enables you to request map copyright attribution
information so that you can display in on the map within your applications.

When to use the Get Map Attribution API


The map copyright attribution information must be displayed on the map in any
applications that use the Render API.

When using map tiles from the Render service in a third-party map, you must display
and update the copyright attribution information on the map.

Map content changes whenever an end user selects a different style, zooms in or out, or
pans the map. Each of these user actions causes an event to fire. When any of these
events fire, you need to call the Get Map Attribution API. Once you have the updated
copyright attribution information, you then need to display it in the lower right-hand
corner of the map.

Since the data providers can differ depending on the region and zoom level, the Get
Map Attribution API takes these parameters as input and returns the corresponding
attribution text.

How to use the Get Map Attribution API


You need the following information to run the attribution command:

ノ Expand table

Parameter Type Description

api-version string Version number of Azure Maps API.

bounds array A string that represents the rectangular area of a bounding box. The
bounds parameter is defined by the four bounding box coordinates.
The first 2 are the WGS84 longitude and latitude defining the
southwest corner and the last 2 are the WGS84 longitude and latitude
defining the northeast corner. The string is presented in the following
format: [SouthwestCorner_Longitude, SouthwestCorner_Latitude,
NortheastCorner_Longitude, NortheastCorner_Latitude].
Parameter Type Description

tilesetId TilesetID A tileset is a collection of raster or vector data broken up into a


uniform grid of square tiles at preset zoom levels. Every tileset has a
tilesetId to use when making requests. The tilesetId for tilesets created
using Azure Maps Creator are generated through the Tileset Create
API. There are ready-to-use tilesets supplied by Azure Maps, such as
microsoft.base.road , microsoft.base.hybrid and
microsoft.weather.radar.main , a complete list can be found the Get
Map Attribution REST API documentation.

zoom integer Zoom level for the selected tile. The valid range depends on the tile,
see the TilesetID table for valid values for a specific tileset. For more
information, see the Zoom levels and tile grid article.

subscription- string One of the Azure Maps keys provided from an Azure Map Account. For
key more information, see the Authentication with Azure Maps article.

Run the following GET request to get the corresponding copyright attribution to display
on the map:

HTTP

https://atlas.microsoft.com/map/attribution?subscription-key={Your-Azure-
Maps-Subscription-key}&api-version=2024-04-
01&tilesetId=microsoft.base&zoom=6&bounds=-122.414162,47.579490,-122.247157,
47.668372

Additional information
For more information, see the Render service documentation.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Configure global data processing
Article • 11/27/2024

In some cases, it may be necessary to process requests in a region different from your
Azure Maps Account's region due to local data residency laws. When this happens, you
can grant Azure Maps consent to process your data in other specified regions. For more
information, see Consent management.

This article guides you on configuring global data processing settings to comply with
data residency laws using multiple approaches including the Azure Portal, REST APIs or
an ARM deployment template. This allows Azure Maps to process address requests
within the specified country's region, regardless of your Azure Maps Account's region.

) Important

If your scenarios don't involve South Korea data, there is no need to enable cross-
region processing. This requirement is specific to South Korea due to its data
residency laws.

Configure global data processing in the Azure


portal
The Azure Maps Resource location is enabled by default and can be configured in the
Process Data Globally page of the Azure portal.

To give consent to one or more regions:

1. Sign in to your Azure Maps Account in the Azure portal .

2. In Settings, select Process data globally.

A map of the world appears with a plus sign for each region that can be selected.

3. Additionally you can select Add region, then select the region you wish to add or
remove.

4. Once you all desired regions are chosen, select Save.


Once your updates are saved, one or more new selections appear in the list of regions.

Configure global data processing using REST


API
Consent can be managed using Azure Maps Account Management REST APIs. To
Configure global data processing, send an Accounts - Update PATCH request and pass in
the properties.locations parameter in the body of the request.

Be sure to include the appropriate subscription key, resource group and Azure Maps
account name.

HTML

https://management.azure.com/subscriptions/<subscription-
key>/resourceGroups/<resource-group-
name>/providers/Microsoft.Maps/accounts/<account-name>?api-version=2024-07-
01-preview

Header

Be sure to include a correct access-token.

HTML

Content-Type: application/json
Authorization: Bearer <access-token>

Body

JSON

{
"properties": {
"locations": [
{
"locationName": "Korea Central"
}
]
},
}

Configure global data processing using an


ARM deployment template
The following template will add West Europe to the list of valid global data processing
regions.

Be sure to include the appropriate Azure Maps account name and location.
JSON

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-
01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Maps/accounts",
"apiVersion": "2024-07-01-preview",
"name": "<account-name>",
"location": "<account-location>",
"sku": {
"name": "G2"
},
"properties":
{
"locations": [
{
"locationName": "West Europe"
}
]
}
}
]
}

7 Note

Your data is always stored in the region you created your Azure Maps Account,
regardless of your global data processing settings.

Next steps
Azure Maps is a global service that allows specifying a geographic scope, which enables
limiting data residency to specific regions.

Azure Maps service geographic scope

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Drawing package requirements
Article • 03/28/2023

You can convert uploaded drawing packages into map data by using the Azure Maps
Conversion service . This article describes the drawing package requirements for the
Conversion API. To view a sample package, you can download the sample Drawing
package .

Prerequisites
The drawing package includes drawings saved in DWG format, which is the native file
format for Autodesk's AutoCAD® software.

You can choose any CAD software to produce the drawings in the drawing package.

The Conversion service converts the drawing package into map data. The Conversion
service works with the AutoCAD DWG file format AC1032 .

Glossary of terms
For easy reference, here are some terms and definitions that are important as you read
this article.

Term Definition

Layer An AutoCAD DWG layer from the drawing file.

Entity An AutoCAD DWG entity from the drawing file.

Xref A file in AutoCAD DWG file format, attached to the primary drawing as an external
reference.

Level An area of a building at a set elevation. For example, the floor of a building.

Feature An instance of an object produced from the Conversion service that combines a
geometry with metadata information.

Feature A common blueprint for features. For example, a unit is a feature class, and an office
classes is a feature.

Drawing package structure


A drawing package is a .zip archive that contains the following files:
DWG files in AutoCAD DWG file format.
A manifest.json file that describes the DWG files in the drawing package.

The drawing package must be zipped into a single archive file, with the .zip extension.
The DWG files can be organized in any way inside the package, but the manifest file
must live at the root directory of the zipped package. The next sections detail the
requirements for the DWG files, manifest file, and the content of these files. To view a
sample package, you can download the sample drawing package .

DWG file conversion process


The Conversion service does the following on each DWG file:

Extracts feature classes:


Levels
Units
Zones
Openings
Walls
Vertical penetrations
Produces a Facility feature.
Produces a minimal set of default Category features referenced by other features:
room
structure
wall
opening.door
zone
facility

DWG file requirements


A single DWG file is required for each level of the facility. All data of a single level must
be contained in a single DWG file. Any external references (xrefs) must be bound to the
parent drawing. For example, a facility with three levels has three DWG files in the
drawing package.

Each DWG file must adhere to the following requirements:

The DWG file must define the Exterior and Unit layers. It can optionally define the
following layers: Wall, Door, UnitLabel, Zone, and ZoneLabel.
The DWG file can't contain features from multiple levels.
The DWG file can't contain features from multiple facilities.
The DWG must reference the same measurement system and unit of measurement
as other DWG files in the drawing package.

DWG layer requirements


Each DWG layer must adhere to the following rules:

A layer must exclusively contain features of a single class. For example, units and
walls can’t be in the same layer.
A single class of features can be represented by multiple layers.
Self-intersecting polygons are permitted, but are automatically repaired. When
they repaired, the Conversion service raises a warning. It's advisable to manually
inspect the repaired results, because they might not match the expected results.
Each layer has a supported list of entity types. Any other entity types in a layer will
be ignored. For example, text entities aren't supported on the wall layer.

The following table outlines the supported entity types and converted map features for
each layer. If a layer contains unsupported entity types, then the Conversion service
ignores those entities.

Layer Entity types Converted Features

Exterior POLYGON, POLYLINE Levels


(closed), CIRCLE, or
ELLIPSE (closed)

Unit POLYGON, POLYLINE Units and Vertical penetrations


(closed), CIRCLE, or
ELLIPSE (closed)

Wall POLYGON, POLYLINE


(closed), CIRCLE, or
ELLIPSE (closed),
Structures

Door POLYGON, POLYLINE, Openings


LINE, CIRCULARARC,
CIRCLE

Zone POLYGON, POLYLINE Zones


(closed), CIRCLE, or
ELLIPSE (closed)
Layer Entity types Converted Features

UnitLabel Text (single line) Not applicable. This layer can only add properties to
the unit features from the Units layer. For more
information, see the UnitLabel layer.

ZoneLabel Text (single line) Not applicable. This layer can only add properties to
zone features from the ZonesLayer. For more
information, see the ZoneLabel layer.

The following sections describe the requirements for each layer.

Exterior layer
The DWG file for each level must contain a layer to define that level's perimeter. This
layer is referred to as the exterior layer. For example, if a facility contains two levels, then
it needs to have two DWG files, with an exterior layer for each file.

No matter how many entity drawings are in the exterior layer, the resulting facility
dataset contains only one level feature for each DWG file. Additionally:

Exteriors must be drawn as POLYGON, POLYLINE (closed), CIRCLE, or ELLIPSE


(closed).
Exteriors may overlap, but are dissolved into one geometry.
Resulting level feature must be at least 4 square meters.
Resulting level feature must not be greater 400,000 square meters.

If the layer contains multiple overlapping PolyLines, they're dissolved into a single Level
feature. Instead, if the layer contains multiple non-overlapping PolyLines, the resulting
Level feature has a multi-polygonal representation.

You can see an example of the Exterior layer as the outline layer in the sample drawing
package .

Unit layer
The DWG file for each level defines a layer containing units. Units are navigable spaces
in the building, such as offices, hallways, stairs, and elevators. If the
VerticalPenetrationCategory property is defined, navigable units that span multiple
levels, such as elevators and stairs, are converted to Vertical Penetration features.
Vertical penetration features that overlap each other are assigned one setid .

The Units layer should adhere to the following requirements:


Units must be drawn as POLYGON, POLYLINE (closed), CIRCLE, or ELLIPSE (closed).
Units must fall inside the bounds of the facility exterior perimeter.
Units must not partially overlap.
Units must not contain any self-intersecting geometry.

Name a unit by creating a text object in the UnitLabel layer, and then place the object
inside the bounds of the unit. For more information, see the UnitLabel layer.

You can see an example of the Units layer in the sample drawing package .

Wall layer
The DWG file for each level can contain a layer that defines the physical extents of walls,
columns, and other building structure.

Walls must be drawn as POLYGON, POLYLINE (closed), CIRCLE, or ELLIPSE (closed).


The wall layer or layers should only contain geometry that's interpreted as building
structure.

You can see an example of the Walls layer in the sample drawing package .

Door layer
You can include a DWG layer that contains doors. Each door must overlap the edge of a
unit from the Unit layer.

Door openings in an Azure Maps dataset are represented as a single-line segment that
overlaps multiple unit boundaries. The following images show how Azure Maps converts
door layer geometry into opening features in a dataset.

Zone layer
The DWG file for each level can contain a Zone layer that defines the physical extents of
zones. A zone is a non-navigable space that can be named and rendered. Zones can
span multiple levels and are grouped together using the zoneSetId property.
Zones must be drawn as POLYGON, POLYLINE (closed), or ELLIPSE (closed).
Zones can overlap.
Zones can fall inside or outside the facility's exterior perimeter.

Name a zone by creating a text object in the ZoneLabel layer, and placing the text
object inside the bounds of the zone. For more information, see ZoneLabel layer.

You can see an example of the Zone layer in the sample drawing package .

UnitLabel layer
The DWG file for each level can contain a UnitLabel layer. The UnitLabel layer adds a
name property to units extracted from the Unit layer. Units with a name property can
have more details specified in the manifest file.

Unit labels must be single-line text entities.


Unit labels must fall entirely inside the bounds of their unit.
Units must not contain multiple text entities in the UnitLabel layer.

You can see an example of the UnitLabel layer in the sample drawing package .

ZoneLabel layer
The DWG file for each level can contain a ZoneLabel layer. This layer adds a name
property to zones extracted from the Zone layer. Zones with a name property can have
more details specified in the manifest file.

Zones labels must be single-line text entities.


Zones labels must fall inside the bounds of their zone.
Zones must not contain multiple text entities in the ZoneLabel layer.

You can see an example of the ZoneLabel layer in the sample drawing package .

Manifest file requirements


The zip folder must contain a manifest file at the root level of the directory, and the file
must be named manifest.json. It describes the DWG files to allow the Conversion
service to parse their content. Only the files identified by the manifest are ingested.
Files that are in the zip folder, but aren't properly listed in the manifest, are ignored.

The file paths in the buildingLevels object of the manifest file must be relative to the
root of the zip folder. The DWG file name must exactly match the name of the facility
level. For example, a DWG file for the "Basement" level is "Basement.dwg." A DWG file
for level 2 is named as "level_2.dwg." Use an underscore, if your level name has a space.

Although there are requirements when you use the manifest objects, not all objects are
required. The following table shows the required and optional objects for version 1.1 of
the Conversion service .

7 Note

Unless otherwise specified, all properties with a string property type allow for one
thousand characters.

Object Required Description

version true Manifest schema version. Currently, only version 1.1 is supported.

directoryInfo true Outlines the facility geographic and contact information. It can also
be used to outline an occupant geographic and contact
information.

buildingLevels true Specifies the levels of the buildings and the files containing the
design of the levels.

georeference true Contains numerical geographic information for the facility drawing.

dwgLayers true Lists the names of the layers, and each layer lists the names of its
own features.

unitProperties false Can be used to insert more metadata for the unit features.

zoneProperties false Can be used to insert more metadata for the zone features.

The next sections detail the requirements for each object.

directoryInfo

Property Type Required Description

name string true Name of building.

streetAddress string false Address of building.

unit string false Unit in building.

locality string false Name of a city, town, area,


neighborhood, or region.
Property Type Required Description

adminDivisions JSON false An array containing address


array of designations. For example:
strings (Country, State) Use ISO 3166
country codes and ISO 3166-2
state/territory codes.

postalCode string false The mail sorting code.

hoursOfOperation string false Adheres to the OSM Opening


Hours format.

phone string false Phone number associated with


the building.

website string false Website associated with the


building.

nonPublic bool false Flag specifying if the building is


open to the public.

anchorLatitude numeric false Latitude of a facility anchor


(pushpin).

anchorLongitude numeric false Longitude of a facility anchor


(pushpin).

anchorHeightAboveSeaLevel numeric false Height of the facility's ground


floor above sea level, in meters.

defaultLevelVerticalExtent false Default height


numeric (thickness) of a level
of this facility to use
when a level's
verticalExtent is
undefined.

buildingLevels

The buildingLevels object contains a JSON array of buildings levels.

Property Type Required Description

levelName string true Descriptive level name. For example: Floor 1,


Lobby, Blue Parking, or Basement.

ordinal integer true Determines the vertical order of levels. Every


facility must have a level with ordinal 0.
Property Type Required Description

heightAboveFacilityAnchor numeric false Level height above the anchor in meters.

verticalExtent numeric false Floor-to-ceiling height (thickness) of the


level in meters.

filename string true File system path of the CAD drawing for a
building level. It must be relative to the root
of the building's zip file.

georeference

Property Type Required Description

lat numeric true Decimal representation of degrees latitude at the facility


drawing's origin. The origin coordinates must be in WGS84
Web Mercator ( EPSG:3857 ).

lon numeric true Decimal representation of degrees longitude at the facility


drawing's origin. The origin coordinates must be in WGS84
Web Mercator ( EPSG:3857 ).

angle numeric true The clockwise angle, in degrees, between true north and the
drawing's vertical (Y) axis.

dwgLayers

Property Type Required Description

exterior array of true Names of layers that define the exterior building
strings profile.

unit array of false Names of layers that define units.


strings

wall array of false Names of layers that define walls.


strings

door array of false Names of layers that define doors.


strings

unitLabel array of false Names of layers that define names of units.


strings

zone array of false Names of layers that define zones.


strings
Property Type Required Description

zoneLabel array of false Names of layers that define names of zones.


strings

unitProperties

The unitProperties object contains a JSON array of unit properties.

Property Type Required Description

unitName string true Name of unit to associate with this


unitProperty record. This record is
only valid when a label matching
unitName is found in the unitLabel
layers.

categoryName string false Purpose of the unit. A list of values


that the provided rendering styles
can make use of is documented in
categories.json .

occupants array of false List of occupants for the unit.


directoryInfo
objects

nameAlt string false Alternate name of the unit.

nameSubtitle string false Subtitle of the unit.

addressRoomNumber string false Room, unit, apartment, or suite


number of the unit.

verticalPenetrationCategory string false When this property is defined, the


resulting feature is a vertical
penetration (VRT) rather than a unit.
You can use vertical penetrations to
go to other vertical penetration
features in the levels above or below
it. Vertical penetration is a
Category name. If this property is
defined, the categoryName property
is overridden with
verticalPenetrationCategory .
Property Type Required Description

verticalPenetrationDirection string false If verticalPenetrationCategory is


defined, optionally define the valid
direction of travel. The permitted
values are: lowToHigh , highToLow ,
both , and closed . The default value
is both . The value is case-sensitive.

nonPublic bool false Indicates if the unit is open to the


public.

isRoutable bool false When this property is set to false ,


you can't go to or through the unit.
The default value is true .

isOpenArea bool false Allows the navigating agent to enter


the unit without the need for an
opening attached to the unit. By
default, this value is set to true for
units with no openings, and false
for units with openings. Manually
setting isOpenArea to false on a
unit with no openings results in a
warning, because the resulting unit
isn't reachable by a navigating agent.

zoneProperties

The zoneProperties object contains a JSON array of zone properties.

Property Type Required Description

zoneName string true Name of zone to associate with zoneProperty record.


This record is only valid when a label matching
zoneName is found in the zoneLabel layer of the zone.

categoryName string false Purpose of the zone. A list of values that the provided
rendering styles can make use of is documented in
categories.json .

zoneNameAlt string false Alternate name of the zone.

zoneNameSubtitle string false Subtitle of the zone.

zoneSetId string false Set ID to establish a relationship among multiple zones


so that they can be queried or selected as a group. For
example, zones that span multiple levels.
Sample drawing package manifest
The following is the manifest file for the sample drawing package. Go to the Sample
drawing package for Azure Maps Creator on GitHub to download the entire package.

Manifest file

JSON

{
"version": "1.1",
"directoryInfo": {
"name": "Contoso Building",
"streetAddress": "Contoso Way",
"unit": "1",
"locality": "Contoso eastside",
"postalCode": "98052",
"adminDivisions": [
"Contoso city",
"Contoso state",
"Contoso country"
],
"hoursOfOperation": "Mo-Fr 08:00-17:00 open",
"phone": "1 (425) 555-1234",
"website": "www.contoso.com",
"nonPublic": false,
"anchorLatitude": 47.636152,
"anchorLongitude": -122.132600,
"anchorHeightAboveSeaLevel": 1000,
"defaultLevelVerticalExtent": 3
},
"buildingLevels": {
"levels": [
{
"levelName": "Basement",
"ordinal": -1,
"filename": "./Basement.dwg"
}, {
"levelName": "Ground",
"ordinal": 0,
"verticalExtent": 5,
"filename": "./Ground.dwg"
}, {
"levelName": "Level 2",
"ordinal": 1,
"heightAboveFacilityAnchor": 3.5,
"filename": "./Level_2.dwg"
}
]
},
"georeference": {
"lat": 47.636152,
"lon": -122.132600,
"angle": 0
},
"dwgLayers": {
"exterior": [
"OUTLINE", "WINDOWS"
],
"unit": [
"UNITS"
],
"wall": [
"WALLS"
],
"door": [
"DOORS"
],
"unitLabel": [
"UNITLABELS"
],
"zone": [
"ZONES"
],
"zoneLabel": [
"ZONELABELS"
]
},
"unitProperties": [
{
"unitName": "B01",
"categoryName": "room.office",
"occupants": [
{
"name": "Joe's Office",
"phone": "1 (425) 555-1234"
}
],
"nameAlt": "Basement01",
"nameSubtitle": "01",
"addressRoomNumber": "B01",
"nonPublic": true,
"isRoutable": true,
"isOpenArea": true
},
{
"unitName": "B02"
},
{
"unitName": "B05",
"categoryName": "room.office"
},
{
"unitName": "STRB01",
"verticalPenetrationCategory": "verticalPenetration.stairs",
"verticalPenetrationDirection": "both"
},
{
"unitName": "ELVB01",
"verticalPenetrationCategory": "verticalPenetration.elevator",
"verticalPenetrationDirection": "high_to_low"
}
],
"zoneProperties":
[
{
"zoneName": "WifiB01",
"categoryName": "Zone",
"zoneNameAlt": "MyZone",
"zoneNameSubtitle": "Wifi",
"zoneSetId": "1234"
},
{
"zoneName": "Wifi101",
"categoryName": "Zone",
"zoneNameAlt": "MyZone",
"zoneNameSubtitle": "Wifi",
"zoneSetId": "1234"
}
]
}

Next steps
For a guide on how to prepare your drawing package, see the drawing package guide.

Drawing Package Guide

Learn more by reading:

Creator for indoor maps


Facility Ontology
Article • 04/13/2023

Facility ontology defines how Azure Maps Creator internally stores facility data in a
Creator dataset. In addition to defining internal facility data structure, facility ontology is
also exposed externally through the WFS API. When WFS API is used to query facility
data in a dataset, the response format is defined by the ontology supplied to that
dataset.

Changes and Revisions


The Facility 1.0 contains revisions for the Facility feature class definitions for Azure Maps
services .

Major Changes
Fixed the following constraint validation checks:

Constraint validation check for exclusivity of isObstruction = true or the presence


of obstructionArea for lineElement and areaElement feature classes.

Constraint validation check for exclusivity of isRoutable = true or the presence of


routeThroughBehavior for the category feature class.

Feature collection
At a high level, the facility ontology consists of feature collections, each contains an
array of feature objects. All feature objects have two fields in common, ID and
Geometry . When importing a drawing package into Azure Maps Creator, these fields are
automatically generated.

In addition to these common fields, each feature class defines a set of properties. Each
property is defined by its data type and constraints. Some feature classes have
properties that are dependent on other feature classes. Dependant properties evaluate
to the ID of another feature class.

The remaining sections in this article define the different feature classes and their
properties that make up the facility ontology in Microsoft Azure Maps Creator.
unit
The unit feature class defines a physical and non-overlapping area that can be
occupied and traversed by a navigating agent. A unit can be a hallway, a room, a
courtyard, and so on.

Geometry Type: Polygon

Property Type Required Description

originalId string false When the dataset is created through the


conversion service, the original ID is
automatically set to the Azure Maps
internal ID. Maximum length allowed is
1,000 characters.

externalId string false An ID used by the client to associate the


feature with another feature in a different
dataset, such as in an internal database.
Maximum length allowed is 1,000
characters.

categoryId category.Id true The ID of a category feature.

isOpenArea boolean false Represents whether the unit is an open


(Default value area. If set to true , structures don't
is null .) surround the unit boundary, and a
navigating agent can enter the unit
without the need of an opening. By
default, units are surrounded by physical
barriers and are open only where an
opening feature is placed on the boundary
of the unit. If walls are needed in an open
area unit, they can be represented as a
lineElement or areaElement with an
isObstruction property equal to true .

navigableBy enum false Indicates the types of navigating agents


["pedestrian", that can traverse the unit. If unspecified,
"wheelchair", the unit is assumed to be traversable by
"machine", any navigating agent.
"bicycle",
"automobile",
"hiredAuto",
"bus", "railcar",
"emergency",
"ferry", "boat"]
Property Type Required Description

isRoutable boolean false Determines if the unit is part of the routing


(Default value graph. If set to true , the unit can be used
is null .) as source/destination or intermediate node
in the routing experience.

routeThroughBehavior enum false Determines if navigating through the unit


["disallowed", is allowed. If unspecified, it inherits its
"allowed", value from the category feature referred to
"preferred"] in the categoryId property. If specified, it
overrides the value given in its category
feature."

nonPublic boolean false If true , the unit is navigable only by


privileged users. Default value is false .

levelId level.Id true The ID of a level feature.

occupants array of false The IDs of directoryInfo features. Used to


directoryInfo.Id represent one or many occupants in the
feature.

addressId directoryInfo.Id false The ID of a directoryInfo feature. Used to


represent the address of the feature.

addressRoomNumber directoryInfo.Id true Room/Unit/Apartment/Suite number of


the unit.

name string false Name of the feature in local language.


Maximum length allowed is 1,000
characters.

nameSubtitle string false Subtitle that shows up under the name of


the feature. Can be used to display the
name in a different language, and so on.
Maximum length allowed is 1,000
characters.

nameAlt string false Alternate name used for the feature.


Maximum length allowed is 1,000
characters.

anchorPoint Point false GeoJSON Point geometry that represents


the feature as a point. Can be used to
position the label of the feature.

zone
The zone feature class defines a virtual area, like a WiFi zone or emergency assembly
area. Zones can be used as destinations but aren't meant for through traffic.

Geometry Type: Polygon

Property Type Required Description

originalId string false When the dataset is created through the conversion
service, the original ID is automatically set to the Azure
Maps internal ID. Maximum length allowed is 1,000
characters.

externalId string false An ID used by the client to associate the feature with
another feature in a different dataset, such as in an
internal database. Maximum length allowed is 1,000
characters.

categoryId category.Id true The ID of a category feature.

setId string true Required for zone features that represent multi-level
zones. The setId is the unique ID for a zone that spans
multiple levels. The setId enables a zone with varying
coverage on different floors to be represented with
different geometry on different levels. The setId can
be any string and is case-sensitive. It's recommended
that the setId is a GUID. Maximum length allowed is
1,000 characters.

levelId level.Id true The ID of a level feature.

name string false Name of the feature in local language. Maximum


length allowed is 1,000 characters.

nameSubtitle string false Subtitle that shows up under the name of the feature.
Can be used to display the name in a different
language, and so on. Maximum length allowed is 1,000
characters.

nameAlt string false Alternate name used for the feature. Maximum length
allowed is 1,000 characters.

anchorPoint Point false GeoJSON Point geometry that represents the feature as
a point. Can be used to position the label of the
feature.

level
The level class feature defines an area of a building at a set elevation. For example, the
floor of a building, which contains a set of features, such as units.

Geometry Type: MultiPolygon

Property Type Required Description

originalId string false When the dataset is created through the


conversion service, the original ID is
automatically set to the Azure Maps internal
ID. Maximum length allowed is 1,000
characters.

externalId string false An ID used by the client to associate the


feature with another feature in a different
dataset, such as in an internal database.
Maximum length allowed is 1,000
characters.

facilityId facility.Id true The ID of a facility feature.

ordinal integer true The level number. Used by the


verticalPenetration feature to determine the
relative order of the floors to help with
travel direction. The general practice is to
start with 0 for the ground floor. Add +1 for
every floor upwards, and -1 for every floor
going down. It can be modeled with any
numbers, as long as the higher physical
floors are represented by higher ordinal
values.

abbreviatedName string false A four-character abbreviated level name,


like what would be found on an elevator
button.

heightAboveFacilityAnchor double false Vertical distance of the level's floor above


facility.anchorHeightAboveSeaLevel, in
meters.

verticalExtent double false Vertical extent of the level, in meters. If not


provided, defaults to
facility.defaultLevelVerticalExtent.

name string false Name of the feature in local language.


Maximum length allowed is 1,000
characters.
Property Type Required Description

nameSubtitle string false Subtitle that shows up under the name of


the feature. Can be used to display the
name in a different language, and so on.
Maximum length allowed is 1,000
characters.

nameAlt string false Alternate name used for the feature.


Maximum length allowed is 1,000
characters.

anchorPoint Point false GeoJSON Point geometry that represents


the feature as a point. Can be used to
position the label of the feature.

facility
The facility feature class defines the area of the site, building footprint, and so on.

Geometry Type: MultiPolygon

Property Type Required Description

originalId string false When the dataset is created through


the conversion service, the original
ID is automatically set to the Azure
Maps internal ID. Maximum length
allowed is 1,000 characters.

externalId string false An ID used by the client to associate


the feature with another feature in a
different dataset, such as in an
internal database. Maximum length
allowed is 1,000 characters.

categoryId category.Id true The ID of a category feature.

occupants array of false The IDs of directoryInfo features.


directoryInfo.Id Used to represent one or many
occupants in the feature.

addressId directoryInfo.Id true The ID of a directoryInfo feature.


Used to represent the address of the
feature.
Property Type Required Description

name string false Name of the feature in local


language. Maximum length allowed
is 1,000 characters.

nameSubtitle string false Subtitle that shows up under the


name of the feature. Can be used to
display the name in a different
language, and so on. Maximum
length allowed is 1,000 characters.

nameAlt string false Alternate name used for the feature.


Maximum length allowed is 1,000
characters.

anchorPoint Point false GeoJSON Point geometry that


represents the feature as a point.
Can be used to position the label of
the feature.

anchorHeightAboveSeaLevel double false Height of anchor point above sea


level, in meters. Sea level is defined
by EGM 2008.

defaultLevelVerticalExtent double false Default value for vertical extent of


levels, in meters.

verticalPenetration
The verticalPenetration class feature defines an area that, when used in a set,
represents a method of navigating vertically between levels. It can be used to model
stairs, elevators, and so on. Geometry can overlap units and other vertical penetration
features.

Geometry Type: Polygon

Property Type Required Description

originalId string false When the dataset is created through the


conversion service, the original ID is
automatically set to the Azure Maps internal
ID. Maximum length allowed is 1,000
characters.
Property Type Required Description

externalId string false An ID used by the client to associate the


feature with another feature in a different
dataset, such as in an internal database.
Maximum length allowed is 1,000
characters.

categoryId category.Id true The ID of a category feature.

setId string true Vertical penetration features must be used


in sets to connect multiple levels. Vertical
penetration features in the same set are
considered to be the same. The setId can
be any string, and is case-sensitive. Using a
GUID as a setId is recommended.
Maximum length allowed is 1,000
characters.

levelId level.Id true The ID of a level feature.

direction string enum [ "both", false Travel direction allowed on this feature. The
"lowToHigh", ordinal attribute on the level feature is used
"highToLow", "closed" to determine the low and high order.
]

navigableBy enum ["pedestrian", false Indicates the types of navigating agents that
"wheelchair", can traverse the unit. If unspecified, the unit
"machine", "bicycle", is traversable by any navigating agent.
"automobile",
"hiredAuto", "bus",
"railcar", "emergency",
"ferry", "boat"]

nonPublic boolean false If true , the unit is navigable only by


privileged users. Default value is false .

name string false Name of the feature in local language.


Maximum length allowed is 1,000
characters.

nameSubtitle string false Subtitle that shows up under the name of


the feature. Can be used to display the
name in a different language, and so on.
Maximum length allowed is 1,000
characters.

nameAlt string false Alternate name used for the feature.


Maximum length allowed is 1,000
characters.
Property Type Required Description

anchorPoint Point false GeoJSON Point geometry that represents


the feature as a point. Can be used to
position the label of the feature.

opening
The opening class feature defines a traversable boundary between two units, or a unit
and verticalPenetration .

Geometry Type: LineString

Property Type Required Description

originalId string false When the dataset is


created through the
conversion service, the
original ID is
automatically set to
the Azure Maps
internal ID. Maximum
length allowed is
1,000 characters.

externalId string false An ID used by the


client to associate the
feature with another
feature in a different
dataset, such as in an
internal database.
Maximum length
allowed is 1,000
characters.

categoryId category.Id true The ID of a category


feature.

levelId level.Id true The ID of a level


feature.
Property Type Required Description

isConnectedToVerticalPenetration boolean false Whether or not this


feature is connected
to a
verticalPenetration
feature on one of its
sides. Default value is
false .

navigableBy enum ["pedestrian", false Indicates the types of


"wheelchair", navigating agents that
"machine", "bicycle", can traverse the unit.
"automobile", If unspecified, the unit
"hiredAuto", "bus", is traversable by any
"railcar", "emergency", navigating agent.
"ferry", "boat"]

accessRightToLeft enum [ "prohibited", false Method of access


"digitalKey", when passing through
"physicalKey", the opening from
"keyPad", "guard", right to left. Left and
"ticket", "fingerprint", right are determined
"retina", "voice", "face", by the vertices in the
"palm", "iris", feature geometry,
"signature", standing at the first
"handGeometry", vertex and facing the
"time", "ticketChecker", second vertex.
"other"] Omitting this property
means there are no
access restrictions.

accessLeftToRight enum [ "prohibited", false Method of access


"digitalKey", when passing through
"physicalKey", the opening from left
"keyPad", "guard", to right. Left and right
"ticket", "fingerprint", are determined by the
"retina", "voice", "face", vertices in the feature
"palm", "iris", geometry, standing at
"signature", the first vertex and
"handGeometry", facing the second
"time", "ticketChecker", vertex. Omitting this
"other"] property means there
are no access
restrictions.
Property Type Required Description

isEmergency boolean false If true , the opening is


navigable only during
emergencies. Default
value is false

anchorPoint Point false GeoJSON Point


geometry y that
represents the feature
as a point. Can be
used to position the
label of the feature.

directoryInfo
The directoryInfo object class feature defines the name, address, phone number,
website, and hours of operation for a unit, facility, or an occupant of a unit or facility.

Geometry Type: None

Property Type Required Description

originalId string false When the dataset is created through the conversion
service, the original ID is automatically set to the Azure
Maps internal ID. Maximum length allowed is 1,000
characters.

externalId string false An ID used by the client to associate the feature with
another feature in a different dataset, such as in an
internal database. Maximum length allowed is 1,000
characters.

streetAddress string false Street address part of the address. Maximum length
allowed is 1,000 characters.

unit string false Unit number part of the address. Maximum length
allowed is 1,000 characters.

locality string false The locality of the address. For example: city,
municipality, village. Maximum length allowed is 1,000
characters.

adminDivisions array false Administrative division part of the address, from


of smallest to largest (County, State, Country). For
strings example: ["King", "Washington", "USA" ] or ["West
Godavari", "Andhra Pradesh", "IND" ]. Maximum length
allowed is 1,000 characters.
Property Type Required Description

postalCode string false Postal code part of the address. Maximum length
allowed is 1,000 characters.

name string false Name of the feature in local language. Maximum length
allowed is 1,000 characters.

nameSubtitle string false Subtitle that shows up under the name of the feature.
Can be used to display the name in a different
language, and so on. Maximum length allowed is 1,000
characters.

nameAlt string false Alternate name used for the feature. Maximum length
allowed is 1,000 characters.

phoneNumber string false Phone number. Maximum length allowed is 1,000


characters.

website string false Website URL. Maximum length allowed is 1,000


characters.

hoursOfOperation string false Hours of operation as text, following the Open Street
Map specification . Maximum length allowed is 1,000
characters.

pointElement
The pointElement is a class feature that defines a point feature in a unit, such as a first
aid kit or a sprinkler head.

Geometry Type: MultiPoint

Property Type Required Description

originalId string false When the dataset is created through the conversion
service, the original ID is automatically set to the Azure
Maps internal ID. Maximum length allowed is 1,000
characters.

externalId string false An ID used by the client to associate the feature with
another feature in a different dataset, such as in an
internal database. Maximum length allowed is 1,000
characters.

categoryId category.Id true The ID of a category feature.


Property Type Required Description

unitId string true The ID of a unit feature containing this feature.


Maximum length allowed is 1,000 characters.

isObstruction boolean false If true , this feature represents an obstruction to be


(Default avoided while routing through the containing unit
value is feature.
null .)

name string false Name of the feature in local language. Maximum


length allowed is 1,000 characters.

nameSubtitle string false Subtitle that shows up under the name of the feature.
Can be used to display the name in a different
language, and so on. Maximum length allowed is
1,000 characters.

nameAlt string false Alternate name used for the feature. Maximum length
allowed is 1,000 characters.

lineElement
The lineElement is a class feature that defines a line feature in a unit, such as a dividing
wall or window.

Geometry Type: LinearMultiString

Property Type Required Description

originalId string false When the dataset is created through the


conversion service, the original ID is automatically
set to the Azure Maps internal ID. Maximum
length allowed is 1,000 characters.

externalId string false An ID used by the client to associate the feature


with another feature in a different dataset, such as
in an internal database. Maximum length allowed
is 1,000 characters.

categoryId category.Id true The ID of a category feature.

unitId unitId true The ID of a unit feature containing this feature.

isObstruction boolean false If true , this feature represents an obstruction to


(Default be avoided while routing through the containing
value is unit feature.
null .)
Property Type Required Description

name string false Name of the feature in local language. Maximum


length allowed is 1,000 characters.

nameSubtitle string false Subtitle that shows up under the name of the
feature. Can be used to display the name in a
different language, and so on. Maximum length
allowed is 1,000 characters.

nameAlt string false Alternate name used for the feature. Maximum
length allowed is 1,000 characters.

anchorPoint Point false GeoJSON Point geometry that represents the


feature as a point. Can be used to position the
label of the feature.

obstructionArea Polygon or false A simplified geometry (when the line geometry is


MultiPolygon complicated) of the feature that is to be avoided
during routing. Requires isObstruction set to
true.

areaElement
The areaElement is a class feature that defines a polygon feature in a unit, such as an
area open to below, an obstruction like an island in a unit.

Geometry Type: MultiPolygon

Property Type Required Description

originalId string false When the dataset is created through the


conversion service, the original ID is automatically
set to the Azure Maps internal ID. Maximum
length allowed is 1,000 characters.

externalId string false An ID used by the client to associate the feature


with another feature in a different dataset, such as
in an internal database. Maximum length allowed
is 1,000 characters.

categoryId category.Id true The ID of a category feature.

unitId unitId true The ID of a unit feature containing this feature.

isObstruction boolean false If true , this feature represents an obstruction to


be avoided while routing through the containing
unit feature.
Property Type Required Description

obstructionArea Polygon or false A simplified geometry (when the line geometry is


MultiPolygon complicated) of the feature that is to be avoided
during routing. Requires isObstruction set to
true.

name string false Name of the feature in local language. Maximum


length allowed is 1,000 characters.

nameSubtitle string false Subtitle that shows up under the name of the
feature. Can be used to display the name in a
different language, and so on. Maximum length
allowed is 1,000 characters.

nameAlt string false Alternate name used for the feature. Maximum
length allowed is 1,000 characters.

anchorPoint Point false GeoJSON Point geometry that represents the


feature as a point. Can be used to position the
label of the feature.

category
The category class feature defines category names. For example: "room.conference".

Geometry Type: None

Property Type Required Description

originalId string false The category's original ID derived from client


data. Maximum length allowed is 1,000
characters.

externalId string false An ID used by the client to associate the category


with another category in a different dataset, such
as in an internal database. Maximum length
allowed is 1,000 characters.

name string true Name of the category. Suggested to use "." to


represent hierarchy of categories. For example:
"room.conference", "room.privateoffice".
Maximum length allowed is 1,000 characters.

routeThroughBehavior boolean false Determines whether a feature can be used for


through traffic.
Property Type Required Description

isRoutable boolean false Determines if a feature should be part of the


(Default routing graph. If set to true , the unit can be used
value is as source/destination or intermediate node in the
null .) routing experience.

Next steps
Learn more about Creator for indoor maps by reading:

Creator for indoor maps


Using the Azure Maps Drawing Error
Visualizer with Creator
Article • 09/25/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

The Drawing Error Visualizer is a stand-alone web application that displays Drawing
package warnings and errors detected during the conversion process. The Error
Visualizer web application consists of a static page that you can use without connecting
to the internet. You can use the Error Visualizer to fix errors and warnings in accordance
with Drawing package requirements. The Azure Maps Conversion API returns a response
with a link to the Error Visualizer only when an error is detected.

Prerequisites
An Azure Maps account
A subscription key
A Creator resource

This tutorial uses the Postman application, but you can choose a different API
development environment.

Download
1. Follow the steps outlined in the How to create data registry article to upload the
drawing package into your Azure storage account then register it in your Azure
Maps account.

) Important

Make sure to make a note of the unique identifier ( udid ) value, you will need
it. The udid is how you reference the drawing package you uploaded into
your Azure storage account from your source code and HTTP requests.

2. Now that the drawing package is uploaded, use udid for the uploaded package to
convert the package into map data.

7 Note

If your conversion process succeeds, you will not receive a link to the Error
Visualizer tool.

3. Under the response Headers tab in the Postman application, look for the
diagnosticPackageLocation property, returned by the Conversion API. The

response should appear like the following JSON:

JSON

{
"operationId": "77dc9262-d3b8-4e32-b65d-74d785b53504",
"created": "2020-04-22T19:39:54.9518496+00:00",
"status": "Failed",
"properties": {
"diagnosticPackageLocation":
"https://us.atlas.microsoft.com/mapData/ce61c3c1-faa8-75b7-349f-
d863f6523748?api-version=2.0"
}
}

4. Download the Drawing Package Error Visualizer by making a HTTP-GET request on


the diagnosticPackageLocation URL.

Setup
The downloaded zipped package from the diagnosticPackageLocation link contains the
following two files.

VisualizationTool.zip: Contains the source code, media, and web page for the
Drawing Error Visualizer.
ConversionWarningsAndErrors.json: Contains a formatted list of warnings, errors,
and other details that are used by the Drawing Error Visualizer.

Unzip the VisualizationTool.zip folder. It contains the following items:

assets folder: contains images and media files


static folder: source code
index.html file: the web application.

Open the index.html file using any of the following browsers, with the respective version
number. You can use a different version, if the version offers equally compatible
behavior as the listed version.

Microsoft Edge 80
Safari 13
Chrome 80
Firefox 74

Using the Drawing Error Visualizer tool


After launching the Drawing Error Visualizer tool, you'll be presented with the upload
page. The upload page contains a drag and drop box. The drag & drop box also
functions as button that launches a File Explorer dialog.

The ConversionWarningsAndErrors.json file has been placed at the root of the


downloaded directory. To load the ConversionWarningsAndErrors.json, drag & drop the
file onto the box. Or, select on the box, find the file in the File Explorer dialogue , and
upload the file.
The ConversionWarningsAndErrors.json contains a list of your drawing package errors
and warnings. To view detailed information about an error or warning, select the Details
link. An intractable section appears below the list. You can now navigate to each error to
learn more details on how to resolve the error.

Next steps
Learn more by reading:
Creator for indoor maps

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Drawing conversion errors and warnings
Article • 04/13/2023

The Azure Maps Conversion service lets you convert uploaded drawing packages into
map data. Drawing packages must adhere to the Drawing package requirements. If one
or more requirements aren't met, then the Conversion service returns errors or
warnings. This article lists the conversion error and warning codes, with
recommendations on how to resolve them. It also provides some examples of drawings
that can cause the Conversion service to return these codes.

The Conversion service succeeds if there are any conversion warnings. However, it's
recommended that you review and resolve all warnings. A warning means part of the
conversion was ignored or automatically fixed. Failing to resolve the warnings could
result in errors in latter processes.

General Warnings

geometryWarning

Description for geometryWarning


A geometryWarning occurs when the drawing contains an invalid entity. An invalid
entity is an entity that doesn't conform to geometric constraints. Examples of an invalid
entity are a self-intersecting polygon or an open PolyLine in a layer that only supports
closed geometry.

The Conversion service is unable to create a map feature from an invalid entity and
instead ignores it.

Examples for geometryWarning


The following two images show examples of self-intersecting polygons.
The following image shows an open PolyLine. Assume that the layer only supports
closed geometry.
How to fix geometryWarning
Inspect the geometryWarning for each entity to verify that it follows geometric
constraints.

unexpectedGeometryInLayer

Description for unexpectedGeometryInLayer

An unexpectedGeometryInLayer warning occurs when the drawing contains geometry


that is incompatible with the expected geometry type for a given layer. When the
Conversion service returns an unexpectedGeometryInLayer warning, it ignores that
geometry.

Example for unexpectedGeometryInLayer


The following image shows an open PolyLine. Assume that the layer only supports
closed geometry.
How to fix unexpectedGeometryInLayer
Inspect each unexpectedGeometryInLayer warning and move the incompatible
geometry to a compatible layer. If it isn't compatible with any of the other layers, it
should be removed.

unsupportedFeatureRepresentation

Description for unsupportedFeatureRepresentation


The unsupportedFeatureRepresentation warning occurs when the drawing contains an
unsupported entity type.

Example for unsupportedFeatureRepresentation

The following image shows an unsupported entity type as a multi-line text object on a
label layer.
How to fix unsupportedFeatureRepresentation
Ensure that your DWG files contain only the supported entity types. Supported types are
listed under the Drawing files requirements section in the drawing package
requirements article.

automaticRepairPerformed

Description for automaticRepairPerformed


The automaticRepairPerformed warning occurs when the Conversion service
automatically repairs invalid geometry.

Examples for automaticRepairPerformed

The following image shows how the Conversion service repaired a self-intersecting
polygon into valid geometry.
The following image shows the Conversion service snapping the first and last
vertex of an open PolyLine to create a closed PolyLine, where the first and last
vertex were less than 1 mm apart.

The following image shows how, in a layer that supports only closed PolyLines, the
Conversion service repaired multiple open PolyLines. To avoid discarding the open
PolyLines, the service combined them into a single closed PolyLine.
How to fix automaticRepairPerformed
To fix an automaticRepairPerformed warning, take the following actions:

1. Inspect each warning's geometry and the specific warning text.


2. Determine if the automated repair is correct.
3. If the repair is correct, continue. Otherwise, go to the design file and resolve the
warning manually.

 Tip

To suppress a warning in the future, make changes to the original drawing so that
the original drawing matches the repaired drawing.

Manifest warnings

redundantAttribution

Description for redundantAttribution

The redundantAttribution warning occurs when the manifest contains redundant or


conflicting object properties.

Examples for redundantAttribution


The following JSON example contains two or more unitProperties objects with
the same name .

JSON

"unitProperties": [
{
"unitName": "L1-100",
"categoryName": "room.office"
},
{
"unitName": "L1-101",
"categoryName": "room.office"
},
{
"unitName": "L1-101",
"categoryName": "room.office"
}
]

In the following JSON snippet, two or more zoneProperties objects have the same
name .

JSON

"zoneProperties": [
{
"zoneName": "Assembly Area 1",
"categoryName": "zone.assembly"
},
{
"zoneName": "Assembly Area 2",
"categoryName": "zone.assembly"
},
{
"zoneName": "Assembly Area 2",
"categoryName": "zone.assembly"
}

How to fix redundantAttribution


To fix a *redundantAttribution warning, remove redundant or conflicting object
properties.

manifestWarning
Description for manifestWarning
A manifestWarning occurs when the manifest contains unitProperties or zoneProperties
objects that are unused during conversion.

Examples for manifestWarning


The manifest contains a unitProperties object with a unitName that has no
matching label in a unitLabel layer.

The manifest contains a zoneProperties object with a zoneName that has no


matching label in a zoneLabel layer.

How to fix manifestWarning

To fix a manifestWarning, remove the unused unitProperties or zoneProperties object


from the manifest, or add a unit/zone label to the drawing so that the properties object
is used during conversion.

Wall warnings

wallOutsideLevel

Description for wallOutsideLevel

The wallOutsideLevel warning occurs when the drawing contains a Wall geometry
outside the bounds of a level outline.

Example for wallOutsideLevel


The following image shows an interior wall, in red, outside the yellow level
boundary.
The following image shows an exterior wall, in red, outside the yellow level
boundary.

How to fix wallOutsideLevel

To fix a wallOutsideLevel warning, expand the level geometry to include all walls. Or,
modify wall boundaries to fit inside the level boundary.

Unit warnings

unitOutsideLevel
Description for unitOutsideLevel
A unitOutsideLevel warning occurs when the drawing contains unit geometry outside
the bounds of the level outline.

Example for unitOutsideLevel


In the following image, unit geometry, in red, exceeds the bounds of the yellow level
boundary.

How to fix unitOutsideLevel


To fix a unitOutsideLevel warning, expand the level boundary to include all units. Or,
modify unit geometry to fit inside the level boundary.

partiallyOverlappingUnit

Description for partiallyOverlappingUnit

A partiallyOverlappingUnit warning occurs when the drawing contains a unit geometry


partially overlapping on another unit geometry. The Conversion service discards
overlapping units.

Example scenarios partiallyOverlappingUnit


In the following image, the overlapping unit is highlighted in red. UNIT110 and HALLWAY
are discarded.
How to fix partiallyOverlappingUnit
To fix a partiallyOverlappingUnit warning, redraw each partially overlapping unit so that
it doesn't overlap any other units.

Door warnings

doorOutsideLevel

Description for doorOutsideLevel


A doorOutsideLevel warning occurs when the drawing contains a door geometry
outside the bounds of the level geometry.

Example for doorOutsideLevel

In the following image, the door geometry, highlighted in red, overlaps the yellow level
boundary.
How to fix doorOutsideLevel
To fix a doorOutsideLevel warning, redraw your door geometry so that it's inside the
level boundaries.

Zone warnings

zoneWarning

Description for zoneWarning


The zoneWarning occurs when a zone doesn't contain a label. The Conversion service
discards a zone that isn't label.l

Example for zoneWarning

The following image shows a zone that doesn't contain a label.


How to fix zoneWarning
To fix a zoneWarning, verify that each zone has a single label.

Label Warnings

labelWarning

Description for labelWarning


The labelWarning occurs when the drawing contains ambiguous or contradictory labels
feature.

A labelWarning occurs because of one or more of the following reasons:

A unit label isn't in any units.


A zone label isn't in any zones.
A zone label is inside two or more zones.

Example for labelWarning


The following image shows a label that inside two zones.
How to fix labelWarning
To fix a labelWarning, ensure that:

All unit labels are inside units.


All zone labels are inside zones.
All zone labels are in one and only one zone.

Drawing Package errors

invalidArchiveFormat

Description for invalidArchiveFormat


An invalidArchiveFormat error occurs when the drawing package is in an invalid archive
format such as GZIP or 7-Zip. Only the ZIP archive format is supported.

An invalidArchiveFormat error also occurs if the ZIP archive is empty.

How to fix invalidArchiveFormat


To fix an invalidArchiveFormat error, verify that:

Your archive file name ends in .zip.


Your ZIP archive contains data.
You can open your ZIP archive.
invalidUserData

Description for invalidUserData


An invalidUserData error occurs when the Conversion service is unable to read a user
data object from storage.

Example scenario for invalidUserData


You attempted to upload a drawing package with an incorrect udid parameter.

How to fix invalidUserData


To fix an invalidUserData error, verify that:

You've provided a correct udid for the uploaded package.


Azure Maps Creator has been enabled for the Azure Maps account you used for
uploading the drawing package.
The API request to the Conversion service contains the subscription key to the
Azure Maps account you used for uploading the drawing package.

dwgError

Description for dwgError

A dwgError when the drawing package contains an issue with one or more DWG files in
the uploaded ZIP archive.

The dwgError occurs when the drawing package contains a DWG file that can't be
opened because it's invalid or corrupt.

A DWG file isn't a valid AutoCAD DWG file format drawing.


A DWG file is corrupt.
A DWG file is listed in the manifest.json file, but it's missing from the ZIP archive.

How to fix dwgError

To fix a dwgError, inspect your manifest.json file confirm that:

All DWG files in your ZIP archive are valid AutoCAD DWG format drawings, open
each one in AutoCAD. Remove or fix all invalid drawings.
The list of DWG files in the manifest.json matches the DWG files in the ZIP archive.

Manifest errors

invalidJsonFormat

Description for invalidJsonFormat


An invalidJsonFormat error occurs when the manifest.json file can't be read.

The _manifest.json_file can't be read because of JSON formatting or syntax errors. To


learn more about how JSON format and syntax, see The JavaScript Object Notation
(JSON) Data Interchange Format .

How to fix invalidJsonFormat


To fix an invalidJsonFormat error, use a JSON linter to detect and resolve any JSON
errors.

missingRequiredField

Description for missingRequiredField

A missingRequiredField error occurs when the manifest.json file is missing required


data.

How to fix missingRequiredField


To fix a missingRequiredField error, verify that the manifest contains all required
properties. For a full list of required manifest object, see the manifest section in the
Drawing package requirements.

missingManifest

Description for missingManifest

The missingManifest error occurs when the manifest.json file is missing from the ZIP
archive.
The missingManifest error occurs because of one or more of the following reasons:

The manifest.json file is misspelled.


The manifest.json is missing.
The manifest.json isn't inside the root directory of the ZIP archive.

How to fix missingManifest

To fix a missingManifest error, confirm that the archive has a file named manifest.json at
the root level of the ZIP archive.

conflict

Description for conflict


The conflict error occurs when the manifest.json file contains conflicting information.

Example scenario for conflict


The Conversion service returns a conflict error when more than one level is defined with
the same level ordinal. The following JSON snippet shows two levels defined with the
same ordinal.

JSON

"buildingLevels":
{
"levels": [
{
"levelName": "Ground",
"ordinal": 0,
"filename": "./Level_0.dwg"
},
{
"levelName": "Parking",
"ordinal": 0,
"filename": "./Level_P.dwg"
}
]
}

How to fix conflict


To fix a conflict error, inspect your manifest.json and remove any conflicting information.
invalidGeoreference

Description for invalidGeoreference


The invalidGeoreference error occurs when a manifest.json file contains an invalid
georeference.

The invalidGeoreference error occurs because of one or more of the following reasons:

The user is georeferencing a latitude or longitude value that is out of range.


The user is georeferencing a rotation value that is out of range.

Example scenario for invalidGeoreference

In the following JSON snippet, the latitude is above the upper limit.

JSON

"georeference"
{
"lat": 88.0,
"lon": -122.132600,
"angle": 0
},

How to fix invalidGeoreference

To fix an invalidGeoreference error, verify that the georeferenced values are within
range.

) Important

In GeoJSON, the coordinates order is longitude and latitude. If you don't use the
correct order, you may accidentally refer a latitude or longitude value that is out of
range.

Wall errors

wallErrors
Description for wallError
The wallError occurs when the drawing contains an error while attempting to create a
wall feature.

Example scenario for wallError


The following image displays a wall feature that doesn't overlap any units.

How to fix wallError

To fix a wallError error, redraw the wall so that it overlaps at least one unit. Or, create a
new unit that overlaps the wall.

Vertical Penetration errors

verticalPenetrationError

Description for verticalPenetrationError

The verticalPenetrationError occurs when the drawing contains an ambiguous vertical


penetration feature.

The verticalPenetrationError occurs because of one or more of the following reasons:

The drawing contains a vertical penetration area with no overlapping vertical


penetration areas on any levels above or below it.
The drawing package contains a level with two or more vertical penetration
features on it that both overlap a single vertical penetration feature on another
level directly above or below it.

Example scenario for verticalPenetrationError


The following image shows a vertical penetration area with no overlapping vertical
penetration areas on levels above or below it.

The following image shows a vertical penetration area that overlaps more than one
vertical penetration area on an adjacent level.

How to fix verticalPenetrationError


To fix a verticalPenetrationError error, read about how to use a vertical penetration
feature in the Drawing package requirements article.

Next steps
How to use Azure Maps Drawing error visualizer
Drawing Package Guide

Creator for indoor mapping


Consumption model
Article • 04/04/2023

The Routing service provides a set of parameters for a detailed description of the
vehicle-specific Consumption Model. Depending on the value of vehicleEngineType,
two principal Consumption Models are supported: Combustion and Electric. It's incorrect
to specify parameters that belong to different models in the same request. Also,
Consumption Model parameters can't be used with the following travelMode values:
bicycle and pedestrian.

Parameter constraints for consumption model


In both Consumption Models, there are some dependencies when specifying
parameters. Meaning that, explicitly specifying some parameters may require specifying
some other parameters. Here are these dependencies to be aware of:

All parameters require constantSpeedConsumption to be specified by the user. It's


an error to specify any other consumption model parameter, if
constantSpeedConsumption isn't specified. The vehicleWeight parameter is an
exception for this requirement.
accelerationEfficiency and decelerationEfficiency must always be specified as a
pair (that is, both or none).
If accelerationEfficiency and decelerationEfficiency are specified, product of their
values must not be greater than 1 (to prevent perpetual motion).
uphillEfficiency and downhillEfficiency must always be specified as a pair (that's,
both or none).
If uphillEfficiency and downhillEfficiency are specified, product of their values
must not be greater than 1 (to prevent perpetual motion).
If the *Efficiency parameters are specified by the user, then vehicleWeight must
also be specified. When vehicleEngineType is combustion,
fuelEnergyDensityInMJoulesPerLiter must be specified as well.
maxChargeInkWh and currentChargeInkWh must always be specified as a pair
(that is, both or none).

7 Note

If only constantSpeedConsumption is specified, no other consumption aspects like


slopes and vehicle acceleration are taken into account for consumption
computations.
Combustion consumption model
The Combustion Consumption Model is used when vehicleEngineType is set to
combustion. The following list of parameters belong to this model. Refer to the
Parameters section for detailed description.

constantSpeedConsumptionInLitersPerHundredkm
vehicleWeight
currentFuelInLiters
auxiliaryPowerInLitersPerHour
fuelEnergyDensityInMJoulesPerLiter
accelerationEfficiency
decelerationEfficiency
uphillEfficiency
downhillEfficiency

Electric consumption model


The Electric Consumption Model is used when vehicleEngineType is set to electric. The
following list of parameters belong to this model. Refer to the Parameters section for
detailed description.

constantSpeedConsumptionInkWhPerHundredkm
vehicleWeight
currentChargeInkWh
maxChargeInkWh
auxiliaryPowerInkW
accelerationEfficiency
decelerationEfficiency
uphillEfficiency
downhillEfficiency

Sensible values of consumption parameters


A particular set of consumption parameters can be rejected, even though the set might
fulfill all the explicit requirements. It happens when the value of a specific parameter, or
a combination of values of several parameters, is considered to lead to unreasonable
magnitudes of consumption values. If that happens, it most likely indicates an input
error, as proper care is taken to accommodate all sensible values of consumption
parameters. In case a particular set of consumption parameters is rejected, the
accompanying error message contains a textual explanation of the reason(s). The
detailed descriptions of the parameters have examples of sensible values for both
models.
Extended GeoJSON geometries
Article • 04/13/2023

Azure Maps provides a list of powerful APIs to search inside and along geographical
features. These APIs adhere to the standard GeoJSON spec of representing
geographical features.

The GeoJSON spec supports only the following geometries:

GeometryCollection
LineString
MultiLineString
MultiPoint
MultiPolygon
Point
Polygon

Some Azure Maps APIs accept geometries that aren't part of the GeoJSON spec . For
instance, the Search Inside Geometry API accepts Circle and Polygons.

This article provides a detailed explanation on how Azure Maps extends the GeoJSON
spec to represent certain geometries.

Circle
The GeoJSON spec doesn't support the Circle geometry. The GeoJSON Point Feature
object is used to represent a circle.

A Circle geometry represented using the GeoJSON Feature object must contain the
following coordinates and properties:

Coordinate Property

Center The circle's center is represented using a GeoJSON Point object.

Radius The circle's radius is represented using GeoJSON Feature 's properties. The radius
value is in meters and must be of the type double .

SubType The circle geometry must also contain the subType property. This property must be
a part of the GeoJSON Feature 's properties and its value should be Circle

Circle example
Here's how you represent a circle using a GeoJSON Feature object. Let's center the circle
at latitude: 47.639754 and longitude: -122.126986, and assign it a radius equal to 100
meters:

JSON

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.126986, 47.639754]
},
"properties": {
"subType": "Circle",
"radius": 100
}
}

Rectangle
The GeoJSON spec doesn't support the Rectangle geometry. The GeoJSON Polygon
Feature object is used to represent a rectangle. The rectangle extension is primarily
used by the Web SDK's drawing tools module.

A Rectangle geometry represented using the GeoJSON Polygon Feature object must
contain the following coordinates and properties:

Coordinate Property

Corners The rectangle's corners are represented using the coordinates of a GeoJSON Polygon
object. There should be five coordinates, one for each corner. And, a fifth
coordinate that is the same as the first coordinate, to close the polygon ring. It's
assumed that these coordinates align, and that the developer may rotate them as
wanted.

SubType The rectangle geometry must also contain the subType property. This property
must be a part of the GeoJSON Feature 's properties, and its value should be
Rectangle.

Rectangle example
JSON

{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[[5,25],[14,25],[14,29],[5,29],[5,25]]]
},
"properties": {
"subType": "Rectangle"
}
}

Next steps
Learn more about GeoJSON data in Azure Maps:

Geofence GeoJSON format

Review the glossary of common technical terms associated with Azure Maps and
location intelligence applications:

Azure Maps glossary


Geofencing GeoJSON data
Article • 04/13/2023

The Azure Maps GET Geofence and POST Geofence API allow you to retrieve proximity
of a coordinate relative to a provided geofence or set of fences. This article details how
to prepare the geofence data that can be used in the Azure Maps GET and POST API.

The data for geofence or set of geofences, represented by the Feature Object and
FeatureCollection Object in GeoJSON format, is defined in rfc7946 . In Addition to it:

The GeoJSON Object type can be a Feature Object or a FeatureCollection Object.


The Geometry Object type can be a Point , MultiPoint , LineString ,
MultiLineString , Polygon , MultiPolygon , and GeometryCollection .
All feature properties should contain a geometryId , which is used for identifying
the geofence.
Feature with Point , MultiPoint , LineString , MultiLineString must contain
radius in properties. radius value is measured in meters, the radius value ranges

from 1 to 10000.
Feature with polygon and multipolygon geometry type doesn't have a radius
property.
validityTime is an optional property that lets the user set expired time and validity
time period for the geofence data. If not specified, the data never expires and is
always valid.
The expiredTime is the expiration date and time of geofencing data. If the value of
userTime in the request is later than this value, the corresponding geofence data is

considered as expired data and isn't queried. Upon which, the geometryId of this
geofence data is included in expiredGeofenceGeometryId array within the geofence
response.
The validityPeriod is a list of validity time period of the geofence. If the value of
userTime in the request falls outside of the validity period, the corresponding

geofence data is considered as invalid and isn't queried. The geometryId of this
geofence data is included in invalidPeriodGeofenceGeometryId array within
geofence response. The following table shows the properties of validityPeriod
element.

Name Type Required Description

startTime Datetime true The start date time of the validity time period.

endTime Datetime true The end date time of the validity time period.
Name Type Required Description

recurrenceType string false The recurrence type of the period. The value can be
Daily , Weekly , Monthly , or Yearly . Default value is
Daily .

businessDayOnly Boolean false Indicate whether the data is only valid during business
days. Default value is false .

All coordinate values are represented as [longitude, latitude] defined in WGS84 .


For each Feature, which contains MultiPoint , MultiLineString , MultiPolygon , or
GeometryCollection , the properties are applied to all the elements. for example: All

the points in MultiPoint use the same radius to form a multiple circle geofence.
In point-circle scenario, a circle geometry can be represented using a Point
geometry object with properties elaborated in Extending GeoJSON geometries.

Following is a sample request body for a geofence represented as a circle geofence


geometry in GeoJSON using a center point and a radius. The valid period of the geofence
data starts from 2018-10-22 , 9AM to 5PM, repeated every day except for the weekend.
expiredTime indicates this geofence data is considered expired, if userTime in the

request is later than 2019-01-01 .

JSON

{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.126986, 47.639754]
},
"properties": {
"geometryId" : "1",
"subType": "Circle",
"radius": 500,
"validityTime":
{
"expiredTime": "2019-01-01T00:00:00",
"validityPeriod": [
{
"startTime": "2018-10-22T09:00:00",
"endTime": "2018-10-22T17:00:00",
"recurrenceType": "Daily",
"recurrenceFrequency": 1,
"businessDayOnly": true
}
]
}
}
}
Azure Maps supported categories
Article • 12/07/2021

When doing a category search for points of interest, there are over a hundred
supported categories. Below is a list of the category codes for supported category
names. Category codes are generated for top-level categories. All sub categories share
same category code. This category list is subject to change with new data releases.

Category code Categories matching code

ACCESS_GATEWAY airline access, security gate, station access, access


gateway

ADMINISTRATIVE_DIVISION province, fourth-order administrative division, first-


order administrative division, historical third-order
administrative division, seat of a fourth-order
administrative division, seat of a second-order
administrative division, dependent political entity,
populated place, seat of a third-order administrative
division, populated places, second-order
administrative division, seat of a first-order
administrative division, administrative division,
populated locality, historical region, historical site,
historical populated place, Israeli settlement, historical
fourth-order administrative division, fifth-order
administrative division, historical first-order
administrative division, third-order administrative
division, historical political entity, historical
administrative division, seat of government of a
political entity, historical second-order administrative
division, capital/major city of a political entity

ADVENTURE_SPORTS_VENUE adventure sports venue

AGRICULTURE horticulture, primary producer, agriculture, farm, farm


village, farmstead, homestead, grazing area, common,
aquaculture facility, farms, fishing area, dairy, field(s)

AIRPORT private authority, military authority, heliport, closed,


medium airport, large airport, small airport, airfield,
seaplane base, public authority, balloon port, airport

AMUSEMENT_PARK amusement arcade, amusement place, amusement


park
Category code Categories matching code

AUTOMOTIVE_DEALER atv/snowmobile, boat, bus, motorcycle, truck, van,


recreational vehicles, car, automotive dealer

BANK bank, banks, bank(s)

BEACH beach, beaches

BUILDING_POINT building (point)

BUSINESS_PARK business park, industrial area

CAFE_PUB internet café, tea house, cafe, internet cafe, café, coffee
shop, microbrewery/beer garden, pub, café/pub,
cafe/pub

CAMPING_GROUND recreational, caravan site, camping ground

CAR_WASH car wash

CASH_DISPENSER automatic teller machine, cash dispenser

CASINO casino

CINEMA drive-in cinema, cinema

CITY_CENTER neighborhood, administrative area, city center, center

CLUB_ASSOCIATION beach club, hockey club, club association

COLLEGE_UNIVERSITY junior college/community college, college/university,


college, university prep school, university

COMMERCIAL_BUILDING office building, park headquarters, commercial


building

COMMUNITY_CENTER community center


Category code Categories matching code

COMPANY electronics, manufacturing, computer data services,


public health technologies, diversified financials,
animal shelter, airline, equipment rental, service,
mail/package/freight delivery, bus lines, home
appliance repair, cleaning services, oem, tax services,
oil natural gas, legal services, construction,
telecommunications, transport, automobile
manufacturing, chemicals, funeral service mortuaries,
bridge tunnel operations, automobile, mechanical
engineering, services, investment advisors,
advertising/marketing, moving storage, savings
institution, insurance, computer software,
pharmaceuticals, catering, wedding services,
agricultural technology, real estate, taxi, limousine
shuttle service, bus charter rentals, mining, publishing
technologies, cable telephone, import/export
distribution, company, asylum, coal mine(s), estate(s),
brewery, gold mine(s)

COURTHOUSE courthouse

CULTURAL_CENTER cultural center

DENTIST dentist

DEPARTMENT_STORE department store

DOCTOR general practitioner, specialist, doctor

ELECTRIC_VEHICLE_STATION electric vehicle station

EMBASSY embassy

EMERGENCY_MEDICAL_SERVICE emergency medical service

ENTERTAINMENT entertainment

EXCHANGE gold exchange, currency exchange, stock exchange,


exchange

EXHIBITION_CONVENTION_CENTER exhibition convention center

FERRY_TERMINAL ferry, ferry terminal

FIRE_STATION_BRIGADE fire station/brigade

FRONTIER_CROSSING frontier crossing

FUEL_FACILITIES fuel facilities


Category code Categories matching code

GEOGRAPHIC_FEATURE bay, cove, pan, locale, ridge, mineral/hot springs, well,


reservoir, marsh/swamp/vlei, quarry, river crossing,
valley, mountain peak, reef, dune, lagoon, plain/flat,
rapids, cape, plateau, oasis, harbor, cave, rocks,
geographic feature, promontory(-ies), islands,
headland, pier, crater lake, cliff(s), hill, desert, portage,
glacier(s), gully, geyser, coral reef(s), gap, gulf, jetty,
ghat, hole, crater lakes, gas field, islet, crater(s), cove(s),
grassland, gravel area, fracture zone, heath, gorge(s),
island, headwaters, hanging valley, hills, hot spring(s),
furrow, anabranch

GOLF_COURSE golf course

GOVERNMENT_OFFICE order 5 area, order 8 area, order 9 area, order 2 area,


order 7 area, order 3 area, supra national, order 4 area,
order 6 area, government office, diplomatic facility,
united states government establishment, local
government office, customs house, customs post

HEALTH_CARE_SERVICE blood bank, personal service, personal care facility,


ambulance unit, health care service, leprosarium,
sanatorium, hospital, medical center, clinic

HELIPAD_HELICOPTER_LANDING helipad/helicopter landing

HOLIDAY_RENTAL bungalow, cottage, chalet, villa, apartment, holiday


rental

HOSPITAL_POLYCLINIC special, hospital of Chinese medicine, hospital for


women children, general, hospital/polyclinic

HOTEL_MOTEL cabins lodges, bed breakfast guest houses, hotel, rest


camps, motel, resort, hostel, hotel/motel, resthouse,
hammock(s), guest house

ICE_SKATING_RINK ice skating rink

IMPORTANT_TOURIST_ATTRACTION building, observatory, arch, tunnel, statue, tower,


bridge, planetarium, mausoleum/grave, monument,
water hole, natural attraction, important tourist
attraction, promenade, pyramids, pagoda, castle,
palace, hermitage, pyramid, fort, gate, country house,
dam, lighthouse, grave

INDUSTRIAL_BUILDING foundry, fuel depot, industrial building, factory


Category code Categories matching code

LEISURE_CENTER bowling, snooker, pool billiard, flying club, dance


studio school, sauna, solarium massage, leisure center,
spa

LIBRARY library

MANUFACTURING_FACILITY manufacturing facility

MARINA yacht basin, marina

MARKET supermarkets hypermarkets, farmers, public, informal,


market

MEDIA_FACILITY media facility

MILITARY_INSTALLATION military base, coast guard station, military installation,


naval base

MOTORING_ORGANIZATION_OFFICE motoring organization office

MOUNTAIN_PASS mountain pass

MUSEUM museum

NATIVE_RESERVATION native reservation, reservation

NIGHTLIFE bar, karaoke club, jazz club, private club, wine bar,
comedy club, cocktail bar, discotheque, nightlife

NON_GOVERNMENTAL_ORGANIZATION non-governmental organization

OPEN_PARKING_AREA open parking area, parking lot

OTHER locality, free trade zone, traffic circle, unknown

PARKING_GARAGE parking garage

PARK_RECREATION_AREA historic site, lakeshore, seashore, river scenic area,


fishing hunting area, battlefield, winter sport, boat
launching ramp, preserve, forest area, recreation area,
ski resort, cemetery, historical park, parkway, memorial,
fairground, picnic area, wilderness area, park recreation
area, forest(s), fossilized forest, garden(s), wildlife
reserve, nature reserve, forest station, hunting reserve,
forest reserve, park

PETROL_STATION petrol station

PHARMACY pharmacy, dispensary


Category code Categories matching code

PLACE_OF_WORSHIP ashram, synagogue, mosque, gurudwara, church,


temple, place of worship, mission, retreat, temple(s),
religious site, religious center, monastery, convent

POLICE_STATION order 1 area, police station, police post

PORT_WAREHOUSE_FACILITY harbor(s), docking basin, port, port/warehouse facility,


dockyard, dock(s)

POST_OFFICE local, post office

PRIMARY_RESOURCE_UTILITY primary resource/utility, power station, gas-oil


separator plant

PRISON_CORRECTIONAL_FACILITY prison, prison/correctional facility

PUBLIC_AMENITY pedestrian subway, toilet, road rescue, passenger


transport ticket office, public call box, public amenity,
communication center

PUBLIC_TRANSPORT_STOP coach stop, bus stop, taxi stand, tram stop, public
transport stop, metro station, railroad station, bus
station, railroad stop

RAILWAY_STATION national, railway siding, metro, (sub) urban, railway


station

RENT_A_CAR_FACILITY rent-a-car facility

RENT_A_CAR_PARKING rent-a-car-parking

REPAIR_FACILITY bodyshops, tyre (tire) services, repair shops, car glass


replacement shops, general car repair servicing, sale
installation of car accessories, motorcycle repair, truck
repair service, repair facility

RESEARCH_FACILITY research facility

RESIDENTIAL_ACCOMMODATION retirement community, townhouse complex,


flats/apartment complex, condominium complex,
residential estate, residential accommodation
Category code Categories matching code

RESTAURANT German, creole-Cajun, Dutch, banquet rooms, bistro,


Israeli, Slovak, Jamaican, vegetarian, seafood,
Vietnamese, Maltese, Sichuan, welsh, Chinese,
Japanese, Algerian, Californian, fusion, Shandong,
salad bar, Savoy an, Spanish, Ethiopian, Taiwanese,
doughnuts, Iranian, Canadian, American, Norwegian,
French, Hunan, Polynesian, afghan, roadside, Asian,
swiss, erotic, crêperie, Surinamese, Egyptian,
Hungarian, Nepalese, barbecue, hot pot, hamburgers,
Mediterranean, Latin American, tapas, British, Mexican,
Guangdong, Asian (other), buffet, sushi, Mongolian,
international, mussels, Thai, Venezuelan, Rumanian,
chicken, soup, kosher, steak house, yogurt/juice bar,
Italian, Korean, Cypriot, Bosnian, Bolivian, Dominican,
Belgian, Tunisian, Scottish, English, Pakistani, Czech,
Hawaiian, Maghrib, Tibetan, Arabian, middle eastern,
Chilean, Shanghai, polish, Filipino, Sudanese,
Armenian, Burmese, Brazilian, Scandinavian, Bulgarian,
soul food, Colombian, Jewish, pizza, Sicilian, organic,
Greek, Basque, Uruguayan, cafeterias, Finnish, African,
Corsican, Syrian, Caribbean, Dongbei, Russian, grill,
take away, fast food, Australian, Irish, pub food,
fondue, Lebanese, Indonesian, Danish, Provençal,
teppanyaki, Indian, Mauritian, western continental,
Peruvian, Cambodian, snacks, Swedish, macrobiotic, ice
cream parlor, Slavic, Turkish, Argentinean, Austrian,
exotic, Portuguese, Luxembourgian, Moroccan,
sandwich, Cuban, restaurant

RESTAURANT_AREA restaurant area

REST_AREA rest area, halting place

SCENIC_PANORAMIC_VIEW scenic/panoramic view, observation point

SCHOOL culinary school, primary school, art school, senior high


school, driving school, language school, sport school,
preschool, high school, middle school, vocational
training, special school, child care facility, school,
technical school, military school, agricultural school
Category code Categories matching code

SHOP factory outlet, security products, Christmas/holiday


store, opticians, house garden: lighting, lottery shop,
musical instruments, nail salon, house garden: painting
decorating, hobby/free time, newsagents tobacconists,
clothing accessories: specialty, dry cleaners, bags
leatherwear, pet supplies, clothing accessories:
children, construction material equipment, jewelry,
clocks watches, clothing accessories: footwear shoe
repairs, house garden: curtains/textiles, electrical, office
it: consumer electronics, electrical, office it: camera's
photography, cd's, DVD videos, laundry, clothing
accessories: men, florists, pawn shop, book shops,
marine electronic equipment, food drinks: food
markets, house garden: carpet/floor coverings,
photocopy, boating equipment accessories, mobile
phone shop, toys games, specialty foods, clothing
accessories: general, food drinks: bakers, tailor shop,
gifts, cards, novelties souvenirs, animal services, sports
equipment clothing, stamp shop, electrical appliance,
electrical, office it: office equipment, photo
lab/development, wholesale clubs, house garden:
furniture fittings, local specialties, food drinks:
butchers, variety store, food drinks: food shops, food
drinks: wine spirits, drug store, furniture/home
furnishings, electrical, office it: computer supplies,
cd/video rental, medical supplies equipment,
agricultural supplies, beauty salon, house garden:
garden centers services, food drinks: fishmongers,
beauty supplies, clothing accessories: women, travel
agents, retail outlet, recycling shop, house garden:
glass windows, hardware, real estate agents,
glassware/ceramic, delicatessen, house garden:
kitchens bathrooms, betting station, hairdressers
barbers, food drinks: grocers, food drinks: green
grocers, convenience stores, drive through bottle shop,
house garden: do-it-yourself centers, antique/art,
shop, store

SHOPPING_CENTER mall, shopping center

SPORTS_CENTER thematic sport, squash court, fitness club center, sports


center

STADIUM netball, football, baseball, race track, multi-purpose,


motor sport, cricket ground, rugby ground, ice hockey,
athletic, horse racing, basketball, soccer, stadium,
athletic field, racetrack
Category code Categories matching code

SWIMMING_POOL swimming pool

TENNIS_COURT tennis court

THEATER amphitheater, concert hall, dinner theater, music


center, opera, cabaret, theater, opera house

TOURIST_INFORMATION_OFFICE tourist information office

TRAFFIC_LIGHT traffic light

TRAFFIC_SERVICE_CENTER traffic control department, traffic service center

TRAFFIC_SIGN traffic sign

TRAIL_SYSTEM adventure vehicle, rock climbing, horse riding,


mountain bike, hiking, trail system

TRANSPORT_AUTHORITY transport authority/vehicle registration


VEHICLE_REGISTRATION

TRUCK_STOP truck stop

VETERINARIAN veterinary facility, veterinarian

WATER_SPORT water sport

WEIGH_STATION weigh scales, weigh station

WELFARE_ORGANIZATION welfare organization

WINERY winery

ZOOS_ARBORETA_BOTANICAL_GARDEN wildlife park, aquatic zoo marine park, arboreta


botanical gardens, zoo, zoos, arboreta botanical
garden
Azure Maps Rest API
Article • 03/24/2025

Azure Maps is a set of mapping and geospatial services that enable developers and
organizations to build intelligent location-based experiences for applications across
many different industries and use cases. Use Azure Maps to bring maps, geocoding,
location search, routing, real-time traffic, geolocation, time zone information, and
weather data into your web, mobile and server-side solutions.

The following tables show overviews of the services that Azure Maps offers:

Latest release
The most recent stable release of the Azure Maps services.

ノ Expand table

API API Description


version

Data 2023- Programmatically store and update geospatial data to use in spatial
Registry 06-01 operations.
The Data registry service is deprecated and will be retired on 9/30/25.

Geolocation 1.0 Convert IP addresses to country/region ISO codes.

Render 2024- Get road, satellite/aerial, weather, traffic map tiles, and static map
04-01 images.

Route 2025- Calculate optimized travel times and distances between locations for
01-01 multiple modes of transportation and returns localized travel
instructions. Now supports Snap to Roads API that snaps GPS data to
road aligned coordinates.

Search 2025- Geocode addresses and coordinates, search for business listings and
01-01 places by name or category and get administrative boundary polygons.

Spatial 2022- Use geofences, great circle distances, and other spatial operations to
08-01 analyze location data.
The Spatial service is deprecated and will be retired on 9/30/25.

Timezone 1.0 Get time zone and sunrise/sunset information for specified locations.

Traffic 2025- Provides traffic incident data, such as construction, traffic congestion,
01-01 accidents, and more, within a specified bounding box.
API API Description
version

Weather 1.1 Get current, forecasted, and historical weather conditions, air quality,
tropical storm details, and weather along a route.

Previous releases
There are previous stable releases of an Azure Maps service that are still in use. The
services in this list have a more recent version available, and some are slated for
retirement. If using a previous release, update to the latest version before it's retired to
avoid disruption of service.

ノ Expand table

API API Description


version

Render 1.0 Get road, satellite/aerial, weather, traffic map tiles, and static map images.
The Azure Maps Render v1 service is now deprecated and will be retired on
9/17/26. To avoid service disruptions, all calls to Render v1 API need to be
updated to use the latest version of the Render API.

Render 2022- Get road, satellite/aerial, weather, traffic map tiles, and static map images.
08-01

Route 1.0 Calculate optimized travel times and distances between locations for
multiple modes of transportation and get localized travel instructions.

Search 1.0 Geocode addresses and coordinates, search for business listings and places
by name or category and get administrative boundary polygons. This is
version 1.0 of the Search service. For the latest version, see Search.

Search 2023- Geocode addresses and coordinates, search for business listings and places
06-01 by name or category and get administrative boundary polygons.

Traffic 1.0 Get current traffic information including traffic flow and traffic incident
details.

Latest preview
Prerelease version of an Azure Maps service. Preview releases contain new functionality
or updates to existing functionality that will be included in a future release.

ノ Expand table
API API version Description

Route 2024-07-01-preview The Route Range API supports high definition isochrone polygons.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Creator Rest API
Article • 09/24/2024

7 Note

Azure Maps Creator retirement

The Azure Maps Creator indoor map service is now deprecated and will be retired
on 9/30/25. For more information, see End of Life Announcement of Azure Maps
Creator .

Indoor mapping is a technology that enables the creation of digital maps of the interior
of buildings. It helps visitors navigate through buildings and locate points of interest
such as restrooms, conference rooms, and offices. Indoor mapping can be used to
create a more convenient and enjoyable visitor experience. Visitors can spend less time
searching for building directories and more time discovering new points of interest.
With Azure Maps Creator, you can create indoor maps that enable customers to zoom in
and out of a building to see each floor and navigate to any desired location using
Creator's wayfinding service. In addition to common mapping functionality, Azure Maps
Creator offers an array of useful services that enable you to implement functionality
such as asset tracking, facility management, workspace optimization, hybrid work
models to support a blend of in-office, remote, and on-the-go working, and much more.

The following tables offer high-level overviews of the services that Azure Maps Creator
offers:

Latest release
The most recent stable release of the Creator services.

ノ Expand table

API API Description


version

Alias 2.0 This API allows the caller to assign an alias to reference a resource.

Conversion 2.0 Used to import a set of DWG design files as a zipped Drawing
Package into Azure Maps.

Dataset 2.0 A collection containing the indoor map features of a facility. This API
API API Description
version

allows the caller to create a dataset from previously uploaded data.

Feature 2.0 The Feature stateset can be used to dynamically render features in a
State facility according to their current state and respective map style.

Tileset 2.0 A tileset is a collection of vector tiles that render on the map, created
from an existing dataset.

WFS 2.0 Use the Web Feature Service (WFS) API to query for all feature
collections or a specific collection within a dataset. For example, you can
use WFS to find all mid-size meeting rooms in a specific building and
floor level.

Latest preview
Pre-release version of a Creator service. Preview releases contain new functionality or
updates to existing functionality that will be included in a future release.

ノ Expand table

API API Description


version

Alias 2023-03- This API allows the caller to assign an alias to reference a resource.
01-preview

Conversion 2023-03- Used to import a set of DWG design files as a zipped Drawing
01-preview Package into Azure Maps.

Dataset 2023-03- A collection of indoor map features in a facility. This API allows the
01-preview caller to create a dataset from previously uploaded data.

Feature State 2023-03- The Feature stateset can be used to dynamically render features in
01-preview a facility according to their current state and respective map style.

Features 2023-03- An instance of an object produced from the Conversion service


01-preview that combines a geometry with metadata information.

Map 2023-03- Map Configuration in indoor mapping refers to the default


Configuration 01-preview settings of a map that are applied when the map is loaded. It
includes the default zoom level, center point, and other map
settings.

Routeset 2023-03- Use the routeset API to create the data that the wayfinding service
01-preview needs to generate paths.
API API Description
version

Style 2023-03- Use the Style API to customize your facility's look and feel.
01-preview Everything is configurable from the color of a feature, the icon
that renders, or the zoom level when a feature should appear or
disappear.

Tileset 2023-03- A collection of vector tiles that render on the map, created from
01-preview an existing dataset.

Wayfinding 2023-03- Wayfinding is a technology that helps people navigate through


01-preview complex indoor environments such as malls, offices, stadiums,
airports and office buildings.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Maps Management API
Article • 03/05/2024

Azure Maps is a set of mapping and geospatial services that enable developers and
organizations to build intelligent location-based experiences for applications across
many different industries and use cases. Use the Azure Maps REST APIs and Web SDK to
bring maps, geocoding, location search, routing, real-time traffic, geolocation, time zone
information, weather data, and custom indoor maps (Creator) into your web and mobile
solutions.
azure-maps-control package

Classes
ノ Expand table

Compass A control for changing the rotation of the map.


Control

ControlBase Implements control interface and provides support for automatic styling based on the map
style.

Fullscreen A control to make the map or a specified element fullscreen.


Control

Pitch A control for changing the pitch of the map.


Control

Scale A control to display a scale bar on the map.


Control

Style A control for changing the style of the map.


Control

Traffic A control to display the traffic information of the map.


Control

Traffic A control that display traffic legend on the map.


Legend
Control

Zoom A control for changing the zoom of the map.


Control

Bounding A GeoJSON BoundingBox object - an array that defines a shape whose edges follow lines
Box of constant longitude, latitude, and elevation. All axes of the most southwesterly point are
followed by all axes of the more northeasterly point. The axes order of the BoundingBox
follows the axes order of geometries. The full description is detailed in RFC 7946 .

Feature A GeoJSON Feature object - a JSON object representing a spatially bounded entity. The full
description is detailed in RFC 7946 .

Feature A GeoJSON FeatureCollection object - a JSON object that contains a collection of GeoJSON
Collection features. The full description is detailed in RFC 7946 .

Geometry A GeoJSON GeometryCollection object - a JSON object that contains a collection of a


Collection GeoJSON Geometry objects. The full description is detailed in RFC 7946 .

LineString A GeoJSON LineString object - a JSON object that represents a geographic curve. The full
description is detailed in RFC 7946 .

Mercator A MercatorPoint object represents a projected three dimensional position. MercatorPoint


Point uses the web mercator projection (EPSG:3857 ) with slightly different units:

the size of 1 unit is the width of the projected world instead of the "mercator meter"
the origin of the coordinate space is at the north-west corner instead of the middle.

For example, MercatorPoint(0, 0, 0) is the north-west corner of the mercator world and
MercatorPoint(1, 1, 0) is the south-east corner. If you are familiar with vector tiles it
may be helpful to think of the coordinate space as the 0/0/0 tile with an extent of 1 .

The z dimension of MercatorPoint is conformal. A cube in the mercator coordinate space


would be rendered as a cube.

MultiLine A GeoJSON MultiLineString object - a JSON object that represents multiple geographic
String curves. The full description is detailed in RFC 7946 .

MultiPoint A GeoJSON MultiPoint object - a JSON object that represents multiple geographic
positions. The full description is detailed in RFC 7946 .

Multi A GeoJSON MultiPolygon object - a JSON object that represents multiple geographic
Polygon polygons. The full description is detailed in RFC 7946 .

Point A GeoJSON Point object - a JSON object that represents a geographic position. The full
description is detailed in RFC 7946 .

Polygon A GeoJSON Polygon object - a JSON object that represents a geographic polygon. The full
description is detailed in RFC 7946 .

Position A GeoJSON Position object - an array that specifies the longitude and latitude of a location.
The full description is detailed in RFC 7946 .

Event A manager for the map control's events. Exposed through the events property of the
Manager atlas.Map class. Cannot be instantiated by the user.

HtmlMarker This class wraps an HTML element that can be displayed on the map.

Event An internal abstract class that can be extended to provide event listening/firing. This class
Emitter is for internal use only, and users will find little use with it. Not to be used by the Map class.
MapCallbackHandler implements the more complex logic for handling map events.

Bubble Renders Point objects as scalable circles (bubbles).


Layer

HeatMap Represent the density of data using different colors (HeatMap).


Layer

ImageLayer Overlays an image on the map with each corner anchored to a coordinate on the map. Also
known as a ground or image overlay.

Layer Abstract class for other layer classes to extend.


LineLayer Renders line data on the map. Can be used with SimpleLine, SimplePolygon, CirclePolygon,
LineString, MultiLineString, Polygon, and MultiPolygon objects.

Polygon Renders extruded filled Polygon and MultiPolygon objects on the map.
Extrusion
Layer

Polygon Renders filled Polygon and MultiPolygon objects on the map.


Layer

Symbol Renders point based data as symbols on the map using text and/or icons. Symbols can also
Layer be created for line and polygon data as well.

TileLayer Renders raster tiled images on top of the map tiles.

Web Enables custom rendering logic with access to the WebGL context of the map.
GLLayer

Map The control for a visual and interactive web map.

Affine An Affine Transform class generated from a set of reference points.


Transform

Pixel Represent a pixel coordinate or offset. Extends an array of [x, y].

Popup An information window anchored at a specified position on a map.

Popup A layout template for a popup.


Template

Shape A helper class that wraps a Geometry or Feature and makes it easy to update and maintain.

DataSource A data source class that makes it easy to manage shapes data that will be displayed on the
map. A data source must be added to a layer before it is visible on the map. The
DataSource class may be used with the SymbolLayer, LineLayer, PolygonLayer, BubbleLayer,
and HeatMapLayer.

Elevation Elevation tile source describes how to access elevation (raster DEM) tile data. It can then be
TileSource used to enable map elevation via map.enableElevation(elevationSource)

Source A base abstract class in which all other source objects extend. A source must be added to a
layer before it is visible on the map.

VectorTile A vector tile source describes how to access a vector tile layer. Vector tile sources can be
Source used with; SymbolLayer, LineLayer, PolygonLayer, BubbleLayer, HeatmapLayer and
VectorTileLayer.

Interfaces
ノ Expand table

Aggregate An aggregate expression defines a calculation that is processed over a set of data.
Expression Schema: [operator: string, initialValue?: boolean | number, mapExpression: Expression]
operator: An expression function that is then applied to against all values calculated by
the mapExpression for each point in the cluster. Supported operators: o For numbers:
+ , * , max , min o For Booleans: all , any initialValue: Optional, an initial value in which
the first calculated value is aggregated against. mapExpression: An expression that is
applied against each point in the data set.

Animation The options for animating changes to the map control's camera.
Options

Authentication A manager for the map control's authentication. Exposed through the authentication
Manager property of the atlas.Map class. Cannot be instantiated by the user.

Authentication Options for specifying how the map control should authenticate with the Azure Maps
Options services.

BorderedMap The style of the bordered map element.


ElementStyles

BubbleLayer Options used when rendering Point objects in a BubbleLayer.


Options

CameraBounds The options for setting the bounds of the map control's camera.
Options

CameraOptions The options for setting the map control's camera.

Clustered The properties which will exist for ClusteredProperties


Properties

CompassControl The options for a CompassControl object.


Options

StyleControl The events supported by the StyleControl .


Events

Control An interface for defining a control of the map.

ControlManager A manager for the map control's controls. Exposed through the controls property of
the atlas.Map class. Cannot be instantiated by the user.

ControlOptions The options for adding a control to the map.

DataSource A data source for managing shape data that will be displayed on the map. A data
Options source must be added to a layer before it is visible on the map. Options for a
DataSourceOptions .

ElevationTileSourceOptions
Fullscreen The options for a FullscreenControl object.
ControlOptions

HeatMapLayer Options used when rendering Point objects in a HeatMapLayer.


Options

HtmlMarkerEvents

HtmlMarker A manager for the map control's HTML markers. Exposed through the markers
Manager property of the atlas.Map class. Cannot be instantiated by the user.

HtmlMarker Options for rendering an HtmlMarker object


Options

HyperLink Format option for hyperlink strings.


FormatOptions

IconOptions Options used to customize the icons in a SymbolLayer

ImageLayer Options used when rendering Point objects in a ImageLayer.


Options

ImageSprite A manager for the map control's image sprite. Exposed through the imageSprite
Manager property of the atlas.Map class. Cannot be instantiated by the user.

EventArgs

LayerEvents

LayerManager A manager for the map control's layers. Exposed through the layers property of the
atlas.Map class. Cannot be instantiated by the user.

LayerOptions A base class which all other layer options inherit from.

LightOptions The options for the map's lighting.

LineLayer Options used when rendering SimpleLine, SimplePolygon, CirclePolygon, LineString,


Options MultiLineString, Polygon, and MultiPolygon objects in a line layer.

Map Represents the contents of map configuration holding a list of styles available to them.
Configuration

Map Represents the info for a single style.


Configuration
Style

MapDataEvent Event object returned by the maps when a data event occurs.

MapElement The style of the map element.​


Styles

MapErrorEvent Event object returned by the maps when an error event occurs.
MapEvent Event object returned by the maps when a basic event occurs.

MapMouse Event object returned by the maps when a mouse event occurs.
Event

MapMouse Event object returned by the maps when a wheel event occurs.
WheelEvent

MapTouchEvent Event object returned by the maps when a touch event occurs.

MediaLayer Options used when rendering canvas, image, raster tile, and video layers
Options

Options

Padding Represent the amount of padding in pixels to add to the side of a BoundingBox when
setting the camera of a map.

PitchControl The options for a PitchControl object.


Options

Polygon Options used when rendering Polygon and MultiPolygon objects in a


ExtrusionLayer PolygonExtrusionLayer .
Options

PolygonLayer Options used when rendering Polygon and MultiPolygon objects in a PolygonLayer.
Options

PopupEvents

PopupManager A manager for the map control's popups. Exposed through the popups property of the
atlas.Map class. Cannot be instantiated by the user.

PopupOptions The options for a popup.

Properties A set of properties that can be used with a PopupTemplate

PropertyInfo Species details of how a property is to be displayed.

RasterTileSourceOptions

Request This is the object type expected to be returned by the transformRequest callback.
Parameters

ScaleControl The options for a ScaleControl object.


Options

ServiceOptions Global properties used in all atlas service requests.

ShapeEvents

DataSourceEvents
SourceEvents

SourceManager A manager for the map control's sources. Exposed through the sources property of the
atlas.Map class. Cannot be instantiated by the user.

StyleChanged Event object returned by the map after loading a new style.
Event

StyleControl The options for a StyleControl object.


Options

StyleOptions The options for the map's style.

StyleOverrides Override the default styles for the map elements.​

SymbolLayer Options used when rendering geometries in a SymbolLayer.


Options

TargetedEvent

TextOptions Options used to customize the text in a SymbolLayer

Tile Tile object returned by the map when a source data event occurs.

TileId

TileLayer Options used when rendering raster tiled images in a TileLayer.


Options

TrafficControlOptions

TrafficOptions The options for setting traffic on the map.

UserInteraction The options for enabling/disabling user interaction with the map.
Options

VectorTile A data source for managing shape data that will be displayed on the map. A data
SourceOptions source must be added to a layer before it is visible on the map. Options for a
VectorTileSource .

WebGLLayer Options used to render graphics in a WebGLLayer.


Options

WebGLRenderer Interface for rendering WebGL graphics in a WebGLLayer.

ZoomControl The options for a ZoomControl object.


Options

Type Aliases
ノ Expand table

Geometry A base Geometry object in which all geometry shapes extend; Point, LineString, Polygon,
MultiPoint, MultiLineString, MultiPolygon, GeometryCollection

Expression Can be specified as the value of filter or certain layer options. An expression defines a
formula for computing the value of the property. Expressions are represented as JSON
arrays. The first element of an expression is a string naming the expression operator.

getAuth The callback function used to acquire an authentication token in anonymous


Token authentication mode. Resolve with the authentication token or reject with any errors.
Callback

ResourceType

StyleImage Signature for the options parameter passed to ImageSpriteManager.add .


Metadata

Position

PositionAnchor

Enums
ノ Expand table

AuthenticationType An enumeration used to specify the type of authentication mechanism to use.

ControlPosition Positions where the control can be placed on the map.

ControlStyle Available styles for a Control.

AccelerationUnits Units of measurement for acceleration.

AreaUnits Units of measurement for areas.

DistanceUnits Units of measurement for distances.

SpeedUnits Units of measurement for speed.

TimeUnits Units of measurement for time.


azure-maps-drawing-tools package

Classes
ノ Expand table

Drawing A control for changing the drawing mode.


Toolbar

Drawing The drawing manager is the primary class that manages all the drawing functionality on
Manager the map. It can be used directly (programmatically or with custom toolbars) or in
combination with the drawing toolbar control.

SnapGrid Manages a pixel based grid for snapping positions at integer based zoom levels.
Manager

Interfaces
ノ Expand table

Event This interface partially defines the map control's EventManager . This definition only includes
Manager the method added by using the drawing tools. For the base definition see:
https://docs.microsoft.com/javascript/api/azure-maps-control/atlas.eventmanager?
view=azure-maps-typescript-latest

Drawing The events supported by the DrawingManager


Manager
Events

SnapGrid Options for the SnapGridManager.


Manager
Options

Drawing A collection of the layers used by the drawing manager for rendering shapes.
Layers

Drawing Options for the drawing manager.


Manager
Options

Drawing Options for the DrawingToolbar control.


Toolbar
Options
Enums
ノ Expand table

Drawing An enumeration of the available drawing interaction types. The drawing interaction
InteractionType type specifies how certain drawing modes behave.

DrawingMode An enumeration of the available drawing modes.


azure-maps-rest package
Azure Maps Web SDK Service Module service retirement. The Azure Maps Web SDK Service
Module is now deprecated and will be retired on 9/30/26. To avoid service disruptions, we
recommend migrating to use Azure Maps JavaScript REST SDK by 9/30/26. Please follow our
instructions to migrate to Azure Maps JavaScript REST SDK.

Classes
ノ Expand table

Aborter An aborter instance implements AbortSignal interface, can abort HTTP requests.

Call Aborter.none to create a new Aborter instance without timeout.


Call Aborter.timeout() to create a new Aborter instance with timeout.

For an existing instance aborter:

Call aborter.withTimeout() to create and return a child Aborter instance with


timeout.
Call aborter.withValue(key, value) to create and return a child Aborter instance
with key/value pair.
Call aborter.abort() to abort current instance and all children instances.
Call aborter.getValue(key) to search and get value with corresponding key from
current aborter to all parents.

CarShare A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

ClosestPoint A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

Credential Credential is an abstract class for Azure Maps HTTP requests signing. This class will
host an credentialPolicyCreator factory which generates CredentialPolicy.

CredentialPolicy Credential policy used to sign HTTP(S) requests before sending. This is an abstract
class.

Geofence A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

LoggingPolicy LoggingPolicyFactory is a factory class helping generating LoggingPolicy objects.


Factory

MapControl MapControlCredential for sharing authentication with an atlas.Map instance.


Credential
MapControl MapControlCredentialPolicy is a policy used to sign HTTP requests with shared
CredentialPolicy authentication from an atlas.Map instance.

MapsURL A MapsURL represents a base URL class for SearchURL, RouteURL and etc.

MetroArea A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

NearbyTransit A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

Pipeline A Pipeline class containing HTTP request policies. You can create a default Pipeline by
calling MapsURL.newPipeline(). Or you can create a Pipeline with your own policies by
the constructor of Pipeline. Refer to MapsURL.newPipeline() and provided policies as
reference before implementing your customized Pipeline.

PointInPolygon A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

RealTime A helper extension providing methods for accessing the response data in GeoJSON
ArrivalsGeojson format.

RenderURL A RenderURL represents a URL to the Azure Maps render operations.

RetryPolicy RetryPolicyFactory is a factory class helping generating RetryPolicy objects.


Factory

RouteGeojson A helper extension providing methods for accessing the response data in GeoJSON
format.

RouteRange A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

RouteURL A RouteURL represents a URL to the Azure Maps route operations.

SasCredential SasCredential is a Credential used to generate a SasCredentialPolicy. Renew token by


setting a new token string value to token property.

Example

const sasCredential = new SasCredential("token"); const pipeline =


MapsURL.newPipeline(sasCredential);

const searchURL = new SearchURL(pipeline);

// Set up a timer to refresh the token const timerID = setInterval(() => { // Update
token by accessing to public sasCredential.token sasCredential.token =
"updatedToken"; // WARNING: Timer must be manually stopped! It will forbid GC of
sasCredential if (shouldStop()) { clearInterval(timerID); } }, 60 * 60 * 1000); // Set an
interval time before your token expired
SasCredential SasCredentialPolicy is a policy used to sign HTTP request with a token. Such as an JWT
Policy SAS token.

SearchGeojson A helper extension providing methods for accessing the response data in GeoJSON
format.

SearchPolygon A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

SearchReverse A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

SearchURL A SearchURL represents a URL to the Azure Maps search operations.

SpatialURL A SpatialURL represents a URL to the Azure Maps spatial operations.

SubscriptionKey SubscriptionKeyCredential for account key authorization of Azure Maps service.


Credential

SubscriptionKey SubscriptionKeyCredentialPolicy is a policy used to sign HTTP requests with a


CredentialPolicy subscription key.

TimezoneURL A TimezoneURL represents a URL to the Azure Maps timezone operations.

TokenCredential TokenCredential is a Credential used to generate a TokenCredentialPolicy. Renew token


by setting a new token string value to token property.

Example

const tokenCredential = new TokenCredential("clientId", "token"); const pipeline =


MapsURL.newPipeline(tokenCredential);

const searchURL = new SearchURL(pipeline);

// Set up a timer to refresh the token const timerID = setInterval(() => { // Update
token by accessing to public tokenCredential.token tokenCredential.token =
"updatedToken"; // WARNING: Timer must be manually stopped! It will forbid GC of
tokenCredential if (shouldStop()) { clearInterval(timerID); } }, 60 * 60 * 1000); // Set an
interval time before your token expired

TokenCredential TokenCredentialPolicy is a policy used to sign HTTP request with a token. Such as an
Policy OAuth bearer token.

TransitDock A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

TransitItinerary A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

TransitLine A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.
TransitStop A helper extension providing methods for accessing the response data in GeoJSON
Geojson format.

Interfaces
ノ Expand table

AuthenticationManager

Map This interface partially defines the Azure Map's web control. Web control version
2.0 or later must be used. For a full definition see https://docs.microsoft.com/en-
us/javascript/api/azure-maps-control/atlas.map?view=azure-iot-typescript-latest

RequestParameters

IBaseGeojson The base interface for a geojson helper extension.

INewPipelineOptions Option interface for MapsURL.newPipeline method.

IPipelineOptions Option interface for Pipeline constructor.

IRequestLogOptions IRequestLogOptions configures the retry policy's behavior.

IRetryOptions Retry options interface.

Agency Details of the agency.

Alert Basic information associated with the active alert.

AlertDescription An interface representing AlertDescription.

AlertDetail A list of alert details.

BatchRequestBody This type represents the request body for the Batch service.

BatchRequestBody Batch Query object


BatchItemsItem

BatchResponse This object is returned from a successful Batch service call

BatchResponse Summary for the batch request


Summary

BufferRequestBody An object with a FeatureCollection and a list of distances. All the feature's
properties should contain geometryId , which is used for identifying the geometry
and is case-sensitive.

BufferResponse This object is returned from a successful Spatial Buffer call.


BufferResponse Summary of the call.
Summary

CarShareResponse Details of the car share vehicle. Name is always returned. Level of other returned
details depends on car share operator.

ClosestPointResult Closest Point Result Entry Object


Entry

Coordinate A location represented as a latitude and longitude.

Coordinate A location represented as a latitude and longitude.


Abbreviated

CopyrightBounding This object is returned from a successful Copyright Bounding call


Result

CopyrightCaption This object is returned from a successful Copyright Caption call


Result

CopyrightTileResult This object is returned from a successful Copyright Tile call

CopyrightWorldResult This object is returned from a successful Copyright World call

Country A country record.

DataSources Optional section. Reference ids for use with the Get Search Polygon API.

DataSources Information about the geometric shape of the result. Only present if type ==
Geometry Geography.

Direction The walking directions guidance.

ErrorModel This object is returned when an error occurs in the Maps API

ErrorResponse This response object is returned when an error occurs in the Maps API

GeofenceGeometry The geofencing geometry.

GeofenceResponse This object is returned from a geofence proximity call.

GeoJSONFeature A valid GeoJSON FeatureCollection object type. Please refer to RFC 7946 for
Collection details.

GeoJSONFeature A valid GeoJSON Feature object type. Please refer to RFC 7946 for details.
CollectionFeatures
Item

GeoJSONGeometry A valid GeoJSON geometry object. Please refer to RFC 7946 for details.

GeoJSONGeometry A valid GeoJSON GeometryCollection object type. Please refer to RFC 7946 for
Collection details.
GetClosestPoint This object is returned from a successful Get Spatial Closest Point call
Response

GetClosestPoint Get Closest Point Summary object


Summary

GetPointInPolygon Returns true if point is within the polygon, false otherwise


Response

GetPointInPolygon Point In Polygon Summary object


Summary

GreatCircleDistance This object is returned from a successful Great Circle Distance call
Response

GreatCircleDistance Result Object


ResponseResult

GreatCircleDistance Summary object


ResponseSummary

IanaId An interface representing IanaId.

ItineraryResult An interface representing ItineraryResult.

Leg An interface representing Leg.

LegPoint An interface representing LegPoint.

Line A stop line

LineArrival An interface representing LineArrival.

LineGroup A line group

LineString A valid GeoJSON LineString geometry type. Please refer to RFC 7946 for
details.

MapsClientOptions An interface representing MapsClientOptions.

MetroAreaInfo This object is returned from a successful Metro Area call.


Response

MetroAreaResponse This object is returned from a successful Get Metro Area call

MetroAreaResult Details of the metro area.

MobilityGetCarShare Optional Parameters.


InfoPreviewOptional
Params

MobilityGetMetro Optional Parameters.


AreaInfoPreview
OptionalParams

MobilityGetMetro Optional Parameters.


AreaPreviewOptional
Params

MobilityGetNearby Optional Parameters.


TransitPreview
OptionalParams

MobilityGetRealTime Optional Parameters.


ArrivalsPreview
OptionalParams

MobilityGetTransit Optional Parameters.


DockInfoPreview
OptionalParams

MobilityGetTransit Optional Parameters.


ItineraryPreview
OptionalParams

MobilityGetTransit Optional Parameters.


LineInfoPreview
OptionalParams

MobilityGetTransit Optional Parameters.


RoutePreview
OptionalParams

MobilityGetTransit Optional Parameters.


StopInfoPreview
OptionalParams

MultiLineString A valid GeoJSON MultiLineString geometry type. Please refer to RFC 7946 for
details.

MultiPoint A valid GeoJSON MultiPoint geometry type. Please refer to RFC 7946 for
details.

MultiPolygon A valid GeoJSON MultiPolygon object type. Please refer to RFC 7946 for details.

Names Timezone names object.

NearbyTransit This object is returned from a successful Get Nearby Transit call
Response

OperatorInfo Contains information about the operator. Apart form Id and name, all other fields
are optional and nor always returned.

Pattern Stop-shape-segments of the trip pattern, which are an ordered list of the stops
and the shapes connecting them.
Point A valid GeoJSON Point geometry type. Please refer to RFC 7946 for details.

PointInPolygonResult Point In Polygon Result Object

Polygon A valid GeoJSON Polygon geometry type. Please refer to RFC 7946 for details.

PostClosestPoint This object is returned from a successful Post Spatial Closest Point call
Response

PostClosestPoint Post Closest Point Summary object


Summary

PostPointInPolygon Returns true if point is within the polygon, false otherwise


Response

PostPointInPolygon Point In Polygon Summary object


Summary

Pricing Pricing details including currency, reservation price and usage price.

RealTimeArrivalResult Contains real-time arrival related details.

RealTimeArrivals This object is returned from a successful Get Real Time Arrival Info call.
Response

ReferenceTime Details in effect at the local time.


ByCoordinates

ReferenceTimeById Details in effect at the local time.

Region An interface representing Region.

RegionCountry Country property

RenderGetCopyright Optional Parameters.


ForTileOptional
Params

RenderGetCopyright Optional Parameters.


ForWorldOptional
Params

RenderGetCopyright Optional Parameters.


FromBoundingBox
OptionalParams

RenderGetMapImage Optional Parameters.


OptionalParams

RenderGetMapTile Optional Parameters.


OptionalParams
RepresentativePoint Representative point property

ResultViewport The viewport that covers the result represented by the top-left and bottom-right
coordinates of the viewport.

RouteBeginPostRoute Optional Parameters.


MatrixPreview
OptionalParams

RouteDirections Post body parameters for Route directions.


RequestBody

RouteDirections A GeoJSON Geometry collection representing sequence of coordinates used as


RequestBody input for route reconstruction
SupportingPoints

RouteDirections This object is returned from a successful Route Directions call


Response

RouteDirectionsResult An interface representing RouteDirectionsResult.

RouteDirections Summary object


Summary

RouteGetRoute Optional Parameters.


DirectionsOptional
Params

RouteGetRouteRange Optional Parameters.


OptionalParams

RouteItineraryLeg An interface representing RouteItineraryLeg.

RouteMatrixRequest An object with a matrix of coordinates.


Body

RouteMatrixResponse This object is returned from a successful Route Matrix call. For ex, if 2 origins and
3 destinations are provided, there are going to 2 arrays with 3 elements in each.
Each element's content depends on the options provided in the query.

RouteMatrixResult Matrix result object

RouteMatrixResult Response object of the current cell in the input matrix.


Response

RouteMatrixSummary Summary object

RouteOptimized Optimized way point object.


Waypoint

RoutePostRoute Defines headers for PostRouteDirectionsBatchPreview operation.


DirectionsBatch
PreviewHeaders

RoutePostRoute Optional Parameters.


DirectionsOptional
Params

RoutePostRoute Defines headers for PostRouteMatrixPreview operation.


MatrixPreview
Headers

RoutePostRoute Optional Parameters.


MatrixPreview
OptionalParams

RouteRange Reachable Range

RouteRangeResponse This object is returned from a successful Route Reachable Range call

RouteResponseReport Reports the effective settings used in the current call.

RouteResponseReport Effective parameter or data used when calling this Route API.
EffectiveSetting

RouteResultGuidance Contains guidance related elements. This field is present only when guidance
was requested and is available.

RouteResult A set of attributes describing a maneuver, e.g. 'Turn right', 'Keep left', 'Take the
Instruction ferry', 'Take the motorway', 'Arrive'.

RouteResult Groups a sequence of instruction elements which are related to each other. The
InstructionGroup sequence range is constrained with firstInstructionIndex and lastInstructionIndex.
When human-readable text messages are requested for guidance
(instructionType=text or tagged), then the instructionGroup has a summary
message returned when available.

RouteResultLeg An interface representing RouteResultLeg.

RouteResultLeg Summary object for route section.


Summary

RouteResultSection An interface representing RouteResultSection.

RouteResultSection Details of the traffic event, using definitions in the TPEG2-TEC standard. Can
Tec contain <effectCode> and <causes> elements.

RouteResultSection The cause of the traffic event. Can contain <mainCauseCode> and
TecCause <subCauseCode> elements. Can be used to define iconography and
descriptions.

SearchAddress This object is returned from a successful Search Address call


Response
SearchAddressResult An interface representing SearchAddressResult.

SearchAddress This object is returned from a successful Search Address Reverse CrossStreet call
ReverseCrossStreet
Response

SearchAddress An interface representing SearchAddressReverseCrossStreetResult.


ReverseCrossStreet
Result

SearchAddress Summary object for a Search Address Reverse Cross Street response
ReverseCrossStreet
Summary

SearchAddress This object is returned from a successful Search Address Reverse call
ReverseResponse

SearchAddress An interface representing SearchAddressReverseResult.


ReverseResult

SearchAddress Summary object for a Search Address Reverse response


ReverseSummary

SearchAddress This object is returned from a successful Search Address Structured call
StructuredResponse

SearchAddress An interface representing SearchAddressStructuredResult.


StructuredResult

SearchAddress Summary object for a Search Address Structured response


StructuredSummary

SearchAddress Summary object for a Search Address response


Summary

SearchAlongRoute This type represents the request body for the Search Along Route service.
RequestBody

SearchAlongRoute This object is returned from a successful Search Along Route call.
Response

SearchAlongRoute This type represents the Search Along Route result object.
Result

SearchAlongRoute Summary object for a Search Along Route response


Summary

SearchFuzzyResponse This object is returned from a successful Search Fuzzy call

SearchFuzzyResult An interface representing SearchFuzzyResult.

SearchFuzzySummary Summary object for a Search Fuzzy response


SearchGeometry This object is returned from a successful Search By Geometry call
Response

SearchGeometry This type represents the Search Inside Geometry result object.
Result

SearchGeometry Summary object for a Search Geometry response


Summary

SearchGetSearch Optional Parameters.


AddressOptional
Params

SearchGetSearch Optional Parameters.


AddressReverseCross
StreetOptionalParams

SearchGetSearch Optional Parameters.


AddressReverse
OptionalParams

SearchGetSearch Optional Parameters.


AddressStructured
OptionalParams

SearchGetSearch Optional Parameters.


FuzzyOptionalParams

SearchGetSearch Optional Parameters.


NearbyOptional
Params

SearchGetSearch Optional Parameters.


POICategoryOptional
Params

SearchGetSearch Optional Parameters.


POIOptionalParams

SearchInside This type represents the request body for the Search Inside Geometry service.
GeometryRequest
Body

SearchNearby This object is returned from a successful Search Nearby call


Response

SearchNearbyResult An interface representing SearchNearbyResult.

SearchNearby Summary object for a Search Nearby response


Summary
SearchPoiCategory This object is returned from a successful Search POI Category call
Response

SearchPoiCategory An interface representing SearchPoiCategoryResult.


Result

SearchPoiCategory Summary object for a Search POI Category response


Summary

SearchPoiResponse This object is returned from a successful Search POI call

SearchPoiResult An interface representing SearchPoiResult.

SearchPoiSummary Summary object for a Search POI response

SearchPolygon This object is returned from a successful Search Polygon call


Response

SearchPolygonResult An interface representing SearchPolygonResult.

SearchPostSearch Defines headers for PostSearchAddressBatchPreview operation.


AddressBatchPreview
Headers

SearchPostSearch Defines headers for PostSearchAddressReverseBatchPreview operation.


AddressReverseBatch
PreviewHeaders

SearchPostSearch Optional Parameters.


AlongRouteOptional
Params

SearchPostSearch Defines headers for PostSearchFuzzyBatchPreview operation.


FuzzyBatchPreview
Headers

SearchPostSearch Optional Parameters.


InsideGeometry
OptionalParams

SearchResultAddress The address of the result

SearchResultAddress Describes the address range on both sides of the street for a search result.
Ranges Coordinates for the start and end locations of the address range are included.

SearchResultEntry The entry point for the POI being returned.


Point

SearchResultPoi Details of the poi including the name, phone, url, and categories.

SearchResultPoiBrand The name of the brand for the POI being returned
SearchResultPoi The classification for the POI being returned
Classification

SearchResultPoi Name for the classification


ClassificationName

SearchResultViewport The viewport that covers the result represented by the top-left and bottom-right
coordinates of the viewport.

SearchSummaryGeo Indication when the internal search engine has applied a geospatial bias to
Bias improve the ranking of results. In some methods, this can be affected by setting
the lat and lon parameters where available. In other cases it is purely internal.

SpatialCoordinate A location represented as a latitude and longitude

SpatialGetClosest Optional Parameters.


PointOptionalParams

SpatialGetGeofence Defines headers for GetGeofence operation.


Headers

SpatialGetGeofence Optional Parameters.


OptionalParams

SpatialPostClosest Optional Parameters.


PointOptionalParams

SpatialPostGeofence Defines headers for PostGeofence operation.


Headers

SpatialPostGeofence Optional Parameters.


OptionalParams

Step An interface representing Step.

Stop The stop's basic info

TimeTransition An interface representing TimeTransition.

TimeZone An interface representing TimeZoneByCoordinates.


ByCoordinates

Timezone This object is returned from a successful Timezone By Coordinates call


ByCoordinatesResult

TimezoneById An interface representing TimezoneById.

TimezoneByIdResult This object is returned from a successful Timezone By ID call

TimezoneEnum An interface representing TimezoneEnumWindow.


Window
TimezoneGet Optional Parameters.
Timezone
ByCoordinates
OptionalParams

TimezoneGet Optional Parameters.


Timezone
ByIDOptionalParams

TimezoneGet Optional Parameters.


TimezoneWindows
ToIANAOptional
Params

TimezoneIanaVersion This object is returned from a successful Timezone IANA Version call
Result

TransitDockInfo This object is returned from a successful Transit Dock Info call.
Response

TransitItinerary This object is returned from a successful Get Transit Itinerary call
Response

TransitLineInfo This object is returned from a successful Transit Line Info call.
Response

TransitObjectResult An interface representing TransitObjectResult.

TransitRouteResponse This object is returned from a successful Get Transit Stop Info call

TransitStopInfo This object is returned from a successful Get Transit Stop Info call
Response

TransitTypeResult An interface representing TransitTypeResult.

UploadDataAccepted The response model for the spatial data upload API. Returns the current status
Response and a status URI.

UploadDataResponse The response model for the spatial data upload API. Returns a unique data id
(udid) for the uploaded content.

Type Aliases
ノ Expand table

BaseRequestPolicy

CalculateRouteDirectionsOptions
CalculateRouteDirectionsResponse

CalculateRouteMatrixOptions

CalculateRouteMatrixRequestBody

CalculateRouteMatrixResponse

CalculateRouteRangeOptions

CalculateRouteRangeResponse

CredentialPolicyCreator A factory function that creates a new CredentialPolicy that uses the
provided nextPolicy.

GetBufferResponse

GetCarShareInfoOptions

GetCarShareInfoResponse

GetClosesPointResponse

GetClosestPointOptions

GetGeofenceOptions

GetGeofenceResponse

GetGreatCircleDistance

GetMapImageOptions

GetMapImageResponse

GetMapImageryTileResponse

GetMapTileOptions

GetMapTileResponse

GetMetroAreaInfoOptions

GetMetroAreaInfoResponse

GetMetroAreaOptions

GetMetroAreaResponse

GetNearbyTransitOptions

GetNearbyTransitResponse

GetPointInPolygonResponse
GetRealTimeArrivalsOptions

GetRealTimeArrivalsResponse

GetTimezoneByCoordinatesOptions

GetTimezoneByCoordinatesResponse

GetTimezoneByIdOptions

GetTimezoneByIdResponse

GetTransitDockInfoOptions

GetTransitDockInfoResponse

GetTransitItineraryOptions

GetTransitItineraryResponse

GetTransitLineInfoOptions

GetTransitLineInfoResponse

GetTransitRouteOptions

GetTransitRouteResponse

GetTransitStopInfoOptions

GetTransitStopInfoResponse

HttpHeaders

HttpOperationResponse

HttpPipelineLogLevel

IHttpClient

IHttpPipelineLogger

Merge

GeoJSONGeometryUnion Contains the possible cases for GeoJSONGeometry.

MobilityGetCarShareInfo Contains response data for the getCarShareInfoPreview operation.


PreviewResponse

MobilityGetMetroAreaInfo Contains response data for the getMetroAreaInfoPreview operation.


PreviewResponse

MobilityGetMetroArea Contains response data for the getMetroAreaPreview operation.


PreviewResponse

MobilityGetNearbyTransit Contains response data for the getNearbyTransitPreview operation.


PreviewResponse

MobilityGetRealTimeArrivals Contains response data for the getRealTimeArrivalsPreview operation.


PreviewResponse

MobilityGetTransitDockInfo Contains response data for the getTransitDockInfoPreview operation.


PreviewResponse

MobilityGetTransitItinerary Contains response data for the getTransitItineraryPreview operation.


PreviewResponse

MobilityGetTransitLineInfo Contains response data for the getTransitLineInfoPreview operation.


PreviewResponse

MobilityGetTransitRoute Contains response data for the getTransitRoutePreview operation.


PreviewResponse

MobilityGetTransitStopInfo Contains response data for the getTransitStopInfoPreview operation.


PreviewResponse

RenderGetCopyrightCaption Contains response data for the getCopyrightCaption operation.


Response

RenderGetCopyrightForTile Contains response data for the getCopyrightForTile operation.


Response

RenderGetCopyrightFor Contains response data for the getCopyrightForWorld operation.


WorldResponse

RenderGetCopyrightFrom Contains response data for the getCopyrightFromBoundingBox operation.


BoundingBoxResponse

RenderGetMapImage Contains response data for the getMapImage operation.


Response

RenderGetMapImageryTile Contains response data for the getMapImageryTile operation.


Response

RenderGetMapTileResponse Contains response data for the getMapTile operation.

RouteGetRouteDirections Contains response data for the getRouteDirections operation.


Response

RouteGetRouteRange Contains response data for the getRouteRange operation.


Response

RoutePostRouteDirections Contains response data for the postRouteDirectionsBatchPreview


BatchPreviewResponse operation.
RoutePostRouteDirections Contains response data for the postRouteDirections operation.
Response

RoutePostRouteMatrix Contains response data for the postRouteMatrixPreview operation.


PreviewResponse

SearchGetSearchAddress Contains response data for the getSearchAddress operation.


Response

SearchGetSearchAddress Contains response data for the getSearchAddressReverseCrossStreet


ReverseCrossStreetResponse operation.

SearchGetSearchAddress Contains response data for the getSearchAddressReverse operation.


ReverseResponse

SearchGetSearchAddress Contains response data for the getSearchAddressStructured operation.


StructuredResponse

SearchGetSearchFuzzy Contains response data for the getSearchFuzzy operation.


Response

SearchGetSearchNearby Contains response data for the getSearchNearby operation.


Response

SearchGetSearch Contains response data for the getSearchPOICategory operation.


POICategoryResponse

SearchGetSearch Contains response data for the getSearchPOI operation.


POIResponse

SearchGetSearchPolygon Contains response data for the getSearchPolygon operation.


Response

SearchPostSearchAddress Contains response data for the postSearchAddressBatchPreview


BatchPreviewResponse operation.

SearchPostSearchAddress Contains response data for the postSearchAddressReverseBatchPreview


ReverseBatchPreview operation.
Response

SearchPostSearchAlong Contains response data for the postSearchAlongRoute operation.


RouteResponse

SearchPostSearchFuzzyBatch Contains response data for the postSearchFuzzyBatchPreview operation.


PreviewResponse

SearchPostSearchInside Contains response data for the postSearchInsideGeometry operation.


GeometryResponse

SpatialGetBufferResponse Contains response data for the getBuffer operation.


SpatialGetClosestPoint Contains response data for the getClosestPoint operation.
Response

SpatialGetGeofenceResponse Contains response data for the getGeofence operation.

SpatialGetGreatCircle Contains response data for the getGreatCircleDistance operation.


DistanceResponse

SpatialGetPointInPolygon Contains response data for the getPointInPolygon operation.


Response

SpatialPostBufferResponse Contains response data for the postBuffer operation.

SpatialPostClosestPoint Contains response data for the postClosestPoint operation.


Response

SpatialPostGeofence Contains response data for the postGeofence operation.


Response

SpatialPostPointInPolygon Contains response data for the postPointInPolygon operation.


Response

TimezoneGetTimezone Contains response data for the getTimezoneByCoordinates operation.


ByCoordinatesResponse

TimezoneGetTimezone Contains response data for the getTimezoneByID operation.


ByIDResponse

TimezoneGetTimezoneEnum Contains response data for the getTimezoneEnumIANA operation.


IANAResponse

TimezoneGetTimezoneEnum Contains response data for the getTimezoneEnumWindows operation.


WindowsResponse

TimezoneGetTimezone Contains response data for the getTimezoneIANAVersion operation.


IANAVersionResponse

TimezoneGetTimezone Contains response data for the getTimezoneWindowsToIANA operation.


WindowsToIANAResponse

RequestPolicy

RequestPolicyFactory

RequestPolicyOptions

Response A type alias for easily representing a response interface with or without a
geojson helper. Also provides the raw response data in the response
object.

RestError
SearchAddressOptions

SearchAddressResponse

SearchAddressReverseCrossStreetOptions

SearchAddressReverseCrossStreetResponse

SearchAddressReverseOptions

SearchAddressReverseResponse

SearchAddressStructuredOptions

SearchAddressStructuredResponse

SearchAlongRouteOptions

SearchAlongRouteRequestBody

SearchAlongRouteResponse

SearchFuzzyOptions

SearchFuzzyResponse

SearchInsideGeometryOptions

SearchInsideGeometryRequestBody

SearchInsideGeometryResponse

SearchNearbyOptions

SearchNearbyResponse

SearchPOICategoryOptions

SearchPOICategoryResponse

SearchPOIOptions

SearchPOIResponse

SearchPolygonResponse

SpatialFeatureCollection A GeoJSON FeatureCollection whose features each specify a geometryId


in their properties.

UndefinedGeojson

WebResource
Enums
ノ Expand table

Absolute Defines values for AbsoluteDirection. Possible values include: 'north', 'northeast', 'east',
Direction 'southeast', 'south', 'southwest', 'west', 'northwest'

AgencyType Defines values for AgencyType. Possible values include: 'agencyId', 'agencyKey',
'agencyName'

Alternative Defines values for AlternativeRouteType. Possible values include: 'anyRoute',


RouteType 'betterRoute'

Avoid Defines values for Avoid. Possible values include: 'tollRoads', 'motorways', 'ferries',
'unpavedRoads', 'carpools', 'alreadyUsedRoads', 'borderCrossings'

BikeType Defines values for BikeType. Possible values include: 'privateBike', 'dockedBike'

ComputeTravel Defines values for ComputeTravelTimeFor. Possible values include: 'none', 'all'
TimeFor

ConnectorSet Defines values for ConnectorSet. Possible values include:


'StandardHouseholdCountrySpecific', 'IEC62196Type1', 'IEC62196Type1CCS',
'IEC62196Type2CableAttached', 'IEC62196Type2Outlet', 'IEC62196Type2CCS',
'IEC62196Type3', 'Chademo', 'IEC60309AC1PhaseBlue', 'IEC60309DCWhite', 'Tesla'

Destination Defines values for DestinationType. Possible values include: 'position', 'stopId', 'stopKey'
Type

DrivingSide Defines values for DrivingSide. Possible values include: 'LEFT', 'RIGHT'

EntityType Defines values for EntityType. Possible values include: 'Country', 'CountrySubdivision',
'CountrySecondarySubdivision', 'CountryTertiarySubdivision', 'Municipality',
'MunicipalitySubdivision', 'Neighbourhood', 'PostalCodeArea'

GeofenceMode Defines values for GeofenceMode. Possible values include: 'All', 'EnterAndExit'

Guidance Defines values for GuidanceInstructionType. Possible values include: 'TURN',


InstructionType 'ROAD_CHANGE', 'LOCATION_DEPARTURE', 'LOCATION_ARRIVAL', 'DIRECTION_INFO',
'LOCATION_WAYPOINT'

Guidance Defines values for GuidanceManeuver. Possible values include: 'ARRIVE', 'ARRIVE_LEFT',
Maneuver 'ARRIVE_RIGHT', 'DEPART', 'STRAIGHT', 'KEEP_RIGHT', 'BEAR_RIGHT', 'TURN_RIGHT',
'SHARP_RIGHT', 'KEEP_LEFT', 'BEAR_LEFT', 'TURN_LEFT', 'SHARP_LEFT', 'MAKE_UTURN',
'ENTER_MOTORWAY', 'ENTER_FREEWAY', 'ENTER_HIGHWAY', 'TAKE_EXIT',
'MOTORWAY_EXIT_LEFT', 'MOTORWAY_EXIT_RIGHT', 'TAKE_FERRY',
'ROUNDABOUT_CROSS', 'ROUNDABOUT_RIGHT', 'ROUNDABOUT_LEFT',
'ROUNDABOUT_BACK', 'TRY_MAKE_UTURN', 'FOLLOW', 'SWITCH_PARALLEL_ROAD',
'SWITCH_MAIN_ROAD', 'ENTRANCE_RAMP', 'WAYPOINT_LEFT', 'WAYPOINT_RIGHT',
'WAYPOINT_REACHED'
Hilliness Defines values for Hilliness. Possible values include: 'low', 'normal', 'high'

LegType Defines values for LegType. Possible values include: 'Walk', 'Bicycle', 'Tram', 'Subway',
'Rail', 'Bus', 'Ferry', 'Cable', 'Gondola', 'Funicular', 'PathWayWalk', 'Wait', 'WaitOnVehicle'

Magnitude Defines values for MagnitudeOfDelay. Possible values include: '0', '1', '2', '3', '4'
OfDelay

MapTileLayer Defines values for MapTileLayer. Possible values include: 'basic', 'hybrid', 'labels', 'terra'

MapTileStyle Defines values for MapTileStyle. Possible values include: 'main', 'shaded_relief'

MetroArea Defines values for MetroAreaDetailType. Possible values include: 'agencies', 'alerts',
DetailType 'alertDetails', 'transitTypes'

MetroArea Defines values for MetroAreaQueryType. Possible values include: 'position',


QueryType 'countryCode'

ModeType Defines values for ModeType. Possible values include: 'walk', 'bike', 'publicTransit'

ObjectType Defines values for ObjectType. Possible values include: 'stop', 'docklessBike',
'docklessElectricBike', 'docklessElectricScooter', 'docklessScooter', 'docklessMoped',
'carShare', 'docklessVehicle', 'bikeDock'

OpeningHours Defines values for OpeningHours. Possible values include: 'nextSevenDays'

OriginType Defines values for OriginType. Possible values include: 'position', 'stopId', 'stopKey'

RealTime Defines values for RealTimeArrivalsQueryType. Possible values include: 'stops', 'line',
ArrivalsQuery 'lineAndStop', 'position'
Type

Relative Defines values for RelativeDirection. Possible values include: 'depart', 'hardLeft', 'left',
Direction 'slightlyLeft', 'continue', 'slightlyRight', 'right', 'hardRight', 'circleClockwise',
'circleCounterclockwise', 'elevator', 'uturnLeft', 'uturnRight'

Route Defines values for RouteInstructionsType. Possible values include: 'coded', 'text',
Instructions 'tagged'
Type

Route Defines values for RouteRepresentation. Possible values include: 'polyline',


Representation 'summaryOnly', 'none'

RouteType Defines values for RouteType. Possible values include: 'fastest', 'shortest', 'eco', 'thrilling'

ScheduleType Defines values for ScheduleType. Possible values include: 'scheduledTime', 'realTime'

SearchIndexSet Defines values for SearchIndexSet. Possible values include: 'Addr', 'Geo', 'PAD', 'POI',
'Str', 'Xstr'

SectionType Defines values for SectionType. Possible values include: 'carTrain', 'country', 'ferry',
'motorway', 'pedestrian', 'tollRoad', 'tollVignette', 'traffic', 'travelMode', 'tunnel'
StaticMapLayer Defines values for StaticMapLayer. Possible values include: 'basic', 'hybrid', 'labels'

StopQueryType Defines values for StopQueryType. Possible values include: 'stopId', 'stopKey'

Style Defines values for Style. Possible values include: 'main'

Text Defines values for Text. Possible values include: 'yes', 'no'

Text1 Defines values for Text1. Possible values include: 'yes', 'no'

Text2 Defines values for Text2. Possible values include: 'yes', 'no'

TileFormat Defines values for TileFormat. Possible values include: 'png', 'pbf'

TimeType Defines values for TimeType. Possible values include: 'arrival', 'departure', 'last'

Timezone Defines values for TimezoneOptions. Possible values include: 'none', 'zoneInfo',
Options 'transitions', 'all'

TransitItinerary Defines values for TransitItineraryDetailType. Possible values include: 'geometry',


DetailType 'schedule'

TransitLine Defines values for TransitLineDetailType. Possible values include: 'alerts', 'alertDetails',
DetailType 'lines', 'stops', 'schedule', 'patterns'

TransitRoute Defines values for TransitRouteType. Possible values include: 'optimal', 'leastWalk',
Type 'leastTransfers'

TransitStop Defines values for TransitStopDetailType. Possible values include: 'alerts', 'alertDetails',
DetailType 'lines', 'lineGroups'

TransitStop Defines values for TransitStopQueryType. Possible values include: 'stopId', 'stopKey'
QueryType

TransitType Defines values for TransitType. Possible values include: 'Bus', 'CableCar', 'Ferry',
'Funicular', 'Gondola', 'Rail', 'Tram', 'Subway'

TransitType Defines values for TransitTypeFilter. Possible values include: 'bus', 'cableCar', 'ferry',
Filter 'funicular', 'gondola', 'rail', 'tram', 'subway'

TravelMode Defines values for TravelMode. Possible values include: 'car', 'truck', 'taxi', 'bus', 'van',
'motorcycle', 'bicycle', 'pedestrian'

Type Defines values for Type. Possible values include: 'main', 'minor'

VehicleEngine Defines values for VehicleEngineType. Possible values include: 'combustion', 'electric'
Type

VehicleLoad Defines values for VehicleLoadType. Possible values include: 'USHazmatClass1',


Type 'USHazmatClass2', 'USHazmatClass3', 'USHazmatClass4', 'USHazmatClass5',
'USHazmatClass6', 'USHazmatClass7', 'USHazmatClass8', 'USHazmatClass9',
'otherHazmatExplosive', 'otherHazmatGeneral', 'otherHazmatHarmfulToWater'
Windingness Defines values for Windingness. Possible values include: 'low', 'normal', 'high'

RetryPolicyType RetryPolicy types.


azure-maps-spatial-io package

Classes
ノ Expand table

CsvReader A class that reads data from a delimited data set.

CsvWriter A class that writes data as a delimited data set.

GmlReader A static class that reads GML data.

GmlWriter A static class that writes GML data.

SimpleXml A simple and fast xml reader that converts an XML string into a JSON object. Ignores
Reader tags that start with "<!" or "<?" as these are usually comments, XML schema, or doctype
tags. Supports CData tag: <![[CData ]]> Can extract all namespaces in the document.

SimpleXml A simple and fast XML writing class that makes it easy to efficiently build an XML string.
Writer

Add An add operator filter.

And Represents an AND logic operator filter.

Binary Abstract class for binary comparison operator filters.


Comparison
OpType

CustomFilter Represents a custom defined XML Filter string component. Do not wrap with the
<Filter> tag.

Div A divide operator filter.

Filter Abstract filter class in which all other filters inherit from.

Id Represents a filter on the GML id of a shape. Uses ogc:GmlObjectId for version 1.1.0 and
fes:ResourceId for all other versions. Version 1.0.0 typically does not support this filter.

IsBetween Checks to see if a value is between two other specified values.

IsEqual Compares two values to see if they are equal.

IsGreaterThan Checks to see if one value is greater than another.

IsGreaterThan Checks to see if one value is greater than or equal to another.


OrEqual

IsLessThan Checks to see if one value is less than another.


IsLessThan Checks to see if one value is less than or equal to another.
OrEqual

IsLike Checks to see if a value is like another using a wild card search.

IsNil Checks to see if a value is nil.

IsNotEqual Compares two values to see if they are not equal.

IsNull Checks to see if a value is null.

LogicOperator Represents a logic operator filter.


Filter

MathOperator An abstract class in which all math operator filters inherit from.

Mul A multiply operator filter.

Not Represents an NOT logic operator filter.

Or Represents an OR logic operator filter.

PropertyName Property name value.

Sub A subtract operator filter.

WfsClient A class that manages connections to an OGC Web Mapping Feature Service (WFS)

WKT A static class for reading/writing Well Known Text (WKT) strings as GeoJSON geometries.

OgcMapLayer Renders raster tiled images on top of the map tiles from an OGC Web Mapping Service
(WMS or WMTS).

SimpleData A layer that simplifies the rendering of geospatial data on the map. Note: Because this
Layer layer wraps other layers which will be added/removed with this some layer ordering
operations are not supported. Adding this layer before another, adding another layer
before this, and moving this layer are not supported. These restrictions only apply to this
layer and not the layers wrapped by this.

SpatialDataSet A data object that contains a set of features and/or kml ground overlays. This is an
extension of the FeatureCollection class thus allowing it to easily be added to a data
source.

Interfaces
ノ Expand table

BaseSpatial Options used for reading spatial data files.


DataRead
Options
BaseSpatialXml Options that customize how XML files are read and parsed.
ReadOptions

CsvHeader Column header definition for a delimited file.

CustomGml Defines a custom XML namespace.


Namespace

Extended A Feature Collection that has properties for the collection.


Feature
Collection

GmlRead Options that customize how GML files are read and parsed.
Options

GmlWrite Options that are used to customize how to write GML.


Options

GpxRead Options that customize how GPX files are read and parsed.
Options

XmlDocument Represents an XML Document object.

XmlNode Represents an XML Node object.

Binary Options for a binary comparison filter.


Comparison
Options

IsNilOptions Options for an IsNil filter.

LikeOptions Options for a Like filter.

KmlRead Options that customize how KML files are read and parsed.
Options

OgcDimension A custom OGC dimension.

OgcMapLayer An object that describes the capabilities of an OGC WMS and WMTS service.
Capabilities

OgcMapLayer Options for an OGC layer.


Options

OgcStyle OGC WMS and WMTS layer style information.

OgcSublayer Sublayer information for OGC WMS and WMTS services.

SimpleData A collection of sub layers used by the SimpleDataLayer class for rendering shapes.
LayerGroup

SimpleData Options used to customize how the SimpleDataLayer renders.


LayerOptions

SimpleStyle A set of common properties that may be included in feature properties capture style
Properties information and common content when reading or writing a spatial data. The
SimpleDataLayer uses these properties to dynamically style the data it renders. Most of
these are the property values used in the geometries respective layer options.

SpatialCsvRead Options used for reading delimited files.


Options

SpatialCsvWrite Options for writing delimited files.


Options

SpatialDataSet Statistics about the content and processing time of a XML feed.
Stats

SpatialData Base options for writing spatial data.


WriteOptions

SpatialXml Options that are used to customize how to write XML.


WriteOptions

WfsCapabilities The capabilities of a WFS service.

WfsFeature Options for requesting features from a WFS service.


Request

WfsFeature Information about a feature type in a WFS service.


Type

WfsFeature Details about a feature type.


Type
Description

WfsService Options for connecting to a WFS service.


Options

Type Aliases
ノ Expand table

Literal A literal value type. string, number, boolean, or Date

SpatialDataReadOptions Options that customize how spatial files are read and parsed.
azure-maps-indoor package
Azure Maps Web SDK Indoor Module service retirement. The Azure Maps Web SDK Indoor
Module and Creator services have been retired and will no longer be available or supported
after September 30th, 2025. For more information, see Creator Services Retirement .

Classes
ノ Expand table

Level A control for changing the level of the indoor map.


Control

Level The options for a LevelControlOptions object.


Control
Options

Indoor
Manager

[ Indoor Manager for Azure Maps Control ]

This module applies filtering logic to mapbox layers so that indoor tilesets with multiple
floors worth of overlapping features can be presented.

This module was written because of a constraint in mapbox styles that prevents feature state
from being used in expressions that drive layout properties like visibility and sort-key. If this
constraint were removed, the logic in this module could be captured in a style definition.

[ Event/Data Flow ]

┌─────────────────┐ ┌────────────────┐ │ event: │ │ event: │ │


"sourcedata" │ │ "levelchanged" │ └────────┬────────┘
└────────┬───────┘ │ │ ▼ ▼ ┌─────────────────┐
┌────────────────┐ │ facilityMapping │ │ selectedLevels │
└────────┬────────┘ └────────┬───────┘ │ │ │ │ │
┌──────────────┐ │ ┌────────────────────┐ └─►│ masterFilter │◄─┘
│ mapbox.getLayers() │ └───────┬──────┘ └────────┬───────────┘ │ │
▼ │ ┌──────────────┐ │ │ filterList │◄───────────────┘
└───────┬──────┘ │ ▼ ┌────────────────────┐ │ mapbox.setFilter() │
└────────────────────┘

Indoor Options for the Indoor Manager.


Manager
Options

Interfaces
ノ Expand table

EventManager

IFacilityChangeEvent Event object returned by map when the facility changes.

IIndoorManagerEvents The events supported by the Indoor Manager .

IIndoorReadyEvent Event object returned by map when the indoor manager has finished loading.

ILevelChangeEvent Event object returned by map when the level number changes.

IMap
Web SDK map control release notes
Article • 04/09/2025

This document contains information about new features and other changes to the Map
Control.

v3 (latest)

3.6.1 (CDN: April 7, 2025, npm: April 9, 2025)

Bug fixes

Fix the issue where maxBounds wasn't included in map.getCamera() , causing it to be unset
when setCamera() is called.

3.6.0 (CDN: February 18, 2025, npm: February 20, 2025)

New features
Add a new option StyleOptions.styleOverrides which controls the visibility of various
map elements, including countryRegion , adminDistrict , adminDistrict2 ,
buildingFootprint , and roadDetails .

Add auto option to StyleOptions.language and atlas.setLanguage which sets the


language option to match the browser's Accept-Language header.

Bug fixes

Resolve the issue where clicking the close button of a popup within a form element
triggers the form submission.
Fix the issue where ImageLayer.setOptions() potentially causing abort errors if the image
is large and the request has not completed.

Other changes

Disable the telemetry by default.

3.5.0 (CDN: November 4, 2024, npm: November 7, 2024)


New features
Add support for fullscreen control.

Bug fixes

Expose new type on PolygonExtrusionLayerOptions.fillPattern to support


DataDrivenPropertyValueSpecification<string> .

3.4.0 (CDN: September 30, 2024, npm: October 2, 2024)

New features
Add support for PMTiles.

Bug fixes
Accessibility: Fix overflow issue with the style picker label in small containers.
Fix attribution not updating after style changes with a GeoJSON data source.
Fix setCamera with bounds and min/max zoom.
Use ResizeObserver instead of window resize events.
Fix footer logo width.

Other changes

Add @types/geojson as a dependency.


Update dependency @microsoft/applicationinsights-web to ^3.3.0

3.3.0 (August 8, 2024)

New features
Update the Copyright control
Make the copyright text smaller and ensure it fits on one line.
Use different types of Microsoft logos for different CSS themes to improve visibility.
Implement RWD to hide part of the component (MS logo) when the map canvas is
relatively small.
Enhance base layer class by adding abstract getOptions and setOptions functions.
Bug fixes
Skip existing sources when copying user layers.
[BREAKING] Address the incorrect ordering of latitude and longitude values in
Position.fromLatLng() .

Fix hidden accessible element visible issue on control buttons.

3.2.1 (May 13, 2024)

New features
Constrain horizontal panning when renderWorldCopies is set to false .
Make easeTo and flyTo animation smoother when the target point is close to the limits:
maxBounds, vertical world edges, or antimeridian.

Bug fixes

Correct accessible numbers for hidden controls while using 'Show numbers' command.
Fix memory leak in worker when the map is removed.
Fix unwanted zoom and panning changes at the end of a panning motion.

Other changes

Improve the format of inline code in the document.

3.2.0 (March 29, 2024)

Other changes

Upgrade MapLibre to V4 .

Correct the default value of HtmlMarkerOptions.pixelOffset from [0, -18] to [0, 0] in


the doc.

3.1.2 (February 22, 2024)

New features
Added fillAntialias option to PolygonLayer for enabling MSAA antialiasing on polygon
fills.

Other changes

Update the feedback icon and link.

3.1.1 (January 26, 2024)

New features

Added a new option, enableAccessibilityLocationFallback , to enable or disable reverse-


geocoding API fallback for accessibility (screen reader).

Bug fixes
Resolved an issue where ApplicationInsights v3.0.5 was potentially sending a large
number of requests.

3.1.0 (January 12, 2024)

New features

Added a new control, atlas.control.ScaleControl , to display a scale bar on the map.

Introduced functions for accessing, updating, and deleting a feature state.

Bug fixes

Addressed the issue of layer ordering after a style update, when a user layer is inserted
before another user layer.

[BREAKING] Aligned the polygon fill pattern behavior with Maplibre. Now, the
fillPattern option consistently disables the fillColor option. When configuring

fillColor for polygon layers, ensure that fillPattern is set to undefined .

3.0.3 (November 29, 2023)

New features
Included ESM support.

Other changes
The accessibility feature for screen reader has been upgraded to utilize the Search v2 API
(reverse geocoding).

Enhanced accessibility in the Compass and Pitch controls.

3.0.2 (November 1, 2023)

Bug fixes
Addressed several errors in the type declaration file and added a dependency for
@maplibre/maplibre-gl-style-spec .

Other changes

Removed Authorization headers from style, thumbnail, sprite, and glyph requests to
enhance CDN caching for static assets.

Updated the documentation for map.clear() and layers.clear() .

3.0.1 (October 6, 2023)

Bug fixes
Various accessibility improvements.

Resolved the issue with dynamic attribution when progressive loading is enabled.

Fixed missing event names in HtmlMarkerEvents .

Other changes
Modified member methods to be protected for the zoom, pitch, and compass controls.

Telemetry is disabled by default in the Azure Government cloud.

3.0.0 (August 18, 2023)


Bug fixes
Fixed zoom control to take into account the maxBounds CameraOptions.

Fixed an issue that mouse positions are shifted after a css scale transform on the map
container.

Other changes

Phased out the style definition version 2022-08-05 and switched the default
styleDefinitionsVersion to 2023-01-01 .

Added the mvc parameter to encompass the map control version in both definitions and
style requests.

Installation

The version is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link
href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0/atlas.min.css
" rel="stylesheet" />
<script
src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0/atlas.min.js">
</script>

3.0.0-preview.10 (July 11, 2023)

Bug fixes

Dynamic pixel ratio fixed in underlying maplibre-gl dependency.

Fixed an issue where sortKey , radialOffset , variableAnchor isn't applied when used in
SymbolLayer options.

Installation
The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.10

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.10/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.10/atlas.min.js"></script>

3.0.0-preview.9 (June 27, 2023)

New features
WebGL2 is used by default.

Elevation APIs: atlas.sources.ElevationTileSource ,


map.enableElevation(elevationSource, options) , map.disableElevation()

Ability to customize maxPitch / minPitch in CameraOptions

Bug fixes

Fixed an issue where accessibility-related duplicated DOM elements might result when
map.setServiceOptions is called

Installation

The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.9

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.9/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.9/atlas.min.js"></script>
3.0.0-preview.8 (June 2, 2023)

Bug fixes
Fixed an exception that occurred while updating the property of a layout that no longer
exists.

Fixed an issue where BubbleLayer's accessible indicators didn't update when the data
source was modified.

Fixed an error in subsequent map.setStyle() calls if the raw Maplibre style is retrieved in
the stylechanged event callback on style serialization.

Other changes
Updated attribution logo and link.

Installation

The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.8

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.8/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.8/atlas.min.js"></script>

3.0.0-preview.7 (May 2, 2023)

New features

In addition to map configuration, Map.setServiceOptions() now supports changing


domain , styleAPIVersion , styleDefinitionsVersion on runtime.

Bug fixes
Fixed token expired exception on relaunches when using Azure AD / shared token /
anonymous authentication by making sure authentication is resolved prior to any style
definition request

Fixed redundant style definition and thumbnail requests

Fixed incorrect aria-label applied to zoom out control button element

Fixed the possibility of undefined copyright element container when


withRuleBasedAttribution is set to false

Fixed the possibility of event listener removal called on undefined target in


EventManager.remove()

Installation

The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.7

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.7/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.7/atlas.min.js"></script>

3.0.0-preview.6 (March 31, 2023)

Installation

The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.6

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.6/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.6/atlas.min.js"></script>

New features
Optimized the internal style transform performance.

Bug fixes

Resolved an issue where the first style set request was unauthenticated for AAD
authentication.

Eliminated redundant requests during map initialization and on style changed events.

3.0.0-preview.5 (March 15, 2023)

Installation

The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.5

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.5/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.5/atlas.min.js"></script>

New features

Support dynamically updating mapConfiguration via map.setServiceOptions({


mapConfiguration: 'MAP_CONFIG' })

3.0.0-preview.4 (March 10, 2023)

Installation
The preview is available on npm and CDN.
NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.4

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.4/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.4/atlas.min.js"></script>

New features

Extended map coverage in China, Japan, and Korea.

Preview of refreshed map styles (Road / Night / Hybrid / Gray Scale Dark / Gray Scale
Light / Terra / High Contrast Dark / High Contrast Light).

More details on roads/building footprints/trails coverage.

Wider zoom level ranges (1~21) for the Terra style.

Greater details on public transit including ferries, metros, and bus stops.

Additional information about the altitude of mountains and the location of waterfalls.

Changes
Traffic data now only support relative mode.

Deprecated showBuildingModels in StyleOptions.

Changed the default minZoom from -2 to 1.

Bug fixes

Cleaned up various memory leaks in Map.dispose().

Improved style picker's tab navigation for accessibility in list layout.

Optimized style switching by avoiding deep cloning objects.

Fixed an exception that occurred in SourceManager when style switching with sources
that weren't vector or raster.
[BREAKING] Previously sourceadded events are only emitted if new sources are added to
the style. Now sourceremoved / sourceadded events are emitted when the new source and
the original source in the current style aren't equal, even if they have the same source ID.

3.0.0-preview.3 (February 2, 2023)

Installation
The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.3

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.3/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.3/atlas.min.js"></script>

New features
[BREAKING] Migrated from adal-angular to @azure/msal-browser used for
authentication with Microsoft Azure Active Directory (Azure AD). Changes that might be
required:
Platform / Reply URL Type must be set to Single-page application on Azure AD App

Registration portal.
Code change is required if a custom authOptions.authContext is used.
For more information, see How to migrate a JavaScript app from ADAL.js to MSAL.js.

Allow pitch and bearing being set with CameraBoundsOptions in


Map.setCamera(options).

Bug fixes
Fixed issue in language mapping , now zh-Hant-TW no longer reverts back to en-US .

Fixed the inability to switch between user regions (view).

Fixed exception that occurred when style switching while progressive layer loading is in
progress.
Fixed the accessibility information retrieval from map tile label layers.

Fixed the occasional issue where vector tiles aren't being rerendered after images are
being added via ImageSpriteManager.add().

3.0.0-preview.2 (December 16, 2022)

Installation
The preview is available on npm and CDN.

NPM: Refer to the instructions at azure-maps-control@3.0.0-preview.2

CDN: Reference the following CSS and JavaScript in the <head> element of an HTML file:

HTML

<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.2/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3.0.0-
preview.2/atlas.min.js"></script>

New features
Add progressiveLoading and progressiveLoadingInitialLayerGroups to StyleOptions to enable
the capability of loading map layers progressively. This feature improves the perceived loading
time of the map. For more information, see 2.2.2 release notes.

Bug fixes

Fixed an issue that the ordering of user layers wasn't preserved after calling
map.layers.move() .

Fixed the inability to disable traffic incidents in TrafficControlOptions when new


atlas.control.TrafficControl({incidents: false}) is used.

Add .atlas-map to all css selectors to scope the styles within the map container. The fix
prevents the css from accidentally adding unwanted styles to other elements on the page.

3.0.0-preview.1 (November 18, 2022)


Installation
The preview is available on npm .

Install azure-maps-control@next to your dependencies:

shell

npm i azure-maps-control@next

New features

This update is the first preview of the upcoming 3.0.0 release. The underlying maplibre-gl
dependency has been upgraded from 1.14 to 3.0.0-pre.1 , offering improvements in stability
and performance.

Bug fixes

Fixed a regression issue that prevents IndoorManager from removing a tileset:

JavaScript

indoorManager.setOptions({
tilesetId: undefined
})

v2

2.3.7 (February 22, 2024)

New features
Added fillAntialias option to PolygonLayer for enabling MSAA antialiasing on polygon
fills.
Added a new option, enableAccessibilityLocationFallback , to enable or disable reverse-
geocoding API fallback for accessibility (screen reader).

Other changes
Update the feedback icon and link.
2.3.6 (January 12, 2024)

New features
Added a new control, atlas.control.ScaleControl , to display a scale bar on the map.

Introduced functions for accessing, updating, and deleting a feature state.

Bug fixes
Addressed the issue of layer ordering after a style update, when a user layer is inserted
before another user layer.

2.3.5 (November 29, 2023)

Other changes

The accessibility feature for screen reader has been upgraded to utilize the Search v2 API
(reverse geocoding).

2.3.4 (November 1, 2023)

Other changes
Removed Authorization headers from style, thumbnail, sprite, and glyph requests to
enhance CDN caching for static assets.

Updated the documentation for map.clear() and layers.clear() .

2.3.3 (October 6, 2023)

Bug fixes
Resolved the issue with dynamic attribution when progressive loading is enabled.

2.3.2 (August 11, 2023)

Bug fixes
Fixed an issue where accessibility-related duplicated DOM elements might result when
map.setServiceOptions is called.

Fixed zoom control to take into account the maxBounds CameraOptions.

Other changes
Added the mvc parameter to encompass the map control version in both definitions and
style requests.

2.3.1 (June 27, 2023)

Bug fixes

Fix ImageSpriteManager icon images might get removed during style change

Other changes

Security: insecure-randomness fix in UUID generation.

2.3.0 (June 2, 2023)

New features

[BREAKING] Refactored the internal StyleManager to replace _stylePatch with


transformStyle . This change will allow road shield icons to update and render properly

after a style switch.

Bug fixes
Fixed an exception that occurred while updating the property of a layout that no longer
exists.

Fixed an issue where BubbleLayer's accessible indicators didn't update when the data
source was modified.

Other changes
Updated attribution logo and link.
2.2.7 (May 2, 2023)

New features
In addition to map configuration, Map.setServiceOptions() now supports changing
domain , styleAPIVersion , styleDefinitionsVersion on runtime.

Bug fixes
Fixed token expired exception on relaunches when using Azure AD / shared token /
anonymous authentication by making sure authentication is resolved prior to any style
definition request

Fixed redundant style definition and thumbnail requests

Fixed incorrect aria-label applied to zoom out control button element

Fixed the possibility of undefined copyright element container when


withRuleBasedAttribution is set to false

Fixed the possibility of event listener removal called on undefined target in


EventManager.remove()

2.2.6

Bug fixes

Resolved an issue where the first style set request was unauthenticated for AAD
authentication.

Eliminated redundant requests during map initialization and on style changed events.

2.2.5

New features

Support dynamically updating mapConfiguration via map.setServiceOptions({


mapConfiguration: 'MAP_CONFIG' })

2.2.4
Bug fixes
Cleaned up various memory leaks in Map.dispose().

Improved style picker's tab navigation for accessibility in list layout.

2.2.3

New features
Allow pitch and bearing being set with CameraBoundsOptions in
Map.setCamera(options).

Bug fixes

Fixed issue in language mapping , now zh-Hant-TW no longer reverts back to en-US .

Fixed the inability to switch between user regions (view).

Fixed exception that occurred when style switching while progressive layer loading is in
progress.

Fixed the accessibility information retrieval from map tile label layers.

Fixed the occasional issue where vector tiles aren't being rerendered after images are
being added via ImageSpriteManager.add().

2.2.2 (December 15, 2022)

New features
Add progressiveLoading and progressiveLoadingInitialLayerGroups to StyleOptions to enable
the capability of loading map layers progressively. This feature improves the perceived loading
time of the map.

progressiveLoading

Enables progressive loading of map layers.


Defaults to false .
progressiveLoadingInitialLayerGroups

Specifies the layer groups to load first.


Defaults to ["base"] .
Possible values are base , transit , labels , buildings , and labels_places .
Other layer groups are deferred such that the initial layer groups can be loaded first.

Bug fixes
Fixed an issue that the ordering of user layers wasn't preserved after calling
map.layers.move() .

Fixed the inability to disable traffic incidents in TrafficControlOptions when new


atlas.control.TrafficControl({incidents: false}) is used.

Next steps
Explore samples showcasing Azure Maps:

Azure Maps Samples

Stay up to date on Azure Maps:

Azure Maps Blog


Indoor Module release notes
Article • 11/03/2023

This document contains information about new features and other changes to the Azure
Maps Indoor Module.

0.2.3

Changes (0.2.3)
Improve rendering performance by reading facility-level data from the style
metadata when available.

0.2.2

Changes (0.2.2)
Performance improvements in dynamic styling updates.

Bug fixes (0.2.2)


Fix incorrect feature IDs usage in dynamic styling for drawing package 2.0 derived
tilesets.

0.2.1

New features (0.2.1)


multiple statesets are now supported for map configurations with multiple tileset,
instead of single stateset ID, a mapping between tileset IDs and stateset ids can be
passed:

JavaScript

indoorManager.setOptions({
statesetId: {
'tilesetId1': 'stasetId1',
'tilesetId2': 'stasetId2'
}
});

indoorManager.setDynamicStyling(true)

autofocus and autofocusOptions support: when you set autofocus on


IndoorManagerOptions , the camera is focused on the indoor facilities once the

indoor map is loaded. Camera options can be further customized via autofocus
options:

JavaScript

indoorManager.setOptions({
autofocus: true,
autofocusOptions: {
padding: { top: 50, bottom: 50, left: 50, right: 50 }
}
});

focusCamera support: instead of autofocus , you can call focusCamera directly.


(Alternative to autofocus , when indoor map configuration is used, tilesetId can be
provided to focus on a specific facility only, otherwise bounds that enclose all
facilities are used):

JavaScript

indoorManager.focusCamera({
type: 'ease',
duration: 1000,
padding: { top: 50, bottom: 50, left: 50, right: 50 }
})

level name labels in LevelControl (in addition to ordinal , LevelControl can now
display level names derived from 'name' property of level features):

JavaScript

indoorManager.setOptions({
levelControl: new LevelControl({ levelLabel: 'name' })
});

Changes (0.2.1)
non level-bound features are now displayed
Bug fixes (0.2.1)
fix facility state not initialized when tile loads don't emit sourcedata event

level preference sorting fixed

0.2.0

New features (0.2.0)


Support for new drawing package 2.0 derived tilesets.

Support the possibility to select a facility when clicking on a feature that doesn't
contain a facilityId, but has a levelId so that the facility can be inferred from the
levelId.

Changes (0.2.0)
Performance improvements for level picker and indoor manager.

Revamp of how level filters are applied to indoor style layers.

Bug fixes (0.2.0)


Fix slider not updating when changing level in the level picker when used inside
the shadow dom of a custom element.

Fix exception on disabling of dynamic styling.

Next steps
Explore samples showcasing Azure Maps:

Azure Maps Creator Samples

Stay up to date on Azure Maps:

Azure Maps Blog


Drawing Tools Module release notes
Article • 11/07/2024

This document contains information about new features and other changes to the Azure
Maps Drawing Tools Module.

1.0.5 (CDN: November 4, 2024, npm:


November 7)

Bug fixes
Fix an issue where DrawingManager would create an empty layer when source
options were provided.

1.0.4 (Aug 8, 2024)

Bug fixes
Fix source not synced in DrawingManager after a style change.

1.0.3

Other changes
Updated CDN links in the readme.

1.0.2

Bug fixes
Resolved various errors in the type declaration file.

Fixed typing incompatibility with MapControl v3.

Next steps
Explore samples showcasing Azure Maps:

Azure Maps Drawing Tools Samples

Stay up to date on Azure Maps:

Azure Maps Blog

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Spatial IO Module release notes
Article • 09/25/2024

This document contains information about new features and other changes to the Azure
Maps Spatial IO Module.

0.1.8 (February 22, 2024)

Bug fixes (0.1.8)


Fix issue while processing replacement character when it doesn't have the
expected binary code in spatial data.

0.1.7

New features (0.1.7)


Introduced a new customization option, bubbleRadiusFactor , to enable users to
adjust the default multiplier for the bubble radius in a SimpleDataLayer.

0.1.6

Other changes (0.1.6)


Remove dependency on core Node.js modules, including crypto and
work_threads .

0.1.5

Bug fixes (0.1.5)


Adds missing check-in WmsClient.getFeatureInfoHtml that decides service
capabilities.

0.1.4
Bug fixes (0.1.4)
Make sure parsed geojson features (from KML) are always assigned with valid IDs

Unescape XML & that otherwise breaks valid urls

Handles empty <Icon><\Icon> inside KMLReader

Next steps
Explore samples showcasing Azure Maps:

Azure Maps Spatial IO Samples

Stay up to date on Azure Maps:

Azure Maps Blog

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Microsoft.Maps accounts
Article • 12/09/2024

Bicep resource definition


The accounts resource type can be deployed with operations that target:

Resource groups - See resource group deployment commands

For a list of changed properties in each API version, see change log.

Resource format
To create a Microsoft.Maps/accounts resource, add the following Bicep to your template.

Bicep

resource symbolicname 'Microsoft.Maps/accounts@2024-07-01-preview' = {


identity: {
type: 'string'
userAssignedIdentities: {
{customized property}: {}
}
}
kind: 'string'
location: 'string'
name: 'string'
properties: {
cors: {
corsRules: [
{
allowedOrigins: [
'string'
]
}
]
}
disableLocalAuth: bool
encryption: {
customerManagedKeyEncryption: {
keyEncryptionKeyIdentity: {
delegatedIdentityClientId: 'string'
federatedClientId: 'string'
identityType: 'string'
userAssignedIdentityResourceId: 'string'
}
keyEncryptionKeyUrl: 'string'
}
infrastructureEncryption: 'string'
}
linkedResources: [
{
id: 'string'
uniqueName: 'string'
}
]
locations: [
{
locationName: 'string'
}
]
}
sku: {
name: 'string'
}
tags: {
{customized property}: 'string'
}
}

Property values
CorsRule
ノ Expand table

Name Description Value

allowedOrigins Required if CorsRule element is present. A list of origin domains that will be allowed via CORS, or "*" to allow all string[]
domains (required)

CorsRules
ノ Expand table

Name Description Value

corsRules The list of CORS rules. You can include up to five CorsRule elements in the request. CorsRule[]

Encryption
ノ Expand table

Name Description Value

customerManagedKeyEncryption All Customer-managed key encryption properties for the resource. EncryptionCustomerManagedKeyEncryption

infrastructureEncryption (Optional) Discouraged to include in resource definition. Only needed 'disabled'


where it is possible to disable platform (AKA infrastructure) encryption. 'enabled'
Azure SQL TDE is an example of this. Values are enabled and disabled.

EncryptionCustomerManagedKeyEncryption
ノ Expand table

Name Description Value

keyEncryptionKeyIdentity All identity configuration for Customer-managed key settings defining which identity should EncryptionCustomerManagedKeyEncrypt
be used to auth to Key Vault.

keyEncryptionKeyUrl key encryption key Url, versioned or unversioned. Ex: string


https://contosovault.vault.azure.net/keys/contosokek/562a4bb76b524a1493a6afe8e536ee78
or https://contosovault.vault.azure.net/keys/contosokek .

EncryptionCustomerManagedKeyEncryptionKeyIdentity
ノ Expand table

Name Description Value

delegatedIdentityClientId delegated identity to use for accessing key encryption key Url. Ex: string
/subscriptions/fa5fc227-a624-475e-b696-cdd604c735bc/resourceGroups/<resource
group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myId. Mutually Constraints:
exclusive with identityType systemAssignedIdentity and userAssignedIdentity - internal Min length = 36
use only. Max length = 36
Pattern = ^[0-9a-fA-F]{8}-
([0-9a-fA-F]{4}-){3}[0-9a-
fA-F]{12}$

federatedClientId application client identity to use for accessing key encryption key Url in a different tenant. string
Ex: f83c6b1b-4d34-47e4-bb34-9d83df58b540
Constraints:
Min length = 36
Max length = 36
Pattern = ^[0-9a-fA-F]{8}-
([0-9a-fA-F]{4}-){3}[0-9a-
fA-F]{12}$
Name Description Value

identityType The type of identity to use. Values can be systemAssignedIdentity, userAssignedIdentity, 'delegatedResourceIdentity'
or delegatedResourceIdentity. 'systemAssignedIdentity'
'userAssignedIdentity'

userAssignedIdentityResourceId User assigned identity to use for accessing key encryption key Url. Ex: string
/subscriptions/fa5fc227-a624-475e-b696-cdd604c735bc/resourceGroups/<resource
group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myId. Mutually
exclusive with identityType systemAssignedIdentity.

LinkedResource
ノ Expand table

Name Description Value

id ARM resource id in the form: string


'/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/accounts/{storageName}'. (required)

uniqueName A provided name which uniquely identifies the linked resource. string
(required)

LocationsItem
ノ Expand table

Name Description Value

locationName The location name. string (required)

ManagedServiceIdentity
ノ Expand table

Name Description

type Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).

userAssignedIdentities The set of user assigned identities associated with the resource. The userAssignedIdentities dictionary keys will be ARM resource ids in the for
'/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity
The dictionary values can be empty objects ({}) in requests.

MapsAccountProperties
ノ Expand table

Name Description Value

cors Specifies CORS rules for the Blob service. You can include up to five CorsRule elements in the request. If no CorsRule CorsRules
elements are included in the request body, all CORS rules will be deleted, and CORS will be disabled for the Blob
service.

disableLocalAuth Allows toggle functionality on Azure Policy to disable Azure Maps local authentication support. This will disable bool
Shared Keys and Shared Access Signature Token authentication from any usage.

encryption All encryption configuration for a resource. Encryption

linkedResources The array of associated resources to the Maps account. Linked resource in the array cannot individually update, you LinkedResource[]
must update all linked resources in the array together. These resources may be used on operations on the Azure
Maps REST API. Access is controlled by the Maps Account Managed Identity(s) permissions to those resource(s).

locations List of additional data processing regions for the Maps Account, which may result in requests being processed in LocationsItem[]
another geography. Some features or results may be restricted to specific regions. By default, Maps REST APIs
process requests according to the account location or the geographic scope.
Microsoft.Maps/accounts
ノ Expand table

Name Description Value

identity Managed service identity (system assigned and/or user assigned identities) ManagedServiceIdentity

kind Get or Set Kind property. 'Gen2'

location The geo-location where the resource lives string (required)

name The resource name string

Constraints:
Min length = 1
Pattern = ^[^%&:\\/#?]+$ (required)

properties The map account properties. MapsAccountProperties

sku The SKU of this account. Sku (required)

tags Resource tags Dictionary of tag names and values. See Tags in templates

Sku
ノ Expand table

Name Description Value

name The name of the SKU, in standard format (such as G2). 'G2' (required)

TrackedResourceTags
ノ Expand table

Name Description Value

UserAssignedIdentities
ノ Expand table

Name Description Value

UserAssignedIdentity
ノ Expand table

Name Description Value

Quickstart samples
The following quickstart samples deploy this resource type.

ノ Expand table

Bicep File Description

Deploy Azure Maps This template deploys and Azure Maps account and lists the primary key.

Deploy Azure Maps with Azure Maps Creator (Indoor Maps) This template deploys and Azure Maps account with the Indoor Maps
Creator Feature to allow building Indoor Maps.
Feedback
Was this page helpful?  Yes  No
az maps
Manage Azure Maps.

Commands
ノ Expand table

Name Description Type Status

az maps Manage Azure Maps accounts. Core GA


account

az maps Create a Maps Account. A Maps Account holds the keys which allow Core GA
account create access to the Maps REST APIs.

az maps Delete a Maps Account. Core GA


account delete

az maps Manage Azure Maps account keys. Core GA


account keys

az maps Get the keys to use with the Maps APIs. A key is used to authenticate Core GA
account keys and authorize access to the Maps REST APIs. Only one key is needed at
list a time; two are given to provide seamless key regeneration.

az maps Regenerate either the primary or secondary key for use with the Maps Core GA
account keys APIs. The old key will stop working immediately.
renew

az maps Show all maps accounts in a subscription or in a resource group. Core GA


account list

az maps Show the details of a maps account. Core GA


account show

az maps Updates a Maps Account. Only a subset of the parameters may be Core GA
account updated after creation, such as Sku, Tags, Properties.
update

az maps Manage creator with maps. Core GA


creator

az maps Create a Maps Creator resource. Creator resource will manage Azure Core GA
creator create resources required to populate a custom set of mapping data. It
requires an account to exist before it can be created.

az maps Delete a Maps Creator resource. Core GA


Name Description Type Status

creator delete

az maps Get all Creator instances for an Azure Maps Account. Core GA
creator list

az maps Get a Maps Creator resource. Core GA


creator show

az maps Updates the Maps Creator resource. Only a subset of the parameters Core GA
creator update may be updated after creation, such as Tags.

az maps map Manage map with maps. Core GA

az maps map List operations available for the Maps Resource Provider. Core GA
list-operation
Azure Maps QPS rate limits
Article • 09/24/2024

Azure Maps doesn't have any maximum daily limits on the number of requests that can
be made, however there are limits to the maximum number of queries per second (QPS).

7 Note

Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2 pricing
tier replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps account has
Gen1 pricing tier selected, you can switch to Gen2 pricing tier before it’s retired,
otherwise it will automatically be updated. For more information, see Manage the
pricing tier of your Azure Maps account.

The following list shows the QPS usage limits for each Azure Maps service by Pricing
Tier.

ノ Expand table

Azure Maps service QPS QPS Limit: Gen QPS Limit: Gen
Limit: Gen 2 1 S1 Pricing 1 S0 Pricing
Pricing Tier Tier Tier

Copyright service 10 10 10

Creator - Alias (Deprecated1) 10 Not Available Not Available

Creator - Conversion, Dataset, Feature 50 Not Available Not Available


State, Features, Map Configuration, Style,
Routeset, TilesetDetails, Wayfinding
(Deprecated1)

Data registry service (Deprecated1) 50 50 Not Available

Geolocation service 50 50 50

Render service - Road tiles 500 500 50

Render service - Satellite tiles 250 250 Not Available

Render service - Static maps 50 50 50

Render service - Traffic tiles 50 50 50


Azure Maps service QPS QPS Limit: Gen QPS Limit: Gen
Limit: Gen 2 1 S1 Pricing 1 S0 Pricing
Pricing Tier Tier Tier

Render service - Weather tiles 100 100 50

Route service - Batch 10 10 Not Available

Route service - Non-Batch 50 50 50

Search service - Batch 10 10 Not Available

Search service - Non-Batch 500 500 50

Search service - Non-Batch Reverse 250 250 50

Spatial service (Deprecated1) 50 50 Not Available

Timezone service 50 50 50

Traffic service 50 50 50

Weather service 50 50 50

1
Azure Maps Creator, and the Data registry and Spatial services are now deprecated
and will be retired on 9/30/25.

When QPS limits are reached, an HTTP 429 error is returned. If you're using the Gen 2 or
Gen 1 S1 pricing tiers, you can create an Azure Maps Technical Support Request in the
Azure portal to increase a specific QPS limit if needed. QPS limits for the Gen 1 S0
pricing tier can't be increased.

Feedback
Was this page helpful?  Yes  No

Provide product feedback | Get help at Microsoft Q&A


Understanding Azure Maps Transactions
Article • 04/18/2025

When you use Azure Maps Services, the API requests you make generate transactions. Your
transaction usage is available for review in your Azure portal Metrics report. For more
information, see View Azure Maps API usage metrics. These transactions can be either billable
or nonbillable usage, depending on the service and the feature. It’s important to understand
which usage generates a billable transaction and how it’s calculated so you can plan and
budget for the costs associated with using Azure Maps. Billable transactions show up in your
Cost Analysis report within the Azure portal.

7 Note

Azure Maps Gen1 pricing tier retirement

Gen1 pricing tier is now deprecated and will be retired on 9/15/26. Gen2 pricing tier
replaces Gen1 (both S0 and S1) pricing tier. If your Azure Maps account has Gen1 pricing
tier selected, you can switch to Gen2 pricing tier before it’s retired, otherwise it will
automatically be updated. For more information, see Manage the pricing tier of your
Azure Maps account.

Azure Maps Transaction information by service


The following table summarizes the Azure Maps services that generate both billable and
nonbillable transactions, along with key aspects to help understand how the number of
transactions is calculated.

7 Note

For Azure Maps pricing information and free offering details, see Azure Maps Pricing .

ノ Expand table

Azure Maps Billable Transaction Calculation Meter


Service

Data registry Yes One request = 1 transaction Location


(Deprecated1) Insights Data
(Gen2
pricing)
Azure Maps Billable Transaction Calculation Meter
Service

Geolocation Yes One request = 1 transaction Location


Insights
Geolocation
(Gen2
pricing)
Standard S1
Geolocation
Transactions
(Gen1 S1
pricing)
Standard
Geolocation
Transactions
(Gen1 S0
pricing)

Render Yes, except Get Copyright API, Get 15 tiles = 1 transaction Maps Base
Attribution API and Terra maps One request for Get Map Tiles
( MapTile.GetTerraTile and Copyright = 1 (Gen2
layer=terra ) which are nonbillable. transaction pricing)
One request for Get Maps
Map Attribution = 1 Imagery
transaction Tiles (Gen2
One request for Get pricing)
Static Map = 1 Maps Static
transaction Map Images
One request for Get (Gen2
Map Tileset = 1 pricing)
transaction Maps
Weather
Tiles (Gen2
For Creator related usage, pricing)
see the Creator table. Standard
Hybrid Aerial
Imagery
Transactions
(Gen1 S0
pricing)
Standard
Aerial
Imagery
Transactions
(Gen1 S0
pricing)
Standard S1
Aerial
Azure Maps Billable Transaction Calculation Meter
Service

Imagery
Transactions
(Gen1 S1
pricing)
Standard S1
Hybrid Aerial
Imagery
Transactions
(Gen1 S1
pricing)
Standard S1
Rendering
Transactions
(Gen1 S1
pricing)
Standard S1
Tile
Transactions
(Gen1 S1
pricing)
Standard S1
Weather Tile
Transactions
(Gen1 S1
pricing)
Standard Tile
Transactions
(Gen1 S0
pricing)
Standard
Weather Tile
Transactions
(Gen1 S0
pricing)
Maps
Copyright
(Gen2
pricing,
Gen1 S0
pricing and
Gen1 S1
pricing)

Route Yes One request = 1 transaction Location


Insights
Routing
Azure Maps Billable Transaction Calculation Meter
Service

If using the Route (Gen2


Matrix, every four cells pricing)
in the Route Matrix Standard S1
request generates a Routing
billable Route Transactions
transaction, rounded (Gen1 S1
up to the nearest pricing)
whole number. If you Standard
provided 5 origins and Services API
10 destinations, that Transactions
would be counted as (Gen1 S0
Ceiling(0.25*5*10) = pricing)
13 Routing
transactions.
If using Batch
transactions, each
query in the Batch
request call generates
a billable Route
transaction.
If using Snap to
Roads. Snap to Roads
is billed similarly to
other Route APIs: 1
request equals 1
transaction, and each
request can support
up to 100 snap-to-
roads points.
Azure Maps Billable Transaction Calculation Meter
Service

Search v1 Yes One request = 1 transaction. Location


Search v2 Insights
If using Batch Search, Search
each location in the Standard S1
Batch request Search
generates a billable Transactions
Search transaction. (Gen1 S1
Note, the billable pricing)
Search transaction Standard
usage results Services API
generated by the Transactions
batch request has - (Gen1 S0
Batch appended to the pricing)
API name of your
Azure portal metrics
report.

Spatial Yes, except for One request = 1 transaction. Location


(Deprecated1) Spatial.GetBoundingBox , Insights
Spatial.PostBoundingBox and
If using Geofence, five Spatial
requests = 1 Calculations
Spatial.PostPointInPolygonBatch ,
transaction (Gen2
which are nonbillable.
pricing)
Standard S1
Spatial
Transactions
(Gen1 S1
pricing)

Timezone Yes One request = 1 transaction Location


Insights
Timezone
(Gen2
pricing)
Standard S1
Time Zones
Transactions
(Gen1 S1
pricing)
Standard
Time Zones
Transactions
(Gen1 S0
pricing)
Azure Maps Billable Transaction Calculation Meter
Service

Traffic Yes One request = 1 transaction Location


(except tiles) Insights
15 tiles = 1 transaction Traffic (Gen2
pricing)
Standard S1
Traffic
Transactions
(Gen1 S1
pricing)
Standard
Traffic
Transactions
(Gen1 S0
pricing)
Maps Traffic
Tiles (Gen2
pricing)
Standard S1
Tile
Transactions
(Gen1 S1
pricing)
Standard Tile
Transactions
(Gen1 S0
pricing)

Weather Yes One request = 1 transaction Location


Insights
Weather
(Gen2
pricing)
Standard S1
Weather
Transactions
(Gen1 S1
pricing)
Standard
Weather
Transactions
(Gen1 S0
pricing)
1
The Azure Maps Data registry and Spatial services are now deprecated and will be retired on
9/30/25.

7 Note

There's no charge to use Azure Maps Power BI visual as long as you have a Power BI
subscription.

 Tip

Unlike Bing Maps, Azure Maps doesn’t use session IDs. Instead, Azure Maps offers many
free transactions each month as shown in Azure Maps pricing . For example, you get
5,000 free Base Map Tile transactions per month. Each transaction can include up to 15
tiles for a total of 75,000 tiles rendered for free each month.

Azure Maps Creator

7 Note

Azure Maps Creator retirement

The Azure Maps Creator is now deprecated and will be retired on 9/30/25. For more
information, see End of Life Announcement of Azure Maps Creator .

ノ Expand table

Azure Maps Billable Transaction Meter


Creator Calculation

Alias No One request = Not applicable


1 transaction

Conversion Part of a provisioned Creator resource and not Not Map Provisioning
transactions based. transaction- (Gen2 pricing)
based

Dataset Part of a provisioned Creator resource and not Not Map Provisioning
transactions based. transaction- (Gen2 pricing)
based

Feature Yes, except for FeatureState.CreateStateset , One request = Azure Maps Creator
State FeatureState.DeleteStateset , 1 transaction Feature State (Gen2
Azure Maps Billable Transaction Meter
Creator Calculation

FeatureState.GetStateset , pricing)
FeatureState.ListStatesets ,
FeatureState.UpdateStatesets

Render Yes, only with GetMapTile with Creator Tileset ID One request = Azure Maps Creator
and GetStaticTile . 1 transaction Map Render (Gen2
For more information on Render related One tile = 1 pricing)
transactions, see the Render section in the transaction
previous table.

Tileset Part of a provisioned Creator resource and not Not Map Provisioning
transactions based. transaction- (Gen2 pricing)
based

WFS Yes One request = Azure Maps Creator


1 transaction Web Feature (WFS)
(Gen2 pricing)

Understand billing transactions


Azure Maps doesn't count billing transactions for:

5xx HTTP Status Codes


401 (Unauthorized)
403 (Forbidden)
408 (Timeout)
429 (TooManyRequests)
CORS preflight requests

For more information on billing transactions and other Azure Maps pricing information, see
Azure Maps pricing .

Next steps
Azure Maps pricing

Pricing calculator

Manage the pricing tier of your Azure Maps account

View Azure Maps API usage metrics


Azure Maps community - Open-source
projects
Article • 05/02/2025

These open-source, community-driven initiatives are created and maintained by the Azure
Maps team. They're not part of the standard product or service offerings.

Open-source Web SDK modules


The following tables list some of the most popular Azure Maps open-source projects and
samples.

Maintained by Azure Maps team

The following table lists the open-source projects maintained by Azure Maps team that extend
the capabilities of the Azure Maps Web SDK.

ノ Expand table

Project Name Description npm Package

react-azure-maps An Azure Maps Web SDK wrapper in react framework. For react-azure-maps
more information and interactive samples, see the Azure
Maps React wrapper Getting Started guide.

Azure Maps A rich library of animations for use with the Azure Maps @azure-
Animation Web SDK. maps/animations
module

Azure Maps A module for the Azure Maps Web SDK that provides a @azure-maps/gridded-
Gridded Data data source that clusters data points into cells of a grid data-source
Source module area. This operation is also known by many names such as
tessellations, data binning, or hex bins.

Azure Maps An Azure Maps Web SDK module that provides controls N/A
selection control for selecting data in a data source using drawing tools or
module by requesting a route range polygon.

Contributed and maintained by Community

The following table lists the open-source projects contributed to, and maintained by the
development Community that extend the capabilities of the Azure Maps Web SDK.
ノ Expand table

Project Name Description

Azure Maps Bring Data Into An Azure Maps Web SDK module that provides a control that makes it
View Control module easy to bring any data loaded on the map into view.

Azure Maps HTML Marker An Azure Maps Web SDK module that provides a layer that renders point
Layer module data from a data source as HTML elements on the map.

Azure Maps Image Exporter A module for the Azure Maps Web SDK that generates screenshots of
module the map.

Azure Maps Overview Map An Azure Maps Web SDK module that provides a control that displays an
module overview map of the area the main map is focused on.

Azure Maps Spider Clusters A module for the Azure Maps Web SDK that adds a visualization to the
module map that expands clusters into a spiral spider layout.

Azure Maps Spyglass Control An Azure Maps Web SDK module that provides a window that displays a
module data set inside of a spyglass on the map.

Azure Maps Swipe Map A module for the Azure Maps Web SDK that allows swiping between two
module overlapping maps, ideal for comparing two overlapping data sets.

Azure Maps Sync Map An Azure Maps Web SDK module that synchronizes the cameras of two
module or more maps.

Samples

ノ Expand table

Project Name Description

Azure Maps Code Samples A collection of code samples for using Azure Maps in web-based
apps.

React Azure Maps Playground A getting started guide to help you create your first map using the
React wrapper for Azure Maps

Azure Maps Jupyter Notebook A collection of Python samples using the Azure Maps REST services.
samples

Supportability of open-source projects


All Azure Maps open-source projects and samples use supported and recommended
techniques and are:
Created and maintained by Microsoft and the community.
A community initiative – people who work on the initiative for the benefit of others, and
have their normal day job as well.
NOT a product, and not supported by Premier Support or other official support channels.
Supported in similar ways as other open-source projects done by Microsoft with support
from the community by the community.

Next steps
Find more open-source Azure Maps projects.

Code samples
Glossary
Article • 03/23/2023

The following list describes common words used with the Azure Maps services.

A
Address validation: The process of verifying the existence of an address.

Advanced routing: A collection of services that perform advance operations using road
routing data; such as, calculating reachable ranges (isochrones), distance matrices, and
batch route requests.

Aerial imagery: See Satellite imagery.

Along a route search: A spatial query that looks for data within a specified detour time
or distance from a route path.

Altitude: The height or vertical elevation of a point above a reference surface. Altitude
measurements are based on a given reference datum, such as mean sea level. See also
elevation.

Ambiguous: A state of uncertainty in data classification that exists when an object may
appropriately be assigned two or more values for a given attribute. For example, when
geocoding "CA", two ambiguous results are returned: "Canada" and "California". "CA" is
a country/region and a state code, for "Canada" and "California", respectively.

Annotation: Text or graphics displayed on the map to provide information to the user.
Annotation may identify or describe a specific map entity, provide general information
about an area on the map, or supply information about the map itself.

Antimeridian: Or 180th Meridian. The point where -180 degrees and 180 degrees of
longitude meet, the opposite of the prime meridian on the globe.

Application Programming Interface (API): A specification that allows developers to


create applications.

API key: See Shared key authentication.

Area of Interest (AOI): The extent used to define a focus area for either a map or a
database production.
Asset tracking: The process of tracking the location of an asset, such as a person,
vehicle, or some other object.

Asynchronous request: An HTTP request that opens a connection and makes a request
to the server that returns an identifier for the asynchronous request, then closes the
connection. The server continues to process the request and the user can check the
status using the identifier. When the request is finished processing, the user can then
download the response. This type of request is used for long running processes.

Autocomplete: A feature in an application that predicts the rest of a word a user is


typing.

Autosuggest: A feature in an application that predicts logical possibilities for what the
user is typing.

Azure Location Based Services (LBS): The former name of Azure Maps when it was in
preview.

Azure Active Directory (Azure AD): Azure AD is Microsoft's cloud-based identity and
access management service. Azure Maps Azure AD integration is currently available in
preview for all Azure Maps APIs. Azure AD supports Azure role-based access control
(Azure RBAC) to allow fine-grained access to Azure Maps resources. To learn more about
Azure Maps Azure AD integration, see Azure Maps and Azure AD and Manage
authentication in Azure Maps.

Azure Maps key: See Shared key authentication.

B
Base map: The part of a map application that displays background reference
information such as roads, landmarks, and political boundaries.

Batch request: The process of combining multiple requests into a single request.

Bearing: The horizontal direction of a point in relation to another point. This is


expressed as an angle relative to north, from 0-degrees to 360 degrees in a clockwise
direction.

Boundary: A line or polygon separating adjacent political entities, such as


countries/regions, districts, and properties. A boundary is a line that may or may not
follow physical features, such as rivers, mountains, or walls.

Bounds: See Bounding box.


Bounding box: A set of coordinates used to represent a rectangular area on the map.

C
Cadastre: A record of registered land and properties. See also Parcel.

Camera: In the context of an interactive map control, a camera defines the maps field of
view. The viewport of the camera is determined based on several map parameters:
center, zoom level, pitch, bearing.

Centroid: The geometric center of a feature. The centroid of a line would be the
midpoint while the centroid of a polygon would be its center of area.

Choropleth map: A thematic map in which areas are shaded in proportion to a


measurement of a statistical variable. This statistical variable is displayed on the map.
For example, coloring the boundary of each US state based on its relative population to
all other states.

Concave hull: A shape that represents a possible concave geometry that encloses all
shapes in the specified data set. The generated shape is similar to wrapping the data
with plastic wrap and then heating it, thus causing large spans between points to cave in
towards other data points.

Consumption model: Information that defines the rate at which a vehicle consumes fuel
or electricity. Also see the consumption model documentation.

Control: A self-contained or reusable component consisting of a graphical user interface


that defines a set of behaviors for the interface. For example, a map control, is generally
the portion of the user interface that loads an interactive map.

Convex hull: A convex hull is a shape that represents the minimum convex geometry
that encloses all shapes in the specified data set. The generated shape is similar to
wrapping an elastic band around the data set.

Coordinate: Consists of the longitude and latitude values used to represent a location
on a map.

Coordinate system: A reference framework used to define the positions of points in


space in two or three dimensions.

Country code: A unique identifier for a country/region based on the ISO standard. ISO2
is a two-character code for a country/region (for example, US), which ISO3 represents a
three-character code (for example, USA).
Country subdivision: A first-level subdivision of a country/region, commonly known as a
state or province.

Country secondary subdivision: A second-level subdivision of a country/region,


commonly known as a county.

Country tertiary subdivision: A third-level subdivision of a country/region, typically a


named area such as a ward.

Cross street: A point where two or more streets intersect.

Cylindrical projection: A projection that transforms points from a spheroid or sphere


onto a tangent or secant cylinder. The cylinder is then sliced from top to bottom and
flattened into a plane.

D
Datum: The reference specifications of a measurement system, a system of coordinate
positions on a surface (a horizontal datum) or heights above or below a surface (a
vertical datum).

DBF file: A database file format that is used in combination with Shapefiles (SHP).

Degree Minutes Seconds (DMS): The unit of measure for describing latitude and
longitude. A degree is 1/360th of a circle. A degree is further divided into 60 minutes,
and a minute is divided into 60 seconds.

Delaunay triangulation: A technique for creating a mesh of contiguous, nonoverlapping


triangles from a dataset of points. Each triangle's circumscribing circle contains no
points from the dataset in its interior.

Demographics: The statistical characteristics (such as age, birth rate, and income) of a
human population.

Destination: An end point or location in which someone is traveling to.

Digital Elevation Model (DEM): A dataset of elevation values related to a surface,


captured over an area in regular intervals using a common datum. DEMs are typically
used to represent terrain relief.

Dijkstra's algorithm: An algorithm that examines the connectivity of a network to find


the shortest path between two points.

Distance matrix: A matrix that contains travel time and distance information between a
set of origins and destinations.
E
Elevation: The vertical distance of a point or an object above or below a reference
surface or datum. Generally, the reference surface is mean sea level. Elevation generally
refers to the vertical height of land.

Envelope: See Bounding box.

Extended postal code: A postal code that may include more information. For example,
in the USA, zip codes have five digits. But, an extended zip code, known as zip+4,
includes four more digits. These digits are used to identify a geographic segment within
the five-digit delivery area, such as a city block, a group of apartments, or a post office
box. Knowing the geographic segment aids in efficient mail sorting and delivery.

Extent: See Bounding box.

F
Federated authentication: An authentication method that allows a single
logon/authentication mechanism to be used across multiple web and mobile apps.

Feature: An object that combines a geometry with metadata information.

Feature collection: A collection of feature objects.

Find along route: A spatial query that looks for data that is within a specified detour
time or distance from a route path.

Find nearby: A spatial query that searches a fixed straight-line distance (as the crow
flies) from a point.

Fleet management: The management of commercial vehicles such as cars, trucks, ships,
and planes. Fleet management can include a range of functions, such as vehicle
financing, maintenance, telematics (tracking and diagnostics) as well as driver, speed,
fuel, and health and safety management. Fleet Management is a process used by
companies who rely on transportation in their business. The companies want to
minimize the risks and reduce their overall transportation and staff costs, while ensuring
compliance with government legislation.

Free flow speed: The free flow speed expected under ideal conditions. Usually the speed
limit.

Free form address: A full address that is represented as a single line of text.
Fuzzy search: A search that takes in a free form string of text that may be an address or
point of interest.

G
Geocode: An address or location that has been converted into a coordinate that can be
used to display that location on a map.

Geocoding: Or forward geocoding, is the process of converting address of location data


into coordinates.

Geodesic path: The shortest path between two points on a curved surface. When
rendered on Azure Maps this path appears as a curved line due to the Mercator
projection.

Geofence: A defined geographical region that can be used to trigger events when a
device enters or exists the region.

GeoJSON: Is a common JSON-based file format used for storing geographical vector
data such as points, lines, and polygons. For more information Azure Maps use of an
extended version of GeoJSON, see Extended geojson.

Geometry: Represents a spatial object such as a point, line, or polygon.

GeometryCollection: A collection of geometry objects.

GeoPol: Refers to geopolitically sensitive data, such as disputed borders and place
names.

Georeference: The process of aligning geographic data or imagery to a known


coordinate system. This process may consist of shifting, rotating, scaling, or skewing the
data.

GeoRSS: An XML extension for adding spatial data to RSS feeds.

GIS: An acronym for "Geographic Information System". A common term used to


describe the mapping industry.

GML (Geography Markup Language): An XML file extension for storing spatial data.

GPS (Global Positioning System): A system of satellites used for determining a devices
position on the earth. The orbiting satellites transmit signals that allow a GPS receiver
anywhere on earth to calculate its own location through trilateration.

GPX (GPS eXchange format): An XML file format commonly created from GPS devices.
Great-circle distance: The shortest distance between two points on the surface of a
sphere.

Greenwich Mean Time (GMT): The time at the prime meridian, which runs through the
Royal Observatory in Greenwich, England.

GUID (globally unique identifier): A string used to uniquely identify an interface, class,
type library, component category, or record.

H
Haversine formula: A common equation used for calculating the great-circle distance
between two points on a sphere.

HD maps (High Definition Maps): consists of high fidelity road network information such
as lane markings, signage, and direction lights required for autonomous driving.

Heading: The direction something is pointing or facing. See also Bearing.

Heatmap: A data visualization in which a range of colors represent the density of points
in a particular area. See also Thematic map.

Hybrid imagery: Satellite or aerial imagery that has road data and labels overlaid on top
of it.

I
IANA: An acronym for the Internet Assigned Numbers Authority. A nonprofit group that
oversees global IP address allocation.

Isochrone: An isochrone defines the area in which someone can travel within a specified
time for a mode of transportation in any direction from a given location. See also
Reachable Range.

Isodistance: Given a location, an isochrone defines the area in which someone can travel
within a specified distance for a mode of transportation in any direction. See also
Reachable Range.

K
KML: Also known as Keyhole Markup Language, is a common XML file format for storing
geographic vector data such as points, lines, and polygons.
L
Landsat: Multispectral, earth-orbiting satellites developed by NASA that gather imagery
of land. This imagery is used in many industries such as agriculture, forestry, and
cartography.

Latitude: The angular distance measured in degrees from equator in a north or south
direction.

Level of detail: See Zoom level.

Lidar: Acronym for light detection and ranging. A remote-sensing technique that uses
lasers to measure distances to reflective surfaces.

Linear interpolation: The estimation of an unknown value using the linear distance
between known values.

LineString: A geometry used to represent a line. Also known as a polyline.

Localization: Support for different languages and cultures.

Logistics: The process of moving people, vehicles, supplies, or assets in a coordinated


way.

Longitude: The angular distance measured in degrees from the prime meridian in an
east or west direction.

M
Map Tile: A rectangular image that represents a partition of a map canvas. For more
information, see the Zoom levels and tile grid documentation.

Marker: Also called a pin or pushpin, is an icon that represents a point location on a
map.

Mercator projection: A cylindrical map projection that became the standard map
projection for nautical purposes because of its ability to represent lines of constant
course, known as rhumb lines, as straight segments that conserve the angles with the
meridians. All flat map projections distort the shapes or sizes of the map when
compared to the true layout of the Earth's surface. The Mercator projection exaggerates
areas far from the equator, such that smaller areas appear larger on the map as you
approach the poles.

MultiLineString: A geometry that represents a collection of LineString objects.


MultiPoint: A geometry that represents a collection of Point objects.

MultiPolygon: A geometry that represents a collection of Polygon objects. For example,


to show the boundary of Hawaii, each island would be outlined with a polygon. Thus,
the boundary of Hawaii would thus be a MultiPolygon.

Municipality: A city or town.

Municipality subdivision: A subdivision of a municipality, such as a neighborhood or


local area name such as "downtown".

N
Navigation bar: The set of controls on a map used for adjusting the zoom level, pitch,
rotation, and switching the base map layer.

Nearby search: A spatial query that searches a fixed straight-line distance (as the crow
flies) from a point.

Neutral Ground Truth: A map that renders labels in the official language of the region it
represents and in local scripts if available.

O
Origin: A start point or location in which a user is.

P
Panning: The process of moving the map in any direction while maintaining a constant
zoom level.

Parcel: A plot of land or property boundary.

Pitch: The amount of tilt the map has relative to the vertical where 0 is looking straight
down at the map.

Point: A geometry that represents a single position on the map.

Points of interest (POI): A business, landmark, or common place of interest.

Polygon: A solid geometry that represents an area on a map.

Polyline: A geometry used to represent a line. Also known as a LineString.


Position: The longitude, latitude, and altitude (x,y,z coordinates) of a point.

Post code: See Postal code.

Postal code: A series of letters or numbers, or both, in a specific format. The postal-code
is used by the postal service of a country/region to divide geographic areas into zones
in order to simplify delivery of mail.

Primary key: The first of two subscription keys provided for Azure Maps shared key
authentication. See Shared key authentication.

Prime meridian: A line of longitude that represents 0-degrees longitude. Generally,


longitude values decrease when traveling in a westerly direction until 180 degrees and
increase when traveling in easterly directions to -180-degrees.

PRJ: A text file often accompanying a Shapefile file that contains information about the
projected coordinate system the data set is in.

Projection: A projected coordinate system based on a map projection such as transverse


Mercator, Albers equal area, and Robinson. Projection enables the earth's spherical
surface to be represented on a two-dimensional Cartesian coordinate plane. Projected
coordinate systems are sometimes referred to as map projections.

Q
Quadkey : A base-4 address index for a tile within a quadtree tiling system. For more

information, see Zoom levels and tile grid.

Quadtree : A data structure in which each node has exactly four children. The tiling

system used in Azure Maps uses a 'quadtree' structure such that as a user zooms in one
level, each map tile breaks up into four subtiles. For more information, see Zoom levels
and tile grid.

Queries Per Second (QPS): The number of queries or requests that can be made to a
service or platform within one second.

R
Radial search: A spatial query that searches a fixed straight-line distance (as the crow
flies) from a point.

Raster data: A matrix of cells (or pixels) organized into rows and columns (or a grid)
where each cell contains a value representing information, such as temperature. Raster's
include digital aerial photographs, imagery from satellites, digital pictures, and scanned
maps.

Raster layer: A tile layer that consists of raster images.

Reachable range: A reachable range defines the area in which someone can travel
within a specified time or distance, for a mode of transportation to travel, in any
direction from a location. See also Isochrone and Isodistance.

Remote sensing: The process of collecting and interpreting sensor data from a distance.

REST service: The acronym REST stands for Representational State Transfer. A REST
service is a URL-based web service that relies on basic web technology to communicate,
the most common methods being HTTP GET and POST requests. These types of services
tend to me much quicker and smaller than traditional SOAP-based services.

Reverse geocode: The process of taking a coordinate and determining the address it
represents on a map.

Reproject: See Transformation.

REST service: Acronym for Representational State Transfer. An architecture for


exchanging information between peers in a decentralized, distributed environment.
REST allows programs on different computers to communicate independently of an
operating system or platform. A service can send a Hypertext Transfer Protocol (HTTP)
request to a uniform resource locator (URL) and get back data.

Route: A path between two or more locations, which may also include additional
information such as instructions for waypoints along the route.

Requests Per Second (RPS): See Queries Per Second (QPS).

RSS: Acronym for Really Simple Syndication, Resource Description Framework (RDF) Site
Summary, or Rich Site Summary, depending on the source. A simple, structured XML
format for sharing content among different Web sites. RSS documents include key
metadata elements such as author, date, title, a brief description, and a hypertext link.
This information helps a user (or an RSS publisher service) decide what materials are
worth further investigation.

S
Satellite imagery: Imagery captured by planes and satellites pointing straight down.
Secondary key: The second of two subscriptions keys provided for Azure Maps shared
key authentication. See Shared key authentication.

Shapefile (SHP): Or ESRI Shapefile, is a vector data storage format for storing the
location, shape, and attributes of geographic features. A shapefile is stored in a set of
related files.

Shared key authentication: Shared Key authentication relies on passing Azure Maps
account generated keys with each request to Azure Maps. These keys are often referred
to as subscription keys. It's recommended that keys are regularly regenerated for
security. Two keys are provided so that you can maintain connections using one key
while regenerating the other. When you regenerate your keys, you must update any
applications that access this account to use the new keys. To learn more about Azure
Maps authentication, see Azure Maps and Azure AD and Manage authentication in
Azure Maps.

Software development kit (SDK): A collection of documentation, sample code, and


sample apps to help a developer use an API to build apps.

Spherical Mercator projection: See Web Mercator.

Spatial query: A request made to a service that performs a spatial operation. Such as a
radial search, or along a route search.

Spatial reference: A coordinate-based local, regional, or global system used to precisely


locate geographical entities. It defines the coordinate system used to relate map
coordinates to locations in the real world. Spatial references ensure spatial data from
different layers, or sources, can be integrated for accurate viewing or analysis. Azure
Maps uses the EPSG:3857 coordinate reference system and WGS 84 for input
geometry data.

SQL spatial: Refers to the spatial functionality built into SQL Azure and SQL Server 2008
and above. This spatial functionality is also available as a .NET library that can be used
independently of SQL Server. For more information, see Spatial Data (SQL Server).

Subscription key: See Shared key authentication.

Synchronous request: An HTTP request opens a connection and waits for a response.
Browsers limit the number of concurrent HTTP requests that can be made from a page.
If multiple long running synchronous requests are made at the same time, then this limit
can be reached. Requests are delayed until one of the other requests has completed.

T
Telematics: Sending, receiving, and storing information via telecommunication devices
along with effecting control on remote objects.

Temporal data: Data that specifically refers to times or dates. Temporal data may refer
to discrete events, such as lightning strikes; moving objects, such as trains; or repeated
observations, such as counts from traffic sensors.

Terrain: An area of land having a particular characteristic, such as sandy terrain or


mountainous terrain.

Thematic maps: A thematic map is a simple map made to reflect a theme about a
geographic area. A common scenario for this type of map is to color the administrative
regions such as countries/regions based on some metric of data.

Tile layer: A layer displayed by assembling map tiles (rectangular sections) into a
continuous layer. The tiles are either raster image tiles or vector tiles. Raster tile layers
are typically rendered ahead of time, and they're stored as images on a server. Raster
tile layers may use a large storage space. Vector tile layers are rendered near real time
within the client application. Thus, the server-side storage requirements are smaller for
vector tile layers.

Time zone: A region of the globe that observes a uniform standard time for legal,
commercial, and social purposes. Time zones tend to follow the boundaries of
countries/regions and their subdivisions.

Transaction: Azure Maps uses a transactional licensing model where;

One transaction is created for every 15 map or traffic tiles requested.


One transaction is created for each API call to one of the services in Azure Maps.
Searching and routing are examples of Azure Maps service.

Transformation: The process of converting data between different geographic


coordinate systems. You may, for example, have some data that was captured in the
United Kingdom and based on the OSGB 1936 geographic coordinate system. Azure
Maps uses the EPSG:3857 coordinate reference system variant of WGS84. As such to
display the data correctly, it needs to have its coordinates transformed from one system
to another.

Traveling Salesmen Problem (TSP): A Hamiltonian circuit problem in which a


salesperson must find the most efficient way to visit a series of stops, then return to the
starting location.

Trilateration: The process of determining the position of a point on the earth's surface,
with respect to two other points, by measuring the distances between all three points.
Turn-by-turn navigation: An application that provides route instructions for each step
of a route as the users approaches the next maneuver.

V
Vector data: Coordinate based data that is represented as points, lines, or polygons.

Vector tile: An open data specification for storing geospatial vector data using the same
tile system as the map control. See also Tile layer.

Vehicle Routing Problem (VRP): A class of problems, in which a set of ordered routes
for a fleet of vehicles is calculated while taking into consideration as set of constraints.
These constraints may include delivery time windows, multiple route capacities, and
travel duration constraints.

Voronoi diagram: A partition of space into areas, or cells, that surrounds a set of
geometric objects, usually point features. These cells, or polygons, must satisfy the
criteria for Delaunay triangles. All locations within an area are closer to the object it
surrounds than to any other object in the set. Voronoi diagrams are often used to
delineate areas of influence around geographic features.

W
Waypoint: A waypoint is a specified geographical location defined by longitude and
latitude that is used for navigational purposes. Often used to represent a point in which
someone navigates a route through.

Waypoint optimization: The process of reordering a set of waypoints to minimize the


travel time or distance required to pass through all provided waypoints. Depending on
the complexity of the optimization, this optimization is often referred to as the Traveling
Salesmen Problem or Vehicle Routing Problem.

Web Map Service (WMS): WMS is an Open Geographic Consortium (OGC) standard
that defines image-based map services. WMS services provide map images for specific
areas within a map on demand. Images include prerendered symbology and may be
rendered in one of several named styles if defined by the service.

Web Mercator: Also known as Spherical Mercator projection. It's a slight variant of the
Mercator projection, one used primarily in Web-based mapping programs. It uses the
same formulas as the standard Mercator projection as used for small-scale maps.
However, the Web Mercator uses the spherical formulas at all scales, but large-scale
Mercator maps normally use the ellipsoidal form of the projection. The discrepancy is
imperceptible at the global scale, but it causes maps of local areas to deviate slightly
from true ellipsoidal Mercator maps, at the same scale.

WGS84: A set of constants used to relate spatial coordinates to locations on the surface
of the map. The WGS84 datum is the standard one used by most online mapping
providers and GPS devices. Azure Maps uses the EPSG:3857 coordinate reference
system variant of WGS84.

Z
Z-coordinate: See Altitude.

Zip code: See Postal code.

Zoom level: Specifies the level of detail and how much of the map is visible. When
zoomed all the way to level 0, the full world map is often visible. But, the map shows
limited details such as country/region names, borders, and ocean names. When zoomed
in closer to level 17, the map displays an area of a few city blocks with detailed road
information. In Azure Maps, the highest zoom level is 22. For more information, see the
Zoom levels and tile grid documentation.
Create elevation data & services
Article • 03/19/2023

This guide describes how to use USGS worldwide DEM data from their SRTM mission
with 30m accuracy to build an Elevation service on the Microsoft Azure Cloud .

This article describes how to:

Create Contour line vector tiles and RGB-encoded DEM tiles.


Create Elevation API using Azure Function and RGB-encoded DEM tiles from Azure
Blob Storage.
Create Contour line vector tile service using Azure Function and PostgreSQL.

Prerequisites
This guide requires the use of the following third-party software and data:

USGS Data. DEM data can be downloaded as GeoTiff with 1 arc second coverage
per tile through the USGS EarthExplorer . This requires an EarthExplorer account,
but the data can be downloaded for free.
The QGIS desktop GIS application is used to process and smoothen the Raster
tiles. QGIS is free to download and use. This guide uses QGIS version 3.26.2-
Buenos Aires.
The rio-rgbify Python package, developed by MapBox, is used to encode the
GeoTIFF as RGB.
PostgreSQL database with the PostGIS spatial extension.

Create Contour line vector tiles and RGB-


encoded DEM tiles
This guide uses the 36 tiles covering the state of Washington, available from USGS
EarthExplorer .

Download raster tiles from USGS EarthExplorer

Search criteria

Select the region that you want raster tiles for. For demonstration purposes, this guide
uses the "Polygon" method to select the region on the map.
1. Navigate to the USGS EarthExplorer .

2. In the Search Criteria tab, select Polygon then click on the map to create the
boundary.

Data sets

1. Select the Data Sets tab.

2. Select SRTM 1 Arc-Second Global from the Digital Elevations section.


Results
1. Select Results >> to view the tiles for the selected region and data set.

2. The list of downloadable tiles appear on the results page. To download only tiles
you want, select the Download Options button on the result card for each tile,
selecting the option GeoTIFF 1 Arc-Second and repeat this step for the remaining
tiles.

3. Alternatively, use the bulk download option and select GeoTIFF 1 Arc-second.

Add raster tiles to QGIS


Once you have the raster tiles you need, you can import them in QGIS.

1. Add raster tiles to QGIS by dragging the files to the QGIS layer tab or selecting
Add Layer in the Layer menu.

2. When the raster layers are loaded into QGIS, there can be different shades of tiles.
Fix this by merging the raster layers, which result in a single smooth raster image in
GeoTIFF format. To do this, select Miscellaneous from the Raster menu, then
Merge...

3. Reproject the merged raster layer to EPSG:3857 (WGS84 / Pseudo-Mercator) using


Save Raster Layer as accessed by right clicking on the merged raster layer in the
table of content -> Export -> Save As option. EPSG:3857 is required to use it with
Azure Maps Web SDK.
4. If you only want to create contour line vector tiles, you can skip the following steps
and go to Create Contour line vector tile service using Azure Function and
PostgreSQL.

5. To create an Elevation API, the next step is to RGB-Encode the GeoTIFF. This can be
done using rio-rgbify , developed by MapBox. There are some challenges
running this tool directly in Windows, so it's easier to run from WSL. Below are the
steps in Ubuntu on WSL:

Bash

sudo apt get update


sudo apt get upgrade
sudo apt install python3-pip
pip install rio-rgbify
PATH="$PATH:/home/<user /.local/bin"
# The following two steps are only necessary when mounting an external
hard drive or USB flash drive:
sudo mkdir /mnt/f
sudo mount -t drvfs D: /mnt/f

rio rgbify -b -10000 -i 0.1 wa_1arc_v3_merged_3857.tif


wa_1arc_v3_merged_3857_rgb.tif

# The following steps are only necessary when unmounting an external


hard drive or USB flash drive:
cd \~
sudo umount /mnt/f/

The RGB-encoded GeoTIFF allows you to retrieve R, G and B values for a pixel and
calculate the elevation from these values:

elevation (m) = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)

6. Next, create a tile set to use with the map control and/or use it to get Elevation for
any geographic coordinates within the map extent of the tile set. The tile set can
be created in QGIS using the Generate XYZ tiles (Directory) tool.
7. Save the location of the tile set, you'll use it in the next Section.

Create Elevation API using Azure Function and


RGB-encoded DEM tiles from Azure Blob
Storage
The RGB encoded DEM Tiles need to be uploaded to a database storage before it can
be used with the Azure Functions to create an API.

1. Upload the tiles to Azure Blob Storage. Azure Storage Explorer is a useful tool for
this purpose.
Uploading tiles to Azure Blob Storage can take several minutes to complete.

2. Once the upload is complete, you can create Azure Function to build an API that
returns elevation for a given geographic coordinate.

This function receives a coordinate pair, determine the tile that covers it at zoom
level 14, then determine the pixel coordinates within that tile that matches the
geographic coordinates. It then retrieves the tile, gets the RGB values for that pixel,
then uses the following formula to determine the elevation:

elevation (m) = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)

Python

import logging
import json
import azure.functions as func
from PIL import Image
import requests
from io import BytesIO
import math

def main(req: func.HttpRequest) -> func.HttpResponse:


logging.info('Python HTTP trigger function processed a request.')

# http://localhost:7071/api/GetElevationPoint?
lng=-122.01911&lat=47.67091
zoom = 14
lng = float(req.params.get('lng'))
lat = float(req.params.get('lat'))
logging.info('Lng: ' + str(lng) + ' / lat: ' + str(lat))

# Calculate th global pixel x and y coordinates for a lng / lat


gx = (lng + 180) / 360
sinLat = math.sin(lat * math.pi / 180)
gy = 0.5 - math.log((1 + sinLat) / (1 - sinLat)) / (4 * math.pi)
mapSize = math.ceil(256 * math.pow(2, zoom));
gxc = min(max(gx * mapSize + 0.5, 0), mapSize - 1);
gyc = min(max(gy * mapSize + 0.5, 0), mapSize - 1);

# Calclate the tile x and y covering the lng / lat


tileX = int(gxc / 256)
tileY = int(gyc / 256)

# Calculate the pixel coordinates for the tile covering the lng / lat
tilePixelX = math.floor(gxc - (tileX * 256))
tilePixelY = math.floor(gyc - (tileY * 256))

response = requests.get("{BlobStorageURL}" + str(zoom) + "/" +


str(tileX) + "/" + str(tileY) + ".png")
im = Image.open(BytesIO(response.content))

pix = im.load()
r = pix[tilePixelX,tilePixelY][0]
g = pix[tilePixelX,tilePixelY][1]
b = pix[tilePixelX,tilePixelY][2]

# elevation (m) = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1)


ele = -10000 + ((r * 256 * 256 + g * 256 + b) * 0.1)

jsonRes = {"elevation": + ele}


logging.info('Response: ' + json.dumps(jsonRes))

if lng and lat:


return func.HttpResponse(
json.dumps(jsonRes),
mimetype="application/json",
)
else:
return func.HttpResponse(
"ERROR: Missing parameter!",
status_code=400
)

To see the results of the code sample, run it locally:

HTTP

localhost:7071/api/GetElevationPoint?lng=-122.01911&lat=47.67091`

Create Contour line vector tile service using


Azure Function and PostgreSQL
This section describes the steps to create and process contour lines in QGIS, upload
them to PostgreSQL then create an Azure Function to Query PostgreSQL to return
vector tiles.

1. In QGIS, open the merged raster tiles in the EPSG:4326 projection created in step 3
of Create Contour line vector tiles and RGB-encoded DEM tiles.

2. Select Extraction -> Contour from the Raster menu to open the Contour tool.

Selecting Run creates contour lines and add them as a layer to the map. some of
the contour line edges may appear a little rough. This will be addressed in the next
step.
3. Select Toolbox from the Processing menu to bring up the Processing Toolbox.

4. Then select Smooth in the Vector geometry section of the Processing Toolbox.
7 Note

Contour line smoothing can be substantially improved but at the cost of


increased file-size.

5. Load the contour lines to the database. This guide uses the free version of
PostgreSQL database that runs on localhost. You can also load them to the
Azure Database for PostgreSQL.

The next step requires a PostgreSQL database with PostGIS extension.

6. To create a connection from QGIS to PostgreSQL, select Add Layer -> Add PostGIS
Layers from the Layer menu, then select the New button.
7. Next, load Data from QGIS to PostgreSQL using the Database Manager in QGIS. To
do this, select DB Manager from the Database menu.
8. Connect to the PostGIS database and select Import Layer/File... to Import contour
lines to the database.
9. You can now use an Azure Function to Query PostgreSQL and return vector tiles for
the contour lines. The tile server can be used with the Azure Maps web SDK to
create a web app that displays contour lines on the map.

Python

import logging
from wsgiref import headers
import azure.functions as func
import psycopg2
# Database to connect to
DATABASE = {
'user': 'postgres',
'password': '{password}',
'host': 'localhost',
'port': '5432',
'database': '{database}'
}
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
DATABASE_CONNECTION = None
# get url parameters http://localhost:7071/api/tileserver?zoom=
{z}&x={x}&y={y}
# http://localhost:7071/api/tileserver?zoom=16&x=10556&y=22870
zoom = int(req.params.get('zoom'))
x = int(req.params.get('x'))
y = int(req.params.get('y'))
table = req.params.get('table')
# calculate the envelope of the tile
# Width of world in EPSG:3857
worldMercMax = 20037508.3427892
worldMercMin = -1 * worldMercMax
worldMercSize = worldMercMax - worldMercMin
# Width in tiles
worldTileSize = 2 ** zoom

# Tile width in EPSG:3857


tileMercSize = worldMercSize / worldTileSize

# Calculate geographic bounds from tile coordinates


# XYZ tile coordinates are in "image space" so origin is
# top-left, not bottom right
xmin = worldMercMin + tileMercSize * x
xmax = worldMercMin + tileMercSize * (x + 1)
ymin = worldMercMax - tileMercSize * (y + 1)
ymax = worldMercMax - tileMercSize * y
# Generate SQL to materialize a query envelope in EPSG:3857.
# Densify the edges a little so the envelope can be
# safely converted to other coordinate systems.
DENSIFY_FACTOR = 4
segSize = (xmax - xmin)/DENSIFY_FACTOR
sql01 = 'ST_Segmentize(ST_MakeEnvelope(' + str(xmin) + ', ' +
str(ymin) + ', ' + str(xmax) + ', ' + str(ymax) + ', 3857), ' +
str(segSize) +')'

# Generate a SQL query to pull a tile worth of MVT data


# from the table of interest.
# Materialize the bounds
# Select the relevant geometry and clip to MVT bounds
# Convert to MVT format
sql02 = 'WITH bounds AS (SELECT ' + sql01 + ' AS geom, ' + sql01 +
'::box2d AS b2d), mvtgeom AS (SELECT ST_AsMVTGeom(ST_Transform(t.geom,
3857), bounds.b2d) AS geom, elev FROM contourlines_smooth t, bounds
WHERE ST_Intersects(t.geom, ST_Transform(bounds.geom, 4326))) SELECT
ST_AsMVT(mvtgeom.*) FROM mvtgeom'

# Run tile query SQL and return error on failure conditions


# Make and hold connection to database
if not DATABASE_CONNECTION:
try:
DATABASE_CONNECTION = psycopg2.connect(**DATABASE)
logging.info('Connected to database.')
except (Exception, psycopg2.Error) as error:
logging.error('ERROR: Cannot connect to database.')
# Query for MVT
with DATABASE_CONNECTION.cursor() as cur:
cur.execute(sql02)
if not cur:
logging.error('ERROR: SQL Query failed.')
pbf = cur.fetchone()[0]
logging.info('Queried database')

if zoom and x and y:


return func.HttpResponse(
# f"This HTTP triggered function executed
successfully.\n\nzoom={zoom}\nx={x}\ny={y}\n\nxmin={xmin}\nxmax=
{xmax}\nymin={ymin}\nymax={ymax}\n\nsql01={sql01}\n\nsql02={sql02}",
bytes(pbf),
status_code=200,
headers={"Content-type": "application/vnd.mapbox-vector-
tile","Access-Control-Allow-Origin": "*"}
)
else:
return func.HttpResponse(
"ERROR: Missing parameter!",
status_code=400
)

To see the results of the code sample, run it locally:

HTTP

http://localhost:7071/api/tileserver?zoom={z}&x={x}&y={y}

You might also like