[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