2011年03月20日
GeoHex V3をPerlに移植 @ ウェブ
大量あるデータを処理して、位置情報を簡単に扱えるようにGeoHexの書式に変換してみた。
元々のGeoHexがJavascriptなので、node.jsでテキストを処理しようかと思ったのですが、1行毎に処理する方法が分からず断念し、Perlで処理する事に決め、GeoHex V3を書き換えてみた。実は、書き換えている途中でV3のPerl版がGitHubに有る事を知ったのですが、必要な部分の8割ほど移植済みだったので、そのまま作る事に。
で、実際に作ってみたのですが、計算の精度の問題なのか、位置がずれる。色々確認してみて、これは簡単に解決出来そうにないので、結局、途中で止めました。経度緯度からGeoHexの文字列に変換するコードしかありませんが、ソースコードを下に貼り付けておきます。場所によってはずれてしまうので、多分実用になりません。
これ以上時間は掛けられないので、今度時間がある時にでも、既にあったPerl版を試してみます。オフィシャルなサイトでV3のPerl版があると書かれてないので、もしかするとダメなのかな。使えるならば、使わせて貰います。
GeoHex V3公開しました。 | geogames.net
>>関連リンク
#!/usr/bin/perl ### GeoHex by @sa2da (http://geogames.net) is licensed under Creative Commons BY-SA 2.1 Japan License. ### use Math::Trig; use POSIX qw(floor); my @h_key = split//,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; $h_base = 20037508.34; $h_deg = pi()*(30.0/180.0); $h_k = tan($h_deg); sub calcHexSize() { $level = $_[0]; return $h_base / 3.0 ** ($level+1); } sub getZoneByLocation() { my ($lat, $lon,$level) = @_; $level+=2; my $h_size = &calcHexSize($level); my($lon_grid,$lat_grid) = &loc2xy($lon,$lat); my $unit_x = 6.0 * $h_size; my $unit_y = 6.0 * $h_size * $h_k; my $h_pos_x = ($lon_grid + $lat_grid / $h_k) / $unit_x; my $h_pos_y = ($lat_grid - $h_k * $lon_grid) / $unit_y; my $h_x_0 = floor($h_pos_x); my $h_y_0 = floor($h_pos_y); my $h_x_q = $h_pos_x - $h_x_0; my $h_y_q = $h_pos_y - $h_y_0; my $h_x = &round($h_pos_x); my $h_y = &round($h_pos_y); if ($h_y_q > (-1 * $h_x_q) + 1.0) { if(($h_y_q < 2.0 * $h_x_q) && ($h_y_q > 0.5 * $h_x_q)){ $h_x = $h_x_0 + 1.0; $h_y = $h_y_0 + 1.0; } } elsif ($h_y_q < (-1 * $h_x_q) + 1.0) { if (($h_y_q > (2.0 * $h_x_q) - 1.0) && ($h_y_q < (0.5 * $h_x_q) + 0.5)){ $h_x = $h_x_0; $h_y = $h_y_0; } } my $h_lat = ($h_k * $h_x * $unit_x + $h_y * $unit_y) / 2; my $h_lon = ($h_lat - $h_y * $unit_y) / $h_k; my($z_loc_x,$z_loc_y) = &xy2loc($h_lon,$h_lat); if($h_base - $h_lon < $h_size){ $z_loc_x = 180; my $h_xy = $h_x; $h_x = $h_y; $h_y = $h_xy; } my $h_code =""; my @code3_x =(); my @code3_y =(); my $code3 =""; my $code9=""; my $mod_x = $h_x; my $mod_y = $h_y; for($i = 0;$i <= $level ; $i++){ my $h_pow = 3**($level-$i); if($mod_x >= &ceil($h_pow/2)){ $code3_x[$i] =2; $mod_x -= $h_pow; }elsif($mod_x <= -1 * &ceil($h_pow/2)){ $code3_x[$i] =0; $mod_x += $h_pow; }else{ $code3_x[$i] =1; } if($mod_y >= &ceil($h_pow/2)){ $code3_y[$i] =2; $mod_y -= $h_pow; }elsif($mod_y <= -1 * &ceil($h_pow/2)){ $code3_y[$i] =0; $mod_y += $h_pow; }else{ $code3_y[$i] =1; } } foreach my $i ( 0..$level ) { $code3 .= "" . $code3_x[$i] . $code3_y[$i]; $code9 .= &parseInt($code3,3); $h_code .= $code9; $code9=""; $code3=""; } $h_2 = substr($h_code,3); $h_1 = substr($h_code,0,3); $h_a1 = floor($h_1/30.0); $h_a2 = $h_1 % 30; $h_code = $h_key[$h_a1] .$h_key[$h_a2] . $h_2; $level-=2; print $h_k."\t".$h_code."\n" return $h_code; } sub loc2xy() { my ($lon,$lat) = @_; $x = $lon * $h_base / 180; $y = log(tan((90 + $lat) * pi / 360)) / (pi / 180); $y *= $h_base / 180; return ($x,$y); } sub xy2loc() { my ($x,$y) = @_; my $lon = ($x / $h_base) * 180; my $lat = ($y / $h_base) * 180; $lat = 180 / pi * (2 * atan(exp($lat * pi / 180)) - pi/ 2); return ($lon,$lat ); } sub round(){ return int($_[0]+0.5); } sub ceil(){ return int($_[0]+0.99); } sub parseInt(){ my($str,$number) = @_; $len = length($str); return $str if($len == 1); $multiplier = $len-1; $resulut = 0; for($i=0 ;$i< $len ;$i++,$multiplier--){ $place = substr($str,$i,1); $resulut += $place*($number**$multiplier); } return $resulut; }
関連日記
- 2004年09月19日 フジグラン緑井に出店する店舗 (24060)@ 広島
- 2006年11月29日 大量にあるswfの縦横幅の調べ方 (7822)@ Flash
- 2006年04月23日 cgi-bin/minibbs/$ENV{SCRIPT_NAME}?log=$cmd{log} (6633)@ ウェブ
- 2007年07月28日 ソケット通信と外部プログラム呼び出し (4968)@ Flash
- 2006年04月27日 たけしのコマネチ大学数学科「モンテカルロ法」 (4205)@ テレビ
- 2006年04月20日 たけしのコマネチ大学数学科 (3561)@ テレビ
- 2009年02月09日 UNIX time が「1234567890」 (3540)@ Linux
- 2009年01月22日 RTMP仕様公開 (3435)@ Flash
- 2006年07月02日 Plaggerインストール (3218)@ Mac
- 2007年08月28日 ADDT:ファイルリストレコードセット2 (3047)@ Mac
- 2009年02月22日 昨日は第10回『Webさわり会議』でした (3039)@ 雑
- 2008年03月22日 Komodo Edit (2954)@ Mac
- 2005年03月13日 FileMerge (2893)@ Mac
- 2007年02月23日 スマートなPerlのススメ (2765)@ ウェブ
- 2011年03月20日 PerlでparseInt (2694)@ Mac
- 2002年09月23日 Zopeのプロダクト (2666)@ Linux
- 2006年07月01日 mixiミュージックへの情報送信 (2615)@ Mac
- 2002年09月29日 Shade6の新機能 (2528)@ Shade
- 2002年09月17日 郵便番号 (2517)@ Linux
- 2003年09月27日 Dreamweaver+PHAkt+PostgreSQL (2463)@ Mac
- 2006年11月06日 awkでファイル名を小文字に (2424)@ Mac
- 2002年09月21日 Python (2412)@ Linux
- 2009年01月23日 The 25-Line ActionScript Contest January 2009 Finalists (2380)@ Flash
- 2004年08月24日 SNS色々 (2378)@ ウェブ
- 2010年10月25日 NSPredicate (2311)@ Mac
- 2006年01月23日 MX Kollectionで日本語メール (2303)@ Mac
- 2007年05月08日 TextMate (2251)@ Mac
- 2004年12月05日 Perlモジュール/WWW::Mixi (2217)@ ウェブ
- 2002年09月17日 PerlでPostgreSQL (2197)@ Linux
- 2004年01月13日 関心空間の情報をRSS化するCGI (2194)@ ウェブ
アマゾン広告
この日記ページは閲覧数などの条件に応じて、閲覧制限を行っています。他からリンクしていただいても、そのリンクから辿った閲覧者が当ページの内容をご覧頂けない場合があります。ご了承下さい。