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.
Instance Attribute Summary collapse
-
#factory ⇒ Object
readonly
Returns the Geographic::Factory associated with this window.
-
#x_max ⇒ Object
readonly
Returns the upper limit in the x (easting) direction.
-
#x_min ⇒ Object
readonly
Returns the lower limit in the x (easting) direction.
-
#y_max ⇒ Object
readonly
Returns the upper limit in the y (northing) direction.
-
#y_min ⇒ Object
readonly
Returns the lower limit in the y (northing) direction.
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?(other) ⇒ Boolean
(also: #==)
:nodoc:.
-
#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 inside 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_span ⇒ Object
(also: #width)
Returns the width of the rectangle.
-
#y_span ⇒ Object
(also: #height)
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.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/rgeo/geographic/projected_window.rb', line 27 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 |
Instance Attribute Details
#factory ⇒ Object (readonly)
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).
81 82 83 |
# File 'lib/rgeo/geographic/projected_window.rb', line 81 def factory @factory end |
#x_max ⇒ Object (readonly)
Returns the upper limit in the x (easting) direction.
87 88 89 |
# File 'lib/rgeo/geographic/projected_window.rb', line 87 def x_max @x_max end |
#x_min ⇒ Object (readonly)
Returns the lower limit in the x (easting) direction.
84 85 86 |
# File 'lib/rgeo/geographic/projected_window.rb', line 84 def x_min @x_min end |
#y_max ⇒ Object (readonly)
Returns the upper limit in the y (northing) direction.
93 94 95 |
# File 'lib/rgeo/geographic/projected_window.rb', line 93 def y_max @y_max end |
#y_min ⇒ Object (readonly)
Returns the lower limit in the y (northing) direction.
90 91 92 |
# File 'lib/rgeo/geographic/projected_window.rb', line 90 def y_min @y_min 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.
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/rgeo/geographic/projected_window.rb', line 343 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 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.
312 313 314 315 316 317 |
# File 'lib/rgeo/geographic/projected_window.rb', line 312 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.
325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/rgeo/geographic/projected_window.rb', line 325 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.
178 179 180 181 182 |
# File 'lib/rgeo/geographic/projected_window.rb', line 178 def center_point return @center_point if defined?(@center_point) @center_point = @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.
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/rgeo/geographic/projected_window.rb', line 127 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.
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/rgeo/geographic/projected_window.rb', line 257 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.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/rgeo/geographic/projected_window.rb', line 198 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.
220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/rgeo/geographic/projected_window.rb', line 220 def contains_window?(window_) return 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.
98 99 100 |
# File 'lib/rgeo/geographic/projected_window.rb', line 98 def crosses_seam? @x_max < @x_min end |
#degenerate? ⇒ Boolean
Returns true if the rectangle has zero area.
104 105 106 |
# File 'lib/rgeo/geographic/projected_window.rb', line 104 def degenerate? @x_min == @x_max || @y_min == @y_max end |
#eql?(other) ⇒ Boolean Also known as: ==
:nodoc:
66 67 68 69 70 |
# File 'lib/rgeo/geographic/projected_window.rb', line 66 def eql?(other) # :nodoc: return false unless other.is_a?(ProjectedWindow) @factory == other.factory && @x_min == other.x_min && @x_max == other.x_max && @y_min = other.y_min && @y_max = other.y_max end |
#hash ⇒ Object
:nodoc:
73 74 75 |
# File 'lib/rgeo/geographic/projected_window.rb', line 73 def hash # :nodoc: [@factory, @x_min, @x_max, @y_min, @y_max].hash end |
#inspect ⇒ Object
:nodoc:
62 63 64 |
# File 'lib/rgeo/geographic/projected_window.rb', line 62 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.
169 170 171 172 173 |
# File 'lib/rgeo/geographic/projected_window.rb', line 169 def ne_point return @ne_point if defined?(@ne_point) @ne_point = @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.
160 161 162 163 164 |
# File 'lib/rgeo/geographic/projected_window.rb', line 160 def nw_point return @nw_point if defined?(@nw_point) @nw_point = @factory.unproject(@factory.projection_factory.point(@x_min, @y_max)) end |
#random_point ⇒ Object
Returns a random point inside the rectangle in unprojected (lat/lng) space, as a Feature::Point object.
187 188 189 190 191 192 193 |
# File 'lib/rgeo/geographic/projected_window.rb', line 187 def random_point y_ = @y_min + y_span * rand x_ = @x_min + x_span * rand limits_ = @factory.projection_limits_window x_ -= limits_.x_span if x_ >= limits_.x_max @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.
238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/rgeo/geographic/projected_window.rb', line 238 def scaled_by(x_factor_, y_factor_ = nil) y_factor_ ||= x_factor_ if x_factor_ != 1 || y_factor_ != 1 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.
151 152 153 154 155 |
# File 'lib/rgeo/geographic/projected_window.rb', line 151 def se_point return @se_point if defined?(@se_point) @se_point = @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.
142 143 144 145 146 |
# File 'lib/rgeo/geographic/projected_window.rb', line 142 def sw_point return @sw_point if defined?(@sw_point) @sw_point = @factory.unproject(@factory.projection_factory.point(@x_min, @y_min)) end |
#to_s ⇒ Object
:nodoc:
58 59 60 |
# File 'lib/rgeo/geographic/projected_window.rb', line 58 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.
292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/rgeo/geographic/projected_window.rb', line 292 def with_margin(x_margin_, y_margin_ = nil) y_margin_ ||= x_margin_ if x_margin_ != 0 || y_margin_ != 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_span ⇒ Object Also known as: width
Returns the width of the rectangle.
110 111 112 113 114 |
# File 'lib/rgeo/geographic/projected_window.rb', line 110 def x_span span_ = @x_max - @x_min span_ += @factory.projection_limits_window.x_span if span_ < 0 span_ end |
#y_span ⇒ Object Also known as: height
Returns the height of the rectangle.
119 120 121 |
# File 'lib/rgeo/geographic/projected_window.rb', line 119 def y_span @y_max - @y_min end |