+ def self.from_xml_node(pt, create = false)
+ cs = Changeset.new
+ if create
+ cs.created_at = Time.now.getutc
+ # initial close time is 1h ahead, but will be increased on each
+ # modification.
+ cs.closed_at = cs.created_at + IDLE_TIMEOUT
+ # initially we have no changes in a changeset
+ cs.num_changes = 0
+ end
+
+ pt.find("tag").each do |tag|
+ raise OSM::APIBadXMLError.new("changeset", pt, "tag is missing key") if tag["k"].nil?
+ raise OSM::APIBadXMLError.new("changeset", pt, "tag is missing value") if tag["v"].nil?
+
+ cs.add_tag_keyval(tag["k"], tag["v"])
+ end
+
+ cs
+ end
+
+ ##
+ # returns the bounding box of the changeset. it is possible that some
+ # or all of the values will be nil, indicating that they are undefined.
+ def bbox
+ @bbox ||= BoundingBox.new(min_lon, min_lat, max_lon, max_lat)
+ end
+
+ def has_valid_bbox?
+ bbox.complete?
+ end
+
+ ##
+ # expand the bounding box to include the given bounding box.
+ def update_bbox!(bbox_update)
+ bbox.expand!(bbox_update)
+
+ # update active record. rails 2.1's dirty handling should take care of
+ # whether this object needs saving or not.
+ self.min_lon, self.min_lat, self.max_lon, self.max_lat = @bbox.to_a if bbox.complete?
+ end
+
+ ##
+ # the number of elements is also passed in so that we can ensure that
+ # a single changeset doesn't contain too many elements.
+ def add_changes!(elements)
+ self.num_changes += elements