advanced
zones
geofencing
enforcement

How Geofencing Zones Work

Technical deep-dive into how Levy Fleets zones function - including enforcement pipelines, ride validation, GPS considerations, and real-time notifications

Levy Fleets Team25 de diciembre de 202520 min read

How Geofencing Zones Work

This article provides an in-depth technical explanation of how zones function in Levy Fleets, covering the enforcement pipeline, ride-end validation, event logging, and customer notifications.

Architecture Overview

Levy Fleets uses zones in two primary contexts:

1. Live Telemetry Enforcement

When a vehicle sends GPS coordinates (latitude/longitude) during an active ride, the system:

  • Loads all speed-limit and no-go zones for the vehicle's subaccount
  • Evaluates whether the vehicle's location falls within any zone polygons
  • Sends IoT commands to adjust speed or disable the motor as needed
  • Logs zone entry/exit events
  • Sends customer notifications

2. Ride-End Validation

When a customer attempts to end a ride, the system:

  • Loads all parking, no-parking, and no-go zones
  • Evaluates whether the ending location satisfies parking requirements
  • Blocks or allows the ride end based on zone membership

Real-Time Processing

Zone enforcement runs on every GPS telemetry update from vehicles during active rides. This ensures immediate response to zone entries and exits.

Zone Data Structure

Zones are stored with the following key properties:

PropertyTypeDescription
idUUIDUnique identifier
subaccount_idUUIDThe subaccount (location) this zone belongs to
nameTEXTHuman-readable zone name
typeENUMparking, no_parking, no_go, speed_limit, charging, bonus, service_area
geojsonJSONBGeoJSON Feature with Polygon geometry
speed_limit_kphINTEGERSpeed limit (1-80 km/h, only for speed_limit type)
parking_reward_pointsINTEGERPoints awarded for parking here (bonus zones)
is_preferred_parkingBOOLEANWhether this is a preferred parking location
rebalancing_multiplierDECIMALPoints multiplier for rebalancing incentives

GeoJSON Format

Zone boundaries are stored as GeoJSON Feature objects:

{
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [-122.4194, 37.7749],
        [-122.4180, 37.7749],
        [-122.4180, 37.7735],
        [-122.4194, 37.7735],
        [-122.4194, 37.7749]
      ]
    ]
  }
}

Coordinate Format

Coordinates are in [longitude, latitude] format (GeoJSON standard), not [latitude, longitude]. This is a common source of errors when importing zone data.

Real-Time Enforcement Flow

The enforcement pipeline runs on every GPS telemetry update from vehicles during active rides.

Step 1: Trigger Conditions

Enforcement is triggered when:

  • A GPS update is received from a vehicle
  • The vehicle has an active ride (ride_status = 'in_progress')
  • The vehicle has a valid IoT IMEI configured
  • Valid coordinates are provided (finite latitude and longitude)

Step 2: Zone Loading

The system queries all speed_limit and no_go zones for the vehicle's subaccount that are not deleted.

Step 3: Point-in-Polygon Evaluation

For each zone, the system uses a ray-casting algorithm to determine if the vehicle's location is inside the polygon:

  1. Cast a ray from the point to infinity
  2. Count how many times the ray crosses polygon edges
  3. Odd count = inside, Even count = outside

The system evaluates the vehicle's current position against all loaded zones and categorizes them:

  • Speed zones: All speed_limit zones containing the vehicle
  • No-go zones: All no_go zones containing the vehicle

Step 4: Determine Active Restrictions

For overlapping speed zones:

  • The system calculates the effective speed limit for each zone
  • If the zone has a speed_limit_kph value, it uses that
  • Otherwise, it falls back to the subaccount's slow_speed_zone_limit_kph setting
  • The lowest limit among all overlapping zones is applied

For no-go zones:

  • Any no-go zone containing the vehicle triggers motor shutdown
  • Only one no-go zone needs to match for enforcement

Step 5: IoT Command Dispatch

Based on the evaluation, IoT commands are sent to the vehicle to enforce speed limits or disable the motor.

Step 6: Command Deduplication

To prevent unnecessary IoT traffic, commands are deduplicated:

  • If the vehicle is already in the same zone with the same speed limit, no command is sent
  • The vehicle's current zone state is tracked:
    • current_speed_limit_zone_id
    • current_speed_limit_kph
    • current_no_go_zone_id
    • engine_disabled_by_zone

Step 7: State Updates

After successful command dispatch, the vehicle record is updated with the new zone state and enforcement timestamp.

Ride-End Validation

When a customer attempts to end a ride, the system validates their location against zone rules.

Validation Flow

  1. Load all zones (not filtered by type)
  2. Get location data:
    • devicePoint: Customer's phone GPS coordinates (from request body)
    • vehiclePoint: Vehicle's last known GPS coordinates (from vehicles table)
  3. Determine validation mode from subaccount settings
  4. Evaluate zone membership for each relevant point
  5. Return result (allow or block with error code)

Validation Rules

For each point being validated:

  • Check if point is inside ANY parking zone (type = 'parking')
  • Check if point is inside ANY no-go zone (type = 'no_go')
  • Check if point is inside ANY no-parking zone (type = 'no_parking')

Result Formula:

valid = inParking && !inNoGo && !inNoParking

Zone Priority

When zones overlap, the following priority applies:

  1. No-go zones - Always block, regardless of other zones
  2. No-parking zones - Block parking even if inside a parking zone
  3. Parking zones - Only valid if not in a no-go or no-parking zone

Parking Zone Validation Modes

Subaccount settings control how parking validation works. Configure this in Settings -> Other -> Parking Zone Validation Mode.

Vehicle Only (Default)

  • Only the vehicle's GPS location is checked
  • Customer's phone location is ignored
  • Falls back to phone location if vehicle location unavailable

Use case: Most reliable for vehicle-centric operations where phone GPS may be inaccurate indoors.

Both

  • Both vehicle AND customer phone must be in a valid parking zone
  • If either is missing, the request is rejected with location_data_missing
  • Most restrictive mode

Use case: High-security environments where you want to ensure the customer is physically with the vehicle.

Hybrid

  • Either vehicle OR customer phone can be in a valid parking zone
  • Most permissive mode
  • Passes if any available point satisfies the requirement

Use case: Areas with poor GPS coverage or when flexibility is preferred.

Zone Event Logging

Every zone entry and exit during active rides is logged for audit and analytics purposes.

Event Data Captured

FieldDescription
ride_uuidThe ride during which the event occurred
zone_idThe zone that was entered/exited
zone_typeType of zone (speed_limit, no_go, parking)
event_typeenter or exit
occurred_atTimestamp of the event
vehicle_latitudeVehicle location at event time
vehicle_longitudeVehicle location at event time
enforcement_actionAction taken (speed_limited, engine_disabled, engine_enabled, speed_restored)
speed_limit_appliedSpeed limit applied (for speed zones)
previous_speed_limitPrevious speed limit (for transitions)
iot_command_sentActual IoT command string sent
iot_command_successWhether the command was acknowledged

Viewing Events

Zone events can be viewed:

  • In the ride detail page (Dashboard -> Rides -> [ride] -> Zones tab)
  • Via database queries for analytics
  • Through the Partner API for external integrations

Customer Notifications

Customers receive push notifications when entering or exiting zones with enforcement.

Speed Zone Notifications

Entering:

Title: "Slow zone activated"
Body: "Your vehicle is now limited to 10 km/h in Downtown Pedestrian Zone."

Exiting:

Title: "Slow zone cleared"
Body: "You have exited Downtown Pedestrian Zone. Your top speed is restored."

No-Go Zone Notifications

Entering:

Title: "No-go zone entered"
Body: "Ride controls paused in Private Property Area. Move to an approved area to continue."

Exiting:

Title: "No-go zone cleared"
Body: "You have left Private Property Area. Ride controls are restored."

Notification Deduplication

To prevent notification spam:

  • A 60-second cooldown applies per zone/event combination
  • Duplicate notifications within this window are suppressed
  • Notifications are logged for audit

GPS Accuracy Considerations

GPS accuracy varies based on environment, affecting zone behavior.

Typical Accuracy Ranges

EnvironmentGPS Accuracy
Open sky3-5 meters
Urban canyon10-30 meters
Near buildings5-15 meters
Indoor/covered20-50+ meters or no signal

Hysteresis Protection

To prevent "flickering" at zone boundaries due to GPS noise, the system implements hysteresis:

No-Go Zone Exit Hysteresis:

  • Vehicle must stream GPS points outside the zone for at least 15 seconds before motor power is restored
  • Prevents false exits from a single GPS reading that drifts outside
  • Tracked via no_go_enforced_at timestamp on the vehicle

GPS Buffer

When designing zones, leave 5-10 meter margins at critical boundaries to account for GPS accuracy variations.

Design Recommendations

  1. Buffer zones: Leave 5-10 meter margins at critical boundaries
  2. Polygon simplicity: Simpler shapes are less affected by GPS jitter
  3. Zone sizing: Very small zones (< 20m radius) may not enforce reliably
  4. Testing: Validate zone boundaries with actual devices in the field

Caching and Performance

Speed Limit Caching

The subaccount's slow_speed_zone_limit_kph setting is cached for 60 seconds:

  • Reduces database queries during high-frequency telemetry processing
  • Cache is per-subaccount
  • Changes to settings take up to 60 seconds to propagate

Vehicle Model Speed Caching

Vehicle model maximum speed is cached for 5 minutes:

  • Used when restoring speed after exiting speed zones
  • Cache is per-vehicle-model-id

Zone Loading

Zones are loaded fresh on each enforcement call (not cached):

  • Ensures zone changes take effect immediately
  • Queries are optimized with indexes on subaccount_id, type, and deleted_at

Performance Tips

  1. Limit zone count: Fewer zones = faster evaluation
  2. Simple polygons: Fewer vertices = faster point-in-polygon checks
  3. Avoid overlapping zones: Reduces the number of evaluations needed

Scenario Playbook

Scenario 1: Ending a Ride with Parking Validation

Setup:

  • Validation mode: both
  • A parking zone covers the street
  • A no-parking zone covers a loading dock within the parking zone

Action: Customer tries to end ride at the loading dock

Result:

  1. Device point: inside parking zone, inside no-parking zone
  2. Vehicle point: inside parking zone, inside no-parking zone
  3. Validation: inParking=true, inNoParking=true
  4. Result: valid = true && !true = false
  5. API returns not_in_parking_zone error
  6. Customer must relocate vehicle

Scenario 2: Speed Zone Transition

Setup:

  • Zone A: speed_limit = 12 km/h
  • Zone B: speed_limit = 8 km/h
  • Subaccount slow_speed_zone_limit_kph = 10 km/h

Action: Vehicle moves from outside zones -> Zone A -> Zone A+B overlap -> Zone B -> outside

Result:

  1. Outside -> Zone A: Speed command sent with limit = min(12, 10) = 10 km/h
  2. Zone A -> A+B: Speed command sent with limit = min(8, 10) = 8 km/h
  3. A+B -> Zone B: No change (still 8 km/h, deduplicated)
  4. Zone B -> Outside: Speed restored to vehicle model max (e.g., 25 km/h)

Scenario 3: Overlapping Speed and No-Go Zones

Setup:

  • Speed zone covering a park (10 km/h)
  • No-go zone covering a construction site within the park

Action: Vehicle enters the construction site

Result:

  1. Speed limit applied: 10 km/h (from speed zone)
  2. Motor disabled (from no-go zone)
  3. Both events logged
  4. Customer receives no-go zone notification
  5. Vehicle must leave the no-go zone AND wait 15 seconds before motor is restored
  6. Speed limit remains at 10 km/h until vehicle also exits the speed zone

Scenario 4: GPS Drift at Zone Boundary

Setup:

  • No-go zone boundary
  • Vehicle is physically at the edge
  • GPS readings fluctuate inside/outside

Action: GPS readings alternate: inside -> outside -> inside -> outside (rapidly)

Result:

  1. First "inside" reading: Motor disabled, timer starts
  2. First "outside" reading: Hysteresis check - timer not expired, motor stays disabled
  3. Second "inside" reading: Still in zone, motor stays disabled
  4. Second "outside" reading: Hysteresis check - if >15s outside, motor restored

The 15-second hysteresis prevents the motor from rapidly toggling on/off due to GPS noise.

Service Area and Out-of-Zone Alerts

Service Area zones define your fleet's operational boundary and trigger alerts when vehicles leave this area.

Configuring Out-of-Zone Alerts

Enable the feature:

  1. Go to Dashboard -> Settings
  2. Navigate to the Other section
  3. Enable Out-of-Zone Alert

Configure email recipients:

  1. Go to Settings -> Alerts
  2. Enable Out-of-Zone Alerts under Operational Alerts
  3. Set the Critical Alerts Email address

Alert Trigger Conditions

An out-of-zone alert is sent when:

  1. A vehicle has an active ride
  2. The vehicle's GPS location is outside all service_area zones for the subaccount
  3. The out_of_zone_alert_enabled setting is true
  4. The out_of_zone_alerts email notification is enabled

Alert Content

The email includes:

  • Vehicle number
  • Last known location
  • Time of detection
  • Link to view the ride in the dashboard

Buffer Zone Configuration

The buffer zone setting adds a GPS accuracy margin around zone boundaries.

Purpose

GPS signals can vary by 5-15 meters depending on environment. The buffer zone setting helps account for this variance by:

  • Adding margin around zone boundaries
  • Reducing false positives at zone edges
  • Improving enforcement reliability

Configuration

Set the buffer zone in Settings -> Other:

  • Default: 10 meters
  • Recommended range: 5-15 meters
GPS EnvironmentRecommended Buffer
Open areas5 meters
Urban/downtown10-15 meters
Near tall buildings15+ meters
Indoor/coveredConsider disabling enforcement

Mobile App Zone Display

Zones are displayed on the customer mobile app map with specific colors and behaviors.

Zone Visibility

Zone TypeVisible on AppColor
ParkingYesGreen (semi-transparent)
No-ParkingYesYellow/Orange (semi-transparent)
No-GoYesRed (semi-transparent)
Speed LimitYesYellow (same as no-parking)
ChargingNo-
BonusNo-
Service AreaNo-

Mobile App Behavior

Zone Loading:

  • Zones are fetched from the mobile API endpoint
  • Cached for 5 minutes to reduce API calls
  • Refreshed when app comes to foreground

Zone Rendering:

  • Displayed as colored polygon overlays on the map
  • Stroke (border) color is more saturated than fill
  • Stroke width: 2 pixels

Invalid Coordinate Handling:

  • The mobile app validates zone coordinates before rendering
  • Checks for valid arrays with at least 3 coordinates
  • Validates each point is a number and finite
  • Silently skips zones with invalid geometry

Zone Analytics and Reporting

Levy Fleets provides comprehensive analytics for zone interactions.

Zone Statistics

Zone statistics provide aggregated data:

MetricDescription
total_entriesNumber of zone entry events
total_exitsNumber of zone exit events
unique_ridesDistinct rides that entered this zone
avg_duration_secondsAverage time spent in zone
total_enforcement_actionsCount of IoT commands sent

Dashboard Analytics

Zone analytics are visible in several dashboard locations:

  1. Ride Detail Page -> Zones Tab

    • Chronological list of zone events
    • Entry/exit times
    • Enforcement actions taken
    • Duration in each zone
  2. Zone Management Page

    • Zone usage counts (when expanded)
    • Last activity timestamp

Exporting Zone Data

Zone event data can be exported via:

  • Direct database queries for advanced analysis
  • Ride CSV exports (include zone events when available)
  • Partner API for integration with external BI tools

What's Next?

Technical Mastery

Understanding how zones work under the hood helps you design more effective geofencing strategies and troubleshoot issues when they arise. Use this knowledge to optimize your zone configuration for your specific operational needs.