[Git][debian-gis-team/sfcgal][master] Add another upstream visibilty patch.
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Thu Nov 30 16:12:38 GMT 2023
Bas Couwenberg pushed to branch master at Debian GIS Project / sfcgal
Commits:
96b2f76d by Bas Couwenberg at 2023-11-30T17:02:50+01:00
Add another upstream visibilty patch.
- - - - -
2 changed files:
- + debian/patches/mr297-Visibility-point-outside-polygon.patch
- debian/patches/series
Changes:
=====================================
debian/patches/mr297-Visibility-point-outside-polygon.patch
=====================================
@@ -0,0 +1,326 @@
+Description: Visibility: fix case when point is outside polygon
+ In a such case, the face is unbounded and raised a CGAL exception.
+ Add a test for this case and raise our exception.
+Author: Loïc Bartoletti <loic.bartoletti at oslandia.com>
+Origin: https://gitlab.com/sfcgal/SFCGAL/-/merge_requests/297
+Forwarded: not-needed
+
+--- a/src/algorithm/visibility.cpp
++++ b/src/algorithm/visibility.cpp
+@@ -23,6 +23,7 @@ using Segment_2 = Kernel::Se
+ using Traits_2 = CGAL::Arr_segment_traits_2<Kernel>;
+ using Arrangement_2 = CGAL::Arrangement_2<Traits_2>;
+ using Face_handle = Arrangement_2::Face_handle;
++using Face_const_handle = Arrangement_2::Face_const_handle;
+ using Halfedge_const_handle = Arrangement_2::Halfedge_const_handle;
+ using TEV =
+ CGAL::Triangular_expansion_visibility_2<Arrangement_2, CGAL::Tag_true>;
+@@ -95,24 +96,20 @@ visibility(const Geometry &polygon, cons
+ CGAL::insert(arr, hit->edges_begin(), hit->edges_end());
+
+ // Find the face
+- Arrangement_2::Face_const_handle *face;
+ CGAL::Arr_naive_point_location<Arrangement_2> pl(arr);
+ CGAL::Arr_point_location_result<Arrangement_2>::Type obj =
+ pl.locate(queryPoint);
+
+- // The query point locates in the interior of a face
+- face = boost::get<Arrangement_2::Face_const_handle>(&obj);
+- Arrangement_2 output_arr;
+- Face_handle fh;
+- Halfedge_const_handle he = Halfedge_const_handle();
++ Arrangement_2 output_arr;
++ Face_handle fh;
+
+ // Create Triangular Expansion Visibility object.
+ TEV tev(arr);
+
+- // If the point is within a face, we can compute the visibility that way
+- if (face != nullptr) {
+- fh = tev.compute_visibility(queryPoint, *face, output_arr);
+- } else {
++ if (obj.which() == 0) {
++
++ Halfedge_const_handle he = Halfedge_const_handle();
++
+ // If the point is in a boundary segment, find the corresponding half edge
+ he = arr.halfedges_begin();
+ bool cont = !Segment_2(he->source()->point(), he->target()->point())
+@@ -125,7 +122,7 @@ visibility(const Geometry &polygon, cons
+ he++;
+ if (he == arr.halfedges_end()) {
+ BOOST_THROW_EXCEPTION(
+- Exception("Can not find corresponding half edge."));
++ Exception("Can not find corresponding half edge (from vertex)."));
+ }
+
+ cont = !Segment_2(he->source()->point(), he->target()->point())
+@@ -135,9 +132,26 @@ visibility(const Geometry &polygon, cons
+
+ // Use the half edge to compute the visibility
+ fh = tev.compute_visibility(queryPoint, he, output_arr);
++
++ } else if (obj.which() == 1) {
++ Halfedge_const_handle *he =
++ boost::get<Arrangement_2::Halfedge_const_handle>(&obj);
++ if (he != nullptr) {
++ fh = tev.compute_visibility(queryPoint, *he, output_arr);
++ } else {
++ BOOST_THROW_EXCEPTION(Exception("Can not find corresponding hedge."));
++ }
++ } else if (obj.which() == 2) {
++ Face_const_handle *face =
++ boost::get<Arrangement_2::Face_const_handle>(&obj);
++ if ((face != nullptr) && !((*face)->is_unbounded())) {
++ fh = tev.compute_visibility(queryPoint, *face, output_arr);
++ } else {
++ BOOST_THROW_EXCEPTION(Exception("Can not find corresponding face."));
++ }
+ }
+
+- return query_visibility(fh, he);
++ return query_visibility(fh, fh->outer_ccb());
+ }
+ ///
+ ///
+--- a/test/unit/SFCGAL/algorithm/Visibility.cpp
++++ b/test/unit/SFCGAL/algorithm/Visibility.cpp
+@@ -58,6 +58,50 @@ BOOST_AUTO_TEST_CASE(testVisibility_Poin
+ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
+ }
+
++BOOST_AUTO_TEST_CASE(testVisibility_PointOnPolygon)
++{
++ std::vector<Point> points;
++ points.push_back(Point(0.0, 4.0));
++ points.push_back(Point(0.0, 0.0));
++ points.push_back(Point(3.0, 2.0));
++ points.push_back(Point(4.0, 0.0));
++ points.push_back(Point(4.0, 4.0));
++ points.push_back(Point(1.0, 2.0));
++ points.push_back(Point(0.0, 4.0));
++
++ LineString lineString(points);
++ Polygon poly(lineString);
++
++ Point queryPoint(0.0, 2.0);
++
++ std::unique_ptr<Polygon> result(algorithm::visibility(poly, queryPoint));
++ std::string expectedWkt =
++ "POLYGON((1.0 2.0,0.0 4.0,0.0 0.0,3.0 2.0,1.0 2.0))";
++ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
++}
++
++BOOST_AUTO_TEST_CASE(testVisibility_PointVertexOnPolygon)
++{
++ std::vector<Point> points;
++ points.push_back(Point(0.0, 4.0));
++ points.push_back(Point(0.0, 0.0));
++ points.push_back(Point(3.0, 2.0));
++ points.push_back(Point(4.0, 0.0));
++ points.push_back(Point(4.0, 4.0));
++ points.push_back(Point(1.0, 2.0));
++ points.push_back(Point(0.0, 4.0));
++
++ LineString lineString(points);
++ Polygon poly(lineString);
++
++ Point queryPoint(3.0, 2.0);
++
++ std::unique_ptr<Polygon> result(algorithm::visibility(poly, queryPoint));
++ std::string expectedWkt =
++ "POLYGON((0.0 0.0,3.0 2.0,4.0 0.0,4.0 4.0,1.0 2.0,0.0 2.0,0.0 0.0))";
++ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
++}
++
+ BOOST_AUTO_TEST_CASE(testVisibility_PointInPolygonHole)
+ {
+ std::vector<Point> points;
+@@ -89,6 +133,129 @@ BOOST_AUTO_TEST_CASE(testVisibility_Poin
+ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
+ }
+
++BOOST_AUTO_TEST_CASE(testVisibility_PointOnPolygonHole)
++{
++ std::vector<Point> points;
++ points.push_back(Point(0.0, 4.0));
++ points.push_back(Point(0.0, 0.0));
++ points.push_back(Point(3.0, 2.0));
++ points.push_back(Point(4.0, 0.0));
++ points.push_back(Point(4.0, 4.0));
++ points.push_back(Point(1.0, 2.0));
++ points.push_back(Point(0.0, 4.0));
++
++ std::vector<Point> points_hole;
++ points_hole.push_back(Point(0.2, 1.75));
++ points_hole.push_back(Point(0.9, 1.8));
++ points_hole.push_back(Point(0.7, 1.2));
++ points_hole.push_back(Point(0.2, 1.75));
++
++ LineString lineString(points);
++ LineString hole(points_hole);
++
++ Polygon poly(lineString);
++ poly.addInteriorRing(hole);
++
++ Point queryPoint(0.0, 2.0);
++
++ std::unique_ptr<Polygon> result(algorithm::visibility(poly, queryPoint));
++ std::string expectedWkt = "POLYGON((1.0 2.0,0.0 4.0,0.0 0.0,1.0 0.7,0.2 "
++ "1.8,0.9 1.8,2.2 1.5,3.0 2.0,1.0 2.0))";
++ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
++}
++
++BOOST_AUTO_TEST_CASE(testVisibility_PointVertexOnPolygonHole)
++{
++ std::vector<Point> points;
++ points.push_back(Point(0.0, 4.0));
++ points.push_back(Point(0.0, 0.0));
++ points.push_back(Point(3.0, 2.0));
++ points.push_back(Point(4.0, 0.0));
++ points.push_back(Point(4.0, 4.0));
++ points.push_back(Point(1.0, 2.0));
++ points.push_back(Point(0.0, 4.0));
++
++ std::vector<Point> points_hole;
++ points_hole.push_back(Point(0.2, 1.75));
++ points_hole.push_back(Point(0.9, 1.8));
++ points_hole.push_back(Point(0.7, 1.2));
++ points_hole.push_back(Point(0.2, 1.75));
++
++ LineString lineString(points);
++ LineString hole(points_hole);
++
++ Polygon poly(lineString);
++ poly.addInteriorRing(hole);
++
++ Point queryPoint(3.0, 2.0);
++
++ std::unique_ptr<Polygon> result(algorithm::visibility(poly, queryPoint));
++ std::string expectedWkt =
++ "POLYGON((0.0 0.0,3.0 2.0,4.0 0.0,4.0 4.0,1.0 2.0,0.0 2.0,0.0 1.7,0.2 "
++ "1.8,0.9 1.8,0.7 1.2,0.0 1.0,0.0 0.0))";
++ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
++}
++
++BOOST_AUTO_TEST_CASE(testVisibility_PointOnHolePolygonHole)
++{
++ std::vector<Point> points;
++ points.push_back(Point(0.0, 4.0));
++ points.push_back(Point(0.0, 0.0));
++ points.push_back(Point(3.0, 2.0));
++ points.push_back(Point(4.0, 0.0));
++ points.push_back(Point(4.0, 4.0));
++ points.push_back(Point(1.0, 2.0));
++ points.push_back(Point(0.0, 4.0));
++
++ std::vector<Point> points_hole;
++ points_hole.push_back(Point(0.2, 1.75));
++ points_hole.push_back(Point(0.9, 1.8));
++ points_hole.push_back(Point(0.7, 1.2));
++ points_hole.push_back(Point(0.2, 1.75));
++
++ LineString lineString(points);
++ LineString hole(points_hole);
++
++ Polygon poly(lineString);
++ poly.addInteriorRing(hole);
++
++ Point queryPoint(0.550, 1.775);
++
++ std::unique_ptr<Polygon> result(algorithm::visibility(poly, queryPoint));
++ std::string expectedWkt = "POLYGON((0.7 1.2,0.9 1.8,0.2 1.8,0.7 1.2))";
++ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
++}
++
++BOOST_AUTO_TEST_CASE(testVisibility_PointVertexOnHolePolygonHole)
++{
++ std::vector<Point> points;
++ points.push_back(Point(0.0, 4.0));
++ points.push_back(Point(0.0, 0.0));
++ points.push_back(Point(3.0, 2.0));
++ points.push_back(Point(4.0, 0.0));
++ points.push_back(Point(4.0, 4.0));
++ points.push_back(Point(1.0, 2.0));
++ points.push_back(Point(0.0, 4.0));
++
++ std::vector<Point> points_hole;
++ points_hole.push_back(Point(0.2, 1.75));
++ points_hole.push_back(Point(0.9, 1.8));
++ points_hole.push_back(Point(0.7, 1.2));
++ points_hole.push_back(Point(0.2, 1.75));
++
++ LineString lineString(points);
++ LineString hole(points_hole);
++
++ Polygon poly(lineString);
++ poly.addInteriorRing(hole);
++
++ Point queryPoint(0.9, 1.8);
++
++ std::unique_ptr<Polygon> result(algorithm::visibility(poly, queryPoint));
++ std::string expectedWkt = "POLYGON((0.7 1.2,0.9 1.8,0.2 1.8,0.7 1.2))";
++ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
++}
++
+ BOOST_AUTO_TEST_CASE(testVisibility_SegmentInPolygon)
+ {
+ std::vector<Point> points;
+@@ -154,4 +321,57 @@ BOOST_AUTO_TEST_CASE(testVisibility_Segm
+ "3.0,19.0 -2.0))";
+ BOOST_CHECK_EQUAL(result->asText(1), expectedWkt);
+ }
++
++BOOST_AUTO_TEST_CASE(testVisibility_PointOutPolygon)
++{
++ std::vector<Point> points;
++
++ points.emplace_back(24.2222222, 40);
++ points.emplace_back(24.183792760806462, 39.609819355967744);
++ points.emplace_back(24.069981265022573, 39.23463313526982);
++ points.emplace_back(23.88516142460509, 38.8888595339608);
++ points.emplace_back(23.636435762373097, 38.58578643762691);
++ points.emplace_back(23.333362666039207, 38.33706077539491);
++ points.emplace_back(22.98758906473018, 38.15224093497743);
++ points.emplace_back(22.612402844032257, 38.038429439193536);
++ points.emplace_back(22.2222222, 38);
++ points.emplace_back(21.832041555967745, 38.038429439193536);
++ points.emplace_back(21.45685533526982, 38.15224093497743);
++ points.emplace_back(21.1110817339608, 38.33706077539491);
++ points.emplace_back(20.808008637626905, 38.58578643762691);
++ points.emplace_back(20.55928297539491, 38.8888595339608);
++ points.emplace_back(20.37446313497743, 39.23463313526982);
++ points.emplace_back(20.26065163919354, 39.609819355967744);
++ points.emplace_back(20.2222222, 40);
++ points.emplace_back(20.26065163919354, 40.390180644032256);
++ points.emplace_back(20.37446313497743, 40.76536686473018);
++ points.emplace_back(20.55928297539491, 41.1111404660392);
++ points.emplace_back(20.808008637626905, 41.41421356237309);
++ points.emplace_back(21.111081733960795, 41.66293922460509);
++ points.emplace_back(21.45685533526982, 41.84775906502257);
++ points.emplace_back(21.832041555967745, 41.96157056080646);
++ points.emplace_back(22.2222222, 42);
++ points.emplace_back(22.612402844032257, 41.961570560806464);
++ points.emplace_back(22.98758906473018, 41.84775906502257);
++ points.emplace_back(23.333362666039204, 41.66293922460509);
++ points.emplace_back(23.636435762373097, 41.41421356237309);
++ points.emplace_back(23.88516142460509, 41.1111404660392);
++ points.emplace_back(24.069981265022573, 40.76536686473018);
++ points.emplace_back(24.183792760806462, 40.390180644032256);
++ points.emplace_back(24.2222222, 40);
++
++ LineString lineString(points);
++ lineString.reverse();
++ Polygon const poly(lineString);
++
++ Point const queryPoint(-10, 60);
++
++ try {
++ std::unique_ptr<Polygon> const result(
++ algorithm::visibility(poly, queryPoint));
++ } catch (std::exception &e) {
++ BOOST_CHECK_EQUAL(e.what(), "Can not find corresponding face.");
++ }
++}
++
+ BOOST_AUTO_TEST_SUITE_END()
=====================================
debian/patches/series
=====================================
@@ -1,2 +1,3 @@
sfcgal-config.patch
mr295-Fix-algo-visibility.patch
+mr297-Visibility-point-outside-polygon.patch
View it on GitLab: https://salsa.debian.org/debian-gis-team/sfcgal/-/commit/96b2f76da22bb61135c6b439c92d7c49e2758419
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/sfcgal/-/commit/96b2f76da22bb61135c6b439c92d7c49e2758419
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20231130/0ff21a4b/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list