Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions api/android-for-longdo.api
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ public final class com.mapconductor.longdo.LongdoMapViewController extends com.m
public void setOnMarkerClickListener(kotlin.jvm.functions.Function1<? super com.mapconductor.core.marker.MarkerState, kotlin.Unit>);
public java.lang.Object compositionRasterLayers(java.util.List<com.mapconductor.core.raster.RasterLayerState>, kotlin.coroutines.Continuation<? super kotlin.Unit>);
public java.lang.Object updateRasterLayer(com.mapconductor.core.raster.RasterLayerState, kotlin.coroutines.Continuation<? super kotlin.Unit>);
public void mountRasterLayer(com.mapconductor.core.raster.RasterLayerState);
public void unmountRasterLayer(java.lang.String);
public boolean hasRasterLayer(com.mapconductor.core.raster.RasterLayerState);
public boolean hasPolyline(com.mapconductor.core.polyline.PolylineState);
public void setOnPolylineClickListener(kotlin.jvm.functions.Function1<? super com.mapconductor.core.polyline.PolylineEvent, kotlin.Unit>);
Expand Down Expand Up @@ -149,6 +151,7 @@ public final class com.mapconductor.longdo.LongdoMapViewControllerRasterKt {
public static final java.lang.String rasterSourceSpec(com.mapconductor.longdo.LongdoMapViewController, com.mapconductor.core.raster.RasterLayerSource);
public static final java.lang.String rasterLayerSpec(com.mapconductor.longdo.LongdoMapViewController, java.lang.String, java.lang.String, float, boolean);
public static final java.lang.String addRasterJs(com.mapconductor.longdo.LongdoMapViewController, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
public static final java.lang.String readdRastersAfterStyleSwapJs(com.mapconductor.longdo.LongdoMapViewController, java.util.List<com.mapconductor.core.raster.RasterLayerState>);
public static final java.lang.String removeRasterJs(com.mapconductor.longdo.LongdoMapViewController, java.lang.String);
public static final java.lang.String setRasterOpacityJs(com.mapconductor.longdo.LongdoMapViewController, java.lang.String, float);
public static final java.lang.String setRasterVisibilityJs(com.mapconductor.longdo.LongdoMapViewController, java.lang.String, boolean);
Expand All @@ -169,8 +172,8 @@ public final class com.mapconductor.longdo.LongdoMapViewHolder implements com.ma
public java.lang.Object getMap();
}
public final class com.mapconductor.longdo.LongdoMapViewKt {
public static final void LongdoMapView(com.mapconductor.longdo.LongdoViewState, androidx.compose.ui.Modifier, com.mapconductor.core.marker.MarkerTilingOptions, com.mapconductor.core.map.CameraRestriction, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapViewStateInterface<?>, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function3<? super com.mapconductor.compose.MapViewScope, ? super androidx.compose.runtime.Composer, ? super java.lang.Integer, kotlin.Unit>, androidx.compose.runtime.Composer, int, int, int);
public static final void LongdoMapSurface(com.mapconductor.longdo.LongdoViewState, androidx.compose.ui.Modifier, com.mapconductor.core.marker.MarkerTilingOptions, com.mapconductor.core.map.CameraRestriction, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapViewStateInterface<?>, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.longdo.LongdoMapViewController, kotlin.Unit>, kotlin.jvm.functions.Function3<? super com.mapconductor.compose.MapViewScope, ? super androidx.compose.runtime.Composer, ? super java.lang.Integer, kotlin.Unit>, androidx.compose.runtime.Composer, int, int, int);
public static final void LongdoMapView(com.mapconductor.longdo.LongdoViewState, androidx.compose.ui.Modifier, com.mapconductor.core.marker.MarkerTilingOptions, com.mapconductor.core.map.CameraRestriction, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapViewStateInterface<?>, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, com.mapconductor.core.map.MapViewStyle, kotlin.jvm.functions.Function1<? super java.util.List<java.lang.String>, kotlin.Unit>, kotlin.jvm.functions.Function3<? super com.mapconductor.compose.MapViewScope, ? super androidx.compose.runtime.Composer, ? super java.lang.Integer, kotlin.Unit>, androidx.compose.runtime.Composer, int, int, int);
public static final void LongdoMapSurface(com.mapconductor.longdo.LongdoViewState, androidx.compose.ui.Modifier, com.mapconductor.core.marker.MarkerTilingOptions, com.mapconductor.core.map.CameraRestriction, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapViewStateInterface<?>, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.features.GeoPoint, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.core.map.MapCameraPosition, kotlin.Unit>, kotlin.jvm.functions.Function1<? super com.mapconductor.longdo.LongdoMapViewController, kotlin.Unit>, com.mapconductor.core.map.MapViewStyle, kotlin.jvm.functions.Function1<? super java.util.List<java.lang.String>, kotlin.Unit>, kotlin.jvm.functions.Function3<? super com.mapconductor.compose.MapViewScope, ? super androidx.compose.runtime.Composer, ? super java.lang.Integer, kotlin.Unit>, androidx.compose.runtime.Composer, int, int, int);
}
public final class com.mapconductor.longdo.LongdoMapViewSaver extends com.mapconductor.compose.map.BaseMapViewSaver<com.mapconductor.longdo.LongdoViewState> {
public static final java.lang.String KEY_DESIGN_ID;
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/com/mapconductor/longdo/LongdoMapView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import com.mapconductor.core.map.MapCameraPosition
import com.mapconductor.core.map.MapCapability
import com.mapconductor.core.map.MapCapabilityStatus
import com.mapconductor.core.map.MapServiceRegistrations
import com.mapconductor.core.map.MapViewStyle
import com.mapconductor.core.map.MapViewStyleEffect
import com.mapconductor.core.map.VisibleRegion
import com.mapconductor.core.marker.MarkerCapableInterface
import com.mapconductor.core.marker.MarkerRenderingSupportKey
Expand Down Expand Up @@ -88,6 +90,15 @@ fun LongdoMapView(
onCameraMoveStart: OnCameraMoveHandler? = null,
onCameraMove: OnCameraMoveHandler? = null,
onCameraMoveEnd: OnCameraMoveHandler? = null,
/**
* How the map looks, when the app states it rather than naming a design.
*
* A vector style *is* the basemap. `com.mapconductor:vectorstyle` builds
* one; what happens underneath depends on this backend and the app does
* not have to know.
*/
style: MapViewStyle? = null,
onStyleDiagnostics: ((List<String>) -> Unit)? = null,
content: (@Composable MapViewScope.() -> Unit)? = null,
) {
LongdoMapSurface(
Expand All @@ -101,6 +112,8 @@ fun LongdoMapView(
onCameraMoveStart = onCameraMoveStart,
onCameraMove = onCameraMove,
onCameraMoveEnd = onCameraMoveEnd,
style = style,
onStyleDiagnostics = onStyleDiagnostics,
content = content,
)
}
Expand Down Expand Up @@ -132,6 +145,15 @@ fun LongdoMapSurface(
onCameraMove: OnCameraMoveHandler? = null,
onCameraMoveEnd: OnCameraMoveHandler? = null,
onControllerReady: ((LongdoMapViewController) -> Unit)? = null,
/**
* How the map looks, when the app states it rather than naming a design.
*
* A vector style *is* the basemap. `com.mapconductor:vectorstyle` builds
* one; what happens underneath depends on this backend and the app does
* not have to know.
*/
style: MapViewStyle? = null,
onStyleDiagnostics: ((List<String>) -> Unit)? = null,
content: (@Composable MapViewScope.() -> Unit)? = null,
) {
val context = LocalContext.current
Expand Down Expand Up @@ -206,6 +228,16 @@ fun LongdoMapSurface(
onDispose { registrations.disposeAll() }
}

// 同じ理由で、スタイルの設置もここで呼ぶ(MapViewBase を通るプロバイダは
// あちらで 1 回呼んでいる)。何が起きるかはバックエンドが宣言した能力で
// 決まるので、このプロバイダ固有の分岐は無い。
MapViewStyleEffect(
state = state,
style = style,
controller = controller,
onDiagnostics = onStyleDiagnostics,
)

// タイル経路に倒すかはコントローラが件数を見て決める(他プロバイダと同じ規則)。
// ここで null を Default へ正規化するのも maplibre / googlemaps / here と揃えてある。
controller.markerTilingOptions =
Expand Down
58 changes: 54 additions & 4 deletions src/main/java/com/mapconductor/longdo/LongdoMapViewController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ class LongdoMapViewController(
dispatchCameraToOverlays()
// Gesture JS issued before ready is dropped by the page; re-apply now.
applyUISettings(appliedUISettings)
if (pendingMountedRasters.isNotEmpty()) {
val waiting = pendingMountedRasters.values.toList()
pendingMountedRasters.clear()
mainCoroutine.launch { waiting.forEach { applyRaster(it) } }
}
}

override fun setMapDesignType(value: LongdoMapDesignTypeInterface) {
Expand Down Expand Up @@ -295,17 +300,62 @@ class LongdoMapViewController(

override suspend fun compositionRasterLayers(data: List<RasterLayerState>) {
val newIds = data.map { it.id }.toSet()
appliedRasters.keys.filter { it !in newIds }.toList().forEach { id ->
runRasterJs(removeRasterJs(id))
appliedRasters.remove(id)
}
appliedRasters.keys
.filter { it !in newIds && it !in mountedRasterIds }
.toList()
.forEach { id ->
runRasterJs(removeRasterJs(id))
appliedRasters.remove(id)
}
data.forEach { applyRaster(it) }
}

/**
* content の外から載せたラスタの id。上の掃除から外すためにある。
*
* `compositionRasterLayers` は「アプリが宣言した集合」で全置換するので、
* 外から載せたものは次の再コンポーズで消える。他プロバイダでは
* [com.mapconductor.core.raster.RasterLayerController] の `upsert` が
* 同じ役割(`upsertedIds`)を持っている。
*/
private val mountedRasterIds = mutableSetOf<String>()

/** [mountRasterLayer] が ready 前に受け取ったもの。 */
private val pendingMountedRasters = mutableMapOf<String, RasterLayerState>()

override suspend fun updateRasterLayer(state: RasterLayerState) {
applyRaster(state)
}

/**
* content の外から載せるラスタ(マーカータイル、ベクタースタイルのラスタ化)。
*
* 他プロバイダは [com.mapconductor.core.raster.RasterLayerController] を
* オーバーレイコントローラとして登録してあるので基底の実装で足りるが、
* Longdo は内部 MapLibre GL へ JS で直接足すのでそれが無い。
* id は [mountedRasterIds] に控えて composition の掃除から外す。
*/
override fun mountRasterLayer(state: RasterLayerState) {
mountedRasterIds.add(state.id)
// ready 前に流した JS はページに捨てられる(`runRasterJs` は握りつぶす)。
// content 経由のラスタは composition が ready より後なので起きないが、
// ビューの外から載せるものは地図より先に来る。退避して [onMapReady] で出す。
if (!mapReady) {
pendingMountedRasters[state.id] = state
return
}
mainCoroutine.launch { applyRaster(state) }
}

override fun unmountRasterLayer(id: String) {
mountedRasterIds.remove(id)
pendingMountedRasters.remove(id)
mainCoroutine.launch {
runRasterJs(removeRasterJs(id))
appliedRasters.remove(id)
}
}

override fun hasRasterLayer(state: RasterLayerState): Boolean = appliedRasters.containsKey(state.id)

// --- PolylineCapableInterface ---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ internal fun LongdoMapViewController.nativeCameraFor(position: MapCameraPosition
// 高度は統一ズーム(Google)基準で算出する(Longdo ネイティブズームではない)。
val altitude = zoomConverter.zoomLevelToAltitude(position.zoom, position.position.latitude, 0.0)
val distanceForward = altitude * tan(tiltAbsRad)
val target = Spherical.computeOffset(position.position, distanceForward, CameraBearing.toNativeHeading(position.bearing))
val target =
Spherical
.computeOffset(position.position, distanceForward, CameraBearing.toNativeHeading(position.bearing))
return NativeCamera(target, longdoZoom, tiltAbsDeg)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,15 @@ internal fun LongdoMapViewController.addRasterJs(
*/
internal fun LongdoMapViewController.readdRastersAfterStyleSwapJs(rasters: List<RasterLayerState>): String {
val adds =
rasters.mapNotNull { state ->
val spec = rasterSourceSpec(state.source) ?: return@mapNotNull null
val srcId = rasterSourceId(state.id)
val layerId = rasterLayerId(state.id)
val layerSpec = rasterLayerSpec(layerId, srcId, state.opacity, state.visible)
"try{if(!m.getSource('$srcId'))m.addSource('$srcId',$spec);" +
"if(!m.getLayer('$layerId'))m.addLayer($layerSpec);}catch(e){}"
}.joinToString("")
rasters
.mapNotNull { state ->
val spec = rasterSourceSpec(state.source) ?: return@mapNotNull null
val srcId = rasterSourceId(state.id)
val layerId = rasterLayerId(state.id)
val layerSpec = rasterLayerSpec(layerId, srcId, state.opacity, state.visible)
"try{if(!m.getSource('$srcId'))m.addSource('$srcId',$spec);" +
"if(!m.getLayer('$layerId'))m.addLayer($layerSpec);}catch(e){}"
}.joinToString("")
return "(function(){var m=map.Renderer;if(!m)return;function re(){$adds}" +
"m.once('style.load',function(){setTimeout(re,0);});setTimeout(re,1500);})()"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.mapconductor.longdo

import androidx.compose.ui.geometry.Offset
import com.longdo.sdk3.LongdoMap
import com.mapconductor.core.ResourceProvider
import com.mapconductor.core.features.GeoPoint
import com.mapconductor.core.features.GeoPointInterface
import com.mapconductor.core.ResourceProvider
import com.mapconductor.core.map.MapCameraPosition
import com.mapconductor.core.map.MapViewHolderInterface
import com.mapconductor.core.projection.WebMercatorScreenProjection
Expand Down
Loading