From 66b8725af0f34684498a94cbea09d85e2822a625 Mon Sep 17 00:00:00 2001 From: Tobias Zwick Date: Fri, 30 Dec 2022 18:30:35 +0100 Subject: [PATCH] fix display of multipolygons (fixes #4689) --- .../components/GeometryMarkersMapComponent.kt | 43 +++++++------ .../main/map/tangram/TangramExtensions.kt | 62 ++++++++++--------- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/components/GeometryMarkersMapComponent.kt b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/components/GeometryMarkersMapComponent.kt index 5264ca4fc08..7a9d096c40a 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/components/GeometryMarkersMapComponent.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/components/GeometryMarkersMapComponent.kt @@ -3,8 +3,6 @@ package de.westnordost.streetcomplete.screens.main.map.components import android.content.res.Resources import android.graphics.drawable.BitmapDrawable import androidx.annotation.DrawableRes -import com.mapzen.tangram.geometry.Polygon -import com.mapzen.tangram.geometry.Polyline import de.westnordost.streetcomplete.data.osm.geometry.ElementGeometry import de.westnordost.streetcomplete.data.osm.geometry.ElementPointGeometry import de.westnordost.streetcomplete.data.osm.geometry.ElementPolygonsGeometry @@ -12,8 +10,9 @@ import de.westnordost.streetcomplete.data.osm.geometry.ElementPolylinesGeometry import de.westnordost.streetcomplete.data.osm.mapdata.LatLon import de.westnordost.streetcomplete.screens.main.map.tangram.KtMapController import de.westnordost.streetcomplete.screens.main.map.tangram.Marker -import de.westnordost.streetcomplete.screens.main.map.tangram.toLngLat +import de.westnordost.streetcomplete.screens.main.map.tangram.toTangramGeometry import de.westnordost.streetcomplete.util.ktx.getBitmapDrawable +import de.westnordost.streetcomplete.util.math.centerPointOfPolyline /** Manages putting some generic geometry markers with an optional drawable on the map. I.e. to * show the geometry of elements surrounding the selected quest */ @@ -90,31 +89,31 @@ class GeometryMarkersMapComponent(private val resources: Resources, private val // polygon / polylines marker(s) if (geometry is ElementPolygonsGeometry || geometry is ElementPolylinesGeometry) { - val positions = when (geometry) { - is ElementPolygonsGeometry -> geometry.polygons - is ElementPolylinesGeometry -> geometry.polylines - else -> throw IllegalStateException() - } if (geometry is ElementPolygonsGeometry) { - val marker = ctrl.addMarker() - marker.setStylingFromString(""" - { - style: 'geometry-polygons', - color: '$areaColor', - order: 2000, - collide: false + for (polygon in geometry.toTangramGeometry()) { + val marker = ctrl.addMarker() + marker.setStylingFromString(""" + { + style: 'geometry-polygons', + color: '$areaColor', + order: 2000, + collide: false + } + """.trimIndent()) + marker.setPolygon(polygon) + markers.add(marker) } - """.trimIndent()) - marker.setPolygon(Polygon( - positions.map { polygon -> polygon.map { it.toLngLat() } }, null - )) - markers.add(marker) } /* Polygons should be styled to have a more opaque outline. Due to a technical * limitation in tangram-es, these have to be actually two markers then. */ - for (polyline in positions) { + val polylines: ElementPolylinesGeometry = when (geometry) { + is ElementPolygonsGeometry -> ElementPolylinesGeometry(geometry.polygons, geometry.polygons.first().centerPointOfPolyline()) + is ElementPolylinesGeometry -> geometry + else -> throw IllegalStateException() + } + for (polyline in polylines.toTangramGeometry()) { val marker = ctrl.addMarker() marker.setStylingFromString(""" { @@ -127,7 +126,7 @@ class GeometryMarkersMapComponent(private val resources: Resources, private val join: round } """.trimIndent()) - marker.setPolyline(Polyline(polyline.map { it.toLngLat() }, null)) + marker.setPolyline(polyline) markers.add(marker) } } diff --git a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/TangramExtensions.kt b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/TangramExtensions.kt index 8662cbf8805..e85454245bf 100644 --- a/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/TangramExtensions.kt +++ b/app/src/main/java/de/westnordost/streetcomplete/screens/main/map/tangram/TangramExtensions.kt @@ -18,40 +18,46 @@ import de.westnordost.streetcomplete.util.math.isRingDefinedClockwise import de.westnordost.streetcomplete.util.math.measuredArea fun ElementGeometry.toTangramGeometry(properties: Map = emptyMap()): List = when (this) { - is ElementPolylinesGeometry -> { - polylines.map { polyline -> - Polyline(polyline.map { it.toLngLat() }, properties + ("type" to "line")) - } + is ElementPolylinesGeometry -> toTangramGeometry(properties) + is ElementPolygonsGeometry -> toTangramGeometry(properties) + is ElementPointGeometry -> toTangramGeometry(properties) +} + +fun ElementPointGeometry.toTangramGeometry(properties: Map = emptyMap()): List { + return listOf(Point(center.toLngLat(), properties + ("type" to "point"))) +} + +fun ElementPolylinesGeometry.toTangramGeometry(properties: Map = emptyMap()): List { + return polylines.map { polyline -> + Polyline(polyline.map { it.toLngLat() }, properties + ("type" to "line")) } - is ElementPolygonsGeometry -> { - val outerRings = mutableListOf>() - val innerRings = mutableListOf>() - if (polygons.size == 1) { - outerRings.add(polygons.first()) - } else { - polygons.forEach { - if (it.isRingDefinedClockwise()) innerRings.add(it) else outerRings.add(it) - } +} + +fun ElementPolygonsGeometry.toTangramGeometry(properties: Map = emptyMap()): List { + val outerRings = mutableListOf>() + val innerRings = mutableListOf>() + if (polygons.size == 1) { + outerRings.add(polygons.first()) + } else { + polygons.forEach { + if (it.isRingDefinedClockwise()) innerRings.add(it) else outerRings.add(it) } + } - // outerRings must be sorted size ascending to correctly handle outer rings within holes - // of larger polygons. - outerRings.sortBy { it.measuredArea() } + // outerRings must be sorted size ascending to correctly handle outer rings within holes + // of larger polygons. + outerRings.sortBy { it.measuredArea() } - outerRings.map { outerRing -> - val rings = mutableListOf>() - rings.add(outerRing.map { it.toLngLat() }) - for (innerRing in innerRings.toList()) { - if (innerRing[0].isInPolygon(outerRing)) { - innerRings.remove(innerRing) - rings.add(innerRing.map { it.toLngLat() }) - } + return outerRings.map { outerRing -> + val rings = mutableListOf>() + rings.add(outerRing.map { it.toLngLat() }) + for (innerRing in innerRings.toList()) { + if (innerRing[0].isInPolygon(outerRing)) { + innerRings.remove(innerRing) + rings.add(innerRing.map { it.toLngLat() }) } - Polygon(rings, properties + ("type" to "poly")) } - } - is ElementPointGeometry -> { - listOf(Point(center.toLngLat(), properties + ("type" to "point"))) + Polygon(rings, properties + ("type" to "poly")) } }