Example #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);

}
Example #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);
}
    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 );
    }	
Example #4
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);
}
Example #5
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;
}
Example #6
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]));
}
Example #7
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]);
}
Example #8
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];
		}
	}

}