★ New in this release · feat/gpkg-3d-editor

3D / Z-Enabled GPKG Editor

A real, end-to-end 3D (Z + M) editing pipeline over GeoPackage — wired into the running app, backed by an ESRI-compatible FeatureServer, and surfaced through the native ArcGIS Editor widget. No stubs, no flat geometry, no elevation lost.

POINT ZPOLYGON ZLINESTRING ZM hasZ · hasMreturnZabsolute-heightOGC 12-128r12
What it does

Edit geometry that actually has height

Most "3D" GIS editors quietly flatten your data. This one doesn't.

  • Stores geometry as standard GPKG blobs — GEOMETRY(Z), POINT Z, POLYGON Z.
  • Round-trips the Z (and M) ordinate exactly: an ESRI 3D point {x,y,z:1500.5} comes back as z = 1500.5.
  • Each vertex renders at its stored elevation above the ellipsoid, matching the world-elevation ground.
  • Schema-driven: hasZ/hasM are read from gpkg_geometry_columns, never hardcoded.
GET .../points/query?returnZ=true
// service advertises the layer's true dimensionality
{
  "hasZ": true,
  "hasM": false,
  "geometryType": "esriGeometryPoint",
  "features": [{
    "geometry": { "x":-74.006, "y":40.712, "z":1500.5 }
  }]
}
Why it matters

Elevation is the whole point

Underground pipes, flight paths, building floors, mine benches, geological strata — none of it lives on a flat plane.

🏙️

3D city models

Capture building heights and multi-level features without losing the Z that defines them.

🚇

Underground utilities

Model pipes and cables at their true depth; navigate below the surface.

✈️

Flight paths & airspace

Use Z + M for altitude and timestamp along 3D trajectories.

⛏️

Mining & geology

Sub-surface excavation and strata modeling with real vertical precision.

🏗️

BIM

Building information modeling where every floor and fixture has a height.

🚪

3D evacuation routes

Plan vertical egress for emergency response scenarios.

The ESRI-compatible REST contract

A FeatureServer your existing tools already speak

All endpoints live under /api/featureserver/{datasetId} and follow the familiar ESRI FeatureServer shape.

Method & endpointReturnsNotes
GET /{ds}Service metadataCapabilities: Query, Create, Update, Delete, Editing, Sync
GET /{ds}/{layer}Layer schemahasZ/hasM from gpkg_geometry_columns
GET /{ds}/{layer}/queryFeaturesHonors returnZ
POST …/addFeaturesAdd resultsFull Z + M ingestion
POST …/updateFeaturesUpdate resultsPer-feature edits
POST …/deleteFeaturesDelete resultsBy OBJECTID
POST …/applyEditsTransactionalAtomic adds + updates + deletes

Capability strings reflect the implemented controller. Spatial filtering uses NetTopologySuite Envelope.Intersects client-side.

EsriGeometry3DConverter.cs
// OGC 12-128r12 standard GPKG blob envelope
// magic "GP" + flags + int32 SRID + ISO WKB
var writer = new WKBWriter {
    Strict = false,        // allow SRID header
    HandleSRID = true,
    HandleOrdinates = XYZM   // preserve Z & M
};
byte[] blob = writer.Write(ntsGeom);
Under the hood

Dependency-light, dependency-correct

A single converter does the heavy lifting — ESRI JSON ↔ NTS Geometry ↔ standard GPKG blob — with no heavyweight ORM.

  • Powered by NetTopologySuite 2.6.0 for 2.5D/3D geometry, WKB, and GPKG blobs.
  • Replaces prior stubs that returned empty blobs and POINT(0 0).
  • Dropped non-functional SpatiaLite ST_Intersects — filtering now via NTS envelopes.
  • Seeds a ready edit3d.gpkg (points = POINT Z, polygons = POLYGON Z) on first run.

Want 3D editing that keeps the Z?

Open the seeded edit3d dataset and start placing features at real elevations in seconds.