

# Searching place and geolocation data using Amazon Location
Places search

**Note**  
We released a new version of the Places API, see the updated [Places Developer Guide](https://docs.aws.amazon.com//location/latest/developerguide/places.html) or [Places API](https://docs.aws.amazon.com//location/latest/APIReference/API_Operations_Amazon_Location_Service_Places_V2.html) for revised information.

Amazon Location includes the ability to search the geolocation, or *place*, data of your chosen provider. There are several kinds of searching available.
+ **Geocoding** – Geocoding is the process of searching for addresses, regions, business names, or other points of interest, based on text input. It returns details and the location (in latitude and longitude) of the results found.
+ **Reverse geocoding** – Reverse geocoding allows you to find places near a given location.
+ **Autocomplete** – Autocomplete is the process of making automatic suggestions as the user types in a query. For example, if they type **Par** one suggestion might be `Paris, France`.

Amazon Location lets you choose a data provider for place search operations by creating and configuring a place index resource.

Once you create your resource, you can send requests using the AWS SDK for your preferred language, Amplify, or the REST API endpoints. You can use data from the response to mark locations on a map, enrich position data, and to convert positions into human-readable text.

**Note**  
For an overview of searching place concepts, see [Learn about Places search in Amazon Location Service](places-concepts.md).

**Topics**
+ [

# Places prerequisites using Amazon Location
](places-prerequisites.md)
+ [

# Geocoding using Amazon Location
](search-place-index-geocoding.md)
+ [

# Reverse geocoding using Amazon Location
](search-place-index-reverse-geocode.md)
+ [

# Autocomplete using Amazon Location
](search-place-index-autocomplete.md)
+ [

# Use place IDs with Amazon Location
](search-using-placeids.md)
+ [

# Place categories and filtering results with Amazon Location
](category-filtering.md)
+ [

# Amazon Aurora PostgreSQL user-defined functions for Amazon Location Service
](database-address-validation.md)
+ [

# Managing your place index resources with Amazon Location
](managing-place-indexes.md)

# Places prerequisites using Amazon Location
Prerequisites

Before you begin geocoding, reverse geocoding or searching for places, follow the prerequisite steps:

**Topics**
+ [

## Creating a place index resource
](#create-place-index-resource)
+ [

## Authenticating your requests
](#places-identity-pool)

## Creating a place index resource
Creating a place index resource

Begin by creating a place index resource in your AWS account. 

When you create a place index resource, you can choose from the data providers available to support queries for geocoding, reverse geocoding, and searches:

1. **Esri **– For more information about Esri's coverage in your region of interest, see [Esri geocoding coverage](https://developers.arcgis.com/rest/geocode/api-reference/geocode-coverage.htm) in the Esri documentation.

1. **HERE Technologies** – For more information about HERE's coverage in your region of interest, see [HERE geocoding coverage](https://developer.here.com/documentation/geocoder/dev_guide/topics/coverage-geocoder.html) in the HERE documentation.

1. **Grab** – Grab provides data only for Southeast Asia. For more information about Grab's coverage, see [Countries/regions and area covered](grab.md#grab-coverage-area) in this guide.

You can do this using the Amazon Location Service console, the AWS CLI, or the Amazon Location APIs.

------
#### [ Console ]

**To create a place index resource using the Amazon Location Service console**

1. Open the Amazon Location Service console at [https://console.aws.amazon.com/location/](https://console.aws.amazon.com/location/home).

1. In the left navigation pane, choose **Place indexes**.

1. Choose **Create place index**.

1. Fill out the following boxes:
   + ****Name **** – Enter a name for the place index resource. For example, *ExamplePlaceIndex*. Maximum 100 characters. Valid entries include alphanumeric characters, hyphens, periods, and underscores.
   + ****Description** ** – Enter an optional description.

1. Under **Data providers**, choose an available [data provider](https://aws.amazon.com/location/data-providers/) to use with your place index resource.
**Note**  
If your application is tracking or routing assets you use in your business, such as delivery vehicles or employees, you must not use Esri as your geolocation provider. See section 82 of the [AWS service terms](https://aws.amazon.com/service-terms) for more details.

1. Under **Data storage options**, specify if you intend to store search results from your place index resource.

1. (Optional) Under **Tags**, enter a tag **Key** and **Value**. This adds a tag your new place index resource. For more information, see [Tagging your resources](tagging.md).

1. Choose **Create place index**.

------
#### [ API ]

**To create a place index resource using the Amazon Location APIs**

Use the `[CreatePlaceIndex](https://docs.aws.amazon.com/location-places/latest/APIReference/API_CreatePlaceIndex.html)` operation from the Amazon Location Places APIs. 

The following example is an API request to create a place index resource called *ExamplePlaceIndex* using the data provider *Esri*.

```
POST /places/v0/indexes
Content-type: application/json

{
   "DataSource": "Esri",
   "DataSourceConfiguration": { 
      "IntendedUse": "SingleUse"
   },
   "Description": "string",
   "IndexName": "ExamplePlaceIndex",
   "Tags": { 
      "Tag1" : "Value1" 
   }
}
```

------
#### [ AWS CLI ]

**To create a place index resource using AWS CLI commands**

Use the `[create-place-index](https://docs.aws.amazon.com/cli/latest/reference/location/create-place-index.html)` command.

The following example creates a place index resource called *ExamplePlaceIndex* using *Esri* as the data provider. 

```
aws location \
  create-place-index \
  --data-source "Esri" \
  --description "Example place index" \
  --index-name "ExamplePlaceIndex" \
  --tags Tag1=Value1
```

------

**Note**  
Billing depends on your usage. You may incur fees for the use of other AWS services. For more information, see [Amazon Location Service pricing](https://aws.amazon.com/location/pricing/).

## Authenticating your requests


Once you create a place index resource and you're ready to begin building location features into your application, choose how you would authenticate your requests:
+ To explore ways you can access the services, see [Accessing Amazon Location Service](how-to-access.md).
+ If you have a website with anonymous users, you may want to use API Keys or Amazon Cognito.

  **Example**

  The following example shows using an API key for authorization, using [AWS JavaScript SDK v3](https://aws.amazon.com/sdk-for-javascript/), and the Amazon Location [JavaScript Authentication helper](loc-sdk-auth.md).

  ```
  import { LocationClient, SearchPlaceIndexForTextCommand } from "@aws-sdk/client-location";
  import { withAPIKey } from "@aws/amazon-location-utilities-auth-helper";
  
  const apiKey = "v1.public.your-api-key-value"; // API key
  
  // Create an authentication helper instance using an API key
  const authHelper = await withAPIKey(apiKey);
  
  const client = new LocationClient({
    region: "<region>", // region containing Cognito pool
    ...authHelper.getLocationClientConfig(), // Provides configuration required to make requests to Amazon Location
  });
  
  const input = {
    IndexName: "ExamplePlaceIndex",
    Text: "Anyplace",
    BiasPosition: [-123.4567, 45.6789]
  };
  
  const command = new SearchPlaceIndexForTextCommand(input);
  
  const response = await client.send(command);
  ```

# Geocoding using Amazon Location
Geocoding

Geocoding is a process that converts text, such as an address, a region, a business name, or point of interest, into a set of geographic coordinates. You can use place index resources to submit geocoding requests and incorporate data retrieved from geocoding to display data on a map for your web or mobile application.

This section guides you through how to send a simple geocoding request, and how to send geocoding requests with optional specifications.

## Geocoding
Start geocoding

You can submit a simple request to geocode using the `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` operation to convert an address to a set of coordinates. A simple request contains the following required parameter:
+ `Text` – An address, name, city, or region to convert to a set of coordinates. For example, the string `Any Town`.

To specify a maximum number of results per pages, use the following optional parameter:
+ `MaxResults` – Limits the maximum number of results returned in the query response.

You can use the AWS CLI or the Amazon Location APIs.

------
#### [ API ]

The following example is a `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` request to search the place index resource, *ExamplePlaceIndex*, for an address, name, city or region called *Any Town*.

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json

{
    "Text": "Any Town",
    "MaxResults": 10
}
```

------
#### [ AWS CLI ]

The following example is a `[search-place-index-for-text](https://docs.aws.amazon.com/cli/latest/reference/location/search-place-index-for-text.html)` command to search the place index resource, *ExamplePlaceIndex*, for an address, name, city or region called *Any Town*.

```
aws location \
    search-place-index-for-text \
        --index-name ExamplePlaceIndex \
        --text "Any Town" \
        --max-results 10
```

------

## Geocode near a position


When geocoding, you can geocode near a given position with the following optional parameter:
+ `BiasPosition` – The position you want to search nearby. This narrows your search by searching for results closest to the given position. Defined as `[longitude, latitude]`

The following example is a `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` request to search the place index resource for an address, name, city or region called *Any Town* near the position [*-123.4567*,*45.6789*].

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json

{
   "Text": "Any Town",
   "BiasPosition": [-123.4567,45.6789]
}
```

## Geocode within a bounding box


You can geocode within a bounding box to narrow your results to coordinates within a given boundary using the following optional parameter:
+ `FilterBBox` – A bounding box that you specify to filter your results to coordinates within the box's boundaries. Defined as `[LongitudeSW, LatitudeSW, LongitudeNE, LatitudeNE]`
**Note**  
A request can't contain both the `FilterBBox` and `BiasPosition` parameters. Specifying both parameters in the request returns a `ValidationException` error.

The following example is a `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` request to search within a bounding box for an address, name, city or region called *Any Town*. The bounding box follows that:
+ The longitude of the southwest corner is *-124.1450*.
+ The latitude of the southwest corner is *41.7045*.
+ The longitude of the northeast corner is *-124.1387*.
+ The latitude of the northeast corner is *41.7096*.

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json

{
   "Text": "Any Town",
   "FilterBBox":  [
        -124.1450,41.7045,
        -124.1387,41.7096
    ]
}
```

## Geocode within a country


You can geocode within one or more countries you specify by using the following optional parameter:
+ `FilterCountries` – The country or region you want to geocode within. You can define up to 100 countries in one request using a [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) three letter country code. For example, use `AUS` for Australia.

The following example is a `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` request to search for an address, name, city or region called *Any Town* in Germany and France. 

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json

{
   "Text": "Any Town",
   "FilterCountries": ["DEU","FRA"]
}
```

## Filtering by category


You can filter the categories that are returned in your geocode request by using the following optional parameter:
+ `FilterCategories` – The categories of results you want returned in your query. You can specify up to 5 categories in one request. You can find the list of Amazon Location Service categories in the [Categories](category-filtering.md) section. For example, you can specify `Hotel` to specify only returning hotels in your query.

The following example is a `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` request to search for an coffee shop called *Hometown Coffee* in the United States.

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json

{
   "Text": "Hometown Coffee",
   "FilterCategories": ["Coffee Shop"],
   "FilterCountries": ["USA"]
}
```

For more details about filtering on categories, see [Place categories and filtering results with Amazon Location](category-filtering.md)

## Geocode in a preferred language


You can set a language preference for results of your search by using the optional `Language` parameter. For example, a search for **100 Main St, Anytown, USA** may return `100 Main St, Any Town, USA` by default. But if you select `fr` as the `Language`, then the results may return `100 Rue Principale, Any Town, États-Unis` instead.
+ `Language` – A language code to use for rendering the results of your query. The value must be a valid [BCP 47](https://www.rfc-editor.org/info/bcp47) language code. For example, `en` for English.

**Note**  
If `Language` is not specified, or the specified language is not supported for a result, the partner's default language for that result will be used.

The following example is a `SearchPlaceIndexforText` request to search for a place called **Any Town** with the preferred language specified as `de`.

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json
{
   "Text": "Any Town",
   "Language": "de"
}
```

## Example response


**Example**  
The following is an example response when you call the `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` operation from the Amazon Location Places APIs. The results include relevant [places](https://docs.aws.amazon.com/location-places/latest/APIReference/API_Place.html) and the request [summary](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForTextSummary.html). Two responses are shown, based on selecting Esri or HERE as the partner.  

```
POST /places/v0/indexes/ExamplePlaceIndex/search/text 
Content-type: application/json

{
   "Text": "Amazon",
   "MaxResults": 1,
   "FilterCountries": ["USA"],
   "BiasPosition": [-112.10, 46.32]
}
```

```
{
    "Results": [
        {
            "Place": {
                "Country": "USA",
                "Geometry": {
                    "Point": [
                        -112.10667999999998,
                        46.319090000000074
                    ]
                },
                "Interpolated": false,
                "Label": "Amazon, MT, USA",
                "Municipality": "Amazon",
                "Region": "Montana",
                "SubRegion": "Jefferson County"
            },
            "Distance": 523.4619749879726,
            "Relevance": 1
        }
    ],
    "Summary": {
        "BiasPosition": [
            -112.1,
            46.32
        ],
        "DataSource": "Esri",
        "FilterCountries": [
            "USA"
        ],
        "MaxResults": 1,
        "ResultBBox": [
            -112.10667999999998,
            46.319090000000074,
            -112.10667999999998,
            46.319090000000074
        ],
        "Text": "Amazon"
    }
}
```

```
{
    "Summary": {
        "Text": "Amazon",
        "BiasPosition": [
            -112.1,
            46.32
        ],
        "FilterCountries": [
            "USA"
        ],
        "MaxResults": 1,
        "ResultBBox": [
            -112.10668,
            46.31909,
            -112.10668,
            46.31909
        ],
        "DataSource": "Here"
    },
    "Results": [
        {
            "Place": {
                "Label": "Amazon, Jefferson City, MT, United States",
                "Geometry": {
                    "Point": [
                        -112.10668,
                        46.31909
                    ]
                },
                "Neighborhood": "Amazon",
                "Municipality": "Jefferson City",
                "SubRegion": "Jefferson",
                "Region": "Montana",
                "Country": "USA",
                "Interpolated": false,
                "TimeZone": {
                    "Name": "America/Denver",
                    "Offset": -25200
                }
            },
            "PlaceId": "AQAAAIAADsn2T3KdrRWeaXLeVEyjNx_JfeTsMB0NVCEAnAZoJ-o3nqdlJZAdgcT2oWi1w9pS4wXXOk3O1vsKlGsPyHjV4EJxsu289i3hVO_BUPgP7SFoWAi8BW2v7LvAjQ5NfUPy7a1v9ajT3feIqcUZszWSTqKbJHFYvQqW7wdqhpQq3Wy-et39ZQDWSPLZUzgcjN-6VD2gyKkH0Po7gSm8YSJNSQ",            "Distance": 523.4619749905755
        }
    ]
}
```

# Reverse geocoding using Amazon Location
Reverse geocoding

Reverse geocoding is a process that converts a set of coordinates into meaningful text, such as an address, a region, a business name, or point of interest. You can use place index resources to submit reverse geocoding requests and incorporate data retrieved from reverse geocoding to display data on a map for your web or mobile application.

This section guides you through how to send a simple reverse geocoding request.

## Reverse geocoding
Start reverse geocoding

You can submit a simple request to reverse geocode a set of coordinates and convert them to a meaningful address, a point of interest or a general location without an address using the `[SearchPlaceIndexForPosition](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForPosition.html)` operation. A simple request contains the following required parameter:
+ `Position` – A set of coordinates that you want to convert to an address, point of interest, or general location. Defined using the format `[longitude,latitude]`. 

To specify a maximum number of results per pages, add the following optional parameter:
+ `MaxResults` – Limits the maximum number of results returned in the query response.

If you want to specify a preferred language for the results of your query, use the following optional parameter:
+ `Language` – A language code to be used for rendering results. The value must be a valid [BCP 47](https://www.rfc-editor.org/info/bcp47) language code. For example, `en` for English.

**Note**  
If `Language` is not specified, or the specified language is not supported for a result, the partner's default language for that result will be used.

You can use the AWS CLI or the Amazon Location APIs.

------
#### [ API ]

The following example is a `[SearchPlaceIndexForPosition](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForPosition.html)` request to search the place index resource, *ExamplePlaceIndex*, for a meaningful address, point of interest or general location near the position [*122.3394*,*47.6159*].

```
POST /places/v0/indexes/ExamplePlaceIndex/search/position
Content-type: application/json

{
   "Position": [-122.3394,47.6159],
   "MaxResults": 5,
   "Language": "de"
}
```

------
#### [ AWS CLI ]

The following example is a `[search-place-index-for-position](https://docs.aws.amazon.com/cli/latest/reference/location/search-place-index-for-position.html)` command to search the place index resource, *ExamplePlaceIndex*, for a meaningful address, point of interest or general location near the position [*122.3394*,*47.6159*].

```
aws location \
    search-place-index-for-position \
        --index-name ExamplePlaceIndex \
        --position -122.3394 47.6159 \
        --max-results 5 \
        --language de
```

------

## Example response


**Example**  
The following is an example response when calling the `[SearchPlaceIndexForPosition](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForPosition.html)` operation from the Amazon Location Places APIs. The results return relevant [places](https://docs.aws.amazon.com/location-places/latest/APIReference/API_Place.html) and the request [summary](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForPositionSummary.html). Two responses are shown, based on selecting Esri or Here as the partner.  

```
POST /places/v0/indexes/ExamplePlaceIndex/search/position
Content-type: application/json

{
   "Position": [-122.3394,47.6159],
   "MaxResults": 1
}
```

```
{
    "Results": [
        {
            "Place": {
                "AddressNumber": "2111",
                "Country": "USA",
                "Geometry": {
                    "Point": [
                        -122.33937999999995,
                        47.61591000000004
                    ]
                },
                "Interpolated": false,
                "Label": "The Spheres, 2111 7th Ave, Seattle, WA, 98121, USA",
                "Municipality": "Seattle",
                "Neighborhood": "Belltown",
                "PostalCode": "98121",
                "Region": "Washington",
                "SubRegion": "King County"
            },
            "Distance": 1.8685861313438727
        }
    ],
    "Summary": {
        "DataSource": "Esri",
        "MaxResults": 1,
        "Position": [
            -122.3394,
            47.6159
        ]
    }
}
```

```
{
    "Summary": {
        "Position": [
            -122.3394,
            47.6159
        ],
        "MaxResults": 1,
        "DataSource": "Here"
    },
    "Results": [
        {
            "Place": {
                "Label": "2111 7th Ave, Seattle, WA 98121-5114, United States",
                "Geometry": {
                    "Point": [
                        -122.33938,
                        47.61591
                    ]
                },
                "AddressNumber": "2111",
                "Street": "7th Ave",
                "Neighborhood": "Belltown",
                "Municipality": "Seattle",
                "SubRegion": "King",
                "Region": "Washington",
                "Country": "USA",
                "PostalCode": "98121-5114",
                "Interpolated": false,
                "TimeZone": {
                    "Name": "America/Los_Angeles",
                    "Offset": -28800
                }
            },
            "PlaceId": "AQAAAIAADsn2T3KdrRWeaXLeVEyjNx_JfeTsMB0NVCEAnAZoJ-o3nqdlJZAdgcT2oWi1w9pS4wXXOk3O1vsKlGsPyHjV4EJxsu289i3hVO_BUPgP7SFoWAi8BW2v7LvAjQ5NfUPy7a1v9ajT3feIqcUZszWSTqKbJHFYvQqW7wdqhpQq3Wy-et39ZQDWSPLZUzgcjN-6VD2gyKkH0Po7gSm8YSJNSQ",
            "Distance": 1.868586125090601
        }
    ]
}
```

# Autocomplete using Amazon Location
Autocomplete

Autocomplete provides responsive feedback to end users as they are typing their search query. It provides suggestions for addresses and points of interest based on partial or misspelled free-form text. You can use place index resources to request autocomplete suggestions, and display the resulting suggestions in your application.

Amazon Location does not support storage of autocomplete suggestions. An error is returned if the place index used for an autocomplete call is configured for use with stored geocodes. To use stored geocodes and query for suggestions, create and configure multiple place indexes.

This section describes how to send an autocomplete request. It starts with the most basic form of the request, and then shows optional parameters that you can use to increase the relevance of autocomplete search results.

## Using autocomplete
Using autocomplete

You can submit a simple request for autocomplete suggestions by using the `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)` operation. The simplest form of the request has a single required parameter, the query `Text`: 
+ `Text` – The free-form partial text to use to generate place suggestions. For example, the string `eiffel tow`.

To limit the number of results returned, add the optional `MaxResults` parameter: 
+ `MaxResults` – Limits the number of results returned in the query response.

You can use the Amazon Location APIs or the AWS CLI.

------
#### [ API ]

The following example is a `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)` request to search the place index resource, *ExamplePlaceIndex*, for up to *5* suggestions based on the partial place name *kamp*. 

```
POST /places/v0/indexes/ExamplePlaceIndex/search/suggestions
Content-type: application/json

{
    "Text": "kamp",
    "MaxResults": 5
}
```

------
#### [ AWS CLI ]

The following example is a `[search-place-index-for-suggestions](https://docs.aws.amazon.com/cli/latest/reference/location/search-place-index-for-suggestions.html)` command to search the place index resource, *ExamplePlaceIndex*, for up to *5* suggestions based on the partial place name *kamp*. 

```
aws location \
              search-place-index-for-suggestions \
              --index-name ExamplePlaceIndex \
              --text kamp \
              --max-results 5
```

------

The call to `SearchPlaceIndexForSuggestions` results in a list of places with a name and an ID for each. You can use those results to present suggestions of what the user might be searching for, as they are typing, such as providing a dropdown list of choices underneath a text box. For example, here are the results for suggestions, based on a user typing *kamp*.

```
{
    "Summary": {
        "Text": "kamp",
        "MaxResults": 5,
        "DataSource": "Esri"
    },
    "Results": [
        {
            "Text": "Kampuchea",
            "PlaceId": "AQAAAIAADsn2T3KdrRWeaXLeVEyjNx_JfeTsMB0NVCEAnAZoJ-o3nqdlJZAdgcT2oWi1w9pS4wXXOk3O1vsKlGsPyHjV4EJxsu289i3hVO_BUPgP7SFoWAi8BW2v7LvAjQ5NfUPy7a1v9ajT3feIqcUZszWSTqKbJHFYvQqW7wdqhpQq3Wy-et39ZQDWSPLZUzgcjN-6VD2gyKkH0Po7gSm8YSJNSQ"
        },
        {
            "Text": "Kampoul, Kabul, AFG",
            "PlaceId": "AQAAAIAAA1mxl_-9ffzXD07rBgo9fh6E01Pd1YKvuT5rz2qBDxqBkhTlgkeiOPR2s5sa3YBLxUqQI8bhymsYcu9R-DkX3L9QSi3CB5LhNPu160iSFJo6H8S1CrxO3QsJALhrr9mdbg0R4R4YDywkhkeBlnbn7g5C5LI_wYx873WeQZuilwtsGm8jcMA0Ya5oK4netQC6piVx6zmnPdwBs-UeXcb_bg"
        },
        {
            "Text": "Kampala, UGA",
            "PlaceId": "AQAAAIAAzZfZt3qMruKGObyhP6MM0pqy2L8SULlVWT7a3ertLBRS6Q5n7I4s9D7E0nRHADAj7mL7kvX1Q8HD-mpuiATXNJ1Ix4_V_1B15zHe8jlYKMWvXbgbO8cMpgR2fqYqZMR1x-dfBOO8OoqujKZldvPIDK1kNe3GwcaqvvMWWPMeaGd203brFynubAe-MmFF-Gjz-WBMfUy9og6MV7bkk6NGCA"
        },
        {
            "Text": "Kampar, Riau, IDN",
            "PlaceId": "AQAAAIAAvbXXx-srOi111tHOkPdao0GF7WQ_KaZ444SEnevycp6Gtf_2JWgPfCE5bIQCYwya1uZQpX2a8YJoFm2K7Col4fLu7IK0yYOLhZx4kp6QzbG4xEAGzfWtWq6nfbb0lZfuHY6r0g1sRlN1aucvwim4AEcKRzckqaa93JI8064pj6Q59kN37pAa3JX4ayEzH1DzIL3m3oqxzd4O16yGfhAIgA"
        },
        {
            "Text": "Kampung Pasir Gudang Baru, Johor, MYS",
            "PlaceId": "AQAAAIAA4HLQHdjUDcaaXLE9wtNIT1cjQYLgkBnMoG2eNN0AaQ8PJoWabLRXmmPUaAj8MAD6vT0i6zqaun5Mixyj7vnYXrk2xp59cbgdqvQaPoWhSCVxBOX0WGs3cZ8TnIRn3c-6v8_UfmqC7es1gUyECfMGK04VBKiwpHwCzjNsqymkd9BC3A9K3QlMgd3dkrGjv_vV94iLlnFTbaecrckl2UDCkA"
        }
    ]
}
```

The next section explains how to use the `PlaceID` from these results.

## Using the autocomplete results


The call to `SearchPlaceIndexForSuggestions` results in a list of places with a name and an ID for each. You can use those results to present suggestions of what the user might be searching for, as they are typing, such as providing a dropdown list of choices underneath a text box. When the user chooses one of the results, you can then call the [GetPlace](https://docs.aws.amazon.com/location-places/latest/APIReference/API_GetPlace.html) operation with the ID of their selection to return the details of that place, including location, address, or other details.

**Note**  
A `PlaceId` is valid only if all of the following are the same in the original search request, and the call to `GetPlace`.  
Customer AWS account
AWS Region
Data provider specified in the place index resource

Typically, you use `GetPlace` with the Amazon Location APIs. The following example is a `[GetPlace](https://docs.aws.amazon.com/location-places/latest/APIReference/API_GetPlace.html)` request to find one of the suggestions from the previous section. This example is based on the partial place name *kamp*. 

```
POST /places/v0/indexes/ExamplePlaceIndex/places/AQAAAIAADsn2T3KdrRWeaXLeVEyjNx_JfeTsMB0NVCEAnAZoJ-o3nqdlJZAdgcT2oWi1w9pS4wXXOk3O1vsKlGsPyHjV4EJxsu289i3hVO_BUPgP7SFoWAi8BW2v7LvAjQ5NfUPy7a1v9ajT3feIqcUZszWSTqKbJHFYvQqW7wdqhpQq3Wy-et39ZQDWSPLZUzgcjN-6VD2gyKkH0Po7gSm8YSJNSQ
```

## Autocomplete near a position


 When you search for autocomplete place suggestions by using `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)`, you can get more locally-relevant suggestions by adding the following optional parameter:
+ `BiasPosition` – The position you want to search nearby. Defined as `[longitude, latitude]`.

The following example uses a `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)` request to search the place index resource *ExamplePlaceIndex* for place suggestions matching the partial query *kamp* near the position [*32.5827*,*0.3169*]. 

```
POST /places/v0/indexes/ExamplePlaceIndex/search/suggestions
Content-type: application/json

{
    "Text": "kamp",
    "BiasPosition": [32.5827,0.3169]
}
```

The suggestions returned for the same `Text` can be different if a different `BiasPosition` is chosen, such as [*-96.7977*, *32.7776*].

## Autocomplete within a bounding box


You can narrow your autocomplete search to receive only suggestions for places which are located within a given boundary by adding the following optional parameter: 
+ `FilterBBox` – A bounding box that you specify to filter your results to coordinates within the box's boundaries. Defined as `[LongitudeSW, LatitudeSW, LongitudeNE, LatitudeNE]`
**Note**  
A request can't contain both the `FilterBBox` and `BiasPosition` parameters. Specifying both parameters in the request returns a `ValidationException` error.

The following example uses a `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)` request to search the place index resource *ExamplePlaceIndex* for place suggestions matching the partial query *kamp*, and which are contained within the bounding box where: 
+ The longitude of the southwest corner of the bounding box is *32.5020*.
+ The latitude of the southwest corner of the bounding box is *0.2678*.
+ The longitude of the northeast corner of the bounding box is *32.6129*.
+ The latitude of the northeast corner of the bounding box is *0.3502*.

```
POST /places/v0/indexes/ExamplePlaceIndex/search/suggestions
Content-type: application/json

{
    "Text": "kamp",
    "FilterBBox": [
        32.5020, 0.2678,
        32.6129, 0.3502
    ]
}
```

 The suggestions returned for the same `Text` are different if a different `FilterBBox` is chosen, such as [*-97.9651*, *32.0640*, * -95.1196*, *34.0436*]. 

## Autocomplete within a country


You can narrow your autocomplete search to receive only suggestions for places which are located within a given country, or set of countries, by adding the following optional parameter: 
+ `FilterCountries` – The countries you want to search for place suggestions within. You can specify up to 100 countries in one request using a [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) three-letter country code. For example, use `AUS` for Australia.

 The following example uses a `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)` request to search the place index resource *ExamplePlaceIndex* for place suggestions matching the partial query *kamp* and which are contained within Uganda, Kenya, or Tanzania:

```
POST /places/v0/indexes/ExamplePlaceIndex/search/suggestions
Content-type: application/json

{
    "Text": "kamp",
    "FilterCountries": ["UGA", "KEN", "TZA"]
}
```

 The suggestions returned for the same `Text` are different if a different `FilterCountries` list is chosen, such as ["*USA*"]. 

## Example response


The following is an example response of suggested autocompletions for the `[SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html)` operation, using the text *kamp*.

```
{
    "Summary": {
        "Text": "kamp",
        "MaxResults": 5,
        "DataSource": "Esri"
    },
    "Results": [
        {
            "Text": "Kampuchea",
            "PlaceId": "AQAAAIAADsn2T3KdrRWeaXLeVEyjNx_JfeTsMB0NVCEAnAZoJ-o3nqdlJZAdgcT2oWi1w9pS4wXXOk3O1vsKlGsPyHjV4EJxsu289i3hVO_BUPgP7SFoWAi8BW2v7LvAjQ5NfUPy7a1v9ajT3feIqcUZszWSTqKbJHFYvQqW7wdqhpQq3Wy-et39ZQDWSPLZUzgcjN-6VD2gyKkH0Po7gSm8YSJNSQ"
        },
        {
            "Text": "Kampoul, Kabul, AFG",
            "PlaceId": "AQAAAIAAA1mxl_-9ffzXD07rBgo9fh6E01Pd1YKvuT5rz2qBDxqBkhTlgkeiOPR2s5sa3YBLxUqQI8bhymsYcu9R-DkX3L9QSi3CB5LhNPu160iSFJo6H8S1CrxO3QsJALhrr9mdbg0R4R4YDywkhkeBlnbn7g5C5LI_wYx873WeQZuilwtsGm8jcMA0Ya5oK4netQC6piVx6zmnPdwBs-UeXcb_bg"
        },
        {
            "Text": "Kampala, UGA",
            "PlaceId": "AQAAAIAAzZfZt3qMruKGObyhP6MM0pqy2L8SULlVWT7a3ertLBRS6Q5n7I4s9D7E0nRHADAj7mL7kvX1Q8HD-mpuiATXNJ1Ix4_V_1B15zHe8jlYKMWvXbgbO8cMpgR2fqYqZMR1x-dfBOO8OoqujKZldvPIDK1kNe3GwcaqvvMWWPMeaGd203brFynubAe-MmFF-Gjz-WBMfUy9og6MV7bkk6NGCA"
        },
        {
            "Text": "Kampar, Riau, IDN",
            "PlaceId": "AQAAAIAAvbXXx-srOi111tHOkPdao0GF7WQ_KaZ444SEnevycp6Gtf_2JWgPfCE5bIQCYwya1uZQpX2a8YJoFm2K7Col4fLu7IK0yYOLhZx4kp6QzbG4xEAGzfWtWq6nfbb0lZfuHY6r0g1sRlN1aucvwim4AEcKRzckqaa93JI8064pj6Q59kN37pAa3JX4ayEzH1DzIL3m3oqxzd4O16yGfhAIgA"
        },
        {
            "Text": "Kampung Pasir Gudang Baru, Johor, MYS",
            "PlaceId": "AQAAAIAA4HLQHdjUDcaaXLE9wtNIT1cjQYLgkBnMoG2eNN0AaQ8PJoWabLRXmmPUaAj8MAD6vT0i6zqaun5Mixyj7vnYXrk2xp59cbgdqvQaPoWhSCVxBOX0WGs3cZ8TnIRn3c-6v8_UfmqC7es1gUyECfMGK04VBKiwpHwCzjNsqymkd9BC3A9K3QlMgd3dkrGjv_vV94iLlnFTbaecrckl2UDCkA"
        }
    ]
}
```

# Use place IDs with Amazon Location


Searching for places returns a list of results. Most results include a `PlaceId` for that result. You can use a `PlaceId` in a `[GetPlace](https://docs.aws.amazon.com/location-places/latest/APIReference/API_GetPlace.html)` operation to return the information about that place (including name, address, location, or other details).

**Note**  
Using [SearchPlaceIndexForSuggestions](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForSuggestions.html) will return `PlaceId` results for any place indexes created with any data source. Using [SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html) or [SearchPlaceIndexForPosition](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForPosition.html) will return a `PlaceId` only if the data source used is HERE.

Each `PlaceId` uniquely defines the place it refers to, but a single place can have more than one `PlaceId` over time, and based on the context. The following rules describe the uniqueness and longevity of a `PlaceId`.
+ The `PlaceId` returned in calls that you make is specific to your AWS account, to the AWS Region, and to the data provider in your `PlaceIndex` resource. `GetPlace` will find results only when these three attributes match the original call that created the `PlaceId`.
+ The `PlaceId` for a place will change when the data about that place changes. For example, when the business that it refers to moves location or changes names.
+ The `PlaceId` returned from a repeated search call may change when the backend service makes an update. The older `PlaceId` will continue to be found, but new calls to search may return a different ID.

The `PlaceId` is a string. There is no specific limit to the length of a `PlaceId`. The following is an example of a valid `PlaceId`. 

```
AQAAAIAADsn2T3KdrRWeaXLeVEyjNx_JfeTsMB0NVCEAnAZoJ-o3nqdlJZAdgcT2oWi1w9pS4wXXOk3O1vsKlGsPyHjV4EJxsu289i3hVO_BUPgP7SFoWAi8BW2v7LvAjQ5NfUPy7a1v9ajT3feIqcUZszWSTqKbJHFYvQqW7wdqhpQq3Wy-et39ZQDWSPLZUzgcjN-6VD2gyKkH0Po7gSm8YSJNSQ
```

Calling `GetPlace` with a `PlaceId` for a place whose data has changed (for example, a business location that has gone out of business), will result in a `404`, `ResourceNotFound` error. Calling `GetPlace` with a `PlaceId` that is not valid, or one out of context, such as from another AWS account, will return a `400`, `ValidationException` error.

While you can use PlaceID in subsequent requests, PlaceID is not intended to be a permanent identifier and the ID can change between consecutive API calls. Please see the following PlaceID behaviour for each data provider:
+ **Esri**: Place IDs will change every quarter at a minimum. The typical time period for these changes would be March, June, September, and December. Place IDs might also change between the typical quarterly change but that will be much less frequent.
+ **HERE**: We recommend that you cache data for no longer than a week to keep your data data fresh. You can assume that less than 1% ID shifts will release over release which is approximately 1 - 2 times per week.
+ **Grab**: Place IDs can expire or become invalid in the following situations.
  + **Data operations**: The POI may be removed from Grab POI database by Grab Map Ops based on the ground-truth, such as being closed in the real world, being detected as a duplicate POI, or having incorrect information. Grab will synchronize data to the Waypoint environment on weekly basis.
  + **Interpolated POI**: Interpolated POI is a temporary POI generated in real time when serving a request, and it will be marked as derived in the `place.result_type` field in the response. The information of interpolated POIs will be retained for at least 30 days, which means that within 30 days, you are able to obtain POI details by Place ID from Place Details API. After 30 days, the interpolated POIs(both Place ID and details) may expire and inaccessible from the Places Details API.

# Place categories and filtering results with Amazon Location
Categories and filtering

Places are categorized. If you search for a business, the business might be a `Restaurant`, for example. Even the results of a search for an address can be categorized by whether it was matched to an *address*, *street*, or *intersection*.

Broadly, Amazon Location Service categorizes places into *Place types*. Points of interest are further categorized into *Point of interest types*.

**Note**  
Not all results will have categories.

You can use the categories to filter your geocoding searches.

## Filtering results


When you are using `SearchPlaceIndexForText`, you can filter the results that are returned by the categories that you want to use. For example:
+ If you want to search for a place called "Hometown Coffee", and only return results that are categorized as coffee shops, you can do that by calling `SearchPlaceIndexForText` and include the *Point of interest category*, `Coffee Shop` in the `FilterCategories` parameter.
+ When searching for "123 Main St, Anytown, WA, 98123, USA", you can filter result to just addresses, so you don't get matches on, for example, the postal code. Filter to just addresses by including *Place type*, `AddressType` in the `FilterCategories` parameter.

**Note**  
Not all data providers support filtering, or support it in the same way. For more information, see [Filtering limitations by data provider](#filter-limitations).

The next section lists the categories that you can filter on.

## Categories


The following lists show the categories that Amazon Location Service uses to categorize and filter. These categories are used in all languages, independent of the language parameter is set to a different language.

**Note**  
Amazon Location Service maps data provider categories to this set of categories. If a data provider puts a place into a category that is not part of the Amazon Location Service category list, the provider category will be included in the results as a *supplemental category*.

**Place types** – These types are used to indicate the type of match that was used to find the result.
+ `AddressType` – Returned when the result was matched to an address.
+ `StreetType` – Returned when the result was matched to a street.
+ `IntersectionType` – Returned when the result was matched to the intersection of two streets.
+ `PointOfInterestType` – Returned when the result was match to a point of interest, such as a business, or civic location.
+ `CountryType` – Returned when the result was matched to a country or major region.
+ `RegionType` – Returned when the result was matched to a region within a country, such as a state or province.
+ `SubRegionType` – Returned when the result was matched to a subregion within a country, such as a county or metropolitan area.
+ `MunicipalityType` – Returned when the result was matched to a city or town.
+ `NeighborhoodType` – Returned when the result was matched to a neighborhood or area within a city.
+ `PostalCodeType` – Returned when the result was matched to a postal code.

**Point of interest categories** – These categories are used to indicate the type of business or location for point of interest results.
+ `Airport`
+ `Amusement Park`
+ `Aquarium`
+ `Art Gallery`
+ `ATM`
+ `Bakery`
+ `Bank`
+ `Bar`
+ `Beauty Salon`
+ `Bus Station`
+ `Car Dealer`
+ `Car Rental`
+ `Car Repair`
+ `Car Wash`
+ `Cemetery`
+ `Cinema`
+ `City Hall`
+ `Clothing Store`
+ `Coffee Shop`
+ `Consumer Electronics Store`
+ `Convenience Store`
+ `Court House`
+ `Dentist`
+ `Embassy`
+ `Fire Station`
+ `Fitness Center`
+ `Gas Station`
+ `Government Office`
+ `Grocery`
+ `Higher Education`
+ `Hospital`
+ `Hotel`
+ `Laundry`
+ `Library`
+ `Liquor Store`
+ `Lodging`
+ `Market`
+ `Medical Clinic`
+ `Motel`
+ `Museum`
+ `Nightlife`
+ `Nursing Home`
+ `Park`
+ `Parking`
+ `Pet Store`
+ `Pharmacy`
+ `Plumbing`
+ `Police Station`
+ `Post Office`
+ `Religious Place`
+ `Restaurant`
+ `School`
+ `Shopping Mall`
+ `Sports Center`
+ `Storage`
+ `Taxi Stand`
+ `Tourist Attraction`
+ `Train Station`
+ `Veterinary Care`
+ `Zoo`

## Filtering limitations by data provider
Filtering limitations

Not all providers have the same filtering functionality. The following table describes the differences.


| Provider | APIs with filter support | Categories supported for filtering | Return values | 
| --- | --- | --- | --- | 
|  Esri  |  `SearchPlaceIndexForText`, `SearchPlaceIndexForSuggestions`  |  Filter by *Place types* and *Point of interest categories*.  |  Categories are returned by `SearchPlaceIndexForText`, `SearchPlaceIndexForPosition`, and `GetPlace`  | 
|  Here  |  `SearchPlaceIndexForText`, `SearchPlaceIndexForSuggestions`  |  Filter by *Place types* only.  |  Categories are returned by `SearchPlaceIndexForText` and `SearchPlaceIndexForSuggestions`, `SearchPlaceIndexForPosition`, and `GetPlace`  | 
|  Grab  |  not supported  |  not supported  |  not supported  | 
|  Open Data  |  n/a (searching places not supported)  |  n/a  |  n/a  | 

# Amazon Aurora PostgreSQL user-defined functions for Amazon Location Service
Tutorial: Database enrichment

You can use Amazon Location Service to work with coordinates and addresses stored in database tables to clean and enrich your geospatial data.

For example:
+ You can use geocoding to convert addresses to coordinates to normalize and fill gaps in data for addresses stored in a database table. 
+ You can geocode addresses to obtain their positions and use the coordinates with database spatial functions, such as a function that shows rows in a specified area.
+ You can use enriched data to generate automated reporting, such as generating an automated report that illustrates all devices in a given area, or an automated report for machine learning that illustrates areas with higher failure rates when sending location updates.

This tutorial shows how to format and enrich addresses stored in an Amazon Aurora PostgreSQL database table using Amazon Location Service.
+ **Amazon Aurora PostgreSQL** – A fully managed relational database engine, compatible with MySQL and PostgreSQL, that outputs up to five times the throughput of MySQL and up to three times the throughput of PostgreSQL without changing most of your existing application. For more information, see [What is Amazon Aurora?](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html) in the *Amazon Aurora User Guide*.

**Important**  
The resulting application in this tutorial uses a place index that stores geocoding results. For information about applicable charges for storing geocoding results, see [Amazon Location Service pricing](https://aws.amazon.com/location/pricing/). 

Sample code is available in the Amazon Location Service samples repository on [GitHub](https://github.com/aws-samples/amazon-location-samples/tree/main/aurora-udfs), which includes [an AWS CloudFormation template](https://github.com/aws-samples/amazon-location-samples/tree/main/aurora-udfs/cloudformation/template.yaml). 

**Topics**
+ [

## Overview
](#aurora-amazon-location-overview)
+ [

## Prerequisites
](#aurora-amazon-location-prerequisites)
+ [

## Quick start
](#aurora-amazon-location-quick-start)
+ [

## Create a place index resource
](#aurora-create-place-index)
+ [

## Create an AWS Lambda function for geocoding
](#aurora-create-lambda)
+ [

## Grant Amazon Aurora PostgreSQL access to AWS Lambda
](#aurora-invoke-API)
+ [

## Invoke the AWS Lambda function
](#aurora-setup-table)
+ [

## Enriching a database containing address data
](#aurora-run-sql)
+ [

## Next steps
](#aurora-amazon-location-next-steps)

## Overview


![\[alt text not found\]](http://docs.aws.amazon.com/location/previous/developerguide/images/aurora_architecture.PNG)


The architecture involves the following integrations:
+  This solution uses an Amazon Location place index resource to support geocoding queries using the operation `SearchPlaceIndexForText`.
+ AWS Lambda uses a Python Lambda that geocodes addresses when an IAM policy gives permission to allow AWS Lambda to call the Amazon Location geocoding operation, `SearchPlaceIndexForText`.
+ Grant permission to Amazon Aurora PostgreSQL to invoke the geocoding Lambda function using an SQL user-defined function. 

## Prerequisites


Before you begin, you need the following prerequisites:
+ An Amazon Aurora PostgreSQL cluster. For more information about [Creating an Amazon Aurora DB cluster](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.CreateInstance.html), see the *Amazon Aurora User Guide*.
**Note**  
If your Amazon Aurora cluster isn't publicly available, you must also configure Amazon Aurora to connect to AWS Lambda in a virtual private cloud (VPC) in your AWS account. For more information, see [Grant Amazon Aurora PostgreSQL access to AWS Lambda](#aurora-invoke-API).
+ An SQL developer tool to connect to the Amazon Aurora PostgreSQL cluster.

## Quick start


As an alternative to going through the steps in this tutorial, you can launch a quick stack to deploy an AWS Lambda function supporting the Amazon Location operation `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)`. This automatically configures your AWS account to allow Amazon Aurora to call AWS Lambda.

Once you configure your AWS account, you will need to: 
+ Add the Lambda feature to Amazon Aurora. See Add the IAM role to a Amazon Aurora DB cluster in [Grant Amazon Aurora PostgreSQL access to AWS Lambda](#aurora-invoke-API).
+ Load the user-defined function into your database. See [Invoke the AWS Lambda function](#aurora-setup-table).

 

[https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateUrl=https%3A%2F%2Famazon-location-cloudformation-templates.s3.us-west-2.amazonaws.com%2Faurora-udfs%2Ftemplate.yaml&stackName=AuroraUDFs](https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateUrl=https%3A%2F%2Famazon-location-cloudformation-templates.s3.us-west-2.amazonaws.com%2Faurora-udfs%2Ftemplate.yaml&stackName=AuroraUDFs)

## Create a place index resource


Start by creating a place index resource to support geocoding queries. 

1. Open the Amazon Location Service console at [https://console.aws.amazon.com/location/](https://console.aws.amazon.com/location/home). 

1. In the left navigation pane, choose **Place indexes**. 

1. Fill out the following boxes:
   + ** Name** – Enter a name for the place index resource. For example, *AuroraPlaceIndex*. Maximum 100 characters. Valid entries include alphanumeric characters, hyphens, periods, and underscores.
   + ** Description** – Enter an optional description. For example, *Place index for Amazon Aurora*. 

1. Under **Data providers**, choose an available [data provider](https://aws.amazon.com/location/data-providers/) to use with your place index resource. If you have no preference, we recommend starting with *Esri*.

1. Under **Data storage options**, specify **Yes, results will be stored**. This indicates that you intend to save the geocoding results in a database.

1. (Optional) Under **Tags**, enter a tag **Key** and **Value**. This adds a tag your new place index resource. For more information, see [Tagging your resources](tagging.md).

1. Choose **Create place index**.

## Create an AWS Lambda function for geocoding
Create a Lambda function for geocoding

To create a connection between Amazon Aurora PostgreSQL and Amazon Location Service, you need an AWS Lambda function to handle requests from the database engine. This function translates the Lambda user-defined function event and calls the Amazon Location operation `SearchPlaceIndexForText`.

You can create the function using the AWS Lambda console, the AWS Command Line Interface, or the AWS Lambda APIs.

**To create a Lambda user-defined function using the console**

1. Open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/home).

1. From the left navigation, choose **Functions**. 

1.  Choose **Create Function**, and make sure that **Author from scratch** is selected. 

1. Fill out the following boxes:
   + **Function name** – Enter a unique name for your function. Valid entries include alphanumeric characters, hyphens, and underscores with no spaces. For example, *AuroraGeocoder*.
   + **Runtime** – Choose *Python 3.8*.

1. Choose **Create function**. 

1. Choose the **Code** tab to open the editor.

1. Overwrite the placeholder code in `lambda_function.py` with the following:

   ```
   from os import environ
   
   import boto3
   from botocore.config import Config
   
   # load the place index name from the environment, falling back to a default
   PLACE_INDEX_NAME = environ.get("PLACE_INDEX_NAME", "AuroraPlaceIndex")
   
   location = boto3.client("location", config=Config(user_agent="Amazon Aurora PostgreSQL"))
   
   """
   This Lambda function receives a payload from Amazon Aurora and translates it to
   an Amazon Location `SearchPlaceIndex` call and returns the results as-is, to be
   post-processed by a PL/pgSQL function.
   """
   def lambda_handler(event, context):
       kwargs = {}
       
       if event.get("biasPosition") is not None:
           kwargs["BiasPosition"] = event["biasPosition"]
   
       if event.get("filterBBox") is not None:
           kwargs["FilterBBox"] = event["filterBBox"]
   
       if event.get("filterCountries") is not None:
           kwargs["FilterCountries"] = event["filterCountries"]
   
       if event.get("maxResults") is not None:
           kwargs["MaxResults"] = event["maxResults"]
       
       return location.search_place_index_for_text(
           IndexName=PLACE_INDEX_NAME,
           Text=event["text"],
           **kwargs)["Results"]
   ```

1. If you've named your place index something other than *AuroraPlaceIndex*, create an environment variable named `PLACE_INDEX_NAME` to assign the resource name to:
   + From the **Configuration** tab, choose **Environment Variables**.
   + Choose **Edit**, then choose **Add environment variable**.
   + For **Key**: Enter `PLACE_INDEX_NAME`.
   + For **Value**: Enter the name of your place index resource.

1. Choose **Deploy** to save the updated function.

1. From the **Test** drop-down menu, choose **Configure test Event**.

1. Choose **Create new test event**.

1. Enter the following test event:

   ```
   {
     "text": "Baker Beach",
     "biasPosition": [-122.483, 37.790],
     "filterCountries": ["USA"]
   }
   ```

1. Choose **Test** to test the Lambda function.

1. Choose the **Configuration** tab.

1. Under **General configuration**: Choose **Permissions**.

1. Under **Execution role**: Choose the hyper linked **Role name** to grant Amazon Location Service permissions to your Lambda function. 

1. Under the **Permissions** tab: Select the **Add permissions** drop down, then choose **Create inline policy**.

1. Choose the **JSON** tab.

1. Add the following IAM policy:
   + The following policy gives permission to send `SearchPlaceIndexForText` to the place index resource *AuroraPlaceIndex*.

     ```
     {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
         {
           "Effect": "Allow",
           "Action": "geo:SearchPlaceIndexForText",
           "Resource": "arn:aws:geo:<Region>:<AccountId>:place-index/AuroraPlaceIndex"
         }
       ]
     }
     ```

1. Choose **Review policy**.

1. Enter a policy name. For example, *AuroraPlaceIndexReadOnly*.

1. Choose **Create policy**.

## Grant Amazon Aurora PostgreSQL access to AWS Lambda
Grant Aurora access to Lambda

Before Amazon Aurora PostgreSQL can invoke an AWS Lambda function, you must grant access permission.

If your Amazon Aurora PostgreSQL cluster isn't publicly accessible, you will need to first create a VPC endpoint for AWS Lambda in order for Amazon Aurora to call your Lambda function.

**Create a VPC Endpoint for AWS Lambda** 

**Note**  
This step is only required if your Amazon Aurora PostgreSQL cluster isn't publicly accessible. 

1. Open the [Amazon Virtual Private Cloud Console](https://console.aws.amazon.com/vpc/home).

1. In the left navigation, choose **Endpoints**.

1. Choose **Create endpoint**.

1. In the **Service Name** filter, enter "lambda", then choose `com.amazonaws.<region>.lambda`.

1. Choose the VPC containing your Aurora cluster.

1. Choose a subnet for each availability zone.

1. In the **Security group** filter, enter "default" or the name of the security group your Aurora cluster is a member of, then choose the security group.

1. Choose **Create endpoint**.

**Create an IAM policy to grant permission to invoke your AWS Lambda function**

1. Open the [IAM console](https://console.aws.amazon.com/iam/home#/home).

1. In the left navigation, expand **Access Management** to choose **Policies**.

1. Choose **Create policy**.

1. On the **JSON** tab, input the following policy:
   + The following is an example of an IAM policy that grants Amazon Aurora PostgreSQL permission to invoke the `AuroraGeocoder` AWS Lambda function.

   ```
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "lambda:InvokeFunction",
               "Resource": [
                   "arn:aws:lambda:<Region>:<AccountId>:function:AuroraGeocoder"
               ]
           }
       ]
   }
   ```

1. Choose **Next: Tags** to add optional tags.

1. Choose **Next: Review**. 

1. Review your policy and enter the following details for the policy:
   + **Name** – Use alphanumeric and '\$1=,.@-\$1' characters. Maximum 128 characters. For example, *AuroraGeocoderInvoke*.
   + **Description** – Enter an optional description. Use alphanumeric and '\$1=,.@-\$1' characters. Maximum 1000 characters. 

1. Choose **Create policy**. Note the ARN for this policy, which you use to attach the policy to an IAM role.

**Create an IAM role to give permission to Amazon Relational Database Service (Amazon RDS)**

By creating an IAM role, Amazon Aurora PostgreSQL can assume the role on your behalf to access your Lambda function. For more information, see [Creating a role to delegate permissions to an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html) in the *IAM User Guide*.

The following example is an AWS CLI command that creates a role named *AuroraGeocoderInvokeRole*:

```
aws iam create-role  --role-name rds-lambda-role --assume-role-policy-document '{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
        "Effect": "Allow",
        "Principal": {
            "Service": "rds.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
        }
    ] 
}'
```

**Attach your IAM policy to the IAM role**

When you have an IAM role, attach the IAM policy that you've created. 

The following example is an AWS CLI command that attaches the policy *AuroraGeocoderInvoke* to the role *AuroraGeocoderInvokeRole*.

```
aws iam attach-role-policy  --policy-arn AuroraGeocoderInvoke  --role-name AuroraGeocoderInvokeRole
```

**Add the IAM role to a Amazon Aurora DB cluster**

The following example is an AWS CLI command to add an IAM role to a Amazon Aurora PostgreSQL DB cluster named *MyAuroraCluster*.

```
aws rds add-role-to-db-cluster \
--db-cluster-identifier MyAuroraCluster \
--feature-name Lambda \
--role-arn AuroraGeocoderInvokeRole   \
--region your-region
```

## Invoke the AWS Lambda function
Invoke the Lambda function

After you grant permission to Amazon Aurora PostgreSQL to invoke your geocoding Lambda function, you can create an Amazon Aurora PostgreSQL user-defined function to invoke the geocoding AWS Lambda function. For more information, see [Invoking an AWS Lambda function from an Amazon Aurora PostgreSQL DB cluster](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/PostgreSQL-Lambda.html) in the *Amazon Aurora User Guide*.

**Install the required PostgreSQL extensions**

To install the required PostgreSQL extensions `aws_lambda` and `aws _commons` extensions, see [Overview of using a Lambda function](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/PostgreSQL-Lambda.html#PostgreSQL-Lambda-overview) in the *Amazon Aurora User Guide*.

```
CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;
```

**Install the required PostGIS extensions**

PostGIS is an extension to PostgreSQL for storing and managing spatial information. For more information, see [Working with the PostGIS extension](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.PostGIS.html) on the *Amazon Relational Database Service User Guide*.

```
CREATE EXTENSION IF NOT EXISTS postgis;
```

**Create an SQL user-defined function that invokes the Lambda function**

In an SQL editor, create a new user-defined function `f_SearchPlaceIndexForText` to invoke the function *AuroraGeocoder*:

```
CREATE OR REPLACE FUNCTION f_SearchPlaceIndexForText(
  text text,
  bias_position geometry(Point, 4326) DEFAULT NULL,
  filter_bbox box2d DEFAULT NULL,
  filter_countries text[] DEFAULT NULL,
  max_results int DEFAULT 1
)
 RETURNS TABLE (
   label text,
   address_number text,
   street text,
   municipality text,
   postal_code text,
   sub_region text,
   region text,
   country text,
   geom geometry(Point, 4326)
 )
 LANGUAGE plpgsql
 IMMUTABLE
AS $function$
begin
    RETURN QUERY
    WITH results AS (
      SELECT json_array_elements(payload) rsp
      FROM aws_lambda.invoke(
        aws_commons.create_lambda_function_arn('AuroraGeocoder'),
        json_build_object(
          'text', text,
          'biasPosition',
          CASE WHEN bias_position IS NOT NULL THEN
            array_to_json(ARRAY[ST_X(bias_position), ST_Y(bias_position)])
          END,
          'filterBBox',
          CASE WHEN filter_bbox IS NOT NULL THEN
            array_to_json(ARRAY[ST_XMin(filter_bbox), ST_YMin(filter_bbox), ST_XMax(filter_bbox), ST_YMax(filter_bbox)])
          END,
          'filterCountries', filter_countries,
          'maxResults', max_results
        )
      )
    )
    SELECT
      rsp->'Place'->>'Label' AS label,
      rsp->'Place'->>'AddressNumber' AS address_number,
      rsp->'Place'->>'Street' AS street,
      rsp->'Place'->>'Municipality' AS municipality,
      rsp->'Place'->>'PostalCode' AS postal_code,
      rsp->'Place'->>'SubRegion' AS sub_region,
      rsp->'Place'->>'Region' AS region,
      rsp->'Place'->>'Country' AS country,
      ST_GeomFromGeoJSON(
        json_build_object(
          'type', 'Point',
            'coordinates', rsp->'Place'->'Geometry'->'Point'
        )
      ) geom
    FROM results;
end;
$function$;
```

**Call the SQL function to geocode from Aurora**

Running the SQL statement invokes the Lambda function *AuroraGeocoder*, which takes address records from the database table in the Amazon Aurora PostgreSQL database and geocodes them using a place index resource.

**Note**  
Amazon Aurora PostgreSQL invokes the Lambda function for each call to the SQL user-defined function.   
If you are geocoding 50 rows, Amazon Aurora PostgreSQL invokes the Lambda function 50 times. One invocation for each row.

The following `f_SearchPlaceIndexForText` SQL function makes requests to Amazon Location's `[SearchPlaceIndexForText](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html)` API through the *AuroraGeocoder* Lambda function. The function returns a `geom` column that's a PostGIS geometry, which `ST_AsText(geom)` converts to text.

```
SELECT *, ST_AsText(geom)
FROM f_SearchPlaceIndexForText('Vancouver, BC');
```

By default, the return will contain one row. To request additional rows, up to the `MaxResults` limit, run the following SQL statement while providing a `BiasPosition` and limiting to results in Canada.

```
SELECT *
FROM f_SearchPlaceIndexForText('Mount Pleasant', ST_MakePoint(-123.113, 49.260), null, '{"CAN"}', 5);
```

To filter results using a bounding box, then pass a `[Box2D](https://postgis.net/docs/Box2D.html)` as `filter_bbox`:
+ `[FilterBBox](https://docs.aws.amazon.com/location-places/latest/APIReference/API_SearchPlaceIndexForText.html#locationplaces-SearchPlaceIndexForText-request-FilterBBox)` – Filters the results by returning places within a bounding box. This is an optional parameter. 

```
SELECT *
FROM f_SearchPlaceIndexForText('Mount Pleasant', null, 'BOX(-139.06 48.30, -114.03 60.00)'::box2d, '{"CAN"}', 5);
```

For more information on PostGIS types and functions, see the [PostGIS Reference](https://postgis.net/docs/reference.html).

## Enriching a database containing address data


You can construct a formatted address and simultaneously normalize and geocode using the Amazon Location operation `SearchPlaceIndexForText` given a database table with the following data broken out into the following columns:
+ `id`
+ `address`
+ `city`
+ `state`
+ `zip`

```
WITH source_data AS (
  SELECT
    id,
    address || ', ' || city || ', ' || state || ', ' || zip AS formatted_address
  FROM addresses
),
geocoded_data AS (
  SELECT
    *,
    (f_SearchPlaceIndexForText(formatted_address)).*
  FROM source_data
)
SELECT
  id,
  formatted_address,
  label normalized_address,
  ST_Y(geom) latitude,
  ST_X(geom) longitude
FROM geocoded_data
-- limit the number of rows that will be geocoded; remove this to geocode the entire table
LIMIT 1;
```

The following example illustrates one resulting datatable row:

```
 id |      formatted_address         |            normalized_address              |     latitude     |     longitude
----+--------------------------------+--------------------------------------------+------------------+-------------------
 42 | 123 Anytown Ave N, Seattle, WA | 123 Anytown Ave N, Seattle, WA, 12345, USA | 47.6223000127926 | -122.336745971039
(1 row)
```

**Update the database table and populate columns**

The following example updates the table and populates columns with results of `SearchPlaceIndexForText` queries:

```
WITH source_data AS (
  -- select rows that have not been geocoded and created a formatted address for each
  SELECT
    id,
    address || ', ' || city || ', ' || state || ', ' || zip AS formatted_address
  FROM addresses
  WHERE label IS NULL
  -- limit the number of rows that will be geocoded; remove this to geocode the entire table
  LIMIT 1
),
geocoded_data AS (
  -- geocode each row and keep it linked to the source's ID
  SELECT
    id,
    (f_SearchPlaceIndexForText(formatted_address)).*
  FROM source_data
)
UPDATE addresses
-- populate columns
SET
  normalized_address = geocoded_data.label,
  latitude = ST_Y(geocoded_data.geom),
  longitude = ST_X(geocoded_data.geom)
FROM geocoded_data
-- ensure that rows match
WHERE addresses.id = geocoded_data.id;
```

## Next steps


Sample code is available in the Amazon Location Service samples repository on [GitHub](https://github.com/aws-samples/amazon-location-samples/tree/main/aurora-udfs), which includes [an AWS CloudFormation template](https://github.com/aws-samples/amazon-location-samples/tree/main/aurora-udfs/cloudformation/template.yaml). 

# Managing your place index resources with Amazon Location
Managing place index resources

You can manage your place index resources using the Amazon Location console, the AWS CLI, or the Amazon Location APIs.

## List your place index resources


You can view your place index resources list using the Amazon Location console, the AWS CLI, or the Amazon Location APIs:

------
#### [ Console ]

**To view a list of place index resources using the Amazon Location console**

1. Open the Amazon Location console at [https://console.aws.amazon.com/location/](https://console.aws.amazon.com/location/home).

1. Choose **Place indexes** from the left navigation pane.

1. View a list of your place index resources under the **My place indexes**.

------
#### [ API ]

Use the `[ListPlaceIndexes](https://docs.aws.amazon.com/location-places/latest/APIReference/API_ListPlaceIndexes.html)` operation from the Amazon Location Places APIs. 

The following example is an API request to get a list of place index resources in the AWS account. 

```
POST /places/v0/list-indexes
```

The following is an example response for `[ListPlaceIndexes](https://docs.aws.amazon.com/location-places/latest/APIReference/API_ListPlaceIndexes.html)`:

```
{
   "Entries": [ 
      { 
         "CreateTime": 2020-10-30T01:38:36Z,
         "DataSource": "Esri",
         "Description": "string",
         "IndexName": "ExamplePlaceIndex",
         "UpdateTime": 2020-10-30T01:40:36Z
      }
   ],
   "NextToken": "1234-5678-9012"
}
```

------
#### [ CLI ]

Use the `[list-place-indexes](https://docs.aws.amazon.com/cli/latest/reference/location/list-place-indexes.html)` command.

The following example is an AWS CLI to get a list of place index resources in the AWS account. 

```
aws location list-place-indexes
```

------

## Get place index resource details


You can get details about any place index resource in your AWS account using the Amazon Location console, the AWS CLI, or the Amazon Location APIs:

------
#### [ Console ]

**To view the details of a place index resource using the Amazon Location console**

1. Open the Amazon Location console at [https://console.aws.amazon.com/location/](https://console.aws.amazon.com/location/home).

1. Choose **Place indexes** from the left navigation pane.

1. Under **My place indexes**, select the name link of the target place index resource. 

------
#### [ API ]

Use the `[DescribePlaceIndex](https://docs.aws.amazon.com/location-places/latest/APIReference/API_DescribePlaceIndex.html)` operation from the Amazon Location Place APIs. 

The following example is an API request to get the place index resource details for *ExamplePlaceIndex*.

```
GET /places/v0/indexes/ExamplePlaceIndex
```

The following is an example response for `[DescribePlaceIndex](https://docs.aws.amazon.com/location-places/latest/APIReference/API_DescribePlaceIndex.html)`:

```
{
   "CreateTime": 2020-10-30T01:38:36Z,
   "DataSource": "Esri",
   "DataSourceConfiguration": { 
      "IntendedUse": "SingleUse"
   },
   "Description": "string",
   "IndexArn": "arn:aws:geo:us-west-2:123456789012:place-indexes/ExamplePlaceIndex",
   "IndexName": "ExamplePlaceIndex",
   "Tags": { 
      "string" : "string" 
   },
   "UpdateTime": 2020-10-30T01:40:36Z
}
```

------
#### [ CLI ]

Use the `[describe-place-index](https://docs.aws.amazon.com/cli/latest/reference/location/describe-place-index.html)` command.

The following example is an AWS CLI to get the place index resource details for *ExamplePlaceIndex*.

```
aws location describe-place-index \
    --index-name "ExamplePlaceIndex"
```

------

## Delete a place index resource


You can delete a place index resource from your AWS account using the Amazon Location console, the AWS CLI, or the Amazon Location APIs:

------
#### [ Console ]

**To delete a place index resource using the Amazon Location console**

**Warning**  
This operation deletes the resource permanently.

 

1. Open the Amazon Location console at [https://console.aws.amazon.com/location/](https://console.aws.amazon.com/location/home).

1. Choose **Place indexes** from the left navigation pane.

1. Under **My place index**, select the target place index resource. 

1. Choose **Delete place index**.

------
#### [ API ]

Use the `[DeletePlaceIndex](https://docs.aws.amazon.com/location-places/latest/APIReference/API_DeletePlaceIndex.html)` operation from the Amazon Location Places APIs. 

The following example is an API request to delete the place index resource *ExamplePlaceIndex*.

```
DELETE /places/v0/indexes/ExamplePlaceIndex
```

The following is an example success response for `[DeletePlaceIndex](https://docs.aws.amazon.com/location-places/latest/APIReference/API_DeletePlaceIndex.html)`:

```
HTTP/1.1 200
```

------
#### [ CLI ]

Use the `[delete-place-index](https://docs.aws.amazon.com/cli/latest/reference/location/delete-place-index.html)` command.

The following example is an AWS CLI command to delete the place index resource *ExamplePlaceIndex*.

```
aws location delete-place-index \
    --index-name "ExamplePlaceIndex"
```

------