Tutorial: Implement IoT spatial analytics by using Azure Maps

In an IoT scenario, it's common to capture and track relevant events that occur in space and time. Examples include fleet management, asset tracking, mobility, and smart city applications. This tutorial guides you through a solution that tracks used car rental movement by using the Azure Maps APIs.

In this tutorial you will:

  • Create an Azure storage account to log car tracking data.
  • Upload a geofence to the Azure Maps Data service by using the Data Upload API.
  • Create a hub in Azure IoT Hub, and register a device.
  • Create a function in Azure Functions, implementing business logic based on Azure Maps spatial analytics.
  • Subscribe to IoT device telemetry events from the Azure function via Azure Event Grid.
  • Filter the telemetry events by using IoT Hub message routing.


  1. Sign in to the Azure portal.

  2. Create an Azure Maps account.

  3. Obtain a primary subscription key, also known as the primary key or the subscription key. For more information, see manage authentication in Azure Maps.

  4. Create a resource group. In this tutorial, we'll name our resource group ContosoRental, but you can choose whatever name you like.

  5. Download the rentalCarSimulation C# project.

This tutorial uses the Postman application, but you can choose a different API development environment.

Use case: rental car tracking

Let's say that a car rental company wants to log location information, distance traveled, and running state for its rental cars. The company also wants to store this information whenever a car leaves the correct authorized geographic region.

The rental cars are equipped with IoT devices that regularly send telemetry data to IoT Hub. The telemetry includes the current location and indicates whether the car's engine is running. The device location schema adheres to the IoT Plug and Play schema for geospatial data. The rental car's device telemetry schema looks like the following JSON code:

    "data": {
        "properties": {
            "Engine": "ON"
        "systemProperties": {
            "iothub-content-type": "application/json",
            "iothub-content-encoding": "utf-8",
            "iothub-connection-device-id": "ContosoRentalDevice",
            "iothub-connection-auth-method": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}",
            "iothub-connection-auth-generation-id": "636959817064335548",
            "iothub-enqueuedtime": "2019-06-18T00:17:20.608Z",
            "iothub-message-source": "Telemetry"
        "body": {
            "location": {
                "type": "Point",
                "coordinates": [ -77.025988698005662, 38.9015330523316 ]

In this tutorial, you only track one vehicle. After you set up the Azure services, you need to download the rentalCarSimulation C# project to run the vehicle simulator. The entire process, from event to function execution, is summarized in the following steps:

  1. The in-vehicle device sends telemetry data to IoT Hub.

  2. If the car engine is running, the hub publishes the telemetry data to Event Grid.

  3. An Azure function is triggered because of its event subscription to device telemetry events.

  4. The function logs the vehicle device location coordinates, event time, and the device ID. It then uses the Spatial Geofence Get API to determine whether the car has driven outside the geofence. If it has traveled outside the geofence boundaries, the function stores the location data received from the event into a blob container. The function also queries the Search Address Reverse to translate the coordinate location to a street address, and stores it with the rest of the device location data.

The following diagram shows a high-level overview of the system.

Diagram of system overview.

The following figure highlights the geofence area in blue. The rental car's route is indicated by a green line.

Figure showing geofence route.

Create an Azure storage account

To store car violation tracking data, create a general-purpose v2 storage account in your resource group. If you haven't created a resource group, follow the directions in create a resource group. In this tutorial, you'll name your resource group ContosoRental.

To create a storage account, follow the instructions in create a storage account. In this tutorial, name the storage account contosorentalstorage, but in general you can name it anything you like.

When you successfully create your storage account, you then need to create a container to store logging data.

  1. Go to your newly created storage account. In the Essentials section, select the Containers link.

    Screenshot of containers for blob storage.

  2. In the upper-left corner, select + Container. A panel appears on the right side of the browser. Name your container contoso-rental-logs, and select Create.

    Screenshot of create a blob container.

  3. Go to the Access keys pane in your storage account, and copy the Storage account name and the Key value in the key1 section. You need both of these values in the "Create an Azure Function and add an Event Grid subscription" section.

    Screenshot of copy storage account name and key.

Upload a geofence

Next, use the Postman app to upload the geofence to Azure Maps. The geofence defines the authorized geographical area for our rental vehicle. You'll be using the geofence in your Azure function to determine whether a car has moved outside the geofence area.

Follow these steps to upload the geofence by using the Azure Maps Data Upload API:

  1. Open the Postman app, select New again. In the Create New window, select HTTP Request, and enter a request name for the request.

  2. Select the POST HTTP method in the builder tab, and enter the following URL to upload the geofence to the Data Upload API. Make sure to replace {Your-Azure-Maps-Primary-Subscription-key} with your primary subscription key.


    In the URL path, the geojson value against the dataFormat parameter represents the format of the data being uploaded.

  3. Select Body > raw for the input format, and choose JSON from the drop-down list. Open the JSON data file, and copy the JSON into the body section. Select Send.

  4. Select Send and wait for the request to process. After the request completes, go to the Headers tab of the response. Copy the value of the Operation-Location key, which is the status URL.

  5. To check the status of the API call, create a GET HTTP request on the status URL. You'll need to append your primary subscription key to the URL for authentication. The GET request should like the following URL:

  6. When the request completes successfully, select the Headers tab in the response window. Copy the value of the Resource-Location key, which is the resource location URL. The resource location URL contains the unique identifier (udid) of the uploaded data. Copy the udid for later use in this tutorial.

    Copy the resource location URL.

Create an IoT hub

IoT Hub enables secure and reliable bi-directional communication between an IoT application and the devices it manages. For this tutorial, you want to get information from your in-vehicle device to determine the location of the rental car. In this section, you create an IoT hub within the ContosoRental resource group. This hub will be responsible for publishing your device telemetry events.

To create an IoT hub in the ContosoRental resource group, follow the steps in create an IoT hub.

Register a device in your IoT hub

Devices can't connect to the IoT hub unless they're registered in the IoT hub identity registry. Here, you'll create a single device with the name, InVehicleDevice. To create and register the device within your IoT hub, follow the steps in register a new device in the IoT hub. Make sure to copy the primary connection string of your device. You'll need it later.

Create a function and add an Event Grid subscription

Azure Functions is a serverless compute service that allows you to run small pieces of code ("functions"), without the need to explicitly provision or manage compute infrastructure. To learn more, see Azure Functions.

A function is triggered by a certain event. Here, you'll create a function that is triggered by an Event Grid trigger. Create the relationship between trigger and function by creating an event subscription for IoT Hub device telemetry events. When a device telemetry event occurs, your function is called as an endpoint, and receives the relevant data for the device you previously registered in IoT Hub.

Here's the C# script code that your function will contain.

Now, set up your Azure function.

  1. In the Azure portal dashboard, select Create a resource. Type Function App in the search text box. Select Function App > Create.

  2. On the Function App creation page, name your function app. Under Resource Group, select ContosoRental from the drop-down list. Select .NET as the Runtime Stack. Select 3.1 as the Version. At the bottom of the page, select Next: Hosting >.

    Screenshot of create a function app.

  3. For Storage account, select the storage account you created in Create an Azure storage account. Select Review + create.

  4. Review the function app details, and select Create.

  5. After the app is created, you add a function to it. Go to the function app. Select the Functions pane. At the top of the page, select + Add. The function template panel appears. Scroll down the panel, and select Azure Event Grid trigger.


    The Azure Event Hub Trigger and the Azure Event Grid Trigger templates have similar names. Make sure you select the Azure Event Grid Trigger template.

    Screenshot of create a function.

  6. Give the function a name. In this tutorial, you'll use the name, GetGeoFunction, but in general you can use any name you like. Select Create function.

  7. In the left menu, select the Code + Test pane. Copy and paste the C# script into the code window.

    Copy/Screenshot of paste code into function window.

  8. In the C# code, replace the following parameters:

    • Replace SUBSCRIPTION_KEY with your Azure Maps account primary subscription key.
    • Replace UDID with the udid of the geofence you uploaded in Upload a geofence.
    • The CreateBlobAsync function in the script creates a blob per event in the data storage account. Replace the ACCESS_KEY, ACCOUNT_NAME, and STORAGE_CONTAINER_NAME with your storage account's access key, account name, and data storage container. These values were generated when you created your storage account in Create an Azure storage account.
  9. In the left menu, select the Integration pane. Select Event Grid Trigger in the diagram. Type in a name for the trigger, eventGridEvent, and select Create Event Grid subscription.

    Screenshot of add event subscription.

  10. Fill out the subscription details. Name the event subscription. For Event Schema, select Event Grid Schema. For Topic Types, select Azure IoT Hub Accounts. For Resource Group, select the resource group you created at the beginning of this tutorial. For Resource, select the IoT hub you created in "Create an Azure IoT hub." For Filter to Event Types, select Device Telemetry.

    After choosing these options, you'll see the Topic Type change to IoT Hub. For System Topic Name, you can use the same name as your resource. Finally, in the Endpoint details section, select Select an endpoint. Accept all settings and select Confirm Selection.

    Screenshot of create event subscription.

  11. Review your settings. Make sure that the endpoint specifies the function you created in the beginning of this section. Select Create.

    Screenshot of create event subscription confirmation.

  12. Now you're back at the Edit Trigger panel. Select Save.

Filter events by using IoT Hub message routing

When you add an Event Grid subscription to the Azure function, a messaging route is automatically created in the specified IoT hub. Message routing allows you to route different data types to various endpoints. For example, you can route device telemetry messages, device life-cycle events, and device twin change events. For more information, see Use IoT Hub message routing.

Screenshot of message routing in IoT hub.

In your example scenario, you only want to receive messages when the rental car is moving. Create a routing query to filter the events where the Engine property equals "ON". To create a routing query, select the RouteToEventGrid route and replace the Routing query with "Engine='ON'". Then select Save. Now the IoT hub only publishes device telemetry where the engine is on.

Screenshot of filter routing messages.


There are various ways to query IoT device-to-cloud messages. To learn more about message routing syntax, see IoT Hub message routing.

Send telemetry data to IoT Hub

When your Azure function is running, you can now send telemetry data to the IoT hub, which will route it to Event Grid. Use a C# application to simulate location data for an in-vehicle device of a rental car. To run the application, you need .NET Core SDK 3.1 on your development computer. Follow these steps to send simulated telemetry data to the IoT hub:

  1. If you haven't done so already, download the rentalCarSimulation C# project.

  2. Open the simulatedCar.cs file in a text editor of your choice, and replace the value of the connectionString with the one you saved when you registered the device. Save changes to the file.

  3. Make sure you have .NET Core installed on your machine. In your local terminal window, go to the root folder of the C# project and run the following command to install the required packages for simulated device application:

    dotnet restore
  4. In the same terminal, run the following command to build and run the rental car simulation application:

    dotnet run

Your local terminal should look like the one below.

Screenshot of terminal output.

If you open the blob storage container now, you can see four blobs for locations where the vehicle was outside the geofence.

Screenshot of view blobs inside container.

The following map shows four vehicle location points outside the geofence. Each location was logged at regular time intervals.

Screenshot of violation map.

Explore Azure Maps and IoT

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

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

To get a list of devices that are Azure certified for IoT, visit:

Clean up resources

There are no resources that require cleanup.

Next steps

To learn more about how to send device-to-cloud telemetry, and the other way around, see: