Geofencing seems simple on its face – draw a shape, check if a point is inside it, fire an alert if it’s outside. The naive approach of this works great in a demo environment, and predictably breaks down within the first week of deployment due to even the natural jitter in GPS alone causing frequent false “asset left the zone” alerts. This article outlines the system that is actually designed to survive the real world of GPS.
The Naive Implementation (and why it breaks)
The first version many people come up with will likely resemble this:
on_location_update(asset_id, lat, lon):
zone = get_zone_for_asset(asset_id)
if not point_in_polygon(lat, lon, zone.boundary):
send_alert(asset_id, "left zone")
This will only work the first time, with perfectly clean GPS coordinates generated in a test environment. Real-world devices that track locations via GPS report data that can include an error margin ranging from meters to tens of meters, depending on satellite visibility, urban canyon effects, or even weather. An asset that’s just sitting at the boundary of a geofence zone will constantly oscillate in and out of the polygon, bombarding your team with useless “zone exit” alerts until they begin ignoring everything.
Fix #1: Buffer the Boundary, Don’t Trust the Raw Point
You should expand the definition of “inside” the zone to include an additional margin beyond the drawn boundary. This buffer zone should be the size of the expected GPS error margin of your devices (typically 10-15m for consumer devices, shorter for devices that use RTK correction). Before alerting on a zone exit, the asset must be outside this expanded area, not just slightly crossing the border of the polygon itself.
on_location_update(asset_id, lat, lon):
zone = get_zone_for_asset(asset_id)
buffered_boundary = shrink_polygon(zone.boundary, zone.gps_error_margin)
if not point_in_polygon(lat, lon, buffered_boundary):
handle_potential_exit(asset_id, lat, lon)
Fix #2: Require Persistence, Not a Single Reading
An isolated “outside the zone” reading is not an indication of a problem – it may just be a GPS fluctuation. You need to wait for multiple consistent readings or a set duration before concluding that the asset has actually left the zone.
handle_potential_exit(asset_id, lat, lon):
record_exit_candidate(asset_id, timestamp=now())
if exit_candidate_duration(asset_id) >= MIN_EXIT_DURATION:
send_alert(asset_id, "confirmed zone exit")
clear_exit_candidate(asset_id)
MIN_EXIT_DURATION is a value you’ll adjust over time. A high-value asset that’s being stolen may require only 60 seconds of sustained non-compliance, whereas a low-priority asset may need to be outside for minutes or longer.
Fix #3: Different Confidence for Different Location Sources
If your solution includes tracking methods other than GPS (like Bluetooth beacons or Wi-Fi positioning indoors), you’ll want to adjust the system’s tolerance for each method independently. GPS has different characteristics for accuracy than Bluetooth trilateration and indoor Wi-Fi positioning methods, each being influenced differently by factors like signal interference or signal obstruction. Don’t treat all location sources as equal – they aren’t.
Fix #4: Correlate With Sensor State Before Escalating
For cold chain, pharmaceuticals, or any other sensitive material, a zone exit event is far more significant if combined with other important sensor data. "Asset has left the building" is not an urgent alert for many applications, but "asset has left the building and the temperature sensor is approaching its threshold" certainly is. Building alerts that factor in combined conditions like zone status, temperature thresholds, and other sensor states will make the alert much more relevant and less prone to false positives.
on_confirmed_exit(asset_id):
sensor_state = get_current_sensor_reading(asset_id)
if sensor_state.breaches_threshold():
send_urgent_alert(asset_id, "zone exit + sensor breach")
else:
send_standard_alert(asset_id, "zone exit")
The Actual Lesson
Geofencing solutions are most often abandoned or ignored because of poorly designed alerting systems, not inaccurate point-in-polygon logic. These systems fail when they treat every piece of GPS data as exact instead of a rough estimate and when they treat every deviation as equally urgent, ignoring nuances like persistent behavior, location accuracy, and other critical data points. Buffering, minimum duration rules, and sensor data correlation aren’t complicated add-ons - they’re essential to building a system that your team can rely on.
When you’re preparing to implement geofencing with real-world hardware rather than a simulator, be sure to consult with your device vendors about the documented accuracy specifications of their hardware before configuring the system’s tolerance levels and time delays, as the error profile for Bluetooth, cellular, and GPS-based trackers varies considerably. If you need information on different types of asset tracking hardware, visit AssetTrackPro.
I’d be curious to hear from anyone else in the community on their experiences with different confirmation window configurations, especially in the realm of indoor real-time location systems (RTLS), where noise characteristics are much different from outdoor GPS environments.
Top comments (0)