rails API support for history of node/segment/way + various bugfixes and cleanups
authorSteve Coast <steve@asklater.com>
Thu, 30 Nov 2006 18:44:40 +0000 (18:44 +0000)
committerSteve Coast <steve@asklater.com>
Thu, 30 Nov 2006 18:44:40 +0000 (18:44 +0000)
13 files changed:
app/controllers/application.rb
app/controllers/node_controller.rb
app/controllers/old_node_controller.rb
app/controllers/old_segment_controller.rb
app/controllers/old_way_controller.rb
app/controllers/segment_controller.rb
app/controllers/way_controller.rb
app/models/old_node.rb
app/models/old_segment.rb
app/models/old_way.rb
app/models/segment.rb
app/models/way.rb
config/routes.rb

index 366646ae395a27da1bfce1d00f77e3d7c359a3a2..0c8b4f17a8d369d9dbfa802c64ec449d63276042 100644 (file)
@@ -27,6 +27,16 @@ class ApplicationController < ActionController::Base
     end 
   end 
 
+  def get_xml_doc
+    doc = XML::Document.new
+    doc.encoding = 'UTF-8' 
+    root = XML::Node.new 'osm'
+    root['version'] = API_VERSION
+    root['generator'] = 'OpenStreetMap server'
+    doc.root = root
+    return doc
+  end
+
   private 
   def get_auth_data 
     user, pass = '', '' 
index c1a43c8984f610dd714fea5b8e8324607af4d2ae..5370306f3b4cd1bf7cf4118022e811a1cc421c72 100644 (file)
@@ -87,33 +87,4 @@ class NodeController < ApplicationController
 
   end
 
-  def history
-    response.headers["Content-Type"] = 'application/xml'
-    node = Node.find(params[:id])
-
-    unless node
-      render :nothing => true, :staus => 404
-      return
-    end
-
-    doc = XML::Document.new
-    doc.encoding = 'UTF-8' 
-    root = XML::Node.new 'osm'
-    root['version'] = '0.4'
-    root['generator'] = 'OpenStreetMap server'
-    doc.root = root
-
-    node.old_nodes.each do |old_node|
-      el1 = XML::Node.new 'node'
-      el1['id'] = old_node.id.to_s
-      el1['lat'] = old_node.latitude.to_s
-      el1['lon'] = old_node.longitude.to_s
-      Node.split_tags(el1, old_node.tags)
-      el1['visible'] = old_node.visible.to_s
-      el1['timestamp'] = old_node.timestamp.xmlschema
-      root << el1
-    end
-
-    render :text => doc.to_s
-  end
 end
index 0b6a0ee290612cd6c366c69a404314af505262ac..99e0b5675497a09224044bedfd6433c4b4200f26 100644 (file)
@@ -1,2 +1,22 @@
 class OldNodeController < ApplicationController
+
+  def history
+    response.headers["Content-Type"] = 'application/xml'
+    node = Node.find(params[:id])
+
+    unless node
+      render :nothing => true, :staus => 404
+      return
+    end
+
+    doc = get_xml_doc
+
+    node.old_nodes.each do |old_node|
+      doc.root << old_node.to_xml_node
+    end
+
+    render :text => doc.to_s
+  end
+
+
 end
index e07026fa46f61883734a16ff62fef7f46040054e..1971e5dcadf72a745a4ecd1a76f16a40a02c0323 100644 (file)
@@ -1,2 +1,25 @@
 class OldSegmentController < ApplicationController
+
+  def history
+    response.headers["Content-Type"] = 'application/xml'
+    segment = Segment.find(params[:id])
+
+    unless segment
+      render :nothing => true, :staus => 404
+      return
+    end
+
+    doc = get_xml_doc
+
+    segment.old_segments.each do |old_segment|
+      doc.root << old_segment.to_xml_node
+    end
+
+    render :text => doc.to_s
+  end
+
+
+
+
+
 end
index 9c3a257c47154de102a3651ee1cb1fdba3016159..8eca507ef91b96c12aee0198debec05d24861f8c 100644 (file)
@@ -1,4 +1,21 @@
 class OldWayController < ApplicationController
+  def history
+    response.headers["Content-Type"] = 'application/xml'
+    way = Way.find(params[:id])
+
+    unless way
+      render :nothing => true, :staus => 404
+      return
+    end
+    
+    doc = get_xml_doc
+
+    way.old_ways.each do |old_way|
+      doc.root << old_way.to_xml_node
+    end
+
+    render :text => doc.to_s
+  end
 
 
 end
index 91b9ec7e5da084b3501d874a75e87bc1ead2f4ec..9315bce778e6262433a10e1416f780c93a6b7306 100644 (file)
@@ -80,35 +80,4 @@ class SegmentController < ApplicationController
 
   end
 
-  def history
-    response.headers["Content-Type"] = 'application/xml'
-    segment = Segment.find(params[:id])
-
-    unless segment
-      render :nothing => true, :staus => 404
-      return
-    end
-
-    doc = XML::Document.new
-    doc.encoding = 'UTF-8' 
-    root = XML::Node.new 'osm'
-    root['version'] = '0.4'
-    root['generator'] = 'OpenStreetMap server'
-    doc.root = root
-
-    segment.old_segments.each do |old_segment|
-      el1 = XML::Node.new 'segment'
-      el1['id'] = old_segment.id.to_s
-      el1['from'] = old_segment.node_a.to_s
-      el1['to'] = old_segment.node_b.to_s
-      Segment.split_tags(el1, old_segment.tags)
-      el1['visible'] = old_segment.visible.to_s
-      el1['timestamp'] = old_segment.timestamp.xmlschema
-      root << el1
-    end
-
-    render :text => doc.to_s
-  end
-
-
 end
index b443a67c00ec47a8d0f65424540f7ba18da41641..3a11d8a6054f5cb6c92bd15f7e45868131b34de4 100644 (file)
@@ -51,7 +51,7 @@ class WayController < ApplicationController
       render :nothing => true
       return
     when :put
-      way = Way.from_xml(request.raw_post, true)
+      way = Way.from_xml(request.raw_post)
 
       if way
         way_in_db = Way.find(way.id)
@@ -76,4 +76,5 @@ class WayController < ApplicationController
       end
     end
   end
+
 end
index 2b18b819e896656e58a2ac5bbebef8a193685900..7b6162d8d0e612b68a44942dd2abe326dba6daee 100644 (file)
@@ -15,4 +15,15 @@ class OldNode < ActiveRecord::Base
     return old_node
   end
 
+  def to_xml_node
+    el1 = XML::Node.new 'node'
+    el1['id'] = self.id.to_s
+    el1['lat'] = self.latitude.to_s
+    el1['lon'] = self.longitude.to_s
+    Node.split_tags(el1, self.tags)
+    el1['visible'] = self.visible.to_s
+    el1['timestamp'] = self.timestamp.xmlschema
+    return el1
+  end
+
 end
index 26e2b6abb7535c86538e7e75d97b7d2541e8b80f..315f4dda76b2c06fd58fdda3c2838cc4376b99cb 100644 (file)
@@ -15,4 +15,14 @@ class OldSegment < ActiveRecord::Base
     return old_segment
   end
 
+  def to_xml_node
+    el1 = XML::Node.new 'segment'
+    el1['id'] = self.id.to_s
+    el1['from'] = self.node_a.to_s
+    el1['to'] = self.node_b.to_s
+    Segment.split_tags(el1, self.tags)
+    el1['visible'] = self.visible.to_s
+    el1['timestamp'] = self.timestamp.xmlschema
+    return el1
+  end
 end
index db0108ea8f47232c0754899cb216a653579e4700..6682c644a613b0140acdb5e3b0648b59002b57a8 100644 (file)
@@ -14,8 +14,19 @@ class OldWay < ActiveRecord::Base
   end
 
   def save_with_dependencies
+
+    # dont touch this unless you really have figured out why it's called
+    # (Rails doesn't deal well with the old ways table (called 'ways') because
+    # it doesn't have a unique key. It knows how to insert and auto_increment
+    # id and get it back but we have that and we want to get the 'version' back
+    # we could add another column but thats a lot of data. No, set_primary_key
+    # doesn't work either.
     save()
-    self.reload()
+    clear_aggregation_cache
+    clear_association_cache
+    @attributes.update(OldWay.find(:first, :conditions => ['id = ? AND timestamp = ?', self.id, self.timestamp]).instance_variable_get('@attributes'))
+
+    # ok, you can touch from here on
 
     self.tags.each do |k,v|
       tag = OldWayTag.new
@@ -54,4 +65,35 @@ class OldWay < ActiveRecord::Base
     @tags = t
   end
 
+#  has_many :way_segments, :class_name => 'OldWaySegment', :foreign_key => 'id'
+#  has_many :way_tags, :class_name => 'OldWayTag', :foreign_key => 'id'
+
+  def old_segments
+    OldWaySegment.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])    
+  end
+
+  def old_tags
+    OldWayTag.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])    
+  end
+
+  def to_xml_node
+    el1 = XML::Node.new 'way'
+    el1['id'] = self.id.to_s
+    el1['visible'] = self.visible.to_s
+    el1['timestamp'] = self.timestamp.xmlschema
+    
+    self.old_segments.each do |seg| # FIXME need to make sure they come back in the right order
+      e = XML::Node.new 'seg'
+      e['id'] = seg.segment_id.to_s
+      el1 << e
+    end
+    self.old_tags.each do |tag|
+      e = XML::Node.new 'tag'
+      e['k'] = tag.k
+      e['v'] = tag.v
+      el1 << e
+    end
+    return el1
+  end 
 end
index 35d6889d26964576a5bc53ae2130e9224e320e26..ddfc3db03ca918952f6f76341d5e8f44f2ec4d25 100644 (file)
@@ -26,7 +26,7 @@ class Segment < ActiveRecord::Base
         segment.id = pt['id'].to_i
       end
 
-      segment.visible = pt['visible'] and pt['visible'] == 'true'
+      segment.visible = true
 
       if create
         segment.timestamp = Time.now
@@ -94,7 +94,7 @@ class Segment < ActiveRecord::Base
       key = parts[0].strip unless parts[0].nil?
       val = parts[1].strip unless parts[1].nil?
       if key != '' && val != ''
-        el2 = Segment.new('tag')
+        el2 = XML::Node.new('tag')
         el2['k'] = key.to_s
         el2['v'] = val.to_s
         el << el2
index 0c53e5e87c08ce090b7a05561a001ea54c9705c6..43bd4d8c394dae334a1016a9dbb1cc5a9bca4e0b 100644 (file)
@@ -6,6 +6,8 @@ class Way < ActiveRecord::Base
   has_many :way_segments, :foreign_key => 'id'
   has_many :way_tags, :foreign_key => 'id'
 
+  has_many :old_ways, :foreign_key => :id
+
   set_table_name 'current_ways'
 
   def self.from_xml(xml, create=false)
@@ -16,7 +18,7 @@ class Way < ActiveRecord::Base
     way = Way.new
 
     doc.find('//osm/way').each do |pt|
-      unless create and pt['id'] == '0'
+      if !create and pt['id'] != '0'
         way.id = pt['id'].to_i
       end
 
index 3f4b9904efb2f6a8388e6a48414bc3460b3ea54e..33a6dc13adce465bc62060b66f6bb23f7803df05 100644 (file)
@@ -3,16 +3,16 @@ ActionController::Routing::Routes.draw do |map|
   # API
   API_VERSION = '0.4' # change this in envronment.rb too
   map.connect "api/#{API_VERSION}/node/create", :controller => 'node', :action => 'create'
-  map.connect "api/#{API_VERSION}/node/:id/history", :controller => 'node', :action => 'history', :id => nil
+  map.connect "api/#{API_VERSION}/node/:id/history", :controller => 'old_node', :action => 'history', :id => nil
   map.connect "api/#{API_VERSION}/node/:id", :controller => 'node', :action => 'rest', :id => nil
 
   map.connect "api/#{API_VERSION}/segment/create", :controller => 'segment', :action => 'create'
-  map.connect "api/#{API_VERSION}/segment/:id/history", :controller => 'segment', :action => 'history'
+  map.connect "api/#{API_VERSION}/segment/:id/history", :controller => 'old_segment', :action => 'history'
   map.connect "api/#{API_VERSION}/segment/:id", :controller => 'segment', :action => 'rest'
 
   map.connect "api/#{API_VERSION}/way/create", :controller => 'way', :action => 'create'
-  map.connect "api/#{API_VERSION}/way/:id/history", :controller => 'way', :action => 'history'
-  map.connect "api/#{API_VERSION}/way/:id", :controller => 'way', :action => 'rest'
+  map.connect "api/#{API_VERSION}/way/:id/history", :controller => 'old_way', :action => 'history', :id => nil
+  map.connect "api/#{API_VERSION}/way/:id", :controller => 'way', :action => 'rest', :id => nil
 
   map.connect "api/#{API_VERSION}/map", :controller => 'api', :action => 'map'