From ecd95c386e45e6848325aa891674da5c2b963392 Mon Sep 17 00:00:00 2001 From: Masashi Katsumata Date: Sat, 7 Nov 2026 05:40:54 -0800 Subject: [PATCH 1/2] Draw large polygon sets as raster tiles (PolygonTiler) The polygon controller gets a PolygonTiler, whose tiles are shown through the raster layer path the marker tiles use (upsert / removeById, outside the app's RasterLayer composition). Tiled polygons stay registered for taps and give the map SDK nothing. reapply skips tiled entities, which have no handle. A raster whose source changes is added again under new ids: MapTiler had not applied the removal yet, so the add failed with "Source already exists" and the layer disappeared -- after the first tap on a tiled polygon, here. --- .../maptiler/MapTilerMapViewController.kt | 16 ++++++++++++++++ .../polygon/MapTilerPolygonController.kt | 4 +++- .../MapTilerRasterLayerOverlayRenderer.kt | 19 +++++++++++++++---- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/mapconductor/maptiler/MapTilerMapViewController.kt b/src/main/java/com/mapconductor/maptiler/MapTilerMapViewController.kt index d983065..e8451bf 100644 --- a/src/main/java/com/mapconductor/maptiler/MapTilerMapViewController.kt +++ b/src/main/java/com/mapconductor/maptiler/MapTilerMapViewController.kt @@ -17,7 +17,10 @@ import com.mapconductor.core.marker.MarkerState import com.mapconductor.core.marker.MarkerTilingOptions import com.mapconductor.core.marker.OnMarkerEventHandler import com.mapconductor.core.polygon.OnPolygonEventHandler +import com.mapconductor.core.polygon.POLYGON_TILE_LAYER_ID import com.mapconductor.core.polygon.PolygonCapableInterface +import com.mapconductor.core.polygon.PolygonTiler +import com.mapconductor.core.polygon.polygonTileRasterLayerState import com.mapconductor.core.polyline.OnPolylineEventHandler import com.mapconductor.core.polyline.PolylineCapableInterface import com.mapconductor.core.polyline.PolylineState @@ -316,6 +319,19 @@ class MapTilerMapViewController( registerOverlayController(polygonController) registerOverlayController(circleController) registerOverlayController(groundImageController) + + // 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) + } + } + } // ホルダーの同期投影にカメラを供給する。ホルダーはコントローラより先に作られるので // ここで繋ぐ。これが無いと toScreenOffset が常に null を返し、InfoBubble と // マーカー追従が理由も出ずに落ちる(android-for-longdo と同じ)。 diff --git a/src/main/java/com/mapconductor/maptiler/polygon/MapTilerPolygonController.kt b/src/main/java/com/mapconductor/maptiler/polygon/MapTilerPolygonController.kt index 49a1e87..743d080 100644 --- a/src/main/java/com/mapconductor/maptiler/polygon/MapTilerPolygonController.kt +++ b/src/main/java/com/mapconductor/maptiler/polygon/MapTilerPolygonController.kt @@ -18,6 +18,8 @@ class MapTilerPolygonController( * 既知のポリゴンを再適用する(地図 `ready` 後の復元用)。 */ fun reapply() { - renderer.reapply(polygonManager.allEntities().map { it.polygon }) + // Polygons drawn as tiles (PolygonController.tiler) have no handle. + @Suppress("USELESS_CAST") + renderer.reapply(polygonManager.allEntities().mapNotNull { it.polygon as MapTilerPolygonHandle? }) } } diff --git a/src/main/java/com/mapconductor/maptiler/raster/MapTilerRasterLayerOverlayRenderer.kt b/src/main/java/com/mapconductor/maptiler/raster/MapTilerRasterLayerOverlayRenderer.kt index a21306f..2df9fb6 100644 --- a/src/main/java/com/mapconductor/maptiler/raster/MapTilerRasterLayerOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/maptiler/raster/MapTilerRasterLayerOverlayRenderer.kt @@ -52,7 +52,11 @@ class MapTilerRasterLayerOverlayRenderer( val next = params.current.state if (prev.state.source != next.source) { removeLayer(prev) - addLayer(next) + // Under new ids: the removal above is not applied before the + // add below, which then fails with "Source already exists" and + // leaves the layer gone. The marker and polygon tiles change + // source on every in-place change. + addLayer(next, generation = ++replacements) } else { updatePaint(prev.layer, next) prev.layer @@ -76,9 +80,16 @@ class MapTilerRasterLayerOverlayRenderer( } } - private fun addLayer(state: RasterLayerState): MapTilerRasterLayerHandle? { - val sourceId = "raster-source-${state.id}" - val layerId = "raster-layer-${state.id}" + /** Counts source replacements, so each one gets ids of its own. */ + private var replacements = 0 + + private fun addLayer( + state: RasterLayerState, + generation: Int = 0, + ): MapTilerRasterLayerHandle? { + val suffix = if (generation == 0) "" else "-$generation" + val sourceId = "raster-source-${state.id}$suffix" + val layerId = "raster-layer-${state.id}$suffix" val source = buildSource(sourceId, state.source) ?: return null val layer = From 08a16539dc4a90dd1246b83d33143a48d5e07ed8 Mon Sep 17 00:00:00 2001 From: Masashi Katsumata Date: Mon, 9 Nov 2026 06:55:03 -0800 Subject: [PATCH 2/2] Update the API baseline Additions only: the polygon tiles' stacking key, and declarations develop added without running apiDump (TILE_REFRESH_COALESCE, and on ArcGIS the marker controller's constructor that takes a boolean). --- api/android-for-maptiler.api | 1 + 1 file changed, 1 insertion(+) diff --git a/api/android-for-maptiler.api b/api/android-for-maptiler.api index 8cac437..fbed037 100644 --- a/api/android-for-maptiler.api +++ b/api/android-for-maptiler.api @@ -169,6 +169,7 @@ public final class com.mapconductor.maptiler.MapTilerOverlayStacking { public static final com.mapconductor.maptiler.MapTilerOverlayStacking INSTANCE; 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 void add(com.maptiler.maptilersdk.map.style.MTStyle, com.maptiler.maptilersdk.map.style.layer.MTLayer, com.mapconductor.core.controller.OverlayStacking$Key); public final void remove(com.maptiler.maptilersdk.map.style.MTStyle, java.lang.String); public final void onIdle(com.maptiler.maptilersdk.map.style.MTStyle);