/* collapse labels; remove nodata regions */ void detectEdgeNodata::relabelNodata() { AMI_err ae; nodataType *pt; /* sort by label */ if (stats) NODATA_DEBUG *stats << "sort nodataStream (by nodata label): "; AMI_STREAM<nodataType> *sortedInStream; sortedInStream = sort(nodataStream, labelCmpNodataType()); delete nodataStream; nodataStream = new AMI_STREAM<nodataType>(); while((ae = sortedInStream->read_item(&pt)) == AMI_ERROR_NO_ERROR) { cclabel_type root = colTree.findNextRoot(pt->label); assert(root <= pt->label); pt->label = root; ae = nodataStream->write_item(*pt); assert(ae == AMI_ERROR_NO_ERROR); } delete sortedInStream; }
void flow_waterWindower::processWindow(dimension_type i, dimension_type j, waterWindowBaseType *a, waterWindowBaseType *b, waterWindowBaseType *c) { elevation_type el1[3], el2[3], el3[3]; toporank_type ac1[3], ac2[3], ac3[3]; if (is_nodata(b[1].el)) { /*sweep_str does not include nodata */ return; } /*#ifdef COMPRESSED_WINDOWS sweepItem win = sweepItem(i, j, a, b, c); #else */ for (int k=0; k<3; k++) { el1[k] = a[k].el; ac1[k] = -a[k].depth; /*WEIRD */ el2[k] = b[k].el; ac2[k] = -b[k].depth; /*WEIRD*/ el3[k] = c[k].el; ac3[k] = -c[k].depth; /*WEIRD*/ } /* genericWindow<elevation_type> e_win(el); genericWindow<toporank_type> a_win(ac); sweepItem win = sweepItem(i, j, b[1].dir, e_win, a_win); */ sweepItem win = sweepItem(i, j, b[1].dir, el1, el2, el3, ac1, ac2, ac3); /* #endif */ AMI_err ae = sweep_str->write_item(win); assert(ae == AMI_ERROR_NO_ERROR); }
void ccforest<T>::findAllRoots(int depth) { if(foundAllRoots) return; foundAllRoots = 1; Rtimer rt; rt_start(rt); if(depth > 5) { cerr << "WARNING: excessive recursion in ccforest (ignored)" << endl; } int explicitRootCount = 0; assert(!superTree); superTree = new ccforest<T>(); if (stats) DEBUG_CCFOREST *stats << "sort edgeStream (by cclabel)): "; keyCmpKeyvalueType<T> fo; sort(&edgeStream, fo); /* XXX -changed this to use a cmp obj */ /* time forward processing */ EMPQueueAdaptive<cckeyvalue,T> *pq = new EMPQueueAdaptive<cckeyvalue,T>(); /* parent queue */ size_t streamLength = edgeStream->stream_len(); T prevSrc = T(-1); T parent = T(-1); ccedge prevEdge; for(unsigned int i=0; i<streamLength; i++) { ccedge *e; AMI_err ae = edgeStream->read_item(&e); assert(ae == AMI_ERROR_NO_ERROR); #if(0) if (stats) { DEBUG_CCFOREST *stats << "------------------------------" << endl; DEBUG_CCFOREST *stats << "processing edge " << *e << endl; } DEBUG_CCFOREST pq->print(); #endif if(*e == prevEdge) { if (stats) DEBUG_CCFOREST *stats << "\tduplicate " << *e << " removed\n"; continue; /* already have this done */ } prevEdge = *e; if (stats) DEBUG_CCFOREST *stats << "processing edge " << *e << endl; /* find root (assign parent) */ if(e->src() != prevSrc) { prevSrc = e->src(); cckeyvalue kv; /* check if we have a key we don't use. */ while(pq->min(kv) && (kv.getPriority() < e->src())) { pq->extract_min(kv); assert(kv.src() >= kv.dst()); removeDuplicates(kv.src(), kv.dst(), *pq); ae = rootStream->write_item(kv); /* save root */ assert(ae == AMI_ERROR_NO_ERROR); } /* try to find our root */ if(pq->min(kv) && ((e->src() == kv.getPriority()))) { pq->extract_min(kv); parent = kv.getValue(); removeDuplicates(e->src(), parent, *pq); } else { parent = e->src(); /* we are root */ explicitRootCount++; /* technically, we could skip this part. the lookup function automatically assumes that values without parents are roots */ } /* save result */ cckeyvalue kroot(e->src(), parent); assert(kroot.src() >= kroot.dst()); ae = rootStream->write_item(kroot); assert(ae == AMI_ERROR_NO_ERROR); } #ifndef NDEBUG cckeyvalue kv2; assert(pq->is_empty() || (pq->min(kv2) && kv2.getPriority() > e->src())); #endif /* insert */ cckeyvalue kv(e->dst(), parent); assert(kv.src() >= kv.dst()); pq->insert(kv); /* cout << "identified: " << kroot << endl; */ } /* drain the priority queue */ if (stats) DEBUG_CCFOREST *stats << "draining priority queue" << endl; while (!pq->is_empty()) { cckeyvalue kv; pq->extract_min(kv); assert(kv.src() >= kv.dst()); if (stats) DEBUG_CCFOREST *stats << "processing edge " << kv << endl; removeDuplicates(kv.src(), kv.dst(), *pq); AMI_err ae = rootStream->write_item(kv); assert(ae == AMI_ERROR_NO_ERROR); } delete pq; /* note that rootStream is naturally ordered by src */ if(superTree->size()) { if (stats) { DEBUG_CCFOREST *stats << "resolving cycles..." << endl; /* printStream(rootStream); */ DEBUG_CCFOREST *stats << "sort rootStream: "; } AMI_STREAM<cckeyvalue> *sortedRootStream; dstCmpKeyvalueType<T> dstfo; sortedRootStream = sort(rootStream, dstfo); /* XXX replaced this to use a cmp object -- laura AMI_STREAM<cckeyvalue>*sortedRootStream=new AMI_STREAM<cckeyvalue>(); AMI_err ae = AMI_sort(rootStream, sortedRootStream, valueCmp); assert(ae == AMI_ERROR_NO_ERROR); */ delete rootStream; cckeyvalue *kv; T parent; AMI_err ae; AMI_STREAM<cckeyvalue>* relabeledRootStream = new AMI_STREAM<cckeyvalue>(); ae = sortedRootStream->seek(0); superTree->findAllRoots(depth+1); while((ae = sortedRootStream->read_item(&kv)) == AMI_ERROR_NO_ERROR) { parent = superTree->findNextRoot(kv->dst()); ae = relabeledRootStream->write_item(cckeyvalue(kv->src(), parent)); assert(ae == AMI_ERROR_NO_ERROR); } delete sortedRootStream; if (stats) DEBUG_CCFOREST *stats << "sort relabeledRootStream: "; rootStream = sort(relabeledRootStream, fo); /* laura: changed this rootStream = new AMI_STREAM<cckeyvalue>(); ae = AMI_sort(relabeledRootStream, rootStream); assert(ae == AMI_ERROR_NO_ERROR); */ delete relabeledRootStream; if (stats) DEBUG_CCFOREST *stats << "resolving cycles... done." << endl; } rootStream->seek(0); if (stats){ DEBUG_CCFOREST *stats << "Rootstream length=" << rootStream->stream_len() << endl; DEBUG_CCFOREST printStream(*stats, rootStream); DEBUG_CCFOREST *stats << "Explicit root count=" << explicitRootCount << endl; } rt_stop(rt); if (stats) stats->recordTime("ccforest::findAllRoots", (long int)rt_seconds(rt)); }
void detectEdgeNodata::processWindow(dimension_type row, dimension_type col, elevation_type &point, elevation_type *a, elevation_type *b, elevation_type *c) { AMI_err ae; static nodataType prevCell; /* cell on left (gets initialized) */ assert(row>=0); assert(col>=0); /* create window and write out */ ElevationWindow win(a, b, c); fillPit(win); /* fill pit in window */ ae = elevStream->write_item(win.get()); assert(ae == AMI_ERROR_NO_ERROR); /* only interested in nodata in this pass */ if(win.get() != nodata) { prevCell.label = LABEL_UNDEF; return; } if(col == 0) prevCell.label = LABEL_UNDEF; /* no left cell */ /* now check for continuing plateaus */ nodataType *ptarr = getNodataForward(row-1, col-1, nr, nc); /* make sure we use boundary label if appropriate */ cclabel_type crtlabel; crtlabel = (IS_BOUNDARY(row,col,nr, nc) ? LABEL_BOUNDARY : LABEL_UNDEF); for(int i=0; i<4; i++) { if(win.get(i) != win.get()) continue; /* only interesting if same elev */ /* determine label for cell */ cclabel_type label = LABEL_UNDEF; if(i<3) { if(ptarr[i].valid) label = ptarr[i].label; } else { if(prevCell.valid) label = prevCell.label; } /* check for collisions */ if(label != LABEL_UNDEF) { if (crtlabel == LABEL_UNDEF) { crtlabel = label; } else if(crtlabel != label) { /* collision!! */ /* pick smaller label, but prefer nodata */ if(crtlabel==LABEL_BOUNDARY || crtlabel<label) { colTree.insert(crtlabel, label); } else { colTree.insert(label, crtlabel); crtlabel = label; } } } } /* assign label if required */ if(crtlabel == LABEL_UNDEF) { crtlabel = labelFactory::getNewLabel(); } /* write this plateau point to the plateau stream */ nodataType pt; prevCell = pt = nodataType(row, col, crtlabel); nodataQueue->enqueue(pt); /* NODATA_DEBUG *stats << "inserting " << pt << endl; */ nodataStream->write_item(pt); /* save to file for later use */ }