source: subversion/sites/rails_port/app/models/way.rb @ 3375

Last change on this file since 3375 was 3375, checked in by tomhughes, 13 years ago

Make negative caching of users work.

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