Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cartocrow/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ set(SOURCES
polyline_set.cpp
segment_delaunay_graph_helpers.cpp
stopwatch.cpp
polygon_set_raw.cpp
point_set.cpp
)
set(HEADERS
core.h
Expand All @@ -35,6 +37,8 @@ set(HEADERS
polyline_set.h
stopwatch.h
polygon_helpers.h
polygon_set_raw.h
point_set.h
)

add_library(core ${SOURCES})
Expand Down
15 changes: 15 additions & 0 deletions cartocrow/core/cubic_bezier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ CubicBezierCurve::CubicBezierCurve(Point<K> source, Point<K> target) :
source + (target - source) * 2.0 / 3.0,
target) {}

CubicBezierCurve::CubicBezierCurve(Segment<K> seg) : CubicBezierCurve(seg.source(), seg.target()) {}

Point<Inexact> CubicBezierCurve::source() const {
return m_p0;
}
Expand Down Expand Up @@ -346,6 +348,19 @@ bool CubicBezierCurve::selfIntersects(double threshold) const {

CubicBezierSpline::CubicBezierSpline() {};

CubicBezierSpline::CubicBezierSpline(Segment<K> segment) {
appendCurve(segment);
}

CubicBezierSpline::CubicBezierSpline(CubicBezierCurve curve)
: m_c({curve.source(), curve.sourceControl(), curve.targetControl(), curve.target()}) {};

CubicBezierSpline::CubicBezierSpline(Polyline<K> polyline) {
for (int i = 0; i < polyline.num_edges(); ++i) {
appendCurve(polyline.vertex(i), polyline.vertex(i + 1));
}
}

void CubicBezierSpline::appendCurve(const Curve& curve) {
for (int i = 0; i < 4; ++i) {
if (i == 0 && !m_c.empty()) {
Expand Down
12 changes: 12 additions & 0 deletions cartocrow/core/cubic_bezier.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class CubicBezierCurve {
/// Construct a cubic Bézier curve from two endpoints.
CubicBezierCurve(Point<K> source, Point<K> target);

/// Construct a cubic Bézier curve from a line segment.
CubicBezierCurve(Segment<K> seg);

/// Returns the source of this curve.
Point<K> source() const;
/// Returns the control point on the source side of this curve.
Expand Down Expand Up @@ -322,6 +325,15 @@ class CubicBezierSpline {
CubicBezierSpline(InputIterator begin, InputIterator end) : m_c(begin, end)
{ assert(m_c.size() == 0 || (m_c.size() - 1) % 3 == 0);}

/// Create a spline from a polyline.
CubicBezierSpline(Segment<K> segment);

/// Create a spline from a single curve;
CubicBezierSpline(CubicBezierCurve curve);

/// Create a spline from a polyline.
CubicBezierSpline(Polyline<K> polyline);

/// Append a cubic Bézier curve.
void appendCurve(const Curve& curve);
/// Append a cubic Bézier curve from its two endpoints and two control points.
Expand Down
3 changes: 3 additions & 0 deletions cartocrow/core/ellipse.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class Ellipse {

Ellipse() : A(1), B(), C(1), D(), E(), F(-1) {}
Ellipse(double a, double b, double c, double d, double e, double f);
Ellipse(Circle<Inexact> c)
: A(1), B(0), C(1), D(-2 * c.center().x()), E(-2 * c.center().y()),
F(c.center().x() * c.center().x() + c.center().y() * c.center().y() - c.squared_radius()) {}

double angle() const;
Point<Inexact> center() const;
Expand Down
32 changes: 32 additions & 0 deletions cartocrow/core/geometric_feature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Copyright (C) 2026 TU Eindhoven

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "core.h"

namespace cartocrow {
using GeometryAttribute = std::variant<int, std::vector<int>, double, std::vector<double>,
std::string, std::vector<std::string>, int64_t>;

using GeometryAttributes = std::unordered_map<std::string, GeometryAttribute>;

template <class Geometry> struct GeometricFeature {
Geometry geometry;
GeometryAttributes attributes;
};
}
13 changes: 13 additions & 0 deletions cartocrow/core/point_set.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "point_set.h"

namespace cartocrow {
PointSet<Inexact> approximate(const PointSet<Exact>& ps) {
std::vector<Point<Inexact>> psInexact;

for (const auto& p : ps.points) {
psInexact.push_back(approximate(p));
}

return {psInexact};
}
}
24 changes: 24 additions & 0 deletions cartocrow/core/point_set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "core.h"

namespace cartocrow {
template <class K>
struct PointSet {
std::vector<Point<K>> points;

PointSet<K> transform(const CGAL::Aff_transformation_2<K>& trans) const {
PointSet<K> transformed;
for (const auto& p : points) {
transformed.points.push_back(p.transform(trans));
}
return transformed;
}

Box bbox() const {
return CGAL::bbox_2(points.begin(), points.end());
}
};

PointSet<Inexact> approximate(const PointSet<Exact>& ps);
} // namespace cartocrow
19 changes: 19 additions & 0 deletions cartocrow/core/polygon_set_raw.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "polygon_set_raw.h"

namespace cartocrow {
PolygonSetRaw<Inexact> approximate(const PolygonSetRaw<Exact>& pgs) {
PolygonSetRaw<Inexact> approximated;
for (const PolygonWithHoles<Exact>& pgn : pgs.polygons_with_holes) {
approximated.polygons_with_holes.push_back(cartocrow::approximate(pgn));
}
return approximated;
}

PolygonSetRaw<Exact> pretendExact(const PolygonSetRaw<Inexact>& pgs) {
PolygonSetRaw<Exact> exact;
for (const auto& pgn : pgs.polygons_with_holes) {
exact.polygons_with_holes.push_back(cartocrow::pretendExact(pgn));
}
return exact;
}
}
58 changes: 58 additions & 0 deletions cartocrow/core/polygon_set_raw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once

#include <cartocrow/core/core.h>
#include <cartocrow/core/transform_helpers.h>

namespace cartocrow {
template <class K>
struct PolygonSetRaw {
std::vector<PolygonWithHoles<K>> polygons_with_holes;

PolygonSetRaw<K> transform(const CGAL::Aff_transformation_2<K>& trans) const {
PolygonSetRaw<K> transformed;
for (const auto& pgn : polygons_with_holes) {
transformed.polygons_with_holes.push_back(cartocrow::transform(trans, pgn));
}
return transformed;
}

Box bbox() const {
return CGAL::bbox_2(polygons_with_holes.begin(), polygons_with_holes.end());
}

PolygonSet<K> polygonSet() const {
PolygonSet<K> polygonSet;
for (auto pgn : polygons_with_holes) {
if (!pgn.outer_boundary().is_simple()) {
throw std::runtime_error("Encountered non-simple polygon");
}
if (pgn.outer_boundary().is_clockwise_oriented()) {
pgn.outer_boundary().reverse_orientation();
}
for (auto& hole : pgn.holes()) {
if (!hole.is_simple()) {
throw std::runtime_error("Encountered non-simple polygon");
}
if (hole.is_counterclockwise_oriented()) {
hole.reverse_orientation();
}
}
polygonSet.symmetric_difference(pgn);
}
return polygonSet;
}

PolygonSetRaw() = default;

PolygonSetRaw(Polygon<K> polygon) {
polygons_with_holes.emplace_back(std::move(polygon));
}

PolygonSetRaw(PolygonWithHoles<K> polygon) {
polygons_with_holes.push_back(std::move(polygon));
}
};

PolygonSetRaw<Inexact> approximate(const PolygonSetRaw<Exact>& pgs);
PolygonSetRaw<Exact> pretendExact(const PolygonSetRaw<Inexact>& pgs);
}
2 changes: 2 additions & 0 deletions cartocrow/core/polyline.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ template <class K> class Polyline {
std::copy(begin, end, std::back_inserter(m_points));
}

Polyline(Segment<K> segment) : m_points({segment.source(), segment.target()}) {};

explicit Polyline(std::vector<CGAL::Point_2<K>> points): m_points(points) {};

void push_back(const CGAL::Point_2<K>& p) {
Expand Down
32 changes: 32 additions & 0 deletions cartocrow/core/straight_geometry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Copyright (C) 2026 TU Eindhoven

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "polyline.h"
#include "polyline_set.h"
#include "point_set.h"
#include "polygon_set_raw.h"

namespace cartocrow {
/// Type that serves as an internal representation of the straight (i.e. linear) features of the OGC Simple Feature Access.
/// OGC name: MultiPolygon Polygon LinearRing
template <class K>
using StraightGeometry = std::variant<PolygonSetRaw<K>, PolygonWithHoles<K>, Polygon<K>,
// MultiLineString LineString Point MultiPoint
PolylineSet<K>, Polyline<K>, Point<K>, PointSet<K>>;
}
1 change: 0 additions & 1 deletion cartocrow/reader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
set(SOURCES
ipe_reader.cpp
gdal_conversion.cpp
boundary_map_reader.cpp
region_map_reader.cpp
Expand Down
Loading