Commit 5d508893 by Volker Krause

### Compute OTP bounding polygons as convex hull of all stop positions

```This further improves the result beyond what just outlier filtering gives
us.```
parent ef470b25
 ... ... @@ -91,6 +91,7 @@ target_sources(KPublicTransport PRIVATE gbfs/gbfsstore.cpp gbfs/gbfsvehicletypes.cpp geo/convexhull.cpp geo/geojson.cpp geo/polylinedecoder.cpp ... ...
 /* SPDX-FileCopyrightText: 2021 Volker Krause SPDX-License-Identifier: LGPL-2.0-or-later */ #include "convexhull_p.h" #include #include #include using namespace KPublicTransport; static double orientation(QPointF p, QPointF q, QPointF r) { return (q.y() - p.y()) * (r.x() - q.x()) - (r.y() - q.y()) * (q.x() - p.x()); } // see https://en.wikipedia.org/wiki/Gift_wrapping_algorithm QPolygonF ConvexHull::compute(const std::vector &points) { QPolygonF hull; if (points.size() < 3) { return hull; } // find left-most point const auto it = std::min_element(points.begin(), points.end(), [](auto lhs, auto rhs) { return lhs.x() < rhs.x(); }); hull.push_back(*it); auto p = std::distance(points.begin(), it); while (true) { auto q = (p + 1) % points.size(); for (std::size_t r = 0; r < points.size(); ++r) { if (q == r) { continue; } auto o = orientation(points[p], points[q], points[r]); if (o < 0.0) { q = r; } else if (o == 0.0) { if (QLineF(points[p], points[r]).length() > QLineF(points[p], points[q]).length()) { q = r; } } } p = q; hull.push_back(points[p]); if (hull.isClosed()) { break; } } return hull; }
 /* SPDX-FileCopyrightText: 2021 Volker Krause SPDX-License-Identifier: LGPL-2.0-or-later */ #ifndef KPUBLICTRANSPORT_CONVEXHULL_H #define KPUBLICTRANSPORT_CONVEXHULL_H #include class QPointF; class QPolygonF; namespace KPublicTransport { /** Convex hull algorithm. * @internal */ namespace ConvexHull { /** Compute the convex hull of @p points. */ QPolygonF compute(const std::vector &points); } } #endif // KPUBLICTRANSPORT_CONVEXHULL_H
 ... ... @@ -8,6 +8,7 @@ add_custom_target(run-endpoint-probe COMMAND endpointprobe \${CMAKE_SOURCE_DIR}/s add_executable(otpprobe otpprobe.cpp ../lib/geo/geojson.cpp ../lib/geo/convexhull.cpp ) target_link_libraries(otpprobe Qt5::Gui Qt5::Network) add_custom_target(run-otp-probe COMMAND otpprobe \${CMAKE_SOURCE_DIR}/src/lib/networks) ... ...