From 1661e8112ac68108fa4ac7369fe2881ca42d3000 Mon Sep 17 00:00:00 2001 From: Masashi Katsumata Date: Sat, 7 Nov 2026 21:23:01 -0800 Subject: [PATCH 1/2] Interpolate the closing edge of geodesic polygons The geodesic ring was densified with createInterpolatePoints, which only interpolates between neighbouring points. Rings arrive open, so the closing edge (last vertex -> first) stayed a straight chord, and since the native Polygon draws fill and outline from the same points, both were straight there (Boston -> London -> Iceland: the Iceland -> Boston edge). Use android-sdk-core's densifyGeodesicRing. geodesic=false is unchanged. Requires the android-sdk-core release that adds densifyGeodesicRing. --- .../googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt b/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt index d579143..a423696 100644 --- a/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt @@ -6,12 +6,12 @@ import com.google.android.gms.maps.model.PolygonOptions import com.mapconductor.core.ResourceProvider import com.mapconductor.core.features.GeoPoint import com.mapconductor.core.features.GeoPointInterface +import com.mapconductor.core.geometry.densifyGeodesicRing import com.mapconductor.core.polygon.AbstractPolygonOverlayRenderer import com.mapconductor.core.polygon.PolygonEntityInterface import com.mapconductor.core.polygon.PolygonState import com.mapconductor.core.polygon.unionHoles import com.mapconductor.core.spherical.Planar -import com.mapconductor.core.spherical.WGS84Geodesic import com.mapconductor.googlemaps.AdaptiveInterpolation import com.mapconductor.googlemaps.GoogleMapActualPolygon import com.mapconductor.googlemaps.GoogleMapViewHolder @@ -42,7 +42,9 @@ internal class GoogleMapPolygonOverlayRenderer( val key = AdaptiveInterpolation.cacheKey(AdaptiveInterpolation.pointsHash(statePoints), maxSegmentLength) interpolationCache.get(key)?.let { return it } - val geoPoints = WGS84Geodesic.createInterpolatePoints(statePoints, maxSegmentLength = maxSegmentLength) + // リングの閉じる辺(末尾 → 先頭)も大圏で補間する。隣り合う点の間だけを補間すると、閉じる辺が + // 直線の弦になり、塗りも輪郭(同じネイティブポリゴンの stroke)もそこだけ直線になる。 + val geoPoints = densifyGeodesicRing(statePoints, maxSegmentLength = maxSegmentLength) val points = geoPoints.map { GeoPoint.from(it).toLatLng() } interpolationCache.put(key, points) return points From cd15df65db7db59650d354557540508fccbc1b57 Mon Sep 17 00:00:00 2001 From: Masashi Katsumata Date: Sat, 7 Nov 2026 23:25:57 -0800 Subject: [PATCH 2/2] Densify the closing edge of non-geodesic polygons too A geodesic=false ring went through Planar.createInterpolatePoints, which only interpolates between neighbouring points, so the closing edge (last vertex -> first) stayed one straight Web Mercator segment while the other edges - and polylines with geodesic=false - follow linear lat/lng interpolation. Use android-sdk-core's densifyPolygonRing for both modes (it replaces the unreleased densifyGeodesicRing). Requires the android-sdk-core release that adds densifyPolygonRing. --- .../polygon/GoogleMapPolygonOverlayRenderer.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt b/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt index a423696..c7bedf5 100644 --- a/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt +++ b/src/main/java/com/mapconductor/googlemaps/polygon/GoogleMapPolygonOverlayRenderer.kt @@ -6,12 +6,11 @@ import com.google.android.gms.maps.model.PolygonOptions import com.mapconductor.core.ResourceProvider import com.mapconductor.core.features.GeoPoint import com.mapconductor.core.features.GeoPointInterface -import com.mapconductor.core.geometry.densifyGeodesicRing +import com.mapconductor.core.geometry.densifyPolygonRing import com.mapconductor.core.polygon.AbstractPolygonOverlayRenderer import com.mapconductor.core.polygon.PolygonEntityInterface import com.mapconductor.core.polygon.PolygonState import com.mapconductor.core.polygon.unionHoles -import com.mapconductor.core.spherical.Planar import com.mapconductor.googlemaps.AdaptiveInterpolation import com.mapconductor.googlemaps.GoogleMapActualPolygon import com.mapconductor.googlemaps.GoogleMapViewHolder @@ -44,7 +43,7 @@ internal class GoogleMapPolygonOverlayRenderer( // リングの閉じる辺(末尾 → 先頭)も大圏で補間する。隣り合う点の間だけを補間すると、閉じる辺が // 直線の弦になり、塗りも輪郭(同じネイティブポリゴンの stroke)もそこだけ直線になる。 - val geoPoints = densifyGeodesicRing(statePoints, maxSegmentLength = maxSegmentLength) + val geoPoints = densifyPolygonRing(statePoints, geodesic = true, maxSegmentLength = maxSegmentLength) val points = geoPoints.map { GeoPoint.from(it).toLatLng() } interpolationCache.put(key, points) return points @@ -56,7 +55,9 @@ internal class GoogleMapPolygonOverlayRenderer( ): List = when (geodesic) { true -> geodesicPoints(statePoints) - false -> Planar.createInterpolatePoints(statePoints).map { GeoPoint.from(it).toLatLng() } + // geodesic=false も閉じる辺を緯度経度で線形補間する(輪郭のポリラインと同じ線。補間しないと + // 閉じる辺だけメルカトルの直線になる)。 + false -> densifyPolygonRing(statePoints, geodesic = false).map { GeoPoint.from(it).toLatLng() } } private fun toLatLngHoles(