EVOLUTION-MANAGER
Edit File: NodingIntersectionFinder.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/NodingIntersectionFinder.java rev. ??? (JTS-1.8) * **********************************************************************/ #include <geos/noding/NodingIntersectionFinder.h> #include <geos/noding/SegmentString.h> #include <geos/algorithm/LineIntersector.h> #include <geos/geom/Coordinate.h> #include <cstdlib> using namespace geos::geom; namespace geos { namespace noding { // geos.noding /* private */ bool NodingIntersectionFinder::isEndSegment(const SegmentString* segStr, size_t index) { if(index == 0) { return true; } if(index >= segStr->size() - 2) { return true; } return false; } /* private */ bool NodingIntersectionFinder::isInteriorVertexIntersection( const Coordinate& p0, const Coordinate& p1, bool isEnd0, bool isEnd1) { // Intersections between endpoints are valid nodes, so not reported if(isEnd0 && isEnd1) { return false; } if(p0.equals2D(p1)) { return true; } return false; } /* private */ bool NodingIntersectionFinder::isInteriorVertexIntersection( const Coordinate& p00, const Coordinate& p01, const Coordinate& p10, const Coordinate& p11, bool isEnd00, bool isEnd01, bool isEnd10, bool isEnd11) { if(isInteriorVertexIntersection(p00, p10, isEnd00, isEnd10)) { return true; } if(isInteriorVertexIntersection(p00, p11, isEnd00, isEnd11)) { return true; } if(isInteriorVertexIntersection(p01, p10, isEnd01, isEnd10)) { return true; } if(isInteriorVertexIntersection(p01, p11, isEnd01, isEnd11)) { return true; } return false; } /* public (override) */ void NodingIntersectionFinder::processIntersections( SegmentString* e0, size_t segIndex0, SegmentString* e1, size_t segIndex1) { using geos::geom::Coordinate; // short-circuit if intersection already found if(!findAllIntersections && hasIntersection()) { return; } // don't bother intersecting a segment with itself bool isSameSegString = e0 == e1; bool isSameSegment = isSameSegString && segIndex0 == segIndex1; if(isSameSegment) { return; } /** * If enabled, only test end segments (on either segString). */ if(isCheckEndSegmentsOnly) { bool isEndSegPresent = isEndSegment(e0, segIndex0) || isEndSegment(e1, segIndex1); if(! isEndSegPresent) { return; } } const Coordinate& p00 = e0->getCoordinate(segIndex0); 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 == e0->size(); bool isEnd10 = segIndex1 == 0; bool isEnd11 = segIndex1 + 2 == e1->size(); li.computeIntersection(p00, p01, p10, p11); /** * Check for an intersection in the interior of a segment */ bool isInteriorInt = li.hasIntersection() && li.isInteriorIntersection(); /** * Check for an intersection between two vertices which are not both endpoints. */ long long segDiff = segIndex1 - segIndex0; bool isAdjacentSegment = isSameSegString && std::abs(segDiff) <= 1; bool isInteriorVertexInt = (!isAdjacentSegment) && isInteriorVertexIntersection(p00, p01, p10, p11, isEnd00, isEnd01, isEnd10, isEnd11); if(isInteriorInt || isInteriorVertexInt) { // found an intersection! intSegments.push_back(p00); intSegments.push_back(p01); intSegments.push_back(p10); intSegments.push_back(p11); interiorIntersection = li.getIntersection(0); // TODO: record endpoint intersection(s) // if (keepIntersections) intersections.add(interiorIntersection); intersectionCount++; } } } // namespace geos.noding } // namespace geos