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 include/geos/algorithm/locate/SimplePointInAreaLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class GEOS_DLL SimplePointInAreaLocator : public PointOnGeometryLocator {
static bool isContained(const geom::CoordinateXY& p,
const geom::Geometry* geom);

static bool isAnyPointContained(const geom::Geometry& pt, const geom::Geometry& areaGeom);

static bool isEveryPointContained(const geom::Geometry& pt, const geom::Geometry& areaGeom);

SimplePointInAreaLocator(const geom::Geometry* p_g)
: g(p_g)
{ }
Expand Down
30 changes: 30 additions & 0 deletions src/algorithm/locate/SimplePointInAreaLocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,36 @@ SimplePointInAreaLocator::isContained(const CoordinateXY& p, const Geometry* geo
return Location::EXTERIOR != locate(p, geom);
}

bool
SimplePointInAreaLocator::isAnyPointContained(const geom::Geometry& pt, const geom::Geometry& area)
{
if (pt.getNumGeometries() > 1) {
for (size_t i = 0; i < pt.getNumGeometries(); i++ ) {
if (isAnyPointContained(*pt.getGeometryN(i), area)) {
return true;
}
}
return false;
}

return isContained(*pt.getCoordinate(), &area);
}

bool
SimplePointInAreaLocator::isEveryPointContained(const geom::Geometry &pt, const geom::Geometry &area)
{
if (pt.getNumGeometries() > 1) {
for (size_t i = 0; i < pt.getNumGeometries(); i++ ) {
if (!isEveryPointContained(*pt.getGeometryN(i), area)) {
return false;
}
}
return true;
}

return isContained(*pt.getCoordinate(), &area);
}

geom::Location
SimplePointInAreaLocator::locateInGeometry(const CoordinateXY& p, const Geometry* geom)
{
Expand Down
27 changes: 20 additions & 7 deletions src/geom/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ Geometry::getEnvelope() const
bool
Geometry::disjoint(const Geometry* g) const
{
if (hasCurvedComponents() || g->hasCurvedComponents()) {
return !intersects(g);
}

#if USE_RELATENG
return operation::relateng::RelateNG::disjoint(this, g);
#else
Expand Down Expand Up @@ -323,13 +327,13 @@ Geometry::intersects(const Geometry* g) const
return predicate::RectangleIntersects::intersects(*p, *this);
}

auto typ = getGeometryTypeId();
if (typ == GEOS_CURVEPOLYGON && g->getGeometryTypeId() == GEOS_POINT) {
auto loc = locate::SimplePointInAreaLocator::locatePointInSurface(*g->getCoordinate(), *detail::down_cast<const Surface*>(this));
return loc != Location::EXTERIOR;
} else if (typ == GEOS_POINT && g->getGeometryTypeId() == GEOS_CURVEPOLYGON) {
auto loc = locate::SimplePointInAreaLocator::locatePointInSurface(*getCoordinate(), *detail::down_cast<const Surface*>(g));
return loc != Location::EXTERIOR;
if (hasCurvedComponents() || g->hasCurvedComponents()) {
if (getDimension() == Dimension::A && g->getDimension() == Dimension::P) {
return locate::SimplePointInAreaLocator::isAnyPointContained(*g, *this);
}
if (g->getDimension() == Dimension::A && getDimension() == Dimension::P) {
return locate::SimplePointInAreaLocator::isAnyPointContained(*this, *g);
}
}

#if USE_RELATENG
Expand Down Expand Up @@ -426,6 +430,15 @@ Geometry::within(const Geometry* g) const
bool
Geometry::contains(const Geometry* g) const
{
if (hasCurvedComponents() || g->hasCurvedComponents()) {
if (getDimension() == Dimension::A && g->getDimension() == Dimension::P) {
return locate::SimplePointInAreaLocator::isEveryPointContained(*g, *this);
}
if (g->getDimension() == Dimension::A && getDimension() == Dimension::P) {
return locate::SimplePointInAreaLocator::isEveryPointContained(*this, *g);
}
}

#if USE_RELATENG
return operation::relateng::RelateNG::contains(this, g);
#else
Expand Down
35 changes: 35 additions & 0 deletions tests/unit/capi/GEOSContainsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,41 @@ void object::test<6>()
ensure_equals("curved geometry not supported", GEOSContains(geom1_, geom2_), 2);
}

template<>
template<>
void object::test<7>()
{
set_test_name("Single-point multipoint contained by MultiSurface");

geom1_ = fromWKT("MULTISURFACE(POLYGON ((100 100, 200 100, 200 200, 100 100)), CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 2 0), (2 0, 0 0))))");
geom2_ = fromWKT("MULTIPOINT ((0.1556955 0.5355459))");

ensure_equals(GEOSContains(geom1_, geom2_), 1);
}

template<>
template<>
void object::test<8>()
{
set_test_name("Only 1 part of 2-point MultiPoint contained by MultiSurface");

geom1_ = fromWKT("MULTISURFACE(POLYGON ((100 100, 200 100, 200 200, 100 100)), CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 2 0), (2 0, 0 0))))");
geom2_ = fromWKT("MULTIPOINT ((0.1556955 0.5355459), (500 500))");

ensure_equals(GEOSContains(geom1_, geom2_), 0);
}

template<>
template<>
void object::test<9>()
{
set_test_name("MultiPoint contained by MultiSurface");

geom1_ = fromWKT("MULTISURFACE(POLYGON ((100 100, 200 100, 200 200, 100 100)), CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 2 0), (2 0, 0 0))))");
geom2_ = fromWKT("MULTIPOINT ((0.1556955 0.5355459), (199 101))");

ensure_equals(GEOSContains(geom1_, geom2_), 1);
}

} // namespace tut

14 changes: 14 additions & 0 deletions tests/unit/capi/GEOSDisjointTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,19 @@ void object::test<2>()
ensure_equals("curved geometry not supported", GEOSDisjoint(geom2_, geom1_), 2);
}

template<>
template<>
void object::test<3>()
{
set_test_name("MultiSurface / MultiPoint PIP");

geom1_ = fromWKT("MULTISURFACE(POLYGON ((100 100, 200 100, 200 200, 100 100)), CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 2 0), (2 0, 0 0))))");
geom2_ = fromWKT("MULTIPOINT ((5000 5000), (0.1556955 0.5355459))");

ensure_equals(GEOSDisjoint(geom1_, geom2_), 0);
ensure_equals(GEOSDisjoint(geom2_, geom1_), 0);
}


} // namespace tut

17 changes: 15 additions & 2 deletions tests/unit/capi/GEOSIntersectsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ template<>
template<>
void object::test<12>()
{
geom1_ = fromWKT("CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 2 0), (2 0, 0 0)))");
geom2_ = fromWKT("POINT (0.1556955 0.5355459)");
geom1_ = fromWKT("MULTISURFACE(POLYGON ((100 100, 200 100, 200 200, 100 100)), CURVEPOLYGON (COMPOUNDCURVE(CIRCULARSTRING(0 0, 1 1, 2 0), (2 0, 0 0))))");
geom2_ = fromWKT("MULTIPOINT ((5000 5000), (0.1556955 0.5355459))");

// PostGIS would return false here because geom2 is inside geom1
// but outside the linearized form of geom1
Expand All @@ -256,5 +256,18 @@ void object::test<13>()
ensure_equals(GEOSIntersects(geom2_, geom1_), 0);
}

template<>
template<>
void object::test<14>()
{
set_test_name("PostGIS ticket 5832");

geom1_ = fromWKT("MULTISURFACE(CURVEPOLYGON(COMPOUNDCURVE((25492739.7449 6677441.1816,25492771.1213 6677416.7832),CIRCULARSTRING(25492771.1213 6677416.7832,25492832.3384 6677400.8583,25492885.9851 6677434.3719),(25492885.9851 6677434.3719,25492900.7986 6677455.7498),CIRCULARSTRING(25492900.7986 6677455.7498,25492901.1068 6677457.3233,25492900.1601 6677458.6175,25492822.2626 6677477.2365,25492747.0232 6677449.7828),(25492747.0232 6677449.7828,25492739.7748 6677444.3615),CIRCULARSTRING(25492739.7748 6677444.3615,25492738.9731 6677442.7789,25492739.7449 6677441.1816))))");
geom2_ = fromWKT("POINT (25492818 6677399.98)");

ensure_equals(GEOSIntersects(geom1_, geom2_), 1);
ensure_equals(GEOSIntersects(geom2_, geom1_), 1);
}

} // namespace tut