Class: RGeo::Cartesian::BoundingBox
- Inherits:
-
Object
- Object
- RGeo::Cartesian::BoundingBox
- Defined in:
- lib/rgeo/cartesian/bounding_box.rb
Overview
This is a bounding box for Cartesian data. The simple cartesian implementation uses this internally to compute envelopes. You may also use it directly to compute and represent bounding boxes.
A bounding box is a set of ranges in each dimension: X, Y, as well as Z and M if supported. You can compute a bounding box for one or more geometry objects by creating a new bounding box object, and adding the geometries to it. You may then query it for the bounds, or use it to determine whether it encloses other geometries or bounding boxes.
Instance Method Summary collapse
-
#_add_geometry(geometry_) ⇒ Object
:nodoc:.
-
#_add_point(point_) ⇒ Object
:nodoc:.
-
#add(geometry_) ⇒ Object
Adjusts the extents of this bounding box to encomass the given object, which may be a geometry or another bounding box.
-
#contains?(rhs_, opts_ = {}) ⇒ Boolean
Returns true if this bounding box contains the given object, which may be a geometry or another bounding box.
-
#empty? ⇒ Boolean
Returns true if this bounding box is still empty.
-
#eql?(rhs_) ⇒ Boolean
(also: #==)
:nodoc:.
-
#factory ⇒ Object
Returns the bounding box's factory.
-
#has_m ⇒ Object
Returns true if this bounding box tracks M coordinates.
-
#has_z ⇒ Object
Returns true if this bounding box tracks Z coordinates.
-
#initialize(factory_, opts_ = {}) ⇒ BoundingBox
constructor
Create a new empty bounding box with the given factory.
-
#max_m ⇒ Object
Returns the maximum M, or nil if this bounding box is empty.
-
#max_point ⇒ Object
Returns a point representing the maximum extent in all dimensions, or nil if this bounding box is empty.
-
#max_x ⇒ Object
Returns the maximum X, or nil if this bounding box is empty.
-
#max_y ⇒ Object
Returns the maximum Y, or nil if this bounding box is empty.
-
#max_z ⇒ Object
Returns the maximum Z, or nil if this bounding box is empty.
-
#min_m ⇒ Object
Returns the minimum M, or nil if this bounding box is empty.
-
#min_point ⇒ Object
Returns a point representing the minimum extent in all dimensions, or nil if this bounding box is empty.
-
#min_x ⇒ Object
Returns the minimum X, or nil if this bounding box is empty.
-
#min_y ⇒ Object
Returns the minimum Y, or nil if this bounding box is empty.
-
#min_z ⇒ Object
Returns the minimum Z, or nil if this bounding box is empty.
-
#to_geometry ⇒ Object
Converts this bounding box to an envelope polygon.
Constructor Details
#initialize(factory_, opts_ = {}) ⇒ BoundingBox
Create a new empty bounding box with the given factory.
The factory defines the coordinate system for the bounding box, and also defines whether it should track Z and M coordinates. All geometries will be cast to this factory when added to this bounding box, and any generated envelope geometry will have this as its factory.
Options include:
[:ignore_z] If true, ignore z coordinates even if the factory supports them. Default is false. [:ignore_m] If true, ignore m coordinates even if the factory supports them. Default is false.
74 75 76 77 78 79 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 74 def initialize(factory_, opts_={}) @factory = factory_ @has_z = !opts_[:ignore_z] && factory_.property(:has_z_coordinate) ? true : false @has_m = !opts_[:ignore_m] && factory_.property(:has_m_coordinate) ? true : false @min_x = @max_x = @min_y = @max_y = @min_z = @max_z = @min_m = @max_m = nil end |
Instance Method Details
#_add_geometry(geometry_) ⇒ Object
:nodoc:
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 285 def _add_geometry(geometry_) # :nodoc: case geometry_ when Feature::Point _add_point(geometry_) when Feature::LineString geometry_.points.each{ |p_| _add_point(p_) } when Feature::Polygon geometry_.exterior_ring.points.each{ |p_| _add_point(p_) } when Feature::MultiPoint geometry_.each{ |p_| _add_point(p_) } when Feature::MultiLineString geometry_.each{ |line_| line_.points.each{ |p_| _add_point(p_) } } when Feature::MultiPolygon geometry_.each{ |poly_| poly_.exterior_ring.points.each{ |p_| _add_point(p_) } } when Feature::GeometryCollection geometry_.each{ |g_| _add_geometry(g_) } end end |
#_add_point(point_) ⇒ Object
:nodoc:
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 305 def _add_point(point_) # :nodoc: if @min_x x_ = point_.x @min_x = x_ if x_ < @min_x @max_x = x_ if x_ > @max_x y_ = point_.y @min_y = y_ if y_ < @min_y @max_y = y_ if y_ > @max_y if @has_z z_ = point_.z @min_z = z_ if z_ < @min_z @max_z = z_ if z_ > @max_z end if @has_m m_ = point_.m @min_m = m_ if m_ < @min_m @max_m = m_ if m_ > @max_m end else @min_x = @max_x = point_.x @min_y = @max_y = point_.y @min_z = @max_z = point_.z if @has_z @min_m = @max_m = point_.m if @has_m end end |
#add(geometry_) ⇒ Object
Adjusts the extents of this bounding box to encomass the given object, which may be a geometry or another bounding box. Returns self.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 210 def add(geometry_) case geometry_ when BoundingBox add(geometry_.min_point) add(geometry_.max_point) when Feature::Geometry if geometry_.factory == @factory _add_geometry(geometry_) else _add_geometry(Factory.cast(geometry_, @factory)) end end self end |
#contains?(rhs_, opts_ = {}) ⇒ Boolean
Returns true if this bounding box contains the given object, which may be a geometry or another bounding box.
Supports these options:
:ignore_z Ignore the Z coordinate when testing, even if both objects have Z. Default is false. :ignore_m Ignore the M coordinate when testing, even if both objects have M. Default is false.
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 266 def contains?(rhs_, opts_={}) if Feature::Geometry === rhs_ contains?(BoundingBox.new(@factory).add(rhs_)) elsif rhs_.empty? true elsif empty? false elsif @min_x > rhs_.min_x || @max_x < rhs_.max_x || @min_y > rhs_.min_y || @max_y < rhs_.max_y false elsif @has_m && rhs_.has_m && !opts_[:ignore_m] && (@min_m > rhs_.min_m || @max_m < rhs_.max_m) false elsif @has_z && rhs_.has_z && !opts_[:ignore_z] && (@min_z > rhs_.min_z || @max_z < rhs_.max_z) false else true end end |
#empty? ⇒ Boolean
Returns true if this bounding box is still empty.
101 102 103 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 101 def empty? @min_x.nil? end |
#eql?(rhs_) ⇒ Boolean Also known as: ==
:nodoc:
82 83 84 85 86 87 88 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 82 def eql?(rhs_) # :nodoc: rhs_.is_a?(BoundingBox) && @factory == rhs_.factory && @min_x == rhs_.min_x && @max_x == rhs_.max_x && @min_y == rhs_.min_y && @max_y == rhs_.max_y && @min_z == rhs_.min_z && @max_z == rhs_.max_z && @min_m == rhs_.min_m && @max_m == rhs_.max_m end |
#factory ⇒ Object
Returns the bounding box's factory.
94 95 96 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 94 def factory @factory end |
#has_m ⇒ Object
Returns true if this bounding box tracks M coordinates.
115 116 117 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 115 def has_m @has_m end |
#has_z ⇒ Object
Returns true if this bounding box tracks Z coordinates.
108 109 110 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 108 def has_z @has_z end |
#max_m ⇒ Object
Returns the maximum M, or nil if this bounding box is empty.
171 172 173 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 171 def max_m @max_m end |
#max_point ⇒ Object
Returns a point representing the maximum extent in all dimensions, or nil if this bounding box is empty.
194 195 196 197 198 199 200 201 202 203 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 194 def max_point if @min_x extras_ = [] extras_ << @max_z if @has_z extras_ << @max_m if @has_m @factory.point(@max_x, @max_y, *extras_) else nil end end |
#max_x ⇒ Object
Returns the maximum X, or nil if this bounding box is empty.
129 130 131 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 129 def max_x @max_x end |
#max_y ⇒ Object
Returns the maximum Y, or nil if this bounding box is empty.
143 144 145 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 143 def max_y @max_y end |
#max_z ⇒ Object
Returns the maximum Z, or nil if this bounding box is empty.
157 158 159 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 157 def max_z @max_z end |
#min_m ⇒ Object
Returns the minimum M, or nil if this bounding box is empty.
164 165 166 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 164 def min_m @min_m end |
#min_point ⇒ Object
Returns a point representing the minimum extent in all dimensions, or nil if this bounding box is empty.
179 180 181 182 183 184 185 186 187 188 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 179 def min_point if @min_x extras_ = [] extras_ << @min_z if @has_z extras_ << @min_m if @has_m @factory.point(@min_x, @min_y, *extras_) else nil end end |
#min_x ⇒ Object
Returns the minimum X, or nil if this bounding box is empty.
122 123 124 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 122 def min_x @min_x end |
#min_y ⇒ Object
Returns the minimum Y, or nil if this bounding box is empty.
136 137 138 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 136 def min_y @min_y end |
#min_z ⇒ Object
Returns the minimum Z, or nil if this bounding box is empty.
150 151 152 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 150 def min_z @min_z end |
#to_geometry ⇒ Object
Converts this bounding box to an envelope polygon. Returns the empty collection if this bounding box is empty.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/rgeo/cartesian/bounding_box.rb', line 229 def to_geometry if @min_x extras_ = [] extras_ << @min_z if @has_z extras_ << @min_m if @has_m point_min_ = @factory.point(@min_x, @min_y, *extras_) if @min_x == @max_x && @min_y == @max_y point_min_ else extras_ = [] extras_ << @max_z if @has_z extras_ << @max_m if @has_m point_max_ = @factory.point(@max_x, @max_y, *extras_) if @min_x == @max_x || @min_y == @max_y @factory.line(point_min_, point_max_) else @factory.polygon(@factory.linear_ring(point_min_, @factory.point(@max_x, @min_y, *extras_), point_max_, @factory.point(@min_x, @max_y, *extras_), point_min_)) end end else @factory.collection([]) end end |