replace whichways with rails-friendly code
[rails.git] / app / models / node.rb
1 class Node < GeoRecord
2   require 'xml/libxml'
3
4   set_table_name 'current_nodes'
5   
6   validates_presence_of :user_id, :timestamp
7   validates_inclusion_of :visible, :in => [ true, false ]
8   validates_numericality_of :latitude, :longitude
9   validate :validate_position
10
11   has_many :old_nodes, :foreign_key => :id
12   has_many :way_nodes
13   belongs_to :user
14  
15   def validate_position
16     errors.add_to_base("Node is not in the world") unless in_world?
17   end
18
19   def in_world?
20     return false if self.lat < -90 or self.lat > 90
21     return false if self.lon < -180 or self.lon > 180
22     return true
23   end
24
25   def self.from_xml(xml, create=false)
26     begin
27       p = XML::Parser.new
28       p.string = xml
29       doc = p.parse
30   
31       node = Node.new
32
33       doc.find('//osm/node').each do |pt|
34         node.lat = pt['lat'].to_f
35         node.lon = pt['lon'].to_f
36
37         return nil unless node.in_world?
38
39         unless create
40           if pt['id'] != '0'
41             node.id = pt['id'].to_i
42           end
43         end
44
45         node.visible = pt['visible'] and pt['visible'] == 'true'
46
47         if create
48           node.timestamp = Time.now
49         else
50           if pt['timestamp']
51             node.timestamp = Time.parse(pt['timestamp'])
52           end
53         end
54
55         tags = []
56
57         pt.find('tag').each do |tag|
58           tags << [tag['k'],tag['v']]
59         end
60
61         node.tags = Tags.join(tags)
62       end
63     rescue
64       node = nil
65     end
66
67     return node
68   end
69
70   def save_with_history!
71     Node.transaction do
72       self.timestamp = Time.now
73       self.save!
74       old_node = OldNode.from_node(self)
75       old_node.save!
76     end
77   end
78
79   def to_xml
80     doc = OSM::API.new.get_xml_doc
81     doc.root << to_xml_node()
82     return doc
83   end
84
85   def to_xml_node(user_display_name_cache = nil)
86     el1 = XML::Node.new 'node'
87     el1['id'] = self.id.to_s
88     el1['lat'] = self.lat.to_s
89     el1['lon'] = self.lon.to_s
90
91     user_display_name_cache = {} if user_display_name_cache.nil?
92
93     if user_display_name_cache and user_display_name_cache.key?(self.user_id)
94       # use the cache if available
95     elsif self.user.data_public?
96       user_display_name_cache[self.user_id] = self.user.display_name
97     else
98       user_display_name_cache[self.user_id] = nil
99     end
100
101     el1['user'] = user_display_name_cache[self.user_id] unless user_display_name_cache[self.user_id].nil?
102
103     Tags.split(self.tags) do |k,v|
104       el2 = XML::Node.new('tag')
105       el2['k'] = k.to_s
106       el2['v'] = v.to_s
107       el1 << el2
108     end
109
110     el1['visible'] = self.visible.to_s
111     el1['timestamp'] = self.timestamp.xmlschema
112     return el1
113   end
114
115   def tags_as_hash
116     hash = {}
117     Tags.split(self.tags) do |k,v|
118       hash[k] = v
119     end
120     hash
121   end
122
123 end