diff --git a/api/android-for-here.api b/api/android-for-here.api index ecca64e..bca3220 100644 --- a/api/android-for-here.api +++ b/api/android-for-here.api @@ -184,6 +184,14 @@ public final class com.mapconductor.here.HereMapViewSaver extends com.mapconduct public com.mapconductor.core.map.MapViewStateInterface createState(java.lang.String, android.os.Bundle, com.mapconductor.core.map.MapCameraPosition); public java.lang.String getStateId(com.mapconductor.core.map.MapViewStateInterface); } +public final class com.mapconductor.here.HereOverlayStacking { + public static final com.mapconductor.here.HereOverlayStacking INSTANCE; + public final int polygonDrawOrder(int); + public final int circleDrawOrder(int); + public final int polylineDrawOrder(int); + public final com.here.sdk.mapview.MapLayerPriority rasterPriority(); + public final com.here.sdk.mapview.MapLayerPriority groundImagePriority(); +} public final class com.mapconductor.here.HereTypeAliasKt { } public final class com.mapconductor.here.HereViewControllerStoreKt { diff --git a/src/main/java/com/mapconductor/here/HereOverlayStacking.kt b/src/main/java/com/mapconductor/here/HereOverlayStacking.kt new file mode 100644 index 0000000..83f5257 --- /dev/null +++ b/src/main/java/com/mapconductor/here/HereOverlayStacking.kt @@ -0,0 +1,34 @@ +package com.mapconductor.here + +import com.here.sdk.mapview.MapLayerPriority +import com.here.sdk.mapview.MapLayerPriorityBuilder + +/** + * 重なり順(ラスター < GroundImage < ポリゴン < サークル < ポリライン < マーカー)。 + * + * HERE では: + * - ポリゴン・サークル・ポリラインは map item で、`drawOrder` を 1 本の数で比べる。 + * 帯ごとに区間を分けて割り当てる(帯の中は zIndex の順)。 + * - ラスターと GroundImage は MapLayer。既定の優先度だと map item より上に描かれて + * ポリゴン等を覆うので、ベースマップのレイヤー(ルートの手前)に入れる。 + * ラスター → GroundImage の順になるよう、別々のレイヤーの手前を指定する。 + * - マーカーは map item の上に描かれる(drawOrder はマーカーどうしの順)。 + */ +internal object HereOverlayStacking { + private const val BAND = 340 + + fun polygonDrawOrder(zIndex: Int): Int = zIndex.coerceIn(0, BAND - 1) + + fun circleDrawOrder(zIndex: Int): Int = BAND + zIndex.coerceIn(0, BAND - 1) + + fun polylineDrawOrder(zIndex: Int): Int = 2 * BAND + zIndex.coerceIn(0, 1023 - 2 * BAND) + + /** ラスター: ベースマップの "route" レイヤーの手前(GroundImage より下)。 */ + fun rasterPriority(): MapLayerPriority = MapLayerPriorityBuilder().renderedBeforeLayer(RASTER_ANCHOR).build() + + /** GroundImage: "traffic_on_route" レイヤーの手前(ラスターより上、map item より下)。 */ + fun groundImagePriority(): MapLayerPriority = MapLayerPriorityBuilder().renderedBeforeLayer(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/circle/HereCircleOverlayRenderer.kt b/src/main/java/com/mapconductor/here/circle/HereCircleOverlayRenderer.kt index 650c875..37c5811 100644 --- a/src/main/java/com/mapconductor/here/circle/HereCircleOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/here/circle/HereCircleOverlayRenderer.kt @@ -15,6 +15,7 @@ import com.mapconductor.core.features.normalize import com.mapconductor.core.geometry.circleToRing import com.mapconductor.core.geometry.closeRing import com.mapconductor.here.HereActualCircle +import com.mapconductor.here.HereOverlayStacking import com.mapconductor.here.HereViewHolder import com.mapconductor.here.toGeoCoordinates import kotlinx.coroutines.CoroutineScope @@ -36,7 +37,7 @@ class HereCircleOverlayRenderer( Color.valueOf(state.strokeColor.toArgb()), lineWidth, ).apply { - drawOrder = (state.zIndex ?: 0).coerceIn(0, 511) + drawOrder = HereOverlayStacking.circleDrawOrder(state.zIndex ?: 0) } coroutine.launch { holder.map.addMapPolygon(mapCircle) @@ -96,7 +97,7 @@ class HereCircleOverlayRenderer( ) } if (finger.zIndex != prevFinger.zIndex) { - current.circle.drawOrder = (current.state.zIndex ?: 0).coerceIn(0, 511) + current.circle.drawOrder = HereOverlayStacking.circleDrawOrder(current.state.zIndex ?: 0) } circle diff --git a/src/main/java/com/mapconductor/here/groundimage/HereGroundImageOverlayRenderer.kt b/src/main/java/com/mapconductor/here/groundimage/HereGroundImageOverlayRenderer.kt index 55f48f4..3783659 100644 --- a/src/main/java/com/mapconductor/here/groundimage/HereGroundImageOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/here/groundimage/HereGroundImageOverlayRenderer.kt @@ -12,6 +12,7 @@ import com.mapconductor.core.groundimage.GroundImageState import com.mapconductor.core.groundimage.GroundImageTileProvider import com.mapconductor.core.tileserver.LocalTileServer import com.mapconductor.here.HereActualGroundImage +import com.mapconductor.here.HereOverlayStacking import com.mapconductor.here.HereViewHolder import android.util.Log import kotlinx.coroutines.CoroutineScope @@ -136,6 +137,8 @@ class HereGroundImageOverlayRenderer( MapLayerBuilder() .withName(layerName) .withDataSource(config.name, MapContentType.RASTER_IMAGE) + // GroundImage の帯(ラスターの上、ポリゴン等の map item の下)。 + .withPriority(HereOverlayStacking.groundImagePriority()) .forMap(holder.mapView.hereMap) .build() HereGroundImageHandle( diff --git a/src/main/java/com/mapconductor/here/polygon/HerePolygonOverlayRenderer.kt b/src/main/java/com/mapconductor/here/polygon/HerePolygonOverlayRenderer.kt index adf1b56..1b602f3 100644 --- a/src/main/java/com/mapconductor/here/polygon/HerePolygonOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/here/polygon/HerePolygonOverlayRenderer.kt @@ -17,6 +17,7 @@ import com.mapconductor.core.polygon.PolygonState import com.mapconductor.core.polygon.splitPolygonWithHolesIntoSimpleRings import com.mapconductor.core.polygon.unionHoles import com.mapconductor.here.HereActualPolygon +import com.mapconductor.here.HereOverlayStacking import com.mapconductor.here.HereViewHolder import android.util.Log import kotlinx.coroutines.CoroutineScope @@ -145,7 +146,7 @@ class HerePolygonOverlayRenderer( } } if (finger.zIndex != prevFinger.zIndex) { - polygon.forEach { it.drawOrder = current.state.zIndex.coerceIn(0, 511) } + polygon.forEach { it.drawOrder = HereOverlayStacking.polygonDrawOrder(current.state.zIndex) } } polygon @@ -161,7 +162,7 @@ class HerePolygonOverlayRenderer( val strokeWidth = ResourceProvider.dpToPx(state.strokeWidth) val transparentFill = Color.valueOf(0f, 0f, 0f, 0f) val fillColor = Color.valueOf(state.fillColor.toArgb()) - val order = state.zIndex.coerceIn(0, 511) + val order = HereOverlayStacking.polygonDrawOrder(state.zIndex) buildList { // 塗り: 穴を持たないピース群へ分解し、1 ピース 1 枚で塗る。 @@ -231,7 +232,7 @@ class HerePolygonOverlayRenderer( Color.valueOf(state.fillColor.toArgb()), Color.valueOf(state.strokeColor.toArgb()), outlineWidth, - ).apply { drawOrder = state.zIndex.coerceIn(0, 511) } + ).apply { drawOrder = HereOverlayStacking.polygonDrawOrder(state.zIndex) } } private fun toRing( diff --git a/src/main/java/com/mapconductor/here/polyline/HerePolylineOverlayRenderer.kt b/src/main/java/com/mapconductor/here/polyline/HerePolylineOverlayRenderer.kt index 6bc12e1..df4398a 100644 --- a/src/main/java/com/mapconductor/here/polyline/HerePolylineOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/here/polyline/HerePolylineOverlayRenderer.kt @@ -16,6 +16,7 @@ import com.mapconductor.core.polyline.PolylineState import com.mapconductor.core.spherical.Planar import com.mapconductor.core.spherical.WGS84Geodesic import com.mapconductor.here.HereActualPolyline +import com.mapconductor.here.HereOverlayStacking import com.mapconductor.here.HereViewHolder import com.mapconductor.here.toGeoCoordinates import kotlinx.coroutines.CoroutineScope @@ -32,7 +33,7 @@ class HerePolylineOverlayRenderer( val representation = createRepresentation(state) val mapPolyline = MapPolyline(geoPolyline, representation).apply { - drawOrder = (state.zIndex + 512).coerceIn(512, 1023) + drawOrder = HereOverlayStacking.polylineDrawOrder(state.zIndex) } coroutine.launch { @@ -66,7 +67,7 @@ class HerePolylineOverlayRenderer( } if (finger.zIndex != prevFinger.zIndex) { - polyline.drawOrder = (current.state.zIndex + 512).coerceIn(512, 1023) + polyline.drawOrder = HereOverlayStacking.polylineDrawOrder(current.state.zIndex) needsReAdd = true } diff --git a/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt b/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt index f81b068..212000a 100644 --- a/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/here/raster/HereRasterLayerOverlayRenderer.kt @@ -3,6 +3,8 @@ package com.mapconductor.here.raster import com.here.sdk.mapview.MapContentType import com.here.sdk.mapview.MapLayer import com.here.sdk.mapview.MapLayerBuilder +import com.here.sdk.mapview.MapLayerPriority +import com.here.sdk.mapview.MapLayerPriorityBuilder import com.here.sdk.mapview.datasource.RasterDataSource import com.here.sdk.mapview.datasource.RasterDataSourceConfiguration import com.here.sdk.mapview.datasource.RasterTileSource @@ -19,6 +21,7 @@ import com.mapconductor.core.raster.TileScheme import com.mapconductor.core.tileserver.LocalTileServer import com.mapconductor.core.tileserver.TileProviderInterface import com.mapconductor.core.tileserver.TileRequest +import com.mapconductor.here.HereOverlayStacking import com.mapconductor.here.HereViewHolder import java.io.ByteArrayOutputStream import java.net.HttpURLConnection @@ -132,6 +135,7 @@ class HereRasterLayerOverlayRenderer( MapLayerBuilder() .withName(tileSpec.layerName) .withDataSource(tileSpec.sourceName, MapContentType.RASTER_IMAGE) + .withPriority(priorityFor(state)) .forMap(holder.mapView.hereMap) .build() layer.setEnabled(state.visible) @@ -150,6 +154,17 @@ class HereRasterLayerOverlayRenderer( } } + /** + * アプリのラスターはラスターの帯(GroundImage・map item の下)。マーカーのタイルは + * マーカーの帯なので、ポリゴン等の map item より上(最後に描く)。 + */ + private fun priorityFor(state: RasterLayerState): MapLayerPriority = + if (state.id.startsWith("marker-tile-")) { + MapLayerPriorityBuilder().renderedLast().build() + } else { + HereOverlayStacking.rasterPriority() + } + private fun updateLayer( handle: HereRasterLayerHandle, state: RasterLayerState,