]> git.openstreetmap.org Git - rails.git/blobdiff - app/controllers/geocoder_controller.rb
If a search only finds one result then jump straight to it instead of
[rails.git] / app / controllers / geocoder_controller.rb
index 1b9ca05b558659a1e038f8b123554fc3e1201a46..f557668b69e812628e72f4eb12b44f023ea235da 100644 (file)
@@ -4,18 +4,30 @@ class GeocoderController < ApplicationController
   require 'rexml/document'
 
   def search
-    @query = params[:query]
-    @results = Array.new
-
-    if @query.match(/^\d{5}(-\d{4})?$/)
-      @results.push search_us_postcode(@query)
-    elsif @query.match(/(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)
-      @results.push search_uk_postcode(@query)
-    elsif @query.match(/[A-Z]\d[A-Z]\s*\d[A-Z]\d/i)
-      @results.push search_ca_postcode(@query)
+    query = params[:query]
+    results = Array.new
+
+    if query.match(/^\d{5}(-\d{4})?$/)
+      results.push search_us_postcode(query)
+    elsif query.match(/(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)
+      results.push search_uk_postcode(query)
+    elsif query.match(/[A-Z]\d[A-Z]\s*\d[A-Z]\d/i)
+      results.push search_ca_postcode(query)
     else
-      @results.push search_osm_namefinder(@query)
-      @results.push search_geonames(@query)
+      results.push search_osm_namefinder(query)
+      results.push search_geonames(query)
+    end
+
+    results_count = count_results(results)
+
+    render :update do |page|
+      if results_count == 1
+        position = results.collect { |s| s[:results] }.compact.flatten[0]
+        page.call "setPosition", position[:lat], position[:lon], position[:zoom]
+      else
+        page.replace_html :search_results_content, :partial => 'results', :object => results
+        page.call "openSearchResults"
+      end
     end
   end
 
@@ -93,19 +105,23 @@ private
       type = named.attributes["info"].to_s.capitalize
       name = named.attributes["name"].to_s
       description = named.elements["description"].to_s
+      if name.empty?
+        prefix = ""
+        name = type
+      else
+        prefix = "#{type} "
+      end
       if place
         distance = format_distance(place.attributes["approxdistance"].to_i)
         direction = format_direction(place.attributes["direction"].to_i)
         placename = place.attributes["name"].to_s
-        results.push({:lat => lat, :lon => lon, :zoom => zoom,
-                      :prefix => "#{type} ", :name => name,
-                      :suffix => ", #{distance} #{direction} of #{placename}",
-                      :description => description})
+        suffix = ", #{distance} #{direction} of #{placename}"
       else
-        results.push({:lat => lat, :lon => lon, :zoom => zoom,
-                      :prefix => "#{type} ", :name => name,
-                      :description => description})
+        suffix = ""
       end
+      results.push({:lat => lat, :lon => lon, :zoom => zoom,
+                    :prefix => prefix, :name => name, :suffix => suffix,
+                    :description => description})
     end
 
     return { :source => "OpenStreetMap Namefinder", :url => "http://www.frankieandshadow.com/osm/", :results => results }
@@ -158,4 +174,14 @@ private
     return "north-west" if bearing >= 292.5 and bearing < 337.5
     return "west"
   end
+
+  def count_results(results)
+    count = 0
+
+    results.each do |source|
+      count += source[:results].length if source[:results]
+    end
+
+    return count
+  end
 end