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?(obj_) ⇒ 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.
26 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 |
# File 'lib/rgeo/geographic/projected_window.rb', line 26 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.
89 90 91 |
# File 'lib/rgeo/geographic/projected_window.rb', line 89 def x_max @x_max end |
#x_min ⇒ Object (readonly)
Returns the lower limit in the x (easting) direction.
85 86 87 |
# File 'lib/rgeo/geographic/projected_window.rb', line 85 def x_min @x_min end |
#y_max ⇒ Object (readonly)
Returns the upper limit in the y (northing) direction.
97 98 99 |
# File 'lib/rgeo/geographic/projected_window.rb', line 97 def y_max @y_max end |
#y_min ⇒ Object (readonly)
Returns the lower limit in the y (northing) direction.
93 94 95 |
# File 'lib/rgeo/geographic/projected_window.rb', line 93 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.
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 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 |
# File 'lib/rgeo/geographic/projected_window.rb', line 327 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.
301 302 303 304 305 306 |
# File 'lib/rgeo/geographic/projected_window.rb', line 301 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.
314 315 316 317 318 319 320 321 |
# File 'lib/rgeo/geographic/projected_window.rb', line 314 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.
174 175 176 |
# File 'lib/rgeo/geographic/projected_window.rb', line 174 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.
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/rgeo/geographic/projected_window.rb', line 131 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.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/rgeo/geographic/projected_window.rb', line 251 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.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/rgeo/geographic/projected_window.rb', line 192 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.
214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/rgeo/geographic/projected_window.rb', line 214 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.
102 103 104 |
# File 'lib/rgeo/geographic/projected_window.rb', line 102 def crosses_seam? @x_max < @x_min end |
#degenerate? ⇒ Boolean
Returns true if the rectangle has zero area.
108 109 110 |
# File 'lib/rgeo/geographic/projected_window.rb', line 108 def degenerate? @x_min == @x_max || @y_min == @y_max end |
#eql?(obj_) ⇒ Boolean Also known as: ==
:nodoc:
65 66 67 68 69 |
# File 'lib/rgeo/geographic/projected_window.rb', line 65 def eql?(obj_) # :nodoc: return false unless obj_.is_a?(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 |
#hash ⇒ Object
:nodoc:
72 73 74 |
# File 'lib/rgeo/geographic/projected_window.rb', line 72 def hash # :nodoc: @factory.hash + @x_min.hash + @x_max.hash + @y_min.hash + @y_max.hash end |
#inspect ⇒ Object
:nodoc:
61 62 63 |
# File 'lib/rgeo/geographic/projected_window.rb', line 61 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.
167 168 169 |
# File 'lib/rgeo/geographic/projected_window.rb', line 167 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.
160 161 162 |
# File 'lib/rgeo/geographic/projected_window.rb', line 160 def nw_point @nw ||= @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.
181 182 183 184 185 186 187 |
# File 'lib/rgeo/geographic/projected_window.rb', line 181 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.
232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/rgeo/geographic/projected_window.rb', line 232 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.
153 154 155 |
# File 'lib/rgeo/geographic/projected_window.rb', line 153 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.
146 147 148 |
# File 'lib/rgeo/geographic/projected_window.rb', line 146 def sw_point @sw ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_min)) end |
#to_s ⇒ Object
:nodoc:
57 58 59 |
# File 'lib/rgeo/geographic/projected_window.rb', line 57 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.
286 287 288 289 290 291 292 293 294 |
# File 'lib/rgeo/geographic/projected_window.rb', line 286 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_span ⇒ Object Also known as: width
Returns the width of the rectangle.
114 115 116 117 118 |
# File 'lib/rgeo/geographic/projected_window.rb', line 114 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.
123 124 125 |
# File 'lib/rgeo/geographic/projected_window.rb', line 123 def y_span @y_max - @y_min end |