GuidesAPI Reference
Guides

Relationship between geofence polygons and layers

Each geofence polygon, point, or polyline is assigned to exactly one layer. You can create multiple layers. A layer can only contain geometries of one type: polygons, points, or polylines. This allows you to group geofences by fence types, topics, or by asset groups.

If possible then submit or update all polygons of a layer in a single batch. The HERE Geofencing API supports adding or modifying of individual polygons, but only for storage type "updatable", not for "readonly".

Each customer can create multiple layers with many geometries per layer. For maximum values please refer to Geofencing's resource serviceconfiguration.json. If you need to need to extend the limits, please contact Technical Customer Support.

Distribute the geofences across map layers

While it seems obvious to create separate geofence layer per user/device/car, it's not efficient for the service.

Usually, geofences of the same type (spatial extent, update frequency, coordinate resolution) should go together into a single layer.

Each geofence should contain an attribute (or several ones) describing to which assets they apply (and some conditions, like timeframes), so customer’s app can filter which fences apply to the car/user.

Being a backend service, HERE Geofencing API v8 is usually not called by the users/devices directly, so it is not a privacy concern to return geofences of different cars/users to customer’s app.

Also, different geometry types (circles vs polygons) should be stored in separate layers.

Polygon identifier and attribution

While the HERE Geofencing API is not intended to for use as general data storage, the API must have access to geoshapes to respond to requests. Each of these geoshapes must be associated with a unique identifier. The HERE Geofencing API also includes these IDs in the responses.

One common method for assigning these IDs uses straightforward geometry identifiers as follows:

  • polygon ID for polygonal fences
  • link ID for road, railway, river, or other linear fences
  • point ID or store ID for point fences

In the following example, the column ID uniquely identifies the polygon.

ID	NAME	ABBR	WKT
1	AlexanderPlatz	DEU	POLYGON((13.41252 52.52228,13.41426 52.5221,13.41522 52.52113,13.41227 52.51981,13.41252 52.52228))
2	BrandenburgGate	DEU	POLYGON((13.38021 52.51668,13.37987 52.51678,13.37984 52.5163,13.37984 52.5163,13.38021 52.51668))
3	RoyalObservatory	UK	POLYGON((-0.00156 51.47778,-0.00142 51.47796,-0.00114 51.47776,-0.00172 51.4777,-0.00156 51.47778))

To check if a geocoordinate is within a specified radius of a geoshape loaded onto a layer include the attributes request parameter to define how you want the geoshapes grouped in the response. For instance, if you load the example into a layer and set attributes=NAME in your request, the geoshapes within the radius will appear separately in the response, with each entry corresponding to a unique value in the NAME column. A sample response is shown below. The response also includes originalLat and originalLon of the asset point.

{
    "geometries": [
        {
            "attributes": {
                "NAME": "BrandenburgGate"
            },
            "distance": -7.44,
            "nearestLat": 52.51655,
            "nearestLon": 13.38008,
            "originalLat": 52.516582814825604,
            "originalLon": 13.379987793177522,
            "layerId": "GEOFENCINGTEST",
            "geometry": "MULTIPOLYGON(((13.38021 52.51668,13.37984 52.5163,13.37987 52.51678,13.38021 52.51668)))"
        },
        {
            "attributes": {
                "NAME": "AlexanderPlatz"
            },
            "distance": 2216.24,
            "nearestLat": 52.51981,
            "nearestLon": 13.41227,
            "originalLat": 52.516582814825604,
            "originalLon": 13.379987793177522,
            "layerId": "GEOFENCINGTEST",
            "geometry": "MULTIPOLYGON(((13.41252 52.52228,13.41426 52.5221,13.41522 52.52113,13.41227 52.51981,13.41252 52.52228)))"
        }
    ],
    "meta": [
        {
            "layerId": "GEOFENCINGTEST",
            "lastUpdateTimeStamp": 1731580417770
        }
    ]
}

However, if you specify attributes=ID in the same situation, the response groups the results that match the request for those lines that match the specified ABBR value. In other words, if you specify ID=2, the results include geometries only for ID=2. In this case, the response looks as follows:

{
    "geometries": [
        {
            "attributes": {
                "ID": "2"
            },
            "distance": -7.44,
            "nearestLat": 52.51655,
            "nearestLon": 13.38008,
            "originalLat": 52.516582814825604,
            "originalLon": 13.379987793177522,
            "layerId": "GEOFENCINGTEST",
            "geometry": "MULTIPOLYGON(((13.38021 52.51668,13.37984 52.5163,13.37987 52.51678,13.38021 52.51668)))"
        }
    ],
    "meta": [
        {
            "layerId": "GEOFENCINGTEST",
            "lastUpdateTimeStamp": 1731580417770
        }
    ]
}

When you add a line 4 to the geoshapes as follows:

4	Reichstag	BER	POLYGON((13.37494 52.51885,13.37485 52.51948,13.3755 52.51817,13.3744 52.51757,13.37494 52.51885))

the API includes this geoshape in the response if the geocoordinate is within range, but in a separate group because the values were separate. In this case, the response looks as follows:

{
    "geometries": [
        {
            "attributes": {
                "ID": "2"
            },
            "distance": -7.44,
            "nearestLat": 52.51655,
            "nearestLon": 13.38008,
            "originalLat": 52.516582814825604,
            "originalLon": 13.379987793177522,
            "layerId": "GEOFENCINGTEST",
            "geometry": "MULTIPOLYGON(((13.38021 52.51668,13.37984 52.5163,13.37987 52.51678,13.38021 52.51668)))"
        },
        {
            "attributes": {
                "ID": "4"
            },
            "distance": 351.64,
            "nearestLat": 52.51817,
            "nearestLon": 13.3755,
            "originalLat": 52.516582814825604,
            "originalLon": 13.379987793177522,
            "layerId": "GEOFENCINGTEST",
            "geometry": "MULTIPOLYGON(((13.37494 52.51885,13.37485 52.51948,13.3755 52.51817,13.3744 52.51757,13.37494 52.51885)))"
        },
        {
            "attributes": {
                "ID": "1"
            },
            "distance": 2216.24,
            "nearestLat": 52.51981,
            "nearestLon": 13.41227,
            "originalLat": 52.516582814825604,
            "originalLon": 13.379987793177522,
            "layerId": "GEOFENCINGTEST",
            "geometry": "MULTIPOLYGON(((13.41252 52.52228,13.41426 52.5221,13.41522 52.52113,13.41227 52.51981,13.41252 52.52228)))"
        }
    ],
    "meta": [
        {
            "layerId": "GEOFENCINGTEST",
            "lastUpdateTimeStamp": 1731580417770
        }
    ]
}

In summary, you can use these column values similarly to the GROUP BY function in SQL.

Additionally, you can associate custom attributes with geoshapes for use in your app. The API includes any attributes linked to a geoshape in its response, but these attributes should be limited to those essential for your app.

If you need to store a substantial amount of data alongside the geometries—where the size of your additional data equals or exceeds the size of the geometries in bytes—please contact Technical Customer Support.