Пример #1
0
/*private*/
void
ConvexHull::cleanRing(const Coordinate::ConstVect &original,
		Coordinate::ConstVect &cleaned)
{
	size_t npts=original.size();

	const Coordinate *last = original[npts-1];

	//util::Assert::equals(*(original[0]), *last);
	assert(last);
	assert(original[0]->equals2D(*last));

	const Coordinate *prev = NULL;
	for (size_t i=0; i<npts-1; ++i)
	{
		const Coordinate *curr = original[i];
		const Coordinate *next = original[i+1];

		// skip consecutive equal coordinates
		if (curr->equals2D(*next)) continue;

		if ( prev != NULL &&  isBetween(*prev, *curr, *next) )
		{
			continue;
		}

		cleaned.push_back(curr);
		prev=curr;
	}

	cleaned.push_back(last);

}
Пример #2
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);
}
Пример #3
0
/* private */
Geometry*
ConvexHull::lineOrPolygon(const Coordinate::ConstVect &input)
{
	Coordinate::ConstVect cleaned;

	cleanRing(input, cleaned);

	if (cleaned.size()==3) { // shouldn't this be 2 ??
		cleaned.resize(2);
		CoordinateSequence *cl1=toCoordinateSequence(cleaned);
		LineString *ret = geomFactory->createLineString(cl1);
		return ret;
	}
	CoordinateSequence *cl2=toCoordinateSequence(cleaned);
	LinearRing *linearRing=geomFactory->createLinearRing(cl2);
	return geomFactory->createPolygon(linearRing,NULL);
}
Пример #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;
}
Пример #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]));
}
Пример #6
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;
}
Пример #7
0
/* private */
void
ConvexHull::computeOctPts(const Coordinate::ConstVect &inputPts,
		Coordinate::ConstVect &pts)
{
	// Initialize all slots with first input coordinate
	pts = Coordinate::ConstVect(8, inputPts[0]);

	for (size_t i=1, n=inputPts.size(); i<n; ++i)
	{
		if (inputPts[i]->x < pts[0]->x) {
			pts[0] = inputPts[i];
		}
		if (inputPts[i]->x - inputPts[i]->y < pts[1]->x - pts[1]->y) {
			pts[1] = inputPts[i];
		}
		if (inputPts[i]->y > pts[2]->y) {
			pts[2] = inputPts[i];
		}
		if (inputPts[i]->x + inputPts[i]->y > pts[3]->x + pts[3]->y) {
			pts[3] = inputPts[i];
		}
		if (inputPts[i]->x > pts[4]->x) {
			pts[4] = inputPts[i];
		}
		if (inputPts[i]->x - inputPts[i]->y > pts[5]->x - pts[5]->y) {
			pts[5] = inputPts[i];
		}
		if (inputPts[i]->y < pts[6]->y) {
			pts[6] = inputPts[i];
		}
		if (inputPts[i]->x + inputPts[i]->y < pts[7]->x + pts[7]->y) {
			pts[7] = inputPts[i];
		}
	}

}
Пример #8
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;
}
    void object::test<1>()
    {
		using geos::geom::Coordinate;
		
		// Create geometry from WKT
		const Coordinate::ConstVect::size_type size5 = 5;
		const std::string wkt("MULTIPOINT(10 10, 20 20, 30 30, 20 20, 10 10)");
		GeometryPtr geo(reader_.read(wkt));
		
		ensure_equals( geo->getGeometryTypeId(), geos::geom::GEOS_MULTIPOINT );
		std::auto_ptr<geos::geom::CoordinateSequence> cs;
		cs.reset(geo->getCoordinates());
		ensure_equals(cs->getSize(), size5 );
		
		// Create collection buffer for filtered coordinates
		const Coordinate::ConstVect::size_type size0 = 0;
		Coordinate::ConstVect coords;
		
		// Create filtering object		
		geos::util::UniqueCoordinateArrayFilter filter(coords);		
		
		ensure_equals( coords.size(), size0 );
		
		// Apply filter
		const Coordinate::ConstVect::size_type size3 = 3;
		geo->apply_ro(&filter);
		
		cs.reset(geo->getCoordinates());
		ensure_equals( cs->getSize(), size5 );
		ensure_equals( coords.size(), size3 );
		ensure_equals( coords.at(0)->x, 10 );
		ensure_equals( coords.at(0)->y, 10 );
		ensure_equals( coords.at(1)->x, 20 );
		ensure_equals( coords.at(1)->y, 20 );
		ensure_equals( coords.at(2)->x, 30 );
		ensure_equals( coords.at(2)->y, 30 );
    }	
Пример #10
0
/*private*/
void
ConvexHull::grahamScan(const Coordinate::ConstVect &c, 
		Coordinate::ConstVect &ps)
{
	ps.push_back(c[0]);
	ps.push_back(c[1]);
	ps.push_back(c[2]);

	for(size_t i=3, n=c.size(); i<n; ++i)
	{
		const Coordinate *p = ps.back(); ps.pop_back();
		while (!ps.empty() && 
			CGAlgorithms::computeOrientation(
		    *(ps.back()), *p, *(c[i])) > 0)
		{
			p = ps.back(); ps.pop_back();
		}
		ps.push_back(p);
		ps.push_back(c[i]);
	}
	ps.push_back(c[0]);
}