/* private */ void ConvexHull::reduce(Coordinate::ConstVect &pts) { Coordinate::ConstVect polyPts; if ( ! computeOctRing(pts, polyPts) ) { // unable to compute interior polygon for some reason return; } // add points defining polygon Coordinate::ConstSet reducedSet; reducedSet.insert(polyPts.begin(), polyPts.end()); /** * Add all unique points not in the interior poly. * CGAlgorithms.isPointInRing is not defined for points * actually on the ring, but this doesn't matter since * the points of the interior polygon are forced to be * in the reduced set. * * @@TIP: there should be a std::algo for this */ for (size_t i=0, n=pts.size(); i<n; ++i) { if ( !CGAlgorithms::isPointInRing(*(pts[i]), polyPts) ) { reducedSet.insert(pts[i]); } } inputPts.assign(reducedSet.begin(), reducedSet.end()); if ( inputPts.size() < 3 ) padArray3(inputPts); }
/* static */ bool LineSequencer::isSequenced(const Geometry* geom) { const MultiLineString *mls; if ( nullptr == (mls=dynamic_cast<const MultiLineString *>(geom)) ) { return true; } // the nodes in all subgraphs which have been completely scanned Coordinate::ConstSet prevSubgraphNodes; Coordinate::ConstVect currNodes; const Coordinate* lastNode = nullptr; for (std::size_t i=0, n=mls->getNumGeometries(); i<n; ++i) { const LineString* lineptr = \ dynamic_cast<const LineString*>(mls->getGeometryN(i)); assert(lineptr); const LineString& line = *lineptr; const Coordinate* startNode = &(line.getCoordinateN(0)); const Coordinate* endNode = &(line.getCoordinateN(line.getNumPoints() - 1)); /** * If this linestring is connected to a previous subgraph, * geom is not sequenced */ if (prevSubgraphNodes.find(startNode) != prevSubgraphNodes.end()) { return false; } if (prevSubgraphNodes.find(endNode) != prevSubgraphNodes.end()) { return false; } if (lastNode != nullptr) { if (! startNode->equals2D(*lastNode)) { // start new connected sequence prevSubgraphNodes.insert(currNodes.begin(), currNodes.end()); currNodes.clear(); } } currNodes.push_back(startNode); currNodes.push_back(endNode); lastNode = endNode; } return true; }
/*private*/ Coordinate::ConstVect::const_iterator LineStringSnapper::findSnapForVertex(const Coordinate& pt, const Coordinate::ConstVect& snapPts) { Coordinate::ConstVect::const_iterator end = snapPts.end(); Coordinate::ConstVect::const_iterator candidate = end; double minDist = snapTolerance; // TODO: use std::find_if for ( Coordinate::ConstVect::const_iterator it=snapPts.begin(); it != end; ++it) { assert(*it); const Coordinate& snapPt = *(*it); if ( snapPt.equals2D(pt) ) { #if GEOS_DEBUG cerr << " points are equal, returning not-found " << endl; #endif return end; } double dist = snapPt.distance(pt); #if GEOS_DEBUG cerr << " distance from snap point " << snapPt << ": " << dist << endl; #endif if ( dist < minDist ) { minDist = dist; candidate = it; } } #if GEOS_DEBUG if ( candidate == end ) { cerr << " no snap point within distance, returning not-found" << endl; } #endif return candidate; }
/* private */ bool ConvexHull::computeOctRing(const Coordinate::ConstVect &inputPts, Coordinate::ConstVect &dest) { computeOctPts(inputPts, dest); // Remove consecutive equal Coordinates // unique() returns an iterator to the end of the resulting // sequence, we erase from there to the end. dest.erase( std::unique(dest.begin(),dest.end()), dest.end() ); // points must all lie in a line if ( dest.size() < 3 ) return false; // close ring dest.push_back(dest[0]); return true; }
/* private */ void ConvexHull::preSort(Coordinate::ConstVect &pts) { // find the lowest point in the set. If two or more points have // the same minimum y coordinate choose the one with the minimum x. // This focal point is put in array location pts[0]. for(size_t i=1, n=pts.size(); i<n; ++i) { const Coordinate *p0=pts[0]; // this will change const Coordinate *pi=pts[i]; if ( (pi->y<p0->y) || ((pi->y==p0->y) && (pi->x<p0->x)) ) { const Coordinate *t=p0; pts[0]=pi; pts[i]=t; } } // sort the points radially around the focal point. std::sort(pts.begin(), pts.end(), RadiallyLessThen(pts[0])); }