qgmap 開発メモ – クリップボードの操作方法&高速化パッチ

ここ数日、皆様にとても有用なご意見を頂き、なんかとても楽しく嬉しいです笑顔

自分の頭だけでは思いつかないような、目からウロコないろいろな考えが聞けると、知的欲求が満たされてゾクゾクするような、なんかいままで死んでいだ脳細胞が生き返るような(?)、そんな感覚になって嬉しくなってしまいます。

そんなちょっとハイな気分に乗って一気に実装しちゃおうと思います。

まず、sugarware様のコメントにあった、クリップボード経由の緯度経度のやりとりについて。
エディタと組み合わせるという発想が秀逸。私にはこの発想はありませんでした。

Qt/Eでクリップボードはどうやって扱うものかをググってみたところ、LinuZau Tool Box Wikiにそのものずばりのソースコードが載っていました。
なるほど、QApplication経由でクリップボードへ読み書きできると。Qtopia Referenceではここ

ふむふむ。これで実装はできそうです。QClipboardクラスには dataChanged() シグナルがあるから、クリップボード監視も出きるのか。何かに使えそう。

あと感動したのが、tera様のパッチ。いや、これにはほんとビビりました。
パッチを当てるとスクロールが体感で2倍位軽くなります。ほんとスムーズ!
あまりにスムーズなので、画像読み込みのタイミングの引っかかりがあからさまに目立つようになるくらい (^^;

いやー。すばらしい。是非ともこれらを組み込んだ qgmap をリリースしたいですね。
今日中リリースを目標に頑張ります!笑う

qgmap 開発メモ – 画面外マーカの方向

今回は画面外マーカの表示方向についてです。

今のqgmapの画面外マーカの方向は以下の図のようになっています。

 

今のqgmapの画面外マーカ
今のqgmapの画面外マーカ

 

今は、マークした位置が画面の上下左右に直線的に移動して表示できる場合は「辺」の部分にマーカを表示し、上下左右移動で表示できない場合は頂点部分に斜め方向向きのマーカを表示しています。
ですので、右辺にあるマーカの y 座標はマーカの y 座標と一致しています。

開発当初は、以下のようなものを考えていました。


開発当初のマーカの方向

画面の中心からマーカまでを直線で結んだとき、画面の端を横切った所にマーカを表示する方法です。

一応、こちらで実装したんですが、当時はまだ中央マーカ表示機能がなかったこともあり、スクロールさせたときのマーカの挙動に何となく違和感があったため、現在の方法に切り替えました。
マーカを表示させた状態でスクロールさせると違和感はないんですが。

個人的な感覚での、それぞれの特徴をまとめると以下のようになります。

  • 前者の方法
    • 中央マーカなしの時のスクロール時の挙動が自然
    • マーカとの距離がある程度離れているとき、必ずしも正確に方向を表示しない
  • 後者の方法
    • 中央マーかなしの時のスクロール時の挙動がなんとなく不自然
    • マーカとの距離が離れていても、正しい方向を指し示す。

 

一応、後者の方向で実装したパッケージも作成しましたので、どちらがいいかご意見を伺いたいと思います。

パッケージ名や実行ファイルなど名前を変更しているので、オリジナルの qgmap と共存することが可能です。
また、「.」キーでの中央マーカ表示も実装していますので、中央マーカ表示/非表示でスクロールさせてみて、画面外マーカの挙動がしっくりくるかも試していただけると幸いです。

慣れの問題だとはおもうので、どちらでも一緒かもしれませんが・・・。

qgmap 開発メモ – 縮尺表示その2

知恵熱にやられながらも、ついに任意の緯度の緯線1周の長さを求めることができた!

高校生の自分ならもっと早く解けたんだろうな・・・。時間は残酷だぜクールフッ

結果から言うと、緯度θの半径は、こうなった。

x = a2cosθ/√(a2+(b2-a2)sin2θ)

aは地球の長半径(中心と赤道の距離)、bは短半径(中心と北極・南極点の距離)を表している。

半径がわかれば2πr で円周の長さ=緯線の長さがわかるので、後は地球1周分の地図のドット数で割れば、1ドット当たりの距離が求まる!これで縮尺表示の目処が立った。笑う

せっかく錆付いた頭をフル回転させて導いたので、記念に過程も晒しておこう。以下は自己満の世界なので読まなくていいですよ。


楕円の式は以下のようになる。

x2/a2+y2/b2 = 1 ・・・①

ここでも、aは地球の長半径、bは短半径を表す。

まずこの楕円の法線ベクトルを求める。法線ベクトルvは以下の式で計算できる。

v=(∂f/∂x, ∂f/∂y)

楕円の方程式より法線ベクトルを求める。

f(x,y) = x2/a2+y2/b2-1
v=(∂f/∂x, ∂f/∂y)=(2x/a2, 2y/b2

方向が重要で、長さはどうでもいいので、扱いやすいように、a2b2/2をかける。

v=(xb2, ya2

この法線ベクトルを自身の長さで割って単位ベクトル化すると、

v‘=(xb2/|v|, ya2/|v|)

となる。ただし、

|v| =√(x2b4+y2a4)

である。

この単位法線ベクトルと赤道面がなす角度が緯度θなので、

v‘=(xb2/|v|, ya2/|v|) = (cosθ, sinθ)
∴ cosθ = xb2/|v| , sinθ = ya2/|v|

上の2つの式と、楕円の式①を連立方程式として、x,y を θの式で表す。

式①を変形

x2b2+y2a2 = a2b2
y2a2 = a2b2– x2b2 = b2(a2– x2) ・・・②

sinθの式を両辺2乗する。

|v|2sin2θ = y2a4 = a2(y2a2)

式②を代入

|v|2sin2θ = a2(b2(a2– x2))

x2について整理すると、

x2 = a2-(|v|2sin2θ)/a2b2 ・・・③

ここで |v|2 を求める。

|v| 2= x2b4+y2a4

式②を代入

|v| 2=x2b4+a2(b2(a2-x2))

整理すると

|v| 2=b2(x2(b2-a2)+a4)

これを式③に代入

x2 = a2-(b2(x2(b2-a2)+a4)*sin2θ)/a2b2

x2について整理すると

x2 = a4(1-sin2θ)/(a2+(b2-a2)sin2θ)

1-sin2θ = cos2θなので、

x2= a4cos2θ/(a2+(b2-a2)sin2θ)

平方根を取って

x = a2cosθ/√(a2+(b2-a2)sin2θ)

同様にyも求めて、θを0~πまで回してグラフを書いたところ、楕円の図と一致したので、たぶんあってるのでしょう。

ふぅ。