**Note:** Please reach out to us for any feedback and/or issues [here](https://github.com/aws-amplify/amplify-js/issues) ## Add location search functionality on a map First, make sure you've provisioned a search index resource and configured your app using the instructions in either [Amplify CLI - Geo - Location Search](/cli/geo/search) or [Use existing Amazon Location Service resources](/lib/geo/existing-resources) and you have already setup [displaying a map](/lib/geo/maps) in your application. **Note:** For React, you can use the [Amplify UI Location Search component](https://ui.docs.amplify.aws/react/connected-components/geo#location-search) to generate and display the search results. To add a location search UI component to your map, you can use the [maplibre-gl-geocoder](https://github.com/maplibre/maplibre-gl-geocoder) library. `maplibre-gl-js-amplify` package makes it easy to integrate `maplibre-gl-geocoder` with Amplify Geo by exporting a utility function `createAmplifyGeocoder()` that returns an instance of `maplibre-gl-geocoder` with some pre-defined settings and supports all the [options](https://github.com/maplibre/maplibre-gl-geocoder/blob/main/API.md#parameters) for customizing the UI component Install the necessary dependencies with the following command: ```bash npm install @maplibre/maplibre-gl-geocoder maplibre-gl@1 maplibre-gl-js-amplify ``` > **Note:** Make sure that `maplibre-gl-js-amplify` version `1.1.0` or above is installed. First, create a map onto which you want to add the location search UI component. See the guide on [creating and displaying maps](https://docs.amplify.aws/lib/geo/maps/q/platform/js/). Then, use `createAmplifyGeocoder()` to get a new instance of `MaplibreGeocoder` and add the location search UI component to the map. > **Note:** Ensure that your package bundler (webpack, rollup, etc) is configured to handle css files. Check out the webpack documentation [here](https://webpack.js.org/loaders/css-loader/). ```javascript import { createMap, createAmplifyGeocoder } from "maplibre-gl-js-amplify"; import maplibregl from "maplibre-gl"; import "maplibre-gl/dist/maplibre-gl.css"; import "@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css"; import "maplibre-gl-js-amplify/dist/public/amplify-geocoder.css"; // Optional CSS for Amplify recommended styling async function initializeMap() { const el = document.createElement("div"); el.setAttribute("id", "map"); document.body.appendChild(el); const map = await createMap({ container: "map", center: [-123.1187, 49.2819], // [Longitude, Latitude] zoom: 11, }) map.addControl(createAmplifyGeocoder()); } initializeMap(); ``` ![A search box on the top right corner of a map](/images/geocoder-search-box-map.png) ### Display the location search box outside the map You can also use [maplibre-gl-geocoder](https://github.com/maplibre/maplibre-gl-geocoder) to display the location search UI component anywhere in your application, even outside the map. To do so, extract the html element using function `onAdd()` and attach it anywhere in your DOM instead of adding it via the map's `addControl()` function. ```javascript const geocoder = createAmplifyGeocoder(); document.getElementById("search").appendChild(geocoder.onAdd()); ``` ![A search box](/images/geocoder-search-box.png) ### Customize Search Icons You can customize the search icons used by the [maplibre-gl-geocoder](https://github.com/maplibre/maplibre-gl-geocoder) to use any image of your choosing. [MapLibre markers](https://maplibre.org/maplibre-gl-js-docs/api/markers/) require an [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) when passing in custom images. The following example puts an existing SVG icon into an HTMLElement before being passed to `createAmplifyGeocoder` which creates a [maplibre-gl-geocoder](https://github.com/maplibre/maplibre-gl-geocoder). ```javascript import myIcon from "./myIcon.svg" // relative path to your custom icon const icon = new Image(100, 100); icon.src = myIcon; const geocoder = createAmplifyGeocoder({ showResultMarkers: { element: icon } }); map.addControl(geocoder); ``` ![A search box](/images/geocoder-custom-images.png) ## Location-based search capabilities Amplify Geo enables you to search for locations by text, addresses, or geo-coordinates. ### Search by text, address, business name, city, and more The `Geo.searchByText()` API enables you to search for places or points of interest by free-form text, such as an address, name, city, or region. ```javascript import { Geo } from "aws-amplify" Geo.searchByText("Amazon Go Store") ``` Customize your search results further by providing: - `countries` - to limit the search results to given countries (specified in [ISO Alpha-3 country codes](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3)) - `maxResults` - to limit the maximum result set - `biasPosition` - to act as the search origination location - `searchAreaConstraints` - to limit the area to search inside of - `searchIndexName` - to use a different Location Service search index resource than the default **Note:** Providing both `biasPosition` and `searchAreaConstraints` parameters simultaneously returns an error. ```javascript const searchOptionsWithBiasPosition = { countries: string[], // Alpha-3 country codes maxResults: number, // 50 is the max and the default biasPosition: [ longitude // number latitude // number, ], // Coordinates point to act as the center of the search searchIndexName: string, // the string name of the search index } const searchOptionsWithSearchAreaConstraints = { countries: ["USA"], // Alpha-3 country codes maxResults: 25, // 50 is the max and the default searchAreaConstraints: [SWLongitude, SWLatitude, NELongitude, NELatitude], // Bounding box to search inside of searchIndexName: string, // the string name of the search index } Geo.searchByText('Amazon Go Stores', searchOptionsWithBiasPosition) ``` This returns places and their coordinates that match the search constraints. A place can also have additional metadata as shown in the example below. ```javascript // returns [ { geometry: { point: [ -122.34014899999994, // Longitude point 47.61609000000004 // Latitude point ], }, addressNumber: "2131" // optional string for the address number alone country: "USA" // optional Alpha-3 country code label: "Amazon Go, 2131 7th Ave, Seattle, WA, 98121, USA" // Optional string municipality: "Seattle" // Optional string neighborhood: undefined // Optional string postalCode: "98121" // Optional string region: "Washington" // Optional string street: "7th Ave" // Optional string subRegion: "King County" // Optional string } ] ``` ### Search by coordinates The `Geo.searchByCoordinates()` API is a reverse Geocoder that takes a coordinate point and returns information about what it finds at that point on the map. The returned object is the same shape as `searchByText()` API above. ```javascript import { Geo } from "aws-amplify"; Geo.searchByCoordinates([longitudePoint, latitudePoint]) ``` You can optionally limit your result set with the `maxResults` parameter or override the default search index with the `searchIndexName` parameter. ```javascript const searchOptionsWithBiasPosition = { maxResults: number, // 50 is the max and the default searchIndexName: string, // the string name of the search index } Geo.searchByCoordinates([-122.3399573, 47.616179], searchOptionsWithBiasPosition) ``` ### Search for suggestions The `Geo.searchForSuggestions()` API enables you to search for suggestions by free-form text, such as a place, address, city, or region. ```javascript import { Geo } from "aws-amplify" Geo.searchForSuggestions("Amazon Go Store") ``` Similar to `Geo.searchByText()` API, customize your search results further by providing: - `countries` - to limit the search results to given countries (specified in [ISO Alpha-3 country codes](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3)) - `maxResults` - to limit the maximum result set - `biasPosition` - to act as the search origination location - `searchAreaConstraints` - to limit the area to search inside of - `searchIndexName` - to use a different Location Service search index resource than the default **Note:** Providing both `biasPosition` and `searchAreaConstraints` parameters simultaneously returns an error. ```javascript const searchOptionsWithBiasPosition = { countries: string[], // Alpha-3 country codes maxResults: number, // 50 is the max and the default biasPosition: [ longitude // number latitude // number, ], // Coordinates point to act as the center of the search searchIndexName: string, // the string name of the search index } const searchOptionsWithSearchAreaConstraints = { countries: ["USA"], // Alpha-3 country codes maxResults: 25, // 50 is the max and the default searchAreaConstraints: [SWLongitude, SWLatitude, NELongitude, NELatitude], // Bounding box to search inside of searchIndexName: string, // the string name of the search index } Geo.searchForSuggestions('Amazon Go', searchOptionsWithBiasPosition) ``` This returns a list of suggestions (places and their respective `placeId` if available) that match the search constraints. ```javascript // returns [ { text: "Amazon Go, 2131 7th Ave, Seattle, WA, 98121, USA", placeId: "8fd9d4c6-2527-4190-a7df-0dae352c9dc6" }, { text: "Amazon Go, 1906 Terry Ave, Seattle, WA, 98101, USA", placeId: "5d04d071-dea2-4d86-bfce-86bd6a8f4787" } ] ``` In cases where `placeId` is not available on the list of suggestions as below, use ``searchByText`` to search for the selected place by text. ```javascript Geo.searchForSuggestions("Amazon", { MaxResults: 5 }) // returns [ { text: "Amazon Go", }, { text: "Amazon 4-star", } ] Geo.searchByText('Amazon Go', { MaxResults: 5 }) ``` This returns places and their coordinates that match the search text. ### Search by PlaceId The `Geo.searchByPlaceId()` API enables you to search for a place by a `placeId`, which is a unique opaque token for a place returned by the provider. **Note:** Upgrade to the latest Amplify CLI version (greater than version 10.4) and do an ``amplify push`` to update your IAM policies to allow for ``getPlace`` API. ```javascript import { Geo } from "aws-amplify" Geo.searchByPlaceId(placeId) ``` You can optionally override the default search index with the `searchIndexName` parameter. ```javascript const searchByPlaceIdOptions = { searchIndexName: string, // the string name of the search index } Geo.searchByPlaceId("8fd9d4c6-2527-4190-a7df-0dae352c9dc6", searchByPlaceIdOptions) ``` This returns a place with metadata as shown in the example below. ```javascript // returns { geometry: { point: [ -122.34014899999994, // Longitude point 47.61609000000004 // Latitude point ], }, addressNumber: "2131" // optional string for the address number alone country: "USA" // optional Alpha-3 country code label: "Amazon Go, 2131 7th Ave, Seattle, WA, 98121, USA" // Optional string municipality: "Seattle" // Optional string neighborhood: undefined // Optional string postalCode: "98121" // Optional string region: "Washington" // Optional string street: "7th Ave" // Optional string subRegion: "King County" // Optional string } ```