Icon layers display textures (images) at specific map coordinates with configurable scaling behavior. They support user interaction through click and long-press handlers.
Basic Setup
Create an icon layer and add icons using the IconFactory.
val iconLayer = IconLayerInterface.create()
val texture = BitmapTextureHolder(/* drawable or bitmap */)
val icon = IconFactory.createIcon(
identifier = "Icon",
coordinate = coordinate,
texture = texture,
iconSize = Vec2F(iconSize, iconSize),
scaleType = IconType.INVARIANT,
blendMode = BlendMode.NORMAL
)
iconLayer.add(icon)
mapView.addLayer(iconLayer.asLayerInterface())
Custom Anchor Point
Control where the icon is positioned relative to its coordinate using a custom anchor.
val iconWithCustomAnchor = IconFactory.createIconWithAnchor(
"Icon with a custom Anchor",
coordinate = coordinate,
texture = texture,
iconSize = Vec2F(iconSize, iconSize),
scaleType = IconType.INVARIANT,
blendMode = BlendMode.NORMAL,
iconAnchor = Vec2F(0.5f, 1.0f) // e.g. horizontally centered at the bottom
)
iconLayer.add(iconWithCustomAnchor)
Anchor Point Examples
Vec2F(0.5f, 0.5f) - Center of icon (default)
Vec2F(0.5f, 1.0f) - Bottom center (typical for map pins)
Vec2F(0.0f, 0.0f) - Top-left corner
Vec2F(1.0f, 1.0f) - Bottom-right corner
SwiftUI Integration
For SwiftUI apps, use UIViewRepresentable to manage icon layers.
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
}
}
struct ContentView: View {
@State private var camera = MapView.Camera(
latitude: 46.962592372639634,
longitude: 8.378232525377973,
zoom: 1000000
)
var body: some View {
MapWithIconView(
camera: $camera,
coordinate: camera.center.value ?? MCCoord(lat: 46.962592372639634, lon: 8.378232525377973),
imageName: "your-image-name"
)
}
}
Adding User Interaction
Enable click and long-press handling for icons.
iconLayer.setLayerClickable(true)
iconLayer.setCallbackHandler(object : IconLayerCallbackInterface(){
override fun onClickConfirmed(icons: ArrayList<IconInfoInterface>): Boolean {
// React to icon click
icons.forEach { icon ->
Log.d("Map", "Clicked icon: ${icon.getIdentifier()}")
}
return true // Return true if handled
}
override fun onLongPress(icons: ArrayList<IconInfoInterface>): Boolean {
// React to long press
icons.forEach { icon ->
Log.d("Map", "Long pressed icon: ${icon.getIdentifier()}")
}
return true // Return true if handled
}
})
Updating Icon Position
You can update the position of an icon dynamically using the setCoordinate method.
val icon = IconFactory.createIcon(
identifier = "movable-icon",
coordinate = initialCoordinate,
texture = texture,
iconSize = Vec2F(iconSize, iconSize),
scaleType = IconType.INVARIANT,
blendMode = BlendMode.NORMAL
)
iconLayer.add(icon)
// Later, update the position
icon.setCoordinate(newCoordinate)
IconFactory Parameters
Unique identifier for the icon
Map coordinate where the icon should be displayed
Image texture for the icon
Size of the icon in pixels (width, height)
How the icon scales with camera movement
Blending mode for rendering the icon
Anchor point in normalized coordinates (0.0 to 1.0). Defaults to center (0.5, 0.5)
Icon Scale Types
IconType.INVARIANT - Icon size remains constant regardless of zoom levelIconType.FIXED - Icon scales with the map
.INVARIANT - Icon size remains constant regardless of zoom level.FIXED - Icon scales with the map
Blend Modes
BlendMode.NORMAL - Standard alpha blending
- Additional blend modes may be available depending on the platform
Creating Textures
// From Drawable
val drawable = ContextCompat.getDrawable(context, R.drawable.marker)
val texture = BitmapTextureHolder(drawable)
// From Bitmap
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.marker)
val texture = BitmapTextureHolder(bitmap)
// From UIImage
let image = UIImage(named: "marker")
let texture = try! TextureHolder(image!.cgImage!)
// From asset
let image = UIImage(named: "marker", in: Bundle.main, compatibleWith: nil)
let texture = try! TextureHolder(image!.cgImage!)
Example: Multiple Icons
val iconLayer = IconLayerInterface.create()
val markerTexture = BitmapTextureHolder(ContextCompat.getDrawable(context, R.drawable.marker))
val locations = listOf(
Pair("Location 1", Coord(CoordinateSystemIdentifiers.EPSG4326(), 8.378, 46.962, 0.0)),
Pair("Location 2", Coord(CoordinateSystemIdentifiers.EPSG4326(), 8.540, 47.377, 0.0)),
Pair("Location 3", Coord(CoordinateSystemIdentifiers.EPSG4326(), 7.447, 46.947, 0.0))
)
locations.forEach { (name, coord) ->
val icon = IconFactory.createIconWithAnchor(
identifier = name,
coordinate = coord,
texture = markerTexture,
iconSize = Vec2F(48f, 48f),
scaleType = IconType.INVARIANT,
blendMode = BlendMode.NORMAL,
iconAnchor = Vec2F(0.5f, 1.0f) // Bottom-center anchor for map pins
)
iconLayer.add(icon)
}
iconLayer.setLayerClickable(true)
iconLayer.setCallbackHandler(object : IconLayerCallbackInterface(){
override fun onClickConfirmed(icons: ArrayList<IconInfoInterface>): Boolean {
icons.forEach { icon ->
Toast.makeText(context, "Clicked: ${icon.getIdentifier()}", Toast.LENGTH_SHORT).show()
}
return true
}
})
mapView.addLayer(iconLayer.asLayerInterface())
Use IconType.INVARIANT for UI elements like markers that should maintain a consistent size on screen.