USE CASE
Draw geofences with real data behind them.
Each fence carries an alert threshold, a target group, a notification channel. Standard GeoJSON out — feed your device-location pipeline.
The problem
Geofences are rarely just polygons. A useful fence knows: who it applies to, what event triggers (entry, exit, dwell), what happens when the event fires, when it's active. Most geofencing UIs let you draw a polygon and leave the rest to a separate admin screen that drifts out of sync.
How Element Editor fits
One editor — polygon plus typed form. Output is standard RFC 7946 GeoJSON; schemas travel as metadata.schemas. Hand the output to your geofence evaluator (your backend or a third-party service like Radar or Tile38) without a translation step.
Screenshot: a map showing several geofence polygons. One is selected; the side panel shows fields: fence_name (text), trigger (select: enter/exit/dwell), target_group (text), webhook_url (URL), dwell_seconds (number), active (boolean).
What matters most for this use case
- Schema-backed properties — every fence has the same typed shape.
- Snapping — fences that share borders don't leak.
- Buffer tool — grow a fence by 200 m, or turn a road line into a corridor fence.
- Import and export — round-trip fences between Element and your backend without data loss.
A minimal setup
import { ElementEditor } from '@element-editor/react'
import type { Schema } from '@element-editor/react'
import '@element-editor/react/style.css'
const fenceSchema: Schema = {
id: 'geofence',
name: 'Geofence',
fields: [
{ key: 'fence_name', label: 'Name', type: 'text', required: true },
{ key: 'trigger', label: 'Trigger', type: 'select', required: true,
options: ['enter', 'exit', 'dwell'] },
{ key: 'target_group', label: 'Applies to', type: 'text', required: true },
{ key: 'webhook_url', label: 'Webhook', type: 'url', required: false },
{ key: 'dwell_seconds', label: 'Dwell (s)', type: 'number', required: false, min: 0 },
{ key: 'active', label: 'Active', type: 'boolean', required: false },
],
}
export default function Geofences() {
return (
<div style={{ height: 600 }}>
<ElementEditor
schema={fenceSchema}
tools={['polygon', 'rectangle', 'circle']}
onChange={(data) => syncToBackend(data)}
/>
</div>
)
}Circles are useful for "N-metre radius around a POI" fences. They export as a polygon with a _drawType: 'circle' foreign member, so your backend can treat them as circles if it supports that model, or as regular polygons otherwise. Editing a circle's points turns it into a plain polygon and drops the tag.