Work with geofences
Provisioning geofence resources
First, make sure you've provisioned a geofence collection resource and configured your app using the instructions in either Configure a geofence collection or Use existing Amazon Location Service resources and you have already setup displaying a map in your application.
Manage Geofences in Your Application
To add a geofence management component to your map, you can use the amplify-geofence-control.
Install the necessary dependencies with the following command:
npm install aws-amplify @aws-amplify/geo @aws-amplify/ui-react @aws-amplify/ui-react-geo maplibre-gl-js-amplify maplibre-gl
Note: Make sure that
maplibre-gl-js-amplify
version4.0.0
or above andaws-amplify @aws-amplify/geo
version6.0.0
or above are installed.
First, create a map onto which you want to add the geofence management component. See the guide on creating and displaying maps.
Then, import AmplifyGeofenceControl from "maplibre-gl-js-amplify", create a new instance of this control and add it to your MapLibre map instance.
Note: When using the existing maps implementation you can add the Geofence control to an existing map
import { useEffect, useRef } from "react";- import { createMap } from "maplibre-gl-js-amplify";+ import { createMap, AmplifyGeofenceControl } from "maplibre-gl-js-amplify";+ import { withAuthenticator } from "@aws-amplify/ui-react";+ import "@aws-amplify/ui-react/styles.css";+ import "maplibre-gl-js-amplify/dist/public/amplify-ctrl-geofence.css";import "maplibre-gl/dist/maplibre-gl.css";
function Map() { const mapRef = useRef(null); // Reference to the map DOM element // Wrapping your code in a useEffect allows us to run initializeMap after the div has been rendered into the DOM useEffect(() => { let map; async function initializeMap() { // You only want to initialize the underlying maplibre map after the div has been rendered if (mapRef.current != null) { map = await createMap({ container: mapRef.current, center: [-122.431297, 37.773972], zoom: 11, }); }+ const control = new AmplifyGeofenceControl()+ map.addControl(control); } initializeMap(); // Cleans up and maplibre DOM elements and other resources - https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#remove return function cleanup() { if (map != null) map.remove(); }; }, []); return ( <div className="App"> <div ref={mapRef} id="map" /> </div> );}
export default withAuthenticator(Map);
Note: When using the Amplify React MapView component you can use the useControl
hook from react-map-gl to render the Geofence control component. The react-map-gl dependency is already installed through @aws-amplify/ui-react-geo
, you do not need to install it manually.
import React from 'react';import { Amplify } from 'aws-amplify';import { withAuthenticator } from '@aws-amplify/ui-react';import { MapView } from '@aws-amplify/ui-react-geo';import { useControl } from 'react-map-gl';import { AmplifyGeofenceControl } from 'maplibre-gl-js-amplify';import '@aws-amplify/ui-react/styles.css';import '@aws-amplify/ui-react-geo/styles.css';import 'maplibre-gl-js-amplify/dist/public/amplify-ctrl-geofence.css';import amplifyconfig from './amplifyconfiguration.json';Amplify.configure(amplifyconfig);
function Geofence() { useControl(() => new AmplifyGeofenceControl());
return null;}
function App({ signOut }) { return ( <div className="App"> <MapView initialViewState={{ latitude: 37.8, longitude: -122.4, zoom: 14 }} > <Geofence /> </MapView> </div> );}
export default withAuthenticator(App);
Note: Ensure that your package bundler (webpack, rollup, etc) is configured to handle css files. Check out the webpack documentation here.
Notes: To use Geofence Controls the user will need to be authenticated with the administrative Cognito user associated with the Geofence Collection you created above. Below is an example using React and the Amplify Authenticator but for other use cases check the Authentication documentation.
Geofence API
If you are using a different mapping library or need a programmatic approach to managing geofences, the @aws-amplify/geo
package provides methods for managing geofences, but not geofence collections.
First, you need to import Geo from the @aws-amplify/geo
package.
import { Geo } from '@aws-amplify/geo';
saveGeofences
saveGeofences
is used to save geofences to your collection. It can take a single geofence or an array of geofences.
API
Geo.saveGeofences(geofences, options) => Promise<SaveGeofenceResults>;
Parameters
geofences
- can be a single geofence object, or an array of geofence objects to save to a collection.options
- optional options object for saving geofencescollectionName
- the name of the collection to save geofences to.- Defaults to the default collection listed in your
amplifyconfiguration.json
file after provisioning a geofence collection resource.
- Defaults to the default collection listed in your
Geofence objects must have the following properties:
geofenceId
- a opaque and unique identifier for the geofence.geometry
- a geometry object that defines the geofence.polygon
- an array of arrays with [Longitude, Latitude] coordinates.
Return
The return from saveGeofences
is a Promise that resolves to SaveGeofenceResults
which contains both successes and errors for geofences that were successfully created or failed.
Each success object has the following properties:
geofenceId
- the geofenceId of the geofence that was saved.createTime
- the time the geofence was created.updateTime
- the time the geofence was last updated.
Each error object has the following properties:
geofenceId
- the geofenceId of the geofence that failed to be saved.error
- an error objectcode
- the error codemessage
- the error message
Example
let saveGeofenceResults;try { saveGeofenceResults = await Geo.saveGeofences({ geofenceId: 'my-geofence', geometry: { polygon: [ [-123.14695358276366, 49.290090146520434], [-123.1358814239502, 49.294960279811974], [-123.15021514892577, 49.29300108863353], [-123.14909934997559, 49.29132171993048], [-123.14695358276366, 49.290090146520434] ] } });} catch (error) { // errors thrown by input validations of `saveGeofences` throw error;}
if (saveGeofenceResults.errors.length > 0) { // error handling that are from the underlying API calls console.log(`Success count: ${saveGeofenceResults.successes.length}`); console.log(`Error count: ${saveGeofenceResults.errors.length}`);}
getGeofence
geoGeofence
is used to get a single geofence from a collection.
API
Geo.getGeofence(geofenceId, options) => Promise<Geofence>;
Parameters
geofenceId
- theid
of the geofence to get.options
- optional options object for getting a geofencecollectionName
- the name of the collection to get geofence from.- Defaults to the default collection listed in your
amplifyconfiguration.json
file after provisioning a geofence collection resource.
- Defaults to the default collection listed in your
Return
The return from getGeofence
is a Promise that resolves to a geofence object.
Example
let responses;try { response = await Geo.getGeofence('geofenceId');} catch (error) { throw error;}
listGeofences
listGeofences
is used to get a list of geofences from a collection. It has pagination built in and will return 100 geofences per page.
API
Geo.listGeofences(options) => Promise<ListGeofenceResults>;
Parameters
options
- optional options object for saving geofencesnextToken
- the pagination token for the next page of geofences.- if no token is given, it will return the first page of geofences.
collectionName
- the name of the collection to save geofences to.- Defaults to the default collection listed in your
amplifyconfiguration.json
file after provisioning a geofence collection resource.
- Defaults to the default collection listed in your
Return
Returns a Promise that resolves to an object with the following properties:
entries
- an array of geofencesnextToken
- the pagination token for the next page of geofences
Example
let response;try { response = await Geo.listGeofences(); response.entries.forEach((geofence) => console.log(geofence.geofenceId));} catch (error) { throw error;}
deleteGeofences
deleteGeofences
is used to delete a geofences from a collection. It can delete a single or multiple geofences at once.
API
Geo.deleteGeofences(geofenceIds, options) => Promise<DeleteGeofencesResults>;
Parameters
geofenceIds
- a single geofenceId or array of geofenceIds to deleteoptions
- optional options object for saving geofencescollectionName
- the name of the collection to save geofences to.- Defaults to the default collection listed in your
amplifyconfiguration.json
file after provisioning a geofence collection resource.
- Defaults to the default collection listed in your
Return
The return from deleteGeofences
is a Promise that resolves to an object with both successes and errors for geofences that were successfully deleted or not.
- The success object is an array of geofenceIds that were successfully deleted.
- The error object is an array of error objects that include the following properties:
geofenceId
- the geofenceId of the geofence that failed to be deleted.error
- an error objectcode
- the error codemessage
- the error
Example
let response;try { response = await Geo.deleteGeofences( [ "geofence1", "geofence2", "geofence3", ] )catch (error) { // error handling from logic and validation issues within `deleteGeofences` throw error;}
if(response.errors.length > 0){ // error handling that are from the underlying API calls console.log(`Success count: ${response.successes.length}`); console.log(`Error count: ${response.errors.length}`);}