• ベストアンサー

C言語で地図を描きたい

C言語で、地図を描くプログラムを作ろうと考えていますが、 どなたか参考になりそうなソースや文献などご存知でしょうか。 東京湾などの形状を描くつもりですが、将来的に 詳細/広域切り替え機能も必要になります。 海岸線を正確に描くためには、 画面外にある地形座標とも線を繋ぐ必要がありますが これをどう処理しようか考えあぐねています。 標準出力にXY座標を与えて線を描く関数や、 緯度経度をXY座標に変換する関数は用意しています。

質問者が選んだベストアンサー

  • ベストアンサー
  • haniriito
  • ベストアンサー率57% (12/21)
回答No.2

地図ソフト、おもしろそうですね。私も作ってみたいソフトの一つです。 参考になるフリーソフトのソースや解説の場所をお知りになりたいと思いますが、私の知る限りではちょっと分かりません。 下の点についてコメントします。 >使えるリソースが限られているので、地図の一部しか描けないわけですが、膨大なベクトルデータ群から画面内に入りそうなベクトルだけを抽出するのは至難の業のようです。 基本的は地図全体をメッシュに分けて、そのメッシュにひっかかるベクトルデータをあらかじめデータベースとして持っておくしかないと思います。 そして広域・詳細表示の切り替えをサポートするには、それぞれの拡大・縮小にあわせて、異なるメッシュサイズのデータベースを保存しておき、現在の表示サイズに近いメッシュサイズのデータベースから、表示する範囲と重なるメッシュのみを描画する、ということになるのではないでしょうか。 世界地図を描くことを考えるとします。小さい町を表示するときは、例えば1km×1kmのメッシュサイズのデータを参照し、そのメッシュが画面の表示範囲と引っかかる最大4メッシュに引っかかるベクトルデータをすべて描けばよいです。もちろん表示範囲のクリッピングはしてください。その該当するメッシュ内のベクトルデータ数が数千程度に収まるのであれば描画処理はそんなにおもくないでしょう。もちろん、プロセッサの処理に応じて一度に描画できるベクトル数(=許容できる待ち時間)は変わってくるでしょう。 世界の全体を描画するとき、全体を1つのメッシュとしたデータを参照しますが、このときその地図データに含まれるであろう数百万、数千万のすべてのベクトルデータを表示するのはナンセンスですね。世界地図全体でしたら、建物や道路は表示しなくて良いかもしれません。小さい川も表示しなくて良いし、入り組んだ海岸線も要らないでしょう。つまり、細かいベクトルデータはそのサイズのメッシュのデータベースからはあらかじめ除いておき、やはり実処理(描画)時間として許容できるベクトル数に収まるようにしておくべきでしょうね。 こう考えると、地図ソフトで一番難しいのは、大小異なるメッシュサイズに対応するデータベースに、どの程度の粒度のベクトルデータを保存しておくか?という点になるのではないかと思います。 話はそれますが、3Dゲームなどで「バンプマッピング」という手法があるそうです。テクスチャをポリゴンの貼り付け表示するときに、近くで大きなポリゴンに貼り付けるときは精細なテクスチャを貼り付け、遠くで小さく表示されるポリゴンについては粗いおおざっぱなテクスチャを貼り付ける、ということをやるようで、そのためにあらかじめ精細なテクスチャデータから少しずつ粗くしてテクスチャデータをあらかじめ作成しておいて、必要に応じた解像度のテクスチャを利用するという方法です。 今回の件の参考になれば・・・ ご検討をお祈りしています。

earl_gray
質問者

お礼

同じく地図に興味があおりなんですね。地図の世界に踏み込みましたが、なんだか面白みを感じています。更に調べてみましたが、いわゆるGIS(地理情報システム)の分野のようです。 今回質問しております地図描画について、更に踏み込んで調べたところ、一つの方向性が見えてきましたのでご紹介します。 電子地図の分野では、shapefile形式が事実上の標準となっており、日本地図や世界地図などの詳細なベクトルデータが公開されいています。 このデータをC言語で操作することができる Shapefile C Library API がオープンソースで公開されており、これを使えば地図全体から指定座標内に含まれる、あるいは通過する線分を抽出することができます。これで、リソースに限りがあっても、一度切り出す作業さえしてしまえばとりあえず表示領域だけの演算で済むはずです。 多くの場合、頂点データは位置データが緯度、経度で表されて いますが、これを地図と同じメルカトル座標系に変換すればディスプレイに投影できます。これは同じくオープンソースの drawmap に座標変換関数があります。 なお地図の座標を示すのに使われる緯度経度(Latitude/Longitude)は通常度分秒(Degrees/Minutes/Seconds)で表記されますが、座標計算の前に一旦度(Degree)に変換する必要があります。こちらもネットで探せばCの関数は見つかります。 グラフィックライブラリなどを活用して標準出力にX,Y座標を指定して線を書かせることができれば、理論的には地図プログラムが実現できるものと思われます。 その他参考文献を探しましたが、次のものが該当するようです。 Dr. Mark de Berg, Dr. Marc van Kreveld著 Computational Geometry Algorithms and Applications Joseph O'rourke 著 COMPUTATIONAL GEOMETRY IN C 英文のため難しいですが、1冊目は和訳した本もあるようです。2冊目は題目から推定するとCプログラムが掲載されているはずです。これを応用すれば、フルスクラッチで切り出し描画のアルゴリズムが作れると思います。。。 まだまだ勉強途中ではありますが、ご参考になりましたら幸いです。

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

表示範囲が長方形だとして。 線分を考える。曲線だったら、線分として近似できる程度に分割する。 線分が、表示範囲の中か、交差しているか、外かを判定する。 中ならそのまま線を引く。 交差していたら、交点を求めて、範囲内だけ線を引く。 外なら線は引かない。 という処理になるのではないでしょうか。 交点の求め方とかは、中学か高校の数学レベルの問題ですし、画像処理ライブラリとか探せば関数一つで解決するかもしれません。

earl_gray
質問者

お礼

ご回答ありがとうございます。 画面外にある点が関係する線分が画面内に現れると、画面外であっても計算はしなければなりません。 ところが逆に、形状データのベクトルが画面内に入るかは計算しないと分からないので、結局は全世界のデータを演算しなければならなくなります。 使えるリソースが限られているので、地図の一部しか描けないわけですが、膨大なベクトルデータ群から画面内に入りそうなベクトルだけを抽出するのは至難の業のようです。 ここは画像処理ライブラリのみならず、地図描画ライブラリも必要としそうです。一度、フリーのGISシステムのソースコードを見てみる必要がありそうですね。ありがとうございました。

関連するQ&A