Skip to content

Interpolate the closing edge of polygons, geodesic or not - #18

Merged
wf9a5m75 merged 2 commits into
developfrom
fix/geodesic-polygon-fill
Nov 8, 2026
Merged

wf9a5m75 merged 2 commits into
developfrom
fix/geodesic-polygon-fill

Conversation

@wf9a5m75

@wf9a5m75 wf9a5m75 commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

なぜ

ポリゴンの点は開いたリング(末尾 ≠ 先頭)で渡されます。WGS84Geodesic.createInterpolatePoints も Planar.createInterpolatePoints も隣り合う点の間しか補間しないので、そのまま渡すと閉じる辺(末尾 → 先頭)だけが補間されず、描画側で閉じたときに 1 本の直線(弦)になっていました。一方、輪郭はリングを閉じてからポリラインとして密度化するので、閉じる辺も他の辺と同じ形になります。

Boston (42.36N, 71.06W) → London (51.5N, 0.12W) → Iceland (64.1N, 21.9W) の三角形(閉じる辺は Iceland → Boston)での数値:

  • geodesic=true: 大圏の中点は 55.6N / 53.2W。同じ経度で Web メルカトルの弦は 51.6N を通ります(約 4° のずれ)。MapLibre などでは「輪郭は曲線、塗りの一辺だけ直線」、Google のように塗りと輪郭を 1 つのネイティブポリゴンで描くプロバイダでは輪郭まで直線でした。
  • geodesic=false: 緯度経度の線形補間の中点は 53.2N / 46.5W、同じ経度で弦は 54.7N(約 1.4° のずれ)。ポリラインの geodesic=false は緯度経度の線形補間なので、輪郭はメルカトル上でわずかに曲がり、塗りの閉じる辺だけ直線でした。

どの補間を正とするか(geodesic=false)

プロバイダ 輪郭(false) 塗りの閉じる辺(false、修正前)
GL 系(MapLibre / Mapbox / Mappls / MapTiler / Longdo)・OMM ポリラインとして線形補間 補間なし(弦)
Google / MapKit / HERE iOS / Longdo iOS / web HERE 塗りと同じネイティブポリゴン 補間なし(弦)。他の辺は線形補間
HERE Android / TomTom(Android・iOS) 塗りと同じネイティブポリゴン 全辺が補間なし(生の頂点)
ArcGIS(web) 塗りと同じ 閉じてから線形補間(済)
Cesium GEODESIC のポリライン RHUMB の 1 本

ポリラインの geodesic=false(全プロバイダで緯度経度の線形補間)と、既に閉じてから密度化している web の ArcGIS に合わせ、閉じる辺も含めて緯度経度で線形補間する方に統一しました。「密度化しない(メルカトルの直線)」に寄せると、ポリラインの false と形が変わり、ArcGIS・Cesium のように辺を測地線でつなぐ SDK では直線を表せないためです。

何を変えたか

  • geodesic=false は生の頂点をそのまま渡していた(全辺がメルカトルの直線で、ポリラインの false や ios-for-here と形が違った)ので、geodesic / false とも android-sdk-core の densifyPolygonRing で閉じる辺まで密度化します。false は 10 km 刻み(ios-for-here・ポリラインと同じ)です。

関連 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 の閉じる辺がわずかに曲がるようになります。

検証

  • 集約ビルド(android-sdk)でコンパイル・apiCheck 通過。
  • 実機(Android タブレット)で三角形を geodesic=true / false で表示し、修正前後を比べました。false の塗りと輪郭が線形補間の滑らかな線になりました(修正前は頂点を直線で結んだ形)。

確認できていないもの

  • 世界マスク級の大きなポリゴンでの描画(特に TomTom の geodesic=false)は実機で確かめていません。
  • npm 公開前なので、web プロバイダは公開版の js-sdk-core では動きません(集約リポジトリ内でソースを差し替えて確認しました)。
  • HERE の geodesic=false が 10 km 刻みの点列になるので、大きなポリゴンでの描画負荷は増えます(ios-for-here と同じ水準)。

他の PR との関係

The geodesic ring was densified with createInterpolatePoints, which only
interpolates between neighbouring points, so the closing edge (last vertex
-> first) of a geodesic polygon was a straight chord in both fill and
outline. Use android-sdk-core's densifyGeodesicRing. geodesic=false is
unchanged.

Requires the android-sdk-core release that adds densifyGeodesicRing.
A geodesic=false polygon passed its raw vertices to HERE, so every edge
was a straight Web Mercator segment, unlike polylines with geodesic=false
(linear lat/lng interpolation), the other providers and ios-for-here.
Use android-sdk-core's densifyPolygonRing for both modes; it closes the
ring before densifying, so the closing edge (last vertex -> first) matches
the others (it replaces the unreleased densifyGeodesicRing).

Requires the android-sdk-core release that adds densifyPolygonRing.
@wf9a5m75
wf9a5m75 merged commit 4da7ca4 into develop Nov 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant