Skip to main content
Line layers render polylines with extensive styling options including colors, dash patterns, caps, joins, and animation. They support user interaction through click handlers.

Basic Setup

Create a line layer and add lines using the LineFactory.
val lineLayer = LineLayerInterface.create()
val line = LineFactory.createLine(
    identifier = "lineIdentifier",
    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 = lineWidth,
        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)

mapView.addLayer(lineLayer.asLayerInterface())

SwiftUI Integration

For SwiftUI apps, use UIViewRepresentable to manage line layers.
iOS (SwiftUI)
struct MapWithLineView: UIViewRepresentable {
    @Binding var camera: MapView.Camera
    let coords: [MCCoord]
    
    func makeUIView(context: Context) -> MCMapView {
        let mapView = MCMapView()
        
        // Add base layer
        mapView.add(layer: TiledRasterLayer("osm", webMercatorUrlFormat: "https://tiles.sample.org/{z}/{x}/{y}.png"))
        
        // Add line layer
        let lineLayer = MCLineLayerInterface.create()
        lineLayer?.add(MCLineFactory.createLine(
            "lineIdentifier",
            coordinates: coords,
            style: MCLineStyle(
                color: MCColorStateList(
                    normal: UIColor.systemPink.withAlphaComponent(0.5).mapCoreColor,
                    highlighted: UIColor.blue.withAlphaComponent(0.5).mapCoreColor
                ),
                gapColor: MCColorStateList(
                    normal: UIColor.red.withAlphaComponent(0.5).mapCoreColor,
                    highlighted: UIColor.gray.withAlphaComponent(0.5).mapCoreColor
                ),
                opacity: 1.0,
                widthType: .SCREEN_PIXEL,
                width: 50,
                dashArray: [1,1],
                dashFade: 0.0,
                dashAnimationSpeed: 0.0,
                lineCap: .BUTT,
                lineJoin: .ROUND,
                offset: 0.0,
                dotted: false,
                dottedSkew: 0.0
            )
        ))
        mapView.add(layer: lineLayer?.asLayerInterface())
        
        // Set initial camera position
        if let center = camera.center.value, let zoom = camera.zoom.value {
            mapView.camera.move(toCenterPositionZoom: center, zoom: zoom, animated: false)
        }
        
        return mapView
    }
    
    func updateUIView(_ uiView: MCMapView, context: Context) {
        // Handle updates if needed
    }
}

struct ContentView: View {
    @State private var camera = MapView.Camera(
        latitude: 46.962592372639634,
        longitude: 8.378232525377973,
        zoom: 1000000
    )
    
    var body: some View {
        MapWithLineView(
            camera: $camera,
            coords: [
                // your coordinates here
            ]
        )
    }
}

Adding User Interaction

Enable click handling for lines.
lineLayer.setLayerClickable(true)
lineLayer.setCallbackHandler(object : LineLayerCallbackInterface() {
    override fun onLineClickConfirmed(line: LineInfoInterface) {
        // Handle line click
        Log.d("Map", "Clicked line: ${line.getIdentifier()}")
    }
})

LineStyle Parameters

color
ColorStateList
required
Line color for normal and highlighted states
gapColor
ColorStateList
required
Color for gaps in dashed lines (use transparent for solid lines)
opacity
Float
required
Overall opacity of the line (0.0 to 1.0)
blur
Float
Blur amount applied to the line edges (Android)
widthType
SizeType
required
How line width is measured: SCREEN_PIXEL or MAP_UNIT
width
Float
required
Line width in the units specified by widthType
dashArray
Array<Float>
Pattern for dashed lines (e.g., [4.0, 2.0] for 4 pixels on, 2 pixels off)
dashFade
Float
Fade effect for dash transitions
dashAnimationSpeed
Float
Speed of dash animation (0 for static dashes)
lineCap
LineCapType
required
Style for line ends: BUTT, ROUND, or SQUARE
lineJoin
LineJoinType
required
Style for line joins: BEVEL, ROUND, or MITER
offset
Float
required
Offset distance perpendicular to the line direction
dotted
Boolean
required
Whether to render the line as dots
dottedSkew
Double
required
Skew factor for dotted lines

Width Types

SCREEN_PIXEL

The line width remains constant in screen pixels regardless of zoom level. Best for routes and UI elements.
widthType = SizeType.SCREEN_PIXEL,
width = 5.0f  // 5 pixels wide

MAP_UNIT

The line width is specified in map coordinate units and scales with zoom. Best for geographic features.
widthType = SizeType.MAP_UNIT,
width = 100.0f  // 100 map units wide

Line Cap Types

Square edge at the exact endpoint

Line Join Types

Flat edge connecting line segments

ColorStateList

Define different colors for normal and highlighted states.
Android
ColorStateList(
    normal = Color(1.0f, 0.0f, 0.0f, 1.0f),      // Red when normal
    highlighted = Color(1.0f, 0.5f, 0.0f, 1.0f)  // Orange when highlighted
)
iOS
MCColorStateList(
    normal: UIColor.systemPink.withAlphaComponent(0.5).mapCoreColor,
    highlighted: UIColor.blue.withAlphaComponent(0.5).mapCoreColor
)

Example: Dashed Route

Android
val routeCoords = listOf(
    Coord(CoordinateSystemIdentifiers.EPSG4326(), 8.378, 46.962, 0.0),
    Coord(CoordinateSystemIdentifiers.EPSG4326(), 8.540, 47.377, 0.0),
    Coord(CoordinateSystemIdentifiers.EPSG4326(), 7.447, 46.947, 0.0)
)

val lineLayer = LineLayerInterface.create()
val route = LineFactory.createLine(
    identifier = "route",
    coordinates = routeCoords,
    style = LineStyle(
        color = ColorStateList(
            normal = Color(0.0f, 0.5f, 1.0f, 0.8f),
            highlighted = Color(0.0f, 0.7f, 1.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.5f,
        widthType = SizeType.SCREEN_PIXEL,
        width = 8.0f,
        dashArray = arrayListOf(10.0f, 5.0f),  // 10 pixels on, 5 pixels off
        dashFade = 0.0f,
        dashAnimationSpeed = 0.0f,
        lineCap = LineCapType.ROUND,
        lineJoin = LineJoinType.ROUND,
        offset = 0.0f,
        dotted = false,
        dottedSkew = 0.0
    )
)
lineLayer.add(route)

lineLayer.setLayerClickable(true)
lineLayer.setCallbackHandler(object : LineLayerCallbackInterface() {
    override fun onLineClickConfirmed(line: LineInfoInterface) {
        Toast.makeText(context, "Route clicked", Toast.LENGTH_SHORT).show()
    }
})

mapView.addLayer(lineLayer.asLayerInterface())

Example: Animated Dash

Android
val animatedLine = LineFactory.createLine(
    identifier = "animated-route",
    coordinates = coordinates,
    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 = 6.0f,
        dashArray = arrayListOf(8.0f, 4.0f),
        dashFade = 0.0f,
        dashAnimationSpeed = 2.0f,  // Animate the dashes
        lineCap = LineCapType.ROUND,
        lineJoin = LineJoinType.ROUND,
        offset = 0.0f,
        dotted = false,
        dottedSkew = 0.0
    )
)
Use SCREEN_PIXEL width type for consistent line thickness across all zoom levels, perfect for routes and navigation paths.

Build docs developers (and LLMs) love