Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
PolygonFilter.hpp
Go to the documentation of this file.
1#pragma once
2#include "SweepLine.hpp"
4namespace fishnet::geometry {
5
6namespace __impl{
7
8
9// template<Shape S>
10// using ShapeFilter = SweepLine<BoundingBoxWrapper<S>,std::vector<S>,HorizontalAABBOrdering<BoundingBoxWrapper<S>>>;
11
18template<IBoundingBoxWrapper BBWrapper>
19using GeometryFilter = SweepLine<BBWrapper, std::vector<typename BBWrapper::element_type>,HorizontalAABBOrdering<BBWrapper>>;
20
21
29template<IBoundingBoxWrapper BBWrapper,util::BiPredicate<typename BBWrapper::geometry_type> BinaryFilter, util::Predicate<typename BBWrapper::geometry_type> Filter>
30class ShapeFilterInsertEvent:public GeometryFilter<BBWrapper>::InsertEvent{
31private:
32 Filter & filter;
33 BinaryFilter & binaryFilter;
34
35public:
36 ShapeFilterInsertEvent(const BBWrapper & box,BinaryFilter & binaryCondition, Filter & condition):GeometryFilter<BBWrapper>::InsertEvent(box),filter(condition),binaryFilter(binaryCondition){}
37
44 virtual void process(GeometryFilter<BBWrapper> & sweepLine, std::vector<typename BBWrapper::element_type> & output)const{
45 const auto & polygonUnderTest = this->obj->getPolygon();
46 if(not filter(polygonUnderTest))
47 return; // directly return if polygon does not pass filter
48 sweepLine.addSLS(this->obj);
49 const auto & sls = sweepLine.getSLS();
50 for(auto it = sls.lower_bound(this->obj); it != sls.begin() && it != sls.end() /* && this->obj->getBoundingBox().left() <= (*it)->getBoundingBox().right() */; ){
51 --it; // skip same element, by first decrementing
52 if( not binaryFilter((*it)->getPolygon(),polygonUnderTest))
53 return;
54 }
55 for(auto it = sls.upper_bound(this->obj);it != sls.end() /* && this->obj->getBoundingBox().right() >= (*it)->getBoundingBox().left() */; ++it){
56 if(not binaryFilter((*it)->getPolygon(),polygonUnderTest))
57 return;
58 }
59 output.push_back(this->obj->getElement()); // add to output if all filters were passed
60 }
61
67 virtual fishnet::math::DEFAULT_NUMERIC eventPoint() const noexcept {
68 return this->obj->getBoundingBox().top();
69 }
70};
71
72template<IBoundingBoxWrapper BBWrapper>
73struct ShapeFilterRemoveEvent: public GeometryFilter<BBWrapper>::DefaultRemoveEvent {
74 ShapeFilterRemoveEvent(const BBWrapper & box):GeometryFilter<BBWrapper>::DefaultRemoveEvent(box){}
80 virtual fishnet::math::DEFAULT_NUMERIC eventPoint() const noexcept {
81 return this->obj->getBoundingBox().bottom();
82 }
83};
84}
85
97template<PolygonRange R,util::BiPredicate<std::ranges::range_value_t<R>> BinaryFilter, util::Predicate<std::ranges::range_value_t<R>> Filter = util::TruePredicate>
98static std::vector<std::ranges::range_value_t<R>> filter( const R & polygons, BinaryFilter binaryCondition, Filter condition = Filter()) noexcept {
99 using P = std::ranges::range_value_t<R>;
100 using SweepLine_t = typename __impl::GeometryFilter<BoundingBoxWrapper<P>>;
101 SweepLine_t sweepLine;
102 std::vector<P> out;
103 std::vector<BoundingBoxWrapper<P>> boundingBoxPolygons;
104 boundingBoxPolygons.reserve(util::size(polygons));
105
106 std::ranges::for_each(polygons,[&boundingBoxPolygons](const auto & p){boundingBoxPolygons.emplace_back(p);});
107 std::ranges::for_each(boundingBoxPolygons,[&sweepLine,&binaryCondition,&condition](const auto & bbPptr){
108 sweepLine.addEvent(std::make_unique<__impl::ShapeFilterInsertEvent<BoundingBoxWrapper<P>,BinaryFilter,Filter>>(bbPptr,binaryCondition,condition));
109 sweepLine.addEvent(std::make_unique<__impl::ShapeFilterRemoveEvent<BoundingBoxWrapper<P>>>(bbPptr));
110 });
111 return sweepLine.sweep(out);
112}
113
123template<PolygonRange R, util::Predicate<std::ranges::range_value_t<R>> Filter>
124static std::vector<std::ranges::range_value_t<R>> filter(const R & polygons, Filter condition) noexcept {
125 auto alwaysTrue = util::TrueBiPredicate();
126 return filter(polygons,alwaysTrue,condition);
127}
128
129
130template<std::ranges::forward_range R, class Proj, geometry::Shape G = std::invoke_result_t<Proj,std::ranges::range_value_t<std::remove_cvref_t<R>>>>
131static std::vector<std::ranges::range_value_t<R>> filter(const R & elements, const Proj & proj, util::BiPredicate<G,G> auto binaryCondition, util::Predicate<G> auto condition) {
132 using T = std::ranges::range_value_t<R>;
134 using BinaryFilter = decltype(binaryCondition);
135 using Filter = decltype(condition);
136 SweepLine_t sweepLine;
137 std::vector<T> out;
138 std::vector<BoundingBoxWrapper<T,Proj>> boundingBoxWrappers;
139 boundingBoxWrappers.reserve(util::size(elements));
140 std::ranges::for_each(elements,[&boundingBoxWrappers](const auto & p){boundingBoxWrappers.emplace_back(p);});
141 std::ranges::for_each(boundingBoxWrappers,[&sweepLine,&binaryCondition,&condition](const auto & bbPptr){
142 sweepLine.addEvent(std::make_unique<__impl::ShapeFilterInsertEvent<BoundingBoxWrapper<T,Proj>,BinaryFilter,Filter>>(bbPptr,binaryCondition,condition));
143 sweepLine.addEvent(std::make_unique<__impl::ShapeFilterRemoveEvent<BoundingBoxWrapper<T,Proj>>>(bbPptr));
144 });
145 return sweepLine.sweep(out);
146}
147}
Wrapper for Polygon objects, which stores a (custom) bounding box.
Definition BoundingBoxWrapper.hpp:13
virtual fishnet::math::DEFAULT_NUMERIC eventPoint() const noexcept=0
const Input * obj
Definition SweepLine.hpp:38
virtual void process(SweepLine< Input, Output, SLSLess, InsertEventsFirst, EventQueueGreater > &sweepLine, Output &output) const =0
Generic Sweep Line template Stores a Sweep Line Status (SLS), keeping track of the current state of t...
Definition SweepLine.hpp:27
Output sweep(Output &output) noexcept
Definition SweepLine.hpp:187
Definition FunctionalConcepts.hpp:42
Definition FunctionalConcepts.hpp:36
Definition BoundingBoxWrapper.hpp:5
static std::vector< std::ranges::range_value_t< R > > filter(const R &polygons, BinaryFilter binaryCondition, Filter condition=Filter()) noexcept
Filters a range of polygons and returns a list of all polygons that pass the filter(s)
Definition PolygonFilter.hpp:98
double DEFAULT_NUMERIC
Definition NumericConcepts.hpp:13
constexpr size_t size(std::ranges::range auto &&range) noexcept
Definition CollectionConcepts.hpp:50
DefaultRemoveEvent(const Input &obj)
Definition SweepLine.hpp:78
InsertEvent(const Input &obj)
Definition SweepLine.hpp:57
Definition FunctionalConcepts.hpp:83