Class: RGeo::Geographic::ProjectedWindow
- Inherits:
-
Object
- Object
- RGeo::Geographic::ProjectedWindow
- Defined in:
- lib/rgeo/geographic/projected_window.rb
Overview
This object represents an axis-aligned rectangle in a map projection coordinate system. It is commonly used to specify the viewport for a map visualization, an envelope in a projected coordinate system, or a spatial constraint. It must be attached to a Geographic::Factory that has a projection.
Class Method Summary collapse
-
.bounding_points(points_) ⇒ Object
Creates a new window that contains all of the given points.
-
.for_corners(sw_, ne_) ⇒ Object
Creates a new window whose coordinates are the given points, which must be Feature::Point objects in unprojected (lat/lng) space.
-
.surrounding_point(point_, x_margin_ = nil, y_margin_ = nil) ⇒ Object
Creates a new window that surrounds the given point with the given margin.
Instance Method Summary collapse
-
#center_point ⇒ Object
Returns the center of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
-
#center_xy ⇒ Object
Returns a two-element array containing the x and y coordinates of the center of the rectangle.
-
#clamped_by(min_width_, min_height_, max_width_, max_height_) ⇒ Object
Returns a new window resulting from clamping this window to the given minimum and maximum widths and heights, in the projected coordinate system.
-
#contains_point?(point_) ⇒ Boolean
Returns true if the rectangle contains the given point, which must be a Feature::Point in unprojected (lat/lng) space.
-
#contains_window?(window_) ⇒ Boolean
Returns true if the given window is completely contained within this window.
-
#crosses_seam? ⇒ Boolean
Returns true if the projection wraps along the x axis, and this rectangle crosses that seam.
-
#degenerate? ⇒ Boolean
Returns true if the rectangle has zero area.
-
#eql?(obj_) ⇒ Boolean
(also: #==)
:nodoc:.
-
#factory ⇒ Object
Returns the Geographic::Factory associated with this window.
-
#hash ⇒ Object
:nodoc:.
-
#initialize(factory_, x_min_, y_min_, x_max_, y_max_, opts_ = {}) ⇒ ProjectedWindow
constructor
Create a new ProjectedWindow given the Geographic::Factory, and the x and y extents of the rectangle.
-
#inspect ⇒ Object
:nodoc:.
-
#ne_point ⇒ Object
Returns the northeast corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
-
#nw_point ⇒ Object
Returns the northwest corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
-
#random_point ⇒ Object
Returns a random point the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
-
#scaled_by(x_factor_, y_factor_ = nil) ⇒ Object
(also: #*)
Returns a new window resulting from scaling this window by the given factors, which must be floating-point values.
-
#se_point ⇒ Object
Returns the southeast corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
-
#sw_point ⇒ Object
Returns the southwest corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
-
#to_s ⇒ Object
:nodoc:.
-
#with_margin(x_margin_, y_margin_ = nil) ⇒ Object
Returns a new window resulting from adding the given margin to this window.
-
#x_max ⇒ Object
Returns the upper limit in the x (easting) direction.
-
#x_min ⇒ Object
Returns the lower limit in the x (easting) direction.
-
#x_span ⇒ Object
(also: #width, #height)
Returns the width of the rectangle.
-
#y_max ⇒ Object
Returns the upper limit in the y (northing) direction.
-
#y_min ⇒ Object
Returns the lower limit in the y (northing) direction.
-
#y_span ⇒ Object
Returns the height of the rectangle.
Constructor Details
#initialize(factory_, x_min_, y_min_, x_max_, y_max_, opts_ = {}) ⇒ ProjectedWindow
Create a new ProjectedWindow given the Geographic::Factory, and the x and y extents of the rectangle.
The window will be intelligently clamped to the limits imposed by the factory. For example, the simple mercator factory limits latitude to approximately +/-85 degrees.
Generally, you will not need to call this low-level constructor directly. Instead, use one of the provided class methods.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/rgeo/geographic/projected_window.rb', line 61 def initialize(factory_, x_min_, y_min_, x_max_, y_max_, opts_={}) @factory = factory_ limits_ = opts_[:is_limits] ? nil : factory_.projection_limits_window wraps_ = factory_.projection_wraps? y_max_, y_min_ = y_min_, y_max_ if y_max_ < y_min_ x_max_, x_min_ = x_min_, x_max_ if x_max_ < x_min_ && !wraps_ if limits_ y_max_ = limits_.y_max if y_max_ > limits_.y_max y_min_ = limits_.y_min if y_min_ < limits_.y_min if wraps_ width_ = limits_.x_span if x_max_ - x_min_ > width_ center_ = (x_max_ + x_min_) * 0.5 x_min_ = center_ - width_ * 0.499999999 x_max_ = center_ + width_ * 0.499999999 end x_max_ = x_max_ % width_ x_max_ -= width_ if x_max_ >= limits_.x_max x_min_ = x_min_ % width_ x_min_ -= width_ if x_min_ >= limits_.x_max else x_max_ = limits_.x_max if x_max_ > limits_.x_max x_min_ = limits_.x_min if x_min_ < limits_.x_min end end @x_min = x_min_ @y_min = y_min_ @x_max = x_max_ @y_max = y_max_ end |
Class Method Details
.bounding_points(points_) ⇒ Object
Creates a new window that contains all of the given points. which must be Feature::Point objects in unprojected (lat/lng) space.
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/rgeo/geographic/projected_window.rb', line 404 def bounding_points(points_) factory_ = nil limits_ = nil width_ = nil x_max_ = nil x_min_ = nil y_max_ = nil y_min_ = nil x_array_ = nil points_.each do |p_| unless factory_ factory_ = p_.factory limits_ = factory_.projection_limits_window width_ = limits_.x_span x_array_ = [] if factory_.projection_wraps? end proj_ = factory_.project(p_) x_ = proj_.x if x_array_ x_ = x_ % width_ x_ -= width_ if x_ >= limits_.x_max x_array_ << x_ else x_max_ = x_ if !x_max_ || x_max_ < x_ x_min_ = x_ if !x_min_ || x_min_ > x_ end y_ = proj_.y y_max_ = y_ if !y_max_ || y_max_ < y_ y_min_ = y_ if !y_min_ || y_min_ > y_ end return nil unless factory_ if x_array_ x_array_.sort! largest_span_ = nil last_ = x_array_.last x_array_.each do |x_| if largest_span_ span_ = x_ - last_ if span_ > largest_span_ largest_span_ = span_ x_min_ = x_ x_max_ = last_ end else largest_span_ = x_ - last_ + width_ x_min_ = x_ x_max_ = last_ end last_ = x_ end end ProjectedWindow.new(factory_, x_min_, y_min_, x_max_, y_max_) end |
.for_corners(sw_, ne_) ⇒ Object
Creates a new window whose coordinates are the given points, which must be Feature::Point objects in unprojected (lat/lng) space.
376 377 378 379 380 381 |
# File 'lib/rgeo/geographic/projected_window.rb', line 376 def for_corners(sw_, ne_) factory_ = sw_.factory psw_ = factory_.project(sw_) pne_ = factory_.project(ne_) ProjectedWindow.new(factory_, psw_.x, psw_.y, pne_.x, pne_.y) end |
.surrounding_point(point_, x_margin_ = nil, y_margin_ = nil) ⇒ Object
Creates a new window that surrounds the given point with the given margin. The point must be a Feature::Point object in unprojected (lat/lng) space, while the margins are numbers in projected space. The y_margin may be given as nil, in which case it is set to the same as the x_margin.
390 391 392 393 394 395 396 397 |
# File 'lib/rgeo/geographic/projected_window.rb', line 390 def surrounding_point(point_, x_margin_=nil, y_margin_=nil) x_margin_ ||= 0.0 y_margin_ ||= x_margin_ factory_ = point_.factory projection_ = factory_.project(point_) ProjectedWindow.new(factory_, projection_.x - x_margin_, projection_.y - y_margin_, projection_.x + x_margin_, projection_.y + y_margin_) end |
Instance Method Details
#center_point ⇒ Object
Returns the center of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
237 238 239 |
# File 'lib/rgeo/geographic/projected_window.rb', line 237 def center_point @center ||= @factory.unproject(@factory.projection_factory.point(*center_xy)) end |
#center_xy ⇒ Object
Returns a two-element array containing the x and y coordinates of the center of the rectangle.
189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rgeo/geographic/projected_window.rb', line 189 def center_xy y_ = (@y_min + @y_max) * 0.5 if @x_min > @x_max x_ = @x_min + x_span * 0.5 limits_ = @factory.projection_limits_window x_ -= limits_.x_span if x_ >= limits_.x_max else x_ = (@x_min + @x_max) * 0.5 end [x_, y_] end |
#clamped_by(min_width_, min_height_, max_width_, max_height_) ⇒ Object
Returns a new window resulting from clamping this window to the given minimum and maximum widths and heights, in the projected coordinate system. The center of the resulting window is the same as the center of this window. Any of the arguments may be given as nil, indicating no constraint.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
# File 'lib/rgeo/geographic/projected_window.rb', line 323 def clamped_by(min_width_, min_height_, max_width_, max_height_) xr_ = x_span yr_ = y_span changed_ = false if min_width_ && xr_ < min_width_ changed_ = true xr_ = min_width_ end if max_width_ && xr_ > max_width_ changed_ = true xr_ = max_width_ end if min_height_ && yr_ < min_height_ changed_ = true yr_ = min_height_ end if max_height_ && yr_ > max_height_ changed_ = true yr_ = max_height_ end if changed_ x_, y_ = *center_xy xr_ *= 0.5 yr_ *= 0.5 ProjectedWindow.new(@factory, x_ - xr_, y_ - yr_, x_ + xr_, y_ + yr_) else self end end |
#contains_point?(point_) ⇒ Boolean
Returns true if the rectangle contains the given point, which must be a Feature::Point in unprojected (lat/lng) space.
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/rgeo/geographic/projected_window.rb', line 261 def contains_point?(point_) projection_ = @factory.project(point_) y_ = projection_.y if y_ <= @y_max && y_ >= @y_min x_ = projection_.x limits_ = @factory.projection_limits_window width_ = limits_.x_span x_ = x_ % width_ x_ -= width_ if x_ >= limits_.x_max if @x_max < @x_min x_ <= @x_max || x_ >= @x_min else x_ <= @x_max && x_ >= @x_min end else false end end |
#contains_window?(window_) ⇒ Boolean
Returns true if the given window is completely contained within this window.
284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/rgeo/geographic/projected_window.rb', line 284 def contains_window?(window_) return nil if window_.factory != @factory if window_.y_max <= @y_max && window_.y_min >= @y_min if (@x_max < @x_min) == window_.crosses_seam? window_.x_max <= @x_max && window_.x_min >= @x_min else @x_max < @x_min && (window_.x_max <= @x_max || window_.x_min >= @x_min) end else false end end |
#crosses_seam? ⇒ Boolean
Returns true if the projection wraps along the x axis, and this rectangle crosses that seam.
154 155 156 |
# File 'lib/rgeo/geographic/projected_window.rb', line 154 def crosses_seam? @x_max < @x_min end |
#degenerate? ⇒ Boolean
Returns true if the rectangle has zero area.
161 162 163 |
# File 'lib/rgeo/geographic/projected_window.rb', line 161 def degenerate? @x_min == @x_max || @y_min == @y_max end |
#eql?(obj_) ⇒ Boolean Also known as: ==
:nodoc:
102 103 104 105 |
# File 'lib/rgeo/geographic/projected_window.rb', line 102 def eql?(obj_) # :nodoc: return false unless obj_.kind_of?(ProjectedWindow) @factory == obj_.factory && @x_min == obj_.x_min && @x_max == obj_.x_max && @y_min = obj_.y_min && @y_max = obj_.y_max end |
#factory ⇒ Object
Returns the Geographic::Factory associated with this window. Note that this factory is the overall geography factory, not the projected factory (which can be obtained by calling Geographic::Factory#projection_factory on this factory).
118 119 120 |
# File 'lib/rgeo/geographic/projected_window.rb', line 118 def factory @factory end |
#hash ⇒ Object
:nodoc:
108 109 110 |
# File 'lib/rgeo/geographic/projected_window.rb', line 108 def hash # :nodoc: @factory.hash + @x_min.hash + @x_max.hash + @y_min.hash + @y_max.hash end |
#inspect ⇒ Object
:nodoc:
97 98 99 |
# File 'lib/rgeo/geographic/projected_window.rb', line 97 def inspect # :nodoc: to_s end |
#ne_point ⇒ Object
Returns the northeast corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
229 230 231 |
# File 'lib/rgeo/geographic/projected_window.rb', line 229 def ne_point @ne ||= @factory.unproject(@factory.projection_factory.point(@x_max, @y_max)) end |
#nw_point ⇒ Object
Returns the northwest corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
221 222 223 |
# File 'lib/rgeo/geographic/projected_window.rb', line 221 def nw_point @nw ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_max)) end |
#random_point ⇒ Object
Returns a random point the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/rgeo/geographic/projected_window.rb', line 245 def random_point y_ = @y_min + (@y_max - @y_min) * rand if @x_min > @x_max x_ = @x_min + x_span * rand limits_ = @factory.projection_limits_window x_ -= limits_.x_span if x_ >= limits_.x_max else x_ = (@x_min + @x_max) * rand end @factory.unproject(@factory.projection_factory.point(x_, y_)) end |
#scaled_by(x_factor_, y_factor_ = nil) ⇒ Object Also known as: *
Returns a new window resulting from scaling this window by the given factors, which must be floating-point values. If y_factor is not explicitly given, it defaults to the same as the x_factor.
303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/rgeo/geographic/projected_window.rb', line 303 def scaled_by(x_factor_, y_factor_=nil) y_factor_ ||= x_factor_ if x_factor_ != 1.0 || y_factor_ != 1.0 x_, y_ = *center_xy xr_ = x_span * 0.5 * x_factor_ yr_ = y_span * 0.5 * y_factor_ ProjectedWindow.new(@factory, x_ - xr_, y_ - yr_, x_ + xr_, y_ + yr_) else self end end |
#se_point ⇒ Object
Returns the southeast corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
213 214 215 |
# File 'lib/rgeo/geographic/projected_window.rb', line 213 def se_point @se ||= @factory.unproject(@factory.projection_factory.point(@x_max, @y_min)) end |
#sw_point ⇒ Object
Returns the southwest corner of the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
205 206 207 |
# File 'lib/rgeo/geographic/projected_window.rb', line 205 def sw_point @sw ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_min)) end |
#to_s ⇒ Object
:nodoc:
93 94 95 |
# File 'lib/rgeo/geographic/projected_window.rb', line 93 def to_s # :nodoc: "#<#{self.class}:0x#{object_id.to_s(16)} s=#{@y_min} w=#{@x_min} n=#{@y_max} e=#{@x_max}>" end |
#with_margin(x_margin_, y_margin_ = nil) ⇒ Object
Returns a new window resulting from adding the given margin to this window. If y_margin is not given, it defaults to the same value as x_margin. Note that the margins may be negative to indicate shrinking of the window.
359 360 361 362 363 364 365 366 |
# File 'lib/rgeo/geographic/projected_window.rb', line 359 def with_margin(x_margin_, y_margin_=nil) y_margin_ ||= x_margin_ if x_margin_ != 0.0 || y_margin_ != 0.0 ProjectedWindow.new(@factory, @x_min - x_margin_, @y_min - y_margin_, @x_max + x_margin_, @y_max + y_margin_) else self end end |
#x_max ⇒ Object
Returns the upper limit in the x (easting) direction.
132 133 134 |
# File 'lib/rgeo/geographic/projected_window.rb', line 132 def x_max @x_max end |
#x_min ⇒ Object
Returns the lower limit in the x (easting) direction.
125 126 127 |
# File 'lib/rgeo/geographic/projected_window.rb', line 125 def x_min @x_min end |
#x_span ⇒ Object Also known as: width, height
Returns the width of the rectangle.
168 169 170 171 172 173 174 |
# File 'lib/rgeo/geographic/projected_window.rb', line 168 def x_span span_ = @x_max - @x_min if span_ < 0 span_ += @factory.projection_limits_window.x_span end span_ end |
#y_max ⇒ Object
Returns the upper limit in the y (northing) direction.
146 147 148 |
# File 'lib/rgeo/geographic/projected_window.rb', line 146 def y_max @y_max end |
#y_min ⇒ Object
Returns the lower limit in the y (northing) direction.
139 140 141 |
# File 'lib/rgeo/geographic/projected_window.rb', line 139 def y_min @y_min end |
#y_span ⇒ Object
Returns the height of the rectangle.
180 181 182 |
# File 'lib/rgeo/geographic/projected_window.rb', line 180 def y_span @y_max - @y_min end |