Skip to content

Stack overlays by band with moveLayer - #16

Open
wf9a5m75 wants to merge 2 commits into
developfrom
fix/overlay-stacking-order
Open

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

何を変えたか

MTStyle.addLayer には beforeId が無く常に末尾に足すので、追加した順に積まれ、スタイルの読み直し後は reapply の順(ラスター・ポリライン・ポリゴン・サークル・GroundImage)でした。MapTilerOverlayStacking がスタイルごとに SDK のレイヤーの順を持ち、新しいレイヤーを鍵がより大きい SDK のレイヤーのうち一番下のものの下へ moveLayer します。reapply は記録を消してから帯の順に流します。SDK からベースマップのレイヤー一覧が取れないので、ラスターはベースマップ(ラベルを含む)の上になります。

この PR は fix/maptiler-overlay-restore(MTStyle の id の記録を消して外す)の上に載せています。 両方が 5 つのレンダラの削除処理を書き換えたためで、restore 側の removeLayerAndForget / removeSourceAndForget を残し、その前に MapTilerOverlayStacking.remove(...) を呼ぶ形にまとめました。restore の PR を先にマージしてください(この PR の差分には restore の commit も含まれて見えます)。

載せ直しで直したもの: 実機で、逆の順に足すとラスターが一番上に残り、zIndex 0 のポリゴンが zIndex 1 の上に来ていました(載せ直す前の撮影は WebView の描き直しが止まった古い画面で、確かめられていませんでした)。MTStyle.addLayer はすぐにはページへ届かず(画像ソース以外は isSourceLoaded の往復を待ち、ソースが読み込み前なら次の idle まで SDK の中で待つ)、直後の moveLayer が層より先に届いて何もしていなかったためです。足したあとの idle 2 回分、記録した並びを moveLayer で送り直す MapTilerOverlayStacking.onIdle() を足し、MapTilerMapView の ON_IDLE から(1 度メインへ戻してから)呼びます。直した後は実機で 4 場面とも帯の順でした。

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

今のままにしています。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 #17)を入れてください。
  • web はさらに js-sdk-core の npm 公開と、各 react-for-* の依存の引き上げが前提です(npm 公開はまだしない、という決定なので、web のプロバイダ PR はそれまで保留です)。

Overlays removed from a MapTiler map - a polygon, circle, raster layer,
ground image or polyline taken out of the composition, or everything after
clearOverlays() - did not come back when added again with the same id.
MTStyle remembers every source and layer it added, by id, and refuses to
add the same id again (SourceAlreadyExists / LayerAlreadyExists, which the
renderers caught and logged). removeSourceById / removeLayerById only
remove them from the page and leave that record behind; removeSource /
removeLayer clear it too.

Remove by object everywhere the renderers take a source or layer out,
falling back to the id when MTStyle has no record of it (its add records
asynchronously). The same applies to the background layer the vector-style
mutation target adds and removes. A raster layer whose source changes is
removed and re-added under the same ids, so that path was broken too.

MapTilerStyleRemovalTest drives a real MTStyle through a recording command
executor: removing by id leaves the id recorded; removing by object lets
the same id be added again.
MTStyle.addLayer has no beforeId and always appends, so overlays were
stacked in add order, and after a style reload in the reapply order
(raster, polyline, polygon, circle, ground image).

MapTilerOverlayStacking keeps the SDK layers' order per style and moves
each new layer below the lowest SDK layer with a higher key. Reapply now
runs in band order after resetting the record. The SDK cannot list the
basemap's layers, so rasters sit above the basemap including its labels.

MTStyle.addLayer does not reach the page right away: for anything but an
image source it first waits for an isSourceLoaded round trip, and if the
source is not loaded yet it holds the layer until the next idle. A
moveLayer sent right after addLayer then arrives before the layer and does
nothing (adding in reverse order left the raster on top, and a zIndex 0
polygon above a zIndex 1 one). So after an add, the recorded order is sent
again on the next two idle events (onIdle, from onEventTriggered; launched
once on the main dispatcher so it lands after the SDK flushes its queue).

Stacking order (all providers, all platforms), bottom to top: raster
layers < ground images < polygons < circles < polylines < markers.
Needs android-sdk-core with OverlayStacking (fix/overlay-stacking-order).
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