OsmBuildingsLayer

open class OsmBuildingsLayer(var source: TiledFeatureSource = OverpassBuildingsSource(), val tileZoom: Int = 15, val tileRadius: Int = 4, val maxLoadedTiles: Int = 256, val maxConcurrentFetches: Int = 2, val useOsmColors: Boolean = true, val useBatchedRendering: Boolean = true, displayName: String? = "OSM Buildings") : AbstractLayer, VectorLayer

Renders OpenStreetMap-derived schematic 3D buildings. Footprints + height tags are fetched on demand via a TiledFeatureSource (defaults to OverpassBuildingsSource) and cached per slippy-map tile.

Each cached tile is either:

  • a single OsmBuildingsTile (default, useBatchedRendering = true) — one VBO + one EBO for every building in the tile. Required at dense urban density: per-building polygons OOM the Adreno KGSL shared-memory pool by buffer count, not byte volume.

  • a List<Polygon>, one extruded Polygon per OsmBuilding — the legacy path. Needed by subclasses overriding toPolygon / toPolygons for per-building customisation the batched mesh doesn't carry; pass useBatchedRendering = false.

useOsmColors works in both modes — the batched path groups triangles by colour within the tile's element array and issues one sub-draw per colour.

val buildings = OsmBuildingsLayer()
worldWindow.engine.layers.addLayer(buildings)
// ...later:
buildings.close()

Tile selection uses a centre-radius window: at each frame the (2×tileRadius+1)² tiles around the camera's lookAt point (falling back to the camera lat/lon) are scheduled for fetch. At zoom 15 a radius of 4 covers ~10 km square. Fetching is gated by maxActiveAltitude (30 km by default), above which the layer is a no-op.

Style every building uniformly via attributes, or enable useOsmColors for per-tag wall/roof colouring. Always call close to cancel in-flight fetches.

Constructors

Link copied to clipboard
constructor(source: TiledFeatureSource = OverpassBuildingsSource(), tileZoom: Int = 15, tileRadius: Int = 4, maxLoadedTiles: Int = 256, maxConcurrentFetches: Int = 2, useOsmColors: Boolean = true, useBatchedRendering: Boolean = true, displayName: String? = "OSM Buildings")

Types

Link copied to clipboard
@Serializable
data class CacheConfig(val useOsmColors: Boolean = true, val useBatchedRendering: Boolean = true, val tileZoom: Int = 15, val tileRadius: Int = 4, val maxLoadedTiles: Int = 256)

The render-config subset persisted into WebServiceInfo.metadata on cache attach and replayed on reopen, so a cached layer comes back with its original flags instead of bare constructor defaults (the white-buildings-on-reopen bug when useOsmColors was set). Only the val constructor params are carried; attributes / shadowMode are not. Defaults mirror the constructor so an absent field decodes to the same value.

Link copied to clipboard
object Companion
Link copied to clipboard
data class TileKey(val z: Int, val x: Int, val y: Int)

Slippy-map tile coordinate triple used as the tiles LRU key.

Properties

Link copied to clipboard

Shape attributes applied to every building polygon. Mutating between frames is safe.

Link copied to clipboard
Link copied to clipboard
open override var displayName: String?
Link copied to clipboard
open override var isDynamic: Boolean
Link copied to clipboard
open override var isEnabled: Boolean
Link copied to clipboard
open override var isPickEnabled: Boolean
Link copied to clipboard
open override var maxActiveAltitude: Double
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
open override var minActiveAltitude: Double
Link copied to clipboard
open override var opacity: Float
Link copied to clipboard
open override val sector: Sector

Vector content bounding sector — real data availability can be smaller than the tile grid. Full sphere by default; tiled layers skip tiles outside it. Cache reopen narrows it from the persisted content bbox; bulk download widens and persists it. Mirrors earth.worldwind.globe.elevation.coverage.ElevationCoverage.sector.

Link copied to clipboard

Layer-wide shadow participation. Default ShadowMode.ENABLED makes every building both cast shadows onto the terrain and receive cascade shadows. Applies in both batched and legacy rendering paths; in the legacy path it overrides any per-Polygon ShapeAttributes.shadowMode so layer-level intent wins.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

When true (default), every building in a tile is packed into one OsmBuildingsTile mesh (~500× fewer GL buffers per tile). Set false to keep the legacy "one Polygon per building" path — required when overriding toPolygon / toPolygons for per-building customisation the batched path doesn't carry (e.g. per-building geometry variation).

Link copied to clipboard

When true, walls are coloured via OsmColors.resolve on each OsmBuilding's tags (falling back to attributes's interior colour); top caps use roof:colour (falling back to the wall colour). On by default; set false for uniform-gray output. Works in both rendering modes.

Functions

Link copied to clipboard
open override fun clone(): OsmBuildingsLayer

Makes a fresh copy carrying this layer's configuration + appearance; caches and fetch scope are not shared.

Link copied to clipboard
open fun close()

Cancels in-flight fetches and frees the cache. Idempotent. The layer cannot be reused after close.

Link copied to clipboard
open override fun getUserProperty(key: Any): Any?
Link copied to clipboard
open override fun hasUserProperty(key: Any): Boolean
Link copied to clipboard
Link copied to clipboard
fun OsmBuildingsLayer.launchBulkRetrieval(sector: Sector, scope: CoroutineScope = GlobalScope, maxRetries: Int = 3, retryTimeoutShort: Duration = 5.seconds, retryTimeoutLong: Duration = 15.seconds, overrideCache: Boolean = false, onProgress: (downloaded: Long, skipped: Long, total: Long) -> Unit? = null): Job

Download every OSM-Buildings feature tile intersecting sector into the layer's feature store — the "save a region for offline use" flow.

Link copied to clipboard
open override fun putUserProperty(key: Any, value: Any): Any?
Link copied to clipboard
open override fun removeUserProperty(key: Any): Any?
Link copied to clipboard
open override fun render(rc: RenderContext)
Link copied to clipboard
fun VectorLayer.setOfflineOnly(offlineOnly: Boolean = true)

See setOfflineOnly on TiledImageLayer. Dispatches by VectorLayer subtype to reach the right source field. No-op for unknown subtypes.

Link copied to clipboard

Total number of OSM-Buildings feature tiles launchBulkRetrieval would fetch for sector — the slippy analog of LevelSet.tileCount, for sizing a download before committing to it. Counts a single slippy zoom (OsmBuildingsLayer.tileZoom), the only zoom the renderer reads.