Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use spatial index to check shell nesting in IsValidOp #256

Merged
merged 2 commits into from
Dec 13, 2019
Merged
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/IndexedPointInAreaLocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ class IndexedPointInAreaLocator : public PointOnGeometryLocator {
*/
IndexedPointInAreaLocator(const geom::Geometry& g);

const geom::Geometry& getGeometry() const {
return areaGeom;
}

/** \brief
* Determines the [Location](@ref geom::Location) of a point in an areal
* [Geometry](@ref geom::Geometry).
Expand Down
2 changes: 1 addition & 1 deletion include/geos/geomgraph/GeometryGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class GEOS_DLL GeometryGraph: public PlanarGraph {
/// Returned object is owned by this GeometryGraph
geom::CoordinateSequence* getBoundaryPoints();

Edge* findEdge(const geom::LineString* line);
Edge* findEdge(const geom::LineString* line) const;

void computeSplitEdges(std::vector<Edge*>* edgelist);

Expand Down
108 changes: 108 additions & 0 deletions include/geos/operation/valid/IndexedNestedShellTester.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2001-2002 Vivid Solutions Inc.
* Copyright (C) 2005 Refractions Research Inc.
* Copyright (C) 2010 Safe Software Inc.
* Copyright (C) 2010 Sandro Santilli <[email protected]>
* Copyright (C) 2019 Daniel Baston <[email protected]>
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************/

#ifndef GEOS_OP_VALID_INDEXEDNESTEDSHELLTESTER_H
#define GEOS_OP_VALID_INDEXEDNESTEDSHELLTESTER_H

#include <geos/geom/Polygon.h>
#include <geos/index/SpatialIndex.h>

#include <cstddef>
#include <memory>

// Forward declarations
namespace geos {
namespace algorithm {
namespace locate {
class IndexedPointInAreaLocator;
}
}
namespace geom {
class Polygon;
}
namespace geomgraph {
class GeometryGraph;
}
namespace operation {
namespace valid {
class PolygonIndexedLocators;
}
}
}

namespace geos {
namespace operation {
namespace valid {

class IndexedNestedShellTester {

public:
IndexedNestedShellTester(const geomgraph::GeometryGraph& g, size_t initialCapacity);

void add(const geom::Polygon& p) {
polys.push_back(&p);
}

const geom::Coordinate* getNestedPoint();

bool isNonNested();

private:
void compute();

/**
* Check if a shell is incorrectly nested within a polygon.
* This is the case if the shell is inside the polygon shell,
* but not inside a polygon hole.
* (If the shell is inside a polygon hole, the nesting is valid.)
*
* The algorithm used relies on the fact that the rings must be
* properly contained.
* E.g. they cannot partially overlap (this has been previously
* checked by <code>checkRelateConsistency</code>
*/
void checkShellNotNested(const geom::LinearRing* shell, PolygonIndexedLocators & locs);

/**
* This routine checks to see if a shell is properly contained
* in a hole.
* It assumes that the edges of the shell and hole do not
* properly intersect.
*
* @return <code>null</code> if the shell is properly contained, or
* a Coordinate which is not inside the hole if it is not
*/
const geom::Coordinate* checkShellInsideHole(const geom::LinearRing* shell,
algorithm::locate::IndexedPointInAreaLocator & holeLoc);

/// Externally owned
const geomgraph::GeometryGraph& graph;

std::vector<const geom::Polygon*> polys;

// Externally owned, if not null
const geom::Coordinate* nestedPt;

bool processed;
};

}
}
}

#endif //GEOS_INDEXEDNESTEDSHELLTESTER_H
31 changes: 1 addition & 30 deletions include/geos/operation/valid/IsValidOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,35 +149,6 @@ class GEOS_DLL IsValidOp {
void checkShellsNotNested(const geom::MultiPolygon* mp,
geomgraph::GeometryGraph* graph);

/**
* Check if a shell is incorrectly nested within a polygon.
* This is the case if the shell is inside the polygon shell,
* but not inside a polygon hole.
* (If the shell is inside a polygon hole, the nesting is valid.)
*
* The algorithm used relies on the fact that the rings must be
* properly contained.
* E.g. they cannot partially overlap (this has been previously
* checked by <code>checkRelateConsistency</code>
*/
void checkShellNotNested(const geom::LinearRing* shell,
const geom::Polygon* p,
geomgraph::GeometryGraph* graph);

/**
* This routine checks to see if a shell is properly contained
* in a hole.
* It assumes that the edges of the shell and hole do not
* properly intersect.
*
* @return <code>null</code> if the shell is properly contained, or
* a Coordinate which is not inside the hole if it is not
*
*/
const geom::Coordinate* checkShellInsideHole(
const geom::LinearRing* shell,
const geom::LinearRing* hole,
geomgraph::GeometryGraph* graph);

void checkConnectedInteriors(geomgraph::GeometryGraph& graph);

Expand All @@ -201,7 +172,7 @@ class GEOS_DLL IsValidOp {
static const geom::Coordinate* findPtNotNode(
const geom::CoordinateSequence* testCoords,
const geom::LinearRing* searchRing,
geomgraph::GeometryGraph* graph);
const geomgraph::GeometryGraph* graph);

/** \brief
* Checks whether a coordinate is valid for processing.
Expand Down
1 change: 1 addition & 0 deletions include/geos/operation/valid/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ geos_HEADERS = \
ConnectedInteriorTester.h \
ConsistentAreaTester.h \
IsValidOp.h \
IndexedNestedShellTester.h \
MakeValid.h \
QuadtreeNestedRingTester.h \
RepeatedPointRemover.h \
Expand Down
2 changes: 1 addition & 1 deletion src/geomgraph/GeometryGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ GeometryGraph::getBoundaryPoints()
}

Edge*
GeometryGraph::findEdge(const LineString* line)
GeometryGraph::findEdge(const LineString* line) const
{
return lineEdgeMap.find(line)->second;
}
Expand Down
1 change: 1 addition & 0 deletions src/operation/valid/IndexedNestedRingTester.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef GEOS_OP_VALID_OFFSETCURVEVERTEXLIST_H
#define GEOS_OP_VALID_OFFSETCURVEVERTEXLIST_H

#include <cstddef>
#include <vector> // for composition

// Forward declarations
Expand Down
Loading