preliminary commit 0.5 API with relations / untested after entity-relation rename, some changes still in queue
This commit is contained in:
parent
02451061ce
commit
78b440ffc1
46 changed files with 1841 additions and 231 deletions
|
@ -195,12 +195,12 @@ EOF
|
|||
|
||||
RAILS_DEFAULT_LOGGER.info(" Message: whichways, bbox=#{xmin},#{ymin},#{xmax},#{ymax}")
|
||||
|
||||
waylist=WaySegment.find_by_sql("SELECT DISTINCT current_way_segments.id AS wayid"+
|
||||
" FROM current_way_segments,current_segments,current_nodes,current_ways "+
|
||||
waylist=WayNode.find_by_sql("SELECT DISTINCT current_way_nodes.id AS wayid"+
|
||||
" FROM current_way_nodes,current_segments,current_nodes,current_ways "+
|
||||
" WHERE segment_id=current_segments.id "+
|
||||
" AND current_segments.visible=1 "+
|
||||
" AND node_a=current_nodes.id "+
|
||||
" AND current_ways.id=current_way_segments.id "+
|
||||
" AND current_ways.id=current_way_nodes.id "+
|
||||
" AND current_ways.visible=1 "+
|
||||
" AND (latitude BETWEEN "+ymin.to_s+" AND "+ymax.to_s+") "+
|
||||
" AND (longitude BETWEEN "+xmin.to_s+" AND "+xmax.to_s+")")
|
||||
|
@ -403,7 +403,7 @@ EOF
|
|||
ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqs}")
|
||||
ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqn}")
|
||||
|
||||
# insert new version of route into way_segments
|
||||
# insert new version of route into way_nodes
|
||||
|
||||
insertsql =''
|
||||
currentsql=''
|
||||
|
@ -417,9 +417,9 @@ EOF
|
|||
sequence +=1
|
||||
end
|
||||
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_segments WHERE id=#{way}");
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO way_segments (id,segment_id,version ) VALUES #{insertsql}");
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO current_way_segments (id,segment_id,sequence_id) VALUES #{currentsql}");
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_nodes WHERE id=#{way}");
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO way_nodes (id,segment_id,version ) VALUES #{insertsql}");
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO current_way_nodes (id,segment_id,sequence_id) VALUES #{currentsql}");
|
||||
|
||||
# -- 7. insert new way tags
|
||||
|
||||
|
@ -503,7 +503,7 @@ EOF
|
|||
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO ways (id,user_id,timestamp,visible) VALUES (#{way},#{uid},#{db_now},0)")
|
||||
ActiveRecord::Base.connection.update("UPDATE current_ways SET user_id=#{uid},timestamp=#{db_now},visible=0 WHERE id=#{way}")
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_segments WHERE id=#{way}")
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_nodes WHERE id=#{way}")
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_tags WHERE id=#{way}")
|
||||
|
||||
way
|
||||
|
@ -537,7 +537,7 @@ def makeway(args)
|
|||
FROM current_nodes AS cn1,
|
||||
current_nodes AS cn2,
|
||||
current_segments AS cs
|
||||
LEFT OUTER JOIN current_way_segments ON segment_id=cs.id
|
||||
LEFT OUTER JOIN current_way_nodes ON segment_id=cs.id
|
||||
WHERE (cn1.longitude BETWEEN #{xs1} AND #{xs2})
|
||||
AND (cn1.latitude BETWEEN #{ys1} AND #{ys2})
|
||||
AND segment_id IS NULL
|
||||
|
@ -603,7 +603,7 @@ def findconnect(id,nodesused,lookfor,toreverse,baselong,basey,masterscale)
|
|||
FROM current_nodes AS cn1,
|
||||
current_nodes AS cn2,
|
||||
current_segments AS cs
|
||||
LEFT OUTER JOIN current_way_segments ON segment_id=cs.id
|
||||
LEFT OUTER JOIN current_way_nodes ON segment_id=cs.id
|
||||
WHERE segment_id IS NULL
|
||||
AND cs.visible=1
|
||||
AND cn1.id=node_a AND cn1.visible=1
|
||||
|
@ -615,7 +615,7 @@ def findconnect(id,nodesused,lookfor,toreverse,baselong,basey,masterscale)
|
|||
FROM current_nodes AS cn1,
|
||||
current_nodes AS cn2,
|
||||
current_segments AS cs
|
||||
LEFT OUTER JOIN current_way_segments ON segment_id=cs.id
|
||||
LEFT OUTER JOIN current_way_nodes ON segment_id=cs.id
|
||||
WHERE segment_id IS NULL
|
||||
AND cs.visible=1
|
||||
AND cn1.id=node_a AND cn1.visible=1
|
||||
|
@ -663,8 +663,8 @@ end
|
|||
def readwayquery(id)
|
||||
ActiveRecord::Base.connection.select_all "SELECT n1.latitude AS lat1,n1.longitude AS long1,n1.id AS id1,n1.tags as tags1, "+
|
||||
" n2.latitude AS lat2,n2.longitude AS long2,n2.id AS id2,n2.tags as tags2,segment_id "+
|
||||
" FROM current_way_segments,current_segments,current_nodes AS n1,current_nodes AS n2 "+
|
||||
" WHERE current_way_segments.id=#{id} "+
|
||||
" FROM current_way_nodes,current_segments,current_nodes AS n1,current_nodes AS n2 "+
|
||||
" WHERE current_way_nodes.id=#{id} "+
|
||||
" AND segment_id=current_segments.id "+
|
||||
" AND current_segments.visible=1 "+
|
||||
" AND n1.id=node_a and n2.id=node_b "+
|
||||
|
@ -677,9 +677,9 @@ def createuniquesegments(way,uqs_name,seglist)
|
|||
sql=<<-EOF
|
||||
CREATE TEMPORARY TABLE #{uqs_name}
|
||||
SELECT a.segment_id
|
||||
FROM (SELECT DISTINCT segment_id FROM current_way_segments
|
||||
FROM (SELECT DISTINCT segment_id FROM current_way_nodes
|
||||
WHERE id = #{way}) a
|
||||
LEFT JOIN current_way_segments b
|
||||
LEFT JOIN current_way_nodes b
|
||||
ON b.segment_id = a.segment_id
|
||||
AND b.id != #{way}
|
||||
WHERE b.segment_id IS NULL
|
||||
|
|
|
@ -136,12 +136,14 @@ class ApiController < ApplicationController
|
|||
# check the bbox isn't too large
|
||||
requested_area = (max_lat-min_lat)*(max_lon-min_lon)
|
||||
if requested_area > MAX_REQUEST_AREA
|
||||
report_error("The maximum bbox size is " + MAX_REQUEST_AREA.to_s + ", and your request was too large. Either request a smaller area, or use planet.osm")
|
||||
report_error("The maximum bbox size is " + MAX_REQUEST_AREA.to_s +
|
||||
", and your request was too large. Either request a smaller area, or use planet.osm")
|
||||
return
|
||||
end
|
||||
|
||||
# get all the nodes
|
||||
nodes = Node.find(:all, :conditions => ['latitude > ? AND longitude > ? AND latitude < ? AND longitude < ? AND visible = 1', min_lat, min_lon, max_lat, max_lon])
|
||||
nodes = Node.find(:all, :conditions =>
|
||||
['latitude > ? AND longitude > ? AND latitude < ? AND longitude < ? AND visible = 1', min_lat, min_lon, max_lat, max_lon])
|
||||
|
||||
node_ids = nodes.collect {|node| node.id }
|
||||
|
||||
|
@ -151,68 +153,38 @@ class ApiController < ApplicationController
|
|||
end
|
||||
|
||||
if node_ids.length == 0
|
||||
render :text => "<osm version='0.4'></osm>", :content_type => "text/xml"
|
||||
render :text => "<osm version='0.5'></osm>", :content_type => "text/xml"
|
||||
return
|
||||
end
|
||||
|
||||
# grab the segments
|
||||
segments = Array.new
|
||||
if node_ids.length > 0
|
||||
node_ids_sql = "(#{node_ids.join(',')})"
|
||||
# get the referenced segments
|
||||
segments = Segment.find_by_sql "select * from current_segments where visible = 1 and (node_a in #{node_ids_sql} or node_b in #{node_ids_sql})"
|
||||
end
|
||||
# see if we have any missing nodes
|
||||
segments_nodes = segments.collect {|segment| segment.node_a }
|
||||
segments_nodes += segments.collect {|segment| segment.node_b }
|
||||
|
||||
segments_nodes.uniq!
|
||||
|
||||
missing_nodes = segments_nodes - node_ids
|
||||
|
||||
# get missing nodes if there are any
|
||||
nodes += Node.find(missing_nodes) if missing_nodes.length > 0
|
||||
relations = Array.new
|
||||
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
|
||||
# get ways
|
||||
# find which ways are needed
|
||||
segment_ids = segments.collect {|segment| segment.id }
|
||||
ways = Array.new
|
||||
if segment_ids.length > 0
|
||||
way_segments = WaySegment.find_all_by_segment_id(segment_ids)
|
||||
way_ids = way_segments.collect {|way_segment| way_segment.id }
|
||||
ways = Way.find(way_ids) # NB: doesn't pick up segments, tags from db until accessed via way.way_segments etc.
|
||||
if node_ids.length > 0
|
||||
way_nodes = WayNode.find_all_by_node_id(node_ids)
|
||||
way_ids = way_nodes.collect {|way_node| way_node.id }
|
||||
ways = Way.find(way_ids)
|
||||
|
||||
# seg_ids = way_segments.collect {|way_segment| way_segment.segment_id }
|
||||
list_of_way_nodes = ways.collect { |way|
|
||||
way.way_nodes.collect { |way_node| way_node.node_id }
|
||||
}
|
||||
list_of_way_nodes.flatten!
|
||||
|
||||
list_of_way_segs = ways.collect {|way| way.way_segments}
|
||||
list_of_way_segs.flatten!
|
||||
|
||||
list_of_way_segments = list_of_way_segs.collect { |way_seg| way_seg.segment_id }
|
||||
|
||||
else
|
||||
list_of_way_segments = Array.new
|
||||
else
|
||||
list_of_way_nodes = Array.new
|
||||
end
|
||||
|
||||
# - [0] in case some thing links to segment 0 which doesn't exist. Shouldn't actually ever happen but it does. FIXME: file a ticket for this
|
||||
segments_to_fetch = (list_of_way_segments.uniq - segment_ids) - [0]
|
||||
# - [0] in case some thing links to node 0 which doesn't exist. Shouldn't actually ever happen but it does. FIXME: file a ticket for this
|
||||
nodes_to_fetch = (list_of_way_nodes.uniq - node_ids) - [0]
|
||||
|
||||
if segments_to_fetch.length > 0
|
||||
segments += Segment.find(segments_to_fetch)
|
||||
if nodes_to_fetch.length > 0
|
||||
nodes += Node.find(nodes_to_fetch)
|
||||
end
|
||||
|
||||
# get more nodes
|
||||
#
|
||||
|
||||
segments_nodes = segments.collect {|segment| segment.node_a }
|
||||
segments_nodes += segments.collect {|segment| segment.node_b }
|
||||
|
||||
node_ids_a = nodes.collect {|node| node.id }
|
||||
|
||||
nodes_to_get = segments_nodes - node_ids_a
|
||||
nodes += Node.find(nodes_to_get) if nodes_to_get.length > 0
|
||||
|
||||
visible_nodes = {}
|
||||
user_display_name_cache = {}
|
||||
|
||||
|
@ -223,18 +195,40 @@ class ApiController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
visible_segments = {}
|
||||
|
||||
segments.each do |segment|
|
||||
if visible_nodes[segment.node_a] and visible_nodes[segment.node_b] and segment.visible?
|
||||
doc.root << segment.to_xml_node(user_display_name_cache)
|
||||
visible_segments[segment.id] = segment
|
||||
way_ids = Array.new
|
||||
ways.each do |way|
|
||||
if way.visible?
|
||||
doc.root << way.to_xml_node(visible_nodes, user_display_name_cache)
|
||||
way_ids << way.id
|
||||
end
|
||||
end
|
||||
|
||||
# collect relationships. currently done in one big block at the end;
|
||||
# may need to move this upwards if people want automatic completion of
|
||||
# relationships, i.e. deliver referenced objects like we do with ways...
|
||||
relations = Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
|
||||
"e.visible=1 and " +
|
||||
"em.id = e.id and em.member_type='node' and em.member_id in (#{visible_nodes.keys.join(',')})")
|
||||
relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
|
||||
"e.visible=1 and " +
|
||||
"em.id = e.id and em.member_type='way' and em.member_id in (#{way_ids.join(',')})")
|
||||
# we do not normally return the "other" partners referenced by an relation,
|
||||
# e.g. if we return a way A that is referenced by relation X, and there's
|
||||
# another way B also referenced, that is not returned. But we do make
|
||||
# an exception for cases where an relation references another *relation*;
|
||||
# in that case we return that as well (but we don't go recursive here)
|
||||
relation_ids = relations.collect { |relation| relation.id }
|
||||
if relation_ids.length > 0
|
||||
relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
|
||||
"e.visible=1 and " +
|
||||
"em.id = e.id and em.member_type='relation' and em.member_id in (#{relation_ids.join(',')})")
|
||||
end
|
||||
|
||||
ways.each do |way|
|
||||
doc.root << way.to_xml_node(visible_segments, user_display_name_cache) if way.visible?
|
||||
end
|
||||
# this "uniq" may be slightly inefficient; it may be better to first collect and output
|
||||
# all node-related relations, then find the *not yet covered* way-related ones etc.
|
||||
relations.uniq.each do |relation|
|
||||
doc.root << relation.to_xml_node(user_display_name_cache)
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
|
||||
|
@ -251,8 +245,8 @@ class ApiController < ApplicationController
|
|||
|
||||
api = XML::Node.new 'api'
|
||||
version = XML::Node.new 'version'
|
||||
version['minimum'] = '0.4';
|
||||
version['maximum'] = '0.4';
|
||||
version['minimum'] = '0.5';
|
||||
version['maximum'] = '0.5';
|
||||
api << version
|
||||
area = XML::Node.new 'area'
|
||||
area['maximum'] = MAX_REQUEST_AREA.to_s;
|
||||
|
|
|
@ -79,7 +79,9 @@ class NodeController < ApplicationController
|
|||
node = Node.find(params[:id])
|
||||
|
||||
if node.visible
|
||||
if Segment.find(:first, :conditions => [ "visible = 1 and (node_a = ? or node_b = ?)", node.id, node.id])
|
||||
if WayNode.find(:first, :joins => "INNER JOIN current_ways ON current_ways.id = current_way_nodes.id", :conditions => [ "current_ways.visible = 1 AND current_way_nodes.node_id = ?", node.id ])
|
||||
render :nothing => true, :status => :precondition_failed
|
||||
else if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='node' and member_id=?", params[:id]])
|
||||
render :nothing => true, :status => :precondition_failed
|
||||
else
|
||||
node.user_id = @user.id
|
||||
|
|
2
app/controllers/old_way_node_controller.rb
Normal file
2
app/controllers/old_way_node_controller.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class OldWayNodeController < ApplicationController
|
||||
end
|
181
app/controllers/relation_controller.rb
Normal file
181
app/controllers/relation_controller.rb
Normal file
|
@ -0,0 +1,181 @@
|
|||
class RelationController < ApplicationController
|
||||
require 'xml/libxml'
|
||||
|
||||
before_filter :authorize, :only => [:create, :update, :delete]
|
||||
before_filter :check_availability, :only => [:create, :update, :delete]
|
||||
|
||||
after_filter :compress_output
|
||||
|
||||
def create
|
||||
if request.put?
|
||||
relation = Relation.from_xml(request.raw_post, true)
|
||||
|
||||
if relation
|
||||
if !relation.preconditions_ok?
|
||||
render :nothing => true, :status => :precondition_failed
|
||||
else
|
||||
relation.user_id = @user.id
|
||||
|
||||
if relation.save_with_history
|
||||
render :text => relation.id.to_s, :content_type => "text/plain"
|
||||
else
|
||||
print "save error\n";
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => :bad_request
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => :method_not_allowed
|
||||
end
|
||||
end
|
||||
|
||||
def read
|
||||
begin
|
||||
relation = Relation.find(params[:id])
|
||||
|
||||
if relation.visible
|
||||
render :text => relation.to_xml.to_s, :content_type => "text/xml"
|
||||
else
|
||||
render :nothing => true, :status => :gone
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :nothing => true, :status => :not_found
|
||||
rescue
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
relation = Relation.find(params[:id])
|
||||
|
||||
if relation.visible
|
||||
new_relation = Relation.from_xml(request.raw_post)
|
||||
|
||||
if new_relation and new_relation.id == relation.id
|
||||
if !new_relation.preconditions_ok?
|
||||
render :nothing => true, :status => :precondition_failed
|
||||
else
|
||||
relation.user_id = @user.id
|
||||
relation.tags = new_relation.tags
|
||||
relation.members = new_relation.members
|
||||
relation.visible = true
|
||||
|
||||
if relation.save_with_history
|
||||
render :nothing => true
|
||||
else
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => :bad_request
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => :gone
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :nothing => true, :status => :not_found
|
||||
rescue
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
#XXX check if member somewhere!
|
||||
begin
|
||||
relation = Relation.find(params[:id])
|
||||
|
||||
if relation.visible
|
||||
if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='relation' and member_id=?", params[:id]])
|
||||
render :nothing => true, :status => :precondition_failed
|
||||
else
|
||||
relation.user_id = @user.id
|
||||
relation.tags = []
|
||||
relation.members = []
|
||||
relation.visible = false
|
||||
|
||||
if relation.save_with_history
|
||||
render :nothing => true
|
||||
else
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => :gone
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :nothing => true, :status => :not_found
|
||||
rescue
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
|
||||
def full
|
||||
begin
|
||||
relation = Relation.find(params[:id])
|
||||
|
||||
if relation.visible
|
||||
# In future, we might want to do all the data fetch in one step
|
||||
seg_ids = relation.segs + [-1]
|
||||
segments = Segment.find_by_sql "select * from current_segments where visible = 1 and id IN (#{seg_ids.join(',')})"
|
||||
|
||||
node_ids = segments.collect {|segment| segment.node_a }
|
||||
node_ids += segments.collect {|segment| segment.node_b }
|
||||
node_ids += [-1]
|
||||
nodes = Node.find(:all, :conditions => "visible = 1 AND id IN (#{node_ids.join(',')})")
|
||||
|
||||
# Render
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
nodes.each do |node|
|
||||
doc.root << node.to_xml_node()
|
||||
end
|
||||
segments.each do |segment|
|
||||
doc.root << segment.to_xml_node()
|
||||
end
|
||||
doc.root << relation.to_xml_node()
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
else
|
||||
render :nothing => true, :status => :gone
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render :nothing => true, :status => :not_found
|
||||
rescue
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
|
||||
def relations
|
||||
ids = params['relations'].split(',').collect { |w| w.to_i }
|
||||
|
||||
if ids.length > 0
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
|
||||
Relation.find(ids).each do |relation|
|
||||
doc.root << relation.to_xml_node
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
else
|
||||
render :nothing => true, :status => :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
def relations_for_object(objtype)
|
||||
relationids = RelationMember.find(:all, :conditions => ['member_type=? and member_id=?', objtype, params[:id]]).collect { |ws| ws.id }.uniq
|
||||
|
||||
if relationids.length > 0
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
|
||||
Relation.find(relationids).each do |relation|
|
||||
doc.root << relation.to_xml_node
|
||||
end
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
else
|
||||
render :nothing => true, :status => :bad_request
|
||||
end
|
||||
end
|
||||
end
|
5
app/controllers/relation_member_controller.rb
Normal file
5
app/controllers/relation_member_controller.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class RelationMemberController < ApplicationController
|
||||
|
||||
|
||||
|
||||
end
|
9
app/controllers/relation_tag_controller.rb
Normal file
9
app/controllers/relation_tag_controller.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
class RelationTagController < ApplicationController
|
||||
layout 'site'
|
||||
|
||||
def search
|
||||
@tags = RelationTag.find(:all, :limit => 11, :conditions => ["match(v) against (?)", params[:query][:query].to_s] )
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -1,26 +1,23 @@
|
|||
class SearchController < ApplicationController
|
||||
# Support searching for nodes, segments, ways, or all
|
||||
# Support searching for nodes, ways, or all
|
||||
# Can search by tag k, v, or both (type->k,value->v)
|
||||
# Can search by name (k=name,v=....)
|
||||
|
||||
after_filter :compress_output
|
||||
|
||||
def search_all
|
||||
do_search(true,true,true)
|
||||
do_search(true,true)
|
||||
end
|
||||
|
||||
def search_ways
|
||||
do_search(true,false,false)
|
||||
end
|
||||
def search_segments
|
||||
do_search(false,true,false)
|
||||
do_search(true,false)
|
||||
end
|
||||
def search_nodes
|
||||
do_search(false,false,true)
|
||||
do_search(false,true)
|
||||
end
|
||||
|
||||
|
||||
def do_search(do_ways,do_segments,do_nodes)
|
||||
def do_search(do_ways,do_nodes)
|
||||
type = params['type']
|
||||
value = params['value']
|
||||
unless type or value
|
||||
|
@ -33,7 +30,6 @@ class SearchController < ApplicationController
|
|||
|
||||
way_ids = Array.new
|
||||
ways = Array.new
|
||||
segments = Array.new
|
||||
nodes = Array.new
|
||||
|
||||
# Matching for tags table
|
||||
|
@ -75,21 +71,13 @@ class SearchController < ApplicationController
|
|||
ways = Way.find(:all, :conditions => cond_tbl, :limit => 100)
|
||||
end
|
||||
|
||||
# Now, segments matching
|
||||
if do_segments
|
||||
segments = Segment.find(:all, :conditions => cond_tags, :limit => 500)
|
||||
end
|
||||
|
||||
# Now, nodes
|
||||
if do_nodes
|
||||
nodes = Node.find(:all, :conditions => cond_tags, :limit => 2000)
|
||||
end
|
||||
|
||||
# Fetch any segments needed for our ways (only have matching segments so far)
|
||||
segments += Segment.find(ways.collect { |w| w.segs }.uniq)
|
||||
|
||||
# Fetch any nodes needed for our segments (only have matching nodes so far)
|
||||
nodes += Node.find(segments.collect { |s| [s.node_a, s.node_b] }.flatten.uniq)
|
||||
# Fetch any node needed for our ways (only have matching nodes so far)
|
||||
nodes += Node.find(ways.collect { |w| w.nds }.uniq)
|
||||
|
||||
# Print
|
||||
user_display_name_cache = {}
|
||||
|
@ -98,10 +86,6 @@ class SearchController < ApplicationController
|
|||
doc.root << node.to_xml_node(user_display_name_cache)
|
||||
end
|
||||
|
||||
segments.each do |segment|
|
||||
doc.root << segment.to_xml_node(user_display_name_cache)
|
||||
end
|
||||
|
||||
ways.each do |way|
|
||||
doc.root << way.to_xml_node(user_display_name_cache)
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ class SiteController < ApplicationController
|
|||
way = Way.find(params[:id])
|
||||
|
||||
begin
|
||||
node = way.way_segments.first.segment.from_node
|
||||
node = way.way_nodes.first.node
|
||||
redirect_to :controller => 'site', :action => 'index', :lat => node.latitude, :lon => node.longitude, :zoom => 6
|
||||
rescue
|
||||
redirect_to :back
|
||||
|
|
|
@ -94,7 +94,7 @@ class SwfController < ApplicationController
|
|||
sql="SELECT cn1.latitude AS lat1,cn1.longitude AS lon1,"+
|
||||
" cn2.latitude AS lat2,cn2.longitude AS lon2 "+
|
||||
" FROM current_segments "+
|
||||
" LEFT OUTER JOIN current_way_segments"+
|
||||
" LEFT OUTER JOIN current_way_nodes"+
|
||||
" ON segment_id=current_segments.id,"+
|
||||
" current_nodes AS cn1,current_nodes AS cn2"+
|
||||
" WHERE (cn1.longitude BETWEEN #{xmin} AND #{xmax})"+
|
||||
|
|
|
@ -59,7 +59,7 @@ class WayController < ApplicationController
|
|||
else
|
||||
way.user_id = @user.id
|
||||
way.tags = new_way.tags
|
||||
way.segs = new_way.segs
|
||||
way.nds = new_way.nds
|
||||
way.visible = true
|
||||
|
||||
if way.save_with_history
|
||||
|
@ -86,15 +86,19 @@ class WayController < ApplicationController
|
|||
way = Way.find(params[:id])
|
||||
|
||||
if way.visible
|
||||
way.user_id = @user.id
|
||||
way.tags = []
|
||||
way.segs = []
|
||||
way.visible = false
|
||||
|
||||
if way.save_with_history
|
||||
render :nothing => true
|
||||
if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='way' and member_id=?", params[:id]])
|
||||
render :nothing => true, :status => :precondition_failed
|
||||
else
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
way.user_id = @user.id
|
||||
way.tags = []
|
||||
way.nds = []
|
||||
way.visible = false
|
||||
|
||||
if way.save_with_history
|
||||
render :nothing => true
|
||||
else
|
||||
render :nothing => true, :status => :internal_server_error
|
||||
end
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => :gone
|
||||
|
@ -111,23 +115,14 @@ class WayController < ApplicationController
|
|||
way = Way.find(params[:id])
|
||||
|
||||
if way.visible
|
||||
# In future, we might want to do all the data fetch in one step
|
||||
seg_ids = way.segs + [-1]
|
||||
segments = Segment.find_by_sql "select * from current_segments where visible = 1 and id IN (#{seg_ids.join(',')})"
|
||||
|
||||
node_ids = segments.collect {|segment| segment.node_a }
|
||||
node_ids += segments.collect {|segment| segment.node_b }
|
||||
node_ids += [-1]
|
||||
nodes = Node.find(:all, :conditions => "visible = 1 AND id IN (#{node_ids.join(',')})")
|
||||
nd_ids = way.nds + [-1]
|
||||
nodes = Node.find(:all, :conditions => "visible = 1 AND id IN (#{nd_ids.join(',')})")
|
||||
|
||||
# Render
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
nodes.each do |node|
|
||||
doc.root << node.to_xml_node()
|
||||
end
|
||||
segments.each do |segment|
|
||||
doc.root << segment.to_xml_node()
|
||||
end
|
||||
doc.root << way.to_xml_node()
|
||||
|
||||
render :text => doc.to_s, :content_type => "text/xml"
|
||||
|
@ -161,8 +156,8 @@ class WayController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def ways_for_segment
|
||||
wayids = WaySegment.find(:all, :conditions => ['segment_id = ?', params[:id]]).collect { |ws| ws.id }.uniq
|
||||
def ways_for_node
|
||||
wayids = WayNode.find(:all, :conditions => ['node_id = ?', params[:id]]).collect { |ws| ws.id }.uniq
|
||||
|
||||
if wayids.length > 0
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
|
|
5
app/controllers/way_node_controller.rb
Normal file
5
app/controllers/way_node_controller.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class WayNodeController < ApplicationController
|
||||
|
||||
|
||||
|
||||
end
|
2
app/helpers/old_way_node_helper.rb
Normal file
2
app/helpers/old_way_node_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
module OldWayNodeHelper
|
||||
end
|
2
app/helpers/way_node_helper.rb
Normal file
2
app/helpers/way_node_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
module WayNodeHelper
|
||||
end
|
111
app/models/old_relation.rb
Normal file
111
app/models/old_relation.rb
Normal file
|
@ -0,0 +1,111 @@
|
|||
class OldRelation < ActiveRecord::Base
|
||||
set_table_name 'relations'
|
||||
|
||||
belongs_to :user
|
||||
|
||||
def self.from_relation(relation)
|
||||
old_relation = OldRelation.new
|
||||
old_relation.visible = relation.visible
|
||||
old_relation.user_id = relation.user_id
|
||||
old_relation.timestamp = relation.timestamp
|
||||
old_relation.id = relation.id
|
||||
old_relation.members = relation.members
|
||||
old_relation.tags = relation.tags
|
||||
return old_relation
|
||||
end
|
||||
|
||||
def save_with_dependencies!
|
||||
|
||||
# see comment in old_way.rb ;-)
|
||||
save!
|
||||
clear_aggregation_cache
|
||||
clear_association_cache
|
||||
@attributes.update(OldRelation.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 = OldRelationTag.new
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.version = self.version
|
||||
tag.save!
|
||||
end
|
||||
|
||||
i = 1
|
||||
self.members.each do |m|
|
||||
member = OldRelationMember.new
|
||||
member.id = self.id
|
||||
member.member_type = m[0]
|
||||
member.member_id = m[1]
|
||||
member.member_role = m[2]
|
||||
member.version = self.version
|
||||
member.save!
|
||||
end
|
||||
end
|
||||
|
||||
def members
|
||||
unless @members
|
||||
@members = Array.new
|
||||
OldRelationMember.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version]).each do |m|
|
||||
@members += [[m.type,m.id,m.role]]
|
||||
end
|
||||
end
|
||||
@members
|
||||
end
|
||||
|
||||
def tags
|
||||
unless @tags
|
||||
@tags = Hash.new
|
||||
OldRelationTag.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version]).each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
end
|
||||
@tags = Hash.new unless @tags
|
||||
@tags
|
||||
end
|
||||
|
||||
def members=(s)
|
||||
@members = s
|
||||
end
|
||||
|
||||
def tags=(t)
|
||||
@tags = t
|
||||
end
|
||||
|
||||
# has_many :relation_segments, :class_name => 'OldRelationSegment', :foreign_key => 'id'
|
||||
# has_many :relation_tags, :class_name => 'OldRelationTag', :foreign_key => 'id'
|
||||
|
||||
def old_members
|
||||
OldRelationMember.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])
|
||||
end
|
||||
|
||||
def old_tags
|
||||
OldRelationTag.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])
|
||||
end
|
||||
|
||||
def to_xml_node
|
||||
el1 = XML::Node.new 'relation'
|
||||
el1['id'] = self.id.to_s
|
||||
el1['visible'] = self.visible.to_s
|
||||
el1['timestamp'] = self.timestamp.xmlschema
|
||||
el1['user'] = self.user.display_name if self.user.data_public?
|
||||
|
||||
self.old_members.each do |member|
|
||||
e = XML::Node.new 'member'
|
||||
e['type'] = member.member_type.to_s
|
||||
e['ref'] = member.member_id.to_s # "id" is considered uncool here as it should be unique in XML
|
||||
e['role'] = member.member_role.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
|
6
app/models/old_relation_member.rb
Normal file
6
app/models/old_relation_member.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class OldRelationMember < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
|
||||
set_table_name 'relation_members'
|
||||
|
||||
end
|
6
app/models/old_relation_tag.rb
Normal file
6
app/models/old_relation_tag.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class OldRelationTag < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
|
||||
set_table_name 'relation_tags'
|
||||
|
||||
end
|
|
@ -9,7 +9,7 @@ class OldWay < ActiveRecord::Base
|
|||
old_way.user_id = way.user_id
|
||||
old_way.timestamp = way.timestamp
|
||||
old_way.id = way.id
|
||||
old_way.segs = way.segs
|
||||
old_way.nds = way.nds
|
||||
old_way.tags = way.tags
|
||||
return old_way
|
||||
end
|
||||
|
@ -39,23 +39,25 @@ class OldWay < ActiveRecord::Base
|
|||
end
|
||||
|
||||
i = 1
|
||||
self.segs.each do |n|
|
||||
seg = OldWaySegment.new
|
||||
seg.id = self.id
|
||||
seg.segment_id = n
|
||||
seg.version = self.version
|
||||
seg.save!
|
||||
self.nds.each do |n|
|
||||
nd = OldWayNode.new
|
||||
nd.id = self.id
|
||||
nd.node_id = n
|
||||
nd.sequence_id = i
|
||||
nd.version = self.version
|
||||
nd.save!
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
def segs
|
||||
unless @segs
|
||||
@segs = Array.new
|
||||
OldWaySegment.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version], :order => "sequence_id").each do |seg|
|
||||
@segs += [seg.segment_id]
|
||||
def nds
|
||||
unless @nds
|
||||
@nds = Array.new
|
||||
OldWayNode.find(:all, :conditions => ["id = ? AND version = ?", self.id, self.version], :order => "sequence_id").each do |nd|
|
||||
@nds += [nd.node_id]
|
||||
end
|
||||
end
|
||||
@segs
|
||||
@nds
|
||||
end
|
||||
|
||||
def tags
|
||||
|
@ -69,19 +71,19 @@ class OldWay < ActiveRecord::Base
|
|||
@tags
|
||||
end
|
||||
|
||||
def segs=(s)
|
||||
@segs = s
|
||||
def nds=(s)
|
||||
@nds = s
|
||||
end
|
||||
|
||||
def tags=(t)
|
||||
@tags = t
|
||||
end
|
||||
|
||||
# has_many :way_segments, :class_name => 'OldWaySegment', :foreign_key => 'id'
|
||||
# has_many :way_nodes, :class_name => 'OldWayNode', :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])
|
||||
def old_nodes
|
||||
OldWayNode.find(:all, :conditions => ['id = ? AND version = ?', self.id, self.version])
|
||||
end
|
||||
|
||||
def old_tags
|
||||
|
@ -95,9 +97,9 @@ class OldWay < ActiveRecord::Base
|
|||
el1['timestamp'] = self.timestamp.xmlschema
|
||||
el1['user'] = self.user.display_name if self.user.data_public?
|
||||
|
||||
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
|
||||
self.old_nodes.each do |nd| # FIXME need to make sure they come back in the right order
|
||||
e = XML::Node.new 'nd'
|
||||
e['id'] = nd.node_id.to_s
|
||||
el1 << e
|
||||
end
|
||||
|
||||
|
|
6
app/models/old_way_node.rb
Normal file
6
app/models/old_way_node.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class OldWayNode < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
|
||||
set_table_name 'way_nodes'
|
||||
|
||||
end
|
213
app/models/relation.rb
Normal file
213
app/models/relation.rb
Normal file
|
@ -0,0 +1,213 @@
|
|||
class Relation < ActiveRecord::Base
|
||||
require 'xml/libxml'
|
||||
|
||||
belongs_to :user
|
||||
|
||||
has_many :relation_members, :foreign_key => 'id'
|
||||
has_many :relation_tags, :foreign_key => 'id'
|
||||
|
||||
has_many :old_relations, :foreign_key => 'id', :order => 'version'
|
||||
|
||||
set_table_name 'current_relations'
|
||||
|
||||
def self.from_xml(xml, create=false)
|
||||
begin
|
||||
p = XML::Parser.new
|
||||
p.string = xml
|
||||
doc = p.parse
|
||||
|
||||
relation = Relation.new
|
||||
|
||||
doc.find('//osm/relation').each do |pt|
|
||||
if !create and pt['id'] != '0'
|
||||
relation.id = pt['id'].to_i
|
||||
end
|
||||
|
||||
if create
|
||||
relation.timestamp = Time.now
|
||||
relation.visible = true
|
||||
else
|
||||
if pt['timestamp']
|
||||
relation.timestamp = Time.parse(pt['timestamp'])
|
||||
end
|
||||
end
|
||||
|
||||
pt.find('tag').each do |tag|
|
||||
relation.add_tag_keyval(tag['k'], tag['v'])
|
||||
end
|
||||
|
||||
pt.find('member').each do |member|
|
||||
relation.add_member(member['type'], member['ref'], member['role'])
|
||||
end
|
||||
end
|
||||
rescue
|
||||
relation = nil
|
||||
end
|
||||
|
||||
return relation
|
||||
end
|
||||
|
||||
def to_xml
|
||||
doc = OSM::API.new.get_xml_doc
|
||||
doc.root << to_xml_node()
|
||||
return doc
|
||||
end
|
||||
|
||||
def to_xml_node(user_display_name_cache = nil)
|
||||
el1 = XML::Node.new 'relation'
|
||||
el1['id'] = self.id.to_s
|
||||
el1['visible'] = self.visible.to_s
|
||||
el1['timestamp'] = self.timestamp.xmlschema
|
||||
|
||||
user_display_name_cache = {} if user_display_name_cache.nil?
|
||||
|
||||
if user_display_name_cache and user_display_name_cache.key?(self.user_id)
|
||||
# use the cache if available
|
||||
elsif self.user.data_public?
|
||||
user_display_name_cache[self.user_id] = self.user.display_name
|
||||
else
|
||||
user_display_name_cache[self.user_id] = nil
|
||||
end
|
||||
|
||||
el1['user'] = user_display_name_cache[self.user_id] unless user_display_name_cache[self.user_id].nil?
|
||||
|
||||
self.relation_members.each do |member|
|
||||
p=0
|
||||
#if visible_members
|
||||
# # if there is a list of visible members then use that to weed out deleted segments
|
||||
# if visible_members[member.member_type][member.member_id]
|
||||
# p=1
|
||||
# end
|
||||
#else
|
||||
# otherwise, manually go to the db to check things
|
||||
if member.member.visible?
|
||||
p=1
|
||||
end
|
||||
#end
|
||||
if p
|
||||
e = XML::Node.new 'member'
|
||||
e['type'] = member.member_type
|
||||
e['ref'] = member.member_id.to_s
|
||||
e['role'] = member.member_role
|
||||
el1 << e
|
||||
end
|
||||
end
|
||||
|
||||
self.relation_tags.each do |tag|
|
||||
e = XML::Node.new 'tag'
|
||||
e['k'] = tag.k
|
||||
e['v'] = tag.v
|
||||
el1 << e
|
||||
end
|
||||
return el1
|
||||
end
|
||||
|
||||
# FIXME is this really needed?
|
||||
def members
|
||||
unless @members
|
||||
@members = Array.new
|
||||
self.relation_members.each do |member|
|
||||
@members += [[member.member_type,member.member_id,member.member_role]]
|
||||
end
|
||||
end
|
||||
@members
|
||||
end
|
||||
|
||||
def tags
|
||||
unless @tags
|
||||
@tags = Hash.new
|
||||
self.relation_tags.each do |tag|
|
||||
@tags[tag.k] = tag.v
|
||||
end
|
||||
end
|
||||
@tags
|
||||
end
|
||||
|
||||
def members=(m)
|
||||
@members = m
|
||||
end
|
||||
|
||||
def tags=(t)
|
||||
@tags = t
|
||||
end
|
||||
|
||||
def add_member(type,id,role)
|
||||
@members = Array.new unless @members
|
||||
@members += [[type,id,role]]
|
||||
end
|
||||
|
||||
def add_tag_keyval(k, v)
|
||||
@tags = Hash.new unless @tags
|
||||
@tags[k] = v
|
||||
end
|
||||
|
||||
def save_with_history
|
||||
begin
|
||||
Relation.transaction do
|
||||
t = Time.now
|
||||
self.timestamp = t
|
||||
self.save!
|
||||
|
||||
tags = self.tags
|
||||
|
||||
RelationTag.delete_all(['id = ?', self.id])
|
||||
|
||||
tags.each do |k,v|
|
||||
tag = RelationTag.new
|
||||
tag.k = k
|
||||
tag.v = v
|
||||
tag.id = self.id
|
||||
tag.save!
|
||||
end
|
||||
|
||||
members = self.members
|
||||
|
||||
RelationMember.delete_all(['id = ?', self.id])
|
||||
|
||||
members.each do |n|
|
||||
mem = RelationMember.new
|
||||
mem.id = self.id
|
||||
mem.member_type = n[0];
|
||||
mem.member_id = n[1];
|
||||
mem.member_role = n[2];
|
||||
mem.save!
|
||||
end
|
||||
|
||||
old_relation = OldRelation.from_relation(self)
|
||||
old_relation.timestamp = t
|
||||
old_relation.save_with_dependencies!
|
||||
end
|
||||
|
||||
return true
|
||||
rescue Exception => ex
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def preconditions_ok?
|
||||
self.members.each do |m|
|
||||
if (m[0] == "node")
|
||||
n = Node.find(:first, :conditions => ["id = ?", m[1]])
|
||||
unless n and n.visible
|
||||
return false
|
||||
end
|
||||
elsif (m[0] == "way")
|
||||
w = Way.find(:first, :conditions => ["id = ?", m[1]])
|
||||
unless w and w.visible and w.preconditions_ok?
|
||||
return false
|
||||
end
|
||||
elsif (m[0] == "relation")
|
||||
e = Relation.find(:first, :conditions => ["id = ?", m[1]])
|
||||
unless e and e.visible and e.preconditions_ok?
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
rescue
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
30
app/models/relation_member.rb
Normal file
30
app/models/relation_member.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class RelationMember < ActiveRecord::Base
|
||||
set_table_name 'current_relation_members'
|
||||
|
||||
# problem with RelationMember is that it may link to any one
|
||||
# object (a node, a way, another relation), and belongs_to is
|
||||
# not flexible enough for that. So we do this, which is ugly,
|
||||
# but fortunately rails won't actually run the SQL behind that
|
||||
# unless someone really accesses .node, .way, or
|
||||
# .relation - which is what we do below based on member_type.
|
||||
# (and no: the :condition on belongs_to doesn't work here as
|
||||
# it is a condition on the *referenced* object not the
|
||||
# *referencing* object!)
|
||||
|
||||
belongs_to :node, :foreign_key => "member_id"
|
||||
belongs_to :way, :foreign_key => "member_id"
|
||||
belongs_to :relation, :foreign_key => "member_id"
|
||||
|
||||
# so we define this "member" function that returns whatever it
|
||||
# is.
|
||||
|
||||
def member()
|
||||
return (member_type == "node") ? node : (member_type == "way") ? way : relation
|
||||
end
|
||||
|
||||
# NOTE - relations are SUBJECTS of memberships. The fact that nodes,
|
||||
# ways, and relations can be the OBJECT of a membership,
|
||||
# i.e. a node/way/relation can be referenced throgh a
|
||||
# RelationMember object, is NOT modelled in rails, i.e. these links
|
||||
# have to be resolved manually, on demand.
|
||||
end
|
6
app/models/relation_tag.rb
Normal file
6
app/models/relation_tag.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class RelationTag < ActiveRecord::Base
|
||||
set_table_name 'current_relation_tags'
|
||||
|
||||
belongs_to :relation, :foreign_key => 'id'
|
||||
|
||||
end
|
|
@ -3,7 +3,7 @@ class Way < ActiveRecord::Base
|
|||
|
||||
belongs_to :user
|
||||
|
||||
has_many :way_segments, :foreign_key => 'id', :order => 'sequence_id'
|
||||
has_many :way_nodes, :foreign_key => 'id', :order => 'sequence_id'
|
||||
has_many :way_tags, :foreign_key => 'id'
|
||||
|
||||
has_many :old_ways, :foreign_key => 'id', :order => 'version'
|
||||
|
@ -36,8 +36,8 @@ class Way < ActiveRecord::Base
|
|||
way.add_tag_keyval(tag['k'], tag['v'])
|
||||
end
|
||||
|
||||
pt.find('seg').each do |seg|
|
||||
way.add_seg_num(seg['id'])
|
||||
pt.find('nd').each do |nd|
|
||||
way.add_nd_num(nd['id'])
|
||||
end
|
||||
end
|
||||
rescue
|
||||
|
@ -53,7 +53,7 @@ class Way < ActiveRecord::Base
|
|||
return doc
|
||||
end
|
||||
|
||||
def to_xml_node(visible_segments = nil, user_display_name_cache = nil)
|
||||
def to_xml_node(visible_nodes = nil, user_display_name_cache = nil)
|
||||
el1 = XML::Node.new 'way'
|
||||
el1['id'] = self.id.to_s
|
||||
el1['visible'] = self.visible.to_s
|
||||
|
@ -71,26 +71,26 @@ class Way < ActiveRecord::Base
|
|||
|
||||
el1['user'] = user_display_name_cache[self.user_id] unless user_display_name_cache[self.user_id].nil?
|
||||
|
||||
# make sure segments are output in sequence_id order
|
||||
ordered_segments = []
|
||||
self.way_segments.each do |seg|
|
||||
if visible_segments
|
||||
# if there is a list of visible segments then use that to weed out deleted segments
|
||||
if visible_segments[seg.segment_id]
|
||||
ordered_segments[seg.sequence_id] = seg.segment_id.to_s
|
||||
# make sure nodes are output in sequence_id order
|
||||
ordered_nodes = []
|
||||
self.way_nodes.each do |nd|
|
||||
if visible_nodes
|
||||
# if there is a list of visible nodes then use that to weed out deleted nodes
|
||||
if visible_nodes[nd.node_id]
|
||||
ordered_nodes[nd.sequence_id] = nd.node_id.to_s
|
||||
end
|
||||
else
|
||||
# otherwise, manually go to the db to check things
|
||||
if seg.segment.visible? and seg.segment.from_node.visible? and seg.segment.to_node.visible?
|
||||
ordered_segments[seg.sequence_id] = seg.segment_id.to_s
|
||||
if nd.node.visible? and nd.node.visible?
|
||||
ordered_nodes[nd.sequence_id] = nd.node_id.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ordered_segments.each do |seg_id|
|
||||
if seg_id and seg_id != '0'
|
||||
e = XML::Node.new 'seg'
|
||||
e['id'] = seg_id
|
||||
ordered_nodes.each do |nd_id|
|
||||
if nd_id and nd_id != '0'
|
||||
e = XML::Node.new 'nd'
|
||||
e['id'] = nd_id
|
||||
el1 << e
|
||||
end
|
||||
end
|
||||
|
@ -104,14 +104,14 @@ class Way < ActiveRecord::Base
|
|||
return el1
|
||||
end
|
||||
|
||||
def segs
|
||||
unless @segs
|
||||
@segs = Array.new
|
||||
self.way_segments.each do |seg|
|
||||
@segs += [seg.segment_id]
|
||||
def nds
|
||||
unless @nds
|
||||
@nds = Array.new
|
||||
self.way_nodes.each do |nd|
|
||||
@nds += [nd.node_id]
|
||||
end
|
||||
end
|
||||
@segs
|
||||
@nds
|
||||
end
|
||||
|
||||
def tags
|
||||
|
@ -124,17 +124,17 @@ class Way < ActiveRecord::Base
|
|||
@tags
|
||||
end
|
||||
|
||||
def segs=(s)
|
||||
@segs = s
|
||||
def nds=(s)
|
||||
@nds = s
|
||||
end
|
||||
|
||||
def tags=(t)
|
||||
@tags = t
|
||||
end
|
||||
|
||||
def add_seg_num(n)
|
||||
@segs = Array.new unless @segs
|
||||
@segs << n.to_i
|
||||
def add_nd_num(n)
|
||||
@nds = Array.new unless @nds
|
||||
@nds << n.to_i
|
||||
end
|
||||
|
||||
def add_tag_keyval(k, v)
|
||||
|
@ -161,17 +161,17 @@ class Way < ActiveRecord::Base
|
|||
tag.save!
|
||||
end
|
||||
|
||||
segs = self.segs
|
||||
nds = self.nds
|
||||
|
||||
WaySegment.delete_all(['id = ?', self.id])
|
||||
WayNode.delete_all(['id = ?', self.id])
|
||||
|
||||
i = 1
|
||||
segs.each do |n|
|
||||
seg = WaySegment.new
|
||||
seg.id = self.id
|
||||
seg.segment_id = n
|
||||
seg.sequence_id = i
|
||||
seg.save!
|
||||
nds.each do |n|
|
||||
nd = WayNode.new
|
||||
nd.id = self.id
|
||||
nd.node_id = n
|
||||
nd.sequence_id = i
|
||||
nd.save!
|
||||
i += 1
|
||||
end
|
||||
|
||||
|
@ -181,16 +181,17 @@ class Way < ActiveRecord::Base
|
|||
end
|
||||
|
||||
return true
|
||||
rescue
|
||||
rescue => ex
|
||||
puts ex
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def preconditions_ok?
|
||||
return false if self.segs.empty?
|
||||
self.segs.each do |n|
|
||||
segment = Segment.find(:first, :conditions => ["id = ?", n])
|
||||
unless segment and segment.visible and segment.preconditions_ok?
|
||||
return false if self.nds.empty?
|
||||
self.nds.each do |n|
|
||||
node = Node.find(:first, :conditions => ["id = ?", n])
|
||||
unless node and node.visible
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
|
5
app/models/way_node.rb
Normal file
5
app/models/way_node.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class WayNode < ActiveRecord::Base
|
||||
set_table_name 'current_way_nodes'
|
||||
|
||||
belongs_to :node
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue