OSM地図について、レンダリングしてから一定日数たっている場合、 元の画像ファイルを表示した後、レンダリングを行い、完了後に再描画するようにした。
まず、国土地理院地図について、ダウンロードしてから一定日数たっている場合、 元の画像ファイルを表示した後、ダウンロードを行い、完了後に再描画するようにした。
万歩計の表やグラフを ListView で実装した。GridLayout よりも分かりやすくなった。 多分、GridView よりも楽であろう。
いくつかの記事を読むうちに徐々に理解が深まってきた。
GridView in Android with Example
ImageViewを使って、棒グラフを描くようにした。
全体としては、今回は GridLayoutを使ったが、GridViewの方が簡単かも知れない。 少し、使ってみてから、検討したい。
記事 [Android] GridView 作り方使い方 を見る限りでは、予想に反して、GridViewは簡単ではなさそう。別の記事も読んでみよう。
記事 Androidコンポーネント初級編#4 : GridViewの使いかた は、先の記事より分かりやすい。
今のところ、GridViewより GridLayoutの方が分かりやすいようである。
万歩計のグラフ見通しがついた。 タブレットでは月平均算出結果をリスト表示できるが、スマホではリスト表示が起きず、アプリが止まる。
なぜか、date = 0 という不正なレコードが挿入されていた。不正レコード挿入が日々起きるようならば 原因を調べる。
select date(日付), 歩数 from walk; INSERT INTO walk VALUES(date('now'), 1212); select julianday('2019-08-04 08:42:19') as julianday; select datetime('2019-08-04 08:42:19', 'unixepoch'); select date('2019-08-04 08:42:19', 'unixepoch'); select date(日付, 'unixepoch') from walk;
一点から8本の直線が放射線状にのびている。標準OSMにはないのでバグと思われる。
relation には無効な inner polygon があるが、これがエラー原因か。 しかし、このマルチポリゴンのレンダリングをやめると線も消えるので、マルチポリゴンのレンダリングが関係していることは 確かである。
しかし、JOSMでチェックした限りでは異常はないし、レンダリングも正しく行われている。
線は各inner polygon の始点に延びているようだ、ポリゴンの輪郭線描画のバグであろう。 仕様の変更にまだ対応していなかったようだ。以前は全ポリゴンのデータを一つの配列で管理していたが、今は、 ポリゴン毎の配列に変えている。
<relation id="13254789" visible="true" version="1" changeset="111587962" timestamp="2021-09-23T11:45:18Z" user="User7873" uid="12884565"> <member type="way" ref="977500619" role="outer"/> <member type="way" ref="986220706" role="inner"/> <member type="way" ref="986220707" role="inner"/> <member type="way" ref="983835596" role="inner"/> <member type="way" ref="983835597" role="inner"/> <member type="way" ref="977498407" role="inner"/> <member type="way" ref="977498409" role="inner"/> <member type="way" ref="983835594" role="inner"/> <member type="way" ref="983835593" role="inner"/> <member type="way" ref="983835595" role="inner"/> <tag k="bridge" v="yes"/> <tag k="highway" v="pedestrian"/> <tag k="layer" v="1"/> <tag k="type" v="multipolygon"/> </relation>
drawOuterPolygon に問題がある。 一部、修正漏れがあった。
今の所、エラーは中ズームで起きている。osm_id=588538421とかosm_id=509537067などで起きている。
Error OSM.getIntersection: osm_id=588538421 a1*b2=0.022148 a2*b1=0.022148 xA=92.611305 yA=341.722443 xB=92.480232 yB=341.553467 xC=89.951744 yC=343.514771 xD=90.082817 yD=343.683746 Error OSM.getIntersection: osm_id=588538421 a1*b2=0.022148 a2*b1=0.022148 xA=89.951744 yA=343.514771 xB=90.082817 yB=343.683746 xC=92.611305 yC=341.722443 xD=92.480232 yD=341.553467 Error OSM.getIntersection: osm_id=509537067 a1*b2=0.005972 a2*b1=0.005972 xA=248.401367 yA=29.941824 xB=248.499680 yB=30.002571 xC=250.181747 yC=27.280323 xD=250.083435 yD=27.219576 Error OSM.getIntersection: osm_id=509537067 a1*b2=0.005972 a2*b1=0.005972 xA=250.181747 yA=27.280323 xB=250.083435 yB=27.219576 xC=248.401367 yC=29.941824 xD=248.499680 yD=30.0025712
osm_id=588538421の場合、間引きにより、最早ポリゴンでもなくなっていた。 91.34706, 342.7031, 91.21599, 342.53412, 91.34706, 342.7031,
このようなレコードは予め削除すべきである。また、 間引きを境界ボックスに反映すべきかも知れない。
とりあえず、空間検索で除去した。
行政区域を二重境界線で示す方法では、16日の図にあるように、時々、余分な線が現れる。 ハイズームでは起きないが、ノードを間引いた中ズームで起きる。
そこで、塗りつぶしではどうか調べた。 右図は拡大図である。世田谷区の北西は入り組んでいる。間引きが関係するのかしないのか不明であるが、 中ズームでは、境界の内側に薄い太線を描くのに失敗する。 しかし、塗りつぶしは問題ない。
ただし、塗りつぶしの場合、何故か、2回以上塗りつぶしを実行することがある。 右図の下部の中央では、多分、2回塗りつぶしが起きている。
通常は2回以上同じレンダリングをしていても気が付かないが、透過率(α値)を小さくしているので、 重ね書きすればだんだん濃くなる。
急ぐ話ではないが、いずれ、原因を突き止めたい[解決]。
複数のスレッドで同じタイルの描画を行っていた。リクエスト処理で status を busy にすることにより、解決した。 修正前は通常のレンダリングでも無駄があった。今回の修正でこの無駄もなくなった。
これまで、レンダリングでは、マルチポリゴンの座標値データは全ポリゴンを一つの配列で管理 していたが、それぞれのポリゴンを独立した配列で管理するように変更した。
drawPolygon、drawLineなど影響範囲が大きいため、 バグフィックスに時間がかかると思うが、分かりやすくなる。 また、ノードの間引き処理が簡単になる。
修正箇所は多かったが、比較的短時間で修正できた。行政区域名の 描画位置ずれもなくなった。
「麻生区」が境界線から大きくずれている。「下麻生三丁目」もずれている。 道路名や川名と同じメソッドを使っている。
道路や川名でもずれがあるかもしれないが、あったとしてもまれであろう。 道路や川には急峻な変化は少ないが、行政境界線にはある。
全域を building=castle としていうことが原因とわかった。 building=* の面積が非常に大きい時は、色を薄く(透過に)する。
ノード数が10以上の polygon/multipolygon についてはレコードに wayarea を追加した。 10未満の場合、必要ならば、空間検索で算出する。
japan-high zoom 12 2.95GB、zoom 8 421MB、japan-mid9 417MB、 japan-low3 44.2MBから japan-high zoom 12 2.99GB、zoom 8 455MB、japan-mid9 415MB、 japan-low3 44.4MBになった。mid9 は前回の値が間違っていた。
全ファイルzipでは 2.27GB から 2.29GB に増加した。
個々の行政境界をそれぞれ独立したマルチポリゴンレコードとした場合、ファイルサイズがどの程度増加するかを 調べる。
japan-high zoom 12 2.95GB、zoom 8 351MB、japan-mid9 389MB、 japan-low3 44.1MB から japan-high zoom 12 2.95GB、zoom 8 421MB、japan-mid9 415MB、 japan-low3 44.2MB に増加した。
kanto.osmでは昨日のエラーは起きないので、まず、関東データでバス路線表示を確認する。
バス路線表示実装した。
バス路線は表示できるようになったが、広域森林(多分、マルチポリゴン)が描画されない。
japanでのエラーも関連があるかもしれない。
例えば、relation 12433480 が描画されない。outer、inner 各1つの簡単なマルチポリゴンである。
メンバーがHashMapに登録されていないのではないか。
バス路線の追加処理でバグが入り込んだ。修正で解決した。
バス路線データの出力が終わり、リレーションの後処理でエラーが起きた。
37400000: 1319709317 0 rels; 0 nodes, 0.0 MB; 677412 ways, 217.8 MB procRelation high 158185relations Exception in thread "main" java.lang.NullPointerException at Relation.concat(Relation.java:373) at Parser.procRelation(Parser.java:130) at Parser.parse(Parser.java:65) at Util.main(Util.java:56)
このエラーは解決した。バス路線データ追加によるファイルサイズの増加は微々たるものであった。 japan-high zoom 12 2.94GB、zoom 8 351MB が 2.95GB、351MB(同じ) となった。
スマホでは問題ないが、タブレットでは最初の画面では等高線が表示されるが、スクロールした場合、 次のメッセージを出してアプリが止まる。最初の表示の途中で落ちることもある。
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 となった。
大きな問題はなく、すぐに、安定して動作するようになった。