Front-End Web & Mobile

Getting started with Amazon Location

This post was written by Shu Sia Lukito, Partner Solutions Architect

On-line shopping is so common today it will be difficult to find anybody who doesn’t use it. Delivery is a crucial component of this model. E-commerce providers rely heavily on robust and reliable delivery systems.

There is a single customer experience we want to focus on this post, with several distinct use cases. First, customers want to know when their packages will arrive and get notifications. Secondly, drivers should get real time notifications if the delivery system detects any anomaly. For example: notify the driver if an incorrect delivery has been made. This is not uncommon in newer communities where maps are not as up to date as mature communities. By alerting the driver, he or she will have the opportunity to make corrective actions. For the second use case, we want to include a legible address of the actual delivery location instead of the coordinates.

This post walks you through the architecture and the steps required to implement the use cases described above. For the first use case, you will use Amazon Location’s geofence feature to automatically detect the driver when the location updates from the driver’s device enters the geofence. For the second use case, you will use Amazon Location reverse geocoding feature to convert location coordinates of the actual delivery address to a legible address. But, before getting started, let’s learn about Amazon Location service.

What is Amazon Location?

Amazon Location lets you add location data to applications, which includes capabilities such as maps, points of interest, geocoding, routing, geofences, and tracking. Amazon Location provides cost-effective location-based services (LBS) using high-quality data from global, trusted providers Esri and HERE.

In this post, we will be focusing on the Trackers, Geofencing and Places features of Amazon Location.

Trackers

Amazon Location Service Trackers lets you retrieve current and historical location of devices running your tracking-enabled application. You can also link Trackers with Amazon Location Service Geofences to automatically evaluate location updates from your devices against your geofences. While using Trackers, sensitive location information of your tracked devices never leaves your AWS account. This helps protect sensitive information from third parties, protect user privacy, and reduce security risks.

Geofencing

Amazon Location Geofences lets you give your application the ability to detect and act when a device enters or exits a defined geographical boundary known as a geofence. Automatically send an entry or exit event to Amazon EventBridge when a geofence breach is detected. This lets you initiate downstream actions such as sending a notification to a target.

Places

Amazon Location Places lets you integrate search functionality into your application, convert addresses into geographic coordinates in latitude and longitude (geocoding), and convert a coordinate into a street address (reverse geocoding). Amazon Location Service sources high-quality geospatial data from Esri and HERE to support Places functions.

How does Amazon Location work?

You can securely add location data to your application with Amazon Location. Begin exploring some of the capabilities using the visual and interactive tool available on the Amazon Location console. Using the explore tool, you can manipulate a default map, search for points of interest, draw geofences around areas of interest, and simulate sending device location to a tracker.

In this post, you will use the Amazon Location features and Amazon Location SDK for Python to build selected features in a package delivery use case focusing on customer notification and delivery accuracy.

Use Case 1: Notifying Customers of Pending Delivery

This section walks you through a use case where a customer gets notified when the delivery driver enters the geofence. This can be an indication of how far the driver is from the destination. You will start by creating a geofence around the delivery address. Next, you will simulate the driver’s device publishing location updates to the tracker. Amazon Location geofence will automatically detect the device when it enters the geofence and send the event to Amazon EventBridge. This will initiate downstream action to send notification to the customer indicating pending delivery.

Prerequisites

For this walkthrough, you should have the following prerequisites:

Follow these steps to walkthrough the first use case:

  • Create a geofence which will take a set of coordinates of a virtual boundary set up around a geographical location as input
  • Create a tracker and link it to the geofence. This will cause the linked geofence to automatically evaluate location updates from the delivery driver against your geofence
  • Set up Amazon Simple Notification Service (SNS) to manage the notifications
  • Create a Lambda function that will be invoked by the EventBridge rule. This function will publish a message to SNS and trigger a notification to the customer
  • Create an Amazon EventBridge rule that watches for ENTER geofence event and invoke a Lambda function when the event gets triggered
  • Create another AWS Lambda function that can be directly called by your client application (e.g., mobile devices) to test transmitting location updates for the ENTER geofence events to be detected by the EventBridge rule which in turn, invokes the notification

Create a geofence

A geofencing application evaluates a tracked device’s position relative previously-registered areas of interest. This enables actions to be taken based on position updates.

Once you have implemented your geofencing solution, your geofence collection resource will emit the following events:

  • ENTER — An event emitted when a tracked device enters a geofence within a geofence collection.
  • EXIT — An event emitted when a tracked device exits a geofence within a geofence collection.

Follow these steps to create a geofence:

  1. In to the Amazon Location console, go to Geofence collections page
  2. Create a geofence collection and set the name to delivery-geofence-collection
  3. Choose No, do not create a rule under Configure EventBridge option
  4. Add a geofence by uploading a JSON file containing your coordinates (see Geofence Coordinates for example on how to create geofence coordinates)

Here’s an example of a geofence for North Vancouver area.

{
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": { "id": "north-vancouver", "city": "Vancouver" },
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
                [
                    -123.11141927445664,
                    49.342337982757925
                ],
                [
                    -123.09564439341543,
                    49.3273306266273
                ],
                [
                    -123.07613190989761,
                    49.32699031132709
                ],
                [
                    -123.07448296762831,
                    49.33539003824375
                ],
                [
                    -123.0767914868052,
                    49.339884825716176
                ],
                [
                    -123.09363818032138,
                    49.343286981509834
                ],
                [
                    -123.11141927445664,
                    49.342337982757925
                ]
            ]
          ]
        }
      }
    ]
  }

Create a tracker

In this step, you will create a tracker resource to receive location updates from devices capable of transmitting a location update, such as a mobile phone or GPS receiver.

Steps:

  1. In to the Amazon Location console, go to Tracker page
  2. Create a tracker and set the name to delivery-tracker
  3. Link delivery-tracker to delivery-geofence-collection

Set up notification

Amazon Simple Notification Service (SNS) is a fully managed messaging service for both application-to-application (A2A) and application-to-person (A2P) communication. The A2P functionality enables you to send messages to users at scale via SMS, mobile push, and email. In this step, you will use SNS to notify the customer when the driver enters the geofence.

Steps:

  1. In to the Amazon SNS console, go to Topics page
  2. Create a Standard topic and set the name and display name to delivery-topic
  3. Create a subscription, select Email as the protocol and enter the email address as endpoint

Next, Edit the subscription you just created and add a subscription filter policy. You need this subscription filter policy because by default, SNS topic subscriber receives every message published to the topic. In this case, you only want the customer to get notified. If you select Email as the subscription protocol, you use the policy below as an example. In this example, the filter policy is based on email address.

{
  "email": [
    "youremail@domain.com"
  ]
}

Create a Lambda function

AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers. This function will publish a message to SNS and trigger a notification to the customer.

Steps:

  • In the AWS Lambda console, go to Function page
  • Create a function from scratch and set the name to delivery-notifier
  • Select Python 3.8 for the runtime
  • Replace the content of lambda_function.py with the code below. Replace the region, account number, and email attribute accordingly
import json
import boto3

sns_client = boto3.client('sns')

def lambda_handler(event, context):
    print(event)
    
    topicArn = 'arn:aws:sns:us-east-1:<acct-num>:delivery-topic'
    subject = 'Geofence notification'
    message = 'Your delivery is within the area, you should receive it soon!'
    
    response = sns_client.publish(
        TopicArn=topicArn,
        Subject=subject,
        Message=message,
        MessageAttributes={"email" : { "DataType":"String", "StringValue":"youremail@domain.com"}})
    return {
        'statusCode': 200,
        'body': json.dumps('Success!')
    }
  • From the Configuration tab, go to Permissions
  • Click on the execution role. The role name should be similar to delivery-notifier-role-<id>
  • Add an inline policy, select the JSON tab and overwrite the policy with the following. This will allow Lambda to send notification with SNS
  • Choose Review Policy and set the name to DeliveryNotification and create the policy. Replace the region to match the region you’re operating from.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "arn:aws:sns:us-east-2:*:delivery-topic"
        }
    ]
}

Create EventBridge rule

Amazon EventBridge is a serverless event bus that efficiently connects applications together using data from AWS services like Amazon Location. EventBridge receives geofence events from Amazon Location and routes that data to targets like SNS. In this step, you are creating an EventBridge rule that will act on Amazon Location geofence ENTER event.

Steps:

  1. In to the Amazon EventBridge console, go to Rules page
  2. Create a rule and set the name to delivery-geofence-enter
  3. Select Event pattern under Define pattern
  4. Select Pre-defined pattern by service under Event matching pattern, AWS as the service provider, Amazon Location Service as the service name, Location Geofence Event as the event type, and ENTER under specific type
  5. Select Amazon Location Service under service name
  6. Leave the AWS default event bus selected
  7. Select Lambda as the target and the delivery-notifier as the function
  8. Create the rule

Set up a Lambda function

This Lambda function will publish the driver’s location to Amazon Location tracker. You can call this Lambda function from your mobile application to transmit a location update.

Notes:

  • If you already have a source of position updates, like IoT Core or a fleet of mobile devices, you can wire that up the delivery-tracker tracker instead
  • If you want to simulate position updates with a certain interval (e.g., every 1 minute), you can follow the steps in Simulate position updates instead

Steps:

  • In to the AWS Lambda console, go to Function page
  • Create a function from scratch and set the name to delivery-tracker-publisher
  • Select Python 3.8 for the runtime
  • Replace the content of lambda_function.py with the code below
from datetime import datetime
import json
import os

import boto3

# Update this to match the name of your Tracker resource
TRACKER_NAME = "delivery-tracker"

# load the side-loaded Amazon Location Service model; necessary during Public Preview
os.environ["AWS_DATA_PATH"] = os.environ["LAMBDA_TASK_ROOT"]

client = boto3.client("location")

def lambda_handler(event, context):

    updates = []
    updates.append({
        'DeviceId': event['deviceid'],
        'SampleTime': datetime.now().isoformat(),
        'Position': [event['long'], event['lat']]
    })
    
    client.batch_update_device_position(TrackerName=TRACKER_NAME, Updates=updates)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Success')
    }
  • Create a file named service-2.json in a location/2020-11-19 folder as described in the Troubleshooting section. This step is only necessary if this region is not supported for general availability. Please ignore otherwise.
  • From the Configuration tab, go to Permissions
  • Choose the execution role (the name should be similar to delivery-tracker-publisher-role-<id> and it will take you to the Identity and Access Management (IAM) console
  • From the role’s summary page, choose Add inline policy
  • Select the JSON tab and overwrite the policy with the JSON below. This will allow your Lambda function to update device positions managed by the delivery-tracker resource in us-east-1 (you can update the region if you’re operating from a different region)
{
  "Version": "2012-10-17", 
  "Statement": [ 
    {
    "Sid": "UpdateDevicePositions",
    "Effect": "Allow",
    "Action": ["geo:BatchUpdateDevicePosition"], "Resource": 
    "arn:aws:geo:us-east-1:*:tracker/delivery-tracker" 
    } 
  ] 
}
  • Choose Review policy and set the name of your policy name to AmazonLocationUpdateDeliveryTracker and create the policy

Test position update for Use Case 1

You could have your mobile application invoke the Lambda function to publish the driver’s location and pass the parameters using Lambda events. Or you may have other sources of position updates such as IoT Core, etc.

In this post, we will use Lambda console to invoke the function and pass several test events. The first test event will put the driver outside the geofence. The second test event will trigger the ENTER event of the geofence and the EventBridge rule we create in the previous step will detect the event and trigger SNS notification.

Steps:

  • In to the AWS Lambda console, make sure you are in your delivery-tracker-publisher function
  • Go to the Test tab to create a new event, set the name to TestEvent and enter the first set of coordinates below and save it
{
  "long": -123.1152820587158,
  "lat": 49.32982085435519,
  "deviceid": "Driver3"
}
  • Invoke the test to upload a position update one of the devices to the tracker resource. At this point, the driver has not entered the geofence.
  • Edit the test event and replace it with the following set of coordinates
{
  "long": -123.0904769897461,
  "lat": 49.33664459529638,
  "deviceid": "Driver3"
}
  • Run the test again, and this time, the driver has entered the geofence which gets detected by the EventBridge rule and triggers a notification to the customer.
  • Your customer will get notified via either email
  • Optionally, you can repeat step 2 which will put the driver outside the geofence and there should not be any notification sent

Cleaning up

Congratulations! You just demonstrated how you can set up a geofence, then trigger an event inside and outside of the geofence.” Then clean up and move on to next use case.

To avoid incurring future charges, delete the following resources.

  • Amazon Location Tracker
  • Amazon Location Geofences
  • AWS Lambda functions
  • AWS EventBridge rule
  • Amazon SNS topic

Use Case 2: Notifying Drivers in the Event of Incorrect Delivery

This section will walk you through how to use Amazon Location reverse geocoding which converts location coordinates transmitted upon delivery to a human readable address. This human readable address can be useful in a case where the driver delivers a package to the wrong location. In this example, you will send a notification containing both the correct address and the actual address where the package is mistakenly delivered to. This gives the driver an opportunity to act on the error.

In this use case, the driver drops off the package to the intended address. The driver will use a mobile application to mark delivery completion. A delivery system will implement a business rule to determine the accuracy of the delivery and mark the status of the delivery in the database. In this case, the status of the delivery will indicate an error. As a result, a notification will go out to the driver.

Follow these steps to create the artifacts:

  • Create Amazon Location place index which will enable you to perform reverse geocoding
  • Setup SNS to notify the driver in case of delivery error
  • Create DynamoDB database to retrieve the delivery address and store the legible address after successful reverse geocoding using place index
  • Create Lambda function that will utilize the place index to get human readable address based on the location transmitted from the driver’s mobile application upon the completion of a delivery

Create place index

Before you can make geocoding and reverse geocoding queries, you need to create a place index resource in Amazon Location.

Steps:

  • In to the Amazon Location console, go to Place indexes page
  • Create a Place Index and set the name to delivery-placeindex
  • Leave Place index by Esri selected

Set up notification

In this step, you will use SNS to notify the driver if the package is delivered to the wrong address.

  1. In to the Amazon SNS console, go to Topics page
  2. Create a Standard topic and set the name and display name to deliveryerror-topic
  3. Create a subscription, select Email as the protocol and enter the email address as endpoint
  4. Edit the subscription you just created and add a subscription filter policy similar to the steps in customer notification use case above

Create DynamoDB

In this step, you will create a table in DynamoDB database to hold the delivery address and the result of reverse geocoding of the actual delivery coordinates.

  • In the Amazon DynamoDB console, go to Tables page
  • Create a DynamoDB table and set the name to delivery-table
  • Set the primary key to id with type String and leave the rest as default
  • Create an item once your table has been created by going to the Items tab
  • Set the value of id to 1
  • Append a String item under id and set the name to address and set the value to 3293 Fairmont Rd, North Vancouver, North Vancouver District, British Columbia, V7R 2W7, CAN
  • Save the item

Create Lambda

  • In the AWS Lambda console, go to Functions page
  • Create a function from scratch and set the name to delivery-accuracy-check
  • Set the runtime to Python 3.8 for the runtime
  • Overwrite the code in lambda_function.py with the following, replacing the topic arn with your AWS region and account
from datetime import datetime
import json
import os

import boto3

# Update this to match the name of your Tracker resource
INDEX_NAME = "delivery-placeindex"

# load the side-loaded Amazon Location Service model; this step is only necessary during Public Preview
os.environ["AWS_DATA_PATH"] = os.environ["LAMBDA_TASK_ROOT"]

location_client = boto3.client("location")
sns_client = boto3.client('sns')
table = boto3.resource('dynamodb').Table('delivery-table')

def lambda_handler(event, context):
    
    response = location_client.search_place_index_for_position(
        IndexName=INDEX_NAME, 
        Position=[event['long'], event['lat']])
    
    deliveredAddress = response['Results'][0]['Place']['Label']
    
    table.update_item(
        Key={'id': '1',},
        UpdateExpression="set delivered_num = :n, \
            delivered_country = :c, \
            delivered_municipality = :m, \
            delivered_postal = :p, \
            delivered_neighborhood = :h, \
            delivered_region = :r, \
            delivered_subregion = :s, \
            delivered_address = :l, \
            delivery_status = :t, \
            address = :a",
        ExpressionAttributeValues={
            ':n': response['Results'][0]['Place']['AddressNumber'],
            ':c': response['Results'][0]['Place']['Country'],
            ':m': response['Results'][0]['Place']['Municipality'],
            ':p': response['Results'][0]['Place']['PostalCode'],
            ':h': response['Results'][0]['Place']['Neighborhood'],
            ':r': response['Results'][0]['Place']['Region'],
            ':s': response['Results'][0]['Place']['SubRegion'],
            ':l': response['Results'][0]['Place']['Label'],
            ":t": event['status'],
            ":a": event['address']
        },
        ReturnValues="UPDATED_NEW"
    )

    resp = table.get_item(
        Key={'id': '1',},
    )
                
    if 'Item' in resp:
        if resp['Item']['delivery_status'] == 'error':
            topicArn = 'arn:aws:sns:us-east-1:<your-account>:deliveryerror-topic'
            subject = 'Package delivery error'
            correctAddress = resp['Item']['address']
            message = 'You have delivered the package to ' + deliveredAddress + '. The correct address is ' + correctAddress
            
            response = sns_client.publish(
                TopicArn=topicArn,
                Subject=subject,
                Message=message,
                MessageAttributes={"email" : { "DataType":"String", "StringValue":event['sendto']}})

    return {
        'statusCode': 200,
        'body': resp['Item']
    }
  • Create a file named service-2.json in a location/2020-11-19 folder as described in the Troubleshooting section. This step is only necessary if this region is not supported for general availability. Please ignore otherwise.
  • From the Configuration tab, go to Permissions
  • Click on the execution role. The role name should be similar to delivery-accuracy-check-role-<id>
  • Add an inline policy, select the JSON tab and overwrite the policy with the following. This will allow Lambda to update DynamoDB, use Amazon Location place index, and send notification with SNS
  • Choose Review Policy and set the name to DeliveryAccuracyCheck and create the policy. Replace the region with your region
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "sns:Publish",
                "geo:SearchPlaceIndexForPosition",
                "dynamodb:GetItem",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:us-east-2:*:table/delivery-table",
                "arn:aws:geo:us-east-2:*:place-index/delivery-placeindex",
                "arn:aws:sns:us-east-2:*:deliveryerror-topic"
            ]
        }
    ]
} 

Test the Lambda function

You are now ready to test. The delivery-accuracy-check Lambda function can be called from your client code. But in this post, we will use Lambda console for testing. Follow these steps to create a test event.

Steps:

  • If you are not already there, go to Lambda console and open delivery-accuracy-check function
  • Go to the Test tab
  • Create new test event, set the event name to TestEvent and replace the content the following JSON. Be sure to set the sendto parameter to the correct email address. In this post, we pass the coordinates of the actual delivery address using the long and lat parameters and an address to simulate the intended delivery address using the address parameter. In your application, you can implement a business logic to determine whether or not the delivery is accurate. In this post, we will simply set the status parameter indicating a delivery error
{
  "long": -123.09417001797092,
  "lat": 49.33975304708755,
  "sendto": "youraddress@examplemail.com",
  "status": "error",
  "address": "3293 Fairmont Rd, North Vancouver, North Vancouver District, British Columbia, V7R 2W7, CAN"
}
  • Click on the Invoke button to test your Lambda function
  • You should receive an email. Below is an example of an email notification that the driver will get if there has been a delivery error

Cleaning up

To avoid incurring future charges, delete the following resources:

  • Amazon Location Place Index
  • AWS Lambda function
  • Amazon SNS topic
  • Amazon DynamoDB table

Resources

In this section you can find information on tools to generate geofence coordinates, a sample on how to simulate position updates and troubleshooting tips.

Geofence coordinates

There are many tools available that makes it easier for you to create a geofence coordinate. In this section, we will focus on the following:

geojson.io

geojson.io is a tool for editing GeoJSON data on the internet. It enables editing through a map interface, raw GeoJSON, and exporting and importing a large number of formats. You can use geojson.io to create a geofence that is built by drawing a polygon and save (download) the resulting file in JSON format.

For example: you can draw a polygon in Seattle area using geojson.io http://geojson.io/#map=16/47.6212/-122.3430 and it will generate the coordinates. Additionally, you draw markers and have the tool generate the marker coordinates. You can later use these marker coordinates to test entering and exiting geofence events.

See below and example of a geofence in Seattle and 3 markers (2 of the markers are outside the geofence and 1 of the marker is inside the geofence)

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -122.35340595245361,
              47.62582034846417
            ],
            [
              -122.34917879104614,
              47.617590926715444
            ],
            [
              -122.33546733856201,
              47.61575395451285
            ],
            [
              -122.33257055282593,
              47.625429877939126
            ],
            [
              -122.34199047088624,
              47.62671697344543
            ],
            [
              -122.35340595245361,
              47.62582034846417
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Point",
        "coordinates": [
          -122.35280513763428,
          47.62033903234737
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Point",
        "coordinates": [
          -122.34108924865721,
          47.62331839419884
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Point",
        "coordinates": [
          -122.33211994171144,
          47.62198782639315
        ]
      }
    }
  ]
}

Amazon Location Interactive Tool

You can learn and get started quickly with a visual and interactive learning tool that enables you to explore the service’s different geolocation capabilities from Amazon Location Console. You can access this interactive tool from the Explore menu.

 

Using this tool, you can draw a polygon by selecting the Geofence collection tab. You can then explore how the ENTER and EXIT events are captured. In order to do so, first link the geofence to the tracker by clicking on the link icon. Next, you can simulate a device on the map by clicking on the icon that looks like a truck as illustrated in the screenshot below.

You can then use AWS Command Line Interface (CLI) get-geofence to get the geofence coordinates.

aws location get-geofence \
--collection-name explore.geofence-collection \
--geofence-id explore-1

Finally, extract the coordinates and put it in the following format and save it as a JSON file (e.g. north-vancouver.json).

{
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": { "id": "north-vancouver", "city": "Vancouver" },
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
                [
                    -123.11141927445664,
                    49.342337982757925
                ],
                [
                    -123.09564439341543,
                    49.3273306266273
                ],
                [
                    -123.07613190989761,
                    49.32699031132709
                ],
                [
                    -123.07448296762831,
                    49.33539003824375
                ],
                [
                    -123.0767914868052,
                    49.339884825716176
                ],
                [
                    -123.09363818032138,
                    49.343286981509834
                ],
                [
                    -123.11141927445664,
                    49.342337982757925
                ]
            ]
          ]
        }
      }
    ]
  }

And you can use the browser developer tools (e.g., Inspect elements for Chrome) to get the coordinates for the trackers or use the CLI get-device-position-history as described in the example below.

aws location get-device-position-history \
  --tracker-name explore.tracker --device-id 8e76bb04-f79f-4a14 \
  --start-time-inclusive "2020-11-05T00:00:00+0000"

Simulate position updates

You can have various sources of position updates like IoT Core or a fleet of mobile devices. In the absence of a source of position updates, you can simulate it by following the steps in this section.

Steps:

  1. Create Amazon Location Tracker (if you don’t already have one created)
  2. Create a Lambda function to publish synthetic device position updates
  3. Create Amazon EventBridge rule to run the updates once per minute

Create an Amazon Location Service Tracker

If you already have a tracker resource you want to use, you can skip these steps.

Create a new Tracker in the console

Create an Amazon Location Service Tracker. This will keep track of your devices’ current and historical positions.

  1. Sign in to the Amazon Location console.
  2. Go to the Trackers page.
  3. Choose Create tracker.
  4. Give your tracker a name like Tracker1. You will use this name later in the Lambda functions, IAM policies, and EventBridge Rules, so you may wish to copy it or write it down.
  5. Provide a description like Tracker with persisted data.

Create an AWS Lambda function

Create an AWS Lambda function that publishes synthetic device position updates once per minute.

You will need an AWS Lambda function that creates synthetic updates (in a 1º grid between 49º and 50º north, 123º and 124º west). This function will generate a random position for one of 50 fake devices and submit it using the Tracker API. You can create this function through the AWS Lambda console, or you can use the AWS Command Line Interface (AWS CLI) or the AWS Lambda APIs.

Create a new function from the console

  • Sign in to the AWS Lambda console
  • From the Functions page, choose Create function.
  • Give your function a name like tracker-publisher.
  • Select Python 3.8 for the Runtime.
  • Choose Create function to confirm.
  • Choose the Code tab to open the editor.
  • Overwrite the placeholder code in lambda_function.py with the following code snippet:
from datetime import datetime
   import json
   from random import choice, random, shuffle
   import os

   import boto3

   # Update this to match the name of your Tracker resource
   TRACKER_NAME = "Tracker1"
   UPDATE_COUNT = 10

   # load the side-loaded Amazon Location Service model; necessary during Public Preview
   os.environ["AWS_DATA_PATH"] = os.environ["LAMBDA_TASK_ROOT"]

   client = boto3.client("location")

   # create a set of device IDs to randomly generate updates for
   device_ids = list(map(lambda x: "Device-{}".format(x + 1), range(50)))

   # lat/lon ranges to generate synthetic updates within
   xs = range(-124, -123)
   ys = range(49, 50)

   def lambda_handler(event, context):
       # create 50 synthetic updates for random devices
       shuffle(device_ids)
       updates = []

       for device_id in device_ids[0:UPDATE_COUNT]:
           updates.append({
               'DeviceId': device_id,
               'SampleTime': datetime.now().isoformat(),
               'Position': [choice(xs) + round(random(), 6), choice(ys) + round(random(), 6)]
           })

       client.batch_update_device_position(TrackerName=TRACKER_NAME, Updates=updates)
  • Update TRACKER_NAME to match the name of your Amazon Location Tracker created above, e.g., Tracker1.

NOTE: Due to Lambda runtimes lagging `boto3` and `botocore` releases, you will need to provide Amazon Location’s service model, refer to the Troubleshooting section for the details.

  • Choose Deploy to save the function.
  • From the Configuration tab, choose the Permissions section.
  • Choose the hyperlinked tracker-publisher-role-<id> execution role in order to grant Amazon Location Service permissions to your Lambda function
  • From your role’s Summary page, choose Add inline policy.
  • Select the JSON tab and overwrite the policy with the following document. This will allow your Lambda function to update device positions managed by the Tracker1 resource in us-east-1 (change this if using a different region).
{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "UpdateDevicePositions",
          "Effect": "Allow",
          "Action": ["geo:BatchUpdateDevicePosition"],
          "Resource": "arn:aws:geo:us-east-1:*:tracker/Tracker1"
        }
      ]
}
  • Choose Review policy.
  • Give your police a name like AmazonLocationUpdateTracker1.
  • Choose Create policy.

You can manually trigger this function to ensure that it is configured correctly.

First, create an empty test event:

  1. From the Test tab of the AWS Lambda console, create a new test event named EmptyEvent with {} as its body.
  2. Choose Create event to create the event.

Next, invoke the function using EmptyEvent:

  1. Select EmptyEvent from the list of saved events.
  2. Choose Invoke to invoke the function.
  3. Expand Details for information about the execution result

Publish updates once per minute

This function needs to run periodically in order to generate updates. To do so, create an Amazon EventBridge rule that invokes the tracker-publisher function once per minute.

Create an Amazon EventBridge Rule from the console

  1. Sign in to the Amazon EventBridge console.
  2. From the Rules, choose Create rule.
  3. Choose Create rule.
  4. Give your rule a name like PublishTrackerUpdates.
  5. Provide a description like Publish synthetic updates to Tracker1.
  6. Choose Schedule from the Define pattern box.
  7. Configure the schedule with a fixed rate every 1 Minutes.
  8. Ensure that AWS default event bus is selected.
  9. Select Lambda function as the first target.
  10. Select tracker-publisher from the list of function names.
  11. Choose Create to create the rule.

Troubleshooting

Unknown Service Error

If you run into the Unknown service: 'location' error, that’s because Amazon Location is still in public preview during the writing of this post. Consequently, there is a Lambda runtimes lag in boto3 and botocore releases. You can use the steps below to get around this error in the meantime. This workaround is for Lambda functions written in Python. While these steps work, we recommend packaging all of your dependencies explicitly, even those known to be included.

Steps:

  1. In to the AWS Lambda console, go to Function page
  2. Create or update the Lambda functions that uses Amazon Location APIs
  3. Using the Environment panel, create a new folder named location/2020-11-19
  4. Create a new file in location/2020-11-19 named service-2.json and copy and paste the following JSON content into the file
  5. Be sure to add the following line after the import statements in your Lambda function
# load the side-loaded Amazon Location Service model; this step is only necessary during Public Preview
os.environ["AWS_DATA_PATH"] = os.environ["LAMBDA_TASK_ROOT"]

Missing Notification

If you’re not receiving the email notification while testing the Lambda function for Use Case 1, be sure to check that you’ve correctly replaced the AWS region, account number, and email attribute in the delivery-notifier Lambda function.

Conclusion

In this post, we have explored common use cases for Location Based Services (LBS) using Amazon Location. We walk you through the steps of creating applications for customer notification and delivery accuracy to get you started on how to work with Amazon Location SDK with simple examples. We are just scratching the surface here and there are so much more you can do with Amazon Location. Use examples from this post to build production ready, enterprise applications.