rails_port_0.5: Merge rails_port r4664.
[rails.git] / app / controllers / search_controller.rb
1 class SearchController < ApplicationController
2   # Support searching for nodes, ways, or all
3   # Can search by tag k, v, or both (type->k,value->v)
4   # Can search by name (k=name,v=....)
5
6   after_filter :compress_output
7
8   def search_all
9     do_search(true,true)
10   end
11
12   def search_ways
13     do_search(true,false)
14   end
15   def search_nodes
16     do_search(false,true)
17   end
18
19
20   def do_search(do_ways,do_nodes)
21     type = params['type']
22     value = params['value']
23     unless type or value
24       name = params['name']
25       if name
26         type = 'name'
27         value = name
28       end
29     end
30
31     way_ids = Array.new
32     ways = Array.new
33     nodes = Array.new
34
35     # Matching for tags table
36     cond_tbl = Array.new
37     sql = 'id IN (SELECT id FROM current_way_tags WHERE 1=1'
38     if type
39       sql += ' AND k=?'
40       cond_tbl += [type]
41     end
42     if value
43       sql += ' AND v=?'
44       cond_tbl += [value]
45     end
46     sql += ')'
47     cond_tbl = [sql] + cond_tbl
48
49     # Matching for tags column
50     if type and value
51       cond_tags = ['tags LIKE ? OR tags LIKE ? OR tags LIKE ? OR tags LIKE ?', 
52       ''+type+'='+value+'',
53       ''+type+'='+value+';%',
54       '%;'+type+'='+value+';%',
55       '%;'+type+'='+value+'' ]
56     elsif type
57       cond_tags = ['tags LIKE ? OR tags LIKE ?',
58       ''+type+'=%',
59       '%;'+type+'=%' ]
60     elsif value
61       cond_tags = ['tags LIKE ? OR tags LIKE ?',
62       '%='+value+';%',
63       '%='+value+'' ]
64     else
65       cond_tags = ['1=1']
66     end
67
68
69     # First up, look for the ways we want
70     if do_ways
71       ways = Way.find(:all, :conditions => cond_tbl, :limit => 100)
72     end
73
74     # Now, nodes
75     if do_nodes
76       nodes = Node.find(:all, :conditions => cond_tags, :limit => 2000)
77     end
78
79     # Fetch any node needed for our ways (only have matching nodes so far)
80     nodes += Node.find(ways.collect { |w| w.nds }.uniq)
81
82     # Print
83     user_display_name_cache = {}
84     doc = OSM::API.new.get_xml_doc
85     nodes.each do |node|
86       doc.root << node.to_xml_node(user_display_name_cache)
87     end
88
89     ways.each do |way|
90       doc.root << way.to_xml_node(user_display_name_cache)
91     end 
92
93     render :text => doc.to_s, :content_type => "text/xml"
94   end
95 end