Instantly share code, notes, and snippets.

@mogya /geoutils.rb
Last active Dec 25, 2015

Embed
What would you like to do?
緯度経度を表す多様なフォーマットを全部受け入れて任意のフォーマットで出力する試み
require 'active_support/core_ext/hash'
module GeoUtils
extend self
# 様々な緯度経度フォーマットのデータを入出力する関数
# 入力: 以下の5パターンの引数が想定されている
# lat lng FORMAT 数値二つ
# "lat" "lng" FORMAT 文字列二つ
# "lat,lng" FORMAT カンマ区切りの文字列一つ
# [lat,lng] FORMAT 配列
# {lat,lng} FORMAT Hash。keyは、lat,latitude,lng,lon,long,longitude,x,y いずれもOK。
# FORMAT 出力方法を指定
# :array [lat,lng]のarrayで返す。デフォルトのフォーマット
# :lat_lng :lat,:lngをキーにするHash
# :lat_long :lat,:longをキーにするHash
# :lat_lon :lat,:lonをキーにするHash
# :x_y :x,:yをキーにするHash
# :latitude_longitude :latitude,:longitudeをキーにするHash
# :stringify_keys Hashをstringify_keysしてから返す
# :string "lat,lng"という具合に文字列一つで表す
def coordinates(*args)
lat,lng = []
format = [:array]
ret = nil
case args[0]
when Float
# lat lng
lat,lng = args.shift(2)
when Array # [lat,lng]
_lat, _lng = args.shift
if !_lat.nil? && _lat.respond_to?(:to_f) and
!_lng.nil? && _lng.respond_to?(:to_f)
then
lat = _lat.to_f
lng = _lng.to_f
end
when String
if String===args[1]
# "lat" "lng"
_lat, _lng = args.shift(2)
if !_lat.nil? && _lat.respond_to?(:to_f) and
!_lng.nil? && _lng.respond_to?(:to_f)
then
lat = _lat.to_f
lng = _lng.to_f
end
else
# "lat,lng"
latlng = args.shift
if latlng=~/^([0-9. ]+),([0-9. ]+)$/
lat = $1.to_f
lng = $2.to_f
end
end
when Hash
latlng = args.shift
latlng.symbolize_keys!
lat = latlng[:lat]||latlng[:latitude]||latlng[:x]
lng = latlng[:lng]||latlng[:longitude]||latlng[:long]||latlng[:lon]||latlng[:y]
end
format = [args].flatten if (args.size>0)
if format.include?(:array)
ret = [lat,lng]
elsif format.include?(:string)
ret = "#{lat},#{lng}"
else
ret = {}
if format.include?(:lat_lng)
ret[:lat] = lat
ret[:lng] = lng
end
if format.include?(:lat_long)
ret[:lat] = lat
ret[:long] = lng
end
if format.include?(:lat_lon)
ret[:lat] = lat
ret[:lon] = lng
end
if format.include?(:latitude_longitude)
ret[:latitude] = lat
ret[:longitude] = lng
end
if format.include?(:x_y)
ret[:x] = lat
ret[:y] = lng
end
if format.include?(:stringify_keys)||format.include?(:stringify)
ret.stringify_keys!
end
end
ret = nil if (lat.nil? || lng.nil?)
return ret
end
end
require "test-unit"
require "geoutils.rb"
class GeoUtils_test < Test::Unit::TestCase
def test_coordinates()
test1 = GeoUtils::coordinates([34.12345, 135.98765])
assert_equal(34.12345, test1[0], 'in:array[float] out:none (lat)' )
assert_equal(135.98765, test1[1], 'in:array[float] out:none (lng)' )
test1 = GeoUtils::coordinates(["34.12345", "135.98765"])
assert_equal(34.12345, test1[0], 'in:array[string] (lat)' )
assert_equal(135.98765, test1[1], 'in:array[string] (lng)' )
test1 = GeoUtils::coordinates("34.12345", "135.98765")
assert_equal(34.12345, test1[0], 'in:string,string (lat)' )
assert_equal(135.98765, test1[1], 'in:string,string (lng)' )
test1 = GeoUtils::coordinates(34.12345, 135.98765)
assert_equal(34.12345, test1[0], 'in:float,float (lat)' )
assert_equal(135.98765, test1[1], 'in:float,float (lng)' )
test1 = GeoUtils::coordinates( {lat:34.12345, lng:135.98765} )
assert_equal(34.12345, test1[0], 'in:hash[lat_lng] (lat)' )
assert_equal(135.98765, test1[1], 'in:hash[lat_lng] (lng)' )
test1 = GeoUtils::coordinates( {lat:34.12345, lon:135.98765} )
assert_equal(34.12345, test1[0], 'in:hash[lat_lon] (lat)' )
assert_equal(135.98765, test1[1], 'in:hash[lat_lon] (lng)' )
test1 = GeoUtils::coordinates( {lat:34.12345, long:135.98765} )
assert_equal(34.12345, test1[0], 'in:hash[lat_long] (lat)' )
assert_equal(135.98765, test1[1], 'in:hash[lat_long] (lng)' )
test1 = GeoUtils::coordinates( {latitude:34.12345, longitude:135.98765} )
assert_equal(34.12345, test1[0], 'in:hash[latitude_longitude] (lat)' )
assert_equal(135.98765, test1[1], 'in:hash[latitude_longitude] (lng)' )
test1 = GeoUtils::coordinates( {x:34.12345, y:135.98765} )
assert_equal(34.12345, test1[0], 'in:hash[x_y] (lat)' )
assert_equal(135.98765, test1[1], 'in:hash[x_y] (lng)' )
test1 = GeoUtils::coordinates([34.12345, 135.98765],:lat_lng)
assert_equal(34.12345, test1[:lat], 'out(lat)' )
assert_equal(135.98765, test1[:lng], 'out(lng)' )
test1 = GeoUtils::coordinates([34.12345, 135.98765],[:lat_lng,:lat_long,:lat_lon,:latitude_longitude])
assert_equal(34.12345, test1[:lat], 'out:lat_lng (lat)' )
assert_equal(135.98765, test1[:lng], 'out:lat_lng (lng)' )
assert_equal(135.98765, test1[:lon], 'out:lat_long (lng)' )
assert_equal(135.98765, test1[:long], 'out:lat_long (lng)' )
assert_equal(34.12345, test1[:latitude], 'out:latitude_longitude (lat)' )
assert_equal(135.98765, test1[:longitude], 'out:latitude_longitude (lng)' )
test1 = GeoUtils::coordinates([34.12345, 135.98765],[:string])
assert_equal("34.12345,135.98765", test1, 'out:string' )
test1 = GeoUtils::coordinates([34.12345, 135.98765],:x_y)
assert_equal(34.12345, test1[:x], 'out:x_y (lat)' )
assert_equal(135.98765, test1[:y], 'out:x_y (lng)' )
test1 = GeoUtils::coordinates([34.12345, 135.98765],:latitude_longitude,:stringify_keys)
assert_equal(34.12345, test1['latitude'], 'out:string (lat)' )
assert_equal(135.98765, test1['longitude'], 'out:string (lng)' )
test1 = GeoUtils::coordinates( {lat:34.12345, lng:135.98765},[:lat_lng] )
assert_equal(34.12345, test1[:lat], 'in:hash[latlong] out:lat_lng (lat)' )
assert_equal(135.98765, test1[:lng], 'in:hash[latlong] out:lat_lng(lng)' )
test1 = GeoUtils::coordinates(34.12345, 135.98765,:lat_lng)
assert_equal(34.12345, test1[:lat], 'in:float,float out:lat_lng(lat)' )
assert_equal(135.98765, test1[:lng], 'in:float,float out:lat_lng(lng)' )
test1 = GeoUtils::coordinates("34.12345", "135.98765",[:lat_long])
assert_equal(34.12345, test1[:lat], 'in:string,string out:lat_lng(lat)' )
assert_equal(135.98765, test1[:long], 'in:string,string out:lat_lng(lng)' )
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment