X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/e5057dd57adca8e8ad6961eb15346cb365464667..1bee96ede16e1dab41ad82efb9f2486da68a642f:/app/controllers/geocoder_controller.rb?ds=sidebyside diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index 0dabc5a62..43f276efa 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -206,13 +206,9 @@ class GeocoderController < ApplicationController if query = params[:query] query.strip! - if latlon = query.match(/^(?[NS])\s*(?\d{1,3}(?:\.\d+)?)°?\W*(?[EW])\s*(?\d{1,3}(?:\.\d+)?)°?$/) || # [NSEW] decimal degrees - query.match(/^(?\d{1,3}(?:\.\d+)?)°?\s*(?[NS])\W*(?\d{1,3}(?:\.\d+)?)°?\s*(?[EW])$/) || # decimal degrees [NSEW] - query.match(/^(?[NS])\s*(?\d{1,3})°?(?:\s*(?\d{1,3}(?:\.\d+)?)['′]?)\W*(?[EW])\s*(?\d{1,3})°?(?:\s*(?\d{1,3}(?:\.\d+)?)['′]?)$/) || # [NSEW] degrees, decimal minutes - query.match(/^(?\d{1,3})°?(?:\s*(?\d{1,3}(?:\.\d+)?)['′]?)\s*(?[NS])\W*(?\d{1,3})°?(?:\s*(?\d{1,3}(?:\.\d+)?)['′]?)\s*(?[EW])$/) || # degrees, decimal minutes [NSEW] - query.match(/^(?[NS])\s*(?\d{1,3})°?\s*(?\d{1,2})['′]?(?:\s*(?\d{1,3}(?:\.\d+)?)["″]?)\W*(?[EW])\s*(?\d{1,3})°?\s*(?\d{1,2})['′]?(?:\s*(?\d{1,3}(?:\.\d+)?)["″]?)$/) || # [NSEW] degrees, minutes, decimal seconds - query.match(/^(?\d{1,3})°?\s*(?\d{1,2})['′]?(?:\s*(?\d{1,3}(?:\.\d+)?)["″]?)\s*(?[NS])\W*(?\d{1,3})°?\s*(?\d{1,2})['′]?(?:\s*(?\d{1,3}(?:\.\d+)?)["″]?)\s*(?[EW])$/) # degrees, minutes, decimal seconds [NSEW] - params.merge!(to_decdeg(latlon.named_captures)).delete(:query) + if latlon = query.match(/^(?[NS])\s*#{dms_regexp('ns')}\W*(?[EW])\s*#{dms_regexp('ew')}$/) || + query.match(/^#{dms_regexp('ns')}\s*(?[NS])\W*#{dms_regexp('ew')}\s*(?[EW])$/) + params.merge!(to_decdeg(latlon.named_captures.compact)).delete(:query) elsif latlon = query.match(%r{^(?[+-]?\d+(?:\.\d+)?)(?:\s+|\s*[,/]\s*)(?[+-]?\d+(?:\.\d+)?)$}) params.merge!(:lat => latlon["lat"], :lon => latlon["lon"]).delete(:query) @@ -224,20 +220,28 @@ class GeocoderController < ApplicationController params.permit(:query, :lat, :lon, :latlon_digits, :zoom, :minlat, :minlon, :maxlat, :maxlon) end + def dms_regexp(name_prefix) + / + (?: (?<#{name_prefix}d>\d{1,3}(?:\.\d+)?)°? ) | + (?: (?<#{name_prefix}d>\d{1,3})°?\s*(?<#{name_prefix}m>\d{1,2}(?:\.\d+)?)['′]? ) | + (?: (?<#{name_prefix}d>\d{1,3})°?\s*(?<#{name_prefix}m>\d{1,2})['′]?\s*(?<#{name_prefix}s>\d{1,2}(?:\.\d+)?)["″]? ) + /x + end + def to_decdeg(captures) - ns = captures.fetch("ns").casecmp("s").zero? ? -1 : 1 - nsd = captures.fetch("nsd", "0").to_f - nsm = captures.fetch("nsm", "0").to_f - nss = captures.fetch("nss", "0").to_f + ns = captures.fetch("ns").casecmp?("s") ? -1 : 1 + nsd = BigDecimal(captures.fetch("nsd", "0")) + nsm = BigDecimal(captures.fetch("nsm", "0")) + nss = BigDecimal(captures.fetch("nss", "0")) - ew = captures.fetch("ew").casecmp("w").zero? ? -1 : 1 - ewd = captures.fetch("ewd", "0").to_f - ewm = captures.fetch("ewm", "0").to_f - ews = captures.fetch("ews", "0").to_f + ew = captures.fetch("ew").casecmp?("w") ? -1 : 1 + ewd = BigDecimal(captures.fetch("ewd", "0")) + ewm = BigDecimal(captures.fetch("ewm", "0")) + ews = BigDecimal(captures.fetch("ews", "0")) lat = ns * (nsd + (nsm / 60) + (nss / 3600)) lon = ew * (ewd + (ewm / 60) + (ews / 3600)) - { :lat => lat, :lon => lon } + { :lat => lat.round(6).to_s("F"), :lon => lon.round(6).to_s("F") } end end