GeoPoをPythonで

緯度経度を文字列で表現する方式GeoPo、というのがあるらしいというのを知った。んで、サンプルコードにPythonがなかったのでついかっとなってPHPをそのまんまPythonに移植してみた。

http://geopo.at/intl/ja/developer/sample_code.html

import math

def geopoEncode(latitude, longitude, scale):
  # 64characters (number + big and small letter + hyphen + underscore)
  chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
  geopo = ""

  # Change a degree measure to a decimal number
  latitude = (latitude + 90) / 180 * pow(8, 10)
  longitude = (longitude + 180) / 360 * pow(8, 10)

  # Compute a GeoPo code from head and concatenate
  for i in range(scale):
    geopo += chars[int(math.floor(latitude / pow(8, 9 - i) % 8) + math.floor(longitude / pow(8, 9 - i) % 8) * 8)]

  return geopo;
def geopoDecode(geopo):
  # 64characters (number + big and small letter + hyphen + underscore)
  chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
  latitude = 0
  longitude = 0
  for i in range(len(geopo)):
    # What number of character that equal to a GeoPo code (0-63)
    order = chars.find(geopo[i])
    # Lat/Lng plus geolocation value of scale
    latitude  = latitude  + math.floor(order % 8) * pow(8, 9 - i);
    longitude = longitude + math.floor(order / 8) * pow(8, 9 - i);

  # Change a decimal number to a degree measure, and plus revised value that shift center of area
  latitude = latitude * 180 / pow(8, 10) + 180 / pow(8, len(geopo)) / 2 - 90
  longitude = longitude * 360 / pow(8, 10) + 360 / pow(8, len(geopo)) / 2 - 180
  scale = len(geopo)

  return (latitude, longitude, scale)

if __name__ == '__main__':
  print geopoEncode(35.658578, 139.745447, 6) # -> Z4RHXX
  print geopoEncode(48.858271, 2.294512, 6)   # -> C1qn6P
  print geopoEncode(31.658578, 139.745447, 3) # -> Z3O
  print geopoDecode("Z4RHXX")
  print geopoDecode("C1qn6P")
  print geopoDecode("Z30")

間違ってるというご指摘お待ちしております。転載、使用する方がいらっしゃいましたらご自由にどうぞ。ってほんとうに単に写しただけですが。