Page updated Jan 16, 2024

Work with geofences

Note: Please reach out to us for any feedback and/or issues here

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:

1npm 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 version 4.0.0 or above and aws-amplify @aws-amplify/geo version 6.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

1import { useEffect, useRef } from "react";
2- import { createMap } from "maplibre-gl-js-amplify";
3+ import { createMap, AmplifyGeofenceControl } from "maplibre-gl-js-amplify";
4+ import { withAuthenticator } from "@aws-amplify/ui-react";
5+ import "@aws-amplify/ui-react/styles.css";
6+ import "maplibre-gl-js-amplify/dist/public/amplify-ctrl-geofence.css";
7import "maplibre-gl/dist/maplibre-gl.css";
8
9function Map() {
10 const mapRef = useRef(null); // Reference to the map DOM element
11
12 // Wrapping your code in a useEffect allows us to run initializeMap after the div has been rendered into the DOM
13 useEffect(() => {
14 let map;
15 async function initializeMap() {
16 // You only want to initialize the underlying maplibre map after the div has been rendered
17 if (mapRef.current != null) {
18 map = await createMap({
19 container: mapRef.current,
20 center: [-122.431297, 37.773972],
21 zoom: 11,
22 });
23 }
24
25+ const control = new AmplifyGeofenceControl()
26+ map.addControl(control);
27 }
28 initializeMap();
29
30 // Cleans up and maplibre DOM elements and other resources - https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#remove
31 return function cleanup() {
32 if (map != null) map.remove();
33 };
34 }, []);
35
36 return (
37 <div className="App">
38 <div ref={mapRef} id="map" />
39 </div>
40 );
41}
42
43export 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.

1import React from 'react';
2import { Amplify } from 'aws-amplify';
3import { withAuthenticator } from '@aws-amplify/ui-react';
4import { MapView } from '@aws-amplify/ui-react-geo';
5import { useControl } from 'react-map-gl';
6import { AmplifyGeofenceControl } from 'maplibre-gl-js-amplify';
7import '@aws-amplify/ui-react/styles.css';
8import '@aws-amplify/ui-react-geo/styles.css';
9import 'maplibre-gl-js-amplify/dist/public/amplify-ctrl-geofence.css';
10import amplifyconfig from './amplifyconfiguration.json';
11Amplify.configure(amplifyconfig);
12
13function Geofence() {
14 useControl(() => new AmplifyGeofenceControl());
15
16 return null;
17}
18
19function App({ signOut }) {
20 return (
21 <div className="App">
22 <MapView
23 initialViewState={{
24 latitude: 37.8,
25 longitude: -122.4,
26 zoom: 14
27 }}
28 >
29 <Geofence />
30 </MapView>
31 </div>
32 );
33}
34
35export 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 Create

Geofence Edit

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.

1import { 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

1Geo.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 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.

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.

NOTE: Polygon arrays have a few requirements:

  • must have at least 4 vertices (i.e. 4 coordinate points)
  • the first and last point must be the same in order to complete the polygonal loop
  • vertices must be in counter-clockwise order

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 object
    • code - the error code
    • message - the error message

Example

1let saveGeofenceResults;
2try {
3 saveGeofenceResults = await Geo.saveGeofences({
4 geofenceId: 'my-geofence',
5 geometry: {
6 polygon: [
7 [-123.14695358276366, 49.290090146520434],
8 [-123.1358814239502, 49.294960279811974],
9 [-123.15021514892577, 49.29300108863353],
10 [-123.14909934997559, 49.29132171993048],
11 [-123.14695358276366, 49.290090146520434]
12 ]
13 }
14 });
15} catch (error) {
16 // errors thrown by input validations of `saveGeofences`
17 throw error;
18}
19
20if (saveGeofenceResults.errors.length > 0) {
21 // error handling that are from the underlying API calls
22 console.log(`Success count: ${saveGeofenceResults.successes.length}`);
23 console.log(`Error count: ${saveGeofenceResults.errors.length}`);
24}

getGeofence

geoGeofence is used to get a single geofence from a collection.

API

1Geo.getGeofence(geofenceId, options) => Promise<Geofence>;

Parameters

  • geofenceId - the id of the geofence to get.
  • options - optional options object for getting a geofence
    • collectionName - 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.

Return

The return from getGeofence is a Promise that resolves to a geofence object.

Example

1let responses;
2try {
3 response = await Geo.getGeofence('geofenceId');
4} catch (error) {
5 throw error;
6}

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

1Geo.listGeofences(options) => Promise<ListGeofenceResults>;

Parameters

  • options - optional options object for saving geofences
    • nextToken - 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.

Return

Returns a Promise that resolves to an object with the following properties:

  • entries - an array of geofences
  • nextToken - the pagination token for the next page of geofences

Example

1let response;
2try {
3 response = await Geo.listGeofences();
4 response.entries.forEach((geofence) => console.log(geofence.geofenceId));
5} catch (error) {
6 throw error;
7}

deleteGeofences

deleteGeofences is used to delete a geofences from a collection. It can delete a single or multiple geofences at once.

API

1Geo.deleteGeofences(geofenceIds, options) => Promise<DeleteGeofencesResults>;

Parameters

  • geofenceIds - a single geofenceId or array of geofenceIds to delete
  • options - optional options object for saving 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.

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 object

Example

1let response;
2try {
3 response = await Geo.deleteGeofences(
4 [
5 "geofence1",
6 "geofence2",
7 "geofence3",
8 ]
9 )
10catch (error) {
11 // error handling from logic and validation issues within `deleteGeofences`
12 throw error;
13}
14
15if(response.errors.length > 0){
16 // error handling that are from the underlying API calls
17 console.log(`Success count: ${response.successes.length}`);
18 console.log(`Error count: ${response.errors.length}`);
19}