+ # Delete way and all constituent nodes.
+ # Params:
+ # * The user token
+ # * the changeset id
+ # * the id of the way to change
+ # * the version of the way that was downloaded
+ # * a hash of the id and versions of all the nodes that are in the way, if any
+ # of the nodes have been changed by someone else then, there is a problem!
+ # Returns 0 (success), unchanged way id, new way version, new node versions.
+
+ 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
+
+ way_id = way_id.to_i
+ nodeversions = {}
+ old_way=nil # returned, so scope it outside the transaction
+ # Need a transaction so that if one item fails to delete, the whole delete fails.
+ Way.transaction do
+
+ # -- Delete the way
+
+ old_way = Way.find(way_id)
+ delete_way = Way.new
+ delete_way.version = way_version
+ delete_way.changeset_id = changeset_id
+ delete_way.id = way_id
+ old_way.delete_with_history!(delete_way, 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
+ new_node.id = id.to_i
+ begin
+ node.delete_with_history!(new_node, user)
+ nodeversions[node.id]=node.version
+ rescue OSM::APIPreconditionFailedError => ex
+ # We don't do anything with the exception as the node is in use
+ # elsewhere and we don't want to delete it
+ end
+ end
+
+ end # transaction
+ [0, '', way_id, old_way.version, nodeversions]
+ rescue OSM::APIChangesetAlreadyClosedError => ex
+ return [-1, "The changeset #{ex.changeset.id} was closed at #{ex.changeset.closed_at}",way_id,way_version,nodeversions]
+ rescue OSM::APIVersionMismatchError => ex
+ a=ex.to_s.match(/(\d+) of (\w+) (\d+)$/)
+ return [-3, ['way', a[1]],way_id,way_version,nodeversions]
+ rescue OSM::APIAlreadyDeletedError => ex
+ return [-1, "The way has already been deleted.",way_id,way_version,nodeversions]
+ rescue OSM::APIError => ex
+ # Some error that we don't specifically catch
+ return [-2, "An unusual error happened (in 'deleteway' #{way_id}). The server said: #{ex}",way_id,way_version,nodeversions]
+ end
+
+
+ # ====================================================================
+ # Support functions
+
+ # Authenticate token
+ # (can also be of form user:pass)
+ # When we are writing to the api, we need the actual user model,
+ # not just the id, hence this abstraction
+
+ def getuser(token) #:doc:
+ if (token =~ /^(.+)\:(.+)$/) then