DBObjRecord *DBVectorIF::Item (DBCoordinate coord) const { DBObjRecord *record, *retRecord = (DBObjRecord *) NULL; switch (DataPTR->Type ()) { case DBTypeVectorPoint: { DBFloat dist, minDist = DBHugeVal; DBObjTableField *coordFLD = ItemTable->Field (DBrNCoord); DBMathDistanceFunction distFunc = DBMathGetDistanceFunction (DataPTR); for (record = FirstItem ();record != (DBObjRecord *) NULL;record = NextItem ()) { dist = DBMathCoordinateDistance (distFunc,coord,coordFLD->Coordinate (record)); if (dist < minDist) { minDist = dist; retRecord = record; } } } break; case DBTypeVectorLine: break; case DBTypeVectorPolygon: break; default: CMmsgPrint (CMmsgAppError, "Unknown Vector Data Type in: %s %d",__FILE__,__LINE__); break; } return (retRecord); }
void DBVLineIF::Vertexes (DBObjRecord *lineRec,DBCoordinate *coord,DBInt vertexNum) { DBInt vertex; DBFloat length = 0; DBCoordinate *vertexes, prevCoord; DBObjRecord *dataRec = (DBObjRecord *) NULL; DBObjectLIST<DBObjRecord> *dataArrays = Data ()->Arrays (); DBRegion lineExtent, dataExtent = Data ()->Extent (); DBMathDistanceFunction distFunc = DBMathGetDistanceFunction (Data ()); prevCoord = NodeCoordFLD->Coordinate (FromNodeFLD->Record (lineRec)); lineExtent.Expand (prevCoord); if (vertexNum > 0) { if ((dataRec = dataArrays->Item (lineRec->RowID ())) == (DBObjRecord *) NULL) { if ((dataRec = new DBObjRecord (lineRec->Name (),((size_t) vertexNum) * sizeof (DBCoordinate),sizeof (DBFloat))) == (DBObjRecord *) NULL) return; dataArrays->Add (dataRec); } else dataRec->Realloc (vertexNum * sizeof (DBCoordinate)); if ((vertexes = (DBCoordinate *) dataRec->Data ()) == NULL) { CMmsgPrint (CMmsgSysError, "Memory Allocation Error in: %s %d",__FILE__,__LINE__); return; } for (vertex = 0;vertex < vertexNum;vertex++) { lineExtent.Expand (vertexes [vertex] = coord [vertex]); length += DBMathCoordinateDistance (distFunc,prevCoord,coord [vertex]); prevCoord = coord [vertex]; } } VertexesFLD->Record (lineRec,dataRec); VertexNumFLD->Int (lineRec,vertexNum); length += DBMathCoordinateDistance (distFunc,prevCoord,NodeCoordFLD->Coordinate (ToNodeFLD->Record (lineRec))); PerimeterFLD->Float (lineRec,length); lineExtent.Expand (NodeCoordFLD->Coordinate (ToNodeFLD->Record (lineRec))); ExtentFLD->Region (lineRec,lineExtent); dataExtent.Expand (lineExtent); Data ()->Extent (dataExtent); }
DBInt DBPointToGrid(DBObjData *pntData, DBObjData *grdData, DBFloat factor) { DBInt startID, pnt0ID, pntID, id, itemNum; double dist, minDist, box, box0, bWidth, bHeight; DBPosition pos; DBCoordinate gCoord, *pCoord; DBObjRecord *grdRec, *pntRec, *symRec; DBObjTable *itemTable, *symTable; DBObjTableField *valField, *symField; DBVPointIF *pntIF; DBGridIF *gridIF; DBMathDistanceFunction distFunc = DBMathGetDistanceFunction(pntData); if (distFunc != DBMathGetDistanceFunction(grdData)) { CMmsgPrint(CMmsgAppError, "Incompatible projections in: %s %d", __FILE__, __LINE__); return (DBFault); } pntIF = new DBVPointIF(pntData); itemNum = pntIF->ItemNum(); if ((pCoord = (DBCoordinate *) calloc(itemNum, sizeof(DBCoordinate))) == (DBCoordinate *) NULL) { CMmsgPrint(CMmsgSysError, "Memory allocation Error in: %s %d", __FILE__, __LINE__); return (DBFault); } gridIF = new DBGridIF(grdData); for (pntID = 0; pntID < itemNum; ++pntID) pCoord[pntID] = pntIF->Coordinate(pntIF->Item(pntID)); if (grdData->Type() == DBTypeGridContinuous) gridIF->RenameLayer(gridIF->Layer((DBInt) 0), (char *) "Distance to Station"); else { gridIF->RenameLayer(gridIF->Layer((DBInt) 0), (char *) "Station grid"); itemTable = grdData->Table(DBrNItems); symTable = grdData->Table(DBrNSymbols); valField = itemTable->Field(DBrNGridValue); symField = itemTable->Field(DBrNSymbol); if ((symRec = symTable->Item(0)) == (DBObjRecord *) NULL) CMmsgPrint(CMmsgAppError, "Total Metal Gebasz in: %s %d", __FILE__, __LINE__); for (pntID = 0; pntID < itemNum; ++pntID) { pntRec = pntIF->Item(pntID); grdRec = itemTable->Add(pntRec->Name()); valField->Int(grdRec, pntID + 1); symField->Record(grdRec, symRec); } } startID = 0; for (pos.Row = 0; pos.Row < gridIF->RowNum(); ++pos.Row) { DBPause(pos.Row * 100 / gridIF->RowNum()); for (pos.Col = 0; pos.Col < gridIF->ColNum(); ++pos.Col) { gridIF->Pos2Coord(pos, gCoord); minDist = box0 = DBHugeVal; pnt0ID = pntID = startID; id = DBFault; do { bWidth = fabs(gCoord.X - pCoord[pntID].X); bHeight = fabs(gCoord.Y - pCoord[pntID].Y); box = bWidth > bHeight ? bWidth : bHeight; if ((box < box0) && ((dist = DBMathCoordinateDistance(distFunc, gCoord, pCoord[pntID])) < minDist)) { minDist = dist; id = startID = pntID; box *= factor; if (box0 > box) box0 = box; } pntID = pntID + 1 < itemNum ? pntID + 1 : 0; } while (pntID != pnt0ID); if (grdData->Type() == DBTypeGridContinuous) gridIF->Value(pos, minDist); else gridIF->Value(pos, id); } } if (grdData->Type() == DBTypeGridContinuous) gridIF->RecalcStats(); else gridIF->DiscreteStats(); delete gridIF; free(pCoord); return (DBSuccess); }
DBInt DBNetworkIF::Build () { DBInt i, j, row, col, basin, dir, projection = DataPTR->Projection (); DBCoordinate coord0, coord1; char nameStr [DBStringLength]; DBPosition pos; DBObjRecord *cellRec, *toCell, *fromCell, *basinRec, *symbolRec; _DBnetIF = this; for (j = 0;j < BasinTable->ItemNum ();++j) { basinRec = BasinTable->Item (j); if (((cellRec = Cell (MouthPosFLD->Position (basinRec))) == (DBObjRecord *) NULL) || (ToCell (cellRec) != (DBObjRecord *) NULL)) { BasinTable->Delete (basinRec); j--; } } for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); DBPause (i * 10 / CellNum ()); if (Cell (CellPosition (cellRec)) == (DBObjRecord *) NULL) continue; else if (ToCell (ToCell (cellRec)) == cellRec) ToCellFLD->Int (cellRec,DBNull); } DBPause (10); for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); DBPause (10 + i * 10 / CellNum ()); pos = CellPosition (cellRec); if (((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] == DBFault) { CellTable->Delete (cellRec); --i; } else { cellRec->Flags (DBObjectFlagLocked,DBClear); FromCellFLD->Int (cellRec,DBNull); OrderFLD->Int (cellRec,1); BasinFLD->Int (cellRec,DBFault); BasinCellsFLD->Int (cellRec,1); TravelFLD->Int (cellRec,0); UpCellPosFLD->Position (cellRec,pos); CellAreaFLD->Float (cellRec,DBMathRectangleArea (projection,Center (cellRec) - CellSize () / 2,Center (cellRec) + CellSize () / 2)); coord0 = Center (cellRec); coord1 = Center (cellRec) + Delta (cellRec); CellLengthFLD->Float (cellRec,DBMathCoordinateDistance (DataPTR->Projection (),coord0,coord1)); SubbasinLengthFLD->Float (cellRec,CellLength (cellRec)); SubbasinAreaFLD->Float (cellRec,CellAreaFLD->Float (cellRec)); } } for (j = 0;j < BasinTable->ItemNum ();++j) { basinRec = BasinTable->Item (j); cellRec = Cell (MouthPosFLD->Position (basinRec)); if ((cellRec == (DBObjRecord *) NULL) || ((cellRec->Flags () & DBObjectFlagLocked) == DBObjectFlagLocked)) { BasinTable->Delete (basinRec); j--; } else cellRec->Flags (DBObjectFlagLocked,DBSet); } DBPause (20); for (row = 0;row < RowNum ();row++) for (col = 0;col < ColNum ();col++) ((DBInt *) DataRec->Data ()) [row * ColNum () + col] = DBFault; for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); cellRec->Flags (DBObjectFlagLocked,DBClear); DBPause (20 + i * 10 / CellNum ()); pos = CellPosition (cellRec); if (((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] != DBFault) { CellTable->Delete (cellRec); --i; } else ((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] = cellRec->RowID (); } DBPause (30); for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); if ((toCell = ToCell (cellRec)) != (DBObjRecord *) NULL) FromCellFLD->Int (toCell,FromCellFLD->Int (toCell) | _DBNetworkOppositeDirection (ToCellFLD->Int (cellRec))); } for (i = 0;i < CellNum ();++i) { DBPause (30 + i * 10 / CellNum ()); cellRec = CellTable->Item (i); if (ToCell (cellRec) == (DBObjRecord *) NULL) Climb (cellRec,0); } DBPause (40); CellTable->ItemSort (_DBGNetworkCellCompare); for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); DBPause (35 + i * 10/ CellNum ()); pos = CellPosition (cellRec); ((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] = cellRec->RowID (); } DBPause (50); basin = 0; for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); DBPause (50 + i * 20 / CellNum ()); if (ToCell (cellRec) == (DBObjRecord *) NULL) { SetBasin (cellRec,basin + 1); basinRec = (DBObjRecord *) NULL; for (j = 0;j < BasinTable->ItemNum ();++j) { if (((basin - j) >= 0) && ((basin - j) < BasinTable->ItemNum ()) && (cellRec == MouthCell (basinRec = BasinTable->Item (basin - j)))) break; if (((basin + j) < BasinTable->ItemNum ()) && (cellRec == MouthCell (basinRec = BasinTable->Item (basin + j)))) break; basinRec = (DBObjRecord *) NULL; } if (basinRec == (DBObjRecord *) NULL) { basinRec = BasinTable->Add ("GHAASBasin"); MouthPosFLD->Position (basinRec,CellPosition (cellRec)); } basinRec->ListPos (basin++); } } DBPause (70); CellTable->ItemSort (_DBGNetworkCellCompare); BasinTable->ItemSort (); for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); DBPause (70 + i * 10 / CellNum ()); pos = CellPosition (cellRec); ((DBInt *) DataRec->Data ()) [pos.Row * ColNum () + pos.Col] = cellRec->RowID (); sprintf (nameStr,"GHAASCell:%d",cellRec->RowID () + 1); cellRec->Name (nameStr); } DBPause (80); SymbolTable->DeleteAll (); symbolRec = SymbolTable->Add ("Network Symbol"); SymbolIDFLD->Int (symbolRec,1); ForegroundFLD->Int (symbolRec,1); BackgroundFLD->Int (symbolRec,0); for (j = 0;j < BasinTable->ItemNum ();++j) { basinRec = BasinTable->Item (j); if ((strncmp (basinRec->Name (),"GHAASBasin",strlen ("GHAASBasin")) == 0) || (strlen (basinRec->Name ()) < 1)) { sprintf (nameStr,"GHAASBasin%d",basinRec->RowID () + 1); basinRec->Name (nameStr); } ColorFLD->Int (basinRec,DBFault); BasinOrderFLD->Int (basinRec,CellOrder (MouthCell (basinRec))); BasinAreaFLD->Float (basinRec,CellBasinArea (MouthCell (basinRec))); BasinLengthFLD->Float (basinRec,CellBasinLength (MouthCell (basinRec))); SymbolFLD->Record (basinRec,symbolRec); } basin = DBFault; for (i = 0;i < CellNum ();++i) { cellRec = CellTable->Item (i); if ((basinRec = Basin (cellRec)) == (DBObjRecord *) NULL) { CMmsgPrint (CMmsgAppError,"BasinID: %d CellID:%d",BasinFLD->Int (cellRec),cellRec->RowID ()); continue; } if (basin != basinRec->RowID ()) { basin = basinRec->RowID (); DBPause (80 + basin * 20 / BasinNum ()); ColorFLD->Int (basinRec,7); toCell = cellRec; } for (dir = 0;dir < 8;dir += 2) { if ((fromCell = FromCell (cellRec,0x01 << dir,false)) == (DBObjRecord *) NULL) continue; if (basinRec == Basin (fromCell)) continue; if (ColorFLD->Int (basinRec) == ColorFLD->Int (Basin (fromCell))) { ColorFLD->Int (basinRec,ColorFLD->Int (basinRec) + 1); cellRec = MouthCell (basinRec); i = cellRec->RowID () - 1; } } } DBPause (100); if (DistToMouth ()) SetDistToMouth (); if (DistToOcean ()) SetDistToOcean (); if (Magnitude ()) SetMagnitude (); return (DBSuccess); }
DBNetworkIF::DBNetworkIF (DBObjData *data) { DBObjTableField *layerFLD; DataPTR = data; BasinTable = data->Table (DBrNItems); CellTable = data->Table (DBrNCells); LayerTable = data->Table (DBrNLayers); SymbolTable = data->Table (DBrNSymbols); MouthPosFLD = BasinTable->Field (DBrNMouthPos); ColorFLD = BasinTable->Field (DBrNColor); BasinOrderFLD = BasinTable->Field (DBrNBasinOrder); SymbolFLD = BasinTable->Field (DBrNSymbol); BasinLengthFLD = BasinTable->Field (DBrNBasinLength); BasinAreaFLD = BasinTable->Field (DBrNBasinArea); SymbolIDFLD = SymbolTable->Field (DBrNSymbolID); ForegroundFLD = SymbolTable->Field (DBrNForeground); BackgroundFLD = SymbolTable->Field (DBrNBackground); PositionFLD = CellTable->Field (DBrNPosition); ToCellFLD = CellTable->Field (DBrNToCell); FromCellFLD = CellTable->Field (DBrNFromCell); OrderFLD = CellTable->Field (DBrNOrder); MagnitudeFLD = CellTable->Field (DBrNMagnitude); BasinFLD = CellTable->Field (DBrNBasin); BasinCellsFLD = CellTable->Field (DBrNBasinCells); TravelFLD = CellTable->Field (DBrNTravel); UpCellPosFLD = CellTable->Field (DBrNUpCellPos); CellAreaFLD = CellTable->Field (DBrNCellArea); CellLengthFLD = CellTable->Field (DBrNCellLength); DistToMouthFLD = CellTable->Field (DBrNDistToMouth); DistToOceanFLD = CellTable->Field (DBrNDistToOcean); SubbasinLengthFLD = CellTable->Field (DBrNSubbasinLength); SubbasinAreaFLD = CellTable->Field (DBrNSubbasinArea); RowNumFLD = LayerTable->Field (DBrNRowNum); ColNumFLD = LayerTable->Field (DBrNColNum); CellWidthFLD = LayerTable->Field (DBrNCellWidth); CellHeightFLD = LayerTable->Field (DBrNCellHeight); layerFLD = LayerTable->Field (DBrNLayer); if ((LayerRecord = LayerTable->Item (DBrNLookupGrid)) == (DBObjRecord *) NULL) { CMmsgPrint (CMmsgAppError,"Bailing Out like ARC/INFO in: %s %d",__FILE__,__LINE__); exit (-1); } if((DataRec = layerFLD->Record (LayerRecord)) == (DBObjRecord *) NULL) { CMmsgPrint (CMmsgAppError,"Bailing Out in: %s %d",__FILE__,__LINE__); exit (-1); } if (CellLengthFLD == (DBObjTableField *) NULL) { DBInt cellID; DBObjRecord *cellRec; DBCoordinate coord0, coord1; CellLengthFLD = new DBObjTableField (DBrNCellLength,DBTableFieldFloat,"%10.1f",sizeof (DBFloat4),true); CellTable->AddField (CellLengthFLD); for (cellID = 0;cellID < CellNum ();++cellID) { cellRec = Cell (cellID); coord0 = Center (cellRec); coord1 = Center (cellRec) + Delta (cellRec); CellLengthFLD->Float (cellRec,DBMathCoordinateDistance (DataPTR->Projection (),coord0,coord1)); } } }
DBInt DBGridIF::Value(DBObjRecord *layerRec, DBCoordinate coord, DBFloat *value) const { DBInt i, j, pointNum; DBInt row[9], col[9]; DBPosition pos; DBCoordinate cellCoord; DBPosition cellPos; DBFloat precision, dist, wAvg, sumWeight, retVal; DBObjRecord *dataRec = LayerFLD->Record(layerRec); DBFloat missingValue = MissingValueFLD->Float(ItemTable->Item()); DBMathDistanceFunction distFunc = DBMathGetDistanceFunction(DataPTR); if (DataPTR->Extent().InRegion(coord) == false) return (false); precision = pow((double) 10.0, (double) DataPTR->Precision()); Coord2Pos(coord, cellPos); Pos2Coord(cellPos, cellCoord); if (Flat || ((fabs(coord.X - cellCoord.X) < precision) && (fabs(coord.Y - cellCoord.Y) < precision))) { j = DimensionVAR.Col * (DimensionVAR.Row - cellPos.Row - 1) + cellPos.Col; switch (ValueTypeVAR) { case DBTableFieldFloat: switch (ValueSizeVAR) { case sizeof(DBFloat4): retVal = (DBFloat) ((DBFloat4 *) (dataRec->Data()))[j]; break; case sizeof(DBFloat): retVal = (DBFloat) ((DBFloat *) (dataRec->Data()))[j]; break; } break; case DBTableFieldInt: switch (ValueSizeVAR) { case sizeof(DBByte): retVal = (DBFloat) ((DBByte *) (dataRec->Data()))[j]; break; case sizeof(DBShort): retVal = (DBFloat) ((DBShort *) (dataRec->Data()))[j]; break; case sizeof(DBInt): retVal = (DBFloat) ((DBInt *) (dataRec->Data()))[j]; break; } break; } if (!CMmathEqualValues(retVal, missingValue)) { *value = retVal; return (true); } } col[0] = cellPos.Col; row[0] = cellPos.Row; if (coord.X < cellCoord.X) col[0] -= 1; if (coord.Y < cellCoord.Y) row[0] -= 1; col[1] = col[0] + 1; row[1] = row[0]; col[2] = col[0] + 1; row[2] = row[0] + 1; col[3] = col[0]; row[3] = row[0] + 1; pos.Col = col[0]; pos.Row = row[0]; Pos2Coord(pos, cellCoord); if ((coord.X - cellCoord.X) > (3.0 * CellWidth() / 4.0)) i = 1; else if ((coord.X - cellCoord.X) > (CellWidth() / 4.0)) i = 0; else i = -1; if ((coord.Y - cellCoord.Y) > (3.0 * CellHeight() / 4.0)) j = 1; else if ((coord.Y - cellCoord.Y) > (CellHeight() / 4.0)) j = 0; else j = -1; if ((i != 0) || (j != 0)) { if (i == 0) { row[4] = row[5] = j > 0 ? row[2] + 1 : row[0] - 1; col[4] = col[0]; col[5] = col[2]; pointNum = 6; } else if (j == 0) { row[4] = row[0]; row[5] = row[2]; col[4] = col[5] = i > 0 ? col[2] + 1 : col[0] - 1; pointNum = 6; } else { row[7] = row[0]; row[8] = row[2]; if (j > 0) row[4] = row[5] = row[6] = row[2] + 1; else row[4] = row[5] = row[6] = row[0] - 1; if (i > 0) { col[4] = col[0]; col[5] = col[2]; col[6] = col[7] = col[8] = col[2] + 1; } else { col[5] = col[0]; col[6] = col[2]; col[4] = col[7] = col[8] = col[0] - 1; } pointNum = 9; } } else pointNum = 4; wAvg = sumWeight = 0.0; for (i = 0; i < pointNum; ++i) { if (col[i] < 0) continue; if (row[i] < 0) continue; if (col[i] >= DimensionVAR.Col) continue; if (row[i] >= DimensionVAR.Row) continue; j = DimensionVAR.Col * (DimensionVAR.Row - row[i] - 1) + col[i]; switch (ValueTypeVAR) { case DBTableFieldFloat: switch (ValueSizeVAR) { case sizeof(DBFloat4): retVal = (DBFloat) ((DBFloat4 *) (dataRec->Data()))[j]; break; case sizeof(DBFloat): retVal = (DBFloat) ((DBFloat *) (dataRec->Data()))[j]; break; } break; case DBTableFieldInt: switch (ValueSizeVAR) { case sizeof(DBByte): retVal = (DBFloat) ((DBByte *) (dataRec->Data()))[j]; break; case sizeof(DBShort): retVal = (DBFloat) ((DBShort *) (dataRec->Data()))[j]; break; case sizeof(DBInt): retVal = (DBFloat) ((DBInt *) (dataRec->Data()))[j]; break; } break; } if (CMmathEqualValues(retVal, missingValue)) { if ((col[i] == cellPos.Col) && (row[i] == cellPos.Row)) return (false); else continue; } pos.Row = (DBUShort) row[i]; pos.Col = (DBUShort) col[i]; Pos2Coord(pos, cellCoord); if (pointNum > 1) { dist = DBMathCoordinateDistance(distFunc, coord, cellCoord); dist *= dist; } else dist = 1.0; wAvg = wAvg + retVal / dist; sumWeight = sumWeight + 1.0 / dist; } if (sumWeight > 0) { *value = wAvg / sumWeight; return (true); } else { *value = missingValue; return (false); } }
DBInt DBGridCont2Network (DBObjData *gridData,DBObjData *netData, bool downhill) { DBInt basinID, layerID, zLayerID, zLayerNum, dir, maxDir, projection = gridData->Projection (), *zones; DBFloat elev0, elev1, delta, maxDelta, distance; DBCoordinate coord0, coord1; DBInt row, col; DBPosition pos, auxPos; char nameSTR [DBStringLength]; DBObjTable *basinTable = netData->Table (DBrNItems); DBObjTable *cellTable = netData->Table (DBrNCells); DBObjTable *layerTable = netData->Table (DBrNLayers); DBObjRecord *layerRec, *dataRec, *cellRec, *basinRec; DBObjTableField *mouthPosFLD = basinTable->Field (DBrNMouthPos); DBObjTableField *colorFLD = basinTable->Field (DBrNColor); DBObjTableField *positionFLD = cellTable->Field (DBrNPosition); DBObjTableField *toCellFLD = cellTable->Field (DBrNToCell); DBObjTableField *fromCellFLD = cellTable->Field (DBrNFromCell); DBObjTableField *orderFLD = cellTable->Field (DBrNOrder); DBObjTableField *basinFLD = cellTable->Field (DBrNBasin); DBObjTableField *basinCellsFLD= cellTable->Field (DBrNBasinCells); DBObjTableField *travelFLD = cellTable->Field (DBrNTravel); DBObjTableField *upCellPosFLD = cellTable->Field (DBrNUpCellPos); DBObjTableField *cellAreaFLD = cellTable->Field (DBrNCellArea); DBObjTableField *subbasinLengthFLD = cellTable->Field (DBrNSubbasinLength); DBObjTableField *subbasinAreaFLD = cellTable->Field (DBrNSubbasinArea); DBObjTableField *rowNumFLD = layerTable->Field (DBrNRowNum); DBObjTableField *colNumFLD = layerTable->Field (DBrNColNum); DBObjTableField *cellWidthFLD = layerTable->Field (DBrNCellWidth); DBObjTableField *cellHeightFLD = layerTable->Field (DBrNCellHeight); DBObjTableField *valueTypeFLD = layerTable->Field (DBrNValueType); DBObjTableField *valueSizeFLD = layerTable->Field (DBrNValueSize); DBObjTableField *layerFLD = layerTable->Field (DBrNLayer); DBObjData *zGridData = gridData->LinkedData (); DBGridIF *gridIF = new DBGridIF (gridData), *zGridIF; DBNetworkIF *netIF; if ((zGridData != (DBObjData *) NULL) && ((zGridData->Type () == DBTypeGridDiscrete) || (zGridData->Type () == DBTypeGridContinuous))) { zGridIF = new DBGridIF (zGridData); zLayerNum = zGridIF->LayerNum () + 1; } else { zGridIF = (DBGridIF *) NULL; zLayerNum = 1; } if ((zones = (DBInt *) calloc (9 * zLayerNum,sizeof (DBInt))) == (DBInt *) NULL) { CMmsgPrint (CMmsgSysError, "Memory Allocation Error in: %s %d",__FILE__,__LINE__); if (zGridIF != (DBGridIF *) NULL) delete zGridIF; delete gridIF; return (DBFault); } layerTable->Add (DBrNLookupGrid); if ((layerRec = layerTable->Item (DBrNLookupGrid)) == (DBObjRecord *) NULL) { free (zones); if (zGridIF != (DBGridIF *) NULL) delete zGridIF; delete gridIF; return (DBFault); } netData->Projection (projection); netData->Extent (gridData->Extent ()); cellWidthFLD->Float (layerRec,gridIF->CellWidth ()); cellHeightFLD->Float (layerRec,gridIF->CellHeight ()); valueTypeFLD->Int (layerRec,DBTableFieldInt); valueSizeFLD->Int (layerRec,sizeof (DBInt)); rowNumFLD->Int (layerRec,gridIF->RowNum ()); colNumFLD->Int (layerRec,gridIF->ColNum ()); dataRec = new DBObjRecord ("NetLookupGridRecord",((size_t) gridIF->RowNum ()) * gridIF->ColNum () * sizeof (DBInt),sizeof (DBInt)); if (dataRec == (DBObjRecord *) NULL) { if (zGridIF != (DBGridIF *) NULL) delete zGridIF; return (DBFault); } layerFLD->Record (layerRec,dataRec); (netData->Arrays ())->Add (dataRec); for (pos.Row = 0;pos.Row < gridIF->RowNum ();pos.Row++) for (pos.Col = 0;pos.Col < gridIF->ColNum ();pos.Col++) ((DBInt *) dataRec->Data ()) [pos.Row * gridIF->ColNum () + pos.Col] = DBFault; for (pos.Row = 0;pos.Row < gridIF->RowNum ();pos.Row++) { if (DBPause (10 * pos.Row / gridIF->RowNum ())) goto PauseStop; for (pos.Col = 0;pos.Col < gridIF->ColNum ();pos.Col++) { gridIF->Pos2Coord (pos,coord0); zLayerID = 0; if (zGridIF != (DBGridIF *) NULL) for ( ; zLayerID < zGridIF->LayerNum (); zLayerID++) { layerRec = zGridIF->Layer (zLayerID); if ((layerRec->Flags () & DBObjectFlagIdle) == DBObjectFlagIdle) continue; for (dir = 0;dir < 8;++dir) { row = pos.Row; col = pos.Col; if (((0x01 << dir) == DBNetDirNW) || ((0x01 << dir) == DBNetDirN) || ((0x01 << dir) == DBNetDirNE)) row++; if (((0x01 << dir) == DBNetDirSE) || ((0x01 << dir) == DBNetDirS) || ((0x01 << dir) == DBNetDirSW)) row--; if (((0x01 << dir) == DBNetDirNE) || ((0x01 << dir) == DBNetDirE) || ((0x01 << dir) == DBNetDirSE)) col++; if (((0x01 << dir) == DBNetDirNW) || ((0x01 << dir) == DBNetDirW) || ((0x01 << dir) == DBNetDirSW)) col--; if (row < 0) continue; if (col < 0) continue; if (row >= gridIF->RowNum ()) continue; if (col >= gridIF->ColNum ()) continue; auxPos.Row = row; auxPos.Col = col; gridIF->Pos2Coord (auxPos,coord1); switch (zGridData->Type ()) { case DBTypeGridDiscrete: basinID = zGridIF->GridValue (layerRec,coord1); break; case DBTypeGridContinuous: zGridIF->Value (layerRec,coord1,&basinID); break; } zones [zLayerID * 9 + dir] = basinID; } switch (zGridData->Type ()) { case DBTypeGridDiscrete: basinID = zGridIF->GridValue (layerRec,coord0); break; case DBTypeGridContinuous: zGridIF->Value (layerRec,coord0,&basinID); break; } zones [zLayerID * 9 + 8] = basinID; } for (dir = 0;dir < 9;++dir) zones [zLayerID * 9 + dir] = 0; maxDir = DBFault; for (layerID = 0;layerID < gridIF->LayerNum ();++layerID) { layerRec = gridIF->Layer (layerID); if ((layerRec->Flags () & DBObjectFlagIdle) == DBObjectFlagIdle) continue; if (gridIF->Value (layerRec,pos,&elev0)) { maxDelta = (DBFloat) 0.0; maxDir = 0; for (zLayerID = 0;zLayerID < zLayerNum;++zLayerID) { for (dir = 0;dir < 8;++dir) { row = pos.Row; col = pos.Col; if (((0x01 << dir) == DBNetDirNW) || ((0x01 << dir) == DBNetDirN) || ((0x01 << dir) == DBNetDirNE)) row++; if (((0x01 << dir) == DBNetDirSE) || ((0x01 << dir) == DBNetDirS) || ((0x01 << dir) == DBNetDirSW)) row--; if (((0x01 << dir) == DBNetDirNE) || ((0x01 << dir) == DBNetDirE) || ((0x01 << dir) == DBNetDirSE)) col++; if (((0x01 << dir) == DBNetDirNW) || ((0x01 << dir) == DBNetDirW) || ((0x01 << dir) == DBNetDirSW)) col--; if (col < 0) continue; if (row < 0) continue; if (col >= gridIF->ColNum ()) continue; if (row >= gridIF->RowNum ()) continue; auxPos.Row = row; auxPos.Col = col; gridIF->Pos2Coord (auxPos,coord1); distance = DBMathCoordinateDistance (projection,coord0,coord1); if ((zones [zLayerID * 9 + dir] == zones [zLayerID * 9 + 8]) && (gridIF->Value (layerRec,auxPos,&elev1))) { delta = (downhill ? (elev1 - elev0) : (elev0 - elev1)) / distance; if (maxDelta > delta) { maxDelta = delta; maxDir = (0x01 << dir); } } } if (maxDir != 0) goto SlopeStop; } } } SlopeStop: if (maxDir != DBFault) { sprintf (nameSTR,"GHAASCell:%d",cellTable->ItemNum ()); cellRec = cellTable->Add (nameSTR); positionFLD->Position(cellRec,pos); toCellFLD->Int (cellRec,(DBInt) maxDir); fromCellFLD->Int (cellRec,(DBInt) 0); orderFLD->Int (cellRec,(DBInt) 0); basinFLD->Int (cellRec,(DBInt) 0); basinCellsFLD->Int (cellRec,(DBInt) 0); travelFLD->Int (cellRec,(DBInt) 0); upCellPosFLD->Position (cellRec,pos); cellAreaFLD->Float (cellRec,(DBFloat) 0.0); subbasinLengthFLD->Float(cellRec,(DBFloat) 0.0); subbasinAreaFLD->Float (cellRec,(DBFloat) 0.0); ((DBInt *) dataRec->Data ()) [pos.Row * gridIF->ColNum () + pos.Col] = cellRec->RowID (); } } } PauseStop: if (pos.Row < gridIF->RowNum ()) return (DBFault); sprintf (nameSTR,"GHAASBasin%d",(DBInt) 0); basinRec = basinTable->Add (nameSTR); mouthPosFLD->Position (basinRec,positionFLD->Position (cellTable->Item (0))); colorFLD->Int (basinRec,0); free (zones); delete gridIF; if (zGridIF != (DBGridIF *) NULL) delete zGridIF; netData->Precision (DBMathMin (gridIF->CellWidth (),gridIF->CellHeight ()) / 25.0); netIF = new DBNetworkIF (netData); netIF->Build (); delete netIF; return (DBSuccess); }