多少のバグが残っているようだが、概ね完成した。
キーボード表示のため、バス時刻表などとは異なる方法でポップアップしている。 バス時刻表などでは問題がないが、この新しい方法ではポップアップがメニュー操作や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の初期設定をコメントしていた。
マルチポリゴンが描画されていないようだ。
順に実装しており、マルチポリゴンの一部は未実装のため、コメントアウトしていた。 この関係を実装して解決した。