Repository navigation
Densify the closing edge of polygon rings, geodesic or not - #29
Merged
Merged
Conversation
createInterpolatePoints only interpolates between neighbouring points, and polygon rings arrive open (last != first). The closing edge (last -> first) of a geodesic polygon was therefore never densified and was drawn as a straight chord, while the outline - which closes the ring and densifies it as a polyline - followed the great circle. Fill and outline disagreed on that edge (e.g. Boston -> London -> Iceland: the Iceland -> Boston edge's great circle passes 55.6N at 53.2W, the chord passes 51.6N there). Add densifyGeodesicRing, which closes the ring before densifying and keeps the input's open/closed shape, and use it for outer rings and holes in buildPolygonRings / buildUnwrappedPolygonRings and for the PolygonManager hit test (whose holes now follow the great circle too, as on Android and web). geodesic=false is unchanged. The public API only gains the new function. Same change as android-sdk-core and js-sdk-core.
The closing edge (last vertex -> first) of a geodesic=false polygon had the same gap: Planar.createInterpolatePoints also only interpolates between neighbouring points, so the fill's closing edge stayed a single straight Web Mercator chord, while the outline - which closes the ring and densifies it as a polyline - interpolated latitude/longitude linearly and bent slightly on screen. (Boston -> London -> Iceland: halfway along the Iceland -> Boston edge, the linear edge passes 53.2N, the chord 54.7N.) Generalise densifyGeodesicRing (unreleased) into densifyPolygonRing(_: geodesic:maxSegmentLength:), which closes the ring before densifying with WGS84Geodesic or Planar, and use it for every ring in buildPolygonRings / buildUnwrappedPolygonRings (like densifyAndNormalize, the linear case keeps its 10 km segments). The hit test keeps testing geodesic=false against the raw vertices: in the lat/lng plane that is the same line as the linear interpolation. Compared with develop the public API only gains densifyPolygonRing. Same change as android-sdk-core and js-sdk-core.
This was referenced Nov 8, 2026
Merged
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
なぜ
ポリゴンの点は開いたリング(末尾 ≠ 先頭)で渡されます。
WGS84Geodesic.createInterpolatePointsもPlanar.createInterpolatePointsも隣り合う点の間しか補間しないので、そのまま渡すと閉じる辺(末尾 → 先頭)だけが補間されず、描画側で閉じたときに 1 本の直線(弦)になっていました。一方、輪郭はリングを閉じてからポリラインとして密度化するので、閉じる辺も他の辺と同じ形になります。Boston (42.36N, 71.06W) → London (51.5N, 0.12W) → Iceland (64.1N, 21.9W) の三角形(閉じる辺は Iceland → Boston)での数値:
どの補間を正とするか(geodesic=false)
ポリラインの geodesic=false(全プロバイダで緯度経度の線形補間)と、既に閉じてから密度化している web の ArcGIS に合わせ、閉じる辺も含めて緯度経度で線形補間する方に統一しました。「密度化しない(メルカトルの直線)」に寄せると、ポリラインの false と形が変わり、ArcGIS・Cesium のように辺を測地線でつなぐ SDK では直線を表せないためです。
何を変えたか
densifyPolygonRing(_:geodesic:maxSegmentLength:)を追加しました。リングを閉じてから大圏(geodesic)または緯度経度の線形補間(false)で密度化し、入力が開いていれば開いたまま返します(閉じた入力は閉じたまま)。buildPolygonRings/buildUnwrappedPolygonRingsの外周・穴をすべてこれで密度化します(densifyAndNormalizeと同じく、線形補間は 10 km 刻みのまま)。共通パイプラインを使う MapLibre / Mapbox / Mappls / MapTiler / OpenMobileMaps はこの PR だけで直ります。PolygonManager.find(position:))も geodesic は閉じる辺を大圏で補間します。geodesic=false は従来どおり生の頂点を緯度経度平面で判定します(緯度経度の直線=線形補間と同じ線なので、点列を増やす必要がありません)。テストで固定しています。densifyPolygonRingの追加のみです。関連 PR(同じ修正の一式)
fix/geodesic-polygon-fillは次の 16 リポジトリにまたがります。1. core(3 本は互いに独立。先にマージ・公開してください)
core だけで直るプロバイダ(共通パイプライン
buildPolygonRings/buildUnwrappedPolygonRingsを使うもの)には PR がありません: Android の MapLibre / Mapbox / Mappls / MapTiler / Longdo / OpenMobileMaps、iOS の MapLibre / Mapbox / Mappls / MapTiler / OpenMobileMaps、web の MapLibre / Mapbox / Mappls / MapTiler / TomTom / Longdo / Leaflet / OpenLayers / Azure Maps / deck.gl / MapKit JS / ArcGIS。2. Android プロバイダ(android-sdk-core の公開後。
densifyPolygonRingを使うのでそれまでビルドできません。ArcGIS だけは core に依存しません)3. iOS プロバイダ(ios-sdk-core の公開後。ArcGIS だけは core に依存しません)
4. web プロバイダ(js-sdk-core の新しい版を npm に公開し、依存(今は
^0.3.1)を引き上げてから。npm の公開はまだ行いません)マージの順番: core 3 本 → core の公開 → Android / iOS プロバイダ → js-sdk-core の npm 公開と依存の引き上げ → web プロバイダ。
見た目が変わるもの: ArcGIS(Android / iOS)の geodesic=false の閉じる辺は、以前は補間されず ArcGIS が測地線として描いていましたが、他の辺と同じ緯度経度の線形補間になります(web の react-for-arcgis と同じ形で、3 プラットフォームがそろう方向。承認済み)。ほかのプロバイダも geodesic=false の閉じる辺がわずかに曲がるようになります。
検証
xcodebuild test -scheme mapconductor-core(iPhone 17 Pro シミュレータ、357 本すべて通過)。GeodesicPolygonRingTestsを追加: 閉じる辺の補間(true / false)、塗りが輪郭と同じ点列になること(unwrap 版・分割版・穴)、タップ判定(true は大圏、false は緯度経度の直線)、大圏の中点 55.6N と弦 51.6N。false の塗りの 2 本は false の修正前に落ちることを確かめました(点数 717 ≠ 1109)。タップ判定は穴も geodesic のときは大圏で補間するようになりました(Android / web と同じ)。true 側は前のコミットの修正前に落ちることを確かめています。scripts/api-surface.sh check ios-sdk-core(集約リポジトリ): 通過(追加のみ)。確認できていないもの
他の PR との関係
git merge-treeで衝突なし。