From e799022131f3e833179e9058060ec5e136ed2edd Mon Sep 17 00:00:00 2001 From: Steve Coast Date: Thu, 30 Nov 2006 18:44:40 +0000 Subject: [PATCH] rails API support for history of node/segment/way + various bugfixes and cleanups --- app/controllers/application.rb | 10 ++++++ app/controllers/node_controller.rb | 29 --------------- app/controllers/old_node_controller.rb | 20 +++++++++++ app/controllers/old_segment_controller.rb | 23 ++++++++++++ app/controllers/old_way_controller.rb | 17 +++++++++ app/controllers/segment_controller.rb | 31 ---------------- app/controllers/way_controller.rb | 3 +- app/models/old_node.rb | 11 ++++++ app/models/old_segment.rb | 10 ++++++ app/models/old_way.rb | 44 ++++++++++++++++++++++- app/models/segment.rb | 4 +-- app/models/way.rb | 4 ++- config/routes.rb | 8 ++--- 13 files changed, 145 insertions(+), 69 deletions(-) diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 366646ae3..0c8b4f17a 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -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 = '', '' diff --git a/app/controllers/node_controller.rb b/app/controllers/node_controller.rb index c1a43c898..5370306f3 100644 --- a/app/controllers/node_controller.rb +++ b/app/controllers/node_controller.rb @@ -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 diff --git a/app/controllers/old_node_controller.rb b/app/controllers/old_node_controller.rb index 0b6a0ee29..99e0b5675 100644 --- a/app/controllers/old_node_controller.rb +++ b/app/controllers/old_node_controller.rb @@ -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 diff --git a/app/controllers/old_segment_controller.rb b/app/controllers/old_segment_controller.rb index e07026fa4..1971e5dca 100644 --- a/app/controllers/old_segment_controller.rb +++ b/app/controllers/old_segment_controller.rb @@ -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 diff --git a/app/controllers/old_way_controller.rb b/app/controllers/old_way_controller.rb index 9c3a257c4..8eca507ef 100644 --- a/app/controllers/old_way_controller.rb +++ b/app/controllers/old_way_controller.rb @@ -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 diff --git a/app/controllers/segment_controller.rb b/app/controllers/segment_controller.rb index 91b9ec7e5..9315bce77 100644 --- a/app/controllers/segment_controller.rb +++ b/app/controllers/segment_controller.rb @@ -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 diff --git a/app/controllers/way_controller.rb b/app/controllers/way_controller.rb index b443a67c0..3a11d8a60 100644 --- a/app/controllers/way_controller.rb +++ b/app/controllers/way_controller.rb @@ -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 diff --git a/app/models/old_node.rb b/app/models/old_node.rb index 2b18b819e..7b6162d8d 100644 --- a/app/models/old_node.rb +++ b/app/models/old_node.rb @@ -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 diff --git a/app/models/old_segment.rb b/app/models/old_segment.rb index 26e2b6abb..315f4dda7 100644 --- a/app/models/old_segment.rb +++ b/app/models/old_segment.rb @@ -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 diff --git a/app/models/old_way.rb b/app/models/old_way.rb index db0108ea8..6682c644a 100644 --- a/app/models/old_way.rb +++ b/app/models/old_way.rb @@ -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 diff --git a/app/models/segment.rb b/app/models/segment.rb index 35d6889d2..ddfc3db03 100644 --- a/app/models/segment.rb +++ b/app/models/segment.rb @@ -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 diff --git a/app/models/way.rb b/app/models/way.rb index 0c53e5e87..43bd4d8c3 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -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 diff --git a/config/routes.rb b/config/routes.rb index 3f4b9904e..33a6dc13a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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' -- 2.43.2