Skip to content

Add the shared overlay stacking order - #30

Open
wf9a5m75 wants to merge 1 commit into
developfrom
fix/overlay-stacking-order
Open

wf9a5m75 wants to merge 1 commit into
developfrom
fix/overlay-stacking-order

Conversation

@wf9a5m75

@wf9a5m75 wf9a5m75 commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

なぜ

利用者の決定で、すべてのプロバイダ・3 プラットフォームで、オーバーレイを下から次の順に重ねます。

  1. ラスターレイヤー(RasterLayerState)
  2. GroundImage
  3. ポリゴン(ネイティブのポリゴンと、ポリゴンのタイルレイヤーが同じ帯)
  4. サークル
  5. ポリライン
  6. マーカー(ネイティブのマーカーと、マーカーのタイルレイヤーが同じ帯)

追加した順・送り直した順(clearOverlays の後など)・デザイン変更の後に左右されません。帯の中は zIndex、同じ zIndex なら渡された順です。

プロバイダごとに重なり順がばらばらでした(TomTom のラスターがポリゴンを覆う、送り直した GroundImage がポリゴンより上に来る、GL 系でサークルがポリゴンの下になる、など)。

何を変えたか

  • OVERLAY_STACK_ORDER を足しました(全プロバイダが従う順)。
  • 2 種類の SDK 向けのヘルパー(どれも @internal。公開 API のスナップショットは export 名が増えるだけ):
    • overlayStackBeforeId(): レイヤー一覧を持つ SDK(MapLibre GL 系、Azure Maps、ArcGIS、HERE のレイヤー)向けの beforeId。
    • overlayStackZ(): 値で順を決める SDK(pane の z-index、deck.gl/OpenLayers の zIndex、Cesium の ground zIndex、Google の図形 zIndex)向けの帯ごとの数。zIndex は帯をまたがないよう丸めます。
  • CircleController.zIndex を 3(ポリゴンと同じ)から 4 にしました。
  • OverlayStacking.test.mjs: 7 種類のレイヤーの追加順 5040 通りすべてが同じ並びになること、帯の中は zIndex と渡した順、自分のでないレイヤーは飛ばすこと、帯が重ならないことを確かめます。

直す前と後(このプラットフォームのプロバイダ)

プロバイダ 直す前 直した後
MapLibre / Mapbox / MapTiler / Mappls / TomTom / Longdo サークルがポリゴンの下。送り直した GroundImage がポリゴン・ポリラインを覆う 帯の順
ArcGIS ラスターがマーカーまで覆う 帯の順
Azure Maps 種類の間は追加の順。ラスターが一番上 帯の順
Cesium サークルとポリゴンが同じ帯。GroundImage がポリゴンを覆う 帯の順(マーカータイルは imagery なので図形の下=制約)
deck.gl マーカータイルが図形の下 帯の順
Google Maps 同じ zIndex なら後から足した図形が上 帯の順
HERE GroundImage が図形を覆う。サークルとポリゴンが同じ帯 帯の順
Leaflet / OpenLayers 図形どうしが同じ帯。ラスターが GroundImage を越えうる。マーカータイルがラスターの帯 帯の順
MapKit JS 最後に足した種類が上 図形どうしは帯の順。GroundImage は制約で図形の上

SDK の制約で守れないもの

  • Android HERE: ポリラインはポリゴンの下に描かれます(DrawOrderType も試しましたが効果がありませんでした)。
  • iOS TomTom: annotation(ネイティブ図形)に描画順が無く、ポリラインがポリゴン類の下、ポリゴン類(ポリゴン・サークル・GroundImage)どうしは追加の順。
  • ArcGIS(Android / iOS / web 3D): GraphicsOverlay は常に operational layer の上に描かれるので、マーカータイル(operational layer)はポリゴンより下。
  • MapKit JS: GroundImage は図形の上(z-order の手段が無い)。
  • iOS Longdo: 変更なし(SDK に順を決める手段が無い)。
  • Android OpenMobileMaps / iOS OpenMobileMaps: ラスター帯の中の zIndex は効かない(入れ直すと描かれなくなるため既存のレイヤーを動かさない)。
  • Android MapTiler: ベースマップのレイヤー一覧が取れないので、ラスターはラベルの上。
  • Google Maps: 同じ zIndex どうしの順は SDK 任せ。

地図のラベルとの関係(今のまま)

今のままです。GL 系(MapLibre・Mapbox・MapTiler・Mappls・TomTom・Longdo)は、ラスターがベースマップのラベルの下、GroundImage・図形・マーカーはラベルの上(変更なし)。ラスターの帯を一番下にする決定とは矛盾しません(ラスターは自分の他のレイヤーより下で、かつラベルの下)。ラベルの扱いを変えるなら別の判断が必要です。

検証

2026-11-08 に develop(fix/mapview-teardown、fix/geodesic-polygon-fill、fix/clear-followups、refactor/polygon-controller などのマージ後)の上に載せ直してから確かめています。

  • 合成した react-sdk のツリーで、stacking だけの構成と develop + clear-strategy + stacking の構成の両方で、全パッケージのビルド・テスト・api-surface check が通りました(公開 API は export 名の追加のみ)。
  • OverlayStacking.test.mjs(追加順 5040 通り)、GL 系 6 本の OverlayStackOrder.test.mjs(120 通り・送り直し・スタイルの差し替え)が通ります。
  • 載せ直しで、GL 系 6 本の develop 由来のテスト test/PolygonController.test.mjs の偽の地図に getLayersOrder() を 1 行足しました(stacking は今のレイヤー順を読んで beforeId を決めるため。本物の地図にはある API で、テストの期待する並びは変えていません)。
  • Playwright で 15 プロバイダ・17 ルートを撮り直しました(普通に追加・逆の順・clearOverlays → 送り直し・デザイン変更)。ArcGIS 2D/3D・Google 3D・MapKit 以外は自動判定もすべて OK、画像でも下から ラスター < GroundImage < ポリゴン < サークル < ポリライン < マーカー でした。ArcGIS 2D/3D・Google 3D は探針が 3D の陰影や位置ずれで外れるだけで、画像では順が正しいことを見ています。

確認できていないもの

  • MapKit JS: GroundImage が図形の上に出て、ラスターは出ません(制約。直す前と同じ)。検証ページのマーカーも写りません(直す前から同じ、未解決)。
  • ArcGIS 2D はベースマップとラスターが出ない別件があります(別の担当が調査中)。
  • Cesium・OpenLayers・deck.gl は検証ページにデザインの候補が無く、「デザイン変更」の場面は実際には変わっていません。
  • web のプロバイダは js-sdk-core の新しい版が要ります(npm 公開と依存の引き上げ待ち)。

関連 PR(fix/overlay-stacking-order の一式)

マージの順番:

  1. fix/clear-strategy の一式(先に入れる想定。衝突はしないことを git merge-tree で確認済み)
  2. 各プラットフォームの core(android-sdk-core / ios-sdk-core / js-sdk-core)
  3. そのプラットフォームのプロバイダ(core の新しいヘルパーを使うので、core より先に入れるとビルドが通りません)
  • Android MapTiler は fix/maptiler-overlay-restore の上に載せています(同じ削除処理を両方が書き換えたため)。先に restore の PR(Remove style layers and sources by object so they can come back android-for-maptiler#17)を入れてください。
  • web はさらに js-sdk-core の npm 公開と、各 react-for-* の依存の引き上げが前提です(npm 公開はまだしない、という決定なので、web のプロバイダ PR はそれまで保留です)。

OVERLAY_STACK_ORDER is the order every provider stacks overlays in,
bottom to top: raster < ground image < polygon < circle < polyline <
marker. Polygon tiles share the polygon band and marker tiles the
marker band. zIndex orders within a band; equal zIndexes keep the order
they were handed over in. It does not depend on the order overlays were
added in, re-sent in after clearOverlays(), or put back in after a
design change.

Helpers for the two kinds of SDK the providers sit on:
- overlayStackBeforeId(): the beforeId for SDKs that keep an ordered
  layer list (MapLibre GL family, Azure Maps, ArcGIS, HERE layers).
- overlayStackZ(): a number per band for SDKs that order by a value
  (pane z-index, deck.gl/OpenLayers layer zIndex, Cesium ground zIndex,
  Google shape zIndex), with zIndex clamped so it cannot cross a band.

CircleController.zIndex is 4 (was 3, the same as polygons) to match.
All of it is @internal (driver implementation point); the public API
snapshot only gains the export names.

OverlayStacking.test.mjs: every insertion order of the seven layer
kinds (5040) ends in the same stack; zIndex and handed-over order inside
a band; layers that are not ours are skipped; bands never overlap.
This was referenced Nov 8, 2026
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