Creating geofences, POIs, and routes
Create geofences, POIs, and routes in different shapes using GeoJSON geometry.
Geo objects in Business Data Repository represent geographic features like geofences, points of interest, and routes. They store location data in GeoJSON format, making them useful for defining delivery zones, marking important locations, creating routes, and managing areas where your fleet operates.
This guide walks you through creating, updating, and managing geo objects with different geometry types.
Prerequisites
You need an access token for the workspace you work in. The API takes the workspace from the token, so no operation on this page asks for a workspace ID. See Authentication for how to get a token and how the API picks the workspace.
Check the available geo object types
Before creating a geo object, list the available types to see what options exist with this query:
query ListGeoObjectTypes {
bdr {
geoObjectTypes {
nodes {
id
code
title
}
}
}
}The response lists the types your workspace has created. A new workspace has none, so the list is empty until you create a type. A workspace with two types sees this:
If the response is empty or doesn't have the type you need, create it:
The response confirms the new type:
Save the type ID. You'll need it when creating geo objects.
How GeoJSON geometry works
Geo objects store their geographic shape in the geojsonData field, which uses GeoJSON format as defined in RFC 7946. The format describes each shape as a list of coordinates.
A GeoJSON value in the API is the geometry object itself: a JSON object with a type and coordinates:
Inside a GraphQL mutation, you write the same structure with one difference: the keys have no quotes.
More examples of different geometry types can be found in the Common GeoJSON patterns section.
Supported geometry types
Point
A single coordinate marker. To check which vehicles are at the place, draw a Polygon around the point instead.
Warehouse pin on a map
Polygon
Area boundary. One of the two types that have an area, so containsPoint can test a point against it.
Geofence
LineString
A straight or curved line passing through specific points. Useful for visual map overlays, but has no area, so containsPoint returns false for it.
Road segment, boundary line
MultiPoint
Multiple separate coordinate markers
Distribution network
MultiLineString
Multiple line sequences
Multiple road segments
MultiPolygon
Multiple areas treated as a single geo object. The other type that has an area.
Separate zones that don't touch, city districts
GeometryCollection
A mixed collection of geometry objects of different types
A route line together with its checkpoint markers
Routes and detecting deviation: A GeoJSON LineString represents a line with no width. In fleet management, route monitoring works by detecting whether a vehicle leaves a defined corridor: a Polygon drawn as a band around the intended path. A line can't do this job because it has no area. Use LineString only for drawing on a map, and Polygon whenever you need to check what's inside.
Points and GPS presence detection: A Point geometry has no area, so no vehicle can be inside it. To find out whether a GPS device is near a specific location, create a small Polygon around that location instead of a Point. Then test the device's position against the polygon with containsPoint, as Checking which geo objects cover a point shows.
Coordinate format
GeoJSON uses [longitude, latitude] order, which is opposite to how coordinates are often written in text.
For example, Berlin's Brandenburg Gate is located at latitude 52.516275 and longitude 13.377704. In GeoJSON, this becomes [13.377704, 52.516275].
For details on geometry structure, winding order for polygons, and coordinate reference systems, see RFC 7946 Section 3.1.
Valid areas
A Polygon or a MultiPolygon must describe a well-formed area. When it doesn't, geoObjectCreate and geoObjectUpdate fail with a validation error, usually on input.geojsonData, and save nothing. An area is well formed when it follows these rules:
A
Polygonis a non-empty array of rings, and aMultiPolygonis a non-empty array of such polygons.A ring has at least four positions, and its first and last positions have the same longitude and latitude.
A position has at least two elements, and every element is a number: a longitude from -180 to 180, then a latitude from -90 to 90.
The API doesn't check the winding order of a ring. A third number in a position, the altitude, doesn't change the area. Other geometry types are saved without these checks. An update without geojsonData keeps the stored geometry and doesn't check it. A stored polygon that breaks these rules has no area, so containsPoint returns false for it.
Custom fields
Geo objects support custom fields. You might want to add fields for:
Access restrictions (delivery time windows, vehicle type requirements)
Operational metadata (zone manager contact, capacity limits)
Business attributes (pricing tier, priority level)
See Defining and using custom fields for details on defining and using custom fields.
Example scenario: Delivery service zones
A delivery company needs to define service areas and mark important locations. They start by creating an arrival zone around their main warehouse: a small polygon that lets them detect when vehicles arrive or depart. Then they create a larger delivery zone and adjust its boundaries as the business grows.
Create the arrival zone
Rather than a Point, draw the warehouse as a small Polygon around the building. A polygon has an area, so containsPoint can tell whether a vehicle's position is inside it.
The polygon is a small rectangle roughly 30 × 45 meters centered on coordinates [13.404954, 52.520008] in Berlin's Mitte district. Adjust the coordinates to match your actual site boundary.
The response confirms creation:
Save the id. You'll need it for updates.
Create a polygon-shaped delivery zone
Create a rectangular delivery zone covering central Berlin:
Note the coordinate structure:
The outer array holds one or more rings. A ring is a closed loop of coordinate pairs. This example has one ring, the outer boundary.
Each ring is an array of
[longitude, latitude]pairs.The first and last pairs are identical, which closes the loop.
The response returns:
Common GeoJSON patterns
The examples below show the complete geometry objects you send in mutations and receive in responses.
Single location marker (warehouse, customer address)
Rectangular area (simple geofence)
Polygon with exclusion zone (donut-shaped)
The first ring defines the outer boundary. The second ring creates a hole: an area inside the outer boundary where the polygon doesn't apply. This is useful for delivery zones that exclude certain neighborhoods or restricted areas.
Route corridor (for deviation detection)
In fleet management, routes are drawn as Polygon corridors rather than LineString geometries. A corridor is a band around the intended path: if a vehicle leaves this zone, it has deviated from the route. The example below shows a narrow corridor along a Berlin street segment:
Use a wider corridor for highways where minor deviations are acceptable, and a narrower one for city routes requiring precise tracking.
Line overlay (visual display only)
Use LineString when you need to draw a line on a map for display purposes, for example to show the planned path of a delivery or the boundary between two zones. A LineString has no area, so containsPoint returns false for it.
Multiple warehouse locations
Listing geo objects
To retrieve all geo objects for a workspace, use this query:
The response returns a paginated list:
You can filter by type or search by title:
The response returns only matching geo objects:
For more on filtering and pagination, see Filtering and sorting and Pagination.
Checking which geo objects cover a point
A geo object covers a point when the point is inside its area or on the boundary of the area. Only a well-formed Polygon or MultiPolygon has an area. A point inside a hole of a polygon isn't covered, and a point on the boundary of the hole is.
To find the geo objects that cover a point, add containsPoint to the filter. This query lists the zones that cover a delivery address in Berlin:
The address is inside both zones of the example scenario, so the response lists both, sorted by title:
The containsPoint condition combines with typeIds, titleContains, and the custom field conditions, and all of them must match. Sorting, paging, and total work as with any other filter.
To test one geo object against one or more points, select its containsPoint field with a point. The field returns true or false. A geo object without an area returns false for every point. To test several points in one request, give each point its own alias:
The response has one value for each alias:
Edges of an area are straight lines in longitude and latitude. Longitude 180 and -180 are different points, so draw an area that crosses the 180th meridian as two polygons. To check which of your assets are inside a geofence now, combine this test with the positions from Tracking, as Checking which assets are inside a geofence shows.
Handling version conflicts
If you include version in your mutation and the entity has been modified since you last fetched it, the API returns a conflict error:
To resolve this:
Query the geo object to get the current version and geometry
Merge your changes with the current state
Retry the mutation with the correct version
For more details on version conflicts, see Optimistic locking.
Deleting a geo object
When you restructure your delivery zones and no longer need this geo object, you can delete it. While an asset or another geo object names it in a custom field, the delete is refused with IN_USE, and extensions.blockers names those records with the path customFields.<code>. Change the value on them first, or unset it if the field isn't required.
The response confirms deletion:
See also
Geo objects: Complete reference for all geo object operations and types
Filtering and sorting: Narrow list queries and control result order
Optimistic locking: Prevent concurrent updates from overwriting each other with
versionBuilding a live fleet map: Check which assets are inside a geofence right now, using the geometry you drew here
Reading a vehicle trip history: Find where a vehicle drove and where it stopped over a period
Last updated
Was this helpful?