Class ContourTileDataSource

java.lang.Object
com.massifmaps.datasources.TileDataSource
com.massifmaps.datasources.ContourTileDataSource

public class ContourTileDataSource extends TileDataSource
A tile data source that generates vector contour lines on the fly from an
RGB-encoded elevation (DEM) tile data source. The wrapped elevation data source
is shared (e.g. with a HillshadeRasterTileLayer) so terrain tiles are fetched
only once.

The generated tiles are standard Mapbox Vector Tiles containing a single line
layer (default name "contour"). Each contour feature carries two attributes:
- 'ele': the contour elevation in meters.
- 'div': the largest "nice" divisor of the elevation (1000, 500, 250, 200,
100, 50, 20 or 10), matching the gdal_contour based pipeline. This
lets CartoCSS filter contour importance by elevation, e.g.
#contour[div=500][zoom>=12] { ... }.

Attach the source to a normal VectorTileLayer to render lines and labels
([ele] as the label text) fully from the decoder style.

Note: this class is experimental and may change or even be removed in future SDK versions.
  • Constructor Details

    • ContourTileDataSource

      public ContourTileDataSource(TileDataSource dataSource, ElevationDecoder elevationDecoder)
      Constructs a ContourTileDataSource object.
      Parameters:
      dataSource - The RGB-encoded elevation data source to generate contours from.
      elevationDecoder - The decoder used to convert RGB pixels to elevation. If null,
      the decoder is inferred from the data source 'encoding' metadata (defaults to terrarium).
    • ContourTileDataSource

      public ContourTileDataSource(TileDataSource dataSource)
      Constructs a ContourTileDataSource object, inferring the elevation decoder from the
      data source 'encoding' metadata (defaults to terrarium).
      Parameters:
      dataSource - The RGB-encoded elevation data source to generate contours from.
  • Method Details

    • getLayerName

      public String getLayerName()
      Returns the name of the generated vector tile layer.
      Returns:
      The layer name. The default is "contour".
    • setLayerName

      public void setLayerName(String name)
      Sets the name of the generated vector tile layer. This must match the layer id used in the CartoCSS style.
      Parameters:
      name - The layer name.
    • getBaseInterval

      public float getBaseInterval()
      Returns the base contour interval in meters.
      Returns:
      The base contour interval in meters. The default is 10.
    • setBaseInterval

      public void setBaseInterval(float interval)
      Sets the base contour interval in meters. This is the FINEST interval generated; coarser
      tile zooms generate a multiple of it, see setIntervalMultiplier.
      Parameters:
      interval - The base contour interval in meters.
    • setIntervalMultiplier

      public void setIntervalMultiplier(int maxZoom, float multiplier)
      Sets the interval multiplier used at tile zooms up to (and including) maxZoom. A tile
      carries every elevation that is a multiple of BaseInterval x multiplier, and each contour
      carries 'div' so the style picks per camera zoom which of them to draw.

      The default table is (9, 50), (11, 10), (13, 5), (any, 1): 500m, 100m, 50m, 10m for a 10m base.

      TWO RULES when changing it:
      - the multipliers must NEST - each one a multiple of the finer ones - or a line stops
      dead at the border between tiles of different zoom (200 and 500 share no elevation);
      - cost tracks the number of contours emitted, so a multiplier twice as fine is about
      twice the tracing, the geometry and the draw. Make it no finer than what the style
      actually draws at the camera zoom where tiles of that zoom are used.
      Parameters:
      maxZoom - The highest tile zoom this multiplier applies to, or -1 for every zoom above the other entries.
      multiplier - The multiplier of BaseInterval, >= 1.
    • getIntervalMultiplier

      public float getIntervalMultiplier(int zoom)
      Returns the interval multiplier that applies at the given tile zoom.
      Parameters:
      zoom - The tile zoom.
      Returns:
      The multiplier of BaseInterval.
    • clearIntervalMultipliers

      public void clearIntervalMultipliers()
      Removes every interval multiplier entry, so BaseInterval is used at every zoom.
    • getResolution

      public int getResolution()
      Returns the target grid resolution used for contour tracing.
      Returns:
      The target grid resolution, 0 for the DEM's own. The default is 128.
    • setResolution

      public void setResolution(int resolution)
      Sets the target grid resolution used for contour tracing. The DEM is subsampled so that
      the traced grid is at most this many samples per side. Lower values produce coarser but
      much cheaper geometry (fewer vertices to trace, simplify, upload and drape over terrain).
      Over 3D TERRAIN use 0 (the DEM's own resolution): the surface is displaced by every texel
      of the same tile, so a line traced on a subsampled grid follows a height field the ground
      does not have and cuts through everything between its samples.
      Parameters:
      resolution - The target grid resolution (clamped to at least 8), or 0 for the DEM's own.
    • setResolutionForZoom

      public void setResolutionForZoom(int maxZoom, int resolution)
      Sets the tracing grid resolution used at tile zooms up to (and including) maxZoom,
      overriding Resolution there. Tracing cost is roughly quadratic in this, and a low zoom
      tile covers so much ground that a fine grid buys nothing, so this is the cheapest knob to
      turn for zoomed-out frames - but a costly one for QUALITY: a tile is drawn at roughly the
      same screen size whatever its zoom, so a grid that shrinks with zoom puts contour vertices
      hundreds of metres apart and the lines read as straight chords. Empty by default for that
      reason: Resolution applies at every zoom, and low zoom saves through the interval instead.
      Parameters:
      maxZoom - The highest tile zoom this resolution applies to, or -1 for every zoom above the other entries.
      resolution - The target grid resolution (clamped to at least 8), or 0 for the DEM's own.
    • getResolutionForZoom

      public int getResolutionForZoom(int zoom)
      Returns the tracing grid resolution that applies at the given tile zoom.
      Parameters:
      zoom - The tile zoom.
      Returns:
      The target grid resolution, 0 for the DEM's own.
    • clearResolutionsForZoom

      public void clearResolutionsForZoom()
      Removes every per-zoom resolution entry, so Resolution is used at every zoom.
    • getMinVisibleZoom

      public int getMinVisibleZoom()
      Returns the minimum zoom at which contour geometry is generated.
      Returns:
      The minimum contour zoom. The default is 12.
    • setMinVisibleZoom

      public void setMinVisibleZoom(int zoom)
      Sets the minimum zoom at which contour geometry is generated. Below this zoom loadTile returns
      an empty (but valid) tile without fetching or tracing the DEM. Note: in CartoCSS 'zoom' means the
      TILE zoom, so the style must also draw the desired zoom range for contours to actually appear.
      Parameters:
      zoom - The minimum contour zoom.
    • isSeamlessEdgesEnabled

      public boolean isSeamlessEdgesEnabled()
      Returns whether seamless tile edges are enabled.
      Returns:
      True if seamless edges are enabled. The default is true.
    • setSeamlessEdgesEnabled

      public void setSeamlessEdgesEnabled(boolean enabled)
      Sets whether to generate seamless tile edges. When enabled, the east/north/north-east neighbour
      DEM tiles are fetched so that a tile's east and north edges use the exact same elevation samples
      as the adjacent tiles, removing the small gaps where contour lines meet at tile boundaries.
      This costs up to three extra DEM tile fetches/decodes per tile (they are usually cached).
      Parameters:
      enabled - True to enable seamless edges.
    • getTerrainOptions

      public TerrainOptions getTerrainOptions()
      Returns the terrain options whose elevation manager the label stubs read.
      Returns:
      The terrain options, or null.
    • setTerrainOptions

      public void setTerrainOptions(TerrainOptions terrainOptions)
      Sets the terrain options whose ELEVATION MANAGER the label stubs are generated from.
      With it, a stub tile costs no tile of its own: the seeds are walked over the elevation
      grid the 3D terrain has already fetched and decoded for that tile, which is how tangram
      generates contour labels (core/src/style/contourTextStyle.cpp reads the tile's own
      elevation raster). Without it, the source loads and decodes the DEM tile a second time -
      measured at 44% of a tile decode thread, half of it in the image decode alone.

      The terrain options must be driven by the SAME elevation data source this tile source
      wraps, or the labels state heights the map does not show. Only the stubs use it; traced
      contour geometry keeps reading the DEM at its own resolution, which the terrain's
      mesh-capped elevation level cannot supply.
      Parameters:
      terrainOptions - The terrain options, or null to decode a DEM tile of our own.
    • isLabelStubsEnabled

      public boolean isLabelStubsEnabled()
      Returns whether only short label stubs are generated instead of full contour lines.
      Returns:
      True if label stubs are generated. The default is false.
    • setLabelStubsEnabled

      public void setLabelStubsEnabled(boolean enabled)
      Sets whether to generate short label stubs instead of full contour lines. A stub is a
      ~20 point polyline lying ON a contour, long enough to lay the elevation text along and
      nothing more: a grid of 4x4 seeds per tile is walked down the elevation gradient onto the
      nearest contour level and then along it. The tile then carries a handful of tiny features
      instead of the full traced geometry, which is what makes the labels affordable when the
      contour LINES are drawn by the terrain shader
      (HillshadeRasterTileLayer.setContourEnabled) rather than from this geometry.

      The features keep the same layer name and the same 'ele'/'div' attributes, so the existing
      text rules style them unchanged; they additionally carry 'stub' = 1, so a style that also
      draws contour LINES from this layer can exclude them with a [stub=0] filter.

      The stub levels must match the levels the shader draws, or the labels sit between the
      lines: set LabelInterval to the layer's ContourInterval (or leave both at their zoom
      defaults).
      Parameters:
      enabled - True to generate label stubs only.
    • getLabelInterval

      public float getLabelInterval()
      Returns the contour interval used for label stubs.
      Returns:
      The label interval in meters, or 0 to follow the zoom-dependent interval. The default is 0.
    • setLabelInterval

      public void setLabelInterval(float interval)
      Sets the contour interval used for label stubs, in meters. Use 0 to follow the same
      zoom-dependent interval the traced geometry uses.
      Parameters:
      interval - The label interval in meters.
    • getSimplifyTolerance

      public float getSimplifyTolerance()
      Returns the simplification tolerance in tile pixels.
      Returns:
      The simplification tolerance in tile pixels. The default is 1.0.
    • setSimplifyTolerance

      public void setSimplifyTolerance(float tolerance)
      Sets the simplification tolerance in tile pixels. Use 0.0 to disable simplification.
      Parameters:
      tolerance - The simplification tolerance in tile pixels.
    • getMinZoom

      public int getMinZoom()
      Description copied from class: TileDataSource
      Returns the minimum zoom level supported by this data source.
      Overrides:
      getMinZoom in class TileDataSource
      Returns:
      The minimum zoom level supported (inclusive).
    • getMaxZoom

      public int getMaxZoom()
      Description copied from class: TileDataSource
      Returns the maximum zoom level supported by this data source.
      Overrides:
      getMaxZoom in class TileDataSource
      Returns:
      The maximum zoom level supported (exclusive).
    • getDataExtent

      public MapBounds getDataExtent()
      Description copied from class: TileDataSource
      Returns the extent of the tiles in this data source.
      The bounds are in coordinate system of the projection of the data source.
      Overrides:
      getDataExtent in class TileDataSource
      Returns:
      The extent of the data source.
    • getContainerMetaData

      public String getContainerMetaData(String key)
      Description copied from class: TileDataSource
      Reads one entry of the source's own metadata, when it has any - the MBTiles or PMTiles
      metadata table, for instance. Sources that carry none return an empty string, as do keys
      they do not define. Unlike the meta data map above this is read-only and is NOT attached
      to the loaded tiles: a container's metadata can be tens of kilobytes.
      Overrides:
      getContainerMetaData in class TileDataSource
      Parameters:
      key - The metadata key, as named by the container's specification.
      Returns:
      The value, or empty string if the source does not provide it.
    • loadTile

      public TileData loadTile(MapTile tile)
      Description copied from class: TileDataSource
      Loads the specified tile.
      Note: the tile coordinate system used here is vertically flipped relative to layer tile coordinate system.
      Overrides:
      loadTile in class TileDataSource
      Parameters:
      tile - The tile to load.
      Returns:
      The tile data. If the tile is not available, null may be returned.