Map Overlays

Load GeoJSON, GPX, and georeferenced images as interactive map layers.

7 min read

Overlays extend the map with external spatial data — mission area boundaries from a planning tool, route files from a GPS device, aerial imagery captured by a drone, or any other georeferenced content. Each overlay is an independent layer with its own style settings, and all overlay state is synchronized across connected clients in real time.

Vector Overlays

Any GeoJSON or GPX file that has been uploaded to the File Sharing system can be activated as a vector map overlay. The overlay records a reference to the source file rather than copying the geometry — updating the file and refreshing the overlay will reflect the new content.

POST /api/overlays operator / admin
Create a new overlay referencing an uploaded file.
Body: { "file_id": "uuid", "name": "Mission Boundary", "overlay_type": "vector" }

GPX Conversion

GPX files are converted to GeoJSON server-side when the overlay is activated. Track segments become LineString features, waypoints become Point features, and routes become LineString features. The converted GeoJSON is what the client receives — the original GPX is retained in file storage as the source of truth.

Rendering

Vector overlays are rendered using a MapLibre GeoJSON source. The server parses the geometry and computes a bounding box stored in the overlay record. On the client, each vector overlay gets up to five rendering layers depending on the geometry types present in the data:

  • Fill layer — for Polygon and MultiPolygon features
  • Fill-outline layer — strokes the polygon boundary at a fixed 1px width
  • Line layer — for LineString and MultiLineString features
  • Circle layer — for Point and MultiPoint features
  • Label layer — text symbol from the feature's name property if present

Image Overlays

Raster images — photographs, drone captures, scanned maps — can be placed directly on the map as georeferenced image overlays. The image is stretched to fit four corner coordinates that the operator specifies during placement.

POST /api/overlays operator / admin
Create an image overlay. Set overlay_type to "image" and supply the four corner coordinates.
Body: { "file_id": "uuid", "name": "Drone Survey", "overlay_type": "image", "corners": [[minLon,maxLat],[maxLon,maxLat],[maxLon,minLat],[minLon,minLat]] }

Click-to-Place Workflow

The placement UI walks the operator through a two-step click workflow on the map:

  1. Click the first corner. The cursor becomes a crosshair. Click the map at the top-left corner of the image's intended position.
  2. Click the opposite corner. Click at the bottom-right corner. The server computes the other two corners from these two points and creates a rectangular placement that can be adjusted afterward.

A preview of the placed image appears immediately using the provisional coordinates before the final request is submitted.

Manual Coordinate Entry

For precise placement, the panel offers a manual coordinate entry form where all four corner coordinates can be entered as decimal degrees. This is suitable when the exact bounds of the coverage area are known from metadata — for example, from a drone flight plan export or GeoTIFF world file.

MapLibre Rendering

Image overlays are rendered using MapLibre's native image source type. The image binary is fetched from the file download endpoint using an authenticated request, converted to a blob URL, and passed to the source. This ensures the image data never leaves the local network unprotected even when fetched by the browser. The layer type is raster, which supports hardware-accelerated rendering and opacity control.

3D terrain and hillshade are automatically disabled when one or more image overlays are active. MapLibre does not support mixing raster layers with the terrain elevation model. Terrain resumes automatically when all image overlays are hidden or removed.

Style Controls

Each overlay has independent style properties that persist in the database and are shared with all clients. Changes take effect immediately on all connected clients without a page reload.

PATCH /api/overlays/:id operator / admin
Update overlay style properties or metadata.
Patchable fields: name, color, opacity, line_width, corners (image overlays)
Property Type Applies To Default
color CSS hex string Vector overlays #3B82F6
opacity 0.0 – 1.0 Both types 0.7
line_width Pixels (integer) Vector overlays 2

Style updates are persisted to the overlays table and broadcast via the overlay:updated Socket.IO event. Clients reapply the updated paint properties to the relevant MapLibre layers without re-fetching the geometry.

Interaction

Feature Info Popups

Clicking on any visible vector overlay feature opens a popup anchored to the click location. The popup displays all GeoJSON properties attached to the clicked feature in a key-value table. Properties with null values or internal MapLibre layer identifiers are excluded from the display.

Zoom to Extent

Each overlay entry in the management panel has a zoom-to-extent button. Clicking it calls MapLibre's fitBounds using the overlay's stored bbox with a small padding applied. This is useful for immediately locating an overlay that falls outside the current map view.

Local Visibility Toggle

Each overlay can be toggled visible or hidden using the eye icon in the panel. This is a client-side preference stored in component state — it does not modify the overlay record on the server and does not affect other users. Toggling visibility calls MapLibre's setLayoutProperty with visibility: 'visible' or 'none' rather than adding or removing the layer, which is instantaneous.

Local visibility is reset on page reload. To permanently remove an overlay from everyone's map, delete it via DELETE /api/overlays/:id. The underlying file in file storage is not deleted — only the overlay record and its layers.

Real-Time Sync

All overlay CRUD operations emit Socket.IO events to every connected client. This ensures that when one operator creates or modifies an overlay, all other clients immediately add or update the corresponding map layers.

Event Direction Payload
overlay:created Server → all clients Full overlay record including bbox, overlay_type, and style properties
overlay:updated Server → all clients Full updated overlay record
overlay:removed Server → all clients { id } — the removed overlay's identifier

Receiving clients respond to overlay:created by fetching the geometry from the file content endpoint and adding the new source and layers to the map. overlay:updated triggers a paint property update. overlay:removed removes all associated layers and the source from the map.