EVOLUTION-MANAGER
Edit File: MCIndexPointSnapper.cpp
/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2006 Refractions Research Inc. * * 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. * See the COPYING file for more information. * ********************************************************************** * * Last port: noding/snapround/MCIndexPointSnapper.java r486 (JTS-1.12+) * **********************************************************************/ #include <geos/noding/snapround/MCIndexPointSnapper.h> #include <geos/noding/snapround/HotPixel.h> #include <geos/noding/snapround/SimpleSnapRounder.h> #include <geos/noding/SegmentString.h> #include <geos/noding/NodedSegmentString.h> #include <geos/spatialIndex.h> #include <geos/geom/Envelope.h> #include <geos/index/chain/MonotoneChainSelectAction.h> #include <geos/index/chain/MonotoneChain.h> #include <geos/util.h> #include <algorithm> using namespace geos::index; using namespace geos::geom; namespace geos { namespace noding { // geos.noding namespace snapround { // geos.noding.snapround class HotPixelSnapAction: public index::chain::MonotoneChainSelectAction { public: HotPixelSnapAction(HotPixel& nHotPixel, SegmentString* nParentEdge, size_t nVertexIndex) : MonotoneChainSelectAction(), hotPixel(nHotPixel), parentEdge(nParentEdge), vertexIndex(nVertexIndex), isNodeAddedVar(false) {} /** * Reports whether the HotPixel caused a node to be added in any target * segmentString (including its own). If so, the HotPixel must be added as a * node as well. * * @return true if a node was added in any target segmentString. */ bool isNodeAdded() const { return isNodeAddedVar; } /** * Check if a segment of the monotone chain intersects * the hot pixel vertex and introduce a snap node if so. * Optimized to avoid noding segments which * contain the vertex (which otherwise * would cause every vertex to be noded). */ void select(chain::MonotoneChain& mc, size_t startIndex) override { // This is casting away 'constness'! NodedSegmentString& ss = *(static_cast<NodedSegmentString*>(mc.getContext())); if (parentEdge == &ss) { // exit if hotpixel is equal to endpoint of target segment if (startIndex == vertexIndex || startIndex + 1 == vertexIndex) return; } // snap and record if a node was created isNodeAddedVar |= hotPixel.addSnappedNode(ss, startIndex); } void select(const LineSegment& ls) override { ::geos::ignore_unused_variable_warning(ls); } private: HotPixel& hotPixel; SegmentString* parentEdge; size_t vertexIndex; bool isNodeAddedVar; // Declare type as noncopyable HotPixelSnapAction(const HotPixelSnapAction& other) = delete; HotPixelSnapAction& operator=(const HotPixelSnapAction& rhs) = delete; }; class MCIndexPointSnapperVisitor: public ItemVisitor { public: MCIndexPointSnapperVisitor(const Envelope& nPixelEnv, HotPixelSnapAction& nAction) : pixelEnv(nPixelEnv), action(nAction) {} ~MCIndexPointSnapperVisitor() override {} void visitItem(void* item) override { chain::MonotoneChain& testChain = *(static_cast<chain::MonotoneChain*>(item)); testChain.select(pixelEnv, action); } private: const Envelope& pixelEnv; chain::MonotoneChainSelectAction& action; // Declare type as noncopyable MCIndexPointSnapperVisitor(const MCIndexPointSnapperVisitor& other); MCIndexPointSnapperVisitor& operator=(const MCIndexPointSnapperVisitor& rhs); }; /* public */ bool MCIndexPointSnapper::snap(HotPixel& hotPixel, SegmentString* parentEdge, size_t vertexIndex) { const Envelope& pixelEnv = hotPixel.getSafeEnvelope(); HotPixelSnapAction hotPixelSnapAction(hotPixel, parentEdge, vertexIndex); MCIndexPointSnapperVisitor visitor(pixelEnv, hotPixelSnapAction); index.query(&pixelEnv, visitor); return hotPixelSnapAction.isNodeAdded(); } } // namespace geos.noding.snapround } // namespace geos.noding } // namespace geos