Skip to content

Commit

Permalink
DouglasPeuckerLineSimplifier: Avoid crash with Point input and NaN to…
Browse files Browse the repository at this point in the history
…lerance (#1114)

Fixes #1078
  • Loading branch information
dbaston authored Jun 20, 2024
1 parent 108e599 commit 3fdb41f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/simplify/DouglasPeuckerLineSimplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <geos/geom/LineSegment.h>
#include <geos/geom/LinearRing.h>
#include <geos/util.h>
#include <geos/util/IllegalArgumentException.h>

#include <vector>
#include <memory> // for unique_ptr
Expand Down Expand Up @@ -58,6 +59,9 @@ void
DouglasPeuckerLineSimplifier::setDistanceTolerance(
double nDistanceTolerance)
{
if (std::isnan(nDistanceTolerance)) {
throw util::IllegalArgumentException("Tolerance must not be NaN");
}
distanceTolerance = nDistanceTolerance;
}

Expand Down Expand Up @@ -110,6 +114,7 @@ DouglasPeuckerLineSimplifier::simplifySection(
std::size_t j)
{
if((i + 1) == j) {

return;
}

Expand Down
35 changes: 25 additions & 10 deletions tests/unit/simplify/DouglasPeuckerSimplifierTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct test_dpsimp_data {
GeomPtr simplified = DouglasPeuckerSimplifier::simplify(g.get(), tolerance);

ensure("Simplified geometry is invalid!", simplified->isValid());

GeomPtr exp(wktreader.read(wkt_expected));
ensure_equals_geometry(exp.get(), simplified.get());
}
Expand All @@ -69,8 +69,8 @@ template<>
template<>
void object::test<1>()
{
checkDP("POLYGON ((20 220, 40 220, 60 220, 80 220, 100 220, 120 220, 140 220, 140 180, 100 180, 60 180, 20 180, 20 220))",
10.0,
checkDP("POLYGON ((20 220, 40 220, 60 220, 80 220, 100 220, 120 220, 140 220, 140 180, 100 180, 60 180, 20 180, 20 220))",
10.0,
"POLYGON ((20 220, 140 220, 140 180, 20 180, 20 220))");
}

Expand All @@ -79,8 +79,8 @@ template<>
template<>
void object::test<2>()
{
checkDP("POLYGON ((40 240, 160 241, 280 240, 280 160, 160 240, 40 140, 40 240))",
1,
checkDP("POLYGON ((40 240, 160 241, 280 240, 280 160, 160 240, 40 140, 40 240))",
1,
"MULTIPOLYGON (((40 240, 160 240, 40 140, 40 240)), ((160 240, 280 240, 280 160, 160 240)))");
}

Expand All @@ -90,7 +90,7 @@ template<>
void object::test<3>()
{
checkDP("POLYGON ((120 120, 121 121, 122 122, 220 120, 180 199, 160 200, 140 199, 120 120))",
10,
10,
"POLYGON ((120 120, 220 120, 180 199, 160 200, 140 199, 120 120))");
}

Expand Down Expand Up @@ -267,7 +267,7 @@ template<>
void object::test<14>()
{
checkDP(
"POLYGON ((21.32686 47.78723, 21.32386 47.79023, 21.32186 47.80223, 21.31486 47.81023, 21.32786 47.81123, 21.33986 47.80223, 21.33886 47.81123, 21.32686 47.82023, 21.32586 47.82723, 21.32786 47.82323, 21.33886 47.82623, 21.34186 47.82123, 21.36386 47.82223, 21.40686 47.81723, 21.32686 47.78723))",
"POLYGON ((21.32686 47.78723, 21.32386 47.79023, 21.32186 47.80223, 21.31486 47.81023, 21.32786 47.81123, 21.33986 47.80223, 21.33886 47.81123, 21.32686 47.82023, 21.32586 47.82723, 21.32786 47.82323, 21.33886 47.82623, 21.34186 47.82123, 21.36386 47.82223, 21.40686 47.81723, 21.32686 47.78723))",
0.0036,
"POLYGON ((21.32686 47.78723, 21.31486 47.81023, 21.32786 47.81123, 21.33986 47.80223, 21.328068201892744 47.823286782334385, 21.33886 47.82623, 21.34186 47.82123, 21.40686 47.81723, 21.32686 47.78723))"
);
Expand All @@ -284,7 +284,7 @@ template<>
void object::test<15>()
{
checkDP(
"MULTIPOLYGON (((-76.02716827 36.55671692, -75.99866486 36.55665207, -75.91191864 36.54253006, -75.92480469 36.47397614, -75.97727966 36.4780159, -75.97628784 36.51792526, -76.02716827 36.55671692)), ((-75.90198517 36.55619812, -75.8781662 36.55587387, -75.77315521 36.22925568, -75.78317261 36.22519302, -75.90198517 36.55619812)))",
"MULTIPOLYGON (((-76.02716827 36.55671692, -75.99866486 36.55665207, -75.91191864 36.54253006, -75.92480469 36.47397614, -75.97727966 36.4780159, -75.97628784 36.51792526, -76.02716827 36.55671692)), ((-75.90198517 36.55619812, -75.8781662 36.55587387, -75.77315521 36.22925568, -75.78317261 36.22519302, -75.90198517 36.55619812)))",
0.05,
"POLYGON ((-76.02716827 36.55671692, -75.91191864 36.54253006, -75.92480469 36.47397614, -76.02716827 36.55671692))"
);
Expand All @@ -295,7 +295,7 @@ template<>
template<>
void object::test<16>()
{
checkDP("POLYGON ((1 0, 2 0, 2 2, 0 2, 0 0, 1 0))",
checkDP("POLYGON ((1 0, 2 0, 2 2, 0 2, 0 0, 1 0))",
0,
"POLYGON (( 0 0, 2 0, 2 2, 0 2, 0 0))");
}
Expand All @@ -305,7 +305,7 @@ template<>
template<>
void object::test<17>()
{
checkDPNoChange("LINESTRING (1 0, 2 0, 2 2, 0 2, 0 0, 1 0)",
checkDPNoChange("LINESTRING (1 0, 2 0, 2 2, 0 2, 0 0, 1 0)",
0);
}

Expand Down Expand Up @@ -334,4 +334,19 @@ void object::test<19>()
);
}

// https://github.com/libgeos/geos/issues/1078
template<>
template<>
void object::test<20>()
{
auto gfact = GeometryFactory::getDefaultInstance();
auto pt = gfact->createPoint(Coordinate{0, 0});

try {
DouglasPeuckerSimplifier::simplify(pt.get(), std::numeric_limits<double>::quiet_NaN());
fail("Exception not thrown.");
} catch (const geos::util::IllegalArgumentException&) {
}
}

} // namespace tut

0 comments on commit 3fdb41f

Please sign in to comment.