]> git.openstreetmap.org Git - rails.git/commitdiff
Potlatch 0.11a
authorRichard Fairhurst <richard@systemed.net>
Thu, 30 Apr 2009 01:23:50 +0000 (01:23 +0000)
committerRichard Fairhurst <richard@systemed.net>
Thu, 30 Apr 2009 01:23:50 +0000 (01:23 +0000)
app/controllers/amf_controller.rb
app/models/node.rb
app/models/way.rb
public/potlatch/potlatch.swf

index 9004397218ddcbc47e2e8a43b5761c6266a35ab8..5ff42fdd2628765f2438e134e2924f99388aeaf3 100644 (file)
@@ -501,13 +501,13 @@ class AmfController < ApplicationController
       new_relation.version = version
 
       if relid <= 0
       new_relation.version = version
 
       if relid <= 0
-        # We're creating the node
+        # We're creating the relation
         new_relation.create_with_history(user)
       elsif visible
         new_relation.create_with_history(user)
       elsif visible
-        # We're updating the node
+        # We're updating the relation
         relation.update_from(new_relation, user)
       else
         relation.update_from(new_relation, user)
       else
-        # We're deleting the node
+        # We're deleting the relation
         relation.delete_with_history!(new_relation, user)
       end
     end # transaction
         relation.delete_with_history!(new_relation, user)
       end
     end # transaction
@@ -542,7 +542,8 @@ class AmfController < ApplicationController
   # 4. way ID
   # 5. list of nodes in way
   # 6. hash of way tags
   # 4. way ID
   # 5. list of nodes in way
   # 6. hash of way tags
-  # 7. array of nodes to change (each one is [lon,lat,id,version,tags])
+  # 7. array of nodes to change (each one is [lon,lat,id,version,tags]),
+  # 8. hash of nodes to delete (id->version).
   # 
   # Returns:
   # 0. '0' (code for success),
   # 
   # Returns:
   # 0. '0' (code for success),
@@ -552,7 +553,7 @@ class AmfController < ApplicationController
   # 4. way version,
   # 5. hash of node versions (node=>version)
 
   # 4. way version,
   # 5. hash of node versions (node=>version)
 
-  def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes) #:doc:
+  def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes, deletednodes) #:doc:
 
     # -- Initialise
        
 
     # -- Initialise
        
@@ -561,22 +562,13 @@ class AmfController < ApplicationController
     if pointlist.length < 2 then return -2,"Server error - way is only #{points.length} points long." end
 
     originalway = originalway.to_i
     if pointlist.length < 2 then return -2,"Server error - way is only #{points.length} points long." end
 
     originalway = originalway.to_i
-       pointlist.collect! {|a| a.to_i }
+       pointlist.collect! {|a| a.to_i }
 
     way=nil    # this is returned, so scope it outside the transaction
     nodeversions = {}
     Way.transaction do
 
 
     way=nil    # this is returned, so scope it outside the transaction
     nodeversions = {}
     Way.transaction do
 
-      # -- Get unique nodes
-
-      if originalway <= 0
-        uniques = []
-      else
-        way = Way.find(originalway)
-        uniques = way.unshared_node_ids
-      end
-
-      #-- Update each changed node
+      # -- Update each changed node
 
       nodes.each do |a|
         lon = a[0].to_f
 
       nodes.each do |a|
         lon = a[0].to_f
@@ -609,9 +601,9 @@ class AmfController < ApplicationController
 
       # -- Save revised way
 
 
       # -- Save revised way
 
-         pointlist.collect! {|a|
-               renumberednodes[a] ? renumberednodes[a]:a
-         } # renumber nodes
+           pointlist.collect! {|a|
+                   renumberednodes[a] ? renumberednodes[a]:a
+           } # renumber nodes
       new_way = Way.new
       new_way.tags = attributes
       new_way.nds = pointlist
       new_way = Way.new
       new_way.tags = attributes
       new_way.nds = pointlist
@@ -620,25 +612,26 @@ class AmfController < ApplicationController
       if originalway <= 0
         new_way.create_with_history(user)
         way=new_way    # so we can get way.id and way.version
       if originalway <= 0
         new_way.create_with_history(user)
         way=new_way    # so we can get way.id and way.version
-      elsif way.tags!=attributes or way.nds!=pointlist or !way.visible?
-        way.update_from(new_way, user)
+      else
+             way = Way.find(originalway)
+                 if way.tags!=attributes or way.nds!=pointlist or !way.visible?
+           way.update_from(new_way, user)
+        end
       end
 
       end
 
-      # -- Delete any unique nodes no longer used
+      # -- Delete unwanted nodes
 
 
-      uniques=uniques-pointlist
-      uniques.each do |n|
-        node = Node.find(n)
-        deleteitemrelations(user, changeset_id, id, 'Node', node.version)
+      deletednodes.each do |id,v|
+        node = Node.find(id.to_i)
         new_node = Node.new
         new_node.changeset_id = changeset_id
         new_node = Node.new
         new_node.changeset_id = changeset_id
-        new_node.version = node.version
-        node.delete_with_history!(new_node, user)
+        new_node.version = v.to_i
+        node.delete_with_history_unless_used!(new_node, user)
       end
 
     end # transaction
 
       end
 
     end # transaction
 
-    [0, originalway, way.id, renumberednodes, way.version, nodeversions]
+    [0, originalway, way.id, renumberednodes, way.version, nodeversions, deletednodes]
   rescue OSM::APIChangesetAlreadyClosedError => ex
     return [-2, "Sorry, your changeset #{ex.changeset.id} has been closed (at #{ex.changeset.closed_at})."]
   rescue OSM::APIVersionMismatchError => ex
   rescue OSM::APIChangesetAlreadyClosedError => ex
     return [-2, "Sorry, your changeset #{ex.changeset.id} has been closed (at #{ex.changeset.closed_at})."]
   rescue OSM::APIVersionMismatchError => ex
@@ -747,7 +740,7 @@ class AmfController < ApplicationController
   # of the nodes have been changed by someone else then, there is a problem!
   # Returns 0 (success), unchanged way id.
 
   # of the nodes have been changed by someone else then, there is a problem!
   # Returns 0 (success), unchanged way id.
 
-  def deleteway(usertoken, changeset_id, way_id, way_version, node_id_version) #:doc:
+  def deleteway(usertoken, changeset_id, way_id, way_version, deletednodes) #:doc:
     user = getuser(usertoken)
     unless user then return -1,"You are not logged in, so the way could not be deleted." end
       
     user = getuser(usertoken)
     unless user then return -1,"You are not logged in, so the way could not be deleted." end
       
@@ -755,29 +748,24 @@ class AmfController < ApplicationController
     # Need a transaction so that if one item fails to delete, the whole delete fails.
     Way.transaction do
 
     # Need a transaction so that if one item fails to delete, the whole delete fails.
     Way.transaction do
 
-      # delete the way
+      # -- Delete the way
+
       old_way = Way.find(way_id)
       old_way = Way.find(way_id)
-      u = old_way.unshared_node_ids
       delete_way = Way.new
       delete_way.version = way_version
       delete_way.changeset_id = changeset_id
       old_way.delete_with_history!(delete_way, user)
 
       delete_way = Way.new
       delete_way.version = way_version
       delete_way.changeset_id = changeset_id
       old_way.delete_with_history!(delete_way, user)
 
-      u.each do |node_id|
-        # delete the node
-        node = Node.find(node_id)
-        delete_node = Node.new
-        delete_node.changeset_id = changeset_id
-        if node_id_version[node_id.to_s]
-          delete_node.version = node_id_version[node_id.to_s]
-        else
-          # in case the node wasn't passed (i.e. if it was previously removed
-          # from the way in Potlatch)
-          deleteitemrelations(user, changeset_id, node_id, 'Node', node.version)
-             delete_node.version = node.version
-           end
-        node.delete_with_history!(delete_node, user)
+      # -- Delete unwanted nodes
+
+      deletednodes.each do |id,v|
+        node = Node.find(id.to_i)
+        new_node = Node.new
+        new_node.changeset_id = changeset_id
+        new_node.version = v.to_i
+        node.delete_with_history_unless_used!(new_node, user)
       end
       end
+
     end # transaction
     [0, way_id]
   rescue OSM::APIChangesetAlreadyClosedError => ex
     end # transaction
     [0, way_id]
   rescue OSM::APIChangesetAlreadyClosedError => ex
@@ -798,28 +786,6 @@ class AmfController < ApplicationController
   # ====================================================================
   # Support functions
 
   # ====================================================================
   # Support functions
 
-  # Remove a node or way from all relations
-  # This is only used by putway and deleteway when deleting nodes removed 
-  # from a way (because Potlatch itself doesn't keep track of these - 
-  # possible FIXME).
-
-  def deleteitemrelations(user, changeset_id, objid, type, version) #:doc:
-    relations = RelationMember.find(:all, 
-                                                                       :conditions => ['member_type = ? and member_id = ?', type.classify, objid], 
-                                                                       :include => :relation).collect { |rm| rm.relation }.uniq
-
-    relations.each do |rel|
-      rel.members.delete_if { |x| x[0] == type and x[1] == objid }
-      new_rel = Relation.new
-      new_rel.tags = rel.tags
-      new_rel.visible = rel.visible
-      new_rel.version = rel.version
-      new_rel.members = rel.members
-      new_rel.changeset_id = changeset_id
-      rel.update_from(new_rel, user)
-    end
-  end
-
   # Authenticate token
   # (can also be of form user:pass)
   # When we are writing to the api, we need the actual user model, 
   # Authenticate token
   # (can also be of form user:pass)
   # When we are writing to the api, we need the actual user model, 
index 2c25bbd14cc72cd268c3c078b92b829c1b8dae87..035a07eac8e45e657d31d561bace0a19fe26b028 100644 (file)
@@ -149,6 +149,30 @@ class Node < ActiveRecord::Base
     end
   end
 
     end
   end
 
+  # As above but doesn't throw an error if node is used elsewhere - instead, just silently
+  # returns without deleting the node. Potlatch needs this in case you ask to delete an
+  # off-screen node while deleting a way - it doesn't know whether the node is used
+  # elsewhere or not.
+  def delete_with_history_unless_used!(new_node, user)
+    unless self.visible
+      raise OSM::APIAlreadyDeletedError.new("node", new_node.id)
+    end
+
+    Node.transaction do
+      check_consistency(self, new_node, user)
+      way = WayNode.find(:first, :joins => "INNER JOIN current_ways ON current_ways.id = current_way_nodes.id", 
+                         :conditions => [ "current_ways.visible = ? AND current_way_nodes.node_id = ?", true, self.id ])
+      rel = RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", 
+                                :conditions => [ "visible = ? AND member_type='Node' and member_id=? ", true, self.id])
+      if way.nil? and rel.nil?
+        self.changeset_id = new_node.changeset_id
+        self.visible = false
+        changeset.update_bbox!(bbox)
+        save_with_history!
+      end
+    end
+  end
+
   def update_from(new_node, user)
     check_consistency(self, new_node, user)
 
   def update_from(new_node, user)
     check_consistency(self, new_node, user)
 
index 325ffae4875fd8a53bb14244795d7b6f326f02ff..da305f082173891f3d75039a3dc64fbc0136599e 100644 (file)
@@ -266,18 +266,6 @@ class Way < ActiveRecord::Base
     end
   end
 
     end
   end
 
-  # Find nodes that belong to this way only
-  def unshared_node_ids
-    node_ids = self.nodes.collect { |node| node.id }
-
-    unless node_ids.empty?
-      way_nodes = WayNode.find(:all, :conditions => "node_id in (#{node_ids.join(',')}) and id != #{self.id}")
-      node_ids = node_ids - way_nodes.collect { |way_node| way_node.node_id }
-    end
-
-    return node_ids
-  end
-
   # Temporary method to match interface to nodes
   def tags_as_hash
     return self.tags
   # Temporary method to match interface to nodes
   def tags_as_hash
     return self.tags
index f6cf57b035a25a1ffe04aef6e6c0f847009eb690..a75986e99cff67c159cd04b37c1ea9a9061a7203 100755 (executable)
Binary files a/public/potlatch/potlatch.swf and b/public/potlatch/potlatch.swf differ