예제 #1
0
/*
 PolygonPartition::sweep
 Determines if two polygons are neighbors. The host is assumed to be
 partitioned.
 Uses two criteria to establish neighborhood:
 is_queen == true then: common point, else: common boundary
 */
int PolygonPartition::sweep(PolygonPartition & guest, bool is_queen,
                            double precision_threshold)
{
	int       host, dot, cly, cell;
	double    yStart= GetMinY(), yStop= GetMaxY();
	Shapefile::Point* pt;
	guest.MakeSmallPartition(pX.Cells(), GetMinX(), GetMaxX());
	for (cell= 0; cell < pX.Cells(); ++cell) {
		for (host= pX.first(cell); host != GdaConst::EMPTY; host= pX.tail(host))
            pY.include(host);
		for (dot=guest.pX.first(cell); dot != GdaConst::EMPTY; dot=guest.pX.tail(dot))
        {
			pt= guest.GetPoint(dot);
			cly= pY.inTheRange(pt->y - yStart);
			if (cly != -1) {
				for (host= pY.first(cly); host != GdaConst::EMPTY;
					 host= pY.tail(host))
                {
					if (pt->equals( GetPoint(host), precision_threshold) )
                    {
						if (is_queen || edge(guest, host, dot, precision_threshold)) {
							pY.cleanup(pX, cell);
							return 1;  
						}
					}
				}
			}
		}
		pY.cleanup(pX, cell);
	}
	return 0;
	
}
예제 #2
0
파일: shp2cnt.cpp 프로젝트: jontheepi/geoda
GalElement* MakeContiguity(Shapefile::Main& main, const int crit,
                           double precision_threshold=0.0)
{
	using namespace Shapefile;
	int curr;
	GalElement * gl= new GalElement [ gRecords ];
	
	if (!gl) return NULL;
	GeoDaSet   Neighbors(gRecords), Related(gRecords);
	//  cout << "total steps= " << gMinX.Cells() << endl;
	for (int step= 0; step < gMinX.Cells(); ++step) {
		// include all elements from xmin[step]
		for (curr= gMinX.first(step); curr != GdaConst::EMPTY;
			 curr= gMinX.tail(curr)) gY->include(curr);
		
		// test each element in xmax[step]
		for (curr= gMaxX.first(step); curr != GdaConst::EMPTY;
			 curr= gMaxX.tail(curr))  {
			PolygonContents* ply = dynamic_cast<PolygonContents*> (
												main.records[curr].contents_p);
			PolygonPartition testPoly(ply);
			testPoly.MakePartition();
			
			// form a list of neighbors
			for (int cell=gY->lowest(curr); cell <= gY->upmost(curr); ++cell) {
				int potential = gY->first( cell );
				while (potential != GdaConst::EMPTY) {
					if (potential != curr) Neighbors.Push( potential );
					potential = gY->tail(potential, cell);
				}
			}
			
			// test each potential neighbor
			for (int nbr = Neighbors.Pop(); nbr != GdaConst::EMPTY;
				 nbr = Neighbors.Pop()) {
				PolygonContents* nbr_ply = dynamic_cast<PolygonContents*> (
												main.records[nbr].contents_p);
				if (ply->intersect(nbr_ply)) {
					
					PolygonPartition nbrPoly(nbr_ply);
					//shp.seekg(gOffset[nbr]+12, ios::beg);
					//nbrPoly.ReadShape(shp);
					
					if (curr == 0 && nbr == 0) {
						
					}
					
					// run sweep with testPoly as a host and nbrPoly as a guest
					int related = testPoly.sweep(nbrPoly, crit,
                                                 precision_threshold);
					if (related) Related.Push(nbr);
				}
			}
			
			if (Related.Size() && gl[curr].alloc(Related.Size())) {
				while (Related.Size()) gl[curr].Push(Related.Pop());
			}
			
			gY->remove(curr);       // remove from the partition
		}
	}
	
	return gl;
}
예제 #3
0
	void cleanup(const BasePartition &p, const int cl)  {
		for (int cnt= p.first(cl); cnt != GdaConst::EMPTY; cnt= p.tail(cnt))
			remove(cnt);
	}