diff --git a/api/android-for-mapbox.api b/api/android-for-mapbox.api index 86164e0..9092445 100644 --- a/api/android-for-mapbox.api +++ b/api/android-for-mapbox.api @@ -216,6 +216,7 @@ public final class com.mapconductor.mapbox.MapboxOverlayStacking { 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 getPOLYGON_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); @@ -424,6 +425,7 @@ public final class com.mapconductor.mapbox.polygon.MapboxPolygonController exten public com.mapconductor.mapbox.polygon.MapboxPolygonController(com.mapconductor.mapbox.polygon.MapboxPolygonCompositeRenderer); public com.mapconductor.mapbox.polygon.MapboxPolygonCompositeRenderer getRenderer(); public int getZIndex(); + public void destroy(); public com.mapconductor.core.polygon.PolygonOverlayRendererInterface getRenderer(); } public final class com.mapconductor.mapbox.polygon.MapboxPolygonLayer { diff --git a/src/main/java/com/mapconductor/mapbox/MapboxMapViewController.kt b/src/main/java/com/mapconductor/mapbox/MapboxMapViewController.kt index a3d6324..665a509 100644 --- a/src/main/java/com/mapconductor/mapbox/MapboxMapViewController.kt +++ b/src/main/java/com/mapconductor/mapbox/MapboxMapViewController.kt @@ -1,5 +1,8 @@ package com.mapconductor.mapbox +import com.mapconductor.core.polygon.POLYGON_TILE_LAYER_ID +import com.mapconductor.core.polygon.PolygonTiler +import com.mapconductor.core.polygon.polygonTileRasterLayerState import MapboxMapViewControllerInterface import com.mapbox.android.gestures.MoveGestureDetector import com.mapbox.geojson.Point @@ -116,6 +119,19 @@ class MapboxMapViewController internal constructor( markerTileLayers.forEach { entity -> rasterLayerController.removeById(entity.state.id) } } } + + // Many polygons are drawn as raster tiles, shown through the same RasterLayer + // controller as the marker tiles (upsert / removeById, never the app's layers). + polygonController.tiler = + PolygonTiler().apply { + onTemplate = { template, tileSize -> + if (template != null) { + rasterLayerController.upsert(polygonTileRasterLayerState(template, tileSize)) + } else { + rasterLayerController.removeById(POLYGON_TILE_LAYER_ID) + } + } + } } override fun moveCamera(position: MapCameraPosition) = handleMoveCamera(position) diff --git a/src/main/java/com/mapconductor/mapbox/MapboxOverlayStacking.kt b/src/main/java/com/mapconductor/mapbox/MapboxOverlayStacking.kt index 34757f5..855290f 100644 --- a/src/main/java/com/mapconductor/mapbox/MapboxOverlayStacking.kt +++ b/src/main/java/com/mapconductor/mapbox/MapboxOverlayStacking.kt @@ -15,7 +15,8 @@ import java.util.WeakHashMap * オーバーレイの層をスタイルのどこへ入れるか([OverlayStacking] の帯の順)。 * * 下から: ラスター < GroundImage < ポリゴン < サークル < ポリライン < マーカー - * (マーカーのタイルはマーカーの帯の一番下、ドラッグ中の層は一番上)。 + * (マーカーのタイルはマーカーの帯の一番下、ドラッグ中の層は一番上。 + * ポリゴンのタイルはポリゴンの帯の一番下)。 * * 位置は毎回スタイルの今の並びから決めるので、追加した順・送り直し・ * スタイルの読み直し(デザイン変更)に左右されない。 @@ -38,6 +39,9 @@ internal object MapboxOverlayStacking { /** マーカーのタイル(ラスター): マーカーの帯の一番下。 */ val MARKER_TILE = key(OverlayKind.Marker, Int.MIN_VALUE) + /** ポリゴンのタイル(ラスター): ポリゴンの帯の一番下。 */ + val POLYGON_TILE = key(OverlayKind.Polygon, Int.MIN_VALUE) + /** ドラッグ中のマーカーの層: マーカーの帯の一番上。 */ val MARKER_DRAG = key(OverlayKind.Marker, Int.MAX_VALUE) diff --git a/src/main/java/com/mapconductor/mapbox/polygon/MapboxPolygonOverlayRenderer.kt b/src/main/java/com/mapconductor/mapbox/polygon/MapboxPolygonOverlayRenderer.kt index 853670c..0d8c449 100644 --- a/src/main/java/com/mapconductor/mapbox/polygon/MapboxPolygonOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/mapbox/polygon/MapboxPolygonOverlayRenderer.kt @@ -62,13 +62,16 @@ class MapboxPolygonOverlayRenderer( return prev.polygon } + // Polygons drawn as tiles (PolygonController.tiler) stay in the manager, for + // taps, with no features: their entity's polygon is null. + @Suppress("USELESS_CAST") private fun getAllPolygonEntities(): List> = - polygonManager.allEntities() + polygonManager.allEntities().filter { (it.polygon as MapboxActualPolygon?) != null } private fun getRemainingPolygonEntities( removed: List>, ): List> { val removedIds = removed.mapTo(HashSet()) { it.state.id } - return polygonManager.allEntities().filter { it.state.id !in removedIds } + return getAllPolygonEntities().filter { it.state.id !in removedIds } } } diff --git a/src/main/java/com/mapconductor/mapbox/raster/MapboxRasterLayerOverlayRenderer.kt b/src/main/java/com/mapconductor/mapbox/raster/MapboxRasterLayerOverlayRenderer.kt index 9c36fdc..3700979 100644 --- a/src/main/java/com/mapconductor/mapbox/raster/MapboxRasterLayerOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/mapbox/raster/MapboxRasterLayerOverlayRenderer.kt @@ -4,6 +4,7 @@ import com.mapbox.maps.extension.style.layers.generated.rasterLayer import com.mapbox.maps.extension.style.sources.addSource import com.mapbox.maps.extension.style.sources.generated.rasterSource import com.mapconductor.core.controller.OverlayKind +import com.mapconductor.core.polygon.POLYGON_TILE_LAYER_ID import com.mapconductor.core.raster.RasterHeaderRuleSet import com.mapconductor.core.raster.RasterLayerEntityInterface import com.mapconductor.core.raster.RasterLayerOverlayRendererInterface @@ -25,6 +26,8 @@ class MapboxRasterLayerOverlayRenderer( private fun isMarkerTileRaster(state: RasterLayerState): Boolean = state.id.startsWith(MARKER_TILE_RASTER_ID_PREFIX) + private fun isPolygonTileRaster(state: RasterLayerState): Boolean = state.id == POLYGON_TILE_LAYER_ID + /** Mapbox Android はタイル要求を書き換える公開 API を持たない。 */ override suspend fun onAdd( data: List, @@ -162,7 +165,8 @@ class MapboxRasterLayerOverlayRenderer( /** * 帯の順([MapboxOverlayStacking])で足す。アプリのラスターはラスターの帯 - * (一番下、ベースマップのラベルの下)、マーカーのタイルはマーカーの帯の一番下。 + * (一番下、ベースマップのラベルの下)、マーカーのタイルはマーカーの帯の一番下、 + * ポリゴンのタイルはポリゴンの帯の一番下(画像になったポリゴンであって、地図の画像ではない)。 */ private fun addToStack( style: com.mapbox.maps.Style, @@ -172,6 +176,8 @@ class MapboxRasterLayerOverlayRenderer( val key = if (isMarkerTileRaster(state)) { MapboxOverlayStacking.MARKER_TILE + } else if (isPolygonTileRaster(state)) { + MapboxOverlayStacking.POLYGON_TILE } else { MapboxOverlayStacking.key(OverlayKind.RasterLayer, state.zIndex) } @@ -182,7 +188,7 @@ class MapboxRasterLayerOverlayRenderer( val ordered = stateById.values .asSequence() - .filter { !isMarkerTileRaster(it) } + .filter { !isMarkerTileRaster(it) && !isPolygonTileRaster(it) } .sortedBy { it.zIndex } .mapNotNull { state -> handleById[state.id]?.let { handle -> state to handle } } .toList()