Skip to content
Open
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
9 changes: 9 additions & 0 deletions api/android-for-mapbox.api
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@ public final class com.mapconductor.mapbox.MapboxMapViewSaver extends com.mapcon
public final class com.mapconductor.mapbox.MapboxMapViewScope extends com.mapconductor.compose.MapViewScope {
public com.mapconductor.mapbox.MapboxMapViewScope();
}
public final class com.mapconductor.mapbox.MapboxOverlayStacking {
public static final com.mapconductor.mapbox.MapboxOverlayStacking INSTANCE;
public final com.mapconductor.core.controller.OverlayLayerStack stackOf(com.mapbox.maps.MapboxMap);
public final com.mapconductor.core.controller.OverlayStacking$Key key(com.mapconductor.core.controller.OverlayKind, int);
public final com.mapconductor.core.controller.OverlayStacking$Key getMARKER_TILE();
public final com.mapconductor.core.controller.OverlayStacking$Key getMARKER_DRAG();
public final void add(com.mapbox.maps.MapboxMap, com.mapbox.maps.Style, com.mapbox.maps.extension.style.layers.Layer, com.mapconductor.core.controller.OverlayStacking$Key);
public final void remove(com.mapbox.maps.MapboxMap, com.mapbox.maps.Style, java.lang.String);
}
public final class com.mapconductor.mapbox.MapboxPaddings extends com.mapconductor.core.map.MapPaddings implements com.mapconductor.mapbox.IMapboxPaddingsInterface {
public static final com.mapconductor.mapbox.MapboxPaddings$Companion Companion;
public com.mapconductor.mapbox.MapboxPaddings(double, double, double, double);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.mapconductor.mapbox

import com.mapbox.maps.extension.style.layers.addLayer
import com.mapbox.maps.extension.style.layers.addLayerAbove
import com.mapbox.maps.extension.style.layers.addLayerBelow
import com.mapbox.maps.extension.style.sources.addSource
import com.mapconductor.core.controller.OverlayKind
import com.mapconductor.mapbox.marker.MapboxMarkerOverlayRenderer

/**
Expand All @@ -21,18 +19,12 @@ internal fun MapboxMapViewController.attachMarkerLayers(
style.addSource(renderer.markerLayer.source)
} catch (_: Exception) {
}
try {
style.addLayer(renderer.markerLayer.layer)
} catch (_: Exception) {
}
MapboxOverlayStacking.add(holder.map, style, renderer.markerLayer.layer, MapboxOverlayStacking.key(OverlayKind.Marker))
try {
style.addSource(renderer.dragLayer.source)
} catch (_: Exception) {
}
try {
style.addLayer(renderer.dragLayer.layer)
} catch (_: Exception) {
}
MapboxOverlayStacking.add(holder.map, style, renderer.dragLayer.layer, MapboxOverlayStacking.MARKER_DRAG)
}

internal fun MapboxMapViewController.attachOverlaySourcesAndLayers(style: com.mapbox.maps.Style) {
Expand All @@ -42,14 +34,22 @@ internal fun MapboxMapViewController.attachOverlaySourcesAndLayers(style: com.ma

// Circle fill (fill pass) then stroke (line pass) — both below general polyline
style.addSource(circleController.renderer.layer.source)
style.addLayer(circleController.renderer.layer.fillLayer)
style.addLayer(circleController.renderer.layer.strokeLayer)
// 層の位置は MapboxOverlayStacking が帯の順で決める(追加の順に依らない)。
// 線は塗りの直後(同じ鍵なら後から入れたものが上)。
val circleKey = MapboxOverlayStacking.key(OverlayKind.Circle)
MapboxOverlayStacking.add(holder.map, style, circleController.renderer.layer.fillLayer, circleKey)
MapboxOverlayStacking.add(holder.map, style, circleController.renderer.layer.strokeLayer, circleKey)

// Polyline (general)
style.addSource(polylineController.renderer.layer.source)
style.addLayer(polylineController.renderer.layer.layer)
MapboxOverlayStacking.add(
holder.map,
style,
polylineController.renderer.layer.layer,
MapboxOverlayStacking.key(OverlayKind.Polyline),
)

// Add z-indexed polygon layers below general polylines
// Polygon z-layers (polygon band: above ground images, below circles)
ensurePolygonZLayers(style)

// Marker + drag layers
Expand All @@ -76,14 +76,8 @@ internal fun MapboxMapViewController.ensurePolygonZLayers(style: com.mapbox.maps
toRemove.forEach { z ->
val fillId = "polygon-fill-layer-$z"
val outlineId = "polygon-outline-layer-$z"
try {
style.removeStyleLayer(outlineId)
} catch (_: Exception) {
}
try {
style.removeStyleLayer(fillId)
} catch (_: Exception) {
}
MapboxOverlayStacking.remove(holder.map, style, outlineId)
MapboxOverlayStacking.remove(holder.map, style, fillId)
}

val zList = zSet.toList().sorted()
Expand All @@ -108,11 +102,7 @@ internal fun MapboxMapViewController.ensurePolygonZLayers(style: com.mapbox.maps
.get("fillColor"),
)
}
try {
style.addLayerBelow(layer, anchorId)
} catch (_: Exception) {
style.addLayer(layer)
}
MapboxOverlayStacking.add(holder.map, style, layer, MapboxOverlayStacking.key(OverlayKind.Polygon, z))
}

// Outline layer above its fill
Expand All @@ -138,11 +128,8 @@ internal fun MapboxMapViewController.ensurePolygonZLayers(style: com.mapbox.maps
.get("strokeWidth"),
)
}
try {
style.addLayerAbove(layer, fillId)
} catch (_: Exception) {
style.addLayer(layer)
}
// 塗りの直後(同じ鍵なら後から入れたものが上)。
MapboxOverlayStacking.add(holder.map, style, layer, MapboxOverlayStacking.key(OverlayKind.Polygon, z))
}
}
// Update tracked set
Expand Down
86 changes: 86 additions & 0 deletions src/main/java/com/mapconductor/mapbox/MapboxOverlayStacking.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.mapconductor.mapbox

import android.util.Log
import com.mapbox.maps.MapboxMap
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.layers.Layer
import com.mapbox.maps.extension.style.layers.addLayer
import com.mapbox.maps.extension.style.layers.addLayerBelow
import com.mapconductor.core.controller.OverlayKind
import com.mapconductor.core.controller.OverlayLayerStack
import com.mapconductor.core.controller.OverlayStacking
import java.util.WeakHashMap

/**
* オーバーレイの層をスタイルのどこへ入れるか([OverlayStacking] の帯の順)。
*
* 下から: ラスター < GroundImage < ポリゴン < サークル < ポリライン < マーカー
* (マーカーのタイルはマーカーの帯の一番下、ドラッグ中の層は一番上)。
*
* 位置は毎回スタイルの今の並びから決めるので、追加した順・送り直し・
* スタイルの読み直し(デザイン変更)に左右されない。
*
* ラスターだけはベースマップのラベル(SDK の層でない最初の symbol 層)の下に入れる。
* それ以外の帯はラベルの上に乗る(従来どおり)。Standard スタイルのように
* ベースマップが import で、その層が `styleLayers` に出てこない場合は、
* ラスターも含めてベースマップ全体の上に乗る。
*/
internal object MapboxOverlayStacking {
private val stacks = WeakHashMap<MapboxMap, OverlayLayerStack>()

fun stackOf(map: MapboxMap): OverlayLayerStack = synchronized(stacks) { stacks.getOrPut(map) { OverlayLayerStack() } }

fun key(
kind: OverlayKind,
zIndex: Int = 0,
) = OverlayStacking.Key(kind, zIndex)

/** マーカーのタイル(ラスター): マーカーの帯の一番下。 */
val MARKER_TILE = key(OverlayKind.Marker, Int.MIN_VALUE)

/** ドラッグ中のマーカーの層: マーカーの帯の一番上。 */
val MARKER_DRAG = key(OverlayKind.Marker, Int.MAX_VALUE)

/** [layer] を [key] の位置へ足す。同じ id の層が既にあれば何もしない。 */
fun add(
map: MapboxMap,
style: Style,
layer: Layer,
key: OverlayStacking.Key,
) {
val stack = stackOf(map)
stack.put(layer.layerId, key)
if (style.styleLayerExists(layer.layerId)) return
val layers = style.styleLayers
val ids = layers.map { it.id }
var before = stack.beforeId(ids, key)
if (key.kind == OverlayKind.RasterLayer) {
val label = layers.firstOrNull { it.type == "symbol" && stack.keyOf(it.id) == null }?.id
if (label != null && (before == null || ids.indexOf(label) < ids.indexOf(before))) {
before = label
}
}
try {
if (before != null) style.addLayerBelow(layer, before) else style.addLayer(layer)
} catch (e: Exception) {
if (style.styleLayerExists(layer.layerId)) return
try {
style.addLayer(layer)
} catch (e2: Exception) {
Log.w("Mapbox", "Failed to add layer: ${layer.layerId} (${e2.message})")
}
}
}

fun remove(
map: MapboxMap,
style: Style?,
layerId: String,
) {
stackOf(map).remove(layerId)
try {
style?.removeStyleLayer(layerId)
} catch (_: Exception) {
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ package com.mapconductor.mapbox.groundimage
import com.mapbox.bindgen.DataRef
import com.mapbox.maps.Image
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.layers.addLayer
import com.mapbox.maps.extension.style.layers.addLayerBelow
import com.mapbox.maps.extension.style.layers.generated.rasterLayer
import com.mapbox.maps.extension.style.layers.properties.generated.Visibility
import com.mapbox.maps.extension.style.sources.addSource
import com.mapbox.maps.extension.style.sources.generated.imageSource
import com.mapbox.maps.extension.style.utils.TypeUtils
import com.mapconductor.core.controller.OverlayKind
import com.mapconductor.core.features.GeoRectBounds
import com.mapconductor.core.groundimage.AbstractGroundImageOverlayRenderer
import com.mapconductor.core.groundimage.GroundImageEntityInterface
import com.mapconductor.core.groundimage.GroundImageFingerPrint
import com.mapconductor.core.groundimage.GroundImageState
import com.mapconductor.mapbox.MapboxActualGroundImage
import com.mapconductor.mapbox.MapboxMapViewHolder
import com.mapconductor.mapbox.MapboxOverlayStacking
import java.nio.ByteBuffer
import android.annotation.SuppressLint
import android.graphics.Bitmap
Expand Down Expand Up @@ -134,25 +134,15 @@ class MapboxGroundImageOverlayRenderer(
Log.w("Mapbox", "Failed to add ground image source: ${e.message}")
}

try {
style.addLayerBelow(layer, BELOW_LAYER_ID)
} catch (_: Exception) {
try {
style.addLayer(layer)
} catch (e: Exception) {
Log.w("Mapbox", "Failed to add ground image layer: ${e.message}")
}
}
// GroundImage の帯(ラスターの上、ポリゴンの下)。送り直しても同じ位置。
MapboxOverlayStacking.add(holder.map, style, layer, MapboxOverlayStacking.key(OverlayKind.GroundImage))
}

private fun removeSourceAndLayerIfExists(
style: Style,
handle: MapboxGroundImageHandle,
) {
try {
style.removeStyleLayer(handle.layerId)
} catch (_: Exception) {
}
MapboxOverlayStacking.remove(holder.map, style, handle.layerId)
try {
style.removeStyleSource(handle.sourceId)
} catch (_: Exception) {
Expand Down Expand Up @@ -224,7 +214,6 @@ class MapboxGroundImageOverlayRenderer(
opacity = opacity,
)

companion object {
private const val BELOW_LAYER_ID = "polyline-layer"
}
// 公開 API(Companion)の互換のために残している。
companion object
}
Loading
Loading