+ ##
+ # the bounding box around a node, which is used for determining the changeset's
+ # bounding box
+ def bbox
+ BoundingBox.new(longitude, latitude, longitude, latitude)
+ end
+
+ # Should probably be renamed delete_from to come in line with update
+ def delete_with_history!(new_node, user)
+ unless self.visible
+ raise OSM::APIAlreadyDeletedError.new("node", new_node.id)
+ end
+
+ # need to start the transaction here, so that the database can
+ # provide repeatable reads for the used-by checks. this means it
+ # shouldn't be possible to get race conditions.
+ Node.transaction do
+ self.lock!
+ check_consistency(self, new_node, user)
+ ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id)
+ raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by ways #{ways.collect { |w| w.id }.join(",")}.") unless ways.empty?
+
+ rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Node", :member_id => id }).order(:id)
+ raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by relations #{rels.collect { |r| r.id }.join(",")}.") unless rels.empty?
+
+ self.changeset_id = new_node.changeset_id
+ self.tags = {}
+ self.visible = false
+
+ # update the changeset with the deleted position
+ changeset.update_bbox!(bbox)
+
+ save_with_history!
+ end
+ end