スマホでは問題ないが、タブレットでは最初の画面では等高線が表示されるが、スクロールした場合、 次のメッセージを出してアプリが止まる。最初の表示の途中で落ちることもある。
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x58 in tid 13761
スマホの主メモリは 6GB であるが、タブレットは 4GB である。メモリ不足が原因かもしれない。
Map510 ではこのエラーは起きない。メモリ不足ではないだろう。
地図に上書きするのをやめて、等高線だけを描画した場合エラーは起きない。 問題は等高線表示にあるのではなく、Bitmap#copy で作成したビットマップに上書きするときに エラーが起きるようだ。
オプションを使って、読み込んだ時点で mutable な Bitmap とした。 これにより、
relationによるポリゴンは正規化していたが、単独wayによるものは正規化をしていなかった。
正規化により所望の描画結果となった。
これにより、すぐさま廃棄される OSMオブジェクトやノード座標値配列を大幅に減らせた。
例えば芦ノ湖の北東 polygon #786213267(natural=wood) が描画されない。
レコードは抽出されているが描画されないようだ。
閉ループであるが type=1 になっている。これを type=2 に変更することにより解決した。
見たところ、zoom 6 富士箱根伊豆国立公園の境界線で伊豆付近で長い直線が描画されている。 下はエラーの一つ、数値の異なるエラーもある。
以前の地図アプリでは伊豆付近は正常に描画されている。
zoom 7でも描画エラーがあるが、zoom 8以上ではない。
バイナリレコードは同じであるが、タイル座標に変換するため、交差点算出に使うデータは異なる。
このプログラムを始めて作った頃、似たような描画エラーがあったが、原因・対策は記憶がない。
OSM.getIntesection: S1=-0.027743 S2=0.027743 p1x=14.158438 p2x=12.544266 p1y=127.949944 p2y=128.483276
多角形のほんの少し内側の多角形を求めるために、隣り合う線分に平行な線分を求め、 その交点を算出している。
交点を間引いた段階では隣り合う線分が平行ということはないが、座標値列データを差分コード化するために ノードを挿入することがある。これにより、隣合う線分が平行になることがある。 整数化した座標を float型のタイル座標に変換することにより、微小な差が生まれることにより、 丁度平行な時と、少し平行からずれるときがあるだろう。 このため、zoom によって描画エラーが生じるケースとエラーが起きないケースがあるのであろうか?
二つの線分の座標を表示した。差分に特徴がある。元の多角形はどうだったのか?
今回のエラーとの関係は分からないが、部分的に幅の狭い部分があると、内側に描こうとする 多角形の辺同士が交わってしまうことがある。しかし、線は描けるので、エラーにはならないかもしれない。
線分の長さが非常に短い。低ズームではもっとノードを間引くべきかも。 しかし、低ズームは zoom 9~3 で使う。事前に zoom 9を考えて間引いている。zoom 3では間引きが少ない。 ただ、地図アプリでの間引きは、事前に wayオブジェクトで間引くより面倒である。 また、間引きにより交差が生まれる危険性もある。
S1=-0.008586 S2=0.008586 p0x=149.152313 p0y=127.302841 p1x=149.150955 p1y=127.312851 0.001358 -0.01001 p2x=150.835526 p2y=127.541397 p3x=150.836884 p3y=127.531387 -0.001358 0.01001 S1=-0.004614 S2=0.004614 p0x=269.276978 p0y=17.133081 p1x=269.280365 p1y=17.137323 p2x=270.608795 p2y=16.076509 p3x=270.605408 p3y=16.072268:
このエラー自体は無視して、p0x、p0y を交点座標とすれば実質的に問題はない。 描画がおかしくなるのは別の原因のようである。交点座標が p0x、p0y と大きく異なるときは p0x、p0y を交点座標とすれば実質的に問題はない。
当面はこれで対処する。より、大きな課題は、zoom 3~7といった低ズームでは ノード数が多すぎる無駄を減らすことである。この無駄が、パフォーマンスを損ねている。
座標計算のバグではなく、間引き等により、単純な閉ループでないことがあるのが原因であろう。
当初、低ズームでタイルのレンダリングに抽出されるレコードが40万を超え、 ガーベージコレクションが頻発した。 原因は、小さな森(natural=wood)が多かったことであった。境界ボックスが小さいものを 除外することにより、所望のパフォーマンスが得られるようになった。
低ズームは小数点以下5桁にしている。
やはり、高ズーム7桁、中ズーム6桁、低ズーム5桁としよう。
これまでよりレンダリング用ファイルのサイズが大きい分、レンダリングに時間がかかるが、 一度レンダリングしたら、次回はファイル読み込みで済むので、これでもいい。
低ズームは現状ではメモリ不足でアプリが落ちた。
中ズーム zoom 9分割で 599MB、最大が12.7MB となった。zoom 8では 570MB、最大が 61.4MBとなった。
低ズーム zoom 3分割で 240MB、最大が132MB となった。
低ズームではメモリ使用量が大きくなるが、タイル数は少ないし、更新はまれでよい。 しかし、ラインレコードについてだけでもノードの間引きが必要かも知れない。
ラインレコードの場合はタグで絞り込んだ。これで、zoom 8 分割で 717MBとなった。zoom 9分割では 747MB となった。
低ズームは zoom 3分割で 392MB となった。
中低ズームでは今はまだpointレコードを絞り込んでいない。
これまでは、更にノードの間引きと緯度・経度の精度を下げて、約300MB(zoom 9分割)としていた。
これで一度レンダリングしてみる。
殆どが建物であるが、小さな公園、学校、農地なども除外される。
zoom 8分割で 1.55GB となった。ハイズームの約半分である。
ファイルの出力先を間違えていた。
森林の描画も不完全である。parser にバグがあるのかもしれない。
道路一つ、森林リレーション一つといった小さいレコードでデバッグするのもいいかもしれない。
Encoder.java 境界ボックスの maxlat の算出バグがあった。この修正により、 道路描画は正しくなった。
確認は地図アプリの読み込みプログラムを修正してから行う。
まず、次のエラーが出た。
readAll /storage/36C5-1401/GIS/dat/lands-high6/56/25.dat 1228150 parseTgas: error 864720/864724 tags_length=11 864720/864724 length=11 type=2 osm_id=0 ikey=394 17_116353_51593
バグを一つつぶしたが、次のエラーが出た。
readAll /storage/36C5-1401/GIS/dat/lands-low0/0/0.dat 4631586 parseTgas: error 6447/3819443 tags_length=7625994
陸地ポリゴンについては、multipolygon についても正常動作を確認した。 一般のOSMバイナリレコードについては、中、低ズーム用ファイルはまだ作成していない。
一部の道路描画が欠けているが、その他はざっと見た範囲では問題ない。
陸地ポリゴンのファイル形式が前のままでは、プログラムが二重になるので、 形式を統一する。
point、lineは概ね描画できた。polygon/multipolygonは描画されない。
line/polygonの描画はできない。
Block は現時点ではこれまで通りであり、陸地の描画を確認した。
いずれ、LRUCache 管理に変更する。
等高線とデータ共有、当面 dem5a のみで表示
japan では、デバッグに時間がかかるので、 kanto のデータを使う。
node/wayだけでは zoom 12 が 642MB、zoom 8 が 47MB であった。
一部、relationデータを追加した。 zoom 12 が 647MB、zoom 8 が 53MB となった。
まだ、一部であるが、大幅なファイルサイズの増加はなかった。
現時点では、多くのバグが入りこんだと思われるので、描画で確認したい。
まず、relationは除外して、node と way によるレコードを作成した。
zoom 12 と 8 での分割とした。
zoom 12 に置く場合、重複が起きるとき、zoom 8 に置くと zoom 12 は 2.92GB、zoom 8 は 252MB となった。zoom 8 では重複がありうる。zoom 8 での最大は 27.8MB となった。
大きな問題はなく、すぐに、安定して動作するようになった。