X-Git-Url: https://projects.mako.cc/source/selectricity-live/blobdiff_plain/baf9ff0ec39c13f52ee8d4f087641dc5fcc9c53b..fcc68b4dc198b7cb0cf93467d96038b0844675fe:/vendor/plugins/ym4r_gm/lib/gm_plugin/geocoding.rb diff --git a/vendor/plugins/ym4r_gm/lib/gm_plugin/geocoding.rb b/vendor/plugins/ym4r_gm/lib/gm_plugin/geocoding.rb new file mode 100644 index 0000000..ea015eb --- /dev/null +++ b/vendor/plugins/ym4r_gm/lib/gm_plugin/geocoding.rb @@ -0,0 +1,116 @@ +require 'open-uri' +require 'rexml/document' + +module Ym4r + module GmPlugin + module Geocoding + + GEO_SUCCESS = 200 + GEO_MISSING_ADDRESS = 601 + GEO_UNKNOWN_ADDRESS = 602 + GEO_UNAVAILABLE_ADDRESS = 603 + GEO_BAD_KEY = 610 + GEO_TOO_MANY_QUERIES = 620 + GEO_SERVER_ERROR = 500 + + #Gets placemarks by querying the Google Maps Geocoding service with the +request+ string. Options can either an explicity GMaps API key (:key) or a host, (:host). + def self.get(request,options = {}) + api_key = ApiKey.get(options) + output = options[:output] || "kml" + url = "http://maps.google.com/maps/geo?q=#{URI.encode(request)}&key=#{api_key}&output=#{output}" + + res = open(url).read + + case output.to_sym + when :json + res = eval(res.gsub(":","=>")) #!!!EVAL EVAL EVAL EVAL!!! hopefully we can trust google... + placemarks = Placemarks.new(res['name'],res['Status']['code']) + if res['Placemark'] + placemark = res['Placemark'] + + placemark.each do |data| + + data_country = data['Country']['CountryNameCode'] rescue "" + data_administrative = data['Country']['AdministrativeArea']['AdministrativeAreaName'] rescue "" + data_sub_administrative = data['Country']['AdministrativeArea']['SubAdministrativeArea']['SubAdministrativeAreaName'] rescue "" + data_locality = data['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['LocalityName'] rescue "" + data_dependent_locality = data['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['DependentLocality']['DependentLocalityName'] rescue "" + data_thoroughfare = data['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['DependentLocality']['Thoroughfare']['ThoroughfareName'] rescue "" + data_postal_code = data['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['DependentLocality']['Thoroughfare']['PostalCode']['PostalCodeNumber'] rescue "" + lon, lat = data['Point']['coordinates'][0,2] + data_accuracy = data['Accuracy'] + unless data_accuracy.nil? + data_accuracy = data_accuracy.to_i + end + + placemarks << Geocoding::Placemark.new(data['address'], + data_country, + data_administrative, + data_sub_administrative, + data_locality, + data_dependent_locality, + data_thoroughfare, + data_postal_code, + lon, lat, data_accuracy) + + end + end + when :kml, :xml + + doc = REXML::Document.new(res) + + response = doc.elements['//Response'] + placemarks = Placemarks.new(response.elements['name'].text,response.elements['Status/code'].text.to_i) + response.elements.each(".//Placemark") do |placemark| + data = placemark.elements + data_country = data['.//CountryNameCode'] + data_administrative = data['.//AdministrativeAreaName'] + data_sub_administrative = data['.//SubAdministrativeAreaName'] + data_locality = data['.//LocalityName'] + data_dependent_locality = data['.//DependentLocalityName'] + data_thoroughfare = data['.//ThoroughfareName'] + data_postal_code = data['.//PostalCodeNumber'] + lon, lat = data['.//coordinates'].text.split(",")[0..1].collect {|l| l.to_f } + data_accuracy = data['.//*[local-name()="AddressDetails"]'].attributes['Accuracy'] + unless data_accuracy.nil? + data_accuracy = data_accuracy.to_i + end + placemarks << Geocoding::Placemark.new(data['address'].text, + data_country.nil? ? "" : data_country.text, + data_administrative.nil? ? "" : data_administrative.text, + data_sub_administrative.nil? ? "" : data_sub_administrative.text, + data_locality.nil? ? "" : data_locality.text, + data_dependent_locality.nil? ? "" : data_dependent_locality.text, + data_thoroughfare.nil? ? "" : data_thoroughfare.text, + data_postal_code.nil? ? "" : data_postal_code.text, + lon, lat, data_accuracy ) + end + end + + placemarks + end + + #Group of placemarks returned by the Geocoding service. If the result is valid the +status+ attribute should be equal to Geocoding::GE0_SUCCESS + class Placemarks < Array + attr_accessor :name,:status + + def initialize(name,status) + super(0) + @name = name + @status = status + end + end + + #A result from the Geocoding service. + class Placemark < Struct.new(:address,:country_code,:administrative_area,:sub_administrative_area,:locality,:dependent_locality,:thoroughfare,:postal_code,:longitude,:latitude,:accuracy) + def lonlat + [longitude,latitude] + end + + def latlon + [latitude,longitude] + end + end + end + end +end