Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
DelaunayTriangulation.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <unordered_set>
5#include <ranges>
6#include <algorithm>
7#include <memory>
8
9#include <ogr_geometry.h>
10
11#include <fishnet/Vec2D.hpp>
12#include <fishnet/IGeometry.hpp>
13#include <fishnet/Segment.hpp>
15#include <fishnet/Triangle.hpp>
16#include <fishnet/Option.hpp>
17
18namespace fishnet::geometry {
19
28template<IPoint P>
30public:
31 using point_type = P;
32 using numeric_type = typename P::numeric_type;
33
38 explicit DelaunayTriangulation(util::forward_range_of<P> auto const & points, double tolerance = 0.0, bool onlyEdges = false) {
39 OGRMultiPoint multipoint = OGRMultiPoint();
40 for (const auto & p : points) {
41 multipoint.addGeometry(std::make_unique<OGRPoint>(p.x, p.y));
42 }
43 std::unique_ptr<OGRGeometry> delaunay = std::unique_ptr<OGRGeometry>(multipoint.DelaunayTriangulation(tolerance,onlyEdges));
44 if (!delaunay || delaunay->IsEmpty())
45 return;
46 if (onlyEdges) {
47 std::unordered_set<Segment<numeric_type>> delaunayEdges;
48 for(const auto & line : delaunay->toMultiLineString()) {
49 delaunayEdges.emplace(Vec2DReal{line->getX(0), line->getY(0)}, Vec2DReal{line->getX(1), line->getY(1)});
50 }
51 _edges = std::move(delaunayEdges);
52 return;
53 }
54 std::vector<Triangle<numeric_type>> delaunayTriangles;
55 delaunayTriangles.reserve(delaunay->toGeometryCollection()->getNumGeometries());
56 for(const auto & triangle : delaunay->toGeometryCollection()){
57 OGRLinearRing * exteriorRing = triangle->toPolygon()->getExteriorRing();
59 {exteriorRing->getX(0), exteriorRing->getY(0)},
60 {exteriorRing->getX(1), exteriorRing->getY(1)},
61 {exteriorRing->getX(2), exteriorRing->getY(2)}
62 );
63 delaunayTriangles.push_back(t);
64 }
65 _triangles = std::move(delaunayTriangles);
66 _edges = _triangles.transform([](const auto & triangles){
68 | std::views::transform([](const auto & triangle){return triangle.getSegments();})
69 | std::views::join);
70 });
71 }
72
85 return _edges;
86 }
87
89 return _triangles;
90 }
91
92private:
95};
96
97// Deduction guide: infer point type from the range's value type
98template<std::ranges::forward_range R>
99 requires IPoint<std::ranges::range_value_t<R>>
101
102template<std::ranges::forward_range R>
105
106} // namespace fishnet::geometry
Definition Option.hpp:13
Wrapper around GDAL's Delaunay triangulation (GDALTriangulationCreateDelaunay).
Definition DelaunayTriangulation.hpp:29
DelaunayTriangulation(util::forward_range_of< P > auto const &points, double tolerance=0.0, bool onlyEdges=false)
Construct from a forward range of points.
Definition DelaunayTriangulation.hpp:38
P point_type
Definition DelaunayTriangulation.hpp:31
fishnet::Option< std::vector< Triangle< numeric_type > > > triangles() const noexcept
Definition DelaunayTriangulation.hpp:88
typename P::numeric_type numeric_type
Definition DelaunayTriangulation.hpp:32
fishnet::Option< std::unordered_set< Segment< numeric_type > > > edges() const noexcept
Get the unique undirected edges of the triangulation.
Definition DelaunayTriangulation.hpp:84
Triangle shape implementation Inherits from SimplePolygon<T> (a 3-vertex ring)
Definition Triangle.hpp:19
Implementation of a two-dimensional vector.
Definition Vec2D.hpp:16
constexpr T getX() const noexcept
Definition Vec2D.hpp:85
Interface for a point.
Definition IPoint.hpp:92
Definition CollectionConcepts.hpp:27
Definition BoundingBoxWrapper.hpp:5
constexpr auto toUnorderedSet(R &&range)
Definition CollectionConcepts.hpp:73