Parse lat and lon independently when using dms notation
This commit is contained in:
parent
392d3d1226
commit
7917a7db80
2 changed files with 22 additions and 7 deletions
|
@ -206,13 +206,9 @@ class GeocoderController < ApplicationController
|
|||
if query = params[:query]
|
||||
query.strip!
|
||||
|
||||
if latlon = query.match(/^(?<ns>[NS])\s*(?<nsd>\d{1,3}(?:\.\d+)?)°?\W*(?<ew>[EW])\s*(?<ewd>\d{1,3}(?:\.\d+)?)°?$/) || # [NSEW] decimal degrees
|
||||
query.match(/^(?<nsd>\d{1,3}(?:\.\d+)?)°?\s*(?<ns>[NS])\W*(?<ewd>\d{1,3}(?:\.\d+)?)°?\s*(?<ew>[EW])$/) || # decimal degrees [NSEW]
|
||||
query.match(/^(?<ns>[NS])\s*(?<nsd>\d{1,3})°?(?:\s*(?<nsm>\d{1,3}(?:\.\d+)?)['′]?)\W*(?<ew>[EW])\s*(?<ewd>\d{1,3})°?(?:\s*(?<ewm>\d{1,3}(?:\.\d+)?)['′]?)$/) || # [NSEW] degrees, decimal minutes
|
||||
query.match(/^(?<nsd>\d{1,3})°?(?:\s*(?<nsm>\d{1,3}(?:\.\d+)?)['′]?)\s*(?<ns>[NS])\W*(?<ewd>\d{1,3})°?(?:\s*(?<ewm>\d{1,3}(?:\.\d+)?)['′]?)\s*(?<ew>[EW])$/) || # degrees, decimal minutes [NSEW]
|
||||
query.match(/^(?<ns>[NS])\s*(?<nsd>\d{1,3})°?\s*(?<nsm>\d{1,2})['′]?(?:\s*(?<nss>\d{1,3}(?:\.\d+)?)["″]?)\W*(?<ew>[EW])\s*(?<ewd>\d{1,3})°?\s*(?<ewm>\d{1,2})['′]?(?:\s*(?<ews>\d{1,3}(?:\.\d+)?)["″]?)$/) || # [NSEW] degrees, minutes, decimal seconds
|
||||
query.match(/^(?<nsd>\d{1,3})°?\s*(?<nsm>\d{1,2})['′]?(?:\s*(?<nss>\d{1,3}(?:\.\d+)?)["″]?)\s*(?<ns>[NS])\W*(?<ewd>\d{1,3})°?\s*(?<ewm>\d{1,2})['′]?(?:\s*(?<ews>\d{1,3}(?:\.\d+)?)["″]?)\s*(?<ew>[EW])$/) # degrees, minutes, decimal seconds [NSEW]
|
||||
params.merge!(to_decdeg(latlon.named_captures)).delete(:query)
|
||||
if latlon = query.match(/^(?<ns>[NS])\s*#{dms_regexp('ns')}\W*(?<ew>[EW])\s*#{dms_regexp('ew')}$/) ||
|
||||
query.match(/^#{dms_regexp('ns')}\s*(?<ns>[NS])\W*#{dms_regexp('ew')}\s*(?<ew>[EW])$/)
|
||||
params.merge!(to_decdeg(latlon.named_captures.compact)).delete(:query)
|
||||
|
||||
elsif latlon = query.match(%r{^(?<lat>[+-]?\d+(?:\.\d+)?)(?:\s+|\s*[,/]\s*)(?<lon>[+-]?\d+(?:\.\d+)?)$})
|
||||
params.merge!(:lat => latlon["lat"], :lon => latlon["lon"]).delete(:query)
|
||||
|
@ -224,6 +220,14 @@ 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 = BigDecimal(captures.fetch("nsd", "0"))
|
||||
|
|
|
@ -261,6 +261,17 @@ class GeocoderControllerTest < ActionDispatch::IntegrationTest
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Test identification of lat/lon pairs with mixed precision
|
||||
def test_identify_latlon_ne_mixed_precision
|
||||
latlon_check "N1 5 E15", 1.083333, 15
|
||||
latlon_check "N1 5 9 E15", 1.085833, 15
|
||||
latlon_check "N1 5 9 E1 5", 1.085833, 1.083333
|
||||
latlon_check "N15 E1 5", 15, 1.083333
|
||||
latlon_check "N15 E1 5 9", 15, 1.085833
|
||||
latlon_check "N1 5 E1 5 9", 1.083333, 1.085833
|
||||
end
|
||||
|
||||
#
|
||||
# Test identification of lat/lon pairs with values close to zero
|
||||
def test_identify_latlon_close_to_zero
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue