Select to view content in your preferred language

Calculate Footprint of Building Scene Layer

564
1
Jump to solution
01-08-2026 06:00 AM
Labels (1)
Bernd_Loigge
Regular Contributor

Hello!

Is it possible to calculate a more accurate footprint of a Scene Layer than the extent given?  It needs to be done on the server side either using ArcGIS API for Python or any Rest Service or GP Tool. Also any ideas of a concept to calculate the footprint and writing our own GP Tool for that would be nice to have, if there is nothing available out-of-the-box.

 

Thank you!

 

BR,

Bernd

1 Solution

Accepted Solutions
Bernd_Loigge
Regular Contributor

If someone is interested — I came up with a method  to derive a precise ground footprint polygon for a Scene Layer / Building Scene Layer entirely on the client, without any server-side queries or a separate footprint feature layer. Afterwards the footprint can be used for automatically clip away the footprint of a BuildingSceneLayer from extruded OSM 3D Tiles or from Google 3D Tiles as IntegratedMesh3DTilesLayer.

The trick: once the SDK has streamed a scene layer into a SceneView, it caches the decoded I3S tile geometry in an IndexedDB called esri-scenelayer-cache (same origin/tab, so window.indexedDB gives you read access). Each cache entry keyed by the tile URL (ending in @ECEF) contains:

  • geometryObbData — the tile's oriented bounding box: center in ECEF metres, half-sizes in a local frame, and a quaternion rotating that frame into ECEF; and
  • transformedGeometry + globalTrafo — the actual decoded mesh vertices plus a 4×4 local→ECEF matrix.

From there the approach is:

  1. Open the cache DB and collect all keys that start with the layer's SceneServer URL (this covers every sublayer — Walls, Floors, …).
  2. Decode each tile mesh, transform vertices to lon/lat, and rasterise the triangles into an occupancy grid (~0.75 m cells).
  3. Morphologically close the grid (dilate/erode) to bridge hairline gaps between tiles, trace the region outlines into rings, simplify, and union into a single WGS84 Polygon that follows the model's real shape.
  4. If no mesh is cached yet (layer still streaming), fall back to unioning the per-tile OBB ground rectangles, and retry once geometry is available.

One important gotcha: the cached ECEF frame is spherical, not WGS84-ellipsoidal — the generator treats geodetic lon/lat as spherical angles. Using an ellipsoidal conversion introduces a noticeable latitude error, so the conversion is deliberately spherical.

I use the resulting polygon to clip the integrated-mesh / 3D-tiles basemap around each loaded building so the model isn't buried. Full standalone module below — no references to my own system, so feel free to adapt it. Caveat: it relies on undocumented SDK internals (the cache DB name, its single object store, and the entry shapes), so it may break between SDK versions (I'm on 4.34).  

View solution in original post

0 Kudos
1 Reply
Bernd_Loigge
Regular Contributor

If someone is interested — I came up with a method  to derive a precise ground footprint polygon for a Scene Layer / Building Scene Layer entirely on the client, without any server-side queries or a separate footprint feature layer. Afterwards the footprint can be used for automatically clip away the footprint of a BuildingSceneLayer from extruded OSM 3D Tiles or from Google 3D Tiles as IntegratedMesh3DTilesLayer.

The trick: once the SDK has streamed a scene layer into a SceneView, it caches the decoded I3S tile geometry in an IndexedDB called esri-scenelayer-cache (same origin/tab, so window.indexedDB gives you read access). Each cache entry keyed by the tile URL (ending in @ECEF) contains:

  • geometryObbData — the tile's oriented bounding box: center in ECEF metres, half-sizes in a local frame, and a quaternion rotating that frame into ECEF; and
  • transformedGeometry + globalTrafo — the actual decoded mesh vertices plus a 4×4 local→ECEF matrix.

From there the approach is:

  1. Open the cache DB and collect all keys that start with the layer's SceneServer URL (this covers every sublayer — Walls, Floors, …).
  2. Decode each tile mesh, transform vertices to lon/lat, and rasterise the triangles into an occupancy grid (~0.75 m cells).
  3. Morphologically close the grid (dilate/erode) to bridge hairline gaps between tiles, trace the region outlines into rings, simplify, and union into a single WGS84 Polygon that follows the model's real shape.
  4. If no mesh is cached yet (layer still streaming), fall back to unioning the per-tile OBB ground rectangles, and retry once geometry is available.

One important gotcha: the cached ECEF frame is spherical, not WGS84-ellipsoidal — the generator treats geodetic lon/lat as spherical angles. Using an ellipsoidal conversion introduces a noticeable latitude error, so the conversion is deliberately spherical.

I use the resulting polygon to clip the integrated-mesh / 3D-tiles basemap around each loaded building so the model isn't buried. Full standalone module below — no references to my own system, so feel free to adapt it. Caveat: it relies on undocumented SDK internals (the cache DB name, its single object store, and the entry shapes), so it may break between SDK versions (I'm on 4.34).  

0 Kudos