1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
/**********************************************************************
* $Id: SweeplineNestedRingTester.cpp 1820 2006-09-06 16:54:23Z mloskot $
*
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
* Copyright (C) 2005-2006 Refractions Research Inc.
* Copyright (C) 2001-2002 Vivid Solutions Inc.
*
* 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.
*
**********************************************************************/
#include <geos/operation/valid/SweeplineNestedRingTester.h>
#include <geos/operation/valid/IsValidOp.h>
#include <geos/index/sweepline/SweepLineInterval.h>
#include <geos/index/sweepline/SweepLineIndex.h>
#include <geos/algorithm/CGAlgorithms.h>
#include <geos/geom/LinearRing.h>
#include <cassert>
using namespace geos::algorithm;
using namespace geos::index::sweepline;
using namespace geos::geom;
namespace geos {
namespace operation { // geos.operation
namespace valid { // geos.operation.valid
SweeplineNestedRingTester::OverlapAction::OverlapAction(SweeplineNestedRingTester *p)
{
isNonNested=true;
parent=p;
}
void
SweeplineNestedRingTester::OverlapAction::overlap(SweepLineInterval *s0, SweepLineInterval *s1)
{
LinearRing *innerRing=(LinearRing*) s0->getItem();
LinearRing *searchRing=(LinearRing*) s1->getItem();
if (innerRing==searchRing) return;
if (parent->isInside(innerRing, searchRing))
isNonNested=false;
}
bool
SweeplineNestedRingTester::isNonNested()
{
buildIndex();
OverlapAction *action=new OverlapAction(this);
sweepLine->computeOverlaps(action);
return action->isNonNested;
}
void
SweeplineNestedRingTester::buildIndex()
{
sweepLine=new SweepLineIndex();
for(size_t i=0, n=rings.size(); i<n; i++) {
LinearRing *ring=rings[i];
const Envelope *env=ring->getEnvelopeInternal();
SweepLineInterval *sweepInt=new SweepLineInterval(env->getMinX(),env->getMaxX(),ring);
sweepLine->add(sweepInt);
}
}
bool
SweeplineNestedRingTester::isInside(LinearRing *innerRing,LinearRing *searchRing)
{
CoordinateSequence *innerRingPts=innerRing->getCoordinates();
CoordinateSequence *searchRingPts=searchRing->getCoordinates();
if (!innerRing->getEnvelopeInternal()->intersects(searchRing->getEnvelopeInternal()))
return false;
const Coordinate *innerRingPt=IsValidOp::findPtNotNode(innerRingPts, searchRing, graph);
// Unable to find a ring point not a node of the search ring
assert(innerRingPt!=NULL);
bool isInside=CGAlgorithms::isPointInRing(*innerRingPt,searchRingPts);
if (isInside) {
/*
* innerRingPt is const just because the input
* CoordinateSequence is const. If the input
* Polygon survives lifetime of this object
* we are safe.
*/
nestedPt=const_cast<Coordinate *>(innerRingPt);
return true;
}
return false;
}
} // namespace geos.operation.valid
} // namespace geos.operation
} // namespace geos
/**********************************************************************
* $Log$
* Revision 1.18 2006/06/12 11:29:24 strk
* unsigned int => size_t
*
* Revision 1.17 2006/04/09 04:09:43 mloskot
* Removed redundant semicolon reported by g++ -pedantic.
*
* Revision 1.16 2006/03/21 10:01:30 strk
* indexSweepline.h header split
*
**********************************************************************/
|