トップ地図アプリGIS > PC版地図アプリ 中間報告

PC版地図アプリ 中間報告

はじめに

主だったレンダリングは終わった。プログラム的にはC#の方が楽であるが、Android Javaへ反映するために、Java を選んだ。

Android Java と本家Javaでは、本家Javaの方が楽である。

下にスクリーンショットを示す。

スマホではタイルサイズは PC版(256x256画素)に比べて、縦横3倍の 768x768画素である。このため、小さな文字も極めて鮮明である。

地図アプリでは画面サイズは 1280x800で、地図部分では 1281x700 となった。タイトルとメニューの高さが合わせて100もあるとは 思えない。アスペクト比の関係で 1281x700 となったのかもしれない。

ディスプレイの解像度が 1280x800 だろうと思っていたが、パソコンの仕様によると、1920x1200 である。 下のスクリーンショットの画像サイズは 1920x1128 である。

ブラウザでみるページでは小さい文字もきれいである。Javaの場合、ひと昔前のパソコンが標準になっており、 1920x1200 を 1200x800 に変換してしまうのであろう。これにより、文字が汚くなるのであろう。

画面サイズをハードウェアに合わせて 1920x1200 とすれば、文字はもっときれいになるであろう。

PCの仕様

昨年末購入パソコンの仕様を以下に示す。

プロセッサー AMD RyzenTM 7 8840U (8 コア, 16 スレッド, NPU搭載) 1
オペレーティングシステム Windows 11 Home, 日本語 1
OS リカバリー オプションメディアなし 1
メモリー 16GB, 2x8GB, DDR5, 5600 MT/s 1
ストレージ 1TB M.2 PCIe NVMe SSD 1
グラフィックス AMD RadeonTM グラフィックス 1
ディスプレイ 14.0 インチ 16:10 FHD+ (1920 x 1200) 非光沢 非タッチ 250nits 広視野角 ディスプレイ
ComfortView 搭載 1
本体カラー カーボンブラック プラスチックシャーシ 1
ワイヤレス Realtek Wi-Fi 6 RTL8852BE, 2x2, 802.11ax, MU-MIMO, Bluetooth® ワイヤレス カード 1
キーボード Copilotキー搭載 カーボン ブラック 日本語 非バックライト キーボード 1
パームレスト カーボン ブラック 電源 ボタン 指紋認証リーダーなし 1
プライマリバッテリ4-セル バッテリー, 54WHr (内蔵) 1
アダプタ 65 Watt AC アダプタ 1
FGA モジュール Fixed Hardware Configuration 1
ワイヤレス ドライバ Realtek 8852BE ワイヤレス ドライバー

Javaでの画面サイズをハードウェアに合わせる

GraphicsDevice の解像度は 1920x1200x32bpp@60Hz であることが分かった。 しかし、ScreenSize は 1280x800 である。

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
System.out.println(gd.getDisplayMode());
System.out.println( Toolkit.getDefaultToolkit().getScreenSize() );

1920x1200x32bpp@60Hz
java.awt.Dimension[width=1280,height=800]

ScreenSize を 1920x1200 にできないかあれこれ試みたがうまくいかなかった。

JavaScriptによるテスト[2]

JavaScriptで調べてみた。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ディスプレイのサイズと色の情報</title>
</head>
<body>

<h1>ディスプレイのサイズと色の情報</h1>

<p id="msg">ディスプレイのサイズと色の情報を表示します</p>

<script>
let element = document.getElementById('msg');

let screenInfo = 
'availWidth:' + screen.availWidth + '<br>' +
'availHeight:' + screen.availHeight + '<br>' +
'Width:' + screen.width + '<br>' +
'Height:' + screen.height + '<br>' +
'ColorDepth:' + screen.colorDepth + '<br>' +
'PixelDepth:' + screen.pixelDepth;

element.insertAdjacentHTML('afterend', '<p>' + screenInfo + '</p>');
</script>

</body>
</html>

Java と同じくサイズは 1280x800 であった。しかし、スクショは 1902x1119 となった。

availWidth:1280
availHeight:752
Width:1280
Height:800
ColorDepth:24
PixelDepth:24

タイルサイズを 368x368画素としてレンダリングを行い、256x256画素に縮小して表示する

Javaのアプリでは画面サイズは 1280x800 であるが、実際のハードでは 1920x1200 である。 そこで、タイルサイズを 368x368画素としてレンダリングを行い、256x256画素に縮小して表示する。 プログラム上は縮小表示であるが、実際上は、縮小は起きないと想定される。

実際、地図の表示結果は下のようになり、文字も図形も以前より鮮明になった。

上下線道路およびタイルマージン

小さい文字も鮮明に表示されるようになった。

ほぼこれまで通りの表示を盛り込んだ。

道路番号について、上図(zoom 15)では、画面中央交差点近くの 187(号)が道路の中心からずれている。

zoom 18で見ると、ここは上下線が分かれている。zoom 15では上下線が近接しているため、一車線に見えるのは バグではない。番号がずれるのは、線分角度処理か何かのバグであろう。

画面中央を南北に走る196号線はちょうどタイル境界線に近い。このため、96、6 しか表示されないのは、 隣のタイルで道路番号の描画が行われなかったことによる。しかし、道路自体は描画されているので、 タイルマージン以外に原因があるかもしれない。

道路番号は繰り返し表示するため、短い線分やタイル境界では描画しないようにすることにより、上記の不完全描画を回避するようにした。

新たな異常発見[解決]

道路名が学校名などと同じ形で多数表示される場所がある。文字色は amenity と同じ色のようである。 zoom を変えても起きる。

別の場所ではこのような現象は現時点では見つかっていない。 Windows版やAndroid版ではこのような現象は経験していない。

4文字以上の場合、複数行に分割されているので、学校名などの描画に使うメソッドが使われているものと思われる。

学校名などの描画で ラインレコード除外をコメントアウトしていたことが原因であった。 なぜ、特定の地域だけで異常が起きたかは追及しなかった。

マージン不足か?

zoom17 で画面ほぼ中央の「双葉町立老人福祉センター」の文字が下のタイルで表示されないのはタイルマージン 不足であろうか?

しかし、zoom 18では4タイルをまたいで正しく表示されている。アイコンを座標データの中心に表示している。 中心点は下のタイルからかなり離れているが正しく表示されている。マージンは十分にあるが、別の事情で、zoom 17では 表示されない可能性が高い。

zoom 17で「双葉郵便局」が表示されないのは、先に描画された双葉町立老人福祉センターのアイコンに重なるからである。

標準OSM地図とは異なり、自作レンダラーでは、タイルマージンだけでなく、ブロックマージンも存在する。 タイルマージンの変更は簡単であるが、ブロックマージンの変更ではバイナリレコードファイルの作り直しが必要になる。

ブロック境界はこの場合、zoom 12のタイル境界に一致する。 エラーが起きている境界線はブロック境界線ではないことを確認した。

問題のレコードはポイントレコードである。ポイントレコードのタイルマージンは 200%という巨大な値に設定されている ことも確認した。

件のレコードの osm_id は 1655769866 である。下のタイル 17/115957/51611 でなぜレンダリングされなかったか を調べてみよう。

まず、名称描画レンダラーの先頭で、件のレコードの存在を調べた。

if (osm.osm_id == 1655769866 && r.zoom==17 && r.x==115957 && r.y==51611) {
    System.out.println(osm.type + " " + name);
}

結果は

0 双葉町立老人福祉センター
となり、正常に抽出されていることが確認できた。

次に、osm.drawText(g, r, name, colorAmenityChar, 12, 10, 1.0f); の直前でチェックした。やはり、同じ結果が得られた。

次に、drawText(g, r, name, colorAmenityChar, 12, 10, 1.0f)で同じチェックを行った。 個々結果、競合回避で描画しないことが分かった。この付近に競合するものは見たらない。

登録データに問題があるのであろう。この吟味には少し時間がかかる。 気分転換して、後ほど調べることにする。

重複回避

どのような矩形データが登録されているかを調べた。

図書館のアイコン、名称エリアおよび道路番号は正しく登録されている。

タイルの上部に固まっている不審なデータは、道路名や一方通行の矢印の登録誤りではなかろうか。 川名も道路名と同じメソッドで描画している。

簡単な引数エラーであった。修正により直った。川名は傾きにより少しずれがあるが、 この程度ならさほど問題ではない。

等高線

スマホ版と同様、国土地理院の標高タイル dem5a による等高線描画を実装した。

zoom 14以下は未サポートである。

アルゴリズムもおおむね理解できた。短い線分をつなぎ合わせて、ラインレコードを出力することも可能であるが、 平地では等高線間隔を1、2mにしたいこともあるだろう。この場合、ラインレコードファイルのサイズが大きくなる。 したがって、ラインレコードファイルは容易せず、その都度、標高タイルから等高線を生成、描画する方法が簡単で柔軟であろう。

zoom 14以下については、zoom 15の標高タイルから生成するのは手間がかかる。 zoom 14以下の標高タイルもネットからダウンロードできるので、そうした方がプログラムは楽である。

dem5aは日本全土をサポートしているわけではない。いずれ、dem10bによる等高線描画もサポートしたい。

おわりに

実時間でのGPS履歴や万歩計機能はいらないが、過去データを見る機能はいずれ備えたい。

全体としてスマホ版よりもプログラムがスリムになった。 本家JavaとAndroid Javaには大きな違いがあるため、容易ではないが、極力、成果をスマホ版地図アプリに反映したい。

急ぐ話ではないので、PC版地図アプリをさらに洗練してから、少しずつ、移植したい。

リファレンス

[1] 【Java】ゲーム用フルスクリーンの実装
[2] ディスプレイの画面サイズと色情報を取得する