Commit f1868e13 authored by Paul Ramsey's avatar Paul Ramsey

Merge branch 'svn-3.6' of https://git.osgeo.org/gogs/geos/geos into svn-3.6

parents b8a51cb0 dfea6aaa
Pipeline #82818025 passed with stage
in 18 minutes and 40 seconds
......@@ -6,6 +6,12 @@ Changes in 3.6.4
(#928, Sergey Fedoseev)
- Fix incorrect error return values in GEOSLength and
GEOSisValidDetail (#941, Dan Baston)
- Envelope constructor use strtod (#875)
- Polygon build failure in Overlay difference (#789 Paul Ramsey)
- Invalid union result from valid polygon inputs (#838)
- Static library does not contain C API (#878)
- Prevent crash when querying empty STRtree (#730)
- Overlay performance improvement (#986, Paul Ramsey)
Changes in 3.6.3
......
......@@ -7,8 +7,8 @@ Project homepage: http://geos.osgeo.org/
| branch / CI | Debbie | Winnie | Dronie | Travis CI | GitLab CI | AppVeyor |
|:--- |:--- |:--- |:--- |:--- |:--- |:--- |
| svn-trunk | [![debbie](https://debbie.postgis.net/buildStatus/icon?job=GEOS_Trunk)](https://debbie.postgis.net/view/GEOS/job/GEOS_Trunk/) | [![winnie](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_trunk/badge/icon)](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_trunk/) | [![dronie](https://drone.osgeo.org/api/badges/geos/geos/status.svg?branch=svn-trunk)](https://drone.osgeo.org/geos/geos?branch=svn-trunk) | [![travis](https://travis-ci.org/OSGeo/geos.svg?branch=svn-trunk)](https://travis-ci.org/OSGeo/geos?branch=svn-trunk) | [![gitlab-ci](https://gitlab.com/geos/libgeos/badges/svn-trunk/build.svg)](https://gitlab.com/geos/libgeos/commits/svn-trunk) | [![appveyor](https://ci.appveyor.com/api/projects/status/ao909hwpsb1yu062/branch/svn-trunk?svg=true)](https://ci.appveyor.com/project/OSGeo/geos/branch/svn-trunk) |
| svn-3.6 | [![debbie](https://debbie.postgis.net/buildStatus/icon?job=GEOS_Branch_3.6)](https://debbie.postgis.net/view/GEOS/job/GEOS_Branch_3.6/) | [![winnie](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_branch_3.6/badge/icon)](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_branch_3.6/) | [![dronie](https://drone.osgeo.org/api/badges/geos/geos/status.svg?branch=svn-3.6)](https://drone.osgeo.org/geos/geos?branch=svn-3.6) | [![travis](https://travis-ci.org/OSGeo/geos.svg?branch=svn-3.6)](https://travis-ci.org/OSGeo/geos?branch=svn-3.6) | [![gitlab-ci](https://gitlab.com/geos/libgeos/badges/svn-3.6/build.svg)](https://gitlab.com/geos/libgeos/commits/svn-3.6) | [![appveyor](https://ci.appveyor.com/api/projects/status/ao909hwpsb1yu062/branch/svn-3.6?svg=true)](https://ci.appveyor.com/project/OSGeo/geos/branch/svn-3.6) |
| svn-trunk | [![debbie](https://debbie.postgis.net/buildStatus/icon?job=GEOS_Trunk)](https://debbie.postgis.net/view/GEOS/job/GEOS_Trunk/) | [![winnie](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_trunk/badge/icon)](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_trunk/) | [![dronie](https://dronie.osgeo.org/api/badges/geos/geos/status.svg?branch=svn-trunk)](https://dronie.osgeo.org/geos/geos?branch=svn-trunk) | [![travis](https://travis-ci.org/OSGeo/geos.svg?branch=svn-trunk)](https://travis-ci.org/OSGeo/geos?branch=svn-trunk) | [![gitlab-ci](https://gitlab.com/geos/libgeos/badges/svn-trunk/build.svg)](https://gitlab.com/geos/libgeos/commits/svn-trunk) | [![appveyor](https://ci.appveyor.com/api/projects/status/ao909hwpsb1yu062/branch/svn-trunk?svg=true)](https://ci.appveyor.com/project/OSGeo/geos/branch/svn-trunk) |
| svn-3.6 | [![debbie](https://debbie.postgis.net/buildStatus/icon?job=GEOS_Branch_3.6)](https://debbie.postgis.net/view/GEOS/job/GEOS_Branch_3.6/) | [![winnie](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_branch_3.6/badge/icon)](https://debbie.postgis.net:444/view/GEOS/job/GEOS_matrix_branch_3.6/) | [![dronie](https://dronie.osgeo.org/api/badges/geos/geos/status.svg?branch=svn-3.6)](https://dronie.osgeo.org/geos/geos?branch=svn-3.6) | [![travis](https://travis-ci.org/OSGeo/geos.svg?branch=svn-3.6)](https://travis-ci.org/OSGeo/geos?branch=svn-3.6) | [![gitlab-ci](https://gitlab.com/geos/libgeos/badges/svn-3.6/build.svg)](https://gitlab.com/geos/libgeos/commits/svn-3.6) | [![appveyor](https://ci.appveyor.com/api/projects/status/ao909hwpsb1yu062/branch/svn-3.6?svg=true)](https://ci.appveyor.com/project/OSGeo/geos/branch/svn-3.6) |
More on: https://trac.osgeo.org/geos#BuildandInstall
......
......@@ -6,7 +6,7 @@
#
# 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.
# by the Free Software Foundation.
# See the COPYING file for more information.
#
#################################################################################
......@@ -21,9 +21,9 @@ set(geos_c_SOURCES
file(GLOB geos_capi_HEADERS ${CMAKE_BINARY_DIR}/capi/*.h) # fix source_group issue
if(NOT GEOS_ENABLE_MACOSX_FRAMEWORK)
# if building OS X framework, CAPI built into C++ library
add_library(geos_c SHARED ${geos_c_SOURCES})
if(NOT GEOS_ENABLE_MACOSX_FRAMEWORK AND GEOS_BUILD_SHARED)
# if building OS X framework or only building static libs, CAPI built into C++ library)
add_library(geos_c SHARED ${geos_c_SOURCES})
target_link_libraries(geos_c geos)
......@@ -55,7 +55,7 @@ else()
DESTINATION include)
endif()
if(NOT GEOS_ENABLE_MACOSX_FRAMEWORK)
if(NOT GEOS_ENABLE_MACOSX_FRAMEWORK)
install(TARGETS geos_c
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
......
......@@ -8,7 +8,7 @@
*
* 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.
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
......@@ -38,14 +38,14 @@ namespace geomgraph { // geos.geomgraph
/** \brief
* A TopologyLocation is the labelling of a
* GraphComponent's topological relationship to a single Geometry.
*
*
* If the parent component is an area edge, each side and the edge itself
* have a topological location. These locations are named
*
*
* - ON: on the edge
* - LEFT: left-hand side of the edge
* - RIGHT: right-hand side
*
*
* If the parent component is a line edge or node, there is a single
* topological relationship attribute, ON.
*
......@@ -65,15 +65,13 @@ public:
~TopologyLocation();
TopologyLocation(const std::vector<int> &newLocation);
/** \brief
* Constructs a TopologyLocation specifying how points on, to the
* left of, and to the right of some GraphComponent relate to some
* Geometry.
*
* Possible values for the
* parameters are Location::UNDEF, Location::EXTERIOR, Location::BOUNDARY,
* parameters are Location::UNDEF, Location::EXTERIOR, Location::BOUNDARY,
* and Location::INTERIOR.
*
* @see Location
......@@ -115,7 +113,7 @@ public:
void setLocation(int locValue);
/// Warning: returns reference to owned memory
const std::vector<int> &getLocations() const;
const int* getLocations() const;
void setLocations(int on, int left, int right);
......@@ -131,7 +129,8 @@ public:
private:
std::vector<int> location;
int location[3];
std::size_t locationSize;
};
std::ostream& operator<< (std::ostream&, const TopologyLocation&);
......
......@@ -6,7 +6,7 @@
#
# 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.
# by the Free Software Foundation.
# See the COPYING file for more information.
#
#################################################################################
......@@ -14,25 +14,26 @@
file(GLOB_RECURSE geos_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file(GLOB_RECURSE geos_ALL_HEADERS ${CMAKE_SOURCE_DIR}/include/*.h) # fix source_group issue
# Include CAPI in OS X framework binary and in static libs
set(geos_c_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/../capi/geos_c.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../capi/geos_ts_c.cpp)
if(GEOS_ENABLE_MACOSX_FRAMEWORK)
# OS X frameworks don't have static libs
# also 1 binary, so include CAPI here
# and, make name all caps
set(geos_c_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/../capi/geos_c.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../capi/geos_ts_c.cpp)
add_library(GEOS SHARED ${geos_SOURCES} ${geos_c_SOURCES})
math(EXPR CVERSION "${VERSION_MAJOR} + 1")
# VERSION = current version, SOVERSION = compatibility version
math(EXPR CVERSION "${VERSION_MAJOR} + 1")
# VERSION = current version, SOVERSION = compatibility version
set_target_properties(GEOS
PROPERTIES
CLEAN_DIRECT_OUTPUT 1
FRAMEWORK 1
VERSION "${CVERSION}.${VERSION_MINOR}.${VERSION_PATCH}"
SOVERSION ${CVERSION}
VERSION "${CVERSION}.${VERSION_MINOR}.${VERSION_PATCH}"
SOVERSION ${CVERSION}
FRAMEWORK_VERSION ${VERSION_MAJOR}
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}"
......@@ -77,7 +78,8 @@ else()
endif()
if(GEOS_BUILD_STATIC)
add_library(geos-static STATIC ${geos_SOURCES} ${geos_ALL_HEADERS})
file(GLOB geos_capi_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../capi/*.h) # fix source_group issue
add_library(geos-static STATIC ${geos_SOURCES} ${geos_c_SOURCES} ${geos_ALL_HEADERS} ${geos_capi_HEADERS})
set_target_properties(geos-static
PROPERTIES
......
......@@ -140,10 +140,10 @@ Envelope::Envelope(const string &str)
vector<string> values = split(coordString, ":,");
// create a new envelopet
init(::atof(values[0].c_str()),
::atof(values[1].c_str()),
::atof(values[2].c_str()),
::atof(values[3].c_str()));
init(strtod(values[0].c_str(), NULL),
strtod(values[1].c_str(), NULL),
strtod(values[2].c_str(), NULL),
strtod(values[3].c_str(), NULL));
}
/*public*/
......
......@@ -8,7 +8,7 @@
*
* 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.
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
......@@ -26,17 +26,11 @@
#include <iostream>
#include <cassert>
using namespace std;
using namespace geos::geom;
namespace geos {
namespace geomgraph { // geos.geomgraph
/*public*/
TopologyLocation::TopologyLocation(const vector<int> &newLocation):
location(newLocation.size(), Location::UNDEF)
{
}
/*public*/
TopologyLocation::TopologyLocation()
......@@ -50,7 +44,7 @@ TopologyLocation::~TopologyLocation()
/*public*/
TopologyLocation::TopologyLocation(int on, int left, int right):
location(3)
locationSize(3)
{
location[Position::ON]=on;
location[Position::LEFT]=left;
......@@ -59,23 +53,28 @@ TopologyLocation::TopologyLocation(int on, int left, int right):
/*public*/
TopologyLocation::TopologyLocation(int on):
location(1, on)
locationSize(1)
{
//(*location)[Position::ON]=on;
location[Position::ON] = on;
}
/*public*/
TopologyLocation::TopologyLocation(const TopologyLocation &gl)
:
location(gl.location)
TopologyLocation::TopologyLocation(const TopologyLocation &gl):
locationSize(gl.locationSize)
{
for (size_t i=0; i<locationSize; ++i) {
location[i] = gl.location[i];
}
}
/*public*/
TopologyLocation&
TopologyLocation::operator= (const TopologyLocation &gl)
{
location = gl.location;
locationSize = gl.locationSize;
for (size_t i=0; i<locationSize; ++i) {
location[i] = gl.location[i];
}
return *this;
}
......@@ -84,7 +83,7 @@ int
TopologyLocation::get(size_t posIndex) const
{
// should be an assert() instead ?
if (posIndex<location.size()) return location[posIndex];
if (posIndex<locationSize) return location[posIndex];
return Location::UNDEF;
}
......@@ -92,7 +91,7 @@ TopologyLocation::get(size_t posIndex) const
bool
TopologyLocation::isNull() const
{
for (size_t i=0, sz=location.size(); i<sz; ++i) {
for (size_t i=0; i<locationSize; ++i) {
if (location[i]!=Location::UNDEF) return false;
}
return true;
......@@ -102,7 +101,7 @@ TopologyLocation::isNull() const
bool
TopologyLocation::isAnyNull() const
{
for (size_t i=0, sz=location.size(); i<sz; ++i) {
for (size_t i=0; i<locationSize; ++i) {
if (location[i]==Location::UNDEF) return true;
}
return false;
......@@ -119,21 +118,21 @@ TopologyLocation::isEqualOnSide(const TopologyLocation &le, int locIndex) const
bool
TopologyLocation::isArea() const
{
return location.size()>1;
return locationSize>1;
}
/*public*/
bool
TopologyLocation::isLine() const
{
return location.size()==1;
return locationSize==1;
}
/*public*/
void
TopologyLocation::flip()
{
if (location.size()<=1) return;
if (locationSize<=1) return;
int temp=location[Position::LEFT];
location[Position::LEFT]=location[Position::RIGHT];
location[Position::RIGHT] = temp;
......@@ -143,7 +142,7 @@ TopologyLocation::flip()
void
TopologyLocation::setAllLocations(int locValue)
{
for (size_t i=0, sz=location.size(); i<sz; ++i) {
for (size_t i=0; i<locationSize; ++i) {
location[i]=locValue;
}
}
......@@ -152,7 +151,7 @@ TopologyLocation::setAllLocations(int locValue)
void
TopologyLocation::setAllLocationsIfNull(int locValue)
{
for (size_t i=0, sz=location.size(); i<sz; ++i) {
for (size_t i=0; i<locationSize; ++i) {
if (location[i]==Location::UNDEF) location[i]=locValue;
}
}
......@@ -172,7 +171,7 @@ TopologyLocation::setLocation(int locValue)
}
/*public*/
const vector<int> &
const int*
TopologyLocation::getLocations() const
{
return location;
......@@ -182,7 +181,7 @@ TopologyLocation::getLocations() const
void
TopologyLocation::setLocations(int on, int left, int right)
{
assert(location.size() >= 3);
assert(locationSize >= 3);
location[Position::ON]=on;
location[Position::LEFT]=left;
location[Position::RIGHT]=right;
......@@ -192,7 +191,7 @@ TopologyLocation::setLocations(int on, int left, int right)
bool
TopologyLocation::allPositionsEqual(int loc) const
{
for (size_t i=0, sz=location.size(); i<sz; ++i) {
for (size_t i=0; i<locationSize; ++i) {
if (location[i]!=loc) return false;
}
return true;
......@@ -203,32 +202,32 @@ void
TopologyLocation::merge(const TopologyLocation &gl)
{
// if the src is an Area label & and the dest is not, increase the dest to be an Area
size_t sz=location.size();
size_t glsz=gl.location.size();
size_t sz=locationSize;
size_t glsz=gl.locationSize;
if (glsz>sz) {
location.resize(3);
locationSize = 3;
location[Position::LEFT]=Location::UNDEF;
location[Position::RIGHT]=Location::UNDEF;
}
for (size_t i=0; i<sz; ++i) {
for (size_t i=0; i<locationSize; ++i) {
if (location[i]==Location::UNDEF && i<glsz)
location[i]=gl.location[i];
}
}
string
std::string
TopologyLocation::toString() const
{
stringstream ss;
std::stringstream ss;
ss << *this;
return ss.str();
}
std::ostream& operator<< (std::ostream& os, const TopologyLocation& tl)
{
if (tl.location.size()>1) os << Location::toLocationSymbol(tl.location[Position::LEFT]);
if (tl.locationSize>1) os << Location::toLocationSymbol(tl.location[Position::LEFT]);
os << Location::toLocationSymbol(tl.location[Position::ON]);
if (tl.location.size()>1) os << Location::toLocationSymbol(tl.location[Position::RIGHT]);
if (tl.locationSize>1) os << Location::toLocationSymbol(tl.location[Position::RIGHT]);
return os;
}
......
......@@ -125,7 +125,10 @@ AbstractSTRtree::query(const void* searchBounds, vector<void*>& matches)
{
if (!built) build();
if (itemBoundables->empty()) assert(root->getBounds()==NULL);
if (itemBoundables->empty()) {
assert(root->getBounds()==NULL);
return;
}
if (getIntersectsOp()->intersects(root->getBounds(), searchBounds))
{
......@@ -139,8 +142,11 @@ AbstractSTRtree::query(const void* searchBounds, ItemVisitor& visitor)
{
if (!built) build();
if (itemBoundables->empty()) assert(root->getBounds()==NULL);
if (itemBoundables->empty()) {
assert(root->getBounds()==NULL);
return;
}
if (getIntersectsOp()->intersects(root->getBounds(),searchBounds))
{
query(searchBounds, *root, visitor);
......
......@@ -7,12 +7,12 @@
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Licence as published
* by the Free Software Foundation.
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
*
* Last port: noding/SingleInteriorIntersectionFinder.java rev. ??? (JTS-1.8)
* Last port: noding/SingleInteriorIntersectionFinder.java rev. 2019-01-28
*
**********************************************************************/
......@@ -23,6 +23,38 @@
using namespace geos::geom;
namespace { // anonymous
/* private in JTS */
bool isEndInteriorIntersection(
const Coordinate& p0, bool isEnd0,
const Coordinate& p1, bool isEnd1)
{
if (isEnd0 && isEnd1) return false;
if (p0.equals2D(p1)) {
return true;
}
return false;
}
/* public in JTS */
bool isEndInteriorIntersection(
const Coordinate& p00, const Coordinate& p01,
const Coordinate& p10, const Coordinate& p11,
bool isEnd00, bool isEnd01,
bool isEnd10, bool isEnd11)
{
if (isEndInteriorIntersection(p00, isEnd00, p10, isEnd10)) return true;
if (isEndInteriorIntersection(p00, isEnd00, p11, isEnd11)) return true;
if (isEndInteriorIntersection(p01, isEnd01, p10, isEnd10)) return true;
if (isEndInteriorIntersection(p01, isEnd01, p11, isEnd11)) return true;
return false;
}
} // anonymous namespace
namespace geos {
namespace noding { // geos.noding
......@@ -37,7 +69,7 @@ SingleInteriorIntersectionFinder::processIntersections(
// short-circuit if intersection already found
if (hasIntersection())
return;
// don't bother intersecting a segment with itself
if (e0 == e1 && segIndex0 == segIndex1) return;
......@@ -45,23 +77,29 @@ SingleInteriorIntersectionFinder::processIntersections(
const Coordinate& p01 = e0->getCoordinate(segIndex0 + 1);
const Coordinate& p10 = e1->getCoordinate(segIndex1);
const Coordinate& p11 = e1->getCoordinate(segIndex1 + 1);
bool isEnd00 = segIndex0 == 0;
bool isEnd01 = segIndex0 + 2 == static_cast<int>(e0->size());
bool isEnd10 = segIndex1 == 0;
bool isEnd11 = segIndex1 + 2 == static_cast<int>(e1->size());
li.computeIntersection(p00, p01, p10, p11);
//if (li.hasIntersection() && li.isProper()) Debug.println(li);
bool isProperInteriorInt = li.hasIntersection() &&
li.isInteriorIntersection();
bool isEndInteriorInt = (e0 != e1) && isEndInteriorIntersection(
p00, p01, p10, p11, isEnd00, isEnd01, isEnd10, isEnd11);
if (li.hasIntersection())
{
if (li.isInteriorIntersection())
{
intSegments.resize(4);
intSegments[0] = p00;
intSegments[1] = p01;
intSegments[2] = p10;
intSegments[3] = p11;
interiorIntersection = li.getIntersection(0);
}
if (isProperInteriorInt || isEndInteriorInt) {
// found an intersection!
intSegments.resize(4);
intSegments[0] = p00;
intSegments[1] = p01;
intSegments[2] = p10;
intSegments[3] = p11;
interiorIntersection = li.getIntersection(0);
}
}
......
......@@ -8,7 +8,7 @@
*
* 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.
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
......@@ -21,6 +21,7 @@
#include <geos/operation/overlay/OverlayOp.h>
#include <geos/operation/overlay/MaximalEdgeRing.h>
#include <geos/operation/overlay/MinimalEdgeRing.h>
#include <geos/operation/polygonize/EdgeRing.h>
#include <geos/geomgraph/Node.h>
#include <geos/geomgraph/NodeMap.h>
#include <geos/geomgraph/DirectedEdgeStar.h>
......@@ -44,7 +45,6 @@ using namespace geos::geomgraph;
using namespace geos::algorithm;
using namespace geos::geom;
namespace geos {
namespace operation { // geos.operation
namespace overlay { // geos.operation.overlay
......@@ -74,7 +74,7 @@ PolygonBuilder::add(PlanarGraph *graph)
size_t eeSize=ee.size();
#if GEOS_DEBUG
#if GEOS_DEBUG
cerr << __FUNCTION__ << ": PlanarGraph has " << eeSize << " EdgeEnds" << endl;
#endif
......@@ -146,9 +146,9 @@ PolygonBuilder::buildMaximalEdgeRings(const vector<DirectedEdge*> *dirEdges,
DirectedEdge *de=(*dirEdges)[i];
#if GEOS_DEBUG
cerr << " dirEdge " << i << endl
<< de->printEdge() << endl
<< " inResult:" << de->isInResult() << endl
<< " isArea:" << de->getLabel().isArea() << endl;
<< de->printEdge() << endl
<< " inResult:" << de->isInResult() << endl
<< " isArea:" << de->getLabel().isArea() << endl;
#endif
if (de->isInResult() && de->getLabel().isArea())
{
......@@ -305,14 +305,14 @@ PolygonBuilder::placeFreeHoles(std::vector<EdgeRing*>& newShellList,
{
geom = (*rIt)->toPolygon(geometryFactory);
std::cerr << "INSERT INTO shells VALUES ('"
<< *geom
<< "');" << std::endl;
<< *geom
<< "');" << std::endl;
delete geom;
}
geom = hole->toPolygon(geometryFactory);
std::cerr << "INSERT INTO hole VALUES ('"
<< *geom
<< "');" << std::endl;
<< *geom
<< "');" << std::endl;
delete geom;
#endif
//assert(shell!=NULL); // unable to assign hole to a shell
......@@ -329,32 +329,35 @@ EdgeRing*
PolygonBuilder::findEdgeRingContaining(EdgeRing *testEr,
vector<EdgeRing*>& newShellList)
{
LinearRing *testRing=testEr->getLinearRing();
const Envelope *testEnv=testRing->getEnvelopeInternal();
const Coordinate& testPt=testRing->getCoordinateN(0);
EdgeRing *minShell=NULL;
const Envelope *minEnv=NULL;
for(size_t i=0, n=newShellList.size(); i<n; i++)
{
LinearRing *lr=NULL;
EdgeRing *tryShell=newShellList[i];
LinearRing *tryRing=tryShell->getLinearRing();
const Envelope *tryEnv=tryRing->getEnvelopeInternal();
if (minShell!=NULL) {
lr=minShell->getLinearRing();
minEnv=lr->getEnvelopeInternal();
}
bool isContained=false;
const CoordinateSequence *rcl = tryRing->getCoordinatesRO();
if (tryEnv->contains(testEnv)
&& CGAlgorithms::isPointInRing(testPt,rcl))
isContained=true;
LinearRing *testRing = testEr->getLinearRing();
const Envelope *testEnv = testRing->getEnvelopeInternal();
EdgeRing *minShell = NULL;
const Envelope *minShellEnv = NULL;
for(size_t i = 0, n = newShellList.size(); i<n; i++) {
EdgeRing *tryShell = newShellList[i];
LinearRing *tryShellRing = tryShell->getLinearRing();
const Envelope *tryShellEnv = tryShellRing->getEnvelopeInternal();
// hole must be contained in shell
// the hole envelope cannot equal the shell envelope
// (also guards against testing rings against themselves)
if (tryShellEnv->equals(testEnv)) continue;
// hole must be contained in shell
if (!tryShellEnv->contains(testEnv)) continue;
const CoordinateSequence *tsrcs = tryShellRing->getCoordinatesRO();
Coordinate testPt = geos::operation::polygonize::EdgeRing::ptNotInList(testRing->getCoordinatesRO(), tsrcs);
bool isContained = false;
if (CGAlgorithms::locatePointInRing(testPt, *tsrcs) != Location::EXTERIOR)
isContained = true;
// check if this new containing ring is smaller than
// the current minimum ring
if (isContained) {
if (minShell==NULL
|| minEnv->contains(tryEnv)) {
minShell=tryShell;
if (minShell==NULL ||
minShellEnv->contains(tryShellEnv)) {
minShell = tryShell;
minShellEnv = minShell->getLinearRing()->getEnvelopeInternal();
}
}
}
......
......@@ -60,6 +60,7 @@ if(GEOS_ENABLE_TESTS)
${XMLTESTS_DIR}/ticket/bug188.xml
${XMLTESTS_DIR}/ticket/bug244.xml
${XMLTESTS_DIR}/ticket/bug275.xml
${XMLTESTS_DIR}/ticket/bug838.xml
${XMLTESTS_DIR}/general/TestBoundary.xml
${XMLTESTS_DIR}/general/TestBuffer.xml
${XMLTESTS_DIR}/general/TestBufferMitredJoin.xml
......
......@@ -44,6 +44,7 @@ SAFE_XMLTESTS=$(srcdir)/tests/testLeaksBig.xml \
$(srcdir)/tests/ticket/bug615.xml \
$(srcdir)/tests/ticket/bug716.xml \
$(srcdir)/tests/ticket/bug837.xml \
$(srcdir)/tests/ticket/bug838.xml \
$(srcdir)/tests/general/TestBoundary.xml \
$(srcdir)/tests/general/TestBuffer.xml \
$(srcdir)/tests/general/TestBufferMitredJoin.xml \
......
<run>
<precisionModel type="FLOATING" />