Skip to Content
AdvancedCustom Map Layers

MapsGL Android - Custom Map Layers

Layer descriptors configure map layers and how data from a source is drawn. Each layer ties together a source (the data) and a layer style (how it is rendered).

The following layer descriptors are supported. See the linked API reference for configuration options:

DescriptorDescription
RasterLayerDescriptorRaster layers, such as tile imagery. API docs.
SampleLayerDescriptorColorized raster layers, usually from encoded raster sources. API docs.
ContourLayerDescriptorContour / isoline layers over encoded raster data. API docs.
ParticleLayerDescriptorParticle-based layers (e.g. wind or current flow). API docs.
FillLayerDescriptorPolygon geometry (e.g. alerts, boundaries). API docs.
LineLayerDescriptorLine geometry (e.g. roads, rivers). API docs.
CircleLayerDescriptorPoints drawn as circles (e.g. stations, lightning). API docs.
SymbolLayerDescriptorPoints drawn with symbols (icons, labels). API docs.
GridLayerDescriptorGridded icon layers (e.g. wind barbs, directional arrows) using GridLayerPaint. API docs.
HeatmapLayerDescriptorPoint density as a heatmap. API docs.

Adding Layers

After sources are registered on MapController, add layers so the map can render them.

For example, render the alerts vector tile source from the sources guide. Polygons can use fill and/or stroke in FillLayerPaint.

Start with a solid red fill:

import com.xweather.mapsgl.layers.spec.FillLayerDescriptor import com.xweather.mapsgl.map.MapController import com.xweather.mapsgl.sources.source.spec.VectorSourceDescriptor import com.xweather.mapsgl.style.Expression import com.xweather.mapsgl.style.FillLayerPaint import com.xweather.mapsgl.style.FillPaint import com.xweather.mapsgl.style.StrokePaint import com.xweather.mapsgl.style.StyleValue import com.xweather.mapsgl.types.Color // Register the source first val alertsSource = VectorSourceDescriptor(id = "alerts").apply { url = "https://maps{s}.aerisapi.com/[CLIENT_ID]_[CLIENT_SECRET]/alerts/{z}/{x}/{y}/0.pbf" } controller.addSource(alertsSource) // Layer references the source id val alertsLayer = FillLayerDescriptor( id = "alerts-fill", source = alertsSource.id, paint = FillLayerPaint( fill = FillPaint(color = StyleValue.Constant(Color.Red)), ), ) controller.addLayer(alertsLayer, beforeId = null)

The layer’s source is the same string id you passed to VectorSourceDescriptor.

Feature properties can drive the fill. For alerts, each feature includes a COLOR hex string (no #):

{ "ADVISORY": "FLOOD WARNING", "CAT": "flood", "COLOR": "00FF00", "EXPIREDATE": 1652270400, "LOCATION": "madison", "STARTDATE": 1652112060, "VTEC": "FL.W", "ZONE": "ILC119" }

Use a style expression to build a CSS-style color (# + property):

val alertsLayer = FillLayerDescriptor( id = "alerts-fill", source = alertsSource.id, paint = FillLayerPaint( fill = FillPaint( color = StyleValue.Expression( Expression.concat(listOf("#", Expression.get("COLOR"))), ), ), ), ) controller.addLayer(alertsLayer, insertBeforeId = null)

Add a black outline so adjacent polygons stay visible:

val alertsLayer = FillLayerDescriptor( id = "alerts-fill", source = alertsSource.id, paint = FillLayerPaint( fill = FillPaint( color = StyleValue.Expression( Expression.concat(listOf("#", Expression.get("COLOR"))), ), ), stroke = StrokePaint(color = StyleValue.Constant(Color.Black)), ), ) controller.addLayer(alertsLayer, insertBeforeId = null)

StyleValue.Expression with Expression.get("COLOR") (and concat for #) is the Android analogue of data-driven fill color. See Data-driven styling for more expression patterns.

Removing Layers

Remove a layer by the id you assigned when adding it:

controller.removeLayer(id = "alerts-fill")

The source remains until you call removeSource with its id:

controller.removeSource(id = "alerts")
© 2026 Xweather (opens in a new tab)Terms of Service (opens in a new tab)Privacy Policy (opens in a new tab)