Skip to main content
This example demonstrates how to add interactive overlays to your map, including polygons, icons, and lines. These overlay layers can be combined with any base map layer.

Complete Overlay Example

This example combines all three overlay types: polygons, icons, and lines.
import io.openmobilemaps.mapscore.map.MapView
import io.openmobilemaps.mapscore.map.MapConfig
import io.openmobilemaps.mapscore.shared.map.coordinates.*
import io.openmobilemaps.mapscore.shared.map.layers.tiled.raster.TiledRasterLayer
import io.openmobilemaps.mapscore.shared.map.layers.polygon.*
import io.openmobilemaps.mapscore.shared.map.layers.icon.*
import io.openmobilemaps.mapscore.shared.map.layers.line.*
import io.openmobilemaps.mapscore.shared.graphics.*
import io.openmobilemaps.mapscore.MapsCore

class OverlayMapActivity : AppCompatActivity() {
    private lateinit var mapView: MapView
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        MapsCore.initialize()
        mapView = findViewById(R.id.mapView)
        
        // Setup map
        mapView.setupMap(MapConfig(CoordinateSystemFactory.getEpsg3857System()))
        mapView.registerLifecycle(lifecycle)
        
        // Add base raster layer
        val baseLayer = TiledRasterLayer()
        mapView.addLayer(baseLayer)
        
        // Add polygon layer
        setupPolygonLayer()
        
        // Add icon layer
        setupIconLayer()
        
        // Add line layer
        setupLineLayer()
        
        // Set camera position
        mapView.getCamera().moveToCenterPositionZoom(
            Coord(CoordinateSystemIdentifiers.EPSG4326(), 8.378232525377973, 46.962592372639634, 0.0),
            5000000.0,
            false
        )
    }
    
    private fun setupPolygonLayer() {
        val polygonLayer = PolygonLayerInterface.create()
        
        // Define polygon coordinates
        val coordinates = arrayListOf<Coord>(
            // Add your coordinates here
        )
        
        polygonLayer.add(
            PolygonInfo(
                identifier = "region",
                coordinates = PolygonCoord(
                    positions = coordinates,
                    holes = arrayListOf()
                ),
                color = Color(1.0f, 0.0f, 0.0f, 0.5f),
                highlightColor = Color(1.0f, 0.4f, 0.4f, 0.7f)
            )
        )
        
        // Enable click interaction
        polygonLayer.setLayerClickable(true)
        polygonLayer.setCallbackHandler(object : PolygonLayerCallbackInterface() {
            override fun onClickConfirmed(polygon: PolygonInfo) {
                // Handle polygon click
                Log.d("Map", "Polygon clicked: ${polygon.identifier}")
            }
        })
        
        mapView.addLayer(polygonLayer.asLayerInterface())
    }
    
    private fun setupIconLayer() {
        val iconLayer = IconLayerInterface.create()
        val texture = BitmapTextureHolder(/* drawable or bitmap */)
        val iconSize = 64.0f
        
        val coordinate = Coord(
            CoordinateSystemIdentifiers.EPSG4326(),
            8.378232525377973,
            46.962592372639634,
            0.0
        )
        
        val icon = IconFactory.createIconWithAnchor(
            identifier = "marker",
            coordinate = coordinate,
            texture = texture,
            iconSize = Vec2F(iconSize, iconSize),
            scaleType = IconType.INVARIANT,
            blendMode = BlendMode.NORMAL,
            iconAnchor = Vec2F(0.5f, 1.0f) // Centered at bottom
        )
        
        iconLayer.add(icon)
        
        // Enable click interaction
        iconLayer.setLayerClickable(true)
        iconLayer.setCallbackHandler(object : IconLayerCallbackInterface() {
            override fun onClickConfirmed(icons: ArrayList<IconInfoInterface>): Boolean {
                Log.d("Map", "Icon clicked: ${icons.firstOrNull()?.identifier}")
                return true
            }
            
            override fun onLongPress(icons: ArrayList<IconInfoInterface>): Boolean {
                Log.d("Map", "Icon long pressed: ${icons.firstOrNull()?.identifier}")
                return true
            }
        })
        
        mapView.addLayer(iconLayer.asLayerInterface())
    }
    
    private fun setupLineLayer() {
        val lineLayer = LineLayerInterface.create()
        
        val lineCoordinates = arrayListOf<Coord>(
            // Add your line coordinates here
        )
        
        val line = LineFactory.createLine(
            identifier = "route",
            coordinates = lineCoordinates,
            style = LineStyle(
                color = ColorStateList(
                    normal = Color(1.0f, 0.0f, 0.0f, 1.0f),
                    highlighted = Color(1.0f, 0.5f, 0.0f, 1.0f)
                ),
                gapColor = ColorStateList(
                    normal = Color(0.0f, 0.0f, 0.0f, 0.0f),
                    highlighted = Color(0.0f, 0.0f, 0.0f, 0.0f)
                ),
                opacity = 1.0f,
                blur = 0.0f,
                widthType = SizeType.SCREEN_PIXEL,
                width = 5.0f,
                dashArray = arrayListOf(4.0f, 2.0f),
                dashFade = 0f,
                dashAnimationSpeed = 0f,
                lineCap = LineCapType.SQUARE,
                lineJoin = LineJoinType.ROUND,
                offset = 0f,
                dotted = false,
                dottedSkew = 0.0
            )
        )
        
        lineLayer.add(line)
        
        // Enable click interaction
        lineLayer.setLayerClickable(true)
        lineLayer.setCallbackHandler(object : LineLayerCallbackInterface() {
            override fun onLineClickConfirmed(line: LineInfoInterface) {
                Log.d("Map", "Line clicked: ${line.identifier}")
            }
        })
        
        mapView.addLayer(lineLayer.asLayerInterface())
    }
}

Overlay Layer Features

Polygons

  • Fill color and highlight color support
  • Holes for complex shapes
  • Click interaction callbacks
  • Semi-transparent fills

Icons

  • Custom textures/images
  • Configurable anchor points (center, bottom, etc.)
  • Scale types: INVARIANT (fixed size) or FIXED (scales with map)
  • Blend modes for rendering
  • Click and long-press interactions

Lines

  • Solid or dashed patterns
  • Width in screen pixels or map units
  • Line caps: SQUARE, ROUND, BUTT
  • Line joins: ROUND, BEVEL, MITER
  • Color states for normal and highlighted
  • Optional gap color for dashed lines
  • Click interaction support

Result

The map displays a combination of polygons, icons, and lines overlaid on the base map. All overlay elements are interactive and support click handling.

Build docs developers (and LLMs) love