Table of Contents

Class TileSource

A provider-agnostic description of where raster tiles come from: the URL template, the tile size, the provider's zoom limits and the mandatory attribution.

public sealed class TileSource : ITileDataSource
Inheritance
object
TileSource
Implements

Remarks

LansMap defaults to OpenStreetMap for evaluation. You supply the provider for production and, where one is needed, the API key. The template understands {z}, {x} and {y}, which are required, plus optional {key} for an API key and {s} for a subdomain rotation.

Immutable and validated at construction, so an unusable source cannot exist: a template missing a required placeholder, a {key} with no key, a {s} with no subdomains or a missing attribution all throw here rather than failing later as a silently blank map.

Attribution is not optional. Every provider's terms require credit, and the overlay renders Attribution verbatim.

Constructors

TileSource(string, string, int, string, int, string, string[], int, int, string, TileTextureFormat, int, int)

Creates a validated tile source.

public TileSource(string name, string urlTemplate, int tileSizePx, string attribution, int maxConcurrentRequests = 14, string apiKey = null, string[] subdomains = null, int minZoom = 0, int maxNativeZoom = 22, string attributionUrl = null, TileTextureFormat textureFormat = TileTextureFormat.RGBA32, int pixelRatio = 1, int prefetchReserveSlots = 2)

Parameters

name string

Provider name for display. Required.

urlTemplate string

URL template. Must contain {z}, {x} and {y}.

tileSizePx int

Zoom scheme as a tile edge length in px; 256 or 512. Not the image size - see pixelRatio.

attribution string

Credit text. Required.

maxConcurrentRequests int

Requests in flight at once, 1 to 32. Omit it for DefaultMaxConcurrentRequests; pass a value only where the provider's terms or your contract with them call for one.

apiKey string

Key substituted for {key}; may be null or omitted when the template has no {key}.

subdomains string[]

Hostnames rotated through {s}; may be null when the template has no {s}.

minZoom int

Shallowest level served, 0 to 24.

maxNativeZoom int

Deepest level served, from minZoom to 24.

attributionUrl string

Link target for the credit; null for no link.

textureFormat TileTextureFormat

GPU residency format for this source's tiles. Omit for RGBA32, the default; see TextureFormat's remarks for what RGB565 costs and requires.

pixelRatio int

Texels per scheme pixel, 1 or 2. Omit for 1; pass 2 for a high-DPI endpoint that serves the same {z}/{x}/{y} at double density.

prefetchReserveSlots int

Exceptions

ArgumentException

The name, template or attribution is missing; the template lacks a required placeholder; it uses {key} or {s} without the matching value; the tile size is not 256 or 512; the pixel ratio is not 1 or 2; or a zoom or concurrency value is out of range.

Fields

DefaultMaxConcurrentRequests

Concurrency used when a source does not name one: 14.

public const int DefaultMaxConcurrentRequests = 14

Field Value

int

Remarks

This is the VISIBLE-tile budget only. PrefetchReserveSlots (default 2) is additive on top of it for a normal source (see that member's remarks and TileStreamer.ResolveFetcherSlotCount), so the real aggregate simultaneous-connection ceiling for the shipped defaults is 14 + 2 = 16.

DefaultPrefetchReserveSlots

Default reserve for PrefetchReserveSlots: 2.

public const int DefaultPrefetchReserveSlots = 2

Field Value

int

Remarks

A configurable starting point for how many transport slots the idle-time background trickle (parent-tile prefetch plus the world-floor trickle) gets, held structurally apart from MaxConcurrentRequests so on-screen tile fetches never lose headroom to it - see PrefetchReserveSlots.

Properties

ApiKey

API key substituted for {key}. Empty string, never null, when the provider needs no key.

public string ApiKey { get; }

Property Value

string

Attribution

Credit text, rendered verbatim by the attribution overlay. Never empty; the constructor rejects a source without it.

public string Attribution { get; }

Property Value

string

AttributionUrl

Where the attribution text links to. Empty string, never null, means the credit is not a link.

public string AttributionUrl { get; }

Property Value

string

Remarks

The OSM Foundation's attribution guidelines require a route to the source and its license, so a link is expected for OSM-derived tiles even though this type does not enforce one.

CacheTag

Provider identity for the disk cache: an FNV-1a 64 hash of a "raster:"-tagged URL template.

public ulong CacheTag { get; }

Property Value

ulong

Remarks

Hashed with {key} still unexpanded, which is the point. Switching provider or map style changes the template and so invalidates the cache, while rotating an API key leaves the template identical and keeps every cached tile. A provider switch can therefore never serve tiles cached from a different provider.

Also folds in TextureFormat, because switching format must never serve a format-A blob into a format-B array; only a non-default format adds a suffix, so two default-format sources on the identical template still tag identically.

The leading "raster:" tag means this type's tag can never equal a VectorTileSource's tag (which hashes its own "vector:"-tagged template) even when both are built from the identical template string, so the two source kinds can never collide in the shared disk cache.

ConcurrencyLoweredForPoliteness

Whether MaxConcurrentRequests was deliberately set below DefaultMaxConcurrentRequests to respect a provider's terms.

public bool ConcurrencyLoweredForPoliteness { get; }

Property Value

bool

MaxConcurrentRequests

How many requests to keep in flight against this provider at once, 1 to 32. Set it from the provider's published policy, not from what the network can bear.

public int MaxConcurrentRequests { get; }

Property Value

int

Remarks

Defaults to DefaultMaxConcurrentRequests. Override it when a provider's terms restrict request volume, or when a contract with the provider permits more; that override is a supported path, not a workaround.

MaxNativeZoom

Deepest zoom level the provider actually serves. Zooming past it stretches the deepest real tile rather than requesting one that does not exist. This is commonly called the maximum native zoom.

public int MaxNativeZoom { get; }

Property Value

int

Remarks

Setting this correctly matters more than it looks. Requesting past a provider's real maximum returns 404, which burns the tile's retry budget and leaves it dead for the rest of the session: an independent and complete cause of permanently black tiles.

MinZoom

Shallowest zoom level the provider serves, 0 for a world-wide source.

public int MinZoom { get; }

Property Value

int

Name

Human-readable provider name, used in the inspector and in logs. Never empty.

public string Name { get; }

Property Value

string

PixelRatio

Texels the provider returns per scheme pixel: 1 for standard tiles, 2 for the high-DPI endpoint (commonly an @2x template).

public int PixelRatio { get; }

Property Value

int

Remarks

Density only. A ratio-2 tile covers exactly the ground its ratio-1 sibling at the same {z}/{x}/{y} covers, so raising it must never move the map; it makes the same ground sharper.

PrefetchReserveSlots

How many transport slots the idle-time background trickle (parent-tile prefetch, the world-floor trickle) may use at once, 0 to 16.

public int PrefetchReserveSlots { get; }

Property Value

int

Remarks

This is a separate budget from MaxConcurrentRequests, not a sub-allocation of it: a fetcher is normally built with MaxConcurrentRequests + PrefetchReserveSlots slots total (see TileStreamer.ResolveFetcherSlotCount), so raising this number costs nothing against the visible-tile budget. The real tradeoff it carries is aggregate: total simultaneous connections to the provider becomes MaxConcurrentRequests + PrefetchReserveSlots, so raising both without checking the sum can exceed what "polite and fast" intended.

Never additive for a source whose concurrency was already lowered for provider politeness (ConcurrencyLoweredForPoliteness) - growing the wire budget on top of a ToS-cited lower cap would raise real connections above the number that cap exists to respect, so for those sources the reserve is instead carved OUT of the existing capped budget (never adds to it).

Subdomains

Subdomains rotated through {s}, for HTTP/1.1 providers that shard across hostnames. Empty array, never null, when the template uses no {s}.

public string[] Subdomains { get; }

Property Value

string[]

TextureFormat

The GPU residency format this source's tiles should be uploaded as. Defaults to RGBA32, so every existing construction and preset keeps today's behaviour.

public TileTextureFormat TextureFormat { get; }

Property Value

TileTextureFormat

Remarks

Folded into CacheTag: see that member's remarks - flipping this on an existing source abandons its whole disk cache and re-downloads every tile, which is not free.

RGB565 is opt-in and carries a real trade-off: it halves VRAM per tile array, drops alpha entirely (map tiles are opaque so this costs nothing today), and quantizes each 8-bit color channel down to 5 or 6 bits. That quantization bands smooth gradients - ocean fills, hillshade, satellite imagery are exactly the content where a 16-bit sky-to-ground gradient shows visible steps that RGBA32 does not. It is also not guaranteed on every device: TileBatchRenderer probes SystemInfo.IsFormatSupported once at construction and falls back to RGBA32 loudly (one Debug.LogError, never silent) on a device/graphics API that cannot sample it.

TexturePx

Decoded image edge length in px: TileSizePx times PixelRatio. What the GPU array allocates and what a decoded tile is validated against.

public int TexturePx { get; }

Property Value

int

TileSizePx

The zoom scheme this provider's {z} belongs to, as a tile edge length in px: 256 or 512. A 512 source covers the same ground at z that a 256 source covers at z+1.

public int TileSizePx { get; }

Property Value

int

Remarks

This is the scheme, not the image size. It is the only tile number the projection may use: world size in px is this times 2 to the power of the zoom, so it decides where every tile lands on screen. A high-DPI source returns more texels for the same ground rather than a different scheme, so it raises PixelRatio and leaves this alone. The decoded image edge is TexturePx.

UrlTemplate

The URL template, with {z}, {x}, {y} and optionally {key} and {s} left unexpanded.

public string UrlTemplate { get; }

Property Value

string

Methods

ClampZoom(int)

Clamps a desired zoom level into the range this provider serves.

public int ClampZoom(int desiredZoom)

Parameters

desiredZoom int

The level the view would like.

Returns

int

The level to actually request, between MinZoom and MaxNativeZoom. Always call this before building a URL: it is what keeps the loader from issuing a request the provider will answer with 404.

DiskCacheKey(TileCoord)

The disk cache key for one tile from this source.

public ulong DiskCacheKey(TileCoord tile)

Parameters

tile TileCoord

Tile coordinate.

Returns

ulong

A key combining CacheTag with the tile's packed key, so two providers never collide on the same tile.

IsServable(int)

Whether this provider serves the given zoom level directly.

public bool IsServable(int zoom)

Parameters

zoom int

Zoom level to test.

Returns

bool

True when the level is between MinZoom and MaxNativeZoom inclusive, so a request for it is worth issuing.

WithProviderMetadata(int, int, string)

Returns a copy of this source carrying provider zoom limits and a license link.

public TileSource WithProviderMetadata(int minZoom, int maxNativeZoom, string attributionUrl)

Parameters

minZoom int

Shallowest level served, 0 to 24.

maxNativeZoom int

Deepest level served, from minZoom to 24.

attributionUrl string

Link target for the credit.

Returns

TileSource

A new source; this one is unchanged.

Remarks

Exists so the presets can attach provider metadata after building a template, without every construction site having to pass the extra arguments.