Return usernames correctly.
[rails.git] / app / models / way.rb
1 class Way < ActiveRecord::Base
2   require 'xml/libxml'
3   
4   belongs_to :user
5
6   has_many :way_segments, :foreign_key => 'id'
7   has_many :way_tags, :foreign_key => 'id'
8
9   has_many :old_ways, :foreign_key => :id
10
11   set_table_name 'current_ways'
12
13   def self.from_xml(xml, create=false)
14     p = XML::Parser.new
15     p.string = xml
16     doc = p.parse
17
18     way = Way.new
19
20     doc.find('//osm/way').each do |pt|
21       if !create and pt['id'] != '0'
22         way.id = pt['id'].to_i
23       end
24
25       if create
26         way.timestamp = Time.now
27         way.visible = true
28       else
29         if pt['timestamp']
30           way.timestamp = Time.parse(pt['timestamp'])
31         end
32       end
33
34       pt.find('tag').each do |tag|
35         way.add_tag_keyval(tag['k'], tag['v'])
36       end
37
38       pt.find('seg').each do |seg|
39         way.add_seg_num(seg['id'])
40       end
41
42     end
43
44     return way
45   end
46
47   def to_xml
48     doc = OSM::API.new.get_xml_doc
49     doc.root << to_xml_node()
50     return doc
51   end
52
53   def to_xml_node(visible_segments = nil, user_display_name_cache = nil)
54     el1 = XML::Node.new 'way'
55     el1['id'] = self.id.to_s
56     el1['visible'] = self.visible.to_s
57     el1['timestamp'] = self.timestamp.xmlschema
58
59     user_display_name_cache = {} if user_display_name_cache.nil?
60     
61     if user_display_name_cache and user_display_name_cache[self.user_id]
62       # use the cache if available
63     elsif self.user.data_public?
64       user_display_name_cache[self.user_id] = self.user.display_name
65     else
66       user_display_name_cache[self.user_id] = nil
67     end
68
69     el1['user'] = user_display_name_cache[self.user_id] unless user_display_name_cache[self.user_id].nil?
70
71     # make sure segments are output in sequence_id order
72     ordered_segments = []
73     self.way_segments.each do |seg|
74       if visible_segments
75         # if there is a list of visible segments then use that to weed out deleted segments
76         if visible_segments[seg.segment_id]
77           ordered_segments[seg.sequence_id] = seg.segment_id.to_s
78         end
79       else
80         # otherwise, manually go to the db to check things
81         if seg.segment.visible? and seg.segment.from_node.visible? and seg.segment.to_node.visible?
82           ordered_segments[seg.sequence_id] = seg.segment_id.to_s
83         end
84       end
85     end
86
87     ordered_segments.each do |seg_id|
88       if seg_id and seg_id != '0'
89         e = XML::Node.new 'seg'
90         e['id'] = seg_id
91         el1 << e
92       end
93     end
94  
95     self.way_tags.each do |tag|
96       e = XML::Node.new 'tag'
97       e['k'] = tag.k
98       e['v'] = tag.v
99       el1 << e
100     end
101     return el1
102   end 
103
104   def segs
105     unless @segs
106         @segs = Array.new
107         self.way_segments.each do |seg|
108             @segs += [seg.segment_id]
109         end
110     end
111     @segs
112   end
113
114   def tags
115     unless @tags
116         @tags = Hash.new
117         self.way_tags.each do |tag|
118             @tags[tag.k] = tag.v
119         end
120     end
121     @tags
122   end
123
124   def segs=(s)
125     @segs = s
126   end
127
128   def tags=(t)
129     @tags = t
130   end
131
132   def add_seg_num(n)
133     @segs = Array.new unless @segs
134     @segs << n.to_i
135   end
136
137   def add_tag_keyval(k, v)
138     @tags = Hash.new unless @tags
139     @tags[k] = v
140   end
141
142   def save_with_history
143     t = Time.now
144     self.timestamp = t
145     self.save
146     
147     WayTag.delete_all(['id = ?', self.id])
148
149     self.tags.each do |k,v|
150       tag = WayTag.new
151       tag.k = k
152       tag.v = v
153       tag.id = self.id
154       tag.save
155     end
156
157     WaySegment.delete_all(['id = ?', self.id])
158     
159     i = 0
160     self.segs.each do |n|
161       seg = WaySegment.new
162       seg.id = self.id
163       seg.segment_id = n
164       seg.sequence_id = i
165       seg.save
166       i += 1
167     end
168
169     old_way = OldWay.from_way(self)
170     old_way.timestamp = t
171     old_way.save_with_dependencies
172   end
173
174   def preconditions_ok?
175     self.segs.each do |n|
176       segment = Segment.find(n)
177       unless segment and segment.visible and segment.preconditions_ok?
178         return false
179       end
180     end
181     return true
182   end
183
184 end