X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/8cef62cd2cec4a297e46b4f2a86c9afeadb3b283..d80fac7ad90bfd20d1ad66fba034c2a93e5713d2:/app/controllers/geocoder_controller.rb diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index 4f9efa4dc..8ec0ab6b7 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -13,21 +13,10 @@ class GeocoderController < ApplicationController @sources = [] if @params[:lat] && @params[:lon] - @sources.push "latlon" - @sources.push "osm_nominatim_reverse" - @sources.push "geonames_reverse" if Settings.key?(:geonames_username) + @sources.push(:name => "latlon", :url => root_path) + @sources.push(:name => "osm_nominatim_reverse", :url => nominatim_reverse_url(:format => "html")) elsif @params[:query] - case @params[:query] - when /^\d{5}(-\d{4})?$/, - /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i - @sources.push "osm_nominatim" - when /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i - @sources.push "ca_postcode" - @sources.push "osm_nominatim" - else - @sources.push "osm_nominatim" - @sources.push "geonames" if Settings.key?(:geonames_username) - end + @sources.push(:name => "osm_nominatim", :url => nominatim_url(:format => "html")) end if @sources.empty? @@ -81,50 +70,12 @@ class GeocoderController < ApplicationController end end - def search_ca_postcode - # get query parameters - query = params[:query] - @results = [] - - # ask geocoder.ca (note - they have a per-day limit) - response = fetch_xml("https://geocoder.ca/?geoit=XML&postal=#{escape_query(query)}") - - # parse the response - if response.get_elements("geodata/error").empty? - @results.push(:lat => response.text("geodata/latt"), - :lon => response.text("geodata/longt"), - :zoom => Settings.postcode_zoom, - :name => query.upcase) - end - - render :action => "results" - rescue StandardError => e - @error = "Error contacting geocoder.ca: #{e}" - render :action => "error" - end - def search_osm_nominatim - # get query parameters - query = params[:query] - minlon = params[:minlon] - minlat = params[:minlat] - maxlon = params[:maxlon] - maxlat = params[:maxlat] - - # get view box - viewbox = "&viewbox=#{minlon},#{maxlat},#{maxlon},#{minlat}" if minlon && minlat && maxlon && maxlat - - # get objects to excude - exclude = "&exclude_place_ids=#{params[:exclude]}" if params[:exclude] - # ask nominatim - response = fetch_xml("#{Settings.nominatim_url}search?format=xml&extratags=1&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}") + response = fetch_xml(nominatim_url(:format => "xml")) # extract the results from the response - results = response.elements["searchresults"] - - # extract parameters from more_url - more_url_params = CGI.parse(URI.parse(results.attributes["more_url"]).query) + results = response.elements["searchresults"] # create result array @results = [] @@ -132,7 +83,7 @@ class GeocoderController < ApplicationController # create parameter hash for "more results" link @more_params = params .permit(:query, :minlon, :minlat, :maxlon, :maxlat, :exclude) - .merge(:exclude => more_url_params["exclude_place_ids"].first) + .merge(:exclude => results.attributes["exclude_place_ids"]) # parse the response results.elements.each("place") do |place| @@ -172,49 +123,15 @@ class GeocoderController < ApplicationController render :action => "error" end - def search_geonames - # get query parameters - query = params[:query] - - # get preferred language - lang = I18n.locale.to_s.split("-").first - - # create result array - @results = [] - - # ask geonames.org - response = fetch_xml("http://api.geonames.org/search?q=#{escape_query(query)}&lang=#{lang}&maxRows=20&username=#{Settings.geonames_username}") - - # parse the response - response.elements.each("geonames/geoname") do |geoname| - lat = geoname.text("lat") - lon = geoname.text("lng") - name = geoname.text("name") - country = geoname.text("countryName") - - @results.push(:lat => lat, :lon => lon, - :zoom => Settings.geonames_zoom, - :name => name, - :suffix => ", #{country}") - end - - render :action => "results" - rescue StandardError => e - @error = "Error contacting api.geonames.org: #{e}" - render :action => "error" - end - def search_osm_nominatim_reverse # get query parameters - lat = params[:lat] - lon = params[:lon] zoom = params[:zoom] # create result array @results = [] # ask nominatim - response = fetch_xml("#{Settings.nominatim_url}reverse?lat=#{lat}&lon=#{lon}&zoom=#{zoom}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}") + response = fetch_xml(nominatim_reverse_url(:format => "xml")) # parse the response response.elements.each("reversegeocode/result") do |result| @@ -237,39 +154,36 @@ class GeocoderController < ApplicationController render :action => "error" end - def search_geonames_reverse - # get query parameters - lat = params[:lat] - lon = params[:lon] + private - # get preferred language - lang = I18n.locale.to_s.split("-").first + def nominatim_url(format: nil) + # get query parameters + query = params[:query] + minlon = params[:minlon] + minlat = params[:minlat] + maxlon = params[:maxlon] + maxlat = params[:maxlat] - # create result array - @results = [] + # get view box + viewbox = "&viewbox=#{minlon},#{maxlat},#{maxlon},#{minlat}" if minlon && minlat && maxlon && maxlat - # ask geonames.org - response = fetch_xml("http://api.geonames.org/countrySubdivision?lat=#{lat}&lng=#{lon}&lang=#{lang}&username=#{Settings.geonames_username}") + # get objects to excude + exclude = "&exclude_place_ids=#{params[:exclude]}" if params[:exclude] - # parse the response - response.elements.each("geonames/countrySubdivision") do |geoname| - name = geoname.text("adminName1") - country = geoname.text("countryName") + # build url + "#{Settings.nominatim_url}search?format=#{format}&extratags=1&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}" + end - @results.push(:lat => lat, :lon => lon, - :zoom => Settings.geonames_zoom, - :name => name, - :suffix => ", #{country}") - end + def nominatim_reverse_url(format: nil) + # get query parameters + lat = params[:lat] + lon = params[:lon] + zoom = params[:zoom] - render :action => "results" - rescue StandardError => e - @error = "Error contacting api.geonames.org: #{e}" - render :action => "error" + # build url + "#{Settings.nominatim_url}reverse?format=#{format}&lat=#{lat}&lon=#{lon}&zoom=#{zoom}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}" end - private - def fetch_text(url) response = OSM.http_client.get(URI.parse(url)) @@ -304,10 +218,10 @@ class GeocoderController < ApplicationController 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])$/).try(:captures) # degrees, minutes, decimal seconds [NSEW] params.merge!(dms_to_decdeg(latlon)).delete(:query) - elsif latlon = query.match(/^([+-]?\d+(\.\d*)?)(?:\s+|\s*,\s*)([+-]?\d+(\.\d*)?)$/) + elsif latlon = query.match(%r{^([+-]?\d+(\.\d*)?)(?:\s+|\s*[,/]\s*)([+-]?\d+(\.\d*)?)$}) params.merge!(:lat => latlon[1].to_f, :lon => latlon[3].to_f).delete(:query) - params[:latlon_digits] = true unless params[:whereami] + params[:latlon_digits] = true end end