diff --git a/api/android-for-here.api b/api/android-for-here.api index e3ef70e..e2b5f04 100644 --- a/api/android-for-here.api +++ b/api/android-for-here.api @@ -192,6 +192,8 @@ public final class com.mapconductor.here.HereOverlayStacking { public final com.here.sdk.mapview.MapLayerPriority rasterPriority(); public final com.here.sdk.mapview.MapLayerPriority groundImagePriority(); public final com.here.sdk.mapview.MapLayerPriority polygonTilePriority(); + public final com.here.sdk.mapview.MapLayerPriority polygonTilePriority(java.lang.String); + public final com.here.sdk.mapview.MapLayerPriority polylineTilePriority(java.lang.String); } public final class com.mapconductor.here.HereTypeAliasKt { } diff --git a/src/main/java/com/mapconductor/here/HereMapViewController.kt b/src/main/java/com/mapconductor/here/HereMapViewController.kt index 3c18070..4f18cf1 100644 --- a/src/main/java/com/mapconductor/here/HereMapViewController.kt +++ b/src/main/java/com/mapconductor/here/HereMapViewController.kt @@ -32,7 +32,10 @@ import com.mapconductor.core.marker.StrategyMarkerController import com.mapconductor.core.marker.dispatchGeoMarkerClick import com.mapconductor.core.polygon.OnPolygonEventHandler import com.mapconductor.core.polyline.OnPolylineEventHandler +import com.mapconductor.core.polyline.POLYLINE_TILE_LAYER_ID import com.mapconductor.core.polyline.PolylineState +import com.mapconductor.core.polyline.PolylineTiler +import com.mapconductor.core.polyline.polylineTileRasterLayerState import com.mapconductor.here.circle.HereCircleController import com.mapconductor.here.groundimage.HereGroundImageController import com.mapconductor.here.marker.HereMarkerController @@ -185,6 +188,18 @@ class HereMapViewController( } } } + + // Many polylines too: the same raster layer path, in the polyline band. + polylineController.tiler = + PolylineTiler().apply { + onTemplate = { template, tileSize -> + if (template != null) { + rasterLayerController.upsert(polylineTileRasterLayerState(template, tileSize)) + } else { + rasterLayerController.removeById(POLYLINE_TILE_LAYER_ID) + } + } + } } override fun moveCamera(position: MapCameraPosition) = handleMoveCamera(position) diff --git a/src/main/java/com/mapconductor/here/HereOverlayStacking.kt b/src/main/java/com/mapconductor/here/HereOverlayStacking.kt index abb1a8b..571998b 100644 --- a/src/main/java/com/mapconductor/here/HereOverlayStacking.kt +++ b/src/main/java/com/mapconductor/here/HereOverlayStacking.kt @@ -33,7 +33,27 @@ internal object HereOverlayStacking { * ポリゴンのタイル(SDK が描くラスター): ポリゴンの帯の一番下。GroundImage のアンカー * "traffic_on_route" の直後(GroundImage より上、map item より下)。 */ - fun polygonTilePriority(): MapLayerPriority = MapLayerPriorityBuilder().renderedAfterLayer(GROUND_IMAGE_ANCHOR).build() + fun polygonTilePriority(): MapLayerPriority = polygonTilePriority(beforeLayer = null) + + /** [polygonTilePriority]; when the polyline tiles are already on the map, just below them ([beforeLayer]). */ + fun polygonTilePriority(beforeLayer: String?): MapLayerPriority = + if (beforeLayer != null) { + MapLayerPriorityBuilder().renderedBeforeLayer(beforeLayer).build() + } else { + MapLayerPriorityBuilder().renderedAfterLayer(GROUND_IMAGE_ANCHOR).build() + } + + /** + * ポリラインのタイル(SDK が描くラスター): ポリゴンのタイルの上([afterLayer]、無ければ + * GroundImage のアンカーの直後)、map item の下。 + * + * HERE の map item(ポリゴン・サークル・ポリライン)は 1 枚の層にまとめて描かれ、 + * MapLayer をサークルとポリラインの間に挟めない。map item の下に置くので、ネイティブの + * ポリゴン・サークルもこのタイルの上に来る(帯の決まりからの、HERE だけの差)。 + * マーカーとマーカーのタイルより下、ポリゴンのタイルより上は守る。 + */ + fun polylineTilePriority(afterLayer: String?): MapLayerPriority = + MapLayerPriorityBuilder().renderedAfterLayer(afterLayer ?: GROUND_IMAGE_ANCHOR).build() private const val RASTER_ANCHOR = "route" private const val GROUND_IMAGE_ANCHOR = "traffic_on_route" diff --git a/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt b/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt index 53638d3..99b0943 100644 --- a/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt @@ -14,6 +14,7 @@ import com.here.sdk.mapview.datasource.TileUrlProviderCallback import com.here.sdk.mapview.datasource.TileUrlProviderFactory import com.here.sdk.mapview.datasource.TilingScheme import com.mapconductor.core.polygon.POLYGON_TILE_LAYER_ID +import com.mapconductor.core.polyline.POLYLINE_TILE_LAYER_ID import com.mapconductor.core.raster.RasterLayerEntityInterface import com.mapconductor.core.raster.RasterLayerOverlayRendererInterface import com.mapconductor.core.raster.RasterLayerSource @@ -140,6 +141,7 @@ class HereRasterLayerOverlayRenderer( .forMap(holder.mapView.hereMap) .build() layer.setEnabled(state.visible) + if (isShapeTileLayer(state.id)) shapeTileLayers.add(state.id) HereRasterLayerHandle( dataSource = dataSource, layer = layer, @@ -155,20 +157,35 @@ class HereRasterLayerOverlayRenderer( } } + /** The SDK's shape tile layers on the map now (their ids), so each can be placed against the other. */ + private val shapeTileLayers = java.util.Collections.synchronizedSet(HashSet()) + /** * アプリのラスターはラスターの帯(GroundImage・map item の下)。マーカーのタイルは * マーカーの帯なので、ポリゴン等の map item より上(最後に描く)。ポリゴンのタイルは - * ポリゴンの帯の一番下(GroundImage の上、map item の下)。 + * ポリゴンの帯の一番下(GroundImage の上、map item の下)。ポリラインのタイルはその上 + * ([HereOverlayStacking.polylineTilePriority])。どちらも版が変わるたびに作り直すので、 + * もう片方があればそれを基準に置き、作った順に左右されないようにする。 */ private fun priorityFor(state: RasterLayerState): MapLayerPriority = if (state.id.startsWith("marker-tile-")) { MapLayerPriorityBuilder().renderedLast().build() } else if (state.id == POLYGON_TILE_LAYER_ID) { - HereOverlayStacking.polygonTilePriority() + HereOverlayStacking.polygonTilePriority( + beforeLayer = layerNameOf(POLYLINE_TILE_LAYER_ID).takeIf { POLYLINE_TILE_LAYER_ID in shapeTileLayers }, + ) + } else if (state.id == POLYLINE_TILE_LAYER_ID) { + HereOverlayStacking.polylineTilePriority( + afterLayer = layerNameOf(POLYGON_TILE_LAYER_ID).takeIf { POLYGON_TILE_LAYER_ID in shapeTileLayers }, + ) } else { HereOverlayStacking.rasterPriority() } + private fun layerNameOf(id: String) = "raster-layer-$id" + + private fun isShapeTileLayer(id: String) = id == POLYGON_TILE_LAYER_ID || id == POLYLINE_TILE_LAYER_ID + private fun updateLayer( handle: HereRasterLayerHandle, state: RasterLayerState, @@ -178,6 +195,7 @@ class HereRasterLayerOverlayRenderer( private fun removeLayer(entity: RasterLayerEntityInterface) { val handle = entity.layer + if (isShapeTileLayer(entity.state.id)) shapeTileLayers.remove(entity.state.id) handle.routeId?.let { tileServer.unregister(it) } handle.layer.destroy() handle.dataSource.destroy()