« 24時間ぶりに食事を | メイン | Simple FON Maps »
2006年12月17日
世界測地系の座標計算
Google Maps を使ったウェブアプリを書いていたので、その派生物(関数)を。
# IN: latitude(from), longitude(from), latitude(to), longitude(to) # OUT: distance(meter) sub dist { my ($lat_1, $lon_1, $lat_2, $lon_2) = @_; my $pi = atan2(1, 1) * 4; my $radius = 6378140; $lat_1 = $lat_1 * $pi / 180; $lon_1 = $lon_1 * $pi / 180; $lat_2 = $lat_2 * $pi / 180; $lon_2 = $lon_2 * $pi / 180; my $deg = sin($lat_1) * sin($lat_2) + cos($lat_1) * cos($lat_2) * cos($lon_2 - $lon_1); my $dist = $radius * (atan2(-$deg, sqrt(-$deg * $deg + 1)) + $pi / 2); return $dist; }
2点の座標から距離を計算します。地球を真球と仮定して計算するので誤差が生じます。2点の座標があまりにも離れている場合は、その誤差が大きくなります。地球は、経線と赤道では赤道の方が長いです。
# IN: latitude(central), longitude(central), distance(meter) # OUT: SouthWestLat, SouthWestLng, NorthEastlat, NorthEastLng sub bounds { my ($lat, $lon, $dist) = @_; my $pi = atan2(1, 1) * 4; my $radius = 6378140; my $deg_lat = ($dist / $radius) * (180 / $pi); my $deg_lon = ($dist / $radius) * (180 / $pi) / cos($lat * $pi / 180); my $sWLat = $lat - $deg_lat; my $sWLng = $lon - $deg_lon; my $nELat = $lat + $deg_lat; my $nELng = $lon + $deg_lon; return $sWLat, $sWLng, $nELat, $nELng; }
座標と距離から、その座標を囲む線(4点)を求めます。こちらも前記同様に誤差が出ます。
Google Maps API に getBounds という関数があり、この関数では getSouthWest と getNorthEast が取り出せ、それぞれから lat と lng を取り出すことが出来ます。この関数は、表示しているマップの端(南西と北西)の座標を取り出しているわけです。この関数を距離からエミュレートしたかったのです。
ラジアンなどをすっかり忘れていたおかげで、とても時間がかかりました…。そもそも正しいかどうかすら分からない。国内の座標を使う限りでは、それなりに正しい結果が出るようだけど。
後者は、なかなか便利なんだけどいかがでしょうか?多分 CPAN を探せば見つかるだろうけど。
2006年12月17日 23:16 | Programming