これまで、Updater で ストレージからの読み込みとレンダリング/ダウンロードを実行していた。 この場合、全てのスレッドが時間のかかるレンダリングに従事すると、ストレージにタイル画像が あっても、読み込み処理が行えなくなり、長時間表示されないタイルが生まれる。 Loader、Updater をタンデムにつなぐと優先的に Loaderスレッドが現存するタイルの表示を行う。
Loader は LIFOキュー、Updater は FIFOキュー動作をさせる。
Loaderはメモリ使用量が小さいので、スレッド数を8にした。プログラムは分かりやすくなり、 パフォーマンスも向上した。
旧地図アプリ(階層ディレクトリ)も動かしており、これによるメモリ使用量が大きい。当面、動かし続け、 不具合が出たとき削除する。そのときは大幅に使用率が下がる。
ZIPファイルからの画像データ読み出しでガーベージコレクション(GC)が増えたようだ。
バックグラウンドで動くが、やはり、表示が少し遅くなった気がする。しかし、大量のタイル画像を保存するためには、 階層ディレクトリでは対応できないのでやむ得ないだろう。
BitmapFactory.Optionsには色々ある。GCを減らす方法もあるかも知れない。無理はせず、時間をかけて調べてみよう。
例えば、 options.inBitmap = reuseBitmap; を使えば、Bitmap エリアは再利用できる。 デフォルトでは新たにエリアが使われるため、いずれはGCの対象になる。
しかし、GCを減らそうとするとプログラムが複雑になってくる。うかつに取り組んではならない。
Background young concurrent copying GC freed 5266KB AllocSpace bytes, 2(40KB) LOS objects, 3% free, 281MB/290MB, paused 327us,147us total 238.691ms
Background concurrent copying GC freed 52MB AllocSpace bytes, 24(70MB) LOS objects, 28% free, 235MB/331MB, paused 165us,36us total 998.699ms
Bitmap bmp = BitmapFactory.decodeStream(bis) では上書きできない。
Optionsをつかって mutable な Bitmap にした。 これで、等高線を上書きできた。
BitmapFactory.Options options = new BitmapFactory.Options(); options.inMutable = true; Bitmap bmp = BitmapFactory.decodeStream(bis, null, options);
まず、GSIから始めた。読み込み時間は階層ディレクトリよりも少しはかかるようになった感じがあるが、 気になるほどではない。
ORTについてもサポートした[Map67]。
OSMについてもサポートした[Map68]。
mutable については対応できていない可能性がある。
ZIPファイル(japan.zipやkanto,zip)とタイルファイルの更新時間を比較して、 前者の方が大きいときはタイル更新の候補とする。
低ズームなほど更新の必要性は低いので、これを考慮して実際に更新するかどうかを決めている。
地図アプリとしてはリードオンリーのファイルは適宜コンパクトにしたい。
多分、バス路線データ出力を TSV からOSMバイナリレコード形式に変更した際、 Parser.java にエラーが混入したものと推測される。 2, 3日前と比較すると high9 0.98GB -> 826MB、high12 4.64GB -> 4.62GB、mid9 635MB -> 571MB、 low3 635MB -> 571MB となった。恐らく、リレーション処理に誤りが混入したものと思われる。 誤って、何行か消してしまったのかも知れない。 まずは、Parser.java について、変更前と変更後をチェックしよう。
森林だけでなく、マルチポリゴンが全て消えているようだ。
datファイルの出力先を変更したが、リレーション処理結果についての出力先が変更されていなかった。
パソコン版ではないが、経験したことのないレンダリングエラーがある。 ひとつのタイルではなく、タイルをまたいでおり、しかも正方形エリアの表示がほぼかけている。
昨年12月中旬にOSMバイナリレコードに reversedフラグを追加したが、パソコン版では未対応である。
しかし、一部の natural=cliff のトゲの方向が逆になるだけで、本件のエラーとは無関係である。
PC版は主にOSMマッピングに使っているため、このエラーは当面差支えないので、 解決を急ぐ必要はない。
zoom 15以上で等高線描画をサポートした。
parseTgas: error 280484/280669 tags_length=1050 280484/280669 length=1050 type=1 osm_id=319532000 ikey=96 18_233361_102603 `?`?`??`??`??` parseTgas: error 615903/616088 tags_length=1050 615903/616088 length=1050 type=1 osm_id=1123063412 ikey=96 18_233363_102603 `?`?`??`??`??`
ikey=96 はOSMタグではなく、bus_route_id である。 bus_route_japan.tsv を更新していなかった。
highway trunk lanes 4 lanes:backward 2 lanes:forward 2 maxspeed 40 name 銀杏坂 name:en Ichozaka Avenue name:ja 銀杏坂 official_name 国道50号 official_name:en National Highway Route 50 official_name:ja 国道50号 ref 50 sidewalk separate surface asphalt turn:lanes:backward through|through|right
タイルキャッシュには登録されているようだ。
Tile.queRequest.offerFirst(tile); は他スレッドとぶつかりがあると待たずに false を返す。 待つためには putFirst とする必要がある。
昨日は日中に一度アプリがダウンした。
今朝はアプリが固まっていた。 これはLinkedBlockingDequeをタイムアウトで抜けるようにすれば解決するかも知れない。
対策は、1日~数日様子を見て同じ現象が起きたときに考える。
LinkedBlockingDequeに待ちがたまった状態になっている。仕様が理解できていないようだ。
しかし、10分ほどたっと所望の動作をするようになった。OSの設定か何かに時間がかかった のかもしれない。
まず、古いタイル画面を表示、一旦消して描画、新タイルを表示しているのではなかろうか? キャッシュから削除した状態での表示を止める必要がある。
ファイル更新後、再読み込みさせず、直接 cache にセットさせるとちらつきはおさまった。
Tile.cache.put(tile.key, tile);//Tile.cache.remove(tile.key); map.invalidate();
描画の最中にBitmap更新のために tile.bmp が消されるのかもしれない。 この間ロックしてみる。
synchronized (Tile.cache) { // 2026.2.16
drawBitmap(canvas, tile.bmp, PX * (tx - bx) - offX,
PX * (tile.y - by) - offY);
}
synchronized (Tile.cache) { // 2026.2.16
tile.bmp = loadBitmap(tile.path());
}
skia com.example.map D --- Failed to create image decoder with message 'incomplete input'
書き込まれたpngファイルには異常はない。
念のため、スマホを再起動したが、やはり、新規ファイルで起きた。
境界線は way で、名称は relation で描く。relation は RAdminに届いているが文字が 描画されない。
これを機会に描画方法を見直したい。
文字ごとならば次のようになる。
canvas.save() で現在の状態を保存。 canvas.rotate(角度, 中心X, 中心Y) でキャンバス自体を回転。 canvas.drawText() で文字を描画。 canvas.restore() で状態を元に戻す。
canvas.save();
// 回転角と回転の中心点を指定して回転する
canvas.rotate(180f, canvas.getWidth(), canvas.getHeight() / 2);
canvas.drawText("兵", canvas.getWidth(), canvas.getHeight() / 2 - paint.ascent() / 2 - paint.descent() / 2, paint);
canvas.restore();
しかし、文字列の場合、Path に沿う方が、角度計算も自動化され楽であろう。 少なくとも当面は、他の描画との重なりは考えなくてもいいだろう。
canvas.drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
hOffset: パスの開始点からの水平距離(文字の開始位置をずらす)
vOffset: パスからの垂直距離(パスの上下にテキストを配置)
大字、小字レベルではうまくいく。都道府県堺は巨大なポリゴンまたはマルチポリゴンであり、 各タイルには少なくとも一つは含まれる。 しかし、境界線がタイルを横切ることはまれであり、パスのセットや空描画は全て無駄になる。 したがって、境界線全体でパスを作るのではなく、横切る場合に限り、その部分だけをパスに登録するなど の工夫が必要になる。
工夫により、パフォーマンス上は問題なくなった。乱数で、なるべく名称が重ならないようにした。 いずれ、もう少し改善して、行政名での重なりはなくしたい。
急ぐ必要はないので、少しずつ改良していきたい。
シンプルなケースでは drawTextOnPath が簡単でいい。しかし、 OSM地図では、境界線がタイルを横切ることは稀であり、無駄を極力省くことが必要である。 また、境界線が極端に折れ曲がっているような位置には行政境界名をうまく描けない。
行政境界名の場合は縁取り文字でなくてもよいが、特に川名の場合には文字の色が水の色に近いため、 文字を白色で縁取ることが望まれる。理解する限りでは drawTextOnPath では縁取り文字を描画できない。
結局、煩雑ではあるが、これまでの描画を使い続けることにした。 あらかじめ、描画位置を決めておき、その部分だけのラインレコードをOSMバイナリレコードとして出力して おけば、レンダリング時間は短縮できるが、このような手を使わずに高速化できる方が望ましい。
wait/notify をやめて LinkedBlockingDeque に変えた。 これでアプリが止まることがなくなった。
行政境界線が正常に描画されるようになったので、OSMデータを更新した。
建物 27454756 / 全地物 46216883 = 59.4%
次の行政境界線(way id=1375320805)がなぜ描画されなくなったか調べよう。
relationのメンバーではあるが、wayレコードとしても出力され、境界線は、wayレコードで描画する仕組みである。
<way id="1375320805" visible="true" version="1" changeset="164593256" timestamp="2025-04-06T14:10:13Z" user="Rokomo35" uid="19071241"> <nd ref="6818087660"/> <nd ref="3405224735"/> <nd ref="12734117083"/> <tag k="admin_level" v="4"/> <tag k="boundary" v="administrative"/> <tag k="maritime" v="yes"/> </way>
この wayレコードは存在し、RAdminクラスの描画メソッドに届いている。
RAdmin 14_14557_6454 osm_id=1375320805, type=1, admin_level=4
次に osm.drawLine(canvas, r, paint4) をチェックする。
タイルサイズは 876x876 であるから、座標値に異常はない。 ノード数は差分を2バイトで表すために、ノード追加が起きたため増えたようで問題はない。
574.6582, 91.28107 527.336, 183.33154 480.01373, 275.38388 475.8404, 373.3639 471.66708, 471.3411
他の描画をやめて、白地図に行政境界線だけを描画する場合は正しく描画される。
例え、行政境界線描画を最後にしてもうまく行かない。
テーマパークや国立公園などの境界線(二重線)の描画をやめると、行政境界線が正常に描画されるようになった。
二重線描画を canvas.save()、canvas.restore() でくくることにより解決した。
relationメンバーの way に boundary=administrative や admin_level のタグ がなかった場合、親relation のタグが適用される。 複数の relation が親になる場合、最小のadmin_level(正の値)が適用される。
これまでのプログラムではこの処理を省いていた。 境界線が描画されなくなったことにこれが関与しているかもしれない。 別に原因があるかもしれないが、リレーション処理を見直そう。
Tag[] tags を HashMap<Key,Tag> tags に変更する。 この段階で生成されるOSMバイナリレコードファイルに変わりはないかを調べる。
パソコンのgisをコンパイルし直すと、全体のzipサイズが少し変わった。
元のディレクトリ毎のサイズは変わらない。 4ディレクトリの圧縮順序が変わると、圧縮ファイルのサイズは少し変わるようだ。
後 前
kanto-high9 343MB 343MB
kanto-high12 971MB 971MB
kanto-mid9 109MB 109MB
kanto-low3 12.2MB 12.2MB
全都道府県ではなく、描画される場所もある。全体としては描画されないものが多い。
OSMバイナリデータ全ファイルのzipのサイズは 昨年12月13日が 3,815MB に対して今回は 3,692MB と小さくなっている。
この間、プログラムは修正していないはずだが。もっと前の変更が関係しているのかもしれない。
関東地方のOSMデータをダウンロードして確かめよう。関東でも一部が描画され、大半が描画されなかった。
都道府県境界だけでなく、adminラインの殆どが描画されていない。しかし、所々に限り描画される。 タイル境界線で切れているため、OSMバイナリレコード自体には問題はないと思われる。
構成要素のway(type=1)はOSMバイナリデータにある。
Outer Polygonが複数の場合、Outer Polygon別のレコードに分けている。 内部に他県、他市の飛び地があれば Multipolygon(type=3)になる。そうでなければ Polygon(type=2)になる。
RAdminでチェックすると下記のレコードが存在した。しかし、一部のタイルに含まれるだけであり、 大抵のタイルのレンダリングにはこれらが全く含まれていないようだ。
RAdmin osm_id=-2679957, type=2, 千葉県 RAdmin osm_id=-2689487, type=3, 神奈川県 RAdmin osm_id=-2689476, type=3, 川崎市 RAdmin osm_id=-2689482, type=3, 横浜市 RAdmin osm_id=-2689481, type=2, 相模原市 RAdmin osm_id=-2689466, type=2, 緑区 RAdmin osm_id=-5301639, type=2, 八王子市 RAdmin osm_id=-5100276, type=2, 町田市 RAdmin osm_id=-1759474, type=2, 世田谷区 RAdmin osm_id=-2689451, type=2, 南区 RAdmin osm_id=-2689449, type=2, 中央区 RAdmin osm_id=-2689471, type=2, 青葉区 RAdmin osm_id=-2689461, type=2, 港北区 RAdmin osm_id=-2689474, type=3, 麻生区 RAdmin osm_id=-2689469, type=2, 都筑区
昨年12月半ばに reversedフラグを導入した。これが関係しているのだろうか?
中低ズームで boundary=administrative が出力されていないのではないか?
RAdmin 9_454_203 osm_id=269179477, type=1, admin_level=2, null RAdmin 9_454_203 osm_id=269179483, type=1, admin_level=2, null RAdmin 9_454_203 osm_id=355231075, type=1, admin_level=2, null RAdmin 9_454_203 osm_id=355233089, type=1, admin_level=2, null RAdmin 9_454_203 osm_id=262103468, type=1, admin_level=2, null RAdmin 9_454_202 osm_id=269179483, type=1, admin_level=2, null
二重線描画を canvas.save()、canvas.restore() でくくることにより解決した。
一斉に全タイル更新ではなく、確率的に更新を減らしたときは起こりにくい。
国土地理院地図はサーバーからのダウンロードであり、この現象は起きない。 OSMタイル更新処理はスレッドで行っているので、メインスレッドの負荷にはならないはずだが。
タイル更新時のロック(synchronized)が原因かもしれない。
メインスレッドの高負荷が関係しているかもしれない。
タイマー起動のスレッドによる監視がなくなった。今日の動作は問題なかったが、 1、2か月使ってみないと、これで問題ないかどうかは判断できない。
室内自転車を踏んでいたときの記録はあるが、午後の散歩の記録がない。
たまたま、GPS追跡はオフにしていたが、GPS追跡のオン・オフは地図画面表示だけに関するものであり、これをオフにしても GPSログファイルへの書き込みとデータベースへの登録は行うはず。前アプリではGBS追跡が行われていた。
原因は室内ではGBSをオフにして、動きを感知したときオンにしているが、このオンにする操作に問題があるようだ。
前アプリでは一つのServiceで GBSログとステップカウンタログの処理を行っていたが、 新アプリでは LocationService と WalkService に分けた。前者はフォアグラウンドサービスにしているが、 WalkServiceはそうしていない。メインActivityと同様にスリープしてしまうようだ。 そうすると、動きが検出できない。
まずは、まずは現状のLocationServiceとWalkServiceの動作を比較する。
スレッドはスリープさせられることがある。AI検索では 「バックグラウンドでの定期的・長期的な処理は WorkManager に任せる」、 「バックグラウンドで確実に処理を継続させたい場合は、Foreground Service の利用や、 WorkManager によるジョブのスケジューリングを検討するのが一般的です」となった。
WalkServiceをやめて、LocationServiceに一体化した方が簡単かもしれない。
Serviceは Activityと同じプロセスで動くので、重い仕事をさせてはならない。
テーマパーク(tourism=theme_park)等の境界線は見栄えのよい二重線で描画する。 C#では使いやすい関数があるが、Android Javaではこれまでは手の込んだ方法で二重線を描画していた。 しかし、Canvas#setClipPathメソッドを使えば簡単に二重線を引けることが分かった。
多少のバグが残っているようだが、概ね完成した。
キーボード表示のため、バス時刻表などとは異なる方法でポップアップしている。 バス時刻表などでは問題がないが、この新しい方法ではポップアップがメニュー操作やoutsideタッチで消える。
setOutsideTouchable(false);としているがダメ。
注意すればデータベースの編集には問題がないため、保留する。そのうち、解決策が見つかるだろう。
これまでの SQLiteデータベースの修正はパソコン経由のため手間がかかる。
とりあえず、万歩計データのUpdate は新アプリから直接実行できるようにする。
データベースは GIS/sqlite3/gis.db と Map/sqlite3/walklog.db の二つ。
update テーブル set 項目 = 値 where date = 日付
日中での shutdown にはこれでいいだろう。
データベースへの登録をやり直した。ORDER BY date DESCは正常に動作した。 データベース異常で地図アプリが動かなくならないようにしたい。
DB Browser で直近のデータが確認できない。ORDER BY date DESC がうまく動作しない。
来年、step by step でチェックしよう。
変換プログラムで db.close() が漏れていたのが原因かもしれない。
これまでと同じ形式での出力を完成した。
GBSログ表示は gbslogデータベースを使う。
インスタンスは自動生成される一つを共有する App app = new App(); としてはならない。 必ず、App app = (App) getApplication() とする。 Activity、Service からでないと App のインスタンスを得られない。
最初に walklog オフライン訂正した。
update walklog set steps=10198, cum_steps=83450 where date = 20251226; insert into walklog values(20251227,5511,88961);
地図に表示する今日の歩数およびリスト&グラフ(日別、月別、DBテーブル)が正常に動作することを確認した。
シャットダウン時の処理はもう少し見直したい。 また、シャットダウンさせると、現在使っている地図アプリでDBのオフライン修正が必要になる。 頻繁なテストが面倒であるため、この動作確認は新アプリの完成が近くなったときまで保留する。
冗長なレコードを除けばGPSログ全体をひとつのSQLiteデータベースとしても、 十分な速さで空間検索を行えることが分かった。これにより、過去のGPS軌跡表示が簡単になる。 新アプリの運用開始はもっと先でよいので、時間をかけて細部を詰めたい。
歩数計については、前システムから、SQLiteを使用しているが、項目を見直し、 シャットダウン対策をシンプルにしたい。
ここ1年強のデータを登録した。スマホでの2箇所での空間検索時間は「350行, 実行時間 19ミリ秒」、 「9862行, 実行時間 38ミリ秒」となった。
過去のGBSログ表示では、歩行は10秒間隔で十分であろう。 しかし、日別のログファイルをやめる場合には、現状のデータをそのまま年単位のデータベースとするのが 望ましい。空間検索用データベースは別途用意する。
項目は UNIXタイムを date(20251224)、time (102113) に分けた方がいいであろう。 インデックスは date だけに付与する。
実際上の空間検索では、日付 date だけを抽出する。そのあと、この日付ごとの全レコードを抽出して 地図に、GPS軌跡を表示する。
理想としては、現在のGBSログを一つの SQLite データベースにすることである。 可能かどうかはもう少し時間をかけて検討する。
前システムでは一体化していたサービスを二つに分けた。 分かりやすくなったが、WalkService から LocationService へ(またはその逆)のデータ引き渡しには 少し手間がいる。
停止からの起動では画面全体が一旦水色(海)になってから、所定の地図が表示されることがある。
activity_main.xmlにエラーがある。これが原因とは思えないがこのエラーをとろう。
zoom in/out ボタンのパラメータにそれぞれ一つずつのエラーがあるようだ。 そのほか com.example.map.Map にも一つのエラーがある。
エラーとは関係ないようだが、
<com.example.map.Map
android:id="@+id/map_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop = "50dp"/>
としていた最後の行が
tools:layout_editor_absoluteX="72dp"
tools:layout_editor_absoluteY="50dp"
に置き換わっていた。
アプリ起動には時間がかかる。水色になったので違和感を感じるようになったのかもしれない。 他のアプリでは真っ白な画面である。
最初の zoom、x、y が海になっており、そのあと、GPSの位置情報取得で、現在地に変わるのではなかろうか。 LocationService導入でどこかにミスが入り込んだのではなかろうか。
この予想は当たった。最初は onDraw 10-512-512 で、そのあと onDraw 10-908-403 に変わった。
最初に無効な移動を行っていた。実行条件を tracking から tracking & time > 0 に変更することにより解決した。
例えば余呉湖を取り巻く琵琶湖国定公園はハイズームでは交差のない閉ループであるが、 中低ズームで単純のノードを間引くと、自己交差が生まれる。 このため、多角形の少し内側の境界線を求めるときにエラーが起きる。
例えば、PostgreSQL/PostGIS では、自己交差が生じないように間引きを行うことができる。 たしか自己交差で生まれた小さい閉ループを切り取っているはずである。
しかし、自作地図ではPostgreSQL/PostGISを使わない。 似たことを自作プログラムで行うのは面倒である。
一番簡単なのは、中低ズームでは二重線の描画をやめて、単純な実線を引くことである。 例え自己交差があっても実線は問題なく描画できる。
境界内側の線を求めるのに失敗したときだけ内側の線を引くのをやめてみたが、 これではうまく行かなかった。
中低ズーム(zoom 13以下)では単純な実線にするのが一番簡単である。簡単な方法が見つからない限り、 こうしておく。
Windows Javaや C# の場合、二重線が簡単に描画できる。Android Javaのグラフィックスもそのうち 進歩する可能性もあるので、ここは無理はしない方が無難であろう。
国土地理院地図と同様に、低ズームほど更新確率を小さくした。 これまでの地図アプリとはかなり異なるため、しばらくは様子見としたい。
zoom 18を基準として、zoom が1小さくなるにつれて、更新確率を半減した。 これにより、更新による画面のちらつきは感じられなくなった。
gsiにあるタイルをosmにも含まれるように一括レンダリングを行った。
通常の地図表示では殆どのタイルが存在するため、表示は素早くなった。
スマホ gsi 1.85GB 62,584tiles スマホ osm 11.09GB 68,016tiles tablet gsi 1.88GB 63,536tiles tablet osm 4.56GB 66,060tiles
低中ズームタイルの更新は殆どいらない。
例えば、zoom 18以上は確率1.0、zoom 17は確率 1/2、zoom 16は確率 1/4、 zoom 15は確率 1/8、zoom 14は確率 1/16、zoom 13は確率 1/32、... という風に 低ズームほど更新確率を下げるのが望ましいであろう。 これによって、通常は、パフォーマンスを損なうことなく更新が行われるであろう。
画面表示範囲の全タイルを更新するモードも用意しておきたい。
Map の static 変数は使用するが、オブジェクトの変数は使わない。 バッググラウンド更新でも同じ renderメソッドを使う。
まず、保存されたタイルを表示する。 現時点では半年以上たっていたら、サーバーの更新時間をチェックして、更新されていた場合 ダウンロード更新する。更新されていなかった場合、保存タイルの時刻だけを更新しておく。 これにより、再び半年たったとき、更新処理を行う。
サーバー上のタイルの更新時間が変わっていても実際は中身は同じケースが多い。 同じでも、描画をしなおすと画面がちらつく。 したがって、バイナリチェックを行い、変化がない場合、更新時間の変更だけでもよい。 しかし、日常利用が OSM地図が中心のため、当面、この対策は保留する。
パフォーマンスについては5~10万タイルほどで判断する。
スマホ gsi 1.83GB 62,413tiles スマホ osm 1.09MB 5,110tiles tablet gsi 1.87GB 63,405tiles tablet osm 571MB 5,899tiles
画面からはずれたタイルは後回しでよい。
標準OSM地図は正しいので、データの誤りではない。閉ループでない場所は正しく描画されている。
全ての閉ループを機械的に並び替えているのが誤りである。 natural=wood のようなエリアタグの場合は閉ループにする必要があるが、natural=cliffのような ラインタグの場合は例え閉ループでも polygon(type=2) とはせず、line(type=1)とする。
以前はこのようにしていたと思うが、現時点のプログラムではこの例外処理が漏れているのであろう。
Parser.java の修正がいる。現在は、最初に polygon 扱いにしてからタグ処理をしている。 polygon処理の前にタグ処理を移す。natural=cliff、man_made=embankment などは閉ループであっても、type=1 とする。
地図表示システムも 閉ループを polygon扱いとしており、修正は簡単ではない。 反転したことをフラグで記憶しておく方法もある。時間をかけて対策を考える。
reversedフラグを導入した。Parser.javaでは、polygon を反転した場合、この reversed フラグをオンにしておく。 地図レンダリングアプリではこのフラグがオンのときは、180度回転したアイコンを並べて描画するように 変更した。 この方法では Parser.java、地図アプリとも修正はシンプルで済んだ。
tile.zoom が更新されていないようだ。例えば map.zoom = 16、tile.zoom = 15。
zoom 14 から、すばやく 15、16 と変えたとき、map.zoom = 16、tile.zoom = 15 が起きるので、 このことは異常ではない。zoom 16 のタイルが描画されないのは問題であるが、最近はこの現象はあまり経験して いないので、様子見とする。
気づいたのは山梨県と神奈川県の境界付近の一部だけ。まずは、その領域の osm_id を調べよう。
osm_idは 967900(relation: natural=wood, type=multipolygon) であることが分かった。
OSM Inspectorにより、outer polygon の一部の way の role が inner になっていた。 これを outer に訂正した。これによって、正しく描画された。
見たところ、ソーティングを忘れたわけではなさそう。
zorderの初期設定をコメントしていた。
マルチポリゴンが描画されていないようだ。
順に実装しており、マルチポリゴンの一部は未実装のため、コメントアウトしていた。 この関係を実装して解決した。