- # create XML.
- doc = OSM::API.new.get_xml_doc
- visible_nodes = {}
- changeset_cache = {}
- user_display_name_cache = {}
-
- nodes.each do |node|
- if node.visible? # should be unnecessary if data is consistent.
- doc.root << node.to_xml_node(changeset_cache, user_display_name_cache)
- visible_nodes[node.id] = node
- end
+ if relation.visible
+
+ # first find the ids of nodes, ways and relations referenced by this
+ # relation - note that we exclude this relation just in case.
+
+ node_ids = relation.members.select { |m| m[0] == 'Node' }.map { |m| m[1] }
+ way_ids = relation.members.select { |m| m[0] == 'Way' }.map { |m| m[1] }
+ relation_ids = relation.members.select { |m| m[0] == 'Relation' and m[1] != relation.id }.map { |m| m[1] }
+
+ # next load the relations and the ways.
+
+ relations = Relation.where(:id => relation_ids).includes(:relation_tags)
+ ways = Way.where(:id => way_ids).includes(:way_nodes, :way_tags)
+
+ # now additionally collect nodes referenced by ways. Note how we
+ # recursively evaluate ways but NOT relations.
+
+ way_node_ids = ways.collect { |way|
+ way.way_nodes.collect { |way_node| way_node.node_id }
+ }
+ node_ids += way_node_ids.flatten
+ nodes = Node.where(:id => node_ids.uniq).includes(:node_tags)
+
+ # create XML.
+ doc = OSM::API.new.get_xml_doc
+ visible_nodes = {}
+ visible_members = { "Node" => {}, "Way" => {}, "Relation" => {} }
+ changeset_cache = {}
+ user_display_name_cache = {}
+
+ nodes.each do |node|
+ if node.visible? # should be unnecessary if data is consistent.
+ doc.root << node.to_xml_node(changeset_cache, user_display_name_cache)
+ visible_nodes[node.id] = node
+ visible_members["Node"][node.id] = true