More search improvements - a "Where am I?" link that does a reverse
search, and various cleanups to the previous changes.
This commit is contained in:
parent
215958fa0f
commit
d2bd78627e
6 changed files with 73 additions and 4 deletions
|
@ -21,15 +21,32 @@ class GeocoderController < ApplicationController
|
|||
results_count = count_results(results)
|
||||
|
||||
render :update do |page|
|
||||
page.replace_html :search_results_content, :partial => 'results', :object => results
|
||||
|
||||
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
|
||||
|
||||
def description
|
||||
results = Array.new
|
||||
|
||||
lat = params[:lat]
|
||||
lon = params[:lon]
|
||||
|
||||
results.push description_osm_namefinder("cities", lat, lon, 2)
|
||||
results.push description_osm_namefinder("towns", lat, lon, 4)
|
||||
results.push description_osm_namefinder("places", lat, lon, 10)
|
||||
|
||||
render :update do |page|
|
||||
page.replace_html :search_results_content, :partial => 'results', :object => results
|
||||
page.call "openSearchResults"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
@ -151,6 +168,34 @@ private
|
|||
return { :source => "GeoNames", :url => "http://www.geonames.org/", :error => "Error contacting ws.geonames.org: #{ex.to_s}" }
|
||||
end
|
||||
|
||||
def description_osm_namefinder(types, lat, lon, max)
|
||||
results = Array.new
|
||||
|
||||
# ask OSM namefinder
|
||||
response = fetch_xml("http://www.frankieandshadow.com/osm/search.xml?find=#{types}+near+#{lat},#{lon}&max=#{max}")
|
||||
|
||||
# parse the response
|
||||
response.elements.each("searchresults/named") do |named|
|
||||
lat = named.attributes["lat"].to_s
|
||||
lon = named.attributes["lon"].to_s
|
||||
zoom = named.attributes["zoom"].to_s
|
||||
place = named.elements["place/named"] || named.elements["nearestplaces/named"]
|
||||
type = named.attributes["info"].to_s
|
||||
name = named.attributes["name"].to_s
|
||||
description = named.elements["description"].to_s
|
||||
distance = format_distance(place.attributes["approxdistance"].to_i)
|
||||
direction = format_direction(360 - place.attributes["direction"].to_i)
|
||||
prefix = "#{distance} #{direction} of #{type} "
|
||||
results.push({:lat => lat, :lon => lon, :zoom => zoom,
|
||||
:prefix => prefix.capitalize, :name => name,
|
||||
:description => description})
|
||||
end
|
||||
|
||||
return { :type => types.capitalize, :source => "OpenStreetMap Namefinder", :url => "http://www.frankieandshadow.com/osm/", :results => results }
|
||||
rescue Exception => ex
|
||||
return { :type => types.capitalize, :source => "OpenStreetMap Namefinder", :url => "http://www.frankieandshadow.com/osm/", :error => "Error contacting www.frankieandshadow.com: #{ex.to_s}" }
|
||||
end
|
||||
|
||||
def fetch_text(url)
|
||||
return Net::HTTP.get(URI.parse(url))
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<% results.each do |source| %>
|
||||
<p class="search_results_heading">Results from <%= link_to source[:source], source[:url] %></p>
|
||||
<% type = source[:type] || "Results" %>
|
||||
<p class="search_results_heading"><%= type %> from <%= link_to source[:source], source[:url] %></p>
|
||||
<% if source[:results] %>
|
||||
<% if source[:results].empty? %>
|
||||
<p class="search_results_entry">No results found</p>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<script type="text/javascript">
|
||||
<!--
|
||||
function startSearch() {
|
||||
$("search_results_content").innerHTML = "<p class='search_results_entry'>Searching...</p>";
|
||||
$("search_field").style.display = "none";
|
||||
$("search_active").style.display = "inline";
|
||||
}
|
||||
|
@ -31,6 +32,15 @@
|
|||
<%= onclose %>
|
||||
}
|
||||
|
||||
function describeLocation() {
|
||||
var position = getPosition();
|
||||
|
||||
<%= remote_function(:loading => "startSearch()",
|
||||
:complete => "endSearch()",
|
||||
:url => { :controller => :geocoder, :action => :description },
|
||||
:with => "'lat=' + position.lat + '&lon=' + position.lon") %>
|
||||
}
|
||||
|
||||
<% if params[:query] %>
|
||||
<%= remote_function(:loading => "startSearch()",
|
||||
:complete => "endSearch()",
|
||||
|
@ -42,6 +52,7 @@
|
|||
<% content_for "optionals" do %>
|
||||
<div class="optionalbox">
|
||||
<span class="oboxheader">Search</span>
|
||||
<span class="whereami"><a href="javascript:describeLocation()">Where am I?</a></span>
|
||||
<div class="search_form">
|
||||
<span id="search_field">
|
||||
<% form_remote_tag(:loading => "startSearch()",
|
||||
|
|
|
@ -102,6 +102,10 @@
|
|||
handleResize();
|
||||
}
|
||||
|
||||
function getPosition() {
|
||||
return mercatorToLonLat(map.getCenter());
|
||||
}
|
||||
|
||||
function setPosition(lat, lon, zoom) {
|
||||
var centre = lonLatToMercator(new OpenLayers.LonLat(lon, lat));
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ ActionController::Routing::Routes.draw do |map|
|
|||
|
||||
# geocoder
|
||||
map.connect '/geocoder/search', :controller => 'geocoder', :action => 'search'
|
||||
map.connect '/geocoder/description', :controller => 'geocoder', :action => 'description'
|
||||
|
||||
# messages
|
||||
|
||||
|
|
|
@ -338,8 +338,15 @@ hides rule from IE5-Mac \*/
|
|||
.oboxheader {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
line-height: 1.4em;
|
||||
text-align: top;
|
||||
line-height: 22px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.whereami {
|
||||
position: absolute;
|
||||
right: 21px;
|
||||
line-height: 22px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.optionalbox form {
|
||||
|
|
Loading…
Add table
Reference in a new issue