API 0.4 Updates - work on traces pages + pagination, edit tab, some API testing
[rails.git] / app / models / node.rb
1 class Node < ActiveRecord::Base
2   require 'xml/libxml'
3   set_table_name 'current_nodes'
4   
5
6   validates_numericality_of :latitude
7   validates_numericality_of :longitude
8   # FIXME validate lat and lon within the world
9
10   has_many :old_nodes, :foreign_key => :id
11   belongs_to :user
12
13
14   def self.from_xml(xml, create=false)
15     p = XML::Parser.new
16     p.string = xml
17     doc = p.parse
18
19     node = Node.new
20
21     doc.find('//osm/node').each do |pt|
22
23
24       node.latitude = pt['lat'].to_f
25       node.longitude = pt['lon'].to_f
26
27       if node.latitude > 90 or node.latitude < -90 or node.longitude > 180 or node.longitude < -180
28         return nil
29       end
30
31       unless create
32         if pt['id'] != '0'
33           node.id = pt['id'].to_i
34         end
35       end
36
37       node.visible = pt['visible'] and pt['visible'] == 'true'
38
39       if create
40         node.timestamp = Time.now
41       else
42         if pt['timestamp']
43           node.timestamp = Time.parse(pt['timestamp'])
44         end
45       end
46
47       tags = []
48
49       pt.find('tag').each do |tag|
50         tags << [tag['k'],tag['v']]
51       end
52
53       tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';')
54       tags = '' if tags.nil?
55
56       node.tags = tags
57
58     end
59     return node
60   end
61
62   def save_with_history
63     begin
64       Node.transaction do
65         self.save
66         old_node = OldNode.from_node(self)
67         old_node.save
68       end
69       return true
70     rescue Exception => ex
71       return nil
72     end
73   end
74
75   def to_xml
76     doc = XML::Document.new
77     doc.encoding = 'UTF-8' 
78     root = XML::Node.new 'osm'
79     root['version'] = API_VERSION
80     root['generator'] = 'OpenStreetMap server'
81     doc.root = root
82     root << to_xml_node()
83     return doc
84   end
85
86   def to_xml_node
87     el1 = XML::Node.new 'node'
88     el1['id'] = self.id.to_s
89     el1['lat'] = self.latitude.to_s
90     el1['lon'] = self.longitude.to_s
91     Node.split_tags(el1, self.tags)
92     el1['visible'] = self.visible.to_s
93     el1['timestamp'] = self.timestamp.xmlschema
94     return el1
95   end
96
97   def self.split_tags(el, tags)
98     tags.split(';').each do |tag|
99       parts = tag.split('=')
100       key = ''
101       val = ''
102       key = parts[0].strip unless parts[0].nil?
103       val = parts[1].strip unless parts[1].nil?
104       if key != '' && val != ''
105         el2 = XML::Node.new('tag')
106         el2['k'] = key.to_s
107         el2['v'] = val.to_s
108         el << el2
109       end
110     end
111   end
112 end