Skip to main content

Maps

The Map is Stratumly's 2D spatial visualisation surface. It renders user-defined feature layers on an interactive basemap and is the primary canvas through which every other concept (Forms, Submissions, Dashboards, Analysis) becomes visible.

Core data model

EntityPurpose
feature_classesA user-defined layer definition: name, slug, geometry_type (POINT / LINESTRING / POLYGON), schema_json (column definitions), style_json (MapLibre symbology).
featuresAn individual spatial object: geometry GEOMETRY(GEOMETRYZ, 4326) (3D-capable from day one), properties JSONB validated against the class schema. Versioned, soft-deletable, with nullable links to a twin element, source submission, or source annotation.
feature_editsImmutable audit log of every create / update / delete with before and after JSONB snapshots.
Vector tile cacheMVT tile version counter served via Martin (open-source tile server) for browser rendering.
basemapsCurated catalogue (OpenStreetMap, OS Open, Esri World Imagery, Carto, satellite) with entitlement-based access per tier.

Why it matters

Every GIS conversation starts with "we already have all our asset data in shapefiles / CSVs / a GIS database, can you load that?". Without the Map, Stratumly would compete with point-cloud visualisers, not asset-management platforms. With it, the pitch becomes "bring your existing asset register, we'll put your inspections on top of it."

The vision is one platform, one data model, one bill: the asset register, the form, the inspection survey, the dashboard, the twin, the sensor feed, the compliance report all live in the same workspace and talk to each other natively.

Daily users

  • GIS analyst / Asset manager: /map, layers, spatial analysis, dashboard authoring.
  • Ops supervisor: shared live maps, alert triage on top of layers.
  • Exec / director: embedded dashboard maps, mobile read-only.
  • Field engineer: mobile map for navigation and offline feature edits.

Feature layers (asset registers)

Customers define their own layers (pipes, bridges, signals, poles, flood_zones, easements), any geometry type, any attribute schema.

  • Full CRUD with field-level edit history (who changed what, when, from what to what).
  • Bulk import:
    • CSV (POINT only, expects lon / lat columns).
    • GeoJSON (Feature or FeatureCollection, any geometry).
    • Shapefile (zipped .shp + .dbf + .shx, optional .prj / .cpg; native parser, no external GIS dependency).
    • KML is on our roadmap.
  • Browser-direct upload: files PUT presigned multipart parts straight to object storage via a Web Worker pool; the API server never sees the bytes. Up to 3 files in parallel, each with 4 parallel multipart parts.
  • Resumable uploads: each session and its completed-parts manifest persists to IndexedDB. An interrupted upload (page reload, network drop) shows a one-click "Resume" banner on next app boot that skips the already-completed parts. Pause is soft; cancel is hard.
  • Live data layers: beyond user-defined classes, Stratumly ships system-managed feature classes for live operational data. Today: annotations (defect mirror) and flood-warnings (live EA flood-monitoring poll, refreshed every 15 minutes). See Flood data for the complete flood-zones plus flood-warnings story.
  • Partial-success import: validation failures become error entries; the transaction only rolls back on genuinely unexpected exceptions.
  • SQL + spatial filtering, e.g. material = 'cast_iron' AND ST_DWithin(geom, $zone, 500).
  • Served as MVT vector tiles for efficient web and mobile rendering.
  • Per-field permissions (viewer / editor / admin per feature class).
  • Features can link to twin elements, submissions, and annotations.
  • Soft delete and recover.

2D map view

  • MapLibre GL JS renders any combination of basemaps, feature layers, survey footprints, and twin footprints.
  • Dynamic symbology: classify by attribute (categorical breaks, gradient ramps).
  • Labels driven by attribute columns.
  • Click feature → inspector panel: attributes, history, "open in twin" if linked, "open in survey" if an annotation.

Universal Map sidebar

One panel at top-left holds Layers, Draw, and Basemap stacked as collapsible sections. Collapsible to a thin icon rail when you want more map space.

  • Layers section: system overlays plus user feature classes with checkboxes and colour swatches.
  • Draw section: tool buttons, target-layer dropdown, per-tool hint.
  • Basemap section: basemap list with org-default pin and Set as org default for OWNER / ADMIN.

Drawing tools

Click-to-place point, line, and polygon tools controlled from the Draw section:

  • Pick a tool, pick a target layer (auto-filtered to layers whose geometry_type matches the tool), click to place vertices.
  • Single-click commits a point; double-click commits a line or polygon (≥ 2 / ≥ 3 vertices respectively); Escape cancels in-progress geometry.
  • On commit a property-entry dialog opens, pre-rendering the layer's schema columns with type-aware inputs and required-field validation. Fill in or hit Skip & save to land the feature with empty properties and edit them later via the inspector.
  • The Draw section is hidden on the public-share view; only authenticated org members can draw.

Vertex editing

Click any non-system feature → Edit geometry in the inspector → drag vertex handles to move, click a midpoint marker to insert a new vertex, shift-click a vertex to delete (with a min-vertex floor: line ≥ 2, polygon ≥ 3). Save bar at top-right confirms or discards. Save PATCHes the feature and bumps the per-class tile cache version so Martin re-fetches and the new shape shows up immediately.

Snapping

While drawing or moving a vertex, the cursor magnetises onto the nearest vertex or edge of any visible feature within a 12-pixel tolerance. A yellow indicator (filled circle for vertex snap, hollow ring for edge snap) shows the active target. Vertex snaps win over edge snaps when both are within tolerance. Distance is computed in pixel space; at the zoom levels we draw at, the great-circle correction is below pixel tolerance and projection is much cheaper.

Other view tools

  • Time slider: show layer state as of a specific date.
  • Print composer: export current view to A3 / A4 PDF.
  • Public sharing: share read-only views with expiring tokens.

Basemap registry and swapping

  • STARTER tier sees free basemaps (CARTO Voyager, OSM Standard).
  • PRO tier unlocks satellite imagery (Esri World Imagery).
  • ENTERPRISE accesses premium sources.
  • Seamless swap via MapLibre's setStyle API with layer re-attachment in the style.load event, so user-added layers don't vanish on switch.

Geometry

  • 2D types (POINT, LINESTRING, POLYGON, MULTI*) plus a JSONB attribute table.
  • 3D support (GEOMETRYZ) from day one.
  • SRID 4326 (WGS84) throughout.
  • Polygon holes are dropped on import. Interior-ring support is on our roadmap; we'll ship it when a customer needs it.
  • Forms → Map. Every published form appears in the mobile and web app and can target a feature class for auto-creation.
  • Submissions → Map. A submission's location becomes a pin on the map; if the form has a target feature class, the submission auto-creates a feature in that layer with submission.linked_feature_id pointing back.
  • Dashboards → Map. Map widgets embedded in dashboards consume the same basemap registry and feature layers; cross-widget filters cascade so clicking a chart segment can update the embedded map.
  • Analysis → Map. Spatial-analysis output is always a new feature layer. It appears immediately on the map and is chainable as input to the next operation.
  • Annotations → Map. Survey annotations are written into a system-managed annotations feature class so cross-survey browsing happens on the same 2D map.
  • Twins → Map. Twin elements link back to features so a 2D pin can deep-link to a 3D twin element; work orders generated from twin edits appear as map pins with status colour-coding.