Skip to content

Add OverlayStacking: one bottom-to-top order for every overlay kind - #31

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 系でサークルがポリゴンの下になる、など)。

何を変えたか

  • OverlayStacking を足しました。帯の順と、ネイティブ API の種類ごとの道具を持ちます。
    • flatZIndex(): 種類をまたいで 1 つの数で比べる SDK(Google Maps)向け。帯ごとに区間を分け、zIndex がどんな Int でも帯をまたぎません。
    • insertBefore() / OverlayLayerStack: スタイルのレイヤー一覧を持つ SDK(MapLibre・Mapbox・Mappls など)向け。差し込む位置を毎回スタイルの今の一覧から求めるので、追加の順・送り直し・スタイルの読み直しに左右されません。
  • CircleController.zIndex を 3(ポリゴンと同じ)から 4 にしました。読む箇所はありませんが、帯の順と食い違わないように揃えています。
  • OverlayStackingTest: 帯の順、flatZIndex が帯をまたがないこと、insertBefore が追加の順に依らず同じ並びになることを固定しています。公開 API は追加のみ(apiCheck)。

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

プロバイダ 直す前 直した後
ArcGIS サークルがポリゴンの下。後から足したラスターが GroundImage を覆う 帯の順(マーカータイルは図形の下=制約)
Google Maps GroundOverlay の順不定。ラスターがポリライン・GroundImage を覆う。サークルがラスターより下 帯の順(flatZIndex)
HERE ラスター・GroundImage が図形の上。ポリゴンとサークルが同じ drawOrder 帯の順(ポリラインはポリゴンの下=制約)
Longdo 届いた順。送り直したラスターがすべてを覆う 帯の順
Mapbox サークル < ポリゴン < GroundImage。Standard でラスターが一番上 帯の順
MapLibre / Mappls サークル < ポリゴン < GroundImage。後から足したラスターが一番上 帯の順
MapTiler 追加の順。スタイル読み直し後は reapply の順 帯の順(ラスターはラベルの上=制約)
OpenMobileMaps ラスターと GroundImage が追加の順。マーカータイルがポリゴンの下 帯の順(帯の中の zIndex は効かない=制約)
TomTom ラスターがポリゴン・ポリライン・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 任せ。

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

今のままにしています。MapLibre・Mapbox・Mappls・Longdo はラスターをベースマップの最初のラベルの下、ほかのオーバーレイはラベルの上です。Mapbox Standard はベースマップが import なので POI などのラベルは図形の上に出ます。Google はラベルを図形の上に描きます。MapTiler はベースマップのレイヤー一覧が取れないので、ラスターもラベルの上です(制約)。

検証

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

  • 親ビルドと各 submodule の単体ビルドで、コンパイルと単体テストが通りました(OverlayStackingTest を含む。落ちたのは develop でも落ちる 2 つだけ)。apiCheck: この PR の .api の差分は追加のみ。
  • maplibre / mappls / mapbox は develop の refactor/polygon-controller を受けたので、載せ直す前の commit との range-diff を確かめました(差は名前の付け替えだけで、ポリゴンの z レイヤーの追加・削除は *OverlayStacking を通っています。stacking の外で addLayer* を呼ぶ箇所はありません)。
  • タブレット実機(develop + fix/clear-strategy + この PR 一式 + MapTiler の restore を合わせた APK)で、普通に追加・逆の順・clearOverlays → 送り直し・デザイン変更 を撮り直しました。
    • MapLibre・Mapbox・Mappls・MapTiler・Google・TomTom・Longdo: 下から ラスター < GroundImage < ポリゴン(z0 < z1)< サークル < ポリライン < マーカー。
    • HERE: ポリラインがポリゴン・サークルの下(制約)。ほかは帯の順。
    • OMM: 帯の中の zIndex が効かない(制約)。ほかは帯の順。
    • ArcGIS 2D: 順は正しい(GroundImage が出ない別件あり。別の担当が調査中)。

確認できていないもの

  • ArcGIS 3D: 実機で逆の順に足している途中にアプリが前面から消え、その後タブレットが adb から外れたため、原因を取れていません(載せ直す前は最後まで動いていました)。ArcGIS の 2 つの PR は、これを確かめるまで draft にしています。
  • Mappls・Longdo はデザイン変更の後に図形が消えます。develop でも直す前でも同じで、この PR とは無関係の既存の問題です。
  • apiCheck は arcgis / mapbox / maplibre / mappls / omm で、develop でも同じ内容で落ちます(develop の .api の取り残し)。
  • CI: プロバイダの CI は core の同名ブランチを clone して組むので、core 未マージでも通っています(初回の gradle ダウンロードのタイムアウトは再実行で解消)。

関連 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 はそれまで保留です)。

The user decided one stacking order for every provider on every
platform, bottom to top: raster layers < ground images < polygons
(native and polygon tiles) < circles < polylines < markers (native and
marker tiles). zIndex orders within a band; equal keys keep the order
they were handed over in. Providers had drifted (TomTom rasters on top
of polygons, ground images jumping above polygons after a re-send,
circles under polygons on GL providers and ArcGIS).

OverlayStacking carries the band order and two tools, one per kind of
native API: flatZIndex() for SDKs that compare one number across kinds
(Google Maps), and insertBefore()/OverlayLayerStack for SDKs that keep
an ordered list of style layers (MapLibre, Mapbox, Mappls). The layer
position is computed from the style's current list each time, so it
does not depend on add order, re-sends or style reloads.

CircleController.zIndex goes from 3 (same as polygons) to 4. Nothing
reads the controller zIndex; it is aligned with the band order so it
does not say otherwise.

OverlayStackingTest pins the band order, that flatZIndex never crosses
a band for any Int zIndex, and that insertBefore produces the same
order whatever order layers are added in. Public API: additions only.
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