Skip to content

Show ground images on ArcGIS again, and keep rasters under them - #27

Merged
wf9a5m75 merged 2 commits into
developfrom
fix/arcgis-groundimage-raster
Nov 8, 2026
Merged

wf9a5m75 merged 2 commits into
developfrom
fix/arcgis-groundimage-raster

Conversation

@wf9a5m75

@wf9a5m75 wf9a5m75 commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

なぜ

ArcGIS で GroundImage が表示されていませんでした(3D・2D とも)。

いつから壊れたかを android-sdk の履歴で切り分けました。

  • 42bba2fc(1.3.0 のリリース準備、ArcGIS SDK を 200.7 → 300.1.0 に上げたコミット)から表示されなくなっています。 親の 67d81ec5(ArcGIS 200.7)では、3D の SceneView に University of Eswatini(当時は Newark)の画像が枠どおりに出ていました。42bba2fc では同じページで枠と角のマーカーだけが出て、画像は出ません(タブレット TB520FU で両方を組んで比較)。
  • Android の 2D(MapView)は、200.7 の時点でももともと表示されていませんでした。 今回の変更で 2D も表示されるようになります。

原因は GroundImage の WebTiledLayer に渡すレベルの梯子です。512px のタイルなのに、解像度を 256px 基準のまま刻んでいたため、level L のタイルが L-1 の広さを覆い、ArcGIS 300 は番号だけ 1 段深い (z, x, y) を要求していました(例: エスワティニ上空で z=15, x=9618。正しくは z=15 なら x=19235)。GroundImageTileProvider は URL が指すタイルを素直に描くので、どのタイルも画像の外になり、全面透明でした(端末から取得したタイルは 512x512・アルファ 0)。200.x の SceneView は自前の 256px 格子で (col, row) を数えていたので、この読み替えで合っていました。

ラスターレイヤーは d0f4819 で同じ問題を直していましたが、GroundImage は古い梯子のコピーを持ったまま残っていました。

何を変えたか

  1. GroundImage の梯子をタイルの一辺どおりに組む(5b3cc2d)。ラスターと GroundImage の解像度・縮尺を WebMercatorTileLevels の 1 か所から取るようにして、片方だけ直す状態に戻らないようにしました。
  2. 重なり順の表を同一性で引く(30fbf21)。GroundImage が表示されるようになって見えた問題です。3D で GroundImage を先に載せてからラスターを足すと、ラスターが GroundImage の上に積まれていました。ArcGISOverlayStacking が WeakHashMap<Layer, …> で帯の鍵を持っていて、ArcGIS の Layer は equals / hashCode を上書きしているため、直前に登録した層の鍵が引けないことがありました(ログでは同じ層が「鍵なし」になり、ラスターが一番上に足されていた)。弱参照で持ち、=== で引く表に替えました。

WebMercatorTileLevels と IdentityWeakTable は internal です。API ダンプには ArcGIS2DTiltEmulation と同じく載るので、ベースラインに追加しました(追加のみ)。

検証

  • 単体テスト: WebMercatorTileLevelsTest(512px の level が 256px の level+1 と同じ地面を覆うこと等)と IdentityWeakTableTest(鍵の hashCode が変わっても引けること等)を足しました。WebMercatorTileLevelsTest は、GroundImage が持っていた古い読み替え(512 のとき 256 基準)に戻すと 3 件中 2 件落ちます。testDebugUnitTest は全部通過。
  • apiCheck: 残る差分は develop に既にある ArcGISMarkerController のコンストラクタのずれ(今回とは無関係)だけです。
  • 実機(TB520FU、develop の他モジュールと組み合わせ):
    • GroundImage のサンプル: 3D・2D とも、画像が枠(SW/NE のマーカー)の中に正しい位置・大きさで出ます。
    • 重なり順の検証ページ(ラスター 0.85 の上にチェッカーの GroundImage、その上にポリゴン・サークル・ポリライン・マーカー): 下の帯から足した場合・上の帯から足した場合とも、3D・2D で「ラスター < GroundImage < ポリゴン < サークル < ポリライン」の順になります。直す前は、上の帯から足すと 3D で GroundImage がラスターの下に潜り、うっすら透けるだけでした。
    • ラスター・ポリゴン・マーカー・ヒートマップのページは直す前と同じ見た目です。

web について

web(react-for-arcgis)はこの PR では変更していません。最新の develop で example(examples/basic、API キーは .env から vite 経由で読み込み)を Playwright で開き、ArcGIS 2D・3D とも、ラスターレイヤー(GSI の陰影起伏図)と GroundImage(University of Eswatini の画像が枠どおり)が表示されることを確かめました。

確認できていないもの・残った課題

  • 重なり順の検証ページで、zIndex=1 のポリゴンを先に、zIndex=0 のポリゴンを後に足すと、Android の 3D・2D とも zIndex=1 が下になります(上の帯から足す順では正しい)。ポリゴンは GraphicsOverlay 側の問題で、この PR の変更とは関係しません。別に調べます。

関連 PR

それぞれ独立していて、マージの順番の制約はありません。

…r layer

GroundImage drew nothing on ArcGIS, in 3D and 2D. Its WebTiledLayer still
built the levels of detail on a 256 reference when handed 512-pixel tiles,
so level L covered the ground of level L-1 and ArcGIS asked for
"z=15, x=9618" over Eswatini, where z=15 is x=19235. The ground image tile
provider draws the tile the URL names, which is outside the image, so every
tile came back transparent (fetched from the device: 512x512, all alpha 0).

The raster layer stopped doing this in d0f4819, after ArcGIS 300 (the bump
to 300.1.0 in the 1.3.0 release) no longer needed the reading for SceneView.
The ground image kept its own copy of the old ladder. Both now take the
resolution and scale from one place, WebMercatorTileLevels, so the two
cannot drift again.

Measured on the TB520FU: the University of Eswatini image is back inside its
frame on ArcGIS 3D and 2D. Raster, polygon, marker and heatmap pages look the
same before and after. WebMercatorTileLevels is internal; the API dump lists it
like ArcGIS2DTiltEmulation, so it is added to the baseline (additions only).
On ArcGIS 3D a raster added after a ground image went on top of it: the
ground image's band key could not be found again (logged as "?" for the
very layer registered a moment earlier), so the raster's insertion point
was "none above" and it was appended. ArcGIS's Layer overrides equals and
hashCode, and a WeakHashMap keyed on it does not reliably find the same
layer again. The 2D map happened to work; the 3D one did not.

The stacking table now holds layers by weak reference and looks them up
with ===. It holds at most a few dozen entries, so a linear scan is fine.

Measured on the TB520FU (stack check page, raster at 0.85 opacity under a
checker ground image): before, in reverse order the checker showed only as
a faint tint through the raster on 3D; after, it sits above the raster in
both orders on 3D and 2D, under polygons, circles and polylines as before.
IdentityWeakTable is internal; the API dump lists it, so it is added to
the baseline (additions only).
@wf9a5m75
wf9a5m75 merged commit 9e9bd27 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