EncodedGridVectorTileSource

class EncodedGridVectorTileSource(val id: String, encodedSource: XweatherEncodedTileSource, gridSpacing: Double, iconEncodedColorScale: ColorScaleOptions? = null, iconEncodedScalarMax: Double? = null, val timelineMeldInvalidatesMapboxTiles: Boolean = true, instancedQuadMonochromeWhite: Boolean = false) : VectorTileSource

Sidecar vector source for gridded/symbol layers backed by XweatherEncodedTileSource.

Mapbox requests geometry per tile via requestTile; features are placed on a global Web Mercator world-pixel grid (512×2^zoom) for even screen spacing. Wind uses G/B u/v (atan2(u,-v); sampleFieldsFromEncodedRgb). Maritime *_dir.fill (instancedQuadMonochromeWhite) uses blue-only scalar degrees like JS EXPRESSION_ANGLE (norm * 360 - 180, wrapped to 0–360°).

Constructors

Link copied to clipboard
constructor(id: String, encodedSource: XweatherEncodedTileSource, gridSpacing: Double, iconEncodedColorScale: ColorScaleOptions? = null, iconEncodedScalarMax: Double? = null, timelineMeldInvalidatesMapboxTiles: Boolean = true, instancedQuadMonochromeWhite: Boolean = false)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
var bounds: LatLonBounds?
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
open override val eventDispatcher: EventDispatcher
Link copied to clipboard
var glStencilMaskTileListener: (coord: TileCoord, coordHash: String, features: List<Feature>) -> Unit?

When set (GL stencil mask mode), invoked on the tile decode thread after each successful MVT parse with the same TileCoord / coord-hash key used by encoded raster meshes.

Link copied to clipboard
open override val id: String

Same id as the registered style source / descriptor.

Link copied to clipboard
open val isEncoded: Boolean
Link copied to clipboard
Link copied to clipboard
open override var isReady: Boolean

true when metadata (and any bootstrap work) is available so layers can request tiles safely.

Link copied to clipboard
Link copied to clipboard

True when metadata exposes valid times and tiles should cache multiple intervals per z/x/y. Excludes isAdminSource — static OSM/basemap products (open-street-map*) reuse the same "layers" + "validTimes" JSON shape as interval weather vectors (hail-threats, road-wx, lightning-threat-zones) but are not per-interval-tiled. Treating those basemaps as time-series pulls place labels / roads into the playback gate; their tiles are never cached under a playback interval, so resolveVectorTileData fails forever and stalls every layer via the shared readiness map. Weather products that share this metadata shape must remain time-series so timeline play can swap /vector/{code}/{time}/… tiles.

Link copied to clipboard
open override val kind: DataSourceKind

High-level source family (raster, encoded, vector, …).

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

com.xweather.mapsgl.map.MapController.mapSessionId that owns in-flight / ready tile bookkeeping.

Link copied to clipboard

MVT layer name values from product metadata (e.g. fires-obs for fires observation points).

Link copied to clipboard

Retain raw MVT bytes in native memory for time-series tiles (rules 6 & 7).

Link copied to clipboard
open override var tileCache: TileCache<DataType>
Link copied to clipboard
open var tileManager: TileRequestManager<VectorData>
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Mapbox symbol overlays need timeline meld invalidation so custom-geometry tiles refetch blended icons. Instanced GL wind barbs meld on the GPU (com.xweather.mapsgl.anim.Timeline.dataMeld) and skip this work.

Link copied to clipboard
open override var timeRange: ClosedRange<Date>?

Optional interval filter for time-series products; drives tile requests with timeline state.

Link copied to clipboard

Alias for DataSource.kind (matches JS naming type).

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

Valid times from product metadata; drives interval time-series tile caching.

Functions

Link copied to clipboard
fun abortTile(x: Int, y: Int, z: Int)
Link copied to clipboard
open override fun addConsumer(consumer: DataSourceConsumer)

Register a layer that should receive updates when this source loads or changes.

Link copied to clipboard
fun addCustomStencilTileListener(listenerId: String, listener: (coord: TileCoord, coordHash: String, features: List<Feature>) -> Unit): () -> Unit

Invoked on the tile decode thread after each successful parse, after glStencilMaskTileListener.

Link copied to clipboard
fun addStencilParseLayerDependency(sourceLayerTag: String): () -> Unit

Ensures parseVectorTile includes sourceLayerTag in decoded MVT layers (refcounted).

Link copied to clipboard
fun addToAnimationQueue(inputString: String)
Link copied to clipboard
fun adjustDateBySeconds(dateString: String, offsetSeconds: Long): String?

Used by prepareTileRequest() to increment or decremnet the time and reformate it for sources with time offets

Link copied to clipboard
fun applyIconColorOptions(scale: ColorScaleOptions?, encodedScalarMax: Double?)

Rebuilds the CPU palette used for instanced wind barb/arrow RGB when SamplePaint.colorScale or SamplePaint.encodedScalarNormMax changes. Safe to call when reusing a cached gridVector sidecar source.

Link copied to clipboard
suspend fun buildInstancedWindBufferDualPhase(coords: List<TileCoord>, mapZoom: Double, visibleGeoBounds: VisibleGeoBounds?, maxInstances: Int, viewportGridMarginWorldPx: Double = 0.0, viewportExtraEastFraction: Double = 0.0, phaseA: Int = Timeline.currentPhaseA, phaseB: Int = Timeline.currentPhaseB): Pair<FloatArray, Int>

Packed instanced wind barbs: endpoint phase A and B only (no Timeline.dataMeld in sampling). Matches encoded raster layers: the GPU applies dataMeld each frame so timeline crossfade stays smooth without rebuilding this buffer at playback frame rate.

Link copied to clipboard

Cached tile coords at zoom z that already hold parsed VectorData. Used when viewport enumeration yields no coords but MVTs have loaded (e.g. alert point legends).

Link copied to clipboard

Cancels every queued/active time-series download (e.g. before playback gate at z−1).

Link copied to clipboard
fun cancelInFlightTilesOutside(keepSpatialHashes: Set<String>)

Cancels in-flight MVT downloads outside keepSpatialHashes (rule 5).

Link copied to clipboard
fun clearRawPathEligibility(consumerLayerId: String)

Clears every raw-path declaration for consumerLayerId (e.g. on layer removal).

Link copied to clipboard
open fun contains(coord: TileCoord): Boolean
Link copied to clipboard
Link copied to clipboard
fun debugIntervalByteSize(coord: TileCoord, intervalMs: Long): Int?

Demo/debug-only: raw MVT byte size retained for one intervalMs of the spatial tile at coord. Time-series sources retain raw bytes per interval in mvtNativeCache (see storeNativeMvtBytes), so this is both the download and stored size for that interval. Null when this source isn't time-series or that interval's bytes were trimmed/never fetched.

Link copied to clipboard

Demo/debug-only: epoch-ms time intervals with parsed data currently cached for the spatial tile at coord, sorted ascending. Null when this source isn't a time-series source (there's only ever one interval per tile); empty when the tile hasn't been fetched yet.

Link copied to clipboard

Demo/debug-only: last-fetch download size and currently-retained raw size for coord, in bytes.

Link copied to clipboard

Demo/debug-only: where coord currently sits in the fetch/parse pipeline. DebugTileStage.DOWNLOADED_NOT_PROCESSED is normally short-lived (parsing happens inline right after a successful fetch) but can persist under load, e.g. while multiple tiles wait on vectorParseSemaphore for a free decode slot.

Link copied to clipboard
fun declareNeededPropertyKeys(consumerLayerId: String, keys: Set<String>?)

See neededPropertyKeysByConsumerLayerId. Pass null to clear a previously-declared restriction.

Link copied to clipboard
suspend fun ensureTimeSeriesParsedAt(z: Int, x: Int, y: Int, intervalMs: Long): VectorData?
Link copied to clipboard
open suspend override fun fetchMetadata(startDate: Date?, endDate: Date?): Result<Unit>

Returns the metadata for the source, which can be loaded from a remote source.

Link copied to clipboard
fun findCachedVectorTileForNominalZxy(z: Int, x: Int, y: Int, allowStaleTimeFallback: Boolean = true): Tile<VectorData>?

Finds a cached vector tile by nominal z/x/y. Tries the validTime key first, then scans the cache so draws still resolve tiles after subtle key drift (e.g. time format rounding).

Link copied to clipboard
open override fun getMetadataURL(): URL?
Link copied to clipboard
open override fun getTileData(coord: TileCoord): Any?
Link copied to clipboard
fun hasNativeMvtBytesAt(z: Int, x: Int, y: Int, intervalMs: Long): Boolean
Link copied to clipboard
fun hasTimeSeriesDataLoadedAt(z: Int, x: Int, y: Int, intervalMs: Long): Boolean

True when the spatial time-series tile already holds parsed data for intervalMs.

Link copied to clipboard
fun hasTimeSeriesIntervalAt(z: Int, x: Int, y: Int, intervalMs: Long): Boolean

True when data is cached or a download is already in flight (dedupe prefetch).

Link copied to clipboard
fun hasUnparsedNativeMvtAt(z: Int, x: Int, y: Int, intervalMs: Long): Boolean

Retained MVT bytes exist but VectorTimeSeriesData has no parsed snapshot yet.

Link copied to clipboard

Count of (spatial tile, interval) MVT HTTP requests actively downloading.

Link copied to clipboard
fun <DataType : TileData> TileSource<DataType>.init(id: String, authenticator: Authenticator<MediaSession.Token>?)
Link copied to clipboard
fun inspectorSampleMaritimeDirDeg(lon: Double, latDeg: Double, mapZoom: Double): Float?

Data inspector for maritime *_dir.fill: bilinear sample at lon/latDeg using the same placement zoom as buildInstancedWindBufferDualPhase (stablePlacementZoomInt\(mapZoom\)), then vector-blend phases like the GPU. Nearest-neighbor tile bytes in EncodedTileLayer do not match instanced sampling.

Link copied to clipboard
fun intervalToIsoPathTime(intervalTime: String): String

Plain ISO-8601 for URL path {time} segments (encoded tile GET). Cache keys and POST validTimes still use bracketed ["…"] strings.

Link copied to clipboard
fun intervalToURLTime(intervalTime: String): String

convert from \"2025-04-22T03:49:31Z\" to 20250422030000

Link copied to clipboard
open override fun invalidate()
Link copied to clipboard

Timeline-only invalidation: keep cached placement geometry, refresh only sampled icon properties.

Link copied to clipboard

True while any time-series tile HTTP requests are still in flight.

Link copied to clipboard
fun isRawPathEligible(consumerLayerId: String): Boolean

True when consumerLayerId currently declares itself raw-path eligible for any tile layer.

Link copied to clipboard
fun isTimeSeriesIntervalDownloading(z: Int, x: Int, y: Int, intervalMs: Long): Boolean

True when a download is in flight for (coord, interval) but parsed data is not cached yet.

Link copied to clipboard
fun makeTileURL(coord: TileCoord, variables: Map<String, Any>?): URL
Link copied to clipboard
suspend fun mergeFeaturesForTiles(coords: List<TileCoord>, mapZoom: Double, visibleGeoBounds: VisibleGeoBounds?): List<Pair<TileCoord, Feature>>

Same feature generation as the Mapbox sidecar path, merged for OpenGL instanced drawing (no Mapbox vector layer).

Link copied to clipboard
Link copied to clipboard
fun onTileError(tile: TileType, error: Error)
Link copied to clipboard
suspend fun parseTile(tile: TileType, data: ByteArray, headers: <Error class: unknown class><Any, Any>?): Bitmap
Link copied to clipboard
fun pinNativeMvtBytesAt(z: Int, x: Int, y: Int, intervalMs: Long)

Pins z/x/y's MVT bytes for intervalMs against native-cache eviction — see pinFillTriangulationNative for the eviction-priority semantics this declares.

Link copied to clipboard
inline fun <EventType : Event> EventSource.publisher(eventType: Class<EventType>): Flow<EventType>
Link copied to clipboard
open override fun removeConsumer(layerId: String)

Unregister a layer previously added with addConsumer.

Link copied to clipboard
Link copied to clipboard
open suspend override fun requestTile(x: Int, y: Int, z: Int, mapZoomForDensity: Double?, visibleGeoBounds: VisibleGeoBounds?, intervalTime: Date?, countsForGlFillLoadIndicator: Boolean): VectorData?
Link copied to clipboard
open suspend override fun requestTiles(coord: TileCoord, options: TileRequestOptions, currentDate: String, fromAnimation: Boolean, intervals: List<String>?, trackDownloadProgress: Boolean): Any
Link copied to clipboard
fun setBatchInvalidateFunction(batchInvalidateFunction: (List<Triple<Int, Int, Int>>) -> Unit?)
Link copied to clipboard
fun setInvalidateFunction(invalidateFunction: (Int, Int, Int) -> Unit?)
Link copied to clipboard
fun setRawPathEligible(consumerLayerId: String, tileLayerName: String?, eligible: Boolean)

Declares whether consumerLayerId currently allows the raw fast path for tileLayerName. null means the consumer has no sourceLayer restriction (matches whichever tile-layer it ends up needing) — stored under a wildcard key so rawPathEligibleForLayer can still resolve it against any concrete tile-layer name.

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

Epoch ms key used for MVT fetch and VectorTimeSeriesData lookup.

Link copied to clipboard
inline suspend fun <EventType : Event> EventSource.subscribe(eventType: Class<EventType>, crossinline handler: (EventType) -> Unit)
Link copied to clipboard
fun syncGridSpacingFromPaint(authoredSpacing: Double, displayDensity: Float)

JS GridPaint.spacing is in logical px; instanced gridded placement uses authored × density × 0.5 (same density convention as com.xweather.mapsgl.renderers.GridLayerRenderer icon sizing). Safe when reusing a cached sidecar: bumps spacing and invalidates placement caches when the effective value changes.

Link copied to clipboard
Link copied to clipboard
fun trimParsedHeapForTimeline(keepSpatialHashes: Set<String>? = null)
Link copied to clipboard
fun trimParsedTimeSeriesIntervalsOutside(spatialCoord: TileCoord, keepSnappedMs: Set<Long>)
Link copied to clipboard
fun unpinNativeMvtBytesAt(z: Int, x: Int, y: Int, intervalMs: Long)