Rok Oblak
12/11/2024, 3:01 PMRok Oblak
12/11/2024, 3:02 PM<script async defer src="<https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=marker>"></script>
3. define bindings
import org.w3c.dom.Element
@JsName("google.maps.Map")
external class GMap(element: Element, options: JsAny) {
@JsName("addListener")
fun addListener(eventName: String, handler: (MapsMouseEvent) -> Unit): JsAny
}
@JsName("google.maps.marker.AdvancedMarkerElement")
external class GAdvancedMarkerElement(options: JsAny) {
fun setPosition(position: JsAny)
fun setMap(map: GMap?)
}
external interface LatLng {
fun lat(): Double
fun lng(): Double
}
external interface MapsMouseEvent {
val latLng: LatLng
}
fun createMarkerOptions(lat: Double, lng: Double): JsAny = js("""
({
position: { lat: lat, lng: lng }
})
""")
fun createGMapOptions(lat: Double, lng: Double, zoomLevel: Double, mapType: String): JsAny = js("""
({
center: { lat: lat, lng: lng },
zoom: zoomLevel,
mapTypeId: mapType,
mapId: "MAP_ID_HERE"
})
""")
4. define the composable and connect the map element
@Composable
fun GoogleMapView(
modifier: Modifier = Modifier,
lat: Double,
lng: Double,
markerPos: MapPos?,
zoomLevel: Double = 8.0,
mapType: String = "roadmap", // "satellite", "hybrid", "terrain"
onClick: (ClickedLatLng) -> Unit,
) {
val mapRef = remember { mutableStateOf<GMap?>(null) }
val markers = remember {
mutableListOf<GAdvancedMarkerElement>()
}
HtmlView(
modifier = modifier,
factory = {
createElement("div").apply { id = "map" }
},
update = { element ->
if (mapRef.value == null) {
mapRef.value = GMap(element, createGMapOptions(lat, lng, zoomLevel, mapType)).apply {
addListener("click", handler = { event ->
onClick(ClickedLatLng(lat = event.latLng.lat(), long = event.latLng.lng()))
})
}
} else {
if (markerPos != null) {
for (marker in markers) {
marker.setMap(null)
}
markers.clear()
val map = mapRef.value!!
val newMarker = GAdvancedMarkerElement(createMarkerOptions(markerPos.lat, markerPos.long)).apply {
setMap(map)
}
markers.add(newMarker)
}
}
},
)
}
(implementation of HtmlView)