Skip to main content

Overview

Open Mobile Maps provides layer interfaces for rendering various types of overlays on the map, including polygons, icons, and lines. Each layer type has its own interface and configuration options.
In SwiftUI, overlay layers (polygons, icons, lines) need to be managed through the underlying MCMapView using UIViewRepresentable. Base layers can be added directly to the SwiftUI MapView.

Polygon Layer

The polygon layer interface handles rendering of filled polygons with customizable colors and interaction callbacks.

MCPolygonLayerInterface

let polygonLayer = MCPolygonLayerInterface.create()

Adding Polygons

let coords: [MCCoord] = [
    // coordinates
]

let polygonInfo = MCPolygonInfo(
    identifier: "switzerland",
    coordinates: MCPolygonCoord(positions: coords, holes: []),
    color: UIColor.red.mapCoreColor,
    highlight: UIColor.red.withAlphaComponent(0.2).mapCoreColor
)

polygonLayer?.add(polygonInfo)
identifier
String
required
Unique identifier for the polygon
coordinates
MCPolygonCoord
required
Polygon coordinates including positions and optional holes
color
Color
required
Fill color for the polygon in normal state
highlight
Color
required
Fill color for the polygon in highlighted/selected state

Callback Handler

polygonLayer?.setCallbackHandler(handler)

UIKit Example

let coords: [MCCoord] = [
    // coordinates
]

let polygonLayer = MCPolygonLayerInterface.create()
let polygonInfo = MCPolygonInfo(
    identifier: "switzerland",
    coordinates: MCPolygonCoord(positions: coords, holes: []),
    color: UIColor.red.mapCoreColor,
    highlight: UIColor.red.withAlphaComponent(0.2).mapCoreColor
)

polygonLayer?.add(polygonInfo)
polygonLayer?.setCallbackHandler(handler)
mapView.add(layer: polygonLayer?.asLayerInterface())

SwiftUI Example

struct MapWithPolygonView: 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 polygon layer
        let polygonLayer = MCPolygonLayerInterface.create()
        let polygonInfo = MCPolygonInfo(
            identifier: "switzerland",
            coordinates: MCPolygonCoord(positions: coords, holes: []),
            color: UIColor.red.mapCoreColor,
            highlight: UIColor.red.withAlphaComponent(0.2).mapCoreColor
        )
        
        polygonLayer?.add(polygonInfo)
        mapView.add(layer: polygonLayer?.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 camera updates if needed
    }
}

Icon Layer

The icon layer interface supports displaying textures at specific coordinates with configurable scaling.

MCIconLayerInterface

let iconLayer = MCIconLayerInterface.create()

Adding Icons

let image = UIImage(named: "image")
let texture = try! TextureHolder(image!.cgImage!)
let icon = MCIconFactory.createIcon(
    "icon",
    coordinate: coordinate,
    texture: texture,
    iconSize: .init(x: Float(texture.getImageWidth()), y: Float(texture.getImageHeight())),
    scale: .FIXED,
    blendMode: .NORMAL
)
iconLayer?.add(icon)
identifier
String
required
Unique identifier for the icon
coordinate
MCCoord
required
Position where the icon should be displayed
texture
TextureHolder
required
Image texture to display
iconSize
Vec2F
required
Size of the icon in pixels
scale
IconScale
How the icon should be affected by camera movements (e.g., .FIXED)
blendMode
BlendMode
Blend mode for rendering (e.g., .NORMAL)

UIKit Example

let iconLayer = MCIconLayerInterface.create()
let image = UIImage(named: "image")
let texture = try! TextureHolder(image!.cgImage!)
let icon = MCIconFactory.createIcon(
    "icon",
    coordinate: coordinate,
    texture: texture,
    iconSize: .init(x: Float(texture.getImageWidth()), y: Float(texture.getImageHeight())),
    scale: .FIXED,
    blendMode: .NORMAL
)
iconLayer?.add(icon)
iconLayer?.setCallbackHandler(handler)
mapView.add(layer: iconLayer?.asLayerInterface())

SwiftUI Example

struct MapWithIconView: UIViewRepresentable {
    @Binding var camera: MapView.Camera
    let coordinate: MCCoord
    let imageName: String
    
    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 icon layer
        let iconLayer = MCIconLayerInterface.create()
        let image = UIImage(named: imageName)
        let texture = try! TextureHolder(image!.cgImage!)
        let icon = MCIconFactory.createIcon(
            "icon",
            coordinate: coordinate,
            texture: texture,
            iconSize: .init(x: Float(texture.getImageWidth()), y: Float(texture.getImageHeight())),
            scale: .FIXED,
            blendMode: .NORMAL
        )
        iconLayer?.add(icon)
        mapView.add(layer: iconLayer?.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
    }
}

Line Layer

The line layer interface renders styled lines with customizable appearance including width, color, dash patterns, and more.

MCLineLayerInterface

let lineLayer = MCLineLayerInterface.create()

Adding Lines

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
    )
))
identifier
String
required
Unique identifier for the line
coordinates
[MCCoord]
required
Array of coordinates defining the line path
color
MCColorStateList
required
Line color for normal and highlighted states
gapColor
MCColorStateList
Color for gaps in dashed lines
opacity
Float
Line opacity (0.0 to 1.0)
widthType
WidthType
How width is measured (.SCREEN_PIXEL or .MAP_UNIT)
width
Float
Line width in the specified unit type
dashArray
[Float]
Pattern for dashed lines (e.g., [1, 1] for equal dash/gap)
lineCap
LineCap
End cap style (.BUTT, .ROUND, or .SQUARE)
lineJoin
LineJoin
Join style for line segments (.ROUND, .BEVEL, or .MITER)
offset
Float
Offset distance from the line path

UIKit Example

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],
        lineCap: .BUTT,
        offset: 0.0
    )
))

mapView.add(layer: lineLayer?.asLayerInterface())

SwiftUI Example

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
    }
}

Converting to Layer Interface

All overlay layer interfaces must be converted to the base layer interface before adding to the map view:
mapView.add(layer: polygonLayer?.asLayerInterface())
mapView.add(layer: iconLayer?.asLayerInterface())
mapView.add(layer: lineLayer?.asLayerInterface())

Build docs developers (and LLMs) love