/* 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; }
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; }