2021-03-28
日本生まれのプログラミング言語といえば Ruby
Swift, Elixir, Scala, Crystal, Groovy, D言語など、さまざまな新しい誕生する言語にも影響を与えています。


Geo3x3 in HSP
高専生にプログラミングをはじめたきっかけの言語として聞く、HSP (Hot Soup Processor) で、Geo3x3にて実装してみました。(src on GitHub)

#defcfunc gex3x3_encode double lat, double lng, int level if level < 1 { Return "" } if lng < 0 { res = "W" flng = lng + 180.0 } else { res = "E" flng = lng } flat = lat + 90.0 unit = 180.0 repeat level - 1 unit = unit / 3.0 x = int(flng / unit) y = int(flat / unit) n = x + y * 3 + 1 res = res + n flng = flng - double(x) * unit flat = flat - double(y) * unit loop return res

if文はカッコ、ループはend式なのがユニーク。

Ruby版と比較してみましょう。(src on GitHub)

module Geo3x3 module_function def encode(lat, lng, level) raise ArgumentError if level < 1 lat = lat.to_f lng = lng.to_f if lng >= 0 result = "E" else result = "W" lng += 180 end lat += 90 unit = 180.0 (level - 1).times do unit /= 3 x = (lng / unit).to_i y = (lat / unit).to_i result << "#{x + y * 3 + 1}" lng -= x * unit lat -= y * unit end result end

こちら国産言語、Kuinでの実装 (src on GitHub)

+func encode(lat: float, lng: float, level: int): []char var result: []char if(level < 1) do result :: "" ret result end if if(lng >= 0.0) do result :: "E" else do result :: "W" do lng :+ 180.0 end if do lat :+ 90.0 {180:the North Pole, 0:the South Pole} var unit: float :: 180.0 var i: int :: 1 var array: []char while(i < level) do unit :/ 3.0 var x: int :: (lng / unit) $ int var y: int :: (lat / unit) $ int do array :: "\{x + y * 3 + 1}" do result :: result ~ array do lng :- x $ float * unit do lat :- y $ float * unit do i :+ 1 end while ret result end func

こちらはend式。プログラミング言語で独特な使い方になり勝ちな「=」を代入では使わず、「:」としています。

日本語プログラミング言語のなでしこ3での実装。(src on GitHub)

●(緯度と、経度を、レベルで)Geo3x3エンコードとは もし、(経度>=0.0)ならば コード="E" 違えば コード="W" 経度=経度+180 ここまで。 緯度=緯度+90 ユニット=180 (レベル-1)回 ユニット=ユニット/3 X=INT(経度/ユニット) Y=INT(緯度/ユニット) コード=コード&(X+Y*3+1) 経度=経度-X*ユニット 緯度=緯度-Y*ユニット ここまで コードを戻す ここまで

おもしろいのは関数の呼び出し方。日本語っぽい書き方で取得できます。

35.65858と139.745433を14でGeo3x3エンコードして表示

ASCIIコードが基本だった昔と違ってユニコード時代。JavaScriptなど多くの言語で日本語の関数名や変数名が使えます。

class Geo3x3 { static エンコード(緯度, 経度, レベル) { if (レベル < 1) { return null; } if (typeof 緯度 == "string") { 緯度 = parseFloat(緯度); } if (typeof 経度 == "string") { 経度 = parseFloat(経度); } let コード = "E"; if (経度 < 0.0) { コード = "W"; 経度 += 180.0; } 緯度 += 90.0; // 180:the North Pole, 0:the South Pole let ユニット = 180.0; for (let i = 1; i < レベル; i++) { ユニット /= 3.0; const x = Math.floor(経度 / ユニット); const y = Math.floor(緯度 / ユニット); コード += x + y * 3 + 1; 経度 -= x * ユニット; 緯度 -= y * ユニット; } return コード; }

英単語で記述し、読むときだけ日本語になってくれるプログラミング言語やエディタの支援とかもいいかもしれません。

Geo3x3にうれしいお知らせ!
地球規模で行われる宝探し「ジオキャッシング」用のお助けアプリ「GC Wizard」の緯度経度変換の1つとしてGeo3x3を追加いただきました!

Search · Geo3x3 / S-Man42/GCWizard
Flutter/Dartで実装されている GC Wizard、GitHubにて、Geo3x3追加に関する変更履歴を見ることができます。 作っててよかった Dart版

class Geo3x3 { static String encode(num lat, num lng, num level) { if (level < 1) { return ""; } var res = ""; var lng2 = lng; if (lng >= 0) { res = "E"; } else { res = "W"; lng2 += 180; } var lat2 = lat + 90.0; var unit = 180.0; for (int i = 1; i < level; i++) { unit /= 3; final x = (lng2 / unit).toInt(); final y = (lat2 / unit).toInt(); res += (x + y * 3 + 1).toString(); lng2 -= x * unit; lat2 -= y * unit; } return res; }

Geo3x3の応用例としてご紹介するので、使われた方ぜひご一報ください。

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS