Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
Rectangle.hpp
Go to the documentation of this file.
1#pragma once
3#include <algorithm>
4#include "Ring.hpp"
5#include <iostream>
6
7namespace fishnet::geometry {
8
14template<fishnet::math::Number T>
15class Rectangle:public Ring<T>{
16private:
17 T _left;
18 T _top;
19 T _right;
20 T _bottom;
21
22 void init() noexcept {
23 for(const auto p : this->getPoints() | std::views::take(1)){
24 _left = p.x;
25 _right = _left;
26 _top = p.y;
27 _bottom = _top;
28 }
29 for(const auto p : this->getPoints()){
30 if(p.y > _top)
31 _top = p.y;
32 if(p.y < _bottom)
33 _bottom = p.y;
34 if(p.x > _right)
35 _right = p.x;
36 if(p.x < _left)
37 _left = p.x;
38 }
39 }
40
41public:
42 Rectangle(Shape auto const & ring):Ring<T>(ring.aaBB().getPoints()){
43 init();
44 }
45
46 Rectangle(T left, T top, T right, T bottom):Ring<T>({{left,top},{right,top},{right,bottom},{left,bottom}}),_left(left),_top(top),_right(right),_bottom(bottom){}
47
52 Rectangle(Vec2D<T> const& corner, Vec2D<T> const& oppositeCorner)
53 :Rectangle(std::min(corner.x, oppositeCorner.x), std::max(corner.y, oppositeCorner.y),
54 std::max(corner.x, oppositeCorner.x), std::min(corner.y, oppositeCorner.y)) {}
55
56 T left() const noexcept {
57 return _left;
58 }
59
60 T right() const noexcept {
61 return _right;
62 }
63
64 T top() const noexcept {
65 return _top;
66 }
67
68 T bottom() const noexcept {
69 return _bottom;
70 }
71
72 const Rectangle<T> & aaBB() const noexcept {
73 return *this;
74 }
75
76 Rectangle<T> scale(T factor) const noexcept {
77 if (factor <= 0){
78 std::cerr << "Scale factor must be greater than 0!" << std::endl;
79 return Rectangle<T>(*this);
80 }
81 auto xDiff = (_right - _left) * (factor-1);
82 auto yDiff = (_top - _bottom) * (factor-1);
83 auto top = _top + yDiff;
84 auto bottom = _bottom - yDiff;
85 auto left = _left - xDiff;
86 auto right = _right + xDiff;
88 }
89
90 template<fishnet::math::Number U>
91 bool overlap(const Rectangle<U> & other) const noexcept {
92 if(this->right() < other.left() || this->left() > other.right())
93 return false;
94 if(this->top() < other.bottom() || this->bottom() > other.top())
95 return false;
96 return true;
97 }
98
99};
100
101//Deduction guide:
102template<Shape S>
104
105// Explicit template instantiation
106// Ring<DEFAULT_NUMERIC> is instantiated here rather than in Ring.hpp: aaBB() returns Rectangle<T>
107// by value, so it needs Rectangle<T> complete, which is only guaranteed at this point regardless
108// of whether Ring.hpp or Rectangle.hpp gets included first (see the NOTE in Ring.hpp).
111
119template<std::ranges::range R>
121 static_assert(Shape<std::ranges::range_value_t<R>>, "Range value type must be a Shape");
122 using number = typename std::ranges::range_value_t<R>::numeric_type;
123 number left = std::numeric_limits<number>::max();
124 number right = std::numeric_limits<number>::lowest();
125 number top = std::numeric_limits<number>::lowest();
126 number bottom = std::numeric_limits<number>::max();
127 if(util::isEmpty(polygons)){
128 throw std::runtime_error("Range of polygons is empty, cannot compute bounding box");
129 }
130 for(const auto & polygon: polygons){
131 auto aaBB = Rectangle<number>(polygon);
132 if(aaBB.left() < left)
133 left = aaBB.left();
134 if(aaBB.right() > right)
135 right = aaBB.right();
136 if(aaBB.top() > top)
137 top = aaBB.top();
138 if(aaBB.bottom() < bottom)
139 bottom = aaBB.bottom();
140 }
141 return Rectangle<number>(left,top,right,bottom);
142}
143static_assert(IEnvelope<Rectangle<double>>);
144static_assert(Shape<Ring<double>>);
145static_assert(IRing<Ring<double>>);
146static_assert(IRing<Rectangle<double>>);
147} // namespace fishnet::geometry
Implementation of a rectangle Stores top,right,bottom and left point of the rectangle.
Definition Rectangle.hpp:15
Rectangle< T > scale(T factor) const noexcept
Definition Rectangle.hpp:76
T left() const noexcept
Definition Rectangle.hpp:56
T right() const noexcept
Definition Rectangle.hpp:60
Rectangle(T left, T top, T right, T bottom)
Definition Rectangle.hpp:46
Rectangle(Shape auto const &ring)
Definition Rectangle.hpp:42
const Rectangle< T > & aaBB() const noexcept
Definition Rectangle.hpp:72
bool overlap(const Rectangle< U > &other) const noexcept
Definition Rectangle.hpp:91
Rectangle(Vec2D< T > const &corner, Vec2D< T > const &oppositeCorner)
Construct the rectangle spanned by two opposite corners.
Definition Rectangle.hpp:52
T bottom() const noexcept
Definition Rectangle.hpp:68
T top() const noexcept
Definition Rectangle.hpp:64
Implementation of a ring.
Definition Ring.hpp:31
constexpr util::view_of< Vec2D< T > > auto getPoints() const noexcept
Definition Ring.hpp:141
Implementation of a two-dimensional vector.
Definition Vec2D.hpp:16
A geometry enclosing an area: a ring, a polygon or a multi-polygon.
Definition IGeometry.hpp:23
Definition BoundingBoxWrapper.hpp:5
static Rectangle< typename std::ranges::range_value_t< R >::numeric_type > minimalBoundingBox(const R &polygons)
Helper function to get the common bounding box for a range of polygons.
Definition Rectangle.hpp:120
constexpr bool isEmpty(std::ranges::range auto &&range) noexcept
Definition CollectionConcepts.hpp:59
STL namespace.