Esempio n. 1
0
/* 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);
}
Esempio n. 2
0
/* 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;
}
Esempio n. 3
0
/* 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;
}
Esempio n. 4
0
/*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;
}
Esempio n. 5
0
/* 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]));
}