[GRASS-SVN] r36623 - in grass-addons/raster: . r.terracost
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Apr 8 03:22:12 EDT 2009
Author: neteler
Date: 2009-04-08 03:22:12 -0400 (Wed, 08 Apr 2009)
New Revision: 36623
Added:
grass-addons/raster/r.terracost/
grass-addons/raster/r.terracost/.DS_Store
grass-addons/raster/r.terracost/Makefile
grass-addons/raster/r.terracost/boundary.cc
grass-addons/raster/r.terracost/boundary.h
grass-addons/raster/r.terracost/boundaryMgr.h
grass-addons/raster/r.terracost/boundarySort.cc
grass-addons/raster/r.terracost/common.cc
grass-addons/raster/r.terracost/common.h
grass-addons/raster/r.terracost/config.cc
grass-addons/raster/r.terracost/config.h
grass-addons/raster/r.terracost/debug.h
grass-addons/raster/r.terracost/description.html
grass-addons/raster/r.terracost/dijkstra.cc
grass-addons/raster/r.terracost/dijkstra.h
grass-addons/raster/r.terracost/dijkstraAbs.cc
grass-addons/raster/r.terracost/dijkstraAbs.h
grass-addons/raster/r.terracost/distanceType.h
grass-addons/raster/r.terracost/formatNumber.cc
grass-addons/raster/r.terracost/formatNumber.h
grass-addons/raster/r.terracost/genericTile.h
grass-addons/raster/r.terracost/grass2str.h
grass-addons/raster/r.terracost/index.cc
grass-addons/raster/r.terracost/index.h
grass-addons/raster/r.terracost/initialize.cc
grass-addons/raster/r.terracost/initialize.h
grass-addons/raster/r.terracost/input.h
grass-addons/raster/r.terracost/iterator.cc
grass-addons/raster/r.terracost/iterator.h
grass-addons/raster/r.terracost/locator.cc
grass-addons/raster/r.terracost/locator.h
grass-addons/raster/r.terracost/main.cc
grass-addons/raster/r.terracost/main.h
grass-addons/raster/r.terracost/option.h
grass-addons/raster/r.terracost/output.cc
grass-addons/raster/r.terracost/output.h
grass-addons/raster/r.terracost/pq.h
grass-addons/raster/r.terracost/pqueue.h
grass-addons/raster/r.terracost/queue.h
grass-addons/raster/r.terracost/quicksortD.h
grass-addons/raster/r.terracost/sortutils.h
grass-addons/raster/r.terracost/stats.cc
grass-addons/raster/r.terracost/stats.h
grass-addons/raster/r.terracost/tile.cc
grass-addons/raster/r.terracost/tile.h
grass-addons/raster/r.terracost/tileAbs.cc
grass-addons/raster/r.terracost/tileAbs.h
grass-addons/raster/r.terracost/tileSplit.cc
grass-addons/raster/r.terracost/types.h
grass-addons/raster/r.terracost/update.cc
grass-addons/raster/r.terracost/update.h
grass-addons/raster/r.terracost/updateAbs.cc
grass-addons/raster/r.terracost/updateAbs.h
Log:
ltoma: new r.terracost; various include file fixes, new description.html, new Makefile; IOSTREAM lib not included as already in GRASS 6
Added: grass-addons/raster/r.terracost/.DS_Store
===================================================================
(Binary files differ)
Property changes on: grass-addons/raster/r.terracost/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: grass-addons/raster/r.terracost/Makefile
===================================================================
--- grass-addons/raster/r.terracost/Makefile (rev 0)
+++ grass-addons/raster/r.terracost/Makefile 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,15 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.terracost
+
+MOD_OBJS = $(subst .cc,.o,$(wildcard *.cc))
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+LIBS = $(GISLIB) $(IOSTREAMLIB)
+DEPLIBS = $(GISDEP) $(IOSTREAMDEP)
+
+default: cmd
+
+$(BIN)/$(PGM)$(EXE): $(ARCH_CMD_OBJS) $(DEPENDENCIES)
+ $(CXX) $(LDFLAGS) $(IOSTREAMFLAG) $(XTRA_LDFLAGS) $(EXTRA_CFLAGS) $(NLS_CFLAGS) -o $@ $(ARCH_CMD_OBJS) $(FMODE_OBJ) $(LIBES) $(MATHLIB) $(XDRLIB) $(IOSTREAM_LIB)
Property changes on: grass-addons/raster/r.terracost/Makefile
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/boundary.cc
===================================================================
--- grass-addons/raster/r.terracost/boundary.cc (rev 0)
+++ grass-addons/raster/r.terracost/boundary.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,315 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include "boundary.h"
+#include "sortutils.h"
+#include "types.h"
+#include "pq.h"
+#include "pqueue.h"
+#include "formatNumber.h"
+
+#include <math.h>
+/*
+ The Boundary Module is used to define the BoundaryType class. This class
+ stores all of the boundary points between tiles in a grid(graph).
+*/
+
+size_t
+memForNormalDijkstra(dimension_type rows, dimension_type cols) {
+ /* Required items for normal dijkstra
+ 1. Grid of costs
+ 2. Grid of distances
+ 3. PQ
+ */
+
+ size_t gridCosts = 2*rows*cols*sizeof(cost_type);
+ size_t pqCost = rows*cols*sizeof(costStructure);
+
+ return gridCosts+pqCost;
+}
+
+
+/************************************************************/
+/* sets tileSizeRows, tileSizeCols, nrowsPad, ncolsPad given the
+ memory to be used by a tile; the size of a tile is chosen so that a
+ tile uses at most maxmem memory; in order that boundary tiles have
+ same size as internal tiles we pad the grid we extra rows and
+ columns; the size of the grid is thus (nrowsPad, ncolsPad) */
+void
+initializeTileSize(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ size_t maxmem) {
+
+
+ /* use all available memory */
+ dimension_type baseTileSize;
+ baseTileSize = (dimension_type)sqrt ((float)(maxmem /(sizeof(ijCostSource) +
+ sizeof(cost_type))));
+ optimizeTileSize(tileSizeRows, tileSizeCols, baseTileSize);
+}
+
+void
+initializeTileSize(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ int numTiles) {
+
+
+ /* Find a divisor of numTiles which will be the number of tiles from
+ top to bottom. Then the number of left to right tiles is computed
+ by dividing the total number of tiles by the number of top to
+ bottom tiles */
+
+ int gridSize = nrows * ncols;
+ int tileSize = gridSize / numTiles;
+
+
+ *tileSizeRows = (int)ceil(sqrt((float)tileSize));
+ *tileSizeCols = tileSize/(*tileSizeRows);
+
+ tileSize = (*tileSizeRows) * (*tileSizeCols);
+
+ int tileRows = (int)ceil((float)(nrows-1)/(float)((*tileSizeRows)-1));
+ int tileCols = (int)ceil((float)(ncols-1)/(float)((*tileSizeCols)-1));
+
+
+ std::cout << "Grid size is: " << gridSize << std::endl;
+ std::cout << "Tile size is: " << tileSize << std::endl;
+ std::cout << "tileSizeRows: " << *tileSizeRows << std::endl;
+ std::cout << "tileSizeCols: " << *tileSizeCols << std::endl;
+ std::cout << "tileRows: " << tileRows << std::endl;
+ std::cout << "tileCols: " << tileCols << std::endl;
+
+ optimizeTileSizeUser(tileSizeRows, tileSizeCols,
+ *tileSizeRows, *tileSizeCols,
+ tileRows, tileCols);
+}
+
+void
+optimizeTileSizeUser(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ int baseSizeRows, int baseSizeCols,
+ int tileRows, int tileCols) {
+
+ /* if the number of tiles divides evenly into the number of rows, we
+ don't have to change anything and nrowsPad=nrows. If not then
+ tileSizeRows*tileRows < nrows b/c of integer division. Then we
+ add 1 to the size of the tile which causes tileSizeRows*tileRows
+ > nrows and then we can pad the total number of rows to
+ compensate. Also # padding rows < tileRows. */
+
+ *tileSizeRows = baseSizeRows;
+ if ((nrows-1)%(*tileSizeRows-1) == 0) {
+ nrowsPad = nrows;
+ }
+ else {
+ nrowsPad = (*tileSizeRows-1)*tileRows + 1;
+ }
+
+ *tileSizeCols = baseSizeCols;
+ if ((ncols-1)%(*tileSizeCols-1) == 0) {
+ ncolsPad = ncols;
+ }
+ else {
+ ncolsPad = (*tileSizeCols-1)*tileCols + 1;
+ }
+
+ std::cout << "Tile Size Rows: " << *tileSizeRows << std::endl;
+ std::cout.flush();
+ std::cout << "Padding Rows: " << nrowsPad - nrows << std::endl;
+ std::cout.flush();
+ std::cout << "Num Row Tiles: " << tileRows << std::endl;
+ std::cout.flush();
+ std::cout << "Tile Size Cols: " << *tileSizeCols << std::endl;
+ std::cout.flush();
+ std::cout << "Padding Cols: " << ncolsPad - ncols << std::endl;
+ std::cout.flush();
+ std::cout << "Num Col Tiles: " << tileCols << std::endl;
+ std::cout.flush();
+
+}
+
+void
+optimizeTileSize(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ int baseTileSize) {
+
+ /* set tileSizeRowsand tileSizeCols to minimize padding */
+ dimension_type bndrows, bndcols, lr, lc;
+ dimension_type paddingRows = 0, paddingCols = 0;
+ float paddingRatio = 0.0, lastRowRatio = 0.0;
+
+ /* optimize tileSizeRows */
+ *tileSizeRows = baseTileSize;
+ if (*tileSizeRows < nrows) {
+ bndrows = computeNumBoundaries(nrows, *tileSizeRows);
+ //cout << "BndRows: " << bndrows << endl; cout.flush();
+ lr = lastTileSizeRow(bndrows, *tileSizeRows);
+ paddingRatio = (float)lr/(*tileSizeRows);
+ lastRowRatio = paddingRatio;
+ paddingRows = (*tileSizeRows)-lr;
+ //cout << "Padding Rows: " << paddingRows << " LR: " << lr << " I: "
+ // << *tileSizeRows << endl;cout.flush();
+ //cout <<"Trying row tile size "<<*tileSizeRows << ". Padding Ratio: " <<
+ // paddingRatio << ".\n";
+ for (int i = *tileSizeRows;paddingRatio<.95 &&
+ lastRowRatio<=paddingRatio;i--) {
+ bndrows = computeNumBoundaries(nrows, i);
+ lr = lastTileSizeRow(bndrows, i);
+ lastRowRatio = paddingRatio;
+ paddingRatio = (float)lr/i;
+ //cout << "Trying row tile size " << i << ". Padding Ratio: " <<
+ // paddingRatio << "LR: " << lr << ".\n";
+ *tileSizeRows = i;
+ paddingRows = i-lr;
+ cout.flush();
+ }
+ if (lastRowRatio>paddingRatio) {
+ (*tileSizeRows)++;
+ lr = lastTileSizeRow(bndrows, *tileSizeRows);
+ paddingRows = (*tileSizeRows)-lr;
+ //cout << "IF:::::Trying row tile size " << *tileSizeRows <<
+ // " Padding Ratio: " << paddingRatio << " BndRows: " << bndrows << " LR: " << lr << ".\n";
+ }
+ }
+
+ else {
+ cout << "#######################HERE#################" << endl;
+ cout.flush();
+ *tileSizeRows = nrows;
+ bndrows = computeNumBoundaries(nrows, *tileSizeRows);
+ lr = lastTileSizeRow(bndrows, *tileSizeRows);
+ //cout << "ELSE::::: Padding Ratio: " << paddingRatio << "LR: " << lr << ".\n";
+ }
+
+
+ cout << "Tile Size Rows: " << *tileSizeRows << endl;cout.flush();
+ cout << "Padding Rows: " << paddingRows << " LR: " << lr << endl;cout.flush();
+ cout << "Num Tiles: " << bndrows - 1 << endl; cout.flush();
+
+
+ bndcols = computeNumBoundaries(ncols, *tileSizeCols);
+ /* optimize tileSizeCols */
+ *tileSizeCols = baseTileSize;
+ if (*tileSizeCols < ncols) {
+ bndcols = computeNumBoundaries(ncols, *tileSizeCols);
+ lc = lastTileSizeCol(bndcols, *tileSizeCols);
+ paddingRatio = (float)lc/(*tileSizeCols);
+ paddingCols = (*tileSizeCols)-lc;
+ //cout << "Trying col tile size " << tileSizeCols << ". Padding Ratio: " <<
+ // paddingRatio << ".\n";
+ for (int j = *tileSizeCols; paddingRatio < .98 ;j--) {
+ bndcols = computeNumBoundaries(ncols, j);
+ lc = lastTileSizeCol(bndcols, j);
+ paddingRatio = (float)lc/j;
+ //cout << "Trying col tile size " << j << ". Padding Ratio: " <<
+ // paddingRatio << ".\n";
+ *tileSizeCols = j;
+ paddingCols = j-lc;
+ }
+ }
+
+ else {
+ *tileSizeCols = ncols;
+ bndcols = computeNumBoundaries(ncols, *tileSizeCols);
+ lc = lastTileSizeCol(bndcols, *tileSizeCols);
+ }
+
+ /* set GLOBALS */
+
+ nrowsPad = nrows+paddingRows;
+ ncolsPad = ncols+paddingCols;
+
+ //nrowsPad = nrows;
+ //ncolsPad = ncols;
+
+ char memBuf[100];
+ formatNumber(memBuf,(*tileSizeRows)*(*tileSizeCols));
+ *stats << "initializeTileSize:: Final tile size = (" << *tileSizeRows << "x"
+ << *tileSizeCols << ") = " << memBuf << " \n";
+
+ bndrows = computeNumBoundaries(nrowsPad, *tileSizeRows);
+ bndcols = computeNumBoundaries(ncolsPad, *tileSizeCols);
+ *stats << "initializeTileSize::Bnd rows=" << bndrows <<
+ ", bnd cols=" << bndcols << "\n"; stats->flush();
+
+ cout << "Padding " << nrowsPad << " x " << ncolsPad << endl;cout.flush();
+
+ int bndPerTile = 2*(*tileSizeRows-1) + 2*(*tileSizeCols-1);
+ int numTiles = (bndrows-1)*(bndcols-1);
+ cout << "Col: " << bndcols << " Row: " << bndrows << " tiles: " << numTiles
+ << endl;cout.flush();
+ int b2bSize = bndPerTile*bndPerTile*numTiles*sizeof(distanceType);
+
+ char buf [100] = "";
+ formatNumber(buf, b2bSize);
+
+ cout << "initializeTileSize:: estimated b2bstream size = " << buf <<
+ endl;
+ *stats << "initializeTileSize:: estimated b2bstream size = " << buf <<
+ endl;
+
+}
+
+
+/************************************************************/
+/*
+ Computes either the number of boundary rows or columns in a grid
+ depending on the input.
+*/
+dimension_type
+computeNumBoundaries(dimension_type dIn, int tsIn) {
+ assert(tsIn > 1);
+
+ // dimension_type variable for return and adjusted values for tileSize and
+ // number of rows or columns.
+ dimension_type dOut, tsAdj, dAdj;
+ dAdj = dIn - 1;
+ tsAdj= tsIn - 1;
+
+
+ dOut = (dimension_type)ceil(((double)dAdj)/tsAdj) + 1;
+ return dOut;
+}
+
+
+/************************************************************/
+/*
+ Computes the size of the last tile (which might be of abnormal size)
+ before padding is applied. This is used to compute the padding ratio
+ which defines tile size and padding required
+*/
+dimension_type
+lastTileSizeRow(dimension_type d, int trIn) {
+ dimension_type secondToLast = (d-2)*(trIn-1) + 1;
+ dimension_type rowSize = nrows - secondToLast + 1;
+ return rowSize;
+}
+
+
+/*
+ Computes the size of the last tile (which might be of abnormal size)
+ before padding is applied. This is used to compute the padding ratio
+ which defines tile size and padding required
+*/
+/************************************************************/
+dimension_type
+lastTileSizeCol(dimension_type d, int tcIn) {
+
+ dimension_type secondToLast = (d-2)*(tcIn-1) + 1;
+ dimension_type colSize = ncols - secondToLast + 1;
+ return colSize;
+}
Added: grass-addons/raster/r.terracost/boundary.h
===================================================================
--- grass-addons/raster/r.terracost/boundary.h (rev 0)
+++ grass-addons/raster/r.terracost/boundary.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,891 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef __boundary_h
+#define __boundary_h
+
+#include <grass/iostream/ami.h>
+
+#include "types.h"
+#include "common.h"
+#include "input.h"
+#include "distanceType.h"
+#include "sortutils.h"
+
+#include <math.h>
+#include <assert.h>
+
+#define BND_ARRAY 0
+#define BND_STREAM 1
+
+//controls print statements
+//#define DEBUG_BND
+
+#define CHECK_AE(ae,stream) \
+if((ae) != AMI_ERROR_NO_ERROR) { \
+ cerr << "ami error at " << __FILE__ << ":" << __LINE__ << endl; \
+ cerr << "ae=" << ami_str_error[(ae)] << endl; \
+ cerr << "path=" << (stream)->name() << endl; \
+ assert(0); \
+ exit(1); \
+}
+
+
+size_t memForNormalDijkstra(dimension_type rows, dimension_type cols);
+
+/* sets tileSizeRows, tileSizeCols, nrowsPad, ncolsPad given the
+ memory to be used by a tile; the size of a tile is chosen so that
+ a tile uses at most maxmem memory; in order that boundary tiles
+ have same size as internal tiles we pad the grid we extra rows and
+ columns; the size of the grid is thus (nrowsPad, ncolsPad) */
+void initializeTileSize(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ size_t maxmem);
+
+void initializeTileSize(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ int numTiles);
+
+void optimizeTileSizeUser(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ int baseSizeRows, int baseSizeCols,
+ int tileRows, int tileCols);
+
+void optimizeTileSize(dimension_type *tileSizeRows,
+ dimension_type *tileSizeCols,
+ int baseTileSize);
+
+
+/* Computes either the number of boundary rows or columns in a grid
+ depending on the input.*/
+dimension_type computeNumBoundaries(dimension_type dIn, int tsIn);
+
+dimension_type lastTileSizeRow(dimension_type d, int trIn);
+dimension_type lastTileSizeCol(dimension_type d, int tcIn);
+
+/* A structure that handles the boundary points of a grid; boundary
+ points are the points on the boundary of the subgrids (tile); The
+ points stored in the structure are of the type CostSourceType (if
+ mode==ARRAY) or ijCostType (if mode==STR).
+
+ If the size of the grid is N and the size of a tile is R, there are
+ order N/sqrt(R) boundary points.
+
+ The structure can work in one of two modes: it stores the boundary
+ points in an array in internal memory (BND_ARRAY mode), or, it
+ stores the boundary points in a stream on disk (BND_STREAM mode).
+
+ The mode is chosen by the structure depending on how much memory is
+ available: if there is enough nemory available to store the
+ boundary the mode is set to BND_ARRAY; otherwise it is set to
+ BND_STREAM
+
+*/
+
+template <class T>
+class BoundaryType {
+
+ /*
+ GLOBALLY DEFINED
+ dimension_tye nrows, ncols, nrowsPad, ncolsPad;
+
+ Size of the entire grid before and after padding.
+ */
+
+
+ /* the number of boundary rows/columns in the grid */
+ dimension_type bndrows, bndcols;
+
+ /* the number of boundary points in the structure */
+ int size;
+
+ /* the dimension of a tile */
+ dimension_type tileSizeRows, tileSizeCols;
+
+ int mode; /* mode can be BND_ARRAY or BND_STREAM */
+ AMI_STREAM< ijCostType<T> > *bndstr;
+ T ** bndGridRows, ** bndGridCols;
+
+ int isSorted;
+
+
+ protected:
+ int isIBoundary(dimension_type i) const;
+
+ int isJBoundary(dimension_type j) const;
+
+ dimension_type iToArrayBnd(dimension_type i) const;
+ dimension_type jToArrayBnd(dimension_type j) const;
+
+ //sorts bnd structure if structure is a stream
+ void sortBnd();
+
+ void decBnd();
+ public:
+
+ /* allocates a BoundaryType structure and finds the optimal tile
+ size; it also sets the mode as BND_ARRAY or BND_STREAM.
+ rows and cols are the tile size */
+ BoundaryType(dimension_type rows, dimension_type cols, size_t mem);
+ BoundaryType(dimension_type rows, dimension_type cols, int inMode);
+ BoundaryType(dimension_type rows, dimension_type cols, const char* bndPath);
+
+ ~BoundaryType();
+
+ void initialize(const T val);
+
+ dimension_type lastTileSizeRow(dimension_type d, int trIn);
+ dimension_type lastTileSizeCol(dimension_type d, int tcIn);
+
+ void markAsSorted() { isSorted = 1; }
+
+ //point (i,j) should be a boundary point;insert cost of point (i,j)
+ //into the structure
+
+ void insert(ijCostType<T> x);
+
+ /*
+ point (i,j) should be a boundary point; returns ijCostType stored
+ at point (i,j); assume space for r is allocated
+ */
+ void get(dimension_type i, dimension_type j, ijCostType<T> *r);
+ int canGetFast(dim_t i, dim_t j) const { return mode == BND_ARRAY; };
+
+ //return nb of boundaries stored in the structure
+ int getSize();
+
+ dimension_type getTileSizeRows();
+
+ dimension_type getTileSizeCols();
+
+ dimension_type getBndrows();
+
+ dimension_type getBndcols();
+
+ int isBoundary(dimension_type i, dimension_type j) const;
+
+ /* Hasn't been written yet, but should print something */
+ void print();
+
+ off_t length(); /* number of objects in boundary */
+
+ //checks points on an input stream against boundary points
+ // exit if error is found
+ void testBoundary(AMI_STREAM< ijCostType<T> >* debugstr);
+
+ //how much memory does it use?
+ long memoryUsage() {
+ if (mode== BND_ARRAY) {
+ return (bndrows*(ncolsPad)+bndcols*(nrowsPad))*sizeof(T);
+ } else {
+ return 0;
+ }
+ }
+
+ /* write the boundary to a file */
+ void serialize(const char* path) {
+
+ if (mode != BND_ARRAY) {
+ cerr << "Method supported only for BND_ARRAY\n";
+ exit(1);
+ }
+ AMI_err ae;
+ AMI_STREAM<T> *stream;
+
+ *stats << "serializing boundary: " << path << endl;
+
+ stream = new AMI_STREAM<T>(path, AMI_WRITE_STREAM);
+ stream->persist(PERSIST_PERSISTENT);
+
+ //first write out size
+ ae = stream->write_item(size);
+ CHECK_AE(ae, stream);
+
+ //save rows
+ assert(bndGridRows );
+ for (int i=0; i< bndrows; i++) {
+ assert(bndGridRows[i]);
+ for (int j=0; j < ncolsPad; j++) {
+ ae = stream->write_item(bndGridRows[i][j]);
+ CHECK_AE(ae, stream);
+ }
+ }
+ //save cols
+ assert(bndGridCols);
+ for (int i=0; i< bndcols; i++) {
+ assert(bndGridCols[i]);
+ for (int j=0; j< nrowsPad; j++) {
+ ae = stream->write_item(bndGridCols[i][j]);
+ CHECK_AE(ae, stream);
+ }
+ }
+
+ delete stream;
+ }
+
+ //reconstruct from file */
+ void reconstruct(const char *path) {
+
+
+ AMI_err ae;
+ AMI_STREAM<T> *stream;
+
+ stream = new AMI_STREAM<T>(path, AMI_READ_STREAM);
+ stream->persist(PERSIST_PERSISTENT);
+
+ assert(stream->stream_len() == (bndrows*ncolsPad + bndcols*nrowsPad + 1));
+
+ //first read out size
+ T* tmp;
+ ae = stream->read_item(&tmp);
+ CHECK_AE(ae, stream);
+ size = (int) (*tmp);
+
+ //read rows
+ assert(bndGridRows );
+ for (int i=0; i< bndrows; i++) {
+ assert(bndGridRows[i]);
+ for (int j=0; j < ncolsPad; j++) {
+ ae = stream->read_item(&tmp);
+ bndGridRows[i][j] = *tmp;
+ CHECK_AE(ae, stream);
+ }
+ }
+
+ //read cols
+ assert(bndGridCols);
+ for (int i=0; i< bndcols; i++) {
+ assert(bndGridCols[i]);
+ for (int j=0; j< nrowsPad; j++) {
+ ae = stream->read_item(&tmp);
+ bndGridCols[i][j] = *tmp;
+ CHECK_AE(ae, stream);
+ }
+ }
+
+ delete stream;
+ };
+
+
+};
+
+
+
+
+
+
+
+/* ************************************************************ */
+/* allocates a BoundaryType structure based on a previously computed
+ optimal size; it also sets the mode as BND_ARRAY or BND_STREAM
+ depending on mem */
+template <class T>
+BoundaryType<T>::BoundaryType(dimension_type rows, dimension_type cols,
+ size_t mem) {
+ bndstr = NULL;
+
+ tileSizeRows = rows;
+ tileSizeCols = cols;
+ bndrows = computeNumBoundaries(nrowsPad, tileSizeRows);
+ bndcols = computeNumBoundaries(ncolsPad, tileSizeCols);
+
+ size = 0;
+
+ //number of boundray points
+ long nb;
+ nb = bndrows*(ncolsPad)+bndcols*(nrowsPad);
+
+ /*
+ if the boundarys will fit into the amount of memory specified by
+ the mem parameter, then they will be stored as arrays, otherwise
+ they will be stored as AMI_STREAMs
+ */
+
+ if (nb*sizeof(T) <= mem) {
+ mode = BND_ARRAY;
+ }
+ else {
+ mode = BND_STREAM;
+ }
+
+ /* Declare the array/stream to store values*/
+ decBnd();
+}
+
+
+
+
+/* ************************************************************ */
+/* allocates a BoundaryType structure and finds the optimal tile size;
+ it also sets the mode as BND_ARRAY or BND_STREAM depending on the
+ inMode.
+*/
+template <class T>
+BoundaryType<T>::BoundaryType(dimension_type rows, dimension_type cols,
+ int inMode) {
+ bndstr = NULL;
+
+ tileSizeRows = rows;
+ tileSizeCols = cols;
+ bndrows = computeNumBoundaries(nrowsPad, tileSizeRows);
+ bndcols = computeNumBoundaries(ncolsPad, tileSizeCols);
+ size = 0;
+ //user can set mode
+ mode = inMode;
+
+ /* Declare the array/stream to store values*/
+ decBnd();
+}
+
+/* constructor set to stream mode where we can specify which stream is
+ to be used. Used in parallel implementation.*/
+template <class T>
+BoundaryType<T>::BoundaryType(dimension_type rows, dimension_type cols,
+ const char* bndPath) {
+
+ tileSizeRows = rows;
+ tileSizeCols = cols;
+ bndrows = computeNumBoundaries(nrowsPad, tileSizeRows);
+ bndcols = computeNumBoundaries(ncolsPad, tileSizeCols);
+
+ mode = BND_STREAM;
+ bndstr = new AMI_STREAM< ijCostType<T> >(bndPath, AMI_READ_STREAM);
+ assert(bndstr);
+ size = bndstr->stream_len();
+ bndstr->persist(PERSIST_PERSISTENT); /* always persistent?? XXX -RW */
+
+ cerr << "BoundaryType: created from path " << bndPath << endl;
+}
+
+
+
+/* ************************************************************ */
+template <class T>
+BoundaryType<T>::~BoundaryType() {
+
+
+ switch (mode) {
+
+ case BND_ARRAY:
+ for (int i=0; i< bndcols; i++) {
+ delete [] bndGridCols[i];
+ }
+ delete [] bndGridCols;
+ for (int i=0; i< bndrows; i++) {
+ delete [] bndGridRows[i];
+ }
+ delete [] bndGridRows;
+ break;
+
+ case BND_STREAM:
+
+ delete bndstr;
+ break;
+ }
+
+}
+
+
+
+/* ************************************************************ */
+/*
+ declares the boundary array or the boundary AMI_STREAM depending
+ on the mode.
+*/
+template <class T>
+void
+BoundaryType<T>::decBnd() {
+
+ switch (mode) {
+
+ case BND_ARRAY:
+
+ cerr << "bndrows=" << bndrows << endl;
+ cerr << "bndcols=" << bndcols << endl;
+ cerr << "ncolsPad=" << ncolsPad << endl;
+ cerr << "nrowsPad=" << nrowsPad << endl;
+ cerr << "memory load = " <<
+ ( ( sizeof(T*) * (bndrows+bndcols) +
+ sizeof(T) * (ncolsPad * bndrows + nrowsPad * bndcols) ) / (1<<20) )
+ << " MB" << endl;
+
+ /* Constructs 2 arrays for storing boundary values one indexed i,j
+ the other indexed j,i */
+ bndGridRows = new T* [bndrows];
+ assert(bndGridRows );
+ for (int i=0; i< bndrows; i++) {
+ bndGridRows[i] = new T[ncolsPad];
+ assert(bndGridRows[i]);
+ }
+
+ bndGridCols = new T* [bndcols];
+ assert(bndGridCols);
+ for (int i=0; i< bndcols; i++) {
+ bndGridCols[i] = new T[nrowsPad];
+ assert(bndGridCols[i]);
+ }
+ break;
+
+ case BND_STREAM:
+ cout << "creating Boundary structure, stream mode.\n";
+ //cout << "step0: " << opt->step0 << endl; cout.flush();
+
+ /* the following condition should probably move to main.cc -RW */
+ /* the following check should be !RUN_S1 or some such... -RW XXX */
+ if (opt->runMode == RUN_S0) {
+ bndstr = new AMI_STREAM< ijCostType<T> >(resolvePath(opt->s0bnd));
+ } else {
+ bndstr = new AMI_STREAM< ijCostType<T> >();
+ }
+ assert(bndstr);
+ bndstr->persist(PERSIST_PERSISTENT); /* leaks temp files? XXX -RW */
+ break;
+ }
+}
+
+template <class T>
+void
+BoundaryType<T>::initialize(const T val) {
+
+ assert(mode == BND_ARRAY);
+ if(mode != BND_ARRAY) {
+ cerr << "invalid call" << endl;
+ exit(1);
+ }
+
+ for(int row=0; row<bndrows; row++) {
+ for(int col=0; col<ncolsPad; col++) {
+ bndGridRows[row][col] = val;
+ }
+ }
+ for(int col=0; col<bndcols; col++) {
+ for(int row=0; row<nrowsPad; row++) {
+ bndGridCols[col][row] = val;
+ }
+ }
+}
+
+
+/* ************************************************************ */
+template <class T>
+void
+BoundaryType<T>::insert(ijCostType<T> ct) {
+
+ switch (mode) {
+
+ case BND_STREAM:
+
+ /* just inserting can't work! (unless it's to just create the stream) XXX-RW */
+
+ AMI_err ae;
+ ae = bndstr->write_item(ct);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ isSorted = 0;
+ break;
+
+ case BND_ARRAY:
+ dimension_type oldI, oldJ;
+ dimension_type newI, newJ;
+
+ oldI = ct.getI();
+ oldJ = ct.getJ();
+ T x = ct.getCost();
+
+ if (!isIBoundary(oldI) && !isJBoundary(oldJ)) {
+ cout << "Boundary::insert::Boundary ERROR at (" << oldI << "," <<
+ oldJ << ")" << endl;
+ cout.flush();
+ *stats << "Boundary::insert::Boundary ERROR at (" << oldI << "," <<
+ oldJ << ")" << endl;
+ stats->flush();
+ exit(0);
+ }
+
+ if (oldI == nrowsPad-1) {
+ newI = iToArrayBnd(oldI);
+ newJ = oldJ;
+#ifdef DEBUG_BND
+ cout << "insert " << ct << "at pos (" << newI << "," << newJ << ") 1\n";
+ cout.flush();
+#endif
+ assert(newI < bndrows);
+ bndGridRows[newI][newJ] = x;
+ }
+
+ // switch i and j here because bndGridCols is indexed [col][row]
+ if (oldJ == ncolsPad-1) {
+ newI = jToArrayBnd(oldJ);
+ newJ = oldI;
+#ifdef DEBUG_BND
+ cout << "insert " << ct << "at pos (" << newI << "," << newJ << ") 2\n";
+ cout.flush();
+#endif
+ assert(newI < bndcols);
+ bndGridCols[newI][newJ] = x;
+ }
+
+ if (isIBoundary(oldI) && oldI != nrowsPad-1) {
+ newI = iToArrayBnd(oldI);
+ newJ = oldJ;
+#ifdef DEBUG_BND
+ cout << "insert " << ct << "at pos (" << newI << "," << newJ << ") 3\n";
+ cout.flush();
+#endif
+ assert(newI < bndrows);
+ bndGridRows[newI][newJ] = x;
+ }
+
+ // switch i and j here because bndGridCols is indexed [col][row]
+ if (isJBoundary(oldJ) && oldJ != ncolsPad-1) {
+ newI = jToArrayBnd(oldJ);
+ newJ = oldI;
+#ifdef DEBUG_BND
+ cout << "insert " << ct << "at pos (" << newI << "," << newJ << ") 4\n";
+ cout.flush();
+#endif
+ assert(newI < bndcols);
+ bndGridCols[newI][newJ] = x;
+ }
+
+#ifndef NDEBUG
+ ijCostType<T> temp;
+ get(ct.getI(),ct.getJ(),&temp);
+ //assert(temp == ct);
+ if (!(temp == ct)) {
+ cout << "BoundaryType::insert " << ct << ", extract " << temp << endl;
+ exit(0);
+ }
+#endif
+ break;
+ }
+
+ size++;
+}
+
+
+
+
+
+/* ************************************************************ */
+//return 1 if (i,j) is on tile boundary
+template <class T>
+int
+BoundaryType<T>::isBoundary(dimension_type i, dimension_type j) const {
+ if (isIBoundary(i) || isJBoundary(j))
+ return 1;
+ return 0;
+}
+
+/* ************************************************************ */
+template <class T>
+int
+BoundaryType<T>::isIBoundary(dimension_type inI) const {
+ if (inI == 0 || inI % (tileSizeRows-1)==0 || inI==nrowsPad-1)
+ return 1;
+ return 0;
+}
+
+
+/* ************************************************************ */
+template <class T>
+int
+BoundaryType<T>::isJBoundary(dimension_type inJ) const {
+ if (inJ == 0 || inJ % (tileSizeCols-1)==0 || inJ==ncolsPad-1)
+ return 1;
+ return 0;
+}
+
+/* ************************************************************ */
+template <class T>
+int
+BoundaryType<T>::getSize() {
+ return size;
+}
+
+/* ************************************************************ */
+template <class T>
+dimension_type
+BoundaryType<T>::getTileSizeRows() {
+ return tileSizeRows;
+}
+
+/* ************************************************************ */
+template <class T>
+dimension_type
+BoundaryType<T>::getTileSizeCols() {
+ return tileSizeCols;
+}
+
+/* ************************************************************ */
+template <class T>
+dimension_type
+BoundaryType<T>::getBndrows() {
+ return bndrows;
+}
+
+/* ************************************************************ */
+template <class T>
+dimension_type
+BoundaryType<T>::getBndcols() {
+ return bndcols;
+}
+
+/* ************************************************************ */
+template <class T>
+void
+BoundaryType<T>::sortBnd() {
+ assert(!isSorted); /* -RW */
+ MinIOCostCompareType<T> sortFun = MinIOCostCompareType<T>(); /* ij compare -RW */
+ sortFun.setTileSize(tileSizeRows, tileSizeCols);
+ assert(mode == BND_STREAM);
+ stats->recordLength("BoundaryType: Sorting boundary stream...", bndstr);
+ sort(&bndstr, sortFun);
+ stats->recordLength("BoundaryType: Sorting boundary stream... done", bndstr);
+ isSorted = 1;
+}
+
+
+/* ************************************************************ */
+/*
+ point (i,j) should be a boundary point; returns ijCostType stored
+ at point (i,j); assume r is allocated
+*/
+template <class T>
+void
+BoundaryType<T>::get(dimension_type i, dimension_type j, ijCostType<T> *r) {
+
+ AMI_err ae;
+
+ switch (mode) {
+
+ case BND_STREAM:
+ if (!isSorted){
+ sortBnd();
+ }
+ ijCostType<T> *tmp;
+ assert(isBoundary(i,j));
+ assert(bndstr);
+ if (isIBoundary(i)) {
+ //stream offset where this bnd point is located
+ int index = ((i/(tileSizeRows-1))*ncolsPad +
+ (i/(tileSizeRows-1))*(tileSizeRows-2)*bndcols + j);
+ //cout << "I Bnd Stream: " << bndstr->stream_len() << " Index: " <<
+ // index << "\n"; cout.flush();
+ //cout << "BndLen: " << bndstr->stream_len() << endl;cout.flush();
+
+ //cout << "BndStrLen: " << bndstr->stream_len() << " index: " << index
+ // << " (" << i << "," << j << ")" << endl; cout.flush();
+
+ assert(bndstr->stream_len() > index);
+ ae = bndstr->seek(index);
+ assert(ae==AMI_ERROR_NO_ERROR);
+
+ ae = bndstr->read_item(&tmp);
+ assert(ae==AMI_ERROR_NO_ERROR);
+ } else {
+ //stream offset where this bnd point is located
+ int index = (i/(tileSizeRows-1)+1)*ncolsPad +
+ (i/(tileSizeRows-1))*(tileSizeRows-2)*bndcols +
+ (j/(tileSizeCols-1))*(tileSizeRows-2) +
+ i%(tileSizeRows-1)-1;
+
+ //cout << "J Bnd Stream: " << bndstr->stream_len() << " Index: " <<
+ // index << "\n"; cout.flush();
+
+ assert(bndstr->stream_len() > index);
+ ae = bndstr->seek(index);
+ assert(ae == AMI_ERROR_NO_ERROR);
+
+ ae = bndstr->read_item(&tmp);
+ assert(ae==AMI_ERROR_NO_ERROR);
+ }
+ *r = ijCostType<T>(*tmp);
+
+ /* debug: error */
+ if(r->getI() != i || r->getJ() != j) {
+ fprintf(stderr, "ij mismatch; r.i=%d r.j=%d i=%d j=%d\n",
+ r->getI(), r->getJ(), i, j);
+ }
+ assert(r->getI() == i && r->getJ() == j);
+ break;
+
+ case BND_ARRAY:
+ int row_i, row_j;
+ assert(isBoundary(i,j));
+
+ if (i == nrowsPad-1) {
+ row_i= bndrows - 1;
+ row_j= j;
+ *r = ijCostType<T>(i,j, bndGridRows[row_i][row_j]);
+ }
+
+ // switch i and j here because bndGridCols is indexed [col][row]
+ else if (j == ncolsPad-1) {
+ row_i= bndcols - 1;
+ row_j= i;
+ *r = ijCostType<T>(i,j, bndGridCols[row_i][row_j]);
+ }
+
+ else if (isIBoundary(i)) {
+ row_i = iToArrayBnd(i);
+ row_j = j;
+ *r = ijCostType<T>(i,j, bndGridRows[row_i][row_j]);
+ }
+
+ // switch i and j here because bndGridCols is indexed [col][row]
+ else if (isJBoundary(j)) {
+ row_i = jToArrayBnd(j);
+ row_j = i;
+ *r = ijCostType<T>(i,j, bndGridCols[row_i][row_j]);
+ }
+
+ assert(r->getI() == i && r->getJ() == j);
+ break;
+ }
+}
+
+
+
+/* ************************************************************ */
+template <class T>
+dimension_type
+BoundaryType<T>::iToArrayBnd(dimension_type i) const {
+ assert(isIBoundary(i));
+
+ dimension_type row_i;
+
+ if (tileSizeRows == 2)
+ return i;
+
+ if (i == 0)
+ return 0;
+
+ if (i == nrowsPad-1) {
+ row_i= bndrows-1;
+ return row_i;
+ }
+
+ if (isIBoundary(i)) {
+ row_i = computeNumBoundaries(i, tileSizeRows) - 1;
+ return row_i;
+ }
+
+ printf("ERROR: Shouldn't have made it here BoundaryType::iToArrayBnd");
+ exit(1);
+ return 0;
+}
+
+
+/* ************************************************************ */
+template <class T>
+dimension_type
+BoundaryType<T>::jToArrayBnd(dimension_type j) const {
+ assert(isJBoundary(j));
+
+ dimension_type col_j;
+
+ if (tileSizeCols == 2)
+ return j;
+
+ if (j == 0)
+ return 0;
+
+ if (j == ncolsPad-1) {
+ col_j = bndcols-1;
+ return col_j;
+ }
+
+ if (isJBoundary(j)) {
+ col_j = computeNumBoundaries(j, tileSizeCols) - 1;
+ return col_j;
+ }
+
+ printf("ERROR: Shouldn't have made it here BoundaryType::iToArrayBnd");
+ assert(0);
+ return 0;
+}
+
+
+/* ************************************************************ */
+template <class T>
+void
+BoundaryType<T>::print() {
+ ijCostType<T> out;
+ for (int i=0; i<nrowsPad; i++) {
+ for (int j=0; j<ncolsPad; j++) {
+ if (isBoundary(i,j)) {
+ get(i,j,&out);
+ *stats << out;
+ }
+ else {
+ *stats << " " ;
+ }
+ }
+ *stats << endl;
+ }
+}
+
+
+/* ************************************************************ */
+template <class T>
+off_t
+BoundaryType<T>::length() {
+ switch (mode) {
+ case BND_ARRAY:
+ assert(0);
+ break;
+ case BND_STREAM:
+ return bndstr->tell();
+ break;
+ }
+ assert(0);
+ return -1;
+}
+
+
+/* ************************************************************ */
+//checks points on an input stream against boundary points
+// exit if error is found
+template <class T>
+void
+BoundaryType<T>::testBoundary(AMI_STREAM< ijCostType<T> >* debugstr) {
+
+ cout << "testing boundary dstr\n"; cout.flush();
+
+ AMI_err ae;
+ ijCostType<T> *in, temp;
+ assert(debugstr);
+ assert(debugstr->stream_len() == nrowsPad*ncolsPad);
+ ae = debugstr->seek(0);
+ assert(ae == AMI_ERROR_NO_ERROR);
+
+ for (int i = 0; i < nrowsPad; i++) {
+ for (int j = 0; j < ncolsPad; j++) {
+ ae = debugstr->read_item(&in);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ if (isBoundary(i,j)) {
+ get(i,j, &temp);
+ if(in->getCost() != temp.getCost())
+ cout << "Cost Mismatch! Real Value: " << *in << "Boundary Value: " <<
+ temp->getCost() << "\n";
+ }
+ }
+ }
+}
+
+#endif
Property changes on: grass-addons/raster/r.terracost/boundary.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/boundaryMgr.h
===================================================================
--- grass-addons/raster/r.terracost/boundaryMgr.h (rev 0)
+++ grass-addons/raster/r.terracost/boundaryMgr.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,423 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <grass/iostream/ami.h>
+#include "input.h"
+#include "genericTile.h"
+
+/* rajiv wickremesinghe 2005 */
+
+/* NB: in this file, a boundary tile is generally the left and top sides ONLY */
+
+
+
+
+/* template <class T> */
+/* class BoundaryStreamObj { */
+/* T data; */
+/* public: */
+/* BoundaryStreamObj(const ijCostType<T> &x) { data = x.getCost(); }; */
+/* }; */
+
+
+#define BMGR_DEBUG if(0)
+
+#define CHECK_AE(ae,stream) \
+if((ae) != AMI_ERROR_NO_ERROR) { \
+ cerr << "ami error at " << __FILE__ << ":" << __LINE__ << endl; \
+ cerr << "ae=" << ami_str_error[(ae)] << endl; \
+ cerr << "path=" << (stream)->name() << endl; \
+ assert(0); \
+ exit(1); \
+}
+
+
+#define IS_BOUNDARY(row,col) ( assert(tsr), assert(tsc), \
+ ( ((row) % (tsr-1)) == 0) || ( ((col) % (tsc-1)) == 0) )
+
+/* ---------------------------------------------------------------------- */
+/* oversee boundary data structures
+ * handle the mapping from i,j to pos etc.
+ */
+
+template <class CST>
+class BoundaryMgr {
+ protected:
+ unsigned int T, R; /* size of tile (L,T) boundary, size of row */
+ unsigned int NB; /* size of whole boundary (plus padding) */
+ dim_t tsra, tsca; /* tsra=tsr-1 etc (tile size rows adjusted) */
+ dim_t trows, tcols; /* number of rows/cols of tiles */
+
+ public:
+ BoundaryMgr(dim_t tsr, dim_t tsc, dim_t nrows, dim_t ncols);
+ int getPos(dim_t i, dim_t j, int debug=0) const; /* map from grid pos to offset in linear arr */
+ void getIJ(int pos, dim_t *ip, dim_t *jp, int debug=0) const;
+ void selfcheck() const;
+
+ /* these two functions for backward compatibility.
+ * returns number of boundary rows/cols;
+ * i.e., 1 more than the number of tile rows/cols */
+ dim_t getBndRows() const { return trows+1; };
+ dim_t getBndCols() const { return tcols+1; };
+};
+
+
+/* ---------------------------------------------------------------------- */
+/*
+ * boundary that is fully stored in memory; supports random access
+ */
+template <class CST>
+class CachedBoundaryMgr : public BoundaryMgr<CST> {
+ CST *data;
+
+ public:
+ char debug;
+
+ CachedBoundaryMgr(dim_t tsr, dim_t tsc, dim_t nrows, dim_t ncols)
+ : BoundaryMgr<CST>(tsr, tsc, nrows, ncols) {
+ data = new CST [ this->NB ];
+ };
+ virtual ~CachedBoundaryMgr() { delete data; }
+
+ void initialize(const CST &val) {
+ for(int i=0; i< this->NB; i++) {
+ data[i] = val;
+ }
+ };
+
+ /* insert one item into the boundary */
+ void insert(const ijCostType<CST> &x) {
+#ifndef NDEBUG
+ if(debug == 'i') {
+ printf("BMGR%c %d\t%d\n", debug, x.getI(), x.getJ());
+ fflush(stdout);
+ }
+#endif
+ int pos = getPos(x.getI(), x.getJ());
+ //printf("BMGRi %d\t%d\n", x.getI(), x.getJ());
+ assert(pos < this->NB);
+ data[pos] = x.getCost();
+ };
+
+ const CST get(dim_t i, dim_t j) const {
+#ifndef NDEBUG
+ if(debug == 'g') {
+ printf("BMGR%c %d\t%d\n", debug, i, j);
+ fflush(stdout);
+ }
+#endif
+ int pos = this->getPos(i, j);
+ assert(pos < this->NB);
+ return data[pos];
+ };
+
+ /* how much memory it uses */
+ long memoryUsage() {
+ return this->NB * sizeof(CST);
+ }
+
+ /* write out the boundary to file */
+ void serialize(const char *path) {
+ AMI_err ae;
+ AMI_STREAM<CST> *stream;
+
+ *stats << "serializing boundary: " << path << endl;
+
+ stream = new AMI_STREAM<CST>(path, AMI_WRITE_STREAM);
+ stream->persist(PERSIST_PERSISTENT);
+
+ for(int i=0; i < this->NB; i++) {
+ ae = stream->write_item(data[i]);
+ CHECK_AE(ae,stream);
+ }
+ delete stream;
+ };
+
+ void reconstruct(const char *path) {
+ AMI_err ae;
+ AMI_STREAM<CST> *stream;
+
+ stream = new AMI_STREAM<CST>(path, AMI_READ_STREAM);
+ stream->persist(PERSIST_PERSISTENT);
+
+ for(int i=0; i < this->NB; i++) {
+ ae = stream->read_item(&data[i]);
+ CHECK_AE(ae,stream);
+ }
+ delete stream;
+ };
+
+};
+
+
+/* ---------------------------------------------------------------------- */
+/*
+ * boundary that is only written to disk. wrapper around cached version for now,
+ * but could be optimized. Note that the stream is only created if serialize() is called.
+ */
+
+template <class CST>
+class BoundaryWriter : public CachedBoundaryMgr<CST> {
+ char *path;
+
+ public:
+ BoundaryWriter(dim_t tsr, dim_t tsc, dim_t nrows, dim_t ncols, const char *pathin)
+ : CachedBoundaryMgr<CST>(tsr, tsc, nrows, ncols) {
+ path = strdup(pathin);
+ };
+ ~BoundaryWriter() { free(path); };
+ void serialize() { CachedBoundaryMgr<CST>::serialize(path); }
+
+ protected:
+ void reconstruct(const char *path) {};
+ const ijCostType<CST> & get(dim_t i, dim_t j) const {};
+};
+
+
+/* ---------------------------------------------------------------------- */
+/* reader, but only load a tile at a time (actually reads 3+)
+ */
+
+template <class CST>
+class BoundaryTileReader : public BoundaryMgr<CST> {
+ AMI_STREAM<CST> *stream;
+ CachedBoundaryMgr<CST> *cache; /* can use another mgr as a source */
+
+ public:
+ BoundaryTileReader(dim_t tsr, dim_t tsc, dim_t nrows, dim_t ncols,
+ const char *path) : BoundaryMgr<CST>(tsr, tsc, nrows, ncols) {
+ *stats << "BoundaryTileReader using " << path << endl;
+ stream = new AMI_STREAM<CST>(path, AMI_READ_STREAM);
+ cache = NULL;
+ };
+ BoundaryTileReader(CachedBoundaryMgr<CST> *cr) : BoundaryMgr<CST>(*cr) {
+ stream = NULL;
+ cache = cr;
+#ifndef NDEBUG
+ this->selfcheck();
+#endif
+ };
+
+ ~BoundaryTileReader() {
+ if(stream) delete stream;
+ };
+
+ /* read one tile, root at i,j */
+ void readTileBoundary(dim_t baseI, dim_t baseJ, genericTile<CST> *tile) {
+
+ BMGR_DEBUG fprintf(stderr, "readTileBoundary: (%d,%d)\n", baseI, baseJ);
+
+ if(cache) {
+ readTileBoundaryCache(baseI, baseJ, tile);
+ } else {
+ readTileBoundaryStream(baseI, baseJ, tile);
+ }
+ }
+
+ private:
+ void readTileBoundaryCache(dim_t baseI, dim_t baseJ, genericTile<CST> *tile) {
+
+/* cache->debug = 'g'; */
+
+ for(int i=0; i < this->tsra; i++) { /* left */
+ tile->put(i, 0, cache->get(baseI+i, baseJ+0));
+ }
+ for(int j=1; j < this->tsca; j++) { /* top */
+ tile->put(0, j, cache->get(baseI+0, baseJ+j));
+ }
+ for(int i=0; i < this->tsra; i++) { /* right */
+ tile->put(i, this->tsca, cache->get(baseI + i, baseJ + this->tsca));
+ }
+ for(int j=0; j <= this->tsca; j++) { /* bottom */
+ tile->put(this->tsra, j, cache->get(baseI + this->tsra, baseJ+j));
+ }
+
+/* cache->debug = 0; */
+
+ };
+
+ void readTileBoundaryStream(dim_t baseI, dim_t baseJ, genericTile<CST> *tile) {
+ AMI_err ae;
+ int n = this->tsca + this->tsra - 1; /* tile (boundary) size */
+ int n1 = n;
+ CST *item;
+ int pos;
+ int k=0; /* useful items read + no. of put()s*/
+
+ pos = this->getPos(baseI, baseJ);
+ BMGR_DEBUG fprintf(stderr, "reading tile from pos=%d\n", pos);
+ ae = stream->seek(pos);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ for(int i=0; i < this->tsra; i++) { /* left */
+ ae = stream->read_item(&item);
+ CHECK_AE(ae,stream);
+ k++;
+ tile->put(i, 0, *item);
+ }
+ for(int j=1; j < this->tsca; j++) { /* top */
+ ae = stream->read_item(&item);
+ CHECK_AE(ae,stream);
+ k++;
+ tile->put(0, j, *item);
+ }
+ assert(k == this->T);
+ for(int i=0; i < this->tsra; i++) { /* right */
+ ae = stream->read_item(&item);
+ CHECK_AE(ae,stream);
+ k++;
+ tile->put(i, this->tsca, *item);
+ }
+
+ ae = stream->seek(this->getPos(baseI + this->tsra, baseJ));
+ CHECK_AE(ae,stream);
+
+ { /* left bottom point (only need one cell; skip rest) */
+ ae = stream->read_item(&item);
+ CHECK_AE(ae,stream);
+ k++;
+ tile->put(this->tsra, 0, *item);
+/* for(int i=1; i<tsra; i++) { */
+/* ae = stream->read_item(&item); */
+/* CHECK_AE(ae,stream); */
+/* } */
+ }
+ ae = stream->seek(getPos(baseI + this->tsra, baseJ+1));
+ CHECK_AE(ae,stream);
+
+ for(int j=1; j < this->tsca; j++) { /* bottom */
+ ae = stream->read_item(&item);
+ CHECK_AE(ae,stream);
+ k++;
+ tile->put(this->tsra, j, *item);
+ }
+ { /* right bottom point (only need one cell; skip rest) */
+ ae = stream->read_item(&item);
+ CHECK_AE(ae,stream);
+ k++;
+ tile->put(this->tsra, this->tsca, *item);
+ }
+
+ assert(k == 2 * this->tsca + 2 * this->tsra);
+ };
+
+};
+
+
+/* ********************************************************************** */
+/* implementations */
+
+
+template <class CST>
+BoundaryMgr<CST>::BoundaryMgr(dim_t tsrin, dim_t tscin, dim_t nrows, dim_t ncols) {
+ tsca = tscin - 1;
+ tsra = tsrin - 1;
+
+ tcols = (ncols-1) / tsca; /* no. of (whole) tiles across */
+ assert(tcols * tsca == ncols - 1);
+ trows = (nrows-1) / tsra; /* no. of (whole) tiles down */
+ assert(trows * tsra == nrows - 1);
+
+ T = tsca + tsra - 1;
+ R = T * tcols + tsra;
+
+ NB = R * (trows + 1); /* yes, we waste a little space... */
+}
+
+/* note: we are returning an int here, in clase dim_t is too small. need another type... */
+/* mapping:
+ * for each tile - left side (tsra rows), top (tsca-1) cols;
+ * end of row (tsra rows) */
+template <class CST>
+int
+BoundaryMgr<CST>::getPos(dim_t i, dim_t j, int debug) const {
+ int tnum_i = i / tsra;
+ int tnum_j = j / tsca;
+ int tt_i = i % tsra;
+ int tt_j = j % tsca;
+ int t = (tt_j ? tsra + tt_j - 1: tt_i);
+ int pos = tnum_i * R + tnum_j * T + t;
+
+#ifndef NDEBUG
+ if(debug) {
+ fprintf(stderr, "getPos:\n");
+ fprintf(stderr, " ts{r,c}a=%d,%d\n", tsra, tsca);
+ fprintf(stderr, " R=%d T=%d\n", R, T);
+ fprintf(stderr, " tnum=%d,%d\n", tnum_i, tnum_j);
+ fprintf(stderr, " tt=%d,%d\n", tt_i, tt_j);
+ fprintf(stderr, " t=%d\n", t);
+ }
+#endif
+
+ return pos;
+}
+
+template <class CST>
+void
+BoundaryMgr<CST>::getIJ(int pos, dim_t *ip, dim_t *jp, int debug) const {
+ int i, j;
+
+ int tnum_i = pos / R;
+ int rpos = (pos % R);
+ int tnum_j = rpos / T;
+ int tpos = rpos % T;
+ if(tpos >= tsra) {
+ i = 0;
+ j = tpos - tsra + 1;
+ } else {
+ i = tpos;
+ j = 0;
+ }
+
+#ifndef NDEBUG
+ if(debug) {
+ fprintf(stderr, "getIJ:\n");
+ fprintf(stderr, " ts{r,c}a=%d,%d\n", tsra, tsca);
+ fprintf(stderr, " R=%d T=%d\n", R, T);
+ fprintf(stderr, " tnum=%d,%d\n", tnum_i, tnum_j);
+ fprintf(stderr, " tt=%d,%d\n", i, j);
+ }
+#endif
+
+ i += tnum_i * tsra;
+ j += tnum_j * tsca;
+ *ip = i;
+ *jp = j;
+}
+
+template <class CST>
+void
+BoundaryMgr<CST>::selfcheck() const {
+ dim_t vi, vj;
+
+ fprintf(stderr, "boundaryMgr: selfcheck...\n");
+ fprintf(stderr, "boundary rows,cols=%d,%d\n", trows, tcols);
+ for(int p=0; p<NB; p++) {
+ getIJ(p, &vi, &vj);
+ int pos = getPos(vi, vj);
+ //printf("BMGRC %d\t%d\n", vi, vj);
+ if(p != pos) {
+ fprintf(stderr, "p=%d; pos=%d\n", p, pos);
+ fprintf(stderr, "vi,vj=%d,%d\n", vi, vj);
+ getIJ(p, &vi, &vj, 1);
+ getPos(vi, vj, 1);
+ assert(p == pos);
+ }
+ }
+ fprintf(stderr, "boundaryMgr: selfcheck... OK\n");
+}
+
+/* ********************************************************************** */
Property changes on: grass-addons/raster/r.terracost/boundaryMgr.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/boundarySort.cc
===================================================================
--- grass-addons/raster/r.terracost/boundarySort.cc (rev 0)
+++ grass-addons/raster/r.terracost/boundarySort.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,125 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+/*
+ * sort boundary stream
+ *
+ * rajiv wickremesinghe 2005
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <grass/iostream/ami.h>
+
+#include "input.h"
+#include "config.h"
+#include "sortutils.h"
+
+void
+usage() {
+ fprintf(stderr, "boudarySort [options]\n"
+ "-h this help"
+ "-i input boundary stream"
+ "-o output sorted stream (defaults to same as -i"
+ "-c config file name");
+
+}
+
+int
+main(int argc, char **argv) {
+ char *stream_name=NULL;
+ char *config_file=NULL;
+ char *sorted_name=NULL;
+ AMI_STREAM< ijCostType<costSourceType> > *bndstr;
+ int ch;
+
+ while ((ch = getopt(argc, argv, "ho:i:c:")) != -1) {
+ switch (ch) {
+ case 'i':
+ stream_name = strdup(optarg);
+ break;
+ case 'o':
+ sorted_name = strdup(optarg);
+ break;
+ case 'c':
+ config_file = strdup(optarg);
+ break;
+ case 'h':
+ default:
+ usage();
+ exit(0);
+ }
+ }
+
+ if(!config_file || !stream_name) {
+ usage();
+ exit(1);
+ }
+ if(! sorted_name) {
+ sorted_name = stream_name;
+ }
+
+ readConfigFile(config_file);
+ stats = new statsRecorder("stats.out");
+
+ bndstr = new AMI_STREAM< ijCostType<costSourceType> >(stream_name);
+ assert(bndstr);
+ bndstr->persist(PERSIST_PERSISTENT);
+
+ MinIOCostCompareType<costSourceType> sortFun = MinIOCostCompareType<costSourceType>();
+ sortFun.setTileSize(tsr, tsc);
+
+ sort(&bndstr, sortFun);
+
+ const char *new_name = bndstr->name();
+ if(strcmp(new_name, sorted_name) == 0) {
+ fprintf(stderr, "output in %s\n", sorted_name);
+ goto done;
+ }
+ fprintf(stderr, "trying to rename %s to %s\n", new_name, sorted_name);
+
+ // try to rename
+ if(rename(new_name, sorted_name) == 0) { // success
+ fprintf(stderr, "output renamed to %s\n", sorted_name);
+ goto done;
+ }
+ perror("rename failed");
+
+ // rename failed; copy the file
+ {
+ fprintf(stderr, "trying to copy\n");
+ char buf[BUFSIZ];
+ sprintf(buf, "/bin/cp \"%s\" \"%s\"", new_name, sorted_name);
+ int status = system(buf);
+ if(WIFEXITED(status)) {
+ if(WEXITSTATUS(status) == 0) {
+ fprintf(stderr, "output copied to %s\n", sorted_name);
+ goto done;
+ }
+ }
+ }
+
+ fprintf(stderr, "boundarySort: Failed!!!\n");
+ exit(1);
+
+ done:
+ return 0;
+}
Added: grass-addons/raster/r.terracost/common.cc
===================================================================
--- grass-addons/raster/r.terracost/common.cc (rev 0)
+++ grass-addons/raster/r.terracost/common.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,62 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <ctype.h>
+
+#include <ostream>
+#include <iostream>
+using namespace std;
+
+#include "types.h"
+#include "common.h"
+
+
+/* globals */
+statsRecorder *stats = NULL;
+userOptions *opt = NULL;
+
+
+const char *
+resolvePath(const char *name) {
+ static char buf[BUFSIZ];
+ static char *vtmpdir = NULL;
+
+ // we should probably save this, but reload each time for now...
+ //if(!vtmpdir) {
+ if(!(vtmpdir = getenv(VTMPDIR))) {
+ fprintf(stderr, "%s: environment not set\n", VTMPDIR);
+ exit(1);
+ }
+ //}
+
+ if(name[0] == '/') { // absolute path
+ strcpy(buf, name);
+ } else { // relative path - use VTMPDIR
+ strcpy(buf, vtmpdir);
+ int len = strlen(buf);
+ // remove trailing slashes
+ while(len > 0 && buf[len - 1] == '/') {
+ buf[--len] = '\0';
+ }
+ strcat(buf, "/");
+ strcat(buf, name);
+ }
+
+ return buf;
+}
Added: grass-addons/raster/r.terracost/common.h
===================================================================
--- grass-addons/raster/r.terracost/common.h (rev 0)
+++ grass-addons/raster/r.terracost/common.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,73 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <sys/types.h>
+#include <iostream>
+
+#include "stats.h"
+#include "option.h"
+#include "types.h"
+#include "config.h" /* for convenience */
+
+extern "C" {
+#include <grass/gis.h>
+}
+
+using namespace std;
+
+
+//#define VTMPDIR "/var/tmp/" USER "/"
+#ifndef USER
+#define USER "user"
+#endif
+
+//#define VTMPDIR "/var/tmp/gis/" USER "/"
+#define VTMPDIR "VTMPDIR"
+
+
+extern statsRecorder *stats; /* stats file */
+extern userOptions *opt; /* command-line options */
+
+
+
+template<class T>
+void
+printStream(AMI_STREAM<T> *s) {
+ T* elt;
+ AMI_err ae;
+ assert(s);
+ ae = s->seek(0);
+ assert(ae == AMI_ERROR_NO_ERROR);
+
+ while ((ae = s->read_item(&elt)) == AMI_ERROR_NO_ERROR) {
+ *stats << *elt << " ";
+ }
+ *stats << "\n";
+ ae = s->seek(0);
+ assert(ae == AMI_ERROR_NO_ERROR);
+};
+
+
+
+const char *resolvePath(const char *name);
+
+
+#endif
+
Property changes on: grass-addons/raster/r.terracost/common.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/config.cc
===================================================================
--- grass-addons/raster/r.terracost/config.cc (rev 0)
+++ grass-addons/raster/r.terracost/config.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,80 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "config.h"
+
+
+//struct Cell_head *region = NULL;
+dimension_type nrows = 0;
+dimension_type ncols = 0;
+dimension_type ncolsPad = 0;
+dimension_type tsr = 0;
+dimension_type tsc = 0;
+
+struct g_t g = { 0 };
+
+
+
+void readConfigFile (const char* fileName) {
+ FILE* fp;
+
+ if(g.inited) { return; }
+
+ fp = fopen(fileName, "r");
+ if (!fp) {
+ cout << "Cannot open config file: " << fileName << endl;;
+ assert(0);
+ exit(1);
+ }
+
+ char buf[20];
+ fscanf(fp,"%s %hd", buf, &nrows);
+ fscanf(fp,"%s %hd", buf, &ncols);
+ fscanf(fp,"%s %hd", buf, &nrowsPad);
+ fscanf(fp,"%s %hd", buf, &ncolsPad);
+ fscanf(fp,"%s %hd", buf, &g.ntiles);
+ fscanf(fp,"%s %hd", buf, &tsr);
+ fscanf(fp,"%s %hd", buf, &tsc);
+ fclose(fp);
+
+ g.inited = 1;
+}
+
+void writeConfigFile (const char* fileName) {
+ FILE* fp;
+
+ cout << "writing config file " << fileName << endl;
+ fp = fopen(fileName, "w");
+ if (!fp) {
+ cerr << "Cannot open config file: " << fileName << endl;;
+ assert(0);
+ exit(1);
+ }
+
+ fprintf(fp,"%s %hd ", "nrows", nrows);
+ fprintf(fp,"%s %hd ", "ncols", ncols);
+ fprintf(fp,"%s %hd ", "nrowsPad", nrowsPad);
+ fprintf(fp,"%s %hd ", "ncolsPad", ncolsPad);
+ fprintf(fp,"%s %hd ", "ntiles", g.ntiles);
+ fprintf(fp,"%s %hd ", "tsr", tsr);
+ fprintf(fp,"%s %hd ", "tsc", tsc);
+ fclose(fp);
+}
Added: grass-addons/raster/r.terracost/config.h
===================================================================
--- grass-addons/raster/r.terracost/config.h (rev 0)
+++ grass-addons/raster/r.terracost/config.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,38 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "types.h"
+
+extern struct g_t {
+ int inited; // must be first
+ /* other globals follow */
+ dimension_type ntiles;
+} g;
+
+
+/* do all these really need to be globals??? XXX-RW */
+extern dimension_type nrows, ncols, nrowsPad, ncolsPad, tsr, tsc;
+
+void readConfigFile (const char* fileName);
+void writeConfigFile (const char* fileName);
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/config.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/debug.h
===================================================================
--- grass-addons/raster/r.terracost/debug.h (rev 0)
+++ grass-addons/raster/r.terracost/debug.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,44 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <ostream>
+
+#include "common.h"
+#include "input.h"
+
+
+template<class T>
+void
+dump_file(const char *strname, const char *outfile, const T &dummy) {
+ AMI_STREAM<T> *str;
+
+ str = new AMI_STREAM<T>(strname, AMI_READ_STREAM);
+ str->persist(PERSIST_PERSISTENT);
+
+ ofstream os(outfile);
+
+ cerr << "dumping " << strname << " to " << outfile << endl;
+
+ T* item;
+ AMI_err err;
+ while((err = str->read_item(&item)) == AMI_ERROR_NO_ERROR) {
+ os << *item << endl;
+ }
+
+ os.close();
+ delete str;
+}
Property changes on: grass-addons/raster/r.terracost/debug.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/description.html
===================================================================
--- grass-addons/raster/r.terracost/description.html (rev 0)
+++ grass-addons/raster/r.terracost/description.html 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,34 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.terracost</em> is a scalable approach for computing least-cost-path surfaces
+on massive grid terrains. The module outperforms standard solutions as
+dataset size increases relative to available memory.
+
+<h2>REFERENCES</h2>
+
+<ul>
+<li>
+Hazel, T., Toma, L., Vahrenhold, J., and Wickremesinghe, R. 2006.
+<i>TerraCost: a versatile and scalable approach to computing least-cost-path
+surfaces for massive grid-based terrains.</i> In: Proceedings of the
+2006 ACM Symposium on Applied Computing (Dijon, France, April 23-27, 2006).
+SAC '06. ACM, New York, NY, 52-57. <br>
+[ <a href="http://delivery.acm.org/10.1145/1150000/1141290/p52-hazel.pdf?key1=1141290&key2=5899155711&coll=&dl=ACM&CFID=15151515&CFTOKEN=6184618">PDF</a> ]
+<li>Toma, L., 2006. <i>TerraCost: Scalable Computation of Least-Cost-Path Surfaces</i>. Talk at
+FOSS4G 2006, Lausanne, Switzerland. <br>
+[ <a href="http://indico.epfl.ch/contributionDisplay.py?contribId=106&sessionId=40&confId=1">Abstract</a> and <a href="http://www.bowdoin.edu/~ltoma/TALKS/FOSS4G-terracost.pdf">PDF</a> ]
+</ul>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.cost.html">r.cost</a>,
+<a href="r.drain.html">r.drain</a>,
+<a href="r.walk.html">r.walk</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Laura I. Toma, <a href="http://www.bowdoin.edu/~ltoma/research.html">http://www.bowdoin.edu/~ltoma/research.html</a>
+
+<p><i>Last changed: $Date: 2009-04-07 22:23:38 +0200 (Tue, 07 Apr 2009) $</i>
Added: grass-addons/raster/r.terracost/dijkstra.cc
===================================================================
--- grass-addons/raster/r.terracost/dijkstra.cc (rev 0)
+++ grass-addons/raster/r.terracost/dijkstra.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,803 @@
+
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#include "dijkstra.h"
+#include "dijkstraAbs.h"
+#include "pq.h"
+#include "formatNumber.h"
+
+#define PQ_TIMER
+#define UPDATE_TIMER
+
+#define DEBUG if(0)
+#define VERBOSE 0
+
+//define this to print all the sources in the grid as they are
+//encountered in tiles
+// #define PRINT_SOURCES
+
+void
+normalDijkstra(char* cellname, char* sourcename, long* nodata_count) {
+ costStructure cs;
+ cost_type cp;
+ dimension_type pqI, pqJ;
+
+ cost_type** costGrid;
+ cost_type** distGrid;
+ costGrid = new cost_type*[nrows];
+ distGrid = new cost_type*[nrows];
+ assert(costGrid);
+ assert(distGrid);
+ for (int i=0; i<nrows; i++) {
+ costGrid[i] = new cost_type[ncols];
+ distGrid[i] = new cost_type[ncols];
+ assert(costGrid[i]);
+ assert(distGrid[i]);
+ }
+
+ pqheap_ijCost *pq = new pqheap_ijCost(nrows*ncols);
+
+ loadNormalGrid (cellname, sourcename, nodata_count, costGrid, distGrid, pq);
+
+ while (!pq->empty()) {
+ pq->extract_min(&cs);
+ pqI = cs.getI();
+ pqJ = cs.getJ();
+ cp = cs.getPriority();
+ assert(cp >= 0);
+ if (distGrid[pqI][pqJ] >= cp) {
+ distGrid[pqI][pqJ] = cp;
+ normalUpdateNeighbors(cs, pq, distGrid, costGrid);
+ }
+ }
+ grid2Grass(distGrid, nrows, ncols, opt->out_grid);
+
+ // cleanup
+ for (int i=0; i<nrows; i++) {
+ delete [] costGrid[i];
+ delete [] distGrid[i];
+ }
+ delete [] costGrid;
+ delete [] distGrid;
+}
+
+
+/* compute SP from each boundary point to ANY source point and writes
+ the output distances to s2bstr
+
+invariant: sourceDist is 0 for all sources and inf for the
+ other points; all source points have been inserted in spq by
+ boundaryTileDijkstra */
+void
+sourceTileDijkstra(const Tile *tile, AMI_STREAM<ijCost> *s2bstr,
+ const TileFactory *tf, cost_type** dist,
+ pqheap_ijCost *pq) {
+
+ //DEBUG { cout << "sourceTileDijkstra::start" << endl; cout.flush(); }
+#ifndef NO_STATS
+ stats->comment("sourceTileDijkstra::start", VERBOSE);
+#endif
+ costStructure sourceCS;
+ dimension_type sourceI, sourceJ;
+ dimension_type tileSizeRows, tileSizeCols, absI, absJ;
+ cost_type sourcePrio;
+ ijCostSource tempCT;
+
+ tileSizeRows = tile->getNumRows();
+ tileSizeCols = tile->getNumCols();
+
+ // *stats << "sourceTileDijkstra: pq size = " << pq->size() << endl; // debug
+
+ // print the sources; this should be taken out maybe
+#ifdef PRINT_SOURCES
+ if(!pq->empty()) {
+ cout << "hello: sources at " << *pq << endl;
+ }
+#endif
+
+ while (!pq->empty()) {
+ pq->extract_min(&sourceCS);
+ sourceI = sourceCS.getI();
+ sourceJ = sourceCS.getJ();
+ sourcePrio = sourceCS.getPriority();
+ assert(sourcePrio >= 0);
+
+ ((Tile *)tile)->s2bPQCount++; // debug
+
+ if (dist[sourceI][sourceJ] >= sourcePrio) {
+ if (tf->isBoundary(sourceI, sourceJ)) {
+ tempCT = tile->getComplex(sourceI, sourceJ);
+ absI = tempCT.getI();
+ absJ = tempCT.getJ();
+ writeToCostTypeStream(absI, absJ, sourcePrio, s2bstr);
+ ((Tile *)tile)->s2bWriteCount++; // debug
+ }
+
+ updateNeighbors(tile, sourceCS, pq, dist);
+ }
+ }
+#ifndef NO_STATS
+ //DEBUG { cerr << "sourceTileDijkstra::end" << endl; cerr.flush(); }
+ stats->comment("sourceTileDijkstra::end", VERBOSE);
+ //stats->recordTime("source tile dijkstra");
+#endif
+}
+
+
+
+
+
+/* ---------------------------------------------------------------------- */
+/* compute SP from all bnd vertices of the tile and writes the outputs
+ to b2bstr; while scanning the tile it sets sourceDist of the points
+ which are sources to 0 and inserts them in spq*/
+int
+boundaryTileDijkstra(Tile *tile, AMI_STREAM<distanceType> *b2bstr,
+ const TileFactory *tf, cost_type** dist,
+ pqheap_ijCost *spq,
+ cost_type** sourceDist) {
+#ifndef NO_STATS
+ //DEBUG { cerr << "boundaryTileDijkstra::start\n"; }
+ stats->comment("boundaryTileDijkstra::start", VERBOSE);
+#endif
+ /* all these are inputs and must exist */
+ assert(tile && b2bstr && tf && dist && spq && sourceDist);
+
+ costStructure tempCS;
+ dimension_type tileSizeRows = tf->getRows();
+ dimension_type tileSizeCols = tf->getCols();
+
+
+ //this pq is to be used for sssp
+ unsigned int heap_size_estimate = tileSizeRows * tileSizeCols;
+ // JV: Removed the "/ 8"; to match standard Dijkstra.// xxx
+ // heap_size_estimate |= 256;
+ // JV: Not necessary due to removing "/ 8".
+
+ pqheap_ijCost *costpq = new pqheap_ijCost(heap_size_estimate);
+ //stats->comment("boundaryTileDijkstra::Created PQ in boundaryTileDijkstra()");
+
+ size_t mma = MM_manager.memory_available();
+ char memBuf[100];
+#ifndef NO_STATS
+ *stats << "boundaryTileDijkstra::Memory Available: "
+ << formatNumber(memBuf, mma) << ".\n";
+#endif
+ int count = 1;
+ int nullCount = 0;
+ int numBnd = 0;
+ int numNull = 0; // number of (unseen) nulls
+ int realNull = 0;
+ int bndCount = 0;
+ int bndShutoff = 0;
+ int totalNumBnd = (tileSizeRows-1)*2 + (tileSizeCols-1)*2;
+ int totalWrites = 0;
+ int expectedWrites = totalNumBnd*totalNumBnd;
+ int isNullPoint = 0;
+ long extracts = 0;
+ long updateCalls = 0;
+ int sourceCount = 0;
+
+ /* Need to compute the number of boundary points that are null in
+ the tile */
+ for (int l = 0, m = 0; l < tileSizeRows; l++) {
+ if(tile->get(l,m).isNull()) // first col
+ numNull++;
+ if (tile->get(l,m+tileSizeCols-1).isNull()) // last col
+ numNull++;
+ }
+ for (int l = 0, m = 1; m < tileSizeCols-1; m++) {
+ if(tile->get(l,m).isNull()) // first row
+ numNull++;
+ if (tile->get(l+tileSizeRows-1,m).isNull()) // last row
+ numNull++;
+ }
+#ifndef NO_STATS
+ *stats << " Num nulls on boundary: " << numNull << endl;
+#endif
+
+ for (int i = 0; i<tileSizeRows; i++) {
+ for (int j = 0; j < tileSizeCols; j++) {
+
+ if (tf->isBoundary(i,j)) {
+
+#if 1
+ numBnd++; // reporting only
+ assert(costpq->empty());
+ if (tile->get(i,j).isNull()) {
+ realNull++; // reporting only
+ numNull--; // numNullRemaining? -RW
+ isNullPoint = 1;
+ } else{
+ isNullPoint = 0;
+ }
+
+ totalNumBnd--; // numBndRemaining? -RW
+ bndShutoff = totalNumBnd - numNull; // =num of points to process? -RW
+ dijkstraAbs(tile, i, j, costpq, dist, bndShutoff, &extracts, &updateCalls);
+
+#else
+ /* run dijkstra now */
+ bndCount = 0;
+ ijCostSource startPoint = tile->get(i,j);
+ numBnd++;
+
+ assert(costpq->empty());
+ if (startPoint.isNull()) {
+ realNull++;
+ numNull--; // numNullRemaining? -RW
+ isNullPoint = 1;
+ //continue;
+ } else{
+ assert(!startPoint.isNull());
+ isNullPoint = 0;
+ //initialize dist grid
+ for (int l=0; l<tileSizeRows; l++) {
+ for (int m=0; m<tileSizeCols; m++) {
+ dist[l][m] = cost_type_max;
+ }
+ }
+ dist[i][j] = 0;
+ costpq->insert(costStructure(0.0, i, j)); // start point
+ }
+
+ totalNumBnd--; // numBndRemaining? -RW
+ bndShutoff = totalNumBnd - numNull; // =num of points to process? -RW
+
+ while (!costpq->empty() && bndCount <= bndShutoff) {
+ costpq->extract_min(&tempCS);
+ assert(tempCS.getPriority() >= 0);
+ extracts++;
+ if (dist[tempCS.getI()][tempCS.getJ()] >= tempCS.getPriority()) {
+ updateCalls++;
+ dist[tempCS.getI()][tempCS.getJ()] = tempCS.getPriority();
+ updateNeighbors(tile, tempCS, costpq, dist);
+ if (tf->isBoundary(tempCS.getI(),tempCS.getJ())
+ && tempCS.getI() >= i && tempCS.getJ() >=j) {
+ bndCount++;
+ }
+ }
+ } // while (!costpq->empty())
+ /* dijkstra done; save boundaries to stream */
+#endif
+
+ /*
+ * save the result to file. We only save 'forward' results;
+ * i.e. dist[i'][j'] where i'>=i and j'>=j -RW
+ */
+
+ ijCostSource startPoint = tile->getComplex(i,j);
+
+ /* row 0 */
+ if (i == 0) {
+ for (int l = 0, m = j; m <tileSizeCols; m++) {
+ assert(tf->isBoundary(l, m));
+ cost_type d = ((dist[l][m] < cost_type_max) && !isNullPoint)?
+ dist[l][m]: NODATA;
+ totalWrites += doubleWriteToDistStream(startPoint, tile->getComplex(l,m),
+ d, b2bstr);
+ }
+ }
+ //column 0
+ for (int l=i+(j==tileSizeCols-1?1:0),m = 0; l<tileSizeRows-1; l++) {
+ if (l == 0) continue;
+ assert(tf->isBoundary(l, m));
+ cost_type d = ((dist[l][m] < cost_type_max) && !isNullPoint)?
+ dist[l][m]: NODATA;
+ totalWrites += doubleWriteToDistStream(startPoint, tile->getComplex(l,m),
+ d,b2bstr);
+ }
+ //column tilesizeCols-1
+ for (int l = i, m = tileSizeCols-1; l < tileSizeRows-1; l++) {
+ if (l == 0) continue;
+ assert(tf->isBoundary(l, m));
+ cost_type d = ((dist[l][m] < cost_type_max) && !isNullPoint)?
+ dist[l][m]: NODATA;
+ totalWrites += doubleWriteToDistStream(startPoint, tile->getComplex(l,m),
+ d,b2bstr);
+ }
+ //row tileSizeRoows-1
+ for (int l = tileSizeRows-1, m = (i<(tileSizeRows-1)?0:j);
+ m < tileSizeCols; m++) {
+ assert(tf->isBoundary(l, m));
+ cost_type d = ((dist[l][m] < cost_type_max) && !isNullPoint)?
+ dist[l][m]: NODATA;
+ totalWrites += doubleWriteToDistStream(startPoint, tile->getComplex(l,m),
+ d,b2bstr);
+ }
+
+ costpq->clear();
+ } //if (tf->isBoundary(i,j))
+
+
+ /* check for sources for next stage.
+ * if the point is not a bnd vertex check if it is a source and
+ * if so insert it in spq */
+ if (tile->get(i,j).isSource()) {
+ DEBUG { cerr << "Source found: " << tile->getComplex(i,j) << "\n";cerr.flush(); }
+ spq->insert( costStructure(0.0, i, j));
+ sourceDist[i][j] = 0;
+ sourceCount++;
+ }
+ } //for j
+ } //for i
+
+#ifndef NO_STATS
+ *stats << " Total updates/extracts: " << updateCalls << "/" << extracts << endl;
+ //cerr << "Total updates/extracts: " << updateCalls << "/" << extracts << endl;
+ *stats << " Total Writes: " << totalWrites
+ << " Expected Writes: " << expectedWrites << endl;
+ *stats << " Non-Null Boundaries: " << numBnd-realNull << "\n";
+ *stats << " Estimated Nulls Left: " << numNull << "\n";
+ *stats << " Boundary inserts: " << count << "\n";
+ *stats << " Source count: " << sourceCount << "\n";
+ stats->comment("BoundaryTileDijkstra:end", VERBOSE);
+ stats->flush();
+#endif
+ delete costpq;
+ return numBnd;
+}
+
+
+
+
+/* ---------------------------------------------------------------------- */
+/*
+ Run Dijkstra on each tile and compute bnd2bnd SP; these will be
+ stored in b2bstr; also, for each point on the bnd of the tile,
+ compute SP to any source point in the tile; store this in s2bstr.
+ */
+void
+computeSubstituteGraph(TileFactory* tf, AMI_STREAM<distanceType> *b2bstr,
+ AMI_STREAM<ijCost> *s2bstr) {
+
+
+ //DEBUG { cerr << "Compute Substitute graph..\n";cerr.flush(); }
+ stats->comment("ComputeSubstitute graph", VERBOSE);
+ size_t mma = MM_manager.memory_available();
+ *stats << "ComputeSubstitute graph::Memory Available :"
+ << formatNumber(NULL, mma) << ".\n";
+
+ assert(tf);
+ assert(b2bstr);
+ assert(s2bstr);
+
+ dimension_type tileSizeRows = tf->getRows();
+ dimension_type tileSizeCols = tf->getCols();
+ AMI_err ae;
+
+ Tile *tile = new Tile(tileSizeRows, tileSizeCols);
+ assert(tile);
+ tile->printStats(*stats);
+
+ mma = MM_manager.memory_available();
+ *stats << "ComputeSubstitute graph::Memory Available after TileFactory: "
+ << formatNumber(NULL, mma) << ".\n";
+
+ /*
+ * dist stores the current SP from a bnd vertex during Dijkstra
+ */
+ cost_type** dist;
+ dist = new cost_type*[tileSizeRows];
+ assert(dist);
+ for (int i=0; i<tileSizeRows; i++) {
+ dist[i] = new cost_type[tileSizeCols];
+ assert(dist[i]);
+ }
+
+
+ mma = MM_manager.memory_available();
+ //formatNumber(NULL, mma);
+// DEBUG { cerr << "ComputeSubstitute graph::Memory Available after dist grid: "
+// << memBuf << ".\n"; }
+ *stats << "ComputeSubstitute graph::Memory Available after dist grid: "
+ << formatNumber(NULL, mma) << ".\n";
+
+ /*
+ * sourceDist stores the SP from a source vertex during Dijkstra
+ */
+ cost_type** sourceDist;
+ sourceDist = new cost_type*[tileSizeRows];
+ assert(sourceDist);
+ for (int i=0; i<tileSizeRows; i++) {
+ sourceDist[i] = new cost_type[tileSizeCols];
+ assert(sourceDist[i]);
+ }
+
+ mma = MM_manager.memory_available();
+ //formatNumber(NULL, mma);
+// DEBUG{cerr<<"ComputeSubstitute graph::Memory Avail after sourcedist grid: "
+// << memBuf << ".\n"; }
+ *stats <<"ComputeSubstitute graph::Memory Available after sourcedist grid: "
+ << formatNumber(NULL, mma) << ".\n";
+
+ long spq_estimate = tileSizeRows * tileSizeCols; // * 8;
+ // JV: Removed the "* 8"; to match standard Dijkstra.// xxx
+ pqheap_ijCost *spq = new pqheap_ijCost(spq_estimate);
+ assert(spq);
+
+ mma = MM_manager.memory_available();
+ //formatNumber(memBuf, mma);
+// DEBUG { cerr << "ComputeSubstitute graph::Memory Available after PQ: "
+// << memBuf << "\n"; }
+ *stats << "ComputeSubstitute graph::Memory Available after PQ: "
+ << formatNumber(NULL, mma) << "\n";
+
+ *stats << "sizeof(costStructure) = " << sizeof(costStructure) << ".\n";
+ //#ifndef NDEBUG
+ int k = 1; /* For debugging only */
+ //#endif
+ int insertCount = 0;
+ tf->reset();
+
+ while (tf->getNextTile(tile)) {
+#ifndef NO_STATS
+ *stats << "ComputeSubstitute graph::Working with tile " << k << "...\n";
+#endif
+#ifndef NDEBUG
+ cerr << "ComputeSubstitute graph::Working with tile " << k << "...\n";
+#endif
+
+ /* set all points to inf; the sources will be set to 0 in
+ boundaryTileDijkstra */
+ for (int i=0; i<tileSizeRows; i++) {
+ for (int j = 0; j<tileSizeCols; j++) {
+ sourceDist[i][j] = cost_type_max;
+ }
+ }
+
+ insertCount += boundaryTileDijkstra(tile, b2bstr, tf, dist, spq, sourceDist);
+
+ /* invariant: sourceDist is 0 for all sources and inf for the
+ other points; all source points have been inserted in spq by
+ boundaryTileDijkstra */
+ sourceTileDijkstra(tile, s2bstr, tf, sourceDist, spq);
+
+ //spq should be empty
+ assert(spq->empty());
+ //#ifndef NDEBUG
+#ifndef NO_STATS
+ stats->timestamp("ComputeSubstitute graph::");
+ *stats << "Leaving tile " << k << ".\n";
+#endif
+ k++;
+
+ //tile->dump(); // debug
+ //#endif
+ }
+
+ delete tile;
+ delete spq;
+ for (int i=0; i<tileSizeRows; i++) {
+ assert(dist[i] && sourceDist[i]);
+ delete [] dist[i];
+ delete [] sourceDist[i];
+ }
+ delete [] dist;
+ delete [] sourceDist;
+
+ //printGrid(*s2bstr);
+
+ *stats << "computeSubstituteGraph::Total Boundaries: " << insertCount
+ << endl;
+ stats->recordLength("******b2bstr ", b2bstr);
+ stats->recordLength("******s2bstr ", s2bstr);
+ *stats << "ComputeSubstitute graph::done\n"; stats->flush();
+ //stats->recordTime("computing substitute graph");
+ //DEBUG { cerr << "ComputeSubstitute graph::done\n"; cerr.flush(); }
+}
+
+
+void
+addNullBnds(const SettleLookup & settled, BoundaryType<cost_type> *phase2Bnd,
+ const TileFactory* tf) {
+ ijCost nullBnd;
+ dimension_type r = tf->getRows();
+ dimension_type c = tf->getCols();
+
+ cerr << "addNullBnds: start..." << endl;
+
+ for (int i = 0, j = 0; i < r; i++) {
+ if(settled.isSettled(i,j,tf) == 0) {
+ nullBnd = ijCost(i,j,NODATA);
+ phase2Bnd->insert(nullBnd);
+ }
+ if(settled.isSettled(i,j+r-1,tf) == 0) {
+ nullBnd = ijCost(i,j,NODATA);
+ phase2Bnd->insert(nullBnd);
+ }
+ }
+ for (int i = 0, j = 1; j < c; j++) {
+ if(settled.isSettled(i,j,tf) == 0) {
+ nullBnd = ijCost(i,j,NODATA);
+ phase2Bnd->insert(nullBnd);
+ }
+ if(settled.isSettled(i+r-1,j,tf) == 0) {
+ nullBnd = ijCost(i,j,NODATA);
+ phase2Bnd->insert(nullBnd);
+ }
+ }
+}
+
+
+
+
+
+/* ---------------------------------------------------------------------- */
+
+void
+interTileDijkstra(AMI_STREAM<ijCost> *s2bstr,
+ AMI_STREAM<distanceType> *b2bstr,
+ BoundaryType<cost_type> *phase2Bnd,
+ const TileFactory *tf) {
+
+ cerr << "interTileDijkstra::start\n";
+ assert(s2bstr && b2bstr && phase2Bnd && tf);
+
+ size_t testMMAvailable = MM_manager.memory_available();
+ cerr << "interTileDijkstra::avail memory: " << testMMAvailable << ".\n";
+
+ int c = 0;
+
+ SettleLookup settled(nrowsPad, ncolsPad, tf);
+
+ AMI_err ae, ae1;
+ ae = s2bstr->seek(0);
+ cerr << "s2sstr len: " << s2bstr->stream_len() << endl;cerr.flush();
+
+ EMPQueueAdaptive<costStructureOld, costPriorityOld> *itpq =
+ new EMPQueueAdaptive<costStructureOld, costPriorityOld>();
+ /* initialize PQ: insert all distances from bnd vertices to a source
+ in the pq */
+ ijCost *ct;
+ costStructureOld cs;
+ assert(itpq);
+
+ ae = s2bstr->read_item(&ct);
+ while (ae != AMI_ERROR_END_OF_STREAM) {
+ cs = costStructureOld(*ct);
+ assert(cs.getPriority().getDist() != NODATA);
+ itpq->insert(cs);
+ ae = s2bstr->read_item(&ct);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ c++;
+ }
+
+ //#define XXX fprintf(stderr, "reached %s:%d\n", __FILE__, __LINE__);
+ dimension_type tI;
+ dimension_type tJ;
+ ijCost extractedPoint;
+ int d = 0;
+ while (!itpq->is_empty()) {
+ itpq->extract_min(cs);
+ //*stats << "Extraxting: " << cs << "\n"; stats->flush();
+ tI = cs.getI();
+ tJ = cs.getJ();
+ /* We used points with i,j = -1 for padding*/
+ costPriorityOld cp = cs.getPriority();
+
+ //assert (cp.getDist() != NODATA && tI != NODATA && tJ != NODATA);
+ assert (cp.getDist() != NODATA && tI != dim_undef && tJ != dim_undef);
+ if (!settled.isSettled(tI, tJ, tf)) {
+ updateInterNeighbors(cs, settled, itpq, b2bstr, tf, phase2Bnd);
+ settled.settlePoint(tI, tJ, tf);
+ extractedPoint = ijCost(tI, tJ, cp.getDist());
+
+ assert(phase2Bnd);
+ phase2Bnd->insert(extractedPoint);
+ // *stats << "Settled: " << extractedPoint << "\n"; stats->flush();
+ d++;
+ }
+ else {
+ //extractedPoint = ijCost(tI, tJ, cp.getDist());
+ //cerr << "already settled: " << extractedPoint << "\n";cerr.flush();
+ }
+ } //while (!itpq->is_empty())
+
+ addNullBnds(settled, phase2Bnd, tf);
+
+
+ cerr << "Total inserts: " << c << ".\n";
+ cerr << "Total settles: " << d << ".\n";
+ delete itpq;
+ cerr << "interTileDijkstra::done\n";
+}
+
+
+
+
+
+
+/* ---------------------------------------------------------------------- */
+void
+finalDijkstra(TileFactory *tf, BoundaryType<cost_type> *phase2Bnd,
+ AMI_STREAM<ijCost> *finalstr) {
+
+ cerr << "finalDijkstra::start\n"; cerr .flush();
+ assert(tf && phase2Bnd && finalstr);
+ cerr << "Phase2Bnd Len: " << phase2Bnd->getSize() << endl; cerr.flush();
+
+ dimension_type tileSizeRows, tileSizeCols, absI, absJ;
+ Tile *tile;
+ cost_type **finalDist;
+ cost_type finalPrio;
+ ijCostSource point, initCT, tempCT;
+ costStructure finalCS;
+
+ tileSizeRows = tf->getRows();
+ tileSizeCols = tf->getCols();
+
+ tile = new Tile(tileSizeRows, tileSizeCols);
+
+ finalDist = new cost_type*[tileSizeRows];
+ assert(finalDist);
+ for (int i=0; i<tileSizeRows; i++) {
+ finalDist[i] = new cost_type[tileSizeCols];
+ assert(finalDist[i]);
+ }
+
+
+ unsigned int pqsize = tileSizeRows*tileSizeCols*2;
+ pqheap_ijCost *finalpq = new pqheap_ijCost(pqsize);
+
+ int count = 1; // this is not being used! XXX-RW
+ ijCost tempijCost;
+
+ tf->reset();
+ while(tf->getNextTile(tile)) {
+
+ // "Initializing finalDist tile
+ for (int i = 0; i<tileSizeRows; i++) {
+ for (int j = 0; j<tileSizeCols; j++) {
+ initCT = tile->getComplex(i,j);
+ if (initCT.getCost().isSource()) finalDist[i][j] = 0;
+ else if (tf->isBoundary(initCT.getI(),initCT.getJ())) {
+ phase2Bnd->get(initCT.getI(),initCT.getJ(),&tempijCost);
+ finalDist[i][j] = tempijCost.getCost();
+ } else finalDist[i][j] = cost_type_max;
+ }
+ } //for
+
+ for (int i = 0; i < tileSizeRows; i++) {
+ for (int j = 0; j < tileSizeCols; j++) {
+ point = tile->getComplex(i,j);
+
+ if (isNull(point.getCost())) {
+ /* We are checking the internal null points in output.cc,
+ but the boundary nulls are still being dealt with here */
+ if (tf->isBoundary(i,j)) {
+ phase2Bnd->insert(ijCost(point.getI(), point.getJ(),
+ point.getCost().getCost()));
+ }
+ /*
+ else {
+ writeToCostTypeStream(point.getI(), point.getJ(),
+ point.getCost().getCost(), finalstr);
+ }
+ */
+ continue;
+ }
+
+ if (tf->isBoundary(i,j)) {
+ /* This is necessary because of the "Puerto Rico Problem"
+ where there could be unreachable points on the
+ boundary. These points will be inserted into the
+ phase2Bnd structure, as NODATA points, but should not be
+ inserted into the PQ */
+ if (finalDist[i][j] == NODATA)
+ continue;
+ finalpq->insert(costStructure(finalDist[i][j], i,j));
+ }
+ if (point.getCost().isSource()) {
+#ifdef PRINT_SOURCES
+ *stats << "finalDijkstra::Source at (" << point
+ <<", inserting it in PQ )\n";
+#endif
+ finalpq->insert(costStructure(0.0, i,j));
+ }
+ }
+ }
+
+
+
+ while (!finalpq->empty()) {
+
+ finalpq->extract_min(&finalCS);
+ finalPrio = finalCS.getPriority();
+ assert(finalPrio != NODATA);
+
+ //assert(absI%tileSizeRows == finalI && absJ%tileSizeCols == finalJ);
+ if (finalDist[finalCS.getI()][finalCS.getJ()] >= finalPrio &&
+ !tf->isBoundary(finalCS.getI(),finalCS.getJ())){
+ tempCT = tile->getComplex(finalCS.getI(),finalCS.getJ());
+ absI = tempCT.getI();
+ absJ = tempCT.getJ();
+ writeToCostTypeStream(absI, absJ, finalPrio, finalstr);
+ }
+
+ updateNeighbors(tile, finalCS, finalpq, finalDist);
+ }
+ count ++;
+
+ } //for each tile
+
+
+ cerr << "Stream length: " << finalstr->stream_len() << "\n";cerr.flush();
+ cerr << "Boundary length: " << phase2Bnd->getSize() << "\n";cerr.flush();
+
+ delete tile;
+ for (int i=0; i<tileSizeRows; i++) {
+ delete [] finalDist[i];
+ }
+ delete [] finalDist;
+ delete finalpq;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int
+doubleWriteToDistStream(const basicIJType& source, const basicIJType& dest,
+ cost_type dist, AMI_STREAM<distanceType> *b2bstr) {
+
+ distanceType toWrite = distanceType(source, dest, dist);
+ AMI_err ae = b2bstr->write_item(toWrite);
+ assert(ae == AMI_ERROR_NO_ERROR);
+
+ if (source != dest) {
+ toWrite = distanceType(dest, source, dist);
+ ae = b2bstr->write_item(toWrite);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ return 2;
+ }
+
+ return 1;
+
+}
+
+/* ---------------------------------------------------------------------- */
+void
+writeToStreamWithDist(distanceType inDist,AMI_STREAM<distanceType> *b2bstr) {
+ AMI_err ae = b2bstr->write_item(inDist);
+ assert(ae == AMI_ERROR_NO_ERROR);
+}
+
+/* ---------------------------------------------------------------------- */
+
+
+void
+writeToCostTypeStream(dimension_type i, dimension_type j, cost_type dist,
+ AMI_STREAM<ijCost> *str) {
+
+ if ((cost_type_max - dist) < 1000) {
+ //if it gets close to overflow
+ printf("warning: large cost at (%d, %d, %f)\n", i, j, dist);
+ }
+
+ /* This Doesn't work
+ ijCost toStr = ijCost(i, j, dist);*/
+
+ /* This does */
+ ijCost toStr;
+ toStr = ijCost(i, j, dist);
+
+ AMI_err ae = str->write_item(toStr);
+ assert(ae == AMI_ERROR_NO_ERROR);
+}
+
+/* ---------------------------------------------------------------------- */
Added: grass-addons/raster/r.terracost/dijkstra.h
===================================================================
--- grass-addons/raster/r.terracost/dijkstra.h (rev 0)
+++ grass-addons/raster/r.terracost/dijkstra.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,67 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef _DIJKSTRA_H
+#define _DIJKSTRA_H
+
+
+#include <grass/iostream/ami.h>
+#include "types.h"
+#include "common.h"
+#include "input.h"
+#include "boundary.h"
+#include "tile.h"
+#include "index.h"
+#include "distanceType.h"
+#include "update.h"
+//#include "iterator.h"
+#include "output.h"
+#include "update.h"
+#include "initialize.h"
+#include "pqueue.h"
+
+void normalDijkstra(char* cellname, char* sourcename, long* nodaa_count);
+
+int boundaryTileDijkstra(Tile *tile, AMI_STREAM<distanceType> *b2bstr,
+ const TileFactory *tf, cost_type** dist,
+ pqheap_ijCost *spq,
+ cost_type** sourceDist);
+
+void computeSubstituteGraph(TileFactory* inTf,
+ AMI_STREAM<distanceType> *b2bstr,
+ AMI_STREAM<ijCost> *s2bstr);
+
+void addNullBnds(int settledArray[], BoundaryType<cost_type> *phase2Bnd,
+ const TileFactory* tf);
+
+void interTileDijkstra(AMI_STREAM<ijCost> *s2bstr,
+ AMI_STREAM<distanceType> *b2bstr,
+ BoundaryType<cost_type> *phase2Bnd, const TileFactory *tf);
+
+void finalDijkstra(TileFactory *tf, BoundaryType<cost_type> *phase2Bnd,
+ AMI_STREAM<ijCost> *finalstr);
+
+int doubleWriteToDistStream(const basicIJType& source,const basicIJType& dest,
+ cost_type dist, AMI_STREAM<distanceType> *b2bstr);
+
+void writeToCostTypeStream(dimension_type i, dimension_type j, cost_type dist,
+ AMI_STREAM<ijCost> *str);
+
+void writeToStreamWithDist(distanceType inDist,
+ AMI_STREAM<distanceType> *b2bstr);
+
+#endif
Property changes on: grass-addons/raster/r.terracost/dijkstra.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/dijkstraAbs.cc
===================================================================
--- grass-addons/raster/r.terracost/dijkstraAbs.cc (rev 0)
+++ grass-addons/raster/r.terracost/dijkstraAbs.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,88 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include "types.h"
+#include "input.h"
+#include "pqueue.h"
+#include "tileAbs.h"
+#include "updateAbs.h"
+#include "dijkstraAbs.h"
+
+#include <assert.h>
+
+
+/*
+ * run dijkstra on a tile, starting at point start_i, start_j
+ * use the (empty) costpq; use the dist array
+ * expect to see bndExpect boundary points
+ */
+void
+dijkstraAbs(Tile *tile, int start_i, int start_j,
+ pqheap_ijCost *costpq, cost_type** dist,
+ int bndExpected,
+ long *extractsIn, long *updatesIn) {
+ long extracts = 0;
+ long updates = 0;
+
+ if (tile->get(start_i, start_j).isNull()) {
+ return;
+ }
+
+ costStructure currentVertex;
+ dim_t tileSizeRows = tile->getNumRows();
+ dim_t tileSizeCols = tile->getNumCols();
+
+ //initialize dist grid
+ for (int l=0; l<tileSizeRows; l++) {
+ for (int m=0; m<tileSizeCols; m++) {
+ dist[l][m] = cost_type_max;
+ }
+ }
+ dist[start_i][start_j] = 0;
+ assert(costpq->empty());
+ costpq->insert(costStructure(0.0, start_i, start_j)); // start point
+
+ while (!costpq->empty() && bndExpected > 0) {
+ costpq->extract_min(¤tVertex);
+ assert(currentVertex.getPriority() >= 0);
+ extracts++;
+
+ dim_t i, j;
+ i = currentVertex.getI();
+ j = currentVertex.getJ();
+ cost_type *dp = &dist[i][j]; // current estimate
+
+ // skip if NODATA
+ if(tile->get(i,j).getCost() == NODATA) {
+ continue;
+ }
+
+ if (*dp >= currentVertex.getPriority()) {
+ updates++;
+ *dp = currentVertex.getPriority();
+ updateNeighbors(tile, currentVertex, costpq, dist);
+ // optimization - break out when we see all non-null boundaries
+ if (tile->isBoundary(i,j) && i >= start_i && j >= start_j) {
+ bndExpected--;
+ }
+ }
+ } // while (!costpq->empty())
+
+ *extractsIn += extracts;
+ *updatesIn += updates;
+}
+
Added: grass-addons/raster/r.terracost/dijkstraAbs.h
===================================================================
--- grass-addons/raster/r.terracost/dijkstraAbs.h (rev 0)
+++ grass-addons/raster/r.terracost/dijkstraAbs.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,23 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+void
+dijkstraAbs(Tile *tile, int start_i, int start_j,
+ pqheap_ijCost *costpq, cost_type** dist,
+ int bndExpected,
+ long *extracts, long *updates);
Property changes on: grass-addons/raster/r.terracost/dijkstraAbs.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/distanceType.h
===================================================================
--- grass-addons/raster/r.terracost/distanceType.h (rev 0)
+++ grass-addons/raster/r.terracost/distanceType.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,130 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef __DISTANCE_H
+#define __DISTANCE_H
+
+
+#include "types.h"
+//#include "common.h"
+#include "input.h"
+
+#define DST_ARRAY 0
+#define DST_STREAM 1
+
+
+class distanceType {
+ basicIJType source;
+ basicIJType dest;
+ cost_type dist;
+
+ public:
+
+ distanceType(const basicIJType& inSource,
+ const basicIJType& inDest,
+ cost_type inDist) {
+ source = inSource;
+ dest = inDest;
+ dist = inDist;
+ };
+
+ distanceType () {};
+
+ dim_t getFromI() const { return source.val_i; };
+ dim_t getFromJ() const { return source.val_j; };
+ dim_t getToI() const { return dest.val_i; };
+ dim_t getToJ() const { return dest.val_j; };
+
+ const basicIJType& getSource() const { return source; };
+ const basicIJType& getDest() const { return dest; };
+
+ cost_type getDistance() const { return dist; };
+
+ friend ostream& operator << (ostream& s, const distanceType &dt) {
+ s << "(" << dt.source << "," << dt.dest << "): " << dt.dist;
+ return s;
+ };
+
+ friend bool operator == (distanceType &d1, distanceType &d2) {
+ return (d1.getFromI() == d2.getFromI()) &&
+ (d1.getFromJ() == d2.getFromJ()) &&
+ (d1.getToI() == d2.getToI()) &&
+ (d1.getToJ() == d2.getToJ());
+ }
+
+ friend bool operator < (distanceType &d1, distanceType &d2) {
+ if (d1.getFromI() >= d2.getFromI())
+ return false;
+ if (d1.getFromJ() >= d2.getFromJ())
+ return false;
+ if (d1.getToI() >= d2.getToI())
+ return false;
+ if (d1.getToJ() >= d2.getToJ())
+ return false;
+ return true;
+ }
+
+ friend bool operator > (distanceType &d1, distanceType &d2) {
+ if (d1.getFromI() <= d2.getFromI())
+ return false;
+ if (d1.getFromJ() <= d2.getFromJ())
+ return false;
+ if (d1.getToI() <= d2.getToI())
+ return false;
+ if (d1.getToJ() <= d2.getToJ())
+ return false;
+ return true;
+ }
+
+};
+
+
+
+class distanceIJCompareType {
+
+ public:
+
+ // Returns -1 if a is less than b (tile order)
+ // Returns 0 if equal
+ // Returns 1 if b is less than a
+ static int compare (const distanceType &a, const distanceType &b) {
+ if (a.getFromI() < b.getFromI()){
+ return -1; /* a <i b */
+ } else if (a.getFromI() == b.getFromI()) {
+ if (a.getFromJ() < b.getFromJ()) {
+ return -1; /* a <j b */
+ } else if (a.getFromJ() == b.getFromJ()) {
+ if (a.getToI() < b.getToI()) {
+ return -1; /* a i< b */
+ } else if (a.getToI() == b.getToI()) {
+ if (a.getToJ() < b.getToJ()) {
+ return -1; /* a j< b */
+ } else if (a.getToJ() == b.getToJ()) {
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+ };
+
+};
+
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/distanceType.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/formatNumber.cc
===================================================================
--- grass-addons/raster/r.terracost/formatNumber.cc (rev 0)
+++ grass-addons/raster/r.terracost/formatNumber.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,52 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <stdio.h>
+
+#if __FreeBSD__ && __i386__
+# define LDFMT "%qd"
+#else
+# if __linux__
+# define LDFMT "%lld"
+# else
+# ifdef __APPLE__
+# define LDFMT "%lld"
+# else
+# define LDFMT "%ld"
+# endif
+# endif
+#endif
+char *
+formatNumber(char *buf, long long val) {
+ static char sbuf[BUFSIZ];
+
+ // use the non-reentrant static buffer if we got passed a NULL
+ if(!buf) {
+ buf = sbuf;
+ }
+
+ if(val > (1<<30)) {
+ sprintf(buf, "%.2fG (" LDFMT ")", (double)val/(1<<30), val);
+ } else if(val > (1<<20)) {
+ sprintf(buf, "%.2fM (" LDFMT ")", (double)val/(1<<20), val);
+ } else if(val > (1<<10)) {
+ sprintf(buf, "%.2fK (" LDFMT ")", (double)val/(1<<10), val);
+ } else {
+ sprintf(buf, LDFMT, val);
+ }
+ return buf;
+}
Added: grass-addons/raster/r.terracost/formatNumber.h
===================================================================
--- grass-addons/raster/r.terracost/formatNumber.h (rev 0)
+++ grass-addons/raster/r.terracost/formatNumber.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,18 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+char *formatNumber(char *buf, long long val);
Property changes on: grass-addons/raster/r.terracost/formatNumber.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/genericTile.h
===================================================================
--- grass-addons/raster/r.terracost/genericTile.h (rev 0)
+++ grass-addons/raster/r.terracost/genericTile.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,190 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef GENERICTILE_H
+#define GENERICTILE_H
+
+#include <ostream>
+#include "types.h"
+#include "input.h"
+
+
+/* #ifndef NDEBUG */
+/* #define ASSERT assert */
+/* #else */
+/* #define ASSERT(x) */
+/* #endif */
+
+/* turn on/off asserts manually until they are fixed in the rest of the code */
+#define ASSERT(x) assert(x)
+
+/* ---------------------------------------------------------------------- */
+
+/* a basic tile type that just provices accessor methods */
+template<class T>
+class genericTile {
+protected:
+ dim_t rows, cols;
+ T **data;
+
+ public:
+ genericTile(dim_t inRows, dim_t inCols);
+ ~genericTile();
+
+ const T& get(dim_t i, dim_t j) const;
+ void put(dim_t i, dim_t j, const T value);
+ void put(dim_t i, dim_t j, const T *value);
+
+ int inTile(dim_t inI, dim_t inJ) const;
+
+ int isBoundary(dim_t i, dim_t j) const {
+ return ((i==0) || (j==0) || (i==rows-1) || (j==cols-1));
+ }
+
+ dim_t getNumRows() const { return rows; };
+ dim_t getNumCols() const { return cols; };
+
+ void dumpTile(ostream &os, const char *prefix) const;
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* a tile that can return a ijCostType using a given offset */
+template<class T>
+class mappedTile : public genericTile<T> {
+ dim_t baseRow, baseCol;
+ public:
+ mappedTile(dim_t inRows, dim_t inCols,
+ dim_t i, dim_t j);
+
+ /* figure out offset given the root element */
+ void deriveBasis(const ijCostType<T> & root, dim_t i, dim_t j);
+
+ const ijCostType<T> getComplex(dim_t i, dim_t j) const;
+ void put(dim_t i, dim_t j, const ijCostType<T> &val);
+};
+
+/* ---------------------------------------------------------------------- */
+/* implementations */
+
+
+template<class T>
+genericTile<T>::genericTile(dim_t inRows, dim_t inCols) : rows(inRows), cols(inCols) {
+ data = new T* [rows];
+ for(dim_t i=0; i<rows; i++) {
+ data[i] = new T [cols];
+ }
+}
+
+template<class T>
+genericTile<T>::~genericTile() {
+ for(dim_t i=0; i<rows; i++) {
+ delete data[i];
+ }
+ delete [] data;
+}
+
+template<class T>
+inline
+const T &
+genericTile<T>::get(dim_t i, dim_t j) const {
+ ASSERT(inTile(i,j));
+ return data[i][j];
+}
+
+template<class T>
+void
+genericTile<T>::put(dim_t i, dim_t j, const T value) {
+ ASSERT(inTile(i,j));
+ data[i][j] = value;
+}
+
+/* template<class T> */
+/* void */
+/* genericTile<T>::put(dim_t i, dim_t j, const T *value) { */
+/* ASSERT(inTile(i,j)); */
+/* data[i][j] = *value; */
+/* } */
+
+template<class T>
+int
+genericTile<T>::inTile(dim_t i, dim_t j) const {
+ //return (i < rows && j < cols && i >= 0 && j >= 0);
+ return (i < rows && j < cols && i != dim_undef && j != dim_undef);
+}
+
+template<class T>
+void
+genericTile<T>::dumpTile(ostream &os, const char *prefix) const {
+ int i, j;
+
+ os.flush();
+ for(i=0; i<rows; i++) {
+ os << prefix;
+ for(j=0; j<cols; j++) {
+ os << data[i][j];
+ }
+ os << endl;
+ }
+ os.flush();
+}
+
+
+
+#define INTILE(_tilep,_i,_j) ( ((_i) >= 0) && ((_j) >= 0) \
+ && ((_i) < (_tilep)->getNumRows()) \
+ && ((_j) < (_tilep)->getNumCols()) )
+
+/* ---------------------------------------------------------------------- */
+
+template<class T>
+mappedTile<T>::mappedTile(dim_t inRows, dim_t inCols,
+ dim_t i=0, dim_t j=0)
+ : genericTile<T>(inRows, inCols), baseRow(i), baseCol(j) {
+}
+
+template<class T>
+void
+mappedTile<T>::deriveBasis(const ijCostType<T> & ijct, dim_t i, dim_t j) {
+ baseRow = ijct.getI() - i;
+ baseCol = ijct.getJ() - j;
+}
+
+template<class T>
+const ijCostType<T>
+mappedTile<T>::getComplex(dim_t i, dim_t j) const {
+ return ijCostType<T>(baseRow + i, baseCol + j, genericTile<T>::get(i, j));
+}
+
+#define DBG_ERROR() ( cerr << __FILE__ << ":" << __LINE__ << " ijmismatch: put " << val \
+ << " at i,j=" << i << "," << j << endl )
+#define DBG_CHECK_I(_val,_i) ( (_val.getI() - baseRow == _i) || DBG_ERROR() )
+#define DBG_CHECK_J(_val,_j) ( (_val.getJ() - baseCol == _j) || DBG_ERROR() )
+
+template<class T>
+void
+mappedTile<T>::put(dim_t i, dim_t j, const ijCostType<T> &val) {
+/* assert(val.getI() >= baseRow && val.getI() < baseRow + rows); */
+/* assert(val.getJ() >= baseCol && val.getJ() < baseCol + cols); */
+ ASSERT(val.getI() - baseRow == i);
+ ASSERT(val.getJ() - baseCol == j);
+ //DBG_CHECK_I(val, i);
+ //DBG_CHECK_J(val, j);
+ genericTile<T>::put(i, j, val.getCost());
+}
+
+#endif
Property changes on: grass-addons/raster/r.terracost/genericTile.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/grass2str.h
===================================================================
--- grass-addons/raster/r.terracost/grass2str.h (rev 0)
+++ grass-addons/raster/r.terracost/grass2str.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,490 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+
+#ifndef _gras2str_H
+#define _gras2str_H
+
+#include <grass/iostream/ami.h>
+#include "option.h"
+#include "types.h"
+#include "common.h"
+#include "nodata.h" /* for TERRAFLOW_INTERNAL_NODATA_VALUE */
+
+
+
+
+
+/* ---------------------------------------------------------------------- */
+/* create and return a STREAM containing the given cell; nodata_count
+ is set to the number of cells that contain nodata */
+template<class T>
+AMI_STREAM<T>*
+cell2stream(char* cellname, elevation_type T_max_value, long* nodata_count) {
+ Rtimer rt;
+ AMI_err ae;
+ elevation_type T_min_value = -T_max_value;
+
+ rt_start(rt);
+ assert(cellname && nodata_count);
+ *nodata_count = 0;
+ /* create output stream */
+ AMI_STREAM<T>* str = new AMI_STREAM<T>();
+ {
+ char * foo;
+ str->name(&foo);
+ *stats << "reading cell file " << cellname
+ << "to stream " << foo << endl;
+ if (opt->verbose)
+ fprintf(stderr, "reading data from %s to stream %s: ", cellname, foo);
+ }
+
+ char *mapset;
+ mapset = G_find_cell (cellname, "");
+ if (mapset == NULL)
+ G_fatal_error ("cell file [%s] not found", cellname);
+
+ /* open map */
+ int infd;
+ if ( (infd = G_open_cell_old (cellname, mapset)) < 0)
+ G_fatal_error ("Cannot open cell file [%s]", cellname);
+
+ /* determine map type (CELL/FCELL/DCELL) */
+ RASTER_MAP_TYPE data_type;
+ data_type = G_raster_map_type(cellname, mapset);
+
+ /* Allocate input buffer */
+ void *inrast;
+ inrast = G_allocate_raster_buf(data_type);
+
+ CELL c;
+ FCELL f;
+ DCELL d;
+ T x;
+ int isnull = 0;
+
+ for (int i = 0; i< nrows; i++) {
+
+ /* read input map */
+ if (G_get_raster_row (infd, inrast, i, data_type) < 0)
+ G_fatal_error ("Could not read from <%s>, row=%d",cellname,i);
+
+ for (int j=0; j<ncols; j++) {
+
+ switch (data_type) {
+ case CELL_TYPE:
+ c = ((CELL *) inrast)[j];
+ isnull = G_is_c_null_value(&c);
+ if (!isnull) {
+ x = (T)c; d = (DCELL)c;
+ }
+ break;
+ case FCELL_TYPE:
+ f = ((FCELL *) inrast)[j];
+ isnull = G_is_f_null_value(&f);
+ if (!isnull) {
+ x = (T)f; d = (DCELL)f;
+ }
+ break;
+ case DCELL_TYPE:
+ d = ((DCELL *) inrast)[j];
+ isnull = G_is_d_null_value(&d);
+ if (!isnull) {
+ x = (T)d;
+ }
+ break;
+ default:
+ G_fatal_error("raster type not implemented");
+ }
+ /* cout << form("(i=%d,j=%d): (%d, %f)\n",i,j,x,d); cout.flush(); */
+ /* handle null values */
+ if (isnull) {
+ x = TERRAFLOW_INTERNAL_NODATA_VALUE;
+ (*nodata_count)++;
+ } else {
+ /* check range */
+ if ((d > (DCELL)T_max_value) || (d < (DCELL)T_min_value)) {
+ fprintf(stderr, "reading cell file %s at (i=%d,j=%d) value=%.1f\n",
+ cellname, i, j, d);
+ G_fatal_error("value out of range.");
+ }
+ }
+ /* write x to stream */
+ ae = str->write_item(x);
+ assert(ae == AMI_ERROR_NO_ERROR);
+
+ } /* for j */
+
+ if (opt->verbose) G_percent(i, nrows, 2);
+ }/* for i */
+
+ if (opt->verbose) fprintf(stderr, "\n");
+ /* delete buffers */
+ G_free(inrast);
+ /* close map files */
+ G_close_cell (infd);
+
+ assert(nrows * ncols == str->stream_len());
+ rt_stop(rt);
+ stats->recordTime("reading cell file", rt);
+
+ return str;
+}
+
+
+
+
+
+/* ---------------------------------------------------------------------- */
+template<class T>
+void
+stream2_CELL(AMI_STREAM<T>* str, dimension_type nrows, dimension_type ncols,
+ char* cellname) {
+ Rtimer rt;
+ AMI_err ae;
+
+ rt_start(rt);
+ assert(str);
+ assert(str->stream_len() == nrows*ncols);
+ str->seek(0);
+ {
+ char * foo;
+ str->name(&foo);
+ *stats << "writing stream " << foo << " to cell file " << cellname << "\n";
+ fprintf(stderr, "writing stream %s to cell file %s: ", foo, cellname);
+ }
+
+ /* open output cell file */
+ int outfd;
+ if ( (outfd = G_open_raster_new (cellname, CELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname);
+ }
+
+ /* Allocate output buffer */
+ unsigned char *outrast;
+ outrast = (unsigned char *)G_allocate_raster_buf(CELL_TYPE);
+ assert(outrast);
+
+ T* elt;
+ for (int i=0; i< nrows; i++) {
+ for (int j=0; j< ncols; j++) {
+
+ /* READ VALUE */
+ ae = str->read_item(&elt);
+ if (ae != AMI_ERROR_NO_ERROR) {
+ str->sprint();
+ fprintf(stderr, "reading stream failed at (%d,%d)\n", i,j);
+ G_fatal_error("stream2cell failed");
+ }
+
+ /* WRITE VALUE */
+ if (is_nodata(*elt)) {
+ G_set_c_null_value( &( ((CELL *) outrast)[j]), 1);
+ } else {
+ ((CELL *) outrast)[j] = (CELL)(*elt);
+ }
+
+ } /* for j*/
+ if (G_put_raster_row (outfd, outrast, CELL_TYPE) < 0)
+ G_fatal_error ("Cannot write to <%s>",cellname);
+
+ G_percent(i, nrows, 2);
+ }/* for i */
+ fprintf(stderr, "\n");
+
+ G_free(outrast);
+ G_close_cell (outfd);
+
+ rt_stop(rt);
+ stats->recordTime("writing cell file", rt);
+
+ str->seek(0);
+
+ return;
+}
+
+
+
+
+
+/* laura: this is identical with stream2_FCELL; did not know how to
+ template ona type --- is that possible? */
+/* ---------------------------------------------------------------------- */
+template<class T, class FUN>
+void
+stream2_CELL(AMI_STREAM<T> *str, dimension_type nrows, dimension_type ncols,
+ FUN fmt, char* cellname) {
+
+
+ Rtimer rt;
+ AMI_err ae;
+
+ assert(str && cellname);
+ /* assert(str->stream_len() == nrows*ncols); */
+
+ rt_start(rt);
+ str->seek(0);
+ {
+ char * foo;
+ str->name(&foo);
+ *stats << "writing stream " << foo << "cellfile " << cellname << endl;
+ fprintf(stderr, "writing stream %s to cell file %s: ", foo, cellname);
+ }
+
+ /* open output cell file */
+ int outfd;
+ if ( (outfd = G_open_raster_new (cellname, CELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname);
+ }
+
+ /* Allocate output buffer */
+ unsigned char *outrast;
+ outrast = (unsigned char *)G_allocate_raster_buf(CELL_TYPE);
+ assert(outrast);
+
+ T* elt;
+ ae = str->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ for (int i=0; i< nrows; i++) {
+ for (int j=0; j< ncols; j++) {
+
+ if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
+ /* WRITE VALUE */
+ if (is_nodata ( fmt(*elt) )) {
+ G_set_c_null_value( &( ((CELL *) outrast)[j]), 1);
+ } else {
+ ((CELL *) outrast)[j] = (CELL)(fmt(*elt));
+ }
+ ae = str->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+
+ } else {
+ /* WRITE NODATA */
+ G_set_c_null_value( &( ((CELL *) outrast)[j]), 1);
+ }
+
+ } /* for j*/
+ if (G_put_raster_row (outfd, outrast, CELL_TYPE) < 0)
+ G_fatal_error ("Cannot write to <%s>",cellname);
+
+ G_percent(i, nrows, 2);
+ }/* for i */
+ fprintf(stderr,"\n");
+
+ G_free(outrast);
+ G_close_cell (outfd);
+
+ rt_stop(rt);
+ stats->recordTime("writing cell file", rt);
+
+ str->seek(0);
+ return;
+}
+
+
+
+/* ---------------------------------------------------------------------- */
+template<class T, class FUN>
+void
+stream2_FCELL(AMI_STREAM<T> *str, dimension_type nrows, dimension_type ncols,
+ FUN fmt, char* cellname) {
+
+
+ Rtimer rt;
+ AMI_err ae;
+
+ assert(str && cellname);
+ /* assert(str->stream_len() == nrows*ncols); */
+
+ rt_start(rt);
+ str->seek(0);
+ {
+ char * foo;
+ str->name(&foo);
+ *stats << "writing stream " << foo << "cellfile " << cellname << endl;
+ fprintf(stderr, "writing stream %s to cell file %s: ", foo, cellname);
+ }
+
+ /* open output cell file */
+ int outfd;
+ if ( (outfd = G_open_raster_new (cellname, FCELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname);
+ }
+
+ /* Allocate output buffer */
+ unsigned char *outrast;
+ outrast = (unsigned char *)G_allocate_raster_buf(FCELL_TYPE);
+ assert(outrast);
+
+ T* elt;
+ ae = str->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ for (int i=0; i< nrows; i++) {
+ for (int j=0; j< ncols; j++) {
+
+ if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
+ /* WRITE VALUE */
+ if (is_nodata ( fmt(*elt) )) {
+ G_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
+ } else {
+ ((FCELL *) outrast)[j] = (FCELL)(fmt(*elt));
+ }
+ ae = str->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+
+ } else {
+ /* WRITE NODATA */
+ G_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
+ }
+
+ } /* for j*/
+ if (G_put_raster_row (outfd, outrast, FCELL_TYPE) < 0)
+ G_fatal_error ("Cannot write to <%s>",cellname);
+
+ G_percent(i, nrows, 2);
+ }/* for i */
+ fprintf(stderr, "\n");
+
+ G_free(outrast);
+ G_close_cell (outfd);
+
+ rt_stop(rt);
+ stats->recordTime("writing cell file", rt);
+
+ str->seek(0);
+ return;
+}
+
+
+/* ---------------------------------------------------------------------- */
+/* outstr is sorted by (i,j);
+
+ class sweepOutput {
+ public:
+ dimension_type i,j;
+ flowaccumulation_type accu;
+ #ifdef OUTPUT_TCI
+ tci_type tci;
+ #endif
+ };
+
+create an accu cell file, and a tci cell file if OUTPUT_TCI is defined
+*/
+template<class T, class FUN1, class FUN2>
+void
+stream2_FCELL(AMI_STREAM<T>* str, dimension_type nrows, dimension_type ncols,
+ FUN1 fmt1, FUN2 fmt2,
+ char* cellname1, char* cellname2) {
+ Rtimer rt;
+ AMI_err ae;
+
+
+ assert(str);
+#ifndef OUTPUT_TCI
+ /* this function should be used only if tci is wanted as output */
+ fprintf(stderr, "use this function only if tci is wanted as output\n");
+ exit(1);
+#else
+ rt_start(rt);
+
+ str->seek(0);
+ {
+ char * foo;
+ str->name(&foo);
+ *stats << "writing stream " << foo << "to cell files "
+ << cellname1 << ", " << cellname2 << endl;
+ fprintf(stderr, "writing stream %s to cell files %s, %s: ",
+ foo, cellname1, cellname2);
+ }
+
+ /* open cell files */
+ int fd1;
+ if ( (fd1 = G_open_raster_new (cellname1, FCELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname1);
+ }
+ int fd2;
+ if ( (fd2 = G_open_raster_new (cellname2, FCELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname2);
+ }
+
+
+ /* Allocate output buffers */
+ FCELL *rast1;
+ rast1 = (FCELL*)G_allocate_raster_buf(FCELL_TYPE);
+ assert(rast1);
+ FCELL *rast2;
+ rast2 = (FCELL*)G_allocate_raster_buf(FCELL_TYPE);
+ assert(rast2);
+
+ T* elt;
+ ae = str->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ for (int i=0; i< nrows; i++) {
+ for (int j=0; j< ncols; j++) {
+
+ if(ae == AMI_ERROR_NO_ERROR && elt->i == i && elt->j == j) {
+ /* WRITE VALUE */
+ if (is_nodata(fmt1(*elt))) {
+ G_set_f_null_value(&(rast1[j]), 1);
+ } else {
+ rast1[j] = fmt1(*elt);
+ };
+ if (is_nodata( fmt2(*elt))) {
+ G_set_f_null_value(&(rast2[j]), 1);
+ } else {
+ rast2[j] = fmt2(*elt);
+ }
+ /* read next value */
+ ae = str->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+
+
+ } else {
+ /* WRITE NODATA */
+ G_set_f_null_value(&(rast1[j]), 1);
+ G_set_f_null_value(&(rast2[j]), 1);
+ }
+
+ } /* for j*/
+
+ if (G_put_raster_row (fd1, rast1, FCELL_TYPE) < 0)
+ G_fatal_error ("Cannot write to <%s>", cellname1);
+ if (G_put_raster_row (fd2, rast2, FCELL_TYPE) < 0)
+ G_fatal_error ("Cannot write to <%s>", cellname2);
+
+ G_percent(i, nrows, 2);
+
+ }/* for i */
+ fprintf(stderr, "\n");
+
+ G_free(rast1);
+ G_close_cell (fd1);
+ G_free(rast2);
+ G_close_cell (fd2);
+
+
+ rt_stop(rt);
+ stats->recordTime("writing stream to cell files", rt);
+
+ str->seek(0);
+ return;
+#endif
+}
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/grass2str.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/index.cc
===================================================================
--- grass-addons/raster/r.terracost/index.cc (rev 0)
+++ grass-addons/raster/r.terracost/index.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,428 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#include "index.h"
+
+// /* ----------------------------------------------------------------------
+
+// This method takes in an i,j coordinate and TileFactory and then returns
+// an ijCost containing the i,j of the upper leftmost point in the tile
+// containing i,j.
+
+// ---------------------------------------------------------------------- */
+// ijCost
+// getNeighborRegionMarker(dimension_type i, dimension_type j, const TileFactory *tf) {
+
+// int mode = tf->classifyPoint(i,j);
+// dimension_type iMarker=-1, jMarker=-1, tileSizeRows, tileSizeCols;
+// tileSizeRows = tf->getRows();
+// tileSizeCols = tf->getCols();
+// ijCost out;
+
+// switch (mode) {
+
+// case EXT_BND :
+// if (i == 0) {
+// iMarker = i;
+// jMarker = (j/(tileSizeCols-1))*(tileSizeCols-1);
+// }
+// else if (i == nrowsPad - 1){
+// iMarker = i-(tileSizeRows-1);
+// jMarker = (j/(tileSizeCols-1))*(tileSizeCols-1);
+// }
+// else if (j == 0) {
+// iMarker = (i/(tileSizeRows-1))*(tileSizeRows-1);
+// jMarker = j;
+// }
+// else if (j == ncolsPad - 1){
+// iMarker = (i/(tileSizeRows-1))*(tileSizeRows-1);
+// jMarker = j-(tileSizeCols-1);
+// }
+// break;
+// case INT_ROW:
+// iMarker = i-(tileSizeRows-1);
+// jMarker = (j/(tileSizeCols-1))*(tileSizeCols-1);
+// break;
+// case INT_COL:
+// iMarker = (i/(tileSizeRows-1))*(tileSizeRows-1);
+// jMarker = j-(tileSizeCols-1);
+// break;
+// case INT_CNR:
+// iMarker = i-(tileSizeRows-1);
+// jMarker = j-(tileSizeCols-1);
+// break;
+// case EXT_ROW_CNR:
+// if (j == 0) {
+// jMarker = j;
+// iMarker = i-(tileSizeRows-1);
+// }
+// else if (j == ncolsPad -1) {
+// jMarker = j-(tileSizeCols-1);
+// iMarker = i-(tileSizeRows-1);
+// }
+// break;
+// case EXT_COL_CNR:
+// if (i == 0) {
+// iMarker = i;
+// jMarker = j-(tileSizeCols-1);
+// }
+// else if (i == nrowsPad -1) {
+// iMarker = i-(tileSizeRows-1);
+// jMarker = j-(tileSizeCols-1);
+// }
+// break;
+// case EXT_CNR:
+// if (i == 0 && j == 0) {
+// iMarker = i;
+// jMarker = j;
+// }
+// if (i == 0 && j == ncolsPad-1) {
+// iMarker = i;
+// jMarker = j-(tileSizeCols-1);
+// }
+// if (i == nrowsPad-1 && j == 0) {
+// iMarker = i-(tileSizeRows-1);
+// jMarker = j;
+// }
+// if (i == nrowsPad-1 && j == 0) {
+// iMarker = i-(tileSizeRows-1);
+// jMarker = j-(tileSizeCols-1);
+// }
+// break;
+// case NOT_BND:
+// cout << "Not Boundary\n";
+// assert(0); // is this an error? -RW
+// break;
+// case NOT_IN_GRID:
+// cout << "Not in Grid\n;";
+// assert(0); // is this an error? -RW
+// break;
+// default:
+// assert(0);
+// }
+
+// /* This point is used only for its i,j coordinate so we can set its
+// caost to -1 aand is source to 'n' as default values */
+// assert(iMarker >= 0 && jMarker >= 0); // -RW
+// out = ijCost(iMarker, jMarker, -1);
+
+// return out;
+
+// }
+
+
+/* ----------------------------------------------------------------------
+
+This method is used for indexing the b2bstr. For any iFrom,jFrom and Tile
+Factory from a distanceType (iFrom, jFrom, iTo, jTo, Distance), this method
+returns the index in b2bstr where iFrom,jFrom starts.
+
+ ---------------------------------------------------------------------- */
+off_t
+getFromIndex(dimension_type iFrom, dimension_type jFrom,
+ const TileFactory *tf) {
+
+ dimension_type nbrows, nbcols, tileSizeRows, tileSizeCols;
+ off_t index;
+ int numTileBndPts, factorA, factorB;
+ nbrows = tf->getBndrows();
+ nbcols = tf->getBndcols();
+ tileSizeRows = tf->getRows();
+ tileSizeCols = tf->getCols();
+
+ numTileBndPts = tf->getNumTileBndPts();
+
+ //cout << "numTileBndPts: " << numTileBndPts << " nbrows: " << nbrows <<
+ // " nbcols: " << nbcols << endl;cout.flush();
+ //cout << "nrowsPad: " << nrowsPad << " ncolsPad: " << ncolsPad << endl;
+ //cout.flush();
+
+
+ factorA = (nbcols-1)*2;
+ factorB = ncolsPad*2 + (nbcols-2)*2;
+ index = 0;
+
+ // (i,j) in the first row
+ if (iFrom == 0) {
+ //index = 0; cout << "iFrom == 0\n";
+ if (jFrom == 0)
+ index = 0;
+ else
+ index = jFrom + (jFrom-1)/(tileSizeCols-1);
+ //cout << "Index: " << index << "\n";
+ }
+
+ // (i,j) in the last row
+ else if (iFrom == nrowsPad-1){
+ index = 0; //cout << "iFrom = nrowsPad-1\n";
+ index = ncolsPad + nbcols-2;
+ index += (iFrom/(tileSizeRows-1))*(tileSizeRows-2)*factorA;
+ index += ((iFrom-1)/(tileSizeRows-1))*factorB;
+ index += jFrom + (jFrom-1)/(tileSizeCols-1);
+ }
+
+ // (i,j) in a boundary row
+ else if (iFrom%(tileSizeRows-1)==0) {
+ //cout << "iFrom%(nbrows-1)==0\n";
+ //1st row
+ index = ncolsPad + nbcols-2;
+ //Rows 2+3 for midTest
+ index += (iFrom/(tileSizeRows-1))*(tileSizeRows-2)*factorA;
+ //Row 4 for midtest
+ index += ((iFrom-1)/(tileSizeRows-1))*factorB;
+ //last row
+ index += (jFrom + (jFrom-1)/(tileSizeCols-1))*2;
+ }
+
+ // (i,j) in a boundary column
+ else if (jFrom%(tileSizeCols-1)==0) {
+ //cout << "iFrom%(nbrows-1)!=0\n";
+ //1st row
+ index = ncolsPad + nbcols-2;
+ //Rows 2+3 for midTest
+ index += (iFrom/(tileSizeRows-1))*(tileSizeRows-2)*factorA;
+ //Row 4 for midtest
+ index += ((iFrom-1)/(tileSizeRows-1))*factorB;
+ //last set of incomplete rows
+ index += ((iFrom%(tileSizeRows-1))-1) * factorA;
+ //last row
+ index += jFrom/(tileSizeCols-1) + (jFrom-1)/(tileSizeCols-1);
+ }
+
+ else {
+ cerr << "Boundary access error: (" << iFrom << "," << jFrom
+ << ") is not a boundary point." << endl;
+ exit(1);
+ }
+
+ //cout << "Index: " << index << "\n";cout.flush();
+
+ return index*numTileBndPts;
+}
+
+
+// /* ----------------------------------------------------------------------
+
+// This method is used for indexing the b2bstr. For any iTo,jTo and Tile
+// Factory from a distanceType (iFrom, jFrom, iTo, jTo, Distance), this method
+// returns the offset after iFrom, jFrom where (iFrom, jFrom, iTo, jTo) can be
+// found
+
+// ---------------------------------------------------------------------- */
+// int getToIndex(dimension_type iFrom, dimension_type jFrom, dimension_type iTo,
+// dimension_type jTo, const TileFactory *tf) {
+
+// int pointType, numTileBndPts;
+// dimension_type tileNumI, tileNumJ, tileSizeRows, tileSizeCols,
+// iMod, jMod, iMarker, jMarker;
+// ijCost markers;
+
+// numTileBndPts = tf->getNumTileBndPts();
+
+// pointType = tf->classifyPoint(iFrom, jFrom);
+// tf->printClassification(pointType);
+// tileSizeRows = tf->getRows();
+// tileSizeCols = tf->getCols();
+// tileNumI = iTo/(tileSizeRows-1);
+// tileNumJ = jTo/(tileSizeCols-1);
+// markers = getNeighborRegionMarker(iFrom, jFrom, tf);
+// iMarker = markers.getI();
+// jMarker = markers.getJ();
+
+// /*
+// cout << "getToIndex()\n";
+// cout << "iFrom: " << iFrom << " jFrom: " << jFrom << "\n";
+// cout << "iTo: " << iTo << " jTo: " << jTo << "\n";
+// cout << "iMarker: " << iMarker << " jMarker: " << jMarker << "\n";
+// */
+
+// switch (pointType) {
+
+// case EXT_BND :
+// if (iTo == iMarker)
+// return jTo-jMarker+1;
+// if (iTo == iMarker + tileSizeRows-1)
+// return numTileBndPts-((jMarker+tileSizeCols-1)-jTo);
+// if (jTo == jMarker)
+// return tileSizeCols + (iTo-iMarker-1)*2 + 1;
+// if (jTo == jMarker+tileSizeCols-1)
+// return tileSizeCols + (iTo-iMarker)*2;
+// cout << "Problem with EXT_BND\n";
+// break;
+
+// case INT_ROW :
+// if (iTo == iMarker)
+// return jTo-jMarker+1;
+// if (iTo == iMarker + tileSizeRows-1)
+// return tileSizeCols + 2*(tileSizeRows-2) + (jTo-jMarker)*2 + 1;
+// if (iTo == iMarker + (tileSizeRows-1)*2)
+// return tileSizeCols*3 + 2*2*(tileSizeRows-2) + (jTo-jMarker) + 1;
+// if (jTo == jMarker && iTo < iFrom)
+// return tileSizeCols + (iTo-iMarker-1)*2 + 1;
+// if (jTo == jMarker && iTo > iFrom)
+// return tileSizeCols*3 + (iTo-iMarker-1)*2 + 1;
+// if (jTo == jMarker+tileSizeCols-1 && iTo < iFrom)
+// return tileSizeCols + (iTo-iMarker)*2 ;
+// if (jTo == jMarker+tileSizeCols-1 && iTo > iFrom)
+// return tileSizeCols*3 + (iTo-iMarker)*2;
+// cout << "Problem with INT_ROW\n";
+// break;
+
+// case INT_COL :
+// if (iTo == iMarker && jTo <= jFrom)
+// return jTo-jMarker+1;
+// if (iTo == iMarker && jTo > jFrom)
+// return jTo-jMarker+2;
+// if (iTo == iMarker + tileSizeRows-1 && jTo <= jFrom)
+// return 2*tileSizeCols+(tileSizeRows-2)*4+(jTo-jMarker)+1;
+// if (iTo == iMarker + tileSizeRows-1 && jTo > jFrom)
+// return 2*tileSizeCols+(tileSizeRows-2)*4+(jTo-jMarker)+2;
+// if (jTo == jMarker)
+// return tileSizeCols*2+(iTo-iMarker-1)*2*2+1;
+// if (jTo == jMarker+tileSizeCols-1)
+// return tileSizeCols*2+(iTo-iMarker-1)*2*2+2;
+// if (jTo == jMarker+(tileSizeCols-1)*2)
+// return tileSizeCols*2+(iTo-iMarker-1)*2*2+4;
+// cout << "Problem with INT_COL\n";
+// break;
+
+// case INT_CNR :
+// if (iTo == iMarker && jTo <= jFrom)
+// return jTo-jMarker+1;
+// if (iTo == iMarker && jTo > jFrom)
+// return jTo-jMarker+2;
+// if (iTo == iMarker + tileSizeRows-1 && jTo <= jFrom)
+// return 2*tileSizeCols+(tileSizeRows-2)*4+(jTo-jMarker)*2+1;
+// if (iTo == iMarker + tileSizeRows-1 && jTo > jFrom)
+// return 2*tileSizeCols+(tileSizeRows-2)*4+(jTo-jMarker+2)*2+1;
+// if (iTo == iMarker + (tileSizeRows-1)*2 && jTo <= jFrom)
+// return tileSizeCols*6 + (tileSizeRows-2)*2*4 + jTo-jMarker+1;
+// if (iTo == iMarker + (tileSizeRows-1)*2 && jTo > jFrom)
+// return tileSizeCols*6 + (tileSizeRows-2)*2*4 + jTo-jMarker+2;
+// if (jTo == jMarker && iTo < iFrom)
+// return tileSizeCols*2 + (jTo-jMarker-1)*2 + 1;
+// cout << "Problem with INT_CNR\n";
+// break;
+
+// case EXT_ROW_CNR : //Same as internal row
+// if (iTo == iMarker)
+// return jTo-jMarker+1;
+// if (iTo == iMarker + tileSizeRows-1)
+// return tileSizeCols + 2*(tileSizeRows-2) + (jTo-jMarker)*2 + 1;
+// if (iTo == iMarker + (tileSizeRows-1)*2)
+// return tileSizeCols*3 + 2*2*(tileSizeRows-2) + (jTo-jMarker) + 1;
+// if (jTo == jMarker && iTo < iFrom)
+// return tileSizeCols + (iTo-iMarker-1)*2 + 1;
+// if (jTo == jMarker && iTo > iFrom)
+// return tileSizeCols*3 + (iTo-iMarker-1)*2 + 1;
+// if (jTo == jMarker+tileSizeCols-1 && iTo < iFrom)
+// return tileSizeCols + (iTo-iMarker)*2 ;
+// if (jTo == jMarker+tileSizeCols-1 && iTo > iFrom)
+// return tileSizeCols*3 + (iTo-iMarker)*2;
+// cout << "Problem with INT_ROW\n";
+// break;
+
+// case EXT_COL_CNR :
+// if (iTo == iMarker && jTo <= jFrom)
+// return jTo-jMarker+1;
+// if (iTo == iMarker && jTo > jFrom) {
+// cout << "I should be here";
+// return jTo-jMarker+2;
+// }
+// if (iTo == iMarker + tileSizeRows-1 && jTo <= jFrom)
+// return 2*tileSizeCols+(tileSizeRows-2)*4+(jTo-jMarker)+1;
+// if (iTo == iMarker + tileSizeRows-1 && jTo > jFrom)
+// return 2*tileSizeCols+(tileSizeRows-2)*4+(jTo-jMarker)+2;
+// if (jTo == jMarker)
+// return tileSizeCols*2+(iTo-iMarker-1)*2*2+1;
+// if (jTo == jMarker+tileSizeCols-1)
+// return tileSizeCols*2+(iTo-iMarker-1)*2*2+2;
+// if (jTo == jMarker+(tileSizeCols-1)*2)
+// return tileSizeCols*2+(iTo-iMarker-1)*2*2+4;
+// cout << "Problem with INT_COL\n";
+// break;
+
+// case EXT_CNR :
+// if (iTo == iMarker)
+// return jTo-jMarker+1;
+// if (iTo == iMarker + tileSizeRows-1)
+// return numTileBndPts-((jMarker+tileSizeCols-1)-jTo);
+// if (jTo == jMarker)
+// return tileSizeCols + (iTo-iMarker-1)*2 + 1;
+// if (jTo == jMarker+tileSizeCols-1)
+// return tileSizeCols + (iTo-iMarker)*2;
+// cout << "Problem with EXT_BND\n";
+// break;
+
+// case NOT_BND :
+// cout << "Problem with NOT_BND\n";
+// break;
+
+// case NOT_IN_GRID :
+// cout << "Problem with NOT_IN_GRID\n";
+// break;
+
+// }
+
+// assert(0); // -RW
+// return -1; // -RW
+// }
+
+/* ----------------------------------------------------------------------
+
+This method is used for indexing the array of settled points used for
+the b2b stream.
+
+ ---------------------------------------------------------------------- */
+int
+getSettledIndex(dimension_type i, dimension_type j, const TileFactory *tf) {
+ dimension_type tileSizeRows, tileSizeCols, nbrows, nbcols;
+ int index = 0;
+ tileSizeRows = tf->getRows();
+ tileSizeCols = tf->getCols();
+ nbrows = tf->getBndrows();
+ nbcols = tf->getBndcols();
+
+
+ if (i == 0) {
+ index = j;
+ }
+ else if (i == nrowsPad-1) {
+ index = ncolsPad*(nbrows-1);
+ index += (nbrows-1)*(tileSizeRows-2)*nbcols;
+ index += j;
+ }
+ else if (i%(tileSizeRows-1) == 0) {
+ index = (i/(tileSizeRows-1))*ncolsPad;
+ index += (i/(tileSizeRows-1))*(tileSizeRows-2)*nbcols;
+ index += j;
+ }
+ else {
+ index = ((i/(tileSizeRows-1))+1)*ncolsPad;
+ index += (i/(tileSizeRows-1))*(tileSizeRows-2)*nbcols;
+ index += ((i%(tileSizeRows-1))-1)*nbcols;
+ index += j/(tileSizeCols-1);
+ }
+
+ /*
+ if (i == 0)
+ cout << "For " << i << "," << j << " Settle Index: " << index << "\n";
+ */
+
+ return index;
+}
Added: grass-addons/raster/r.terracost/index.h
===================================================================
--- grass-addons/raster/r.terracost/index.h (rev 0)
+++ grass-addons/raster/r.terracost/index.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,43 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef __index_H
+#define __index_H
+
+#include "common.h"
+#include "types.h"
+#include "tile.h"
+
+
+off_t getFromIndex(dimension_type iFrom, dimension_type jFrom, const TileFactory *tf);
+
+/* int getToIndex(dimension_type iFrom, dimension_type jFrom, dimension_type iTo, */
+/* dimension_type jTo, const TileFactory *tf); */
+
+ijCost getNeighborRegionMarker(dimension_type i, dimension_type j,
+ const TileFactory *tf);
+
+int getSettledIndex(dimension_type i, dimension_type j, const TileFactory *tf);
+
+
+
+
+
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/index.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/initialize.cc
===================================================================
--- grass-addons/raster/r.terracost/initialize.cc (rev 0)
+++ grass-addons/raster/r.terracost/initialize.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,360 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+/* The initialize module deals with the loading of a raster map from
+ GRASS formatting and changing it into an AMI_STREAM and boundary
+ structure to be used by the tile factory. */
+
+#include "stats.h"
+#include "formatNumber.h"
+#include "initialize.h"
+
+//#define DEBUG_LOADGRID
+
+/* ---------------------------------------------------------------------- */
+cost_type
+loadCell (void *inrast, RASTER_MAP_TYPE data_type, int *isnull,
+ dimension_type j) {
+ FCELL f;
+ DCELL d;
+ CELL c;
+ cost_type x;
+ ijCost out;
+ cost_type T_max_value = cost_type_max;
+ cost_type T_min_value = -T_max_value;
+
+ switch (data_type) {
+ case CELL_TYPE:
+ c = ((CELL *) inrast)[j];
+ //cout << "C: " << c << ".\n";
+ *isnull = G_is_c_null_value(&c);
+ if (!(*isnull)) {
+ x = (cost_type)c; d = (DCELL)c;
+ }
+ else x = NODATA;
+ break;
+ case FCELL_TYPE:
+ f = ((FCELL *) inrast)[j];
+ //cout << "F1: " << f << ".\n";
+ *isnull = G_is_f_null_value(&f);
+ //cout << "F2: " << f << ".\n";
+ if (!(*isnull)) {
+ x = (cost_type)f; d = (DCELL)f;
+ }
+ else x = NODATA;
+ break;
+ case DCELL_TYPE:
+ d = ((DCELL *) inrast)[j];
+ //cout << "D: " << d << ".\n";
+ *isnull = G_is_d_null_value(&d);
+ if (!(*isnull)) {
+ x = (cost_type)d;
+ }
+ else x = NODATA;
+ break;
+ default:
+ G_fatal_error("raster type not implemented");
+ x = NODATA;
+ break;
+ }
+
+ if (d > (DCELL)T_max_value)
+ G_fatal_error("value out of range.");
+
+ return x;
+
+}
+
+/* ---------------------------------------------------------------------- */
+
+int
+checkSource (void *inrastSource, RASTER_MAP_TYPE data_type_source,
+ dimension_type j) {
+ FCELL f;
+ DCELL d;
+ CELL c;
+ cost_type x;
+ int isnull = 0;
+ ijCost out;
+
+ switch (data_type_source) {
+ case CELL_TYPE:
+ c = ((CELL *) inrastSource)[j];
+ isnull = G_is_c_null_value(&c);
+ if (isnull) return 0;
+ break;
+ case FCELL_TYPE:
+ f = ((FCELL *) inrastSource)[j];
+ isnull = G_is_f_null_value(&f);
+ if (isnull) return 0;
+ break;
+ case DCELL_TYPE:
+ d = ((DCELL *) inrastSource)[j];
+ isnull = G_is_d_null_value(&d);
+ if (isnull) return 0;
+ break;
+ default:
+ G_fatal_error("raster type not implemented");
+ }
+ return 1;
+
+}
+
+/* ---------------------------------------------------------------------- */
+void
+loadGrid (char* cellname, char* sourcename, long* nodata_count,
+ TileFactory *tf) {
+
+ AMI_err ae;
+ *nodata_count = 0;
+ int isnull = 0;
+ cost_type cost;
+ char s;
+ ijCostSource out;
+ FCELL f;
+
+ /* Find cost map raster file */
+ char *mapset;
+ mapset = G_find_cell (cellname, "");
+ if (mapset == NULL)
+ G_fatal_error ("cell file [%s] not found", cellname);
+
+ int infd;
+ if ( (infd = G_open_cell_old (cellname, mapset)) < 0)
+ G_fatal_error ("Cannot open cell file [%s]", cellname);
+
+ //Added by tom hazel 7 July 2004
+ /* Find source map raster file */
+ char *mapsetSource;
+ mapsetSource = G_find_cell (sourcename, "");
+ if (mapsetSource == NULL)
+ G_fatal_error ("cell file [%s] not found", sourcename);
+
+ //Added by tom hazel 7 July 2004
+ int infdSource;
+ if ( (infdSource = G_open_cell_old (sourcename, mapsetSource)) < 0)
+ G_fatal_error ("Cannot open cell file [%s]", sourcename);
+
+
+ /* determine map type (CELL/FCELL/DCELL) */
+ RASTER_MAP_TYPE data_type;
+ data_type = G_raster_map_type(cellname, mapset);
+
+ RASTER_MAP_TYPE data_type_source;
+ data_type_source = G_raster_map_type(sourcename, mapsetSource);
+
+ /* Allocate input buffer */
+ void *inrast;
+ inrast = G_allocate_raster_buf(data_type);
+
+ void *inrastSource;
+ inrastSource = G_allocate_raster_buf(data_type_source);
+
+#ifdef DEBUG_LOADGRID
+ AMI_STREAM<ijCostSource>* debugstr;
+ debugstr = new AMI_STREAM<ijCostSource>();
+#endif
+ for (dimension_type i = 0; i< nrows; i++) {
+
+ /* read input map */
+ if (G_get_raster_row (infd, inrast, i, data_type) < 0)
+ G_fatal_error ("Could not read from <%s>, row=%d",cellname,i);
+
+ /* read source map */
+ if (G_get_raster_row (infdSource, inrastSource, i, data_type_source) < 0)
+ G_fatal_error ("Could not read from <%s>, row=%d",sourcename,i);
+
+ for (dimension_type j=0; j<ncols; j++) {
+
+ /* the cost of point i,j is read from the raster file
+ if i,j is null, isnull=1 else isnull=0 */
+ cost = loadCell(inrast, data_type, &isnull, j);
+
+ if (cost < 0 && cost != NODATA) {
+ printf("reading (i=%d,j=%d) value=%.1f\n", i, j, cost);
+ printf("Negative cost detected. This algorithm requires all non-netative costs\n");
+ fflush(stdout);
+ exit(1);
+ }
+
+ if (isnull > 0) {
+ cost = NODATA;
+ (*nodata_count)++;
+ //cout << "No Data at: (" << i << "," << j << ")\n";
+ //cout.flush();
+ }
+
+
+ /* If point i,j is a source s=1 else s=0 */
+ s = checkSource(inrastSource, data_type_source, j);
+
+#ifdef PRINT_SOURCES
+ if (s) {
+ *stats << "loadGrid:: Source found at (" << i << "," << j << ")\n";
+ }
+#endif
+
+ // why is there a cast on the following line? -RW
+ costSourceType tempCST = costSourceType((cost_type)cost, s? 'y':'n');
+
+
+ /* out is the ijCostType to be written to the grid in tf */
+ out = ijCostSource(i, j, tempCST);
+
+ tf->insert(out);
+
+#ifdef DEBUG_LOADGRID
+ ae = debugstr->write_item(out);
+ assert(ae == AMI_ERROR_NO_ERROR);
+#endif
+ } /* for j */
+
+ if (opt->verbose) G_percent(i, nrows, 2);
+ }/* for i */
+
+ if (opt->verbose) fprintf(stderr, "\n");
+ /* delete buffers */
+ G_free(inrast);
+ /* close map files */
+ G_close_cell (infd);
+
+ //cout << "rows: " << nrows << " cols: " << ncols
+ //<< endl;cout.flush();
+
+ //assert(nrows * ncols == tf->getTotalPoints());
+
+ *stats << "loadGrid:: Number of null points: " << formatNumber(NULL, *nodata_count) << "\n";
+
+ //rt_stop(rt);
+ //stats->recordTime("reading cell file", rt);
+
+#ifdef DEBUG_LOADGRID
+ bnd->testBoundary(debugstr);
+#endif
+
+
+}
+/* ---------------------------------------------------------------------- */
+
+// how does this differ from loadGrid?? -RW
+
+void loadNormalGrid(char* cellname, char* sourcename, long* nodata_count,
+ cost_type** costGrid, cost_type** distGrid,
+ pqheap_ijCost *pq) {
+
+ AMI_err ae;
+ *nodata_count = 0;
+ int isnull = 0;
+ cost_type cost;
+ char s;
+ ijCostSource out;
+ FCELL f;
+ costStructure costStruct;
+
+ /* Find cost map raster file */
+ char *mapset;
+ mapset = G_find_cell (cellname, "");
+ if (mapset == NULL)
+ G_fatal_error ("cell file [%s] not found", cellname);
+
+ int infd;
+ if ( (infd = G_open_cell_old (cellname, mapset)) < 0)
+ G_fatal_error ("Cannot open cell file [%s]", cellname);
+
+ //Added by tom hazel 7 July 2004
+ /* Find source map raster file */
+ char *mapsetSource;
+ mapsetSource = G_find_cell (sourcename, "");
+ if (mapsetSource == NULL)
+ G_fatal_error ("cell file [%s] not found", sourcename);
+
+ //Added by tom hazel 7 July 2004
+ int infdSource;
+ if ( (infdSource = G_open_cell_old (sourcename, mapsetSource)) < 0)
+ G_fatal_error ("Cannot open cell file [%s]", sourcename);
+
+
+ /* determine map type (CELL/FCELL/DCELL) */
+ RASTER_MAP_TYPE data_type;
+ data_type = G_raster_map_type(cellname, mapset);
+
+ RASTER_MAP_TYPE data_type_source;
+ data_type_source = G_raster_map_type(sourcename, mapsetSource);
+
+ /* Allocate input buffer */
+ void *inrast;
+ inrast = G_allocate_raster_buf(data_type);
+
+ void *inrastSource;
+ inrastSource = G_allocate_raster_buf(data_type_source);
+
+ for (dimension_type i = 0; i< nrows; i++) {
+
+ /* read input map */
+ if (G_get_raster_row (infd, inrast, i, data_type) < 0)
+ G_fatal_error ("Could not read from <%s>, row=%d",cellname,i);
+
+ /* read source map */
+ if (G_get_raster_row (infdSource, inrastSource, i, data_type_source) < 0)
+ G_fatal_error ("Could not read from <%s>, row=%d",sourcename,i);
+
+ for (dimension_type j=0; j<ncols; j++) {
+
+ distGrid[i][j] = cost_type_max;
+
+
+ /* the cost of point i,j is read from the raster file
+ if i,j is null, isnull=1 else isnull=0 */
+ cost = loadCell(inrast, data_type, &isnull, j);
+
+ if (isnull > 0) {
+ cost = NODATA;
+ (*nodata_count)++;
+ distGrid[i][j] = NODATA;
+ }
+
+
+ /* If point i,j is a source s=1 else s=0 */
+ s = checkSource(inrastSource, data_type_source, j);
+
+ if (s) {
+ costStruct = costStructure(0,i,j);
+ pq->insert(costStruct);
+ costGrid[i][j] = 0;
+ distGrid[i][j] = 0;
+ }
+
+ else {
+ costGrid[i][j] = cost;
+ }
+
+ } /* for j */
+
+ if (opt->verbose) G_percent(i, nrows, 2);
+ }/* for i */
+
+ if (opt->verbose) fprintf(stderr, "\n");
+ /* delete buffers */
+ G_free(inrast);
+ /* close map files */
+ G_close_cell (infd);
+
+ *stats << "loadGrid:: Number of null points: " << *nodata_count << "\n";
+
+
+
+}
Added: grass-addons/raster/r.terracost/initialize.h
===================================================================
--- grass-addons/raster/r.terracost/initialize.h (rev 0)
+++ grass-addons/raster/r.terracost/initialize.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,68 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+/* The initialize module deals with the loading of a raster map from
+ GRASS formatting and changing it into an AMI_STREAM and boundary
+ structure to be used by the tile factory. */
+
+
+
+#ifndef __INITIALIZE_H
+#define __INITIALIZE_H
+
+extern "C" {
+#include <grass/gis.h>
+}
+#include <grass/iostream/ami.h>
+
+#include "types.h"
+#include "common.h"
+#include "input.h"
+#include "boundary.h"
+#include "tile.h"
+//#include "pq.h"
+#include "pqueue.h"
+
+
+/*
+ loadCell takes a raser point and translates the value to a cost_type
+ and returns it. loadCell also sets the isnull variable to 1 if the
+ point is a null point.
+*/
+cost_type loadCell (void *inrast, RASTER_MAP_TYPE data_type, int *isnull,
+ dimension_type j);
+
+/*
+ Given a source raster map row and a column coordinate, returns 1 if the
+ point is a source, 0 otherwise
+*/
+int checkSource (void *inrastSource, RASTER_MAP_TYPE data_type_source,
+ dimension_type j);
+
+/*
+ This method loads a raster grid for reading and then populates
+ the tile factory.
+*/
+void loadGrid (char* cellname, char* sourcename, long* nodata_count,
+ TileFactory *tf);
+
+void loadNormalGrid(char* cellname, char* sourcename, long* nodata_count,
+ cost_type** costGrid, cost_type** distGrid,
+ pqheap_ijCost *pq);
+
+#endif
Property changes on: grass-addons/raster/r.terracost/initialize.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/input.h
===================================================================
--- grass-addons/raster/r.terracost/input.h (rev 0)
+++ grass-addons/raster/r.terracost/input.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,366 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef _INPUT_H
+#define _INPUT_H
+
+//#include "common.h"
+#include "types.h"
+#include "config.h"
+#include <assert.h>
+
+#define NO_SOURCE 0
+#define SOURCE 1
+
+#define NODATA -9999
+
+
+//int isNull( const cost_type x);
+//int isNull(const costSourceType x);
+//int isNull(const dimension_type x);
+
+
+class costSourceType {
+ private:
+ cost_type cost;
+#ifndef sHACKS
+ char source;
+#endif
+ public:
+
+#ifdef sHACKS
+ costSourceType(cost_type inCost, bool inSource) : {
+ cost = (inSource ? cost : -cost);
+ }
+ costSourceType() : cost(cost_type_max) {}; /* no illegal value... */
+#else
+ costSourceType(cost_type inCost, char source):
+ cost(inCost), source(source) {};
+#if 0
+ costSourceType(const costSourceType &a):
+ cost(a.cost), source(a.source) {};
+#endif
+ costSourceType(): cost(-1), source('n') {};
+#endif
+
+#if 0
+ ~costSourceType(){};
+#endif
+
+ cost_type getCost() const {
+#ifdef sHACKS
+ return cost < 0 ? -cost : cost;
+#else
+ return cost;
+#endif
+ };
+ char getSource() const {
+ return source;
+ };
+
+ int isSource() const {
+ return (source == 'y');
+ };
+
+ int isNull() const {
+ return cost == NODATA;
+ };
+
+ void print() {
+ cout << *this;
+ };
+
+ friend ostream& operator << (ostream& s, const costSourceType &ct) {
+ s << "(" << ct.cost << ", isSource=" << ct.source<< ")";
+ return s;
+ };
+
+ friend int operator == (const costSourceType &a, const costSourceType &b) {
+ return (a.cost == b.cost) && (a.source == b.source);
+ };
+
+};
+
+
+
+
+/* typedef float cost_type */
+
+
+static int isNull( const cost_type x) {
+ return x == NODATA;
+};
+
+static int isNull(const costSourceType x) {
+ return x.getCost() == NODATA;
+};
+
+/* static int isNull(const dimension_type x) { */
+/* return x == NODATA; */
+/* }; */
+
+
+class distanceType;
+
+class basicIJType {
+ dimension_type val_i, val_j;
+
+ friend class distanceType;
+public:
+ basicIJType(dim_t i, dim_t j) : val_i(i), val_j(j) {};
+ basicIJType() : val_i(dim_undef), val_j(dim_undef) {};
+
+ dim_t getI() const { assert(val_i != dim_undef); return val_i; };
+ dim_t getJ() const { assert(val_j != dim_undef); return val_j; };
+ void setI(dim_t gi) {
+ val_i = gi;
+ }
+ void setJ(dim_t gj) {
+ val_j = gj;
+ }
+
+
+
+ void transpose() { /* flip row & col */
+ dim_t tmp = val_i;
+ val_i = val_j;
+ val_j = tmp;
+ }
+
+ friend ostream& operator << (ostream& s, const basicIJType &ct) {
+ s << "(" << ct.val_i << "," << ct.val_j << ")";
+ return s;
+ };
+
+ friend int operator == (const basicIJType &a, const basicIJType &b) {
+ return (a.val_i == b.val_i && a.val_j == b.val_j);
+ };
+ friend int operator != (const basicIJType &a, const basicIJType &b) {
+ return (a.val_i != b.val_i || a.val_j != b.val_j);
+ };
+};
+
+
+template <class T>
+class ijCostType : public basicIJType {
+ private:
+ T cs;
+
+ public:
+
+ ijCostType(dim_t inI, dim_t inJ, T x):
+ basicIJType(inI, inJ), cs(x) {};
+
+#if 0
+ ijCostType(const ijCostType &a):
+ basicIJType(a), cs (a.cs) {};
+#endif
+
+ ijCostType(): basicIJType(-1, -1), cs() {};
+
+#if 0
+ ~ijCostType(){};
+#endif
+
+ T getCost() const{
+ return cs;
+ };
+
+ void setCost(T cost) {
+ cs = cost;
+ }
+
+ int isNull() const {
+ //return isNull(cs);
+ return cs.isNull();
+ };
+
+ void print() {
+ cout << *this;
+ };
+
+ friend ostream& operator << (ostream& s, const ijCostType &ct) {
+ s << "(" << ct.getI() << "," << ct.getJ() << ": " << ct.cs << ")";
+ return s;
+ };
+
+ friend int operator == (const ijCostType &a, const ijCostType &b) {
+ return (basicIJType(a) == basicIJType(b) && a.cs == b.cs);
+ };
+
+};
+
+
+typedef ijCostType<cost_type> ijCost;
+typedef ijCostType<costSourceType> ijCostSource;
+
+template <class T>
+class MinIOCostCompareType {
+ private:
+/* static int tileSizeRows; */
+/* static int tileSizeCols; // Check for problems! 22 June 2004 */
+
+ public:
+
+ void setTileSize(dim_t r, dim_t c) {
+ // MinIOCostCompareType::tileSizeRows = r;
+ // MinIOCostCompareType::tileSizeCols = c;
+ /* check against globals */
+ assert(tsr == r);
+ assert(tsc == c);
+ };
+
+/* int getTileSizeRows() { */
+/* return MinIOCostCompareType::tileSizeRows; */
+/* }; */
+
+/* int getTileSizeCols() { */
+/* return MinIOCostCompareType::tileSizeCols; */
+/* }; */
+
+ /* Method used in conjunction with ami_sort if a < b returns -1 if a
+ == b returns 0 and if a > b returns 1 */
+ static int compare(const ijCostType<T> &a, const ijCostType<T> &b) {
+ dim_t ai, aj, bi, bj;
+ //tsr = MinIOCostCompareType::tileSizeRows;
+ ai = a.getI();
+ aj = a.getJ();
+ bi = b.getI();
+ bj = b.getJ();
+
+ if (ai%(tsr-1) == 0 || bi%(tsr-1) == 0) {
+ if (ai < bi ) return -1;
+ if (ai > bi ) return 1;
+ if (ai == bi) {
+ if (aj < bj) return -1;
+ if (aj > bj) return 1;
+ if (aj == bj) return 0;
+ }
+ }
+ if (ai%(tsr-1) != 0 && bi%(tsr-1) != 0) {
+ if ((ai/(tsr-1)) != (bi/(tsr-1))) {
+ if (ai < bi ) return -1;
+ if (ai > bi ) return 1;
+ }
+ if ((ai/(tsr-1)) == (bi/(tsr-1))) {
+ if (aj < bj) return -1;
+ if (aj > bj) return 1;
+ if (aj == bj) {
+ if (ai < bi) return -1;
+ if (ai > bi) return 1;
+ if (ai == bi) return 0;
+ }
+ }
+ }
+ cout << "We have huge problems here!\n";
+ assert(0); // -RW
+ return 0; //-RW
+ };
+};
+
+
+// Returns -1 if a is less than b (tile order)
+// Returns 0 if equal
+// Returns 1 if b is less than a
+//template <class T>
+class ijTileCostCompareType {
+ private:
+ static int tileSizeRows;
+ static int tileSizeCols; // Check for problems! 22 June 2004
+
+ public:
+
+ void setTileSize(dim_t r, dim_t c) {
+ ijTileCostCompareType::tileSizeRows = r;
+ ijTileCostCompareType::tileSizeCols = c;
+ };
+
+
+ int getTileSizeRows() {
+ return ijTileCostCompareType::tileSizeRows;
+ };
+
+ int getTileSizeCols() {
+ return ijTileCostCompareType::tileSizeCols;
+ };
+
+ /* what does this compare?? -RW */
+ static int compare(const ijCostSource &a, const ijCostSource &b) {
+ int tsr = ijTileCostCompareType::tileSizeRows;
+ int tsc = ijTileCostCompareType::tileSizeCols;
+ if (a.getI()/(tsr-1) < b.getI()/(tsr-1))
+ return -1;
+
+ else if (a.getI()/(tsr-1) == b.getI()/(tsr-1)) {
+ if (a.getJ()/(tsc-1) < b.getJ()/(tsc-1))
+ return -1;
+
+ else if (a.getJ()/(tsc-1) == b.getJ()/(tsc-1)) {
+ if (a.getI() < b.getI())
+ return -1;
+ else if(a.getI() == b.getI()) {
+ if (a.getJ() < b.getJ())
+ return -1;
+ else if (a.getJ() == b.getJ())
+ return 0;
+ }
+ }
+ }
+ return 1;
+ };
+};
+
+
+class ijCostCompareType {
+ private:
+ static int tileSizeRows;
+ static int tileSizeCols; // Check for problems! 22 June 2004
+
+ public:
+
+ void setTileSize(dim_t r, dim_t c) {
+ ijCostCompareType::tileSizeRows = r;
+ ijCostCompareType::tileSizeCols = c;
+ };
+
+
+ int getTileSizeRows() {
+ return ijCostCompareType::tileSizeRows;
+ };
+
+ int getTileSizeCols() {
+ return ijCostCompareType::tileSizeCols;
+ };
+
+ static int compare(const ijCost &a, const ijCost &b) {
+ if (a.getI() < b.getI())
+ return -1;
+
+ else if (a.getI() == b.getI()) {
+ if (a.getJ() < b.getJ())
+ return -1;
+ else if (a.getJ() == b.getJ())
+ return 0;
+ }
+ return 1;
+ };
+};
+
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/input.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/iterator.cc
===================================================================
--- grass-addons/raster/r.terracost/iterator.cc (rev 0)
+++ grass-addons/raster/r.terracost/iterator.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,66 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+
+#include <stdio.h>
+#include "iterator.h"
+
+Iterator::Iterator(Tile* inTile) {
+ iMarker = 0;
+ jMarker = 0;
+ tile = inTile;
+ tileSizeRows = tile->getNumRows();;
+ tileSizeCols = tile->getNumCols();;
+}
+
+Iterator::~Iterator() {
+
+}
+
+
+int
+Iterator::getNext (ijCostSource* out) {
+
+ if (iMarker > tileSizeRows - 1)
+ return 0;
+
+ *out = tile->get(iMarker, jMarker);
+
+ if (iMarker == 0){
+ jMarker++;
+ }
+ else if (iMarker > 0 && iMarker < tileSizeRows-1) {
+ jMarker = jMarker + tileSizeCols-1;
+ }
+
+ else
+ jMarker++;
+
+ if (jMarker >= tileSizeCols) {
+ iMarker++;
+ jMarker = 0;
+ }
+
+ return 1;
+}
+
+void
+Iterator::reset() {
+ iMarker = 0;
+ jMarker = 0;
+}
Added: grass-addons/raster/r.terracost/iterator.h
===================================================================
--- grass-addons/raster/r.terracost/iterator.h (rev 0)
+++ grass-addons/raster/r.terracost/iterator.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,46 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef __ITERATOR_H_
+#define __ITERATOR_H_
+
+#include "input.h"
+#include "tile.h"
+
+
+class Iterator {
+
+ int iMarker;
+ int jMarker;
+
+ int tileSizeRows, tileSizeCols;
+
+ Tile* tile;
+
+ public:
+ Iterator(Tile* inTile);
+
+ ~Iterator();
+
+ void reset();
+
+ int getNext(ijCostSource *out);
+
+};
+
+#endif
Property changes on: grass-addons/raster/r.terracost/iterator.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/locator.cc
===================================================================
--- grass-addons/raster/r.terracost/locator.cc (rev 0)
+++ grass-addons/raster/r.terracost/locator.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,122 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+#include <ostream>
+#else
+#include <ostream.h>
+#endif
+#include <iostream>
+#include <math.h>
+#include <assert.h>
+
+#include "locator.h"
+#include "config.h"
+
+// static int
+// computeNumBoundaries(int total, int tile) {
+// assert(tile > 1);
+// total--;
+// tile--;
+
+// return (int)ceil(((double)total)/tile) + 1;
+// }
+
+
+#define CEIL_A_DIV_B(A,B) (((A)+(B)-1)/(B))
+#define IS_BOUNDARY(row,col) (((row % (tsr-1)) == 0) || ((col % (tsc -1)) == 0))
+
+
+void
+IJClassifier::checker() {
+ dimension_type i, j;
+
+ int ntiles_i = CEIL_A_DIV_B(nrowsPad-1, tsr-1);
+ int ntiles_j = CEIL_A_DIV_B(ncolsPad-1, tsc-1);
+
+ fprintf(stderr, "checker running...\n");
+ fprintf(stderr, "nrows,ncols = %d, %d\n", nrows, ncols);
+ fprintf(stderr, "pad: nrows,ncols = %d, %d\n", nrowsPad, ncolsPad);
+ fprintf(stderr, "ntiles i,j = %d, %d\n", ntiles_i, ntiles_j);
+ fprintf(stderr, "tsr,tsc = %d, %d\n", tsr, tsc);
+
+ for(int ti = 0; ti < ntiles_i; ti++) {
+ for(int tj = 0; tj < ntiles_j; tj++) {
+ int tnum = ti * ntiles_j + tj;
+ //cerr << "Checking tile " << ti << "," << tj << " = " << tnum << endl;
+ for(int i=ti*(tsr-1); i <= ti*(tsr-1)+tsr-1; i++) {
+ for(int j=tj*(tsc-1); j <= tj*(tsc-1)+tsc-1; j++) {
+ if(!IS_BOUNDARY(i,j)) {
+ ijCostSource val(i, j, costSourceType());
+ if(classify(&val) != tnum) {
+ fprintf(stderr, "ti=%d, tj=%d, i=%d, j=%d\n", ti, tj, i, j);
+ fprintf(stderr, "classify=%d\n", classify(&val));
+ assert(0);
+ }
+ }
+ }
+ }
+ }
+ }
+ cerr << "Checker OK" << endl;
+}
+
+
+IJClassifier::IJClassifier(const char* config) {
+ readConfigFile(config);
+
+ //computeNumBoundaries(nrows, tsr);
+ numITiles = (int)ceil((double)(ncolsPad - 1) / (tsc - 1));
+
+#ifndef NDEBUG
+ checker();
+#endif
+}
+
+
+// return tile number
+int
+IJClassifier::classify(const ijCostSource *c) {
+ dimension_type row, col;
+
+ assert(numITiles > 0);
+
+ row = c->getI();
+ col = c->getJ();
+
+ // make sure it's not a boundary point - they belong to several tiles
+ assert(!IS_BOUNDARY(row,col));
+
+// int ipart = (row / (tsr-1)) * (numITiles);
+// int jpart = col / (tsc-1);
+ int ipart = (row-1) / (tsr-1);
+ int jpart = (col-1) / (tsc-1);
+
+// int n = ipart + jpart;
+ int ntiles_j = CEIL_A_DIV_B(ncolsPad-1, tsc-1);
+ int n = ipart * ntiles_j + jpart;
+
+ if(n >= g.ntiles) {
+ fprintf(stderr, "i,j = %d,%d\n", row, col);
+ fprintf(stderr, "ipart=%d; jpart=%d\n", ipart, jpart);
+ assert(n < g.ntiles);
+ }
+ return n;
+}
+
Added: grass-addons/raster/r.terracost/locator.h
===================================================================
--- grass-addons/raster/r.terracost/locator.h (rev 0)
+++ grass-addons/raster/r.terracost/locator.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,32 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#include "input.h"
+#include "types.h"
+
+
+class IJClassifier {
+ int numITiles;
+
+ public:
+ IJClassifier(const char* config);
+
+ int classify(const ijCostSource *ptr);
+
+ void checker();
+};
Property changes on: grass-addons/raster/r.terracost/locator.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/main.cc
===================================================================
--- grass-addons/raster/r.terracost/main.cc (rev 0)
+++ grass-addons/raster/r.terracost/main.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,1234 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <libgen.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+
+extern "C" {
+#include <grass/gis.h>
+#include <grass/glocale.h>
+}
+#include <grass/iostream/ami.h>
+
+#include "main.h"
+#include "common.h" /* declares the globals */
+#include "sortutils.h"
+#include "types.h"
+#include "option.h"
+#include "input.h"
+#include "boundary.h"
+#include "tile.h"
+#include "distanceType.h"
+#include "index.h"
+#include "initialize.h"
+#include "dijkstra.h"
+#include "output.h"
+#include "formatNumber.h"
+#include "debug.h"
+
+static int debug = 0;
+static int info = 0;
+
+//#define DEBUG_LOADGRID
+
+int ijTileCostCompareType::tileSizeRows = 0;
+int ijTileCostCompareType::tileSizeCols = 0;
+// int MinIOCostCompareType<costSourceType>::tileSizeRows = 0;
+// int MinIOCostCompareType<cost_type>::tileSizeRows = 0;
+// int MinIOCostCompareType<costSourceType>::tileSizeCols = 0;
+// int MinIOCostCompareType<cost_type>::tileSizeCols = 0;
+int ijCostCompareType::tileSizeRows = 0;
+int ijCostCompareType::tileSizeCols = 0;
+static struct Cell_head *region = NULL; /* header of the region */
+
+#define S0OUT "tileStr"
+#define S0OUT_ANS "terracost.tileStr"
+#define S0BND "bndStr"
+#define S0BND_ANS "terracost.bndStr"
+#define S1OUT "bspStr"
+#define S1OUT_ANS "terracost.bspStr"
+#define S2BOUT "sbspStr"
+#define S2BOUT_ANS "terracost.sbspStr"
+#define PHASE2BND "phase2Bnd"
+#define PHASE2BND_ANS "terracost.phase2Bnd"
+#define CONFIG "config"
+#define CONFIG_ANS "terracost.config"
+#define STATS "stats"
+#define STATS_ANS "terracost.stats"
+#define DIST_GRID "terracost-lcp.asc"
+
+
+const char *description =
+"\nSynopsis:\n"
+" r.terracost computes a least-cost surface for a given cost grid and\n"
+" set of start points.\n"
+"\nDescription:\n"
+" r.terracost computes a least-cost surface for a given cost grid and\n"
+" set of start points using an approach that scales to very large grids.\n"
+" See \"TerraCost: A Versatile and Scalable Approach for Path Computations on Massive\n"
+" Grid-Based Terrains\" by Hazel, Toma, Vahrenhold and Wickremesinghe (2005).\n"
+" \n numtiles is the tiling factor. Run with -i to see the recommended value.\n"
+" It is possible to run r.terracost in five steps. When running in separate\n"
+" steps, the config file stores temporary information, and other streams\n"
+" (see below) contain intermediate data.\n"
+" Step 0 (setup) inputs from grass; outputs are "S0OUT" and "S0BND"\n"
+" Step 1 (compute substitute graph: intra-tile dijkstra)\n"
+" inputs are "S0OUT" and "S0BND"; outputs are "S1OUT" and "S2BOUT"\n"
+" Step 2 (sorting) input is "S1OUT"; output is "S1OUT"\n"
+" Step 3 (inter-tile) inputs are "S0OUT", "S0BND",\n"
+" "S1OUT", and "S2BOUT"; output is "PHASE2BND"\n"
+" Step 4 (final-tile) inputs are "S0OUT" and "PHASE2BND"; output goes to grass\n"
+"\nFiles:\n"
+" File names are specified relative to "VTMPDIR", or with absolute path\n"
+" (name beginning with /)\n"
+" IOLibrary temporary streams will be in STREAM_DIR\n"
+;
+
+
+/* ---------------------------------------------------------------------- */
+/* get the args from GRASS */
+
+void
+parse_args(int argc, char *argv[]) {
+
+ /* input elevation grid */
+ struct Option *input_cost;
+ input_cost = G_define_option() ;
+ input_cost->key = "cost";
+ input_cost->type = TYPE_STRING;
+ //input_cost->required = YES;
+ input_cost->gisprompt = "old,cell,raster" ;
+ input_cost->description= _("Input cost grid");
+
+ /* source point raster */
+ struct Option *source_grid;
+ source_grid = G_define_option() ;
+ source_grid->key = "start_raster";
+ source_grid->type = TYPE_STRING;
+ //source_grid->required = YES;
+ source_grid->gisprompt = _("Raster of source points");
+ source_grid->description= _("Input raster of source points");
+
+ /* output direction grid */
+ struct Option *output_cost;
+ output_cost = G_define_option() ;
+ output_cost->key = "distance";
+ output_cost->type = TYPE_STRING;
+ //output_cost->required = YES;
+ output_cost->gisprompt = "new,cell,raster" ;
+ output_cost->description= _("Output distance grid");
+
+ /* main memory */
+ struct Option *mem;
+ mem = G_define_option() ;
+ mem->key = "memory";
+ mem->type = TYPE_INTEGER;
+ mem->required = NO;
+ mem->answer = G_store("400"); /* 400MB default value */
+ mem->description = _("Main memory size (in MB)");
+
+ /* temporary STREAM path */
+ struct Option *streamdir;
+ streamdir = G_define_option() ;
+ streamdir->key = "STREAM_DIR";
+ streamdir->type = TYPE_STRING;
+ streamdir->required = NO;
+ streamdir->answer = G_store(dirname(G_tempfile()));;
+ streamdir->description= _("Directory to hold temporary files (they can be large)");
+
+ /* temporary VTMPDIR path */
+ struct Option *vtmpdir;
+ vtmpdir = G_define_option() ;
+ vtmpdir->key = VTMPDIR;
+ vtmpdir->type = TYPE_STRING;
+ vtmpdir->required = NO;
+ char vtmpdirbuf[BUFSIZ];
+ struct passwd *pw;
+ if((pw = getpwuid(getuid())) != NULL) {
+ sprintf(vtmpdirbuf, "/var/tmp/%s", pw->pw_name);
+ } else {
+ sprintf(vtmpdirbuf, "/var/tmp/%d", getuid());
+ }
+ vtmpdir->answer = strdup(vtmpdirbuf); // leak
+ vtmpdir->description= _("Location of intermediate STREAMs");
+
+ struct Flag *help_f; // needed??
+ help_f = G_define_flag();
+ help_f->key = 'h' ;
+ help_f->description = _("Help");
+
+ /* verbose flag */
+ struct Flag *quiet;
+ quiet = G_define_flag() ;
+ quiet->key = 'q' ;
+ quiet->description = _("Quiet");
+
+
+ /* save ascii grid flag */
+ struct Flag *ascii;
+ ascii = G_define_flag() ;
+ ascii->key = 's' ;
+ ascii->description = _("Save output to ASCII file \"DIST_GRID\"") ;
+ /* quiet->answer = 'n'; */
+
+ struct Flag *debug_f;
+ debug_f = G_define_flag();
+ debug_f->key = 'd' ;
+ debug_f->description = "Debug (for developer use)";
+
+ struct Flag *info_f;
+ info_f = G_define_flag();
+ info_f->key = 'i' ;
+ info_f->description = _("Info (prints useful information and exits)");
+
+ /* Run step0 only flag */
+ struct Flag *step0;
+ step0 = G_define_flag();
+ step0->key = '0' ;
+ step0->description = _("Step 0 only (-h for info)");
+ /* step0->answer = 'n'; */
+
+ /* Run step 1 only flag*/
+ struct Flag *step1;
+ step1 = G_define_flag() ;
+ step1->key = '1' ;
+ step1->description = _("Step 1 only (-h for info)");
+ /* step1->answer = 'n'; */
+
+ /* Run step 2 and 3 only flags */
+ struct Flag *step2;
+ step2 = G_define_flag();
+ step2->key = '2' ;
+ step2->description = _("Step 2 only (-h for info)");
+
+ struct Flag *step3;
+ step3 = G_define_flag();
+ step3->key = '3' ;
+ step3->description = _("Step 3 only (-h for info)");
+
+ struct Flag *step4;
+ step4 = G_define_flag();
+ step4->key = '4' ;
+ step4->description = _("Step 4 only (-h for info)");
+
+ /* Number of tiles; used in conjunction with step0 flag */
+ struct Option *numtiles;
+ numtiles = G_define_option() ;
+ numtiles->key = "numtiles";
+ numtiles->type = TYPE_INTEGER;
+ numtiles->required = NO;
+ numtiles->description= _("Number of tiles (-h for info)");
+ numtiles->answer = G_store("-1");
+
+ /* Stem name for stream outputs; used in conjunction with step0 flag */
+ struct Option *s0out;
+ s0out = G_define_option() ;
+ s0out->key = S0OUT;
+ s0out->type = TYPE_STRING;
+ s0out->required = NO;
+ s0out->description= _("Stream name stem for step 0 output");
+ s0out->answer = G_store(S0OUT_ANS);
+
+// struct Option *s1in;
+// s1in = G_define_option() ;
+// s1in->key = "s1in";
+// s1in->type = TYPE_STRING;
+// s1in->required = NO;
+// s1in->description= _("Stream name stem for step 0 output");
+// s1in->answer = G_store("s1in");
+
+ struct Option *s0bnd;
+ s0bnd = G_define_option() ;
+ s0bnd->key = S0BND;
+ s0bnd->type = TYPE_STRING;
+ s0bnd->required = NO;
+ s0bnd->description= _("Stream name for boundary data structure");
+ s0bnd->answer = G_store(S0BND_ANS);
+
+ /* Name for config file output */
+ struct Option *s1out;
+ s1out = G_define_option() ;
+ s1out->key = S1OUT;
+ s1out->type = TYPE_STRING;
+ s1out->required = NO;
+ s1out->description= _("Output file for step 1");
+ s1out->answer = G_store(S1OUT_ANS);
+
+ /* Name for config file output */
+ struct Option *s2bout;
+ s2bout = G_define_option() ;
+ s2bout->key = S2BOUT;
+ s2bout->type = TYPE_STRING;
+ s2bout->required = NO;
+ s2bout->description= _("Output file for source to boundary stream");
+ s2bout->answer = G_store(S2BOUT_ANS);
+
+ /* Name for config file output */
+ struct Option *config;
+ config = G_define_option() ;
+ config->key = CONFIG;
+ config->type = TYPE_STRING;
+ config->required = NO;
+ config->description= _("Name for config file");
+ config->answer = G_store(CONFIG_ANS);
+
+ /* Name for config file output */
+ struct Option *phaseBnd;
+ phaseBnd = G_define_option() ;
+ phaseBnd->key = PHASE2BND;
+ phaseBnd->type = TYPE_STRING;
+ phaseBnd->required = NO;
+ phaseBnd->description= _("Name for phase2Bnd file");
+ phaseBnd->answer = G_store(PHASE2BND_ANS);
+
+
+ /* stats file */
+ struct Option *stats_opt;
+ stats_opt = G_define_option() ;
+ stats_opt->key = "stats";
+ stats_opt->type = TYPE_STRING;
+ stats_opt->required = NO;
+ stats_opt->description= _("Stats file");
+ stats_opt->answer = G_store(STATS_ANS);
+
+ struct Option *tilesAreSorted;
+ tilesAreSorted = G_define_option();
+ tilesAreSorted->key = "tilesAreSorted" ;
+ tilesAreSorted->type = TYPE_STRING;
+ tilesAreSorted->required = NO;
+ tilesAreSorted->description = _("Tiles are sorted (used in grid version) (yes/no)");
+ tilesAreSorted->answer = G_store("no");
+
+
+ /* ************************* */
+ if (G_parser(argc, argv)) {
+ exit (EXIT_FAILURE);
+ }
+
+ assert(opt);
+ opt->cost_grid = input_cost->answer;
+ opt->out_grid = output_cost->answer;
+ opt->source_grid = source_grid->answer;
+ opt->mem = atoi(mem->answer);
+ opt->streamdir= streamdir->answer;
+ opt->vtmpdir= vtmpdir->answer;
+ opt->verbose= (!quiet->answer);
+ opt->ascii = ascii->answer;
+ opt->stats= stats_opt->answer;
+ if(step0->answer) {
+ opt->runMode |= RUN_S0;
+ }
+ if(step1->answer) {
+ opt->runMode |= RUN_S1;
+ }
+ if(step2->answer) {
+ opt->runMode |= RUN_S2;
+ }
+ if(step3->answer) {
+ opt->runMode |= RUN_S3;
+ }
+ if(step4->answer) {
+ opt->runMode |= RUN_S4;
+ }
+ if(opt->runMode == RUN_NONE) {
+ opt->runMode = RUN_ALL;
+ }
+ opt->tilesAreSorted = (tilesAreSorted->answer[0] == 'y');
+ opt->numtiles = atoi(numtiles->answer);
+ opt->s0out = s0out->answer;
+ // opt->s1in = s1in->answer;
+ opt->s1out = s1out->answer;
+ opt->s0bnd = s0bnd->answer;
+ opt->s2bout = s2bout->answer;
+ opt->config = config->answer;
+ opt->phase2Bnd = phaseBnd->answer;
+ opt->s1fd = 0;
+
+ debug = (debug_f->answer ? 1 : 0);
+ info = (info_f->answer ? 1 : 0);
+
+ if(help_f->answer) {
+ G_usage();
+ printf(description);
+ exit(EXIT_SUCCESS);
+ }
+
+
+}
+
+
+/* ---------------------------------------------------------------------- */
+void check_args() {
+
+ /* check if cost grid name is valid */
+ if (G_legal_filename (opt->cost_grid) < 0) {
+ G_fatal_error ("[%s] is an illegal name", opt->cost_grid);
+ }
+ /* check if distance grid names is valid */
+ if (G_legal_filename (opt->out_grid) < 0) {
+ G_fatal_error ("[%s] is an illegal name", opt->out_grid);
+ }
+ if (G_legal_filename (opt->source_grid) < 0) {
+ G_fatal_error ("[%s] is an illegal name", opt->source_grid);
+ }
+
+}
+
+/* ---------------------------------------------------------------------- */
+void record_args(int argc, char **argv) {
+
+ time_t t = time(NULL);
+ char buf[1000];
+ if(t == (time_t)-1) {
+ perror("time");
+ exit(1);
+ }
+
+ ctime_r(&t, buf);
+ buf[24] = '\0';
+ stats->timestamp(buf);
+ *stats << "Not printing stats." << endl;
+ *stats << "Command Line: " << endl;
+ for(int i=0; i<argc; i++) {
+ *stats << argv[i] << " ";
+ }
+ *stats << endl;
+
+ *stats << "input cost grid: " << opt->cost_grid << "\n";
+ *stats << "input source grid: " << opt->source_grid << "\n";
+ *stats << "output distance grid: " << opt->out_grid << "\n";
+
+ size_t mm_size = opt->mem << 20; /* (in bytes) */
+ char tmp[100];
+ formatNumber(tmp, mm_size);
+ sprintf(buf,"memory size: %s bytes", tmp);
+ stats->comment(buf);
+}
+
+
+/* ---------------------------------------------------------------------- */
+void printGrid(AMI_STREAM<ijCost> *testStr) {
+
+ statsRecorder *offsetWriter = new statsRecorder("offset.out");
+
+ AMI_err ae;
+ // won't work with boundary streams
+ //assert(testStr->stream_len() == nrows*ncols);
+ ae = testStr->seek(0);
+ ijCost *it;
+ *offsetWriter << "grid: \n" << "Length: " << testStr->stream_len() << "\n";
+ //for (dimension_type i = 0; i<nrows; i++) {
+ // for (dimension_type j=0; j< ncols; j++) {
+ while (ae != AMI_ERROR_END_OF_STREAM) {
+ ae = testStr->read_item(&it);
+ *offsetWriter << *it << "\n";
+ //assert(ae == AMI_ERROR_NO_ERROR);
+ }
+ testStr->seek(0);
+
+ delete offsetWriter;
+}
+
+/* ---------------------------------------------------------------------- */
+
+//cost_type
+// int
+// getb2bValue(dimension_type iFrom, dimension_type jFrom, dimension_type iTo,
+// dimension_type jTo, TileFactory *tf,
+// AMI_STREAM<distanceType> *b2bstr){
+
+// int fromIndex, toIndex, finalIndex;
+
+// /*
+// cout << "getb2bValue()\n";
+// cout << "iFrom: " << iFrom << " jFrom: " << jFrom << "\n";
+// cout << "iTo: " << iTo << " jTo: " << jTo << "\n";
+// */
+
+// fromIndex = getFromIndex(iFrom, jFrom, tf);
+// toIndex = getToIndex(iFrom, jFrom, iTo, jTo, tf);
+// finalIndex = fromIndex+toIndex-1;
+
+
+// return finalIndex;
+// }
+
+
+
+void
+compute_tilesize(const char *label, int nr, int nc, int mem,
+ int *tilesize, int *numtiles) {
+
+ // assume we need tilesize number of all these, that is, we need all
+ // of these to be in memory while we compute sssp on a tile
+ int elt = ( sizeof(costSourceType) /* tile */
+ + sizeof(cost_type) /* dist */
+ + sizeof(costStructure) ); /* pq */
+
+ printf("%s: avail memory M = %s\n", label, formatNumber(NULL, mem));
+ printf("%s: sizeof elt = %d\n", label, elt);
+ printf("%s: grid size N = %s elements\n", label, formatNumber(NULL, nr*nc));
+
+
+ int ts = mem / elt;
+ int nt = (nr * nc + ts - 1) / ts;
+
+ printf("%s: max tilesize R = %s elements\n",label, formatNumber(NULL, ts));
+
+ //does it fit into memory?
+ if (nt == 1) {
+ printf("%s: fits in memory, use numtiles=1\n", label);
+ } else {
+ if (nt <4) {
+ printf("%s: almost.. fits in memory; try numtiles=1 first\n", label);
+ } else {
+ printf("%s: does NOT fits in memory\n", label);
+ }
+ //optimal tilisize, determined experimentally, is approx. 15,000
+ //elements
+ ts = 15000;
+ nt = nr*nc/ts;
+ }
+
+ printf("%s: %s N=%ld elements, M=%d bytes, optimal numtiles=%d\n",
+ label, G_location(), (long)(nr*nc), mem, nt);
+
+ *numtiles = nt;
+ *tilesize = ts;
+}
+
+
+/* ---------------------------------------------------------------------- */
+int
+main(int argc, char *argv[]) {
+ struct GModule *module;
+ char buf[1000];
+
+ /* initialize GIS library */
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+
+ /* get the current region and dimensions */
+ region = (struct Cell_head*)malloc(sizeof(struct Cell_head));
+ assert(region);
+ if (G_get_set_window(region) == -1) {
+ G_fatal_error("r.terracost: error getting current region");
+ }
+ int nr = G_window_rows();
+ int nc = G_window_cols();
+
+ if ((nr > dimension_type_max) || (nc > dimension_type_max)) {
+ printf("[nrows=%d, ncols=%d] dimension_type overflow--change dimension_type and recompile\n",nr,nc);
+ G_fatal_error("[nrows=%d, ncols=%d] dimension_type overflow--change dimension_type and recompile\n",nr,nc);
+ } else {
+ nrows = (dimension_type)nr;
+ ncols = (dimension_type)nc;
+ nrowsPad = (dimension_type)nr;
+ ncolsPad = (dimension_type)nc;
+ }
+
+ /* read user options; fill in global <opt> */
+ opt = (userOptions*)malloc(sizeof(userOptions));
+ assert(opt);
+ parse_args(argc, argv);
+
+
+ /* setup STREAM_DIR */
+ sprintf(buf, "%s=%s", STREAM_TMPDIR, opt->streamdir);
+ putenv(buf);
+ if (getenv(STREAM_TMPDIR) == NULL) {
+ fprintf(stdout, "%s:", STREAM_TMPDIR);
+ G_fatal_error("not set");
+ } else {
+ fprintf(stdout, "STREAM temporary files in %s\n", getenv(STREAM_TMPDIR));
+ fprintf(stdout, "THESE TEMPORARY STREAMS WILL NOT BE DELETED "
+ "IN CASE OF ABNORMAL TERMINATION OF THE PROGRAM.\n");
+ fprintf(stdout, "TO SAVE SPACE PLEASE DELETE THESE FILES MANUALLY!\n");
+ }
+
+
+ /* setup VTMPDIR */
+ sprintf(buf, "%s=%s", VTMPDIR, opt->vtmpdir);
+ putenv(buf);
+ if (getenv(VTMPDIR) == NULL) {
+ fprintf(stdout, "%s: environment not set", VTMPDIR);
+ exit(1);
+ } else {
+ fprintf(stdout, "terracost intermediate files in %s\n", getenv(VTMPDIR));
+ }
+ if(opt->runMode != RUN_ALL) {
+ struct stat sb;
+ if(stat(opt->vtmpdir, &sb) < 0) {
+ perror(opt->vtmpdir);
+ // this is only fatal if we actually need the directory. ie: we
+ // are using intermediate files, and one or more uses relative paths.
+ // allow it for now
+ fprintf(stderr, "%s: WARNING! This could cause errors if relative intermediate files in use\n", opt->vtmpdir);
+ // try to make VTMPDIR, just to avoid common problem
+ fprintf(stderr, "%s: trying to create\n", opt->vtmpdir);
+ if(mkdir(opt->vtmpdir, 0777)) {
+ if(errno != EEXIST) {
+ perror(opt->vtmpdir);
+ // this might not be a fatal error (maybe we dont use it), so go on -RW
+ //exit(1);
+ }
+ }
+ }
+ }
+
+
+ if(info) {
+ printf("\n");
+ printf("STREAM_TMPDIR=%s\n", getenv(STREAM_TMPDIR));
+ printf("VTMPDIR=%s\n", getenv(VTMPDIR));
+
+ int tilesize, numtiles;
+ compute_tilesize("TILESIZE", nrows, ncols, opt->mem << 20,
+ &tilesize, &numtiles);
+ //LT: i took this out, since i dont agree
+ //compute_tilesize("TILE IN CACHE CALC", nrows, ncols, 512 << 10,
+ // &tilesize, &numtiles);
+
+ exit(0);
+ }//info
+
+ if(opt->verbose) {
+ printf("region size is %d x %d\n", nrows, ncols);
+ }
+
+
+ /* quick check for (some) required args */
+ if( (opt->runMode & RUN_S0) && (!opt->cost_grid || !opt->source_grid) ) {
+ fprintf(stderr, "ERROR: required input argument missing\n");
+ G_usage();
+ printf(description);
+ exit(1);
+ }
+ if( (opt->runMode & RUN_S4) && (!opt->out_grid)) {
+ fprintf(stderr, "ERROR: required output argument missing\n");
+ G_usage();
+ printf(description);
+ exit(1);
+ }
+
+
+ // PICK A GOOD NUMBER OF TILES HERE
+ if(opt->numtiles < 1) {
+ fprintf(stderr, "ERROR: numtiles not set; default value=-1\n");
+ fprintf(stderr, "ERROR: numtiles must be >= 1\n");
+ exit(1);
+ }
+
+
+ /* open the stats file */
+ {
+ // note: this is a hack. the default should be set earlier, and just used here -RW
+ if(opt->stats[0] != '/') { // relative path
+ char location[BUFSIZ];
+ //sprintf(location, "%s-%s", G_location(), opt->stats);
+ sprintf(location, "%s", resolvePath(opt->stats));
+ stats = new statsRecorder(location);
+ } else { // absolute path; dont mess with name
+ stats = new statsRecorder(opt->stats);
+ }
+ }
+
+ /* record some info in stats file */
+ record_args(argc, argv);
+ {
+ char buf[BUFSIZ];
+ long grid_size = nrows * ncols;
+ *stats << "region size = " << formatNumber(buf, grid_size) << " elts "
+ << "(" << nrows << " rows x " << ncols << " cols)\n";
+
+ stats->flush();
+ }
+
+
+ /* set up STREAM memory manager */
+ size_t mm_size = opt->mem << 20; /* opt->mem is in MB */
+ MM_manager.set_memory_limit(mm_size);
+ if (opt->verbose) {
+ MM_manager.warn_memory_limit();
+ } else {
+ MM_manager.ignore_memory_limit();
+ }
+ MM_manager.print_limit_mode();
+
+ /* initializes values used in update.cc */
+ Cell_head window;
+ int ok = G_get_window(&window);
+ assert(ok >= 0);
+ opt->EW_fac = 1.0 ;
+ opt->NS_fac = window.ns_res/window.ew_res ;
+ opt->DIAG_fac = (double)sqrt((double)(opt->NS_fac*opt->NS_fac +
+ opt->EW_fac*opt->EW_fac));
+ opt->V_DIAG_fac = (double)sqrt((double)(4*opt->NS_fac*opt->NS_fac +
+ opt->EW_fac*opt->EW_fac));
+ opt->H_DIAG_fac = (double)sqrt((double)(opt->NS_fac*opt->NS_fac +
+ 4*opt->EW_fac*opt->EW_fac));
+ update_init(opt->EW_fac, opt->NS_fac, opt->DIAG_fac);
+
+ /* start timing -- after parse_args, which are interactive */
+ Rtimer rtTotal;
+ rt_start(rtTotal);
+
+
+ /////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////
+
+ /* ************************************************** */
+ /* STEP: set up tile size, padded grid size and load cost grid and
+ compute substitute graph */
+
+ size_t availmem1;
+ availmem1 = MM_manager.memory_available();
+ char memBuf [100] = "";
+ formatNumber(memBuf, availmem1);
+
+ long nodata_count;
+
+ // we don't really know yet, since we might read it from config...
+ //*stats << "numtiles = " << opt->numtiles << endl;
+
+ size_t mem = memForNormalDijkstra(nrows, ncols);
+ if (/*mem < availmem1 */ opt->numtiles == 1) {
+ cout << "Using normal Dijkstra" << endl;
+ stats->comment("Using normal Dijkstra");
+ normalDijkstra(opt->cost_grid,opt->source_grid, &nodata_count);
+ goto cleanup;
+ }
+ {
+ /* Because of all of the if-statements we need to declare these
+ here -- huh? why? XXX-RW */
+ TileFactory *tf=NULL;
+ dimension_type tileSizeRows, tileSizeCols;
+ AMI_STREAM<distanceType> *b2bstr = NULL;
+ AMI_STREAM<ijCost> *s2bstr = NULL;
+ size_t tilemem; /* how much memory we want for a tile */
+ size_t tfmem; /* how much memory we want for the tile factory */
+ size_t bndmem; /* how much memory we want for the bnd dsrt in STEP 2 */
+
+ /*
+ normally we would set the tile size such that :
+ tilesize*sizeof<ijCostType> + tilesize*sizeof(<costType) = avail,
+ which gives tilesize = avail/(sizeof(ijCostType) +
+ sizeof(<costType>)). in this case the tile factory tf
+ (i.e. bndpoints) will be stored as a stream on disk and use no
+ memory.
+
+ we can compromise for a smaller tile and save part of the
+ memory to store the tile factory (boundary points) in memory as
+ well. For small N (grid size) the bnd dstrs may fit completely
+ in memory and will be faster than if it was on disk.
+ */
+
+ /* normally tilemem = availmem; tfmem = 0;bndmem = 0; */
+ tilemem = availmem1 / 2;
+ tfmem = availmem1 / 4;
+ bndmem = availmem1 / 4;
+
+ //if(!opt->step1 && !opt->step2) {
+ if(opt->runMode & RUN_S0) {
+ stats->comment("----------------------------------------");
+ stats->comment("STEP 0: COMPUTE SUBSTITUTE GRAPH");
+ *stats << endl;
+ *stats << "Memory Available: " << memBuf << "bytes\n";
+
+ /* in STEP 0/1 memory is used for:
+ - a tile<ijCostType>
+ - a tileFactory structure, which is a boundary dstr of
+ <costSourceType> (if ARRAY) or <ijCostType> (if STRREAM)
+ - a PQ for bnd 2 bnd Dijkstra in a tile
+ - a PQ for source 2 bnd Dijkstra in a tile
+ - a tile<costType>
+
+ - are we forgetting anything??check!!
+ */
+
+
+ /* dimension of a tile */
+
+ //if (opt->step0) {
+ //if(opt->runMode & RUN_S0) {
+ /* sets tileSizeRows and tileSizeCols based on a user defined
+ number of tiles */
+ initializeTileSize(&tileSizeRows, &tileSizeCols, opt->numtiles);
+ tsr = tileSizeRows;
+ tsc = tileSizeCols;
+ tf = new TileFactory(tileSizeRows, tileSizeCols, 0);
+ g.ntiles = tf->getNumTiles();
+ cout << "Original Grid Size: " << nrows << "x" << ncols << endl;
+ cout << "TF #Tiles: " << g.ntiles << endl; cout.flush();
+ // }
+ // else {
+
+ // /* sets tileSizeRows, tileSizeCols, nrowsPad, ncolsPad
+ // given the memory to be used by a tile; the size of a tile
+ // is chosen so that a tile uses at most tilemem memory; in
+ // order that boundary tiles have same size as internal tiles
+ // we pad the grid we extra rows and columns; the size of the
+ // grid is thus (nrowsPad, ncolsPad) */
+ // initializeTileSize(&tileSizeRows, &tileSizeCols, tilemem);
+ // /*normally tilesize = tilemem /(sizeof(ijCostType) +
+ // sizeof(costType));*/ //tileSizeRows = 4; //tileSizeCols =
+ // 5;
+
+ // /* create a tileFactory structure that will know how to
+ // extract a tile from a a grid and how to iterate on
+ // tiles. This structure should never use more than tfmem
+ // memory */
+
+ // tf = new TileFactory(tileSizeRows, tileSizeCols, tfmem);
+ // ntiles = tf->getNumTiles();
+ // }
+
+ /* read input cost grid and populate tf */
+ loadGrid(opt->cost_grid,opt->source_grid, &nodata_count, tf);
+ *stats <<"Total elements read=" << formatNumber(NULL, (long)nrows*ncols);
+ *stats <<", nodata elements=" << formatNumber(NULL, nodata_count) <<endl;
+
+ /* since we work internally with a padded grid, we need to add the
+ padded values to bndCost and intCost */
+ tf->pad();
+
+ /* Sorting messes up the stream name on disk */
+ // already below
+ // if (!opt->step0)
+ // tf->sortTF();
+
+ // if(debug) {
+ // dump_file((const char *)VTMPDIR "s0out", (const char *)VTMPDIR "s0out.dump", ijCostSource());
+ // dump_file((const char *)VTMPDIR "s0bnd", (const char *)VTMPDIR "s0bnd.dump", ijCostSource());
+ // }
+
+ if(opt->runMode != RUN_ALL) {
+
+ tf->serialize(resolvePath(opt->s0bnd));
+ writeConfigFile(resolvePath(opt->config));
+ //exit(0);
+ }
+ }
+
+
+ /* @S1 */
+
+ if(opt->runMode & RUN_S1) {
+ stats->comment("----------------------------------------");
+ stats->comment("STEP 1");
+ Rtimer rtStep;
+ rt_start(rtStep);
+
+ if(!(opt->runMode & RUN_S0)) {
+ stats->comment("restoring data structures...");
+ readConfigFile(resolvePath(opt->config));
+
+ // if(debug) {
+ // opt->s1fd = open(resolvePath(opt->s1in), O_RDONLY);
+ // if(opt->s1fd < 0) {
+ // perror(resolvePath(opt->s1in));
+ // exit(1);
+ // }
+ // cerr << "debug: using fd " << opt->s1fd << " for file " << buf << endl;
+ // }
+
+ AMI_STREAM<ijCostSource> *dataStream;
+ if(opt->s1fd > 0) {
+#ifdef PEARL
+ dataStream = new AMI_STREAM<ijCostSource>(opt->s1fd, AMI_READ_STREAM);
+#else
+ assert(0);
+ dataStream = NULL;
+#endif
+ } else {
+ dataStream = new AMI_STREAM<ijCostSource>(resolvePath(opt->s0out),
+ AMI_READ_STREAM);
+ }
+
+ tf = new TileFactory(tsr, tsc, dataStream, resolvePath(opt->s0bnd));
+ } // end exclusively-step1 init
+
+ /* this sort is a permute to get the tiles in order.
+ * in parallel version, we want to just split here;
+ * we will get the sort for free within a tile.
+ * (each tile is a separate file) -RW */
+ if(! opt->tilesAreSorted) {
+ tf->sortTF();
+ }
+ if(opt->tilesAreSorted) { // maybe this sould be a different option...
+ tf->markBoundaryAsSorted();
+ }
+
+ /*
+ Run Dijkstra on each tile and compute bnd2bnd SP; these will be
+ stored in b2bstr; also, for each point on the bnd of the tile,
+ compute SP to any source point in the tile; store this in s2bstr.
+ */
+ // outputs
+ if(opt->runMode != RUN_ALL) {
+ b2bstr = new AMI_STREAM<distanceType>(resolvePath(opt->s1out),
+ AMI_WRITE_STREAM);
+ s2bstr = new AMI_STREAM<ijCost>(resolvePath(opt->s2bout),
+ AMI_WRITE_STREAM);
+ } else {
+ b2bstr = new AMI_STREAM<distanceType>();
+ s2bstr = new AMI_STREAM<ijCost>();
+ }
+
+ tf->reset();
+
+ assert(s2bstr);
+ computeSubstituteGraph(tf, b2bstr, s2bstr);
+
+// if(debug) {
+// dump_file(b2bstr->name(), "/tmp/s1out.dump", distanceType());
+// dump_file(s2bstr->name(), "/tmp/s2bout.dump", ijCost());
+// }
+
+ /* sort b2bstr by (<i,j>,<i,j>) */
+// if (!opt->step1) {
+// cout << "Sorting b2b stream" << endl;
+// stats->comment("Sorting b2bstr");
+// distanceCompareType srtFun;
+// sort(&b2bstr, srtFun);
+// }
+ //printStream(b2bstr);
+ //printStream(s2bstr);
+ //if(opt->runMode == RUN_S1) {
+ //exit(0);
+ //}
+
+ rt_stop(rtStep);
+ stats->recordTime("STEP1", rtStep);
+ }
+
+
+
+
+
+
+ /* ************************************************** */
+ /* @S2 STEP 2: compute for each boundary point, the SP to any
+ source. These will be stored in phase2Bnd.
+
+ memory in step 2 is used to store:
+ - a boundaryClass dstr that stores SP to all bnd vertices
+ - the PQ
+ - an array that stores whether a point has been settled or not
+ - are we forgetting anything??check !!!
+ */
+
+ /* step2 = old step2a - just the big sort */
+
+ if(opt->runMode & RUN_S2) {
+ stats->comment("----------------------------------------");
+ stats->comment("STEP 2");
+ Rtimer rtStep;
+ rt_start(rtStep);
+
+ if(!(opt->runMode & RUN_S1)) {
+ stats->comment("restoring data structures...");
+ readConfigFile(resolvePath(opt->config));
+ // tileSizeRows = tsr;
+ // tileSizeCols = tsc;
+
+ b2bstr = new AMI_STREAM<distanceType>(resolvePath(opt->s1out));
+ b2bstr->persist(PERSIST_PERSISTENT);
+ //cout << "b2bLen: " << b2bstr->stream_len() << endl;cout.flush();
+ stats->recordLength("b2bstr ", b2bstr);
+ }
+
+ /* sort and rename */
+
+ /* in the parallel version, this could be just a merge of runs. */
+ cout << "Sorting b2b stream" << endl; cout.flush();
+ stats->comment("Sorting b2bstr");
+ distanceIJCompareType srtFun;
+ char *b2bstrname;
+ b2bstr->name(&b2bstrname);
+
+ if(opt->runMode == RUN_ALL) {
+ sort(&b2bstr, srtFun);
+ } else {
+ AMI_STREAM<distanceType> *sortedStr;
+ int deleteInput = 1;
+ AMI_sort(b2bstr, &sortedStr, &srtFun, deleteInput, b2bstrname);
+ b2bstr = sortedStr;
+ b2bstr->seek(0);
+ }
+ delete b2bstrname;
+
+#if 0
+ sort(&b2bstr, srtFun);
+ //printStream(b2bstr);
+
+ if(opt->runMode != RUN_ALL) {
+ char *b2bstrname_new;
+ b2bstr->name(&b2bstrname_new);
+ b2bstr->persist(PERSIST_PERSISTENT);
+ delete b2bstr;
+ if(rename(b2bstrname_new, b2bstrname) < 0) {
+ cerr << "WARNING could not rename " << b2bstrname_new << " to " << b2bstrname << endl;
+ perror("rename");
+ cerr << "continue computation using s1out=" << b2bstrname_new << "." << endl;
+ // how to free opt->s1out? leak it!
+ opt->s1out = strdup(b2bstrname_new); // fix the name
+ cerr << "continuing..." << endl;
+ }
+ delete b2bstrname;
+ delete b2bstrname_new;
+ }
+#endif
+
+ rt_stop(rtStep);
+ stats->recordTime("STEP2", rtStep);
+ }
+
+
+ BoundaryType<cost_type> *phase2Bnd = NULL;
+
+
+
+ /* ************************************************************ */
+ /* STEP 3 */
+ /* ************************************************************ */
+ /* step3 = old step2 (sans big sort) and old step3 */
+ if(opt->runMode & RUN_S3) {
+ stats->comment("----------------------------------------");
+ stats->comment("STEP 3");
+ Rtimer rtStep;
+ rt_start(rtStep);
+
+ if(!(opt->runMode & RUN_S2)) {
+ stats->comment("restoring data structures...");
+ readConfigFile(resolvePath(opt->config));
+ tileSizeRows = tsr;
+ tileSizeCols = tsc;
+
+ AMI_STREAM<ijCostSource> *dataStream;
+ dataStream = new AMI_STREAM<ijCostSource>(resolvePath(opt->s0out), AMI_READ_STREAM);
+ stats->recordLength("dataStream ", dataStream);
+
+ tf = new TileFactory(tsr, tsc, dataStream, resolvePath(opt->s0bnd));
+ tf->sortTF();
+
+ s2bstr = new AMI_STREAM<ijCost>(resolvePath(opt->s2bout));
+ assert(s2bstr);
+ s2bstr->persist(PERSIST_PERSISTENT);
+ stats->recordLength("s2bstr ", s2bstr);
+
+ b2bstr = new AMI_STREAM<distanceType>(resolvePath(opt->s1out));
+ b2bstr->persist(PERSIST_PERSISTENT);
+ // *stats << "b2bLen: " << b2bstr->stream_len() << endl;
+ stats->recordLength("b2bstr ", b2bstr);
+
+ }
+ if(debug) {
+ dump_file(b2bstr->name(), "/tmp/s1out.dump", distanceType());
+ dump_file(s2bstr->name(), "/tmp/s2bout.dump", ijCost());
+ }
+
+ // ************INTER-TILE ************
+ Rtimer rtInterTile;
+ rt_start(rtInterTile);
+ size_t availmem2, availmem3;
+ availmem2 = MM_manager.memory_available();
+ formatNumber(memBuf, availmem2);
+ stats->comment("----------------------------------------");
+ stats->comment("INTER TILE DIJKSTRA");
+ *stats << "Memory Available: " << memBuf << " bytes\n";
+
+ cout << "nrowsPad: " << nrowsPad << " ncolsPad: " << ncolsPad << endl;
+ cout << "tsr: " << tsr << " tsc: " << tsc << endl;
+ cout << "tileSizeRows: " << tf->getRows() << " tileSizeCols: "
+ << tf->getCols() << endl;
+ cout.flush();
+
+ cerr << "creating phase2Bnd" << endl; cout.flush();
+ //the dstr to handle the distances from each boundary to a
+ //source point
+ phase2Bnd =
+ new BoundaryType<cost_type>(tileSizeRows, tileSizeCols, BND_ARRAY);
+
+ cout << "initializing phase2Bnd" << endl; cout.flush();
+ /* since we are using an in-memory boundary, we consult the values
+ * in updateInterNeighbors (interTileDijkstra) */
+ phase2Bnd->initialize(cost_type_max);
+ cout << "initializing phase2Bnd." << endl; cout.flush();
+
+ *stats << "tileFactory uses " << tf->memoryUsage() << " bytes\n";
+ *stats << "phase2Bnd uses "<< phase2Bnd->memoryUsage()<<" bytes\n";
+
+ availmem3 = MM_manager.memory_available();
+ formatNumber(memBuf, availmem3);
+ *stats << "Memory Available for pqueue " << memBuf << " bytes\n;";
+ assert(s2bstr);
+ cout << "inter-tile dijkstra" << endl; cout.flush();
+ interTileDijkstra(s2bstr, b2bstr, phase2Bnd, tf);
+ delete s2bstr;
+ delete b2bstr;
+ rt_stop(rtInterTile);
+ stats->recordTime("INTER-TILE DIJKSTRA:end", rtInterTile);
+ //cerr << "main: after interTileDijkstra: phase2Bnd len=" <<
+ //phase2Bnd->length() << endl;
+
+ //save structure for next step
+ if (!(opt->runMode & RUN_S4)) {
+ cout << "saving phase2Bnd\n"; cout.flush();
+ phase2Bnd->serialize(resolvePath(opt->phase2Bnd));
+ }
+
+ rt_stop(rtStep);
+ stats->recordTime("STEP3", rtStep);
+ } //step3
+
+
+
+ /* ************************************************************ */
+ /* STEP 4 */
+ /* ************************************************************ */
+ if(opt->runMode & RUN_S4) {
+
+ //printf("runMode=%d run_s4=%d\n", opt->runMode, RUN_S4);
+ stats->comment("----------------------------------------");
+ stats->comment("STEP 4");
+ Rtimer rtStep;
+ rt_start(rtStep);
+
+ /* ************************************************** */
+ /* compute for each tile the SP to each point inside the
+ tile and write resulting distances to finalstr
+
+ memory is used to store:
+ - a tile <ijCostType>
+ - a tile <costType>
+ - a PQ
+ - a tileFactory structure, which is a boundary dstr of <ijCostType>
+ - phase2Bnd, that is a boundary dstr of <ijCostType>
+
+ */
+
+ if(!(opt->runMode & RUN_S3)) {
+ stats->comment("restoring data structures...");
+ readConfigFile(resolvePath(opt->config));
+ tileSizeRows = tsr;
+ tileSizeCols = tsc;
+
+ AMI_STREAM<ijCostSource> *dataStream;
+ dataStream = new AMI_STREAM<ijCostSource>(resolvePath(opt->s0out),
+ AMI_READ_STREAM);
+ tf = new TileFactory(tsr, tsc, dataStream, resolvePath(opt->s0bnd));
+
+ if(! opt->tilesAreSorted) {
+ tf->sortTF();
+ }
+ if(opt->tilesAreSorted) { // maybe this sould be a different option...
+ tf->markBoundaryAsSorted();
+ }
+
+ //phase2Bnd
+ phase2Bnd =
+ new BoundaryType<cost_type>(tileSizeRows, tileSizeCols, BND_ARRAY);
+ cerr << "restoring phase2Bnd" << endl;
+ phase2Bnd->reconstruct(resolvePath(opt->phase2Bnd));
+
+ } else {
+ //if step3 was run just before this, then phase2Bnd should be
+ //still around
+ assert(phase2Bnd);
+ }//end reconstruct
+
+ //this should be known t this point (either form step3 or
+ //reconstructed)
+ assert(phase2Bnd);
+
+ size_t availmem_i;
+ availmem_i = MM_manager.memory_available();
+ formatNumber(memBuf, availmem_i);
+ //cout << "Memory Available: " << memBuf << "\n";
+ stats->comment("----------------------------------------");
+ stats->comment("IN-TILE FINAL DIJKSTRA");
+ *stats << "Memory Available: " << memBuf << " bytes\n";
+
+
+ /* the SP(s, internal points) are dumped to finalstr */
+ AMI_STREAM<ijCost> *finalstr = new AMI_STREAM<ijCost>();
+ cerr << "finalstr = " << finalstr->name() << endl;
+
+ Rtimer rtFinalDijkstra;
+ rt_start(rtFinalDijkstra);
+ finalDijkstra(tf, phase2Bnd, finalstr);
+ assert(tf);
+ delete tf;
+
+ /* sort finalstr in (i,j) order */
+ ijCostCompareType normalSort;;
+ normalSort.setTileSize(tileSizeRows,tileSizeCols);
+ sort(&finalstr, normalSort);
+ //printStream(finalstr);
+ rt_stop(rtFinalDijkstra);
+ stats->recordTime("FINAL DIJSKTRA", rtFinalDijkstra);
+ //phase2Bnd->print();
+
+ /* write to grass grid */
+ writeToGrassFile(finalstr, phase2Bnd);
+
+ //save to ascii file
+ if (opt->ascii) {
+ stream2ascii(finalstr, phase2Bnd, resolvePath(DIST_GRID) );
+ }
+
+ delete finalstr;
+ delete phase2Bnd;
+ size_t availmem4;
+ availmem4 = MM_manager.memory_available();
+ formatNumber(memBuf, availmem4);
+ /* note: availmem4 should be availmem1 */
+ cout << "Memory Available: " << memBuf << "\n"; cout.flush();
+ *stats << "Memory Available: " << memBuf << " bytes\n";
+
+ rt_stop(rtStep);
+ stats->recordTime("STEP4", rtStep);
+
+ } //step 4
+
+ rt_stop(rtTotal);
+ stats->recordTime("Total running time", rtTotal);
+ stats->timestamp("end");
+ }
+ cleanup:
+ /* CLEAN up */
+ cout << "cleaning up\n"; cout.flush();
+ free(region);
+ free(opt);
+ delete stats;
+ cout << "r.terracost done\n"; cout.flush();
+
+ return 0;
+}
+
+
+
+
+
+
Added: grass-addons/raster/r.terracost/main.h
===================================================================
--- grass-addons/raster/r.terracost/main.h (rev 0)
+++ grass-addons/raster/r.terracost/main.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,22 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef __main_H
+#define __main_H
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/main.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/option.h
===================================================================
--- grass-addons/raster/r.terracost/option.h (rev 0)
+++ grass-addons/raster/r.terracost/option.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,75 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef option_h
+#define option_h
+
+
+#define RUN_NONE 0
+#define RUN_S0 0x001
+#define RUN_S1 0x002
+#define RUN_S2 0x004
+#define RUN_S3 0x008
+#define RUN_S4 0x010
+#define RUN_ALL (RUN_S0 | RUN_S1 | RUN_S2 | RUN_S3 | RUN_S4)
+
+
+
+typedef struct {
+ char* cost_grid; /* name of input elevation grid */
+
+ char* out_grid; /* name of output filled elevation grid */
+
+ char* source_grid; //name or source raster
+
+ int mem; /* main memory, in MB */
+ char* streamdir; /* location of temposary STREAMs */
+ char *vtmpdir; /* location of intermediate streams */
+
+ char* stats; /* stats file */
+ int verbose; /* 1 if verbose, 0 otherwise */
+ int ascii; /* 1 if save output to ascii file */
+
+ //int step0; /* 1 if step0 only, 0 otherwise */
+ //int step1; /* 1 if step1 only, 0 otherwise */
+ //int step2; /* 1 if step 2 and 3 only, 0 otherwise */
+ int runMode; /* which step(s) to run */
+
+ int numtiles; /* number of tiles in the grid */
+ char* s0out; /* base name for step 1 output streams */
+ // char* s1in;
+ int s1fd; /* file descriptor containing step 0 streams */
+ char* s0bnd;
+ char* s1out;
+ char* s2bout; /* base name for source to boundary output streams */
+ char* config; /* config file stores number of tiles, size of
+ tiles and total size of grid */
+ char* phase2Bnd; //phase2Bnd
+
+ double EW_fac, NS_fac, DIAG_fac, V_DIAG_fac, H_DIAG_fac;
+
+ int tilesAreSorted; /* before computing substitute graph; set if
+ * sort by tile order is not needed */
+
+} userOptions;
+
+
+
+
+
+#endif
+
Property changes on: grass-addons/raster/r.terracost/option.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/output.cc
===================================================================
--- grass-addons/raster/r.terracost/output.cc (rev 0)
+++ grass-addons/raster/r.terracost/output.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,304 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#include "output.h"
+
+#define UNREACHABLE_VALUE 99999999
+
+
+int isUnreachable(float dist) {
+ //if (dist == cost_type_max) return 1;
+ if ((cost_type_max -dist) < 1000) return 1;
+ return 0;
+}
+
+
+/*
+void
+mergeStream(AMI_STREAM<ijCost> *instr, BoundaryType<cost_type> *inbnd,
+ AMI_STREAM<ijCost> *outstr) {
+
+ //cout << "In Merge\n";cout.flush();
+
+ AMI_err ae;
+ ijCostType *point = &ijCostType();
+
+ int count = 0;
+ cout << "Post Decs\n";cout.flush();
+ for (int i = 0; i<nrowsPad;i++) {
+ for (int j = 0; j<ncolsPad;j++) {
+ if (inbnd->isBoundary(i,j)) {
+ inbnd->get(i,j,point);
+ }
+ else {
+ ae = instr->read_item(&point);
+ assert (ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ }
+ ae = outstr->write_item(*point);
+ assert (ae == AMI_ERROR_NO_ERROR);
+ if (ae == AMI_ERROR_NO_ERROR)
+ count++;
+ }
+ }
+
+ cout << "Num Merges: " << count << "\n"; cout.flush();
+ }*/
+
+
+/* This is a method which takes a 2D array as input and outputs a
+GRASS rasted file. IT also takes the number of rows and cols and a
+file name as input*/
+void
+grid2Grass(cost_type ** grid, dimension_type rows, dimension_type cols,
+ char* cellname) {
+ assert(grid && cellname);
+
+
+ int outfd;
+ if ( (outfd = G_open_raster_new (cellname, FCELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname);
+ }
+
+ cout << "Opened raster file " << cellname << " for writing.\n";cout.flush();
+
+ /* Allocate output buffer */
+ unsigned char *outrast;
+ outrast = (unsigned char *)G_allocate_raster_buf(FCELL_TYPE);
+ assert(outrast);
+
+
+ for (int i=0; i< rows; i++) {
+ for (int j=0; j< cols; j++) {
+
+ /* WRITE VALUE */
+ if (grid[i][j] == NODATA || grid[i][j] == cost_type_max) {
+ G_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
+ } else {
+ ((FCELL *) outrast)[j] = (FCELL)(grid[i][j]);
+ //cout << "(" << i << "," << j << "): " << grid[i][j] << "\n";
+ }
+
+
+ } /* for j*/
+ if (G_put_raster_row (outfd, outrast, FCELL_TYPE) < 0) {
+ G_fatal_error ("Cannot write to <%s>",cellname);
+ }
+ }/* for i */
+
+ fprintf(stderr, "\n");
+
+ G_free(outrast);
+ G_close_cell (outfd);
+ return;
+}
+
+
+
+
+
+void
+stream2ascii(AMI_STREAM<ijCost> *instr, BoundaryType<cost_type> *inbnd,
+ const char* fname) {
+
+ cout << "stream2ascii: start\n";cout.flush();
+ assert(instr && inbnd && fname);
+
+ FILE* fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "cannot open file %s\n", fname);
+ exit(1);
+ }
+ cout << "writing grid ascii file " << fname << endl;cout.flush();
+
+ //write header
+ fprintf(fp, "rows: %d\n", nrows);
+ fprintf(fp, "cols: %d\n", ncols);
+ fprintf(fp, "nodata: %d\n", NODATA);
+
+ AMI_err ae;
+ ijCost *elt, temp;
+ cost_type eltVal;
+
+ ae = instr->seek(0);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+
+ int readNewItem = 1;
+ for (int i=0; i< nrows; i++) {
+ for (int j=0; j< ncols; j++) {
+
+ //get value
+ if (inbnd->isBoundary(i,j)) {
+ //boundary
+ inbnd->get(i, j, &temp);
+ eltVal = temp.getCost();
+ assert(temp.getI() == i && temp.getJ() == j);
+ }
+ else {
+ //internal point
+ if (readNewItem) {
+ ae = instr->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ }
+ if(ae == AMI_ERROR_NO_ERROR && elt->getI() == i && elt->getJ() == j) {
+ eltVal = elt->getCost();
+ readNewItem = 1;
+ } else {
+ //fill in value with NODATA
+ readNewItem = 0;
+ eltVal = NODATA;
+ }
+ }
+ //the value is not noData, but it can be unreachable, if its
+ //cost value is equal to the initial value (infinity, in this
+ //case cost_type_max; in this case set it to some smaller
+ //LARGE value
+ if (isUnreachable(eltVal)) {
+ eltVal = UNREACHABLE_VALUE;
+ }
+ assert(eltVal <= UNREACHABLE_VALUE);
+
+ /* WRITE VALUE */
+ fprintf(fp, "%.1f ", eltVal);
+
+ } /* for j*/
+ fprintf(fp, "\n");
+
+ G_percent(i, nrows, 2);
+ }/* for i */
+
+ fclose(fp);
+ instr->seek(0);
+ cout << "stream2ascii: done...\n"; cout.flush();
+ return;
+}
+
+
+
+
+void
+writeToGrassFile(AMI_STREAM<ijCost> *instr, BoundaryType<cost_type> *inbnd) {
+
+ cout << "writeToGrassFile: start\n";cout.flush();
+
+ //stolen from grass2str.h
+ char* cellname = opt->out_grid;
+ //cout << "Copied filename\n";cout.flush();
+
+ AMI_err ae;
+ printCost fmp = printCost();
+ //cout << "Initialized fmt\n";cout.flush();
+
+ assert(instr && cellname);
+
+ //cout << "stats writen\n";cout.flush();
+
+ /* open output cell file */
+ int outfd;
+ if ( (outfd = G_open_raster_new (cellname, FCELL_TYPE)) < 0) {
+ G_fatal_error ("Could not open <%s>", cellname);
+ }
+
+ cout << "Opened raster file " << cellname << " for writing\n";cout.flush();
+
+ /* Allocate output buffer */
+ unsigned char *outrast;
+ outrast = (unsigned char *)G_allocate_raster_buf(FCELL_TYPE);
+ assert(outrast);
+
+ ijCost *elt, temp;
+ ae = instr->seek(0);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ int countWrites = 0, countNulls = 0, fillIn=0, countUnreachables=0;
+ cost_type eltVal;
+
+ int readNewItem = 1;
+ for (int i=0; i< nrows; i++) {
+ for (int j=0; j< ncols; j++) {
+ //*stats << "(" << i << "," << j << ")" << endl;
+
+ //boundary
+ if (inbnd->isBoundary(i,j)) {
+ inbnd->get(i, j, &temp);
+ eltVal = temp.getCost();
+ assert(temp.getI() == i && temp.getJ() == j);
+ }
+ else { //internal point
+ if (readNewItem) {
+ //cout << "writeToGrassFile::Reading New Item" << endl;
+ ae = instr->read_item(&elt);
+ assert(ae == AMI_ERROR_NO_ERROR || ae == AMI_ERROR_END_OF_STREAM);
+ //eltVal = elt->getCost();
+ }
+ if(ae == AMI_ERROR_NO_ERROR && elt->getI() == i && elt->getJ() == j) {
+ eltVal = elt->getCost();
+ readNewItem = 1;
+ } else {
+ //fill in value with NODATA
+ readNewItem = 0;
+ eltVal = NODATA;
+ fillIn++;
+ }
+ }
+
+
+ /* WRITE VALUE */
+ if (eltVal == NODATA) {
+ G_set_f_null_value( &( ((FCELL *) outrast)[j]), 1);
+ countNulls++;
+ } else {
+ //the value is not noData, but it can be unreachable, if its
+ //cost value is equal to the initial value (infinity, in this
+ //case cost_type_max; in this case set it to some smaller
+ //LARGE value
+ if (isUnreachable(eltVal)) {
+ eltVal = UNREACHABLE_VALUE;
+ countUnreachables++;
+ }
+ assert(eltVal <= UNREACHABLE_VALUE);
+
+ ((FCELL *) outrast)[j] = (FCELL)(eltVal);
+ countWrites++;
+ }
+
+
+ } /* for j*/
+ if (G_put_raster_row (outfd, outrast, FCELL_TYPE) < 0) {
+ G_fatal_error ("Cannot write to <%s>",cellname);
+ }
+
+ G_percent(i, nrows, 2);
+ }/* for i */
+
+ cout << "Good writes: " << countWrites << "\n";
+ cout << "Null (NODATA) writes: " << countNulls << "\n";
+ cout << "Fillin null writes: " << fillIn << "\n";
+ cout << "Unreachable writes: " << countUnreachables << "\n";
+ if (countUnreachables> 0)
+ cout << "Unreachable distance set to " << UNREACHABLE_VALUE << endl;
+ cout.flush();
+
+ G_free(outrast);
+ G_close_cell (outfd);
+
+ //rt_stop(rt);
+ //stats->recordTime("writing cell file", rt);
+ //cout << "After the nested for loops\n";cout.flush();
+ instr->seek(0);
+ cout << "writeToGrassFile: done\n"; cout.flush();
+ return;
+}
Added: grass-addons/raster/r.terracost/output.h
===================================================================
--- grass-addons/raster/r.terracost/output.h (rev 0)
+++ grass-addons/raster/r.terracost/output.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,49 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef _OUTPUT_H
+#define _OUTPUT_H
+
+
+extern "C" {
+#include <grass/gis.h>
+}
+#include <grass/iostream/ami.h>
+#include "sortutils.h"
+#include "boundary.h"
+#include "common.h"
+#include "types.h"
+
+
+void writeToGrassFile(AMI_STREAM<ijCost> *instr,
+ BoundaryType<cost_type> *inbnd);
+
+void stream2ascii(AMI_STREAM<ijCost> *instr,
+ BoundaryType<cost_type> *inbnd, const char* fname);
+
+void grid2Grass(cost_type ** grid, dimension_type rows, dimension_type cols,
+ char* cellname);
+
+class printCost {
+ public:
+ cost_type operator()(const ijCost &p) {
+ return p.getCost();
+ };
+};
+
+#endif
Property changes on: grass-addons/raster/r.terracost/output.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/pq.h
===================================================================
--- grass-addons/raster/r.terracost/pq.h (rev 0)
+++ grass-addons/raster/r.terracost/pq.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,255 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef _PQ_H
+#define _PQ_H
+
+#include "types.h"
+
+class costStructureOld;
+class costPriorityOld;
+class costValueOld;
+
+
+class costPriorityOld {
+ public:
+ cost_type dist;
+
+ public:
+ costPriorityOld(cost_type a=0):
+ dist(a) {}
+
+ costPriorityOld(const costPriorityOld &c):
+ dist(c.dist) {}
+
+ ~costPriorityOld() {}
+
+ cost_type getDist() {
+ return dist;
+ };
+
+ void set (cost_type g_c, dimension_type g_i, dimension_type g_j) {
+ dist = g_c;
+ };
+
+ friend ostream& operator<<(ostream& s, const costPriorityOld &pri) {
+ return s << pri.dist;
+ };
+
+
+ friend istream& operator>>(istream& s, costPriorityOld &pri) {
+ return s >> pri.dist;
+ };
+
+ friend int operator < (const costPriorityOld &p1,
+ const costPriorityOld &p2) {
+ return p1.dist < p2.dist;
+ };
+
+ friend int operator <= (const costPriorityOld &p1,
+ const costPriorityOld &p2) {
+ return p1.dist <= p2.dist;
+ };
+
+ friend int operator > (const costPriorityOld &p1,
+ const costPriorityOld &p2) {
+ return p1.dist > p2.dist;
+ };
+
+ friend int operator >= (const costPriorityOld &p1,
+ const costPriorityOld &p2) {
+ return p1.dist >= p2.dist;
+ };
+
+ friend bool operator==(const costPriorityOld &p1,
+ const costPriorityOld &p2) {
+ return p1.dist == p2.dist;
+ };
+
+ friend bool operator!=(const costPriorityOld &p1,
+ const costPriorityOld &p2) {
+ return p1.dist != p2.dist;
+ };
+
+};
+
+
+class costValueOld {
+ public:
+ dimension_type i,j;
+
+ public:
+ costValueOld(dimension_type a=0, dimension_type b=0):
+ i(a), j(b) {}
+
+ ~costValueOld() {}
+
+ dimension_type getI() const {
+ return i;
+ }
+
+ dimension_type getJ() const {
+ return j;
+ }
+
+ int isNull() {
+ //return (i == NODATA && j == NODATA);
+ return (i == dim_undef && j == dim_undef); // shouldnt this be OR?
+ }
+
+ friend ostream& operator<<(ostream& s, const costValueOld &cst) {
+ return s << "(" << cst.i << "," << cst.j << ")";
+ }
+
+ /*
+ friend istream& operator>>(istream& s, costValueOld &cst) {
+ return s >> "(" >> cst.i >> "," >> cst.j >> ")";
+ }
+ */
+
+
+ /*
+ friend costValueOld operator +(const costValueOld &cst1,
+ const costValueOld &cst2) {
+ costValueOld cst(cst1.value + cst2.value);
+ return cst;
+ }
+ */
+/* costValueOld operator =(const costValueOld &cst) { */
+/* i = cst.getI(); */
+/* j = cst.getJ(); */
+/* return *this; */
+/* } */
+
+ costValueOld operator != (const costValueOld &cst) {
+ return ((i != cst.getI()) || (j != cst.getJ()));
+
+ }
+ costValueOld operator == (const costValueOld &cst) {
+ return ((i == cst.getI()) && (j == cst.getJ()));
+ }
+
+ friend int operator > (const costValueOld &p1, const costValueOld &p2) {
+ if (p1.i > p2.i) return 1;
+ if ((p1.i == p2.i) && (p1.j > p2.j)) return 1;
+ return 0;
+ }
+ friend int operator >= (const costValueOld &p1,
+ const costValueOld &p2) {
+ return ((p1>p2) || ((p1.i == p2.i) && (p1.j == p2.j)));
+ }
+ friend int operator < (const costValueOld &p1,
+ const costValueOld &p2) {
+ if (p1.i < p2.i) return 1;
+ if ((p1.i == p2.i) && (p1.j < p2.j)) return 1;
+ return 0;
+ }
+ friend int operator <= (const costValueOld &p1,
+ const costValueOld &p2) {
+ return ((p1 < p2) || ((p1.i == p2.i) && (p1.j == p2.j)));
+ }
+
+};
+
+class costStructureOld {
+ private:
+ costPriorityOld prio;
+ costValueOld val;
+
+ public:
+
+ costStructureOld(const costPriorityOld &p = 0, const costValueOld &e = 0):
+ prio(p), val(e) {}
+
+/* costStructureOld(const costStructureOld &cs) { */
+/* prio = cs.prio; */
+/* val = cs.val; */
+/* } */
+
+ costStructureOld(const ijCost &ct) {
+ prio = ct.getCost();
+ dimension_type i = ct.getI();
+ dimension_type j = ct.getJ();
+ val = costValueOld(i,j);
+ }
+
+ costStructureOld(dimension_type i, dimension_type j, cost_type p) {
+ prio = p;
+ val = costValueOld(i,j);
+ }
+
+/* ~costStructureOld() {} */
+
+ costPriorityOld getPriority() const {
+ return prio;
+ }
+
+ costValueOld getValue() const {
+ return val;
+ }
+
+ dimension_type getI() {
+ return val.getI();
+ }
+
+ dimension_type getJ() {
+ return val.getJ();
+ }
+
+ friend ostream& operator<<(ostream& s, const costStructureOld &cs) {
+ return s << "[<prio=" << cs.prio << "> " << cs.val <<"]";
+ }
+
+ friend int operator < (const costStructureOld &c1,
+ const costStructureOld &c2) {
+ return (c1.prio < c2.prio);
+ }
+
+ friend int operator <= (const costStructureOld &c1,
+ const costStructureOld &c2) {
+ return (c1.prio <= c2.prio);
+ }
+ friend int operator > (const costStructureOld &c1,
+ const costStructureOld &c2) {
+ return (c1.prio > c2.prio);
+ }
+ friend int operator >= (const costStructureOld &c1,
+ const costStructureOld &c2) {
+ return (c1.prio >= c2.prio);
+ }
+ friend bool operator == (const costStructureOld &c1,
+ const costStructureOld &c2) {
+ return (c1.prio == c2.prio);
+ }
+ friend bool operator != (const costStructureOld &c1,
+ const costStructureOld &c2) {
+ return (c1.prio != c2.prio);
+ }
+
+ static int qscompare(const void *a, const void *b) {
+ costStructureOld* x, *y;
+ x = (costStructureOld*) a;
+ y = (costStructureOld*) b;
+ if (*x < *y) return -1;
+ if (*x == *y) return 0;
+ return 1;
+ }
+
+};
+
+#endif
Property changes on: grass-addons/raster/r.terracost/pq.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/pqueue.h
===================================================================
--- grass-addons/raster/r.terracost/pqueue.h (rev 0)
+++ grass-addons/raster/r.terracost/pqueue.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,399 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef _PQUEUECS_H
+#define _PQUEUECS_H
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <grass/iostream/mm.h>
+
+/* this is a copy of ijCost */
+class costStructure{
+ public:
+ cost_type cost; //the priority
+ dimension_type i,j;
+
+ /***************************************************/
+ costStructure(const cost_type c =0,
+ const dimension_type gi=0, const dimension_type gj=0) {
+ cost = c;
+ i = gi;
+ j = gj;
+ }
+
+/* costStructure(const costStructure &cs) { */
+/* cost = cs.cost; */
+/* i = cs.i; */
+/* j = cs.j; */
+/* } */
+
+/* costStructure(const ijCost &ct) { */
+/* cost = ct.getCost(); */
+/* i = ct.getI(); */
+/* j = ct.getJ(); */
+/* } */
+
+/* ~costStructure() {} */
+
+ static void swap(costStructure *a, costStructure *b) {
+ costStructure tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+
+/* cost_type cost = a->getCost(); */
+/* a->cost = b->cost; */
+/* b->cost = cost; */
+
+/* dimension_type i = a->i; */
+/* a->i = b->i; */
+/* b->i = i; */
+
+/* dimension_type j = a->j; */
+/* a->j = b->j; */
+/* b->j = j; */
+ }
+
+
+/* cost_type getCost() const { */
+/* return cost; */
+/* } */
+
+ cost_type getPriority() const {
+ return cost;
+ }
+
+ dimension_type getI() const {
+ return i;
+ }
+
+ dimension_type getJ() const {
+ return j;
+ }
+
+ friend ostream& operator<<(ostream& s, const costStructure &cs) {
+ return s << "[<prio=" << cs.cost << "> " << cs.i << "," << cs.j <<"]";
+ }
+
+ friend int operator < (const costStructure &c1,
+ const costStructure &c2) {
+ return (c1.cost < c2.cost);
+ }
+
+ friend int operator <= (const costStructure &c1,
+ const costStructure &c2) {
+ return (c1.cost <= c2.cost);
+ }
+ friend int operator > (const costStructure &c1,
+ const costStructure &c2) {
+ return (c1.cost > c2.cost);
+ }
+ friend int operator >= (const costStructure &c1,
+ const costStructure &c2) {
+ return (c1.cost >= c2.cost);
+ }
+ friend int operator == (const costStructure &c1,
+ const costStructure &c2) {
+ return (c1.cost == c2.cost);
+ }
+ friend int operator != (const costStructure &c1,
+ const costStructure &c2) {
+ return (c1.cost != c2.cost);
+ }
+
+ static int qscompare(const void *a, const void *b) {
+ costStructure* x, *y;
+ x = (costStructure*) a;
+ y = (costStructure*) b;
+ if (*x < *y) return -1;
+ if (*x == *y) return 0;
+ return 1;
+ }
+};
+
+
+
+
+
+
+
+
+/* ************************************************** */
+// Helper functions for navigating through a binary heap.
+/* for simplicity the heap structure is slightly modified as:
+ 0
+ |
+ 1
+ /\
+ 2 3
+ /\ /\
+4 5 6 7
+
+*/
+
+// The children of an element of the heap.
+static inline unsigned int heap_lc(unsigned int index) {
+ return 2 * index;
+}
+
+static inline unsigned int heap_rc(unsigned int index) {
+ return 2 * index + 1;
+}
+
+// The parent of an element.
+static inline unsigned int heap_p(unsigned int index) {
+ return index >> 1;
+}
+
+
+// return minimum of two integers
+//static unsigned int min(unsigned int a, unsigned int b) {
+// return (a<=b)? a:b;
+//}
+
+
+
+class pqheap_ijCost {
+ public:
+ // A pointer to an array of elements
+ costStructure* elements;
+
+ // The number of elements currently in the queue.
+ unsigned int cur_elts;
+
+ // The maximum number the queue can hold.
+ unsigned int max_elts;
+
+private:
+
+ /* this function is recursive; replaced by iterative version below */
+ void heapifyx(unsigned int root) {
+ unsigned int min_index = root;
+ unsigned int lc = heap_lc(root);
+ unsigned int rc = heap_rc(root);
+
+ if ((lc < cur_elts) &&
+ ((elements[lc].getPriority()) < elements[min_index].getPriority())) {
+ min_index = lc;
+ }
+ if ((rc < cur_elts) &&
+ ((elements[rc].getPriority()) < elements[min_index].getPriority())) {
+ min_index = rc;
+ }
+
+ if (min_index != root) { /* need to recurse */
+/* costStructure tmp_q = elements[min_index]; */
+/* elements[min_index] = elements[root]; */
+/* elements[root] = tmp_q; */
+ costStructure::swap(&elements[root], &elements[min_index]);
+ heapify(min_index);
+ }
+ }
+
+ /* iterative version of heapify, above */
+ void heapify(unsigned int root) {
+ unsigned int min_index = root;
+
+ do {
+ root = min_index;
+
+ unsigned int lc = heap_lc(root);
+ unsigned int rc = heap_rc(root);
+
+ if ((lc < cur_elts) &&
+ ((elements[lc].getPriority()) < elements[min_index].getPriority())) {
+ min_index = lc;
+ }
+ if ((rc < cur_elts) &&
+ ((elements[rc].getPriority()) < elements[min_index].getPriority())) {
+ min_index = rc;
+ }
+ if (min_index != root) {
+ costStructure::swap(&elements[root], &elements[min_index]);
+ }
+ } while (min_index != root);
+
+
+ }
+
+public:
+ /****************************************************/
+ pqheap_ijCost(unsigned int size) {
+ assert(size>0);
+ //elements = new costStructure [size];
+ elements = (costStructure *)malloc(sizeof(costStructure) * size);
+ MM_manager.register_allocation(sizeof(costStructure) * size);
+ assert(elements);
+ if(!elements) {
+ fprintf(stderr, "malloc failed\n");
+ exit(1);
+ }
+ max_elts = size;
+ cur_elts = 0;
+ // cout << "maxelts=" << max_elts << ", cur_elts=" << cur_elts << endl;
+ }
+
+ /****************************************************/
+ pqheap_ijCost() {
+ cerr << "not implemented;";
+ exit(1);
+ }
+
+ /****************************************************/
+ ~pqheap_ijCost() {
+ //delete [] elements;
+ free(elements);
+ MM_manager.register_deallocation(sizeof(costStructure) * max_elts);
+ cur_elts = 0;
+ max_elts = 0;
+ }
+ /****************************************************/
+
+ /* returns success */
+ int grow() {
+ costStructure *ptr;
+
+ fprintf(stderr, "pqueue: doubling pq from %d elts\n", max_elts);
+ MM_manager.register_allocation(sizeof(costStructure) * max_elts);
+
+ ptr = (costStructure *)realloc(elements, sizeof(costStructure) * max_elts * 2);
+ if(!ptr) {
+ fprintf(stderr, "Warning: realloc failed");
+ //return 0;
+ /* 09/13/2005: this was not checked properly, and generated
+ an infinite nb calls to grow() */
+ exit(0);
+ }
+
+ elements = ptr;
+ max_elts *= 2;
+ return 1;
+ }
+
+ /****************************************************/
+ void clear() {
+ cur_elts = 0;
+ }
+
+ /****************************************************/
+ // Is it full?
+ int full(void) {
+ return cur_elts == max_elts;
+ }
+
+ /****************************************************/
+ //Is it empty?
+ int empty() {
+ return cur_elts == 0;
+ }
+
+ /****************************************************/
+ unsigned int size() {
+ return cur_elts;
+ }
+
+ /****************************************************/
+ unsigned int maxsize() {
+ return max_elts;
+ }
+
+ /****************************************************/
+ // min
+ int min(costStructure* elt) {
+ if (empty()) return 0;
+ *elt = elements[0];
+ return 1;
+ }
+
+ /****************************************************/
+ //min
+ costStructure min() {
+ costStructure elt;
+ if(min(&elt)) return elt;
+ else {
+ assert(0);
+ exit(1);
+ }
+ //should never get here (to avoid warning)
+ return elt;
+ }
+
+ /****************************************************/
+ // Extract min and set elt = min
+ int extract_min(costStructure* elt) {
+ if (empty()) return 0;
+ *elt = elements[0];
+ elements[0] = elements[--cur_elts];
+ heapify(0);
+ return 1;
+ }
+
+ /****************************************************/
+ //delete min; same as extract_min, but ignore the value extracted
+ int delete_min() {
+ costStructure dummy;
+ return extract_min(&dummy);
+ }
+
+
+ /****************************************************/
+ // Insert
+ int insert(const costStructure elt) {
+ //cout << "PQ:insert: cur_elts=" << cur_elts << ",max_elts= "<< max_elts << endl;
+ unsigned int ii;
+ if (full()) {
+ //return 0;
+ if(!grow()) {
+ return 0;
+ }
+ }
+ for (ii = cur_elts++;
+ ii && (elements[heap_p(ii)].getPriority() > elt.getPriority());
+ ii = heap_p(ii)) {
+ elements[ii] = elements[heap_p(ii)];
+ }
+ elements[ii] = elt;
+ return 1;
+ }
+
+ /****************************************************/
+ //Delete the current minimum and insert the new item x;
+ //the minimum item is lost (i.e. not returned to user);
+ //needed to optimize merge
+ void delete_min_and_insert(const costStructure x) {
+ elements[0] = x;
+ heapify(0);
+ }
+
+ /****************************************************/
+ //print the first 10 elements in the pq
+ friend ostream& operator<<(ostream& s, const pqheap_ijCost &pq) {
+ s << "PQ: "; s.flush();
+ for (unsigned int i=0; i< pq.cur_elts; i++) {
+ s << "[" << pq.elements[i] << "]";
+ }
+ return s;
+ }
+
+};
+
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/pqueue.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/queue.h
===================================================================
--- grass-addons/raster/r.terracost/queue.h (rev 0)
+++ grass-addons/raster/r.terracost/queue.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,546 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.32 1999/12/29 04:24:46 peter Exp $
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * slingly-linked tail queues, lists, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may only be traversed in the forward direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ * SLIST LIST STAILQ TAILQ CIRCLEQ
+ * _HEAD + + + + +
+ * _ENTRY + + + + +
+ * _INIT + + + + +
+ * _EMPTY + + + + +
+ * _FIRST + + + + +
+ * _NEXT + + + + +
+ * _PREV - - - + +
+ * _LAST - - + + +
+ * _FOREACH + + + + +
+ * _INSERT_HEAD + + + + +
+ * _INSERT_BEFORE - + - + +
+ * _INSERT_AFTER + + + + +
+ * _INSERT_TAIL - - + + +
+ * _REMOVE_HEAD + - + - -
+ * _REMOVE + + + + +
+ *
+ */
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+
+#define SLIST_FIRST(head) ((head)->slh_first)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+#define SLIST_INIT(head) { \
+ (head)->slh_first = NULL; \
+}
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (0)
+
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while( curelm->field.sle_next != (elm) ) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (0)
+
+/*
+ * Singly-linked Tail queue definitions.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first;/* first element */ \
+ struct type **stqh_last;/* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+
+#define STAILQ_INIT(head) do { \
+ (head)->stqh_first = NULL; \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (0)
+
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+#define STAILQ_LAST(head) (*(head)->stqh_last)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->stqh_first = (elm); \
+} while (0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+} while (0)
+
+#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
+ if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (tqelm)->field.stqe_next = (elm); \
+} while (0)
+
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first = \
+ (head)->stqh_first->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (0)
+
+#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
+ if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (0)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->stqh_first == (elm)) { \
+ STAILQ_REMOVE_HEAD(head, field); \
+ } \
+ else { \
+ struct type *curelm = (head)->stqh_first; \
+ while( curelm->field.stqe_next != (elm) ) \
+ curelm = curelm->field.stqe_next; \
+ if((curelm->field.stqe_next = \
+ curelm->field.stqe_next->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(curelm)->field.stqe_next; \
+ } \
+} while (0)
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+
+#define LIST_FIRST(head) ((head)->lh_first)
+
+#define LIST_FOREACH(var, head, field) \
+ for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
+
+#define LIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (0)
+
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (0)
+
+/*
+ * Tail queue definitions.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+}
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
+
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL){ \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ } else { \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ } \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (0)
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
+
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for((var) = (head)->cqh_first; \
+ (var) != (void *)(head); \
+ (var) = (var)->field.cqe_next)
+
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+} while (0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (0)
+
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+
+#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
+
+#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (0)
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+ struct quehead *qh_link;
+ struct quehead *qh_rlink;
+};
+
+#ifdef __GNUC__
+
+static __inline void
+insque(void *a, void *b)
+{
+ struct quehead *element = a, *head = b;
+
+ element->qh_link = head->qh_link;
+ element->qh_rlink = head;
+ head->qh_link = element;
+ element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+ struct quehead *element = a;
+
+ element->qh_link->qh_rlink = element->qh_rlink;
+ element->qh_rlink->qh_link = element->qh_link;
+ element->qh_rlink = 0;
+}
+
+#else /* !__GNUC__ */
+
+void insque __P((void *a, void *b));
+void remque __P((void *a));
+
+#endif /* __GNUC__ */
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
Property changes on: grass-addons/raster/r.terracost/queue.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/quicksortD.h
===================================================================
--- grass-addons/raster/r.terracost/quicksortD.h (rev 0)
+++ grass-addons/raster/r.terracost/quicksortD.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,54 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef _QUICKSORT_H_
+#define _QUICKSORT_H_
+
+#include "distanceType.h"
+
+int partitionD(distanceType array[], int start, int end) {
+ distanceType x = array[start];
+ int i = start - 1;
+ int j = end - 1;
+ while (1) {
+ do {
+ j--;
+ } while (array[j] > x);
+ do {
+ i++;
+ } while (array[i] < x);
+
+ if (i < j) {
+ distanceType temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ else return j;
+ }
+};
+
+
+void quicksortD(distanceType array[], int start, int end) {
+ if (start < end) {
+ int part = partitionD(array, start, end);
+ quicksortD(array, start, part);
+ quicksortD(array, start+1, end);
+ }
+};
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/quicksortD.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/sortutils.h
===================================================================
--- grass-addons/raster/r.terracost/sortutils.h (rev 0)
+++ grass-addons/raster/r.terracost/sortutils.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,174 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+/*C
+ * Original project: Lars Arge, Jeff Chase, Pat Halpin, Laura Toma, Dean
+ * Urban, Jeff Vitter, Rajiv Wickremesinghe 1999
+ *
+ * GRASS Implementation: Lars Arge, Helena Mitasova, Laura Toma 2002
+ *
+ * Copyright (c) 2002 Duke University -- Laura Toma
+ *
+ * Copyright (c) 1999-2001 Duke University --
+ * Laura Toma and Rajiv Wickremesinghe
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Duke University
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *C*/
+
+
+#ifndef SORTUTILS_H
+#define SORTUTILS_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fstream>
+using namespace std;
+
+#include <grass/iostream/ami.h>
+#include "common.h"
+
+
+#define sort(A,B) ((*stats<< "sort at " << __FILE__ << ":" << __LINE__ << endl), _sort(A,B) )
+
+
+/* ********************************************************************** */
+/* deletes input stream *str and replaces it by the sorted stream */
+
+template<class T, class FUN>
+void
+_sort(AMI_STREAM<T> **str, FUN fo) {
+ //Rtimer rt;
+ AMI_STREAM<T> *sortedStr;
+ /*
+ stats->recordLength("pre-sort", *str);
+ rt_start(rt);
+ */
+
+ /* let AMI_sort create its output stream and delete the inout stream */
+ int eraseInputStream = 1;
+ AMI_sort(*str,&sortedStr, &fo, eraseInputStream);
+ /*rt_stop(rt);
+
+ stats->recordLength("sort", sortedStr);
+ stats->recordTime("sort", rt);
+ */
+
+ sortedStr->seek(0);
+ *str = sortedStr;
+
+}
+
+
+
+
+
+/* ********************************************************************** */
+
+/* warning - creates a new stream and returns it !! */
+template<class T, class FUN>
+AMI_STREAM<T> *
+_sort(AMI_STREAM<T> *strIn, FUN fo) {
+ //Rtimer rt;
+ AMI_STREAM<T> *strOut;
+ /*
+ stats->recordLength("pre-sort", strIn);
+ rt_start(rt);
+ */
+
+ AMI_sort(strIn, &strOut, &fo);
+ assert(strOut);
+ /*
+ rt_stop(rt);
+ stats->recordLength("sort", strOut);
+ stats->recordTime("sort", rt);
+ */
+ strOut->seek(0);
+ return strOut;
+}
+
+
+
+/* ********************************************************************** */
+/* deletes input stream *str and replaces it by the sorted stream */
+
+template<class T, class FUN>
+void
+cachedSort(AMI_STREAM<T> **str, FUN fo) {
+ AMI_STREAM<T> *sortedStr;
+
+ char *unsortedName = strdup((*str)->name());
+ char sortedName[BUFSIZ];
+ sprintf(sortedName, "%s.sorted", unsortedName);
+
+ /* check if file exists */
+ struct stat sb;
+ if(stat(sortedName, &sb) == 0) {
+ sortedStr = new AMI_STREAM<T>(sortedName, AMI_READ_STREAM);
+ /* now see if stream is right length */
+ if(sortedStr->stream_len() == (*str)->stream_len()) {
+ fprintf(stderr, "Guessing that %s is sorted version of %s (skipping sort)\n",
+ sortedName, unsortedName);
+ *stats << "Guessing that " << sortedName
+ << " is sorted version of " << unsortedName << " (skipping sort)\n";
+ delete *str;
+ *str = sortedStr;
+ return;
+ }
+ }
+
+ /* not found; got to sort now */
+ int eraseInputStream = 1;
+ AMI_sort(*str, &sortedStr, &fo, eraseInputStream, sortedName);
+ sortedStr->persist(PERSIST_PERSISTENT); /* might leave streams lying around... */
+ fprintf(stderr, "Saving %s as sorted version of %s\n",
+ sortedName, unsortedName);
+ sortedStr->seek(0);
+ *str = sortedStr;
+ free(unsortedName);
+}
+
+
+
+#endif
+
Property changes on: grass-addons/raster/r.terracost/sortutils.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/stats.cc
===================================================================
--- grass-addons/raster/r.terracost/stats.cc (rev 0)
+++ grass-addons/raster/r.terracost/stats.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,289 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+/*C
+ * Original project: Lars Arge, Jeff Chase, Pat Halpin, Laura Toma, Dean
+ * Urban, Jeff Vitter, Rajiv Wickremesinghe 1999
+ *
+ * GRASS Implementation: Lars Arge, Helena Mitasova, Laura Toma 2002
+ *
+ * Copyright (c) 2002 Duke University -- Laura Toma
+ *
+ * Copyright (c) 1999-2001 Duke University --
+ * Laura Toma and Rajiv Wickremesinghe
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Duke University
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *C*/
+
+
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "stats.h"
+#include "formatNumber.h"
+
+
+#ifdef HAS_UTRACE
+
+struct ut { char buf[8]; };
+
+void utrace __P((void *, int));
+
+#define UTRACE(s) \
+ {struct ut u; strncpy(u.buf,s,8); utrace((void*)&u, sizeof u);}
+#else /* !HAS_UTRACE */
+#define UTRACE(s)
+#endif /* HAS_UTRACE */
+
+#undef UTRACE
+
+#ifdef UTRACE_ENABLE
+#define UTRACE(s) utrace(s)
+#else
+#define UTRACE(s)
+#endif
+
+void
+utrace(const char *s) {
+ void *p;
+ int len = strlen(s);
+ assert(len < 80);
+
+ /* cerr << "UT " << len << endl; */
+ p = malloc(0);
+ /* assert(p); */
+ free(p);
+ p = malloc(len);
+ /* assert(p); */
+ free(p);
+
+ for(int i=0; i<len; i++) {
+ p = malloc(s[i]);
+ /* assert(p); */
+ free(p);
+ }
+}
+
+
+
+int
+noclobberFile(char *fname) {
+ int fd=-1;
+
+ while(fd<0) {
+ fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if(fd < 0) {
+ if(errno != EEXIST) {
+ perror(fname);
+ exit(1);
+ } else { /* file exists */
+ char buf[BUFSIZ];
+ fprintf(stderr, "file %s exists - renaming.\n", fname);
+ sprintf(buf, "%s.old", fname);
+ if(rename(fname, buf) != 0) {
+ perror(fname);
+ exit(1);
+ }
+ }
+ }
+ }
+ return fd;
+}
+
+char*
+noclobberFileName(char *fname) {
+ int fd;
+ fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if(fd < 0) {
+ if(errno != EEXIST) {
+ perror(fname);
+ exit(1);
+ } else { /* file exists */
+ char buf[BUFSIZ];
+ fprintf(stderr, "file %s exists - renaming.\n", fname);
+ sprintf(buf, "%s.old", fname);
+ if(rename(fname, buf) != 0) {
+ perror(fname);
+ exit(1);
+ }
+ close(fd);
+ }
+ }
+ return fname;
+}
+
+
+
+/* ********************************************************************** */
+
+statsRecorder::statsRecorder(char *fname) {
+ //note: in the new version of gcc there is not constructor for
+ //ofstream that takes an fd; wrote another noclobber() function that
+ //closes fd and returns the name;
+
+ // try to turn off buffering
+ rdbuf()->pubsetbuf(0,0);
+
+ open(noclobberFileName(fname));
+ rt_start(tm);
+ bss = sbrk(0);
+ char buf[BUFSIZ];
+ *this << freeMem(buf) << endl;
+}
+
+/* ********************************************************************** */
+
+long
+statsRecorder::freeMem() {
+ struct rlimit rlim;
+ if (getrlimit(RLIMIT_DATA, &rlim) == -1) {
+ perror("getrlimit: ");
+ return -1;
+ }
+ /* printf("getrlimit returns: %d \n", rlim.rlim_cur); */
+ if (rlim.rlim_cur == RLIM_INFINITY) {
+ /* printf("rlim is infinity\n"); */
+ /* should fix this */
+ return -1;
+ }
+ long freeMem = rlim.rlim_cur - ((char*)sbrk(0)-(char*)bss);
+ return freeMem;
+}
+
+char *
+statsRecorder::freeMem(char *buf) {
+ char buf2[BUFSIZ];
+ sprintf(buf, "Free Memory=%s", formatNumber(buf2, freeMem()));
+ return buf;
+}
+
+
+
+/* ********************************************************************** */
+
+char *
+statsRecorder::timestamp() {
+ static char buf[BUFSIZ];
+ rt_stop(tm);
+ sprintf(buf, "[%.1f] ", rt_seconds(tm));
+ return buf;
+}
+
+void
+statsRecorder::timestamp(const char *s) {
+ *this << timestamp() << s << endl;
+}
+
+
+void
+statsRecorder::comment(const char *s, const int verbose) {
+ *this << timestamp() << s << endl;
+ if (verbose) {
+ cout << s << endl;
+ }
+ UTRACE(s);
+ cout.flush();
+}
+
+
+void
+statsRecorder::comment(const char *s1, const char *s2) {
+ char buf[BUFSIZ];
+ sprintf(buf, "%s%s", s1, s2);
+ comment(buf);
+}
+
+void
+statsRecorder::comment(const int n) {
+ char buf[BUFSIZ];
+ sprintf(buf, "%d", n);
+ comment(buf);
+}
+
+
+
+void
+statsRecorder::recordTime(const char *label, long secs) {
+ *this << timestamp() << "TIME " << label << ": " << secs << " secs" << endl;
+ this->flush();
+
+ UTRACE(label);
+}
+
+void
+statsRecorder::recordTime(const char *label, Rtimer rt) {
+ char buf[BUFSIZ];
+ *this << timestamp() << "TIME " << label << ": ";
+ *this << rt_sprint(buf, rt) << endl;
+ this->flush();
+
+ UTRACE(label);
+}
+
+void
+statsRecorder::recordLength(const char *label, off_t len, int siz,
+ char *sname) {
+ UTRACE(label);
+ UTRACE(sname);
+
+ char lenstr[100];
+ char suffix[100]="";
+ if(siz) {
+ formatNumber(suffix, len*siz);
+ strcat(suffix, " bytes");
+ }
+ formatNumber(lenstr, len);
+ *this << timestamp() << "LEN " << label << ": " << lenstr << " elts "
+ << suffix;
+ if(sname) *this << " " << sname;
+ *this << endl;
+ this->flush();
+}
+
+
Added: grass-addons/raster/r.terracost/stats.h
===================================================================
--- grass-addons/raster/r.terracost/stats.h (rev 0)
+++ grass-addons/raster/r.terracost/stats.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,59 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef __STATS_H
+#define __STATS_H
+
+#include <sys/types.h>
+#include <fstream>
+#include <iostream>
+
+#include <grass/iostream/ami.h>
+
+using namespace std;
+
+#define HAVE_STATS
+
+int noclobberFile(char *);
+
+class statsRecorder : public ofstream {
+private:
+ Rtimer tm;
+ void *bss;
+public:
+ statsRecorder(char *fname);
+/* ~statsRecorder() { */
+/* this->flush(); */
+/* } */
+ char *freeMem(char *);
+ long freeMem();
+ char *timestamp();
+ void timestamp(const char *s);
+ void comment(const char *s, const int verbose=1);
+ void comment(const char *s1, const char *s2);
+ void comment(const int n);
+ void recordTime(const char *label, long secs);
+ void recordTime(const char *label, Rtimer rt);
+ void recordLength(const char *label, off_t len, int siz=0, char *sname=NULL);
+ template<class T> void recordLength(const char *label, AMI_STREAM<T> *str) {
+ recordLength(label, str->stream_len(), sizeof(T), str->sprint());
+ }
+};
+
+//char *formatNumber(char *buf, long long val);
+
+#endif
Property changes on: grass-addons/raster/r.terracost/stats.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/tile.cc
===================================================================
--- grass-addons/raster/r.terracost/tile.cc (rev 0)
+++ grass-addons/raster/r.terracost/tile.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,502 @@
+
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include "tile.h"
+#include "formatNumber.h"
+
+/* ************************************************************ */
+
+TileFactory::TileFactory(dimension_type gtileSizeRows,
+ dimension_type gtileSizeCols,
+ size_t tilemem) {
+
+ tileSizeRows = gtileSizeRows;
+ tileSizeCols = gtileSizeCols;
+
+ tileBnd = new CachedBoundaryMgr<costSourceType>(tsr, tsc, nrowsPad, ncolsPad);
+ tileBndR = new BoundaryTileReader<costSourceType>(tileBnd);
+
+// // this will probably create a stream based on opt->s0bnd -RW
+// tileBnd = new BoundaryType<costSourceType>(tileSizeRows, tileSizeCols,
+// tilemem);
+
+ /* the stream that stores the internal points in the grid */
+
+ /* POTENTIAL PROBLEM: What happens if we make more than 1 tile
+ factory?? */
+
+ const char *s0path=resolvePath(opt->s0out);
+ unlink(s0path);
+ cout << "path: " << s0path << endl; cout.flush();
+ internalstr = new AMI_STREAM<ijCostSource>(s0path);
+ internalstr->persist(PERSIST_PERSISTENT);
+
+ char* tempname;
+ internalstr->name(&tempname);
+ cout << "Created internalstr = " << tempname << endl;
+ *stats << "Created internalstr = " << tempname << endl;
+ delete [] tempname;
+
+ iMarker = 0;
+ jMarker = 0;
+ numTileBndPts = 2*(tileSizeRows-1) + 2*(tileSizeCols-1);
+ tile = new Tile(tileSizeRows, tileSizeCols);
+ internalstr->seek(0);
+
+ cout << "Tile Factory Sizes, row: " << tileSizeRows << " col: " <<
+ tileSizeCols << "\n";
+}
+
+
+/* Constructor where the stream paths are specified, used in parallel
+ implementation */
+TileFactory::TileFactory(dimension_type gtileSizeRows,
+ dimension_type gtileSizeCols,
+ AMI_STREAM<ijCostSource> *dataStream, /* char* internalPath, */
+ const char* bndPath) {
+ tileSizeRows = gtileSizeRows;
+ tileSizeCols = gtileSizeCols;
+
+// tileBnd = new BoundaryType<costSourceType>(tileSizeRows, tileSizeCols,
+// bndPath);
+ tileBnd = NULL;
+ tileBndR = new BoundaryTileReader<costSourceType>(tsr, tsc, nrowsPad, ncolsPad, bndPath);
+
+ /* the stream that stores the internal points in the grid */
+
+ /* POTENTIAL PROBLEM: What happens if we make more than 1 tile
+ factory?? */
+
+
+ //internalstr = new AMI_STREAM<ijCostSource>(internalPath);
+ internalstr = dataStream;
+ internalstr->persist(PERSIST_PERSISTENT);
+ internalstr->seek(0);
+ {
+ char* tempname;
+ internalstr->name(&tempname);
+ cout << "Created internalstr = " << tempname << endl;
+ //cout << "StrLen: " << internalstr->stream_len() << endl;
+ cout.flush();
+ *stats << "Created internalstr = " << tempname << endl;
+ delete [] tempname;
+ }
+
+ iMarker = 0;
+ jMarker = 0;
+ numTileBndPts = 2*(tileSizeRows-1) + 2*(tileSizeCols-1);
+ tile = new Tile(tileSizeRows, tileSizeCols);
+ /* XXX-RW is this tile deleted anywhere? */
+ /* nope-TH */
+
+ cout << "Tile Factory Sizes, row: " << tileSizeRows << " col: " <<
+ tileSizeCols << "\n";
+}
+
+/*
+ adds a predetermined number of rows and columns to the grid so that
+ the b2b stream can be indexed properly
+*/
+
+TileFactory::~TileFactory() {
+ //delete tile;
+ if(tileBndR) { delete tileBndR; }
+ if(tileBnd) { delete tileBnd; }
+ delete internalstr;
+
+}
+
+void
+TileFactory::reset() {
+ internalstr->seek(0);
+ iMarker = 0;
+ jMarker = 0;
+}
+
+void
+TileFactory::setIMarker(int inI) {
+ iMarker = inI;
+}
+
+void
+TileFactory::setJMarker(int inJ) {
+ jMarker = inJ;
+}
+
+/*
+ Loads a tile into the t variable using the internalstr and the tilebnd
+ data structures.
+*/
+int
+TileFactory::getNextTile(Tile* t) {
+ if (iMarker <= nrowsPad-tileSizeRows && jMarker <= ncolsPad-tileSizeCols) {
+ // *stats << "loading tile...";
+ // *stats << "iMarker: " << iMarker << " jMarker: " << jMarker << "\n";
+ // *stats << "getNextTile::Internal stream length: " <<
+ // internalstr->stream_len() << endl;
+ //stats->flush();
+
+ assert(t);
+ tile = t;
+ Tile::init(t);
+ int ok = fillTile();
+ if(!ok) {
+ return 0; // error
+ }
+ //tile->dumpTile(*stats, "ftile ");
+
+ //upper left point of next tile to be loaded.
+ jMarker = jMarker + tileSizeCols-1;
+ if (jMarker > ncolsPad - tileSizeCols) {
+ jMarker = 0;
+ iMarker = iMarker + tileSizeRows - 1;
+ }
+ return 1;
+ }
+ return 0;
+
+}
+
+// returns 1 on success
+int
+TileFactory::fillTile() {
+ int npoints=0;
+ int ok;
+ for (int i = 1; i < tileSizeRows-1; i++) {
+ for (int j = 1; j < tileSizeCols-1; j++) {
+ assert (!IS_BOUNDARY(i,j));
+ ok = addInternalPoint(i,j);
+ if(!ok) {
+ //fprintf(stderr, "fillTile: bailing out after %d internal points\n", npoints);
+ assert(npoints == 0);
+ return 0;
+ }
+ npoints++;
+ }
+ }
+
+ ijCostSource tmp = tile->getComplex(1,1);
+ iMarker = tmp.getI()-1;
+ jMarker = tmp.getJ()-1;
+
+
+// // left and right side
+// for (int i = 0, j = 0; i < tileSizeRows; i++) {
+// if (!tileBndR->isBoundary(i+iMarker, j+jMarker)) {
+// cout << "TileF: Not a Bnd: " << i << "," << j << " " << iMarker
+// << "," << jMarker << endl; cout.flush();
+// }
+// assert(tileBndR->isBoundary(i+iMarker, j+jMarker));
+// addBoundaryPoint(i,j);
+// assert(tileBnd->isBoundary(i+iMarker, j+jMarker+tileSizeCols-1));
+// addBoundaryPoint(i,j+tileSizeCols-1);
+// }
+// // top and bottom
+// for (int i = 0, j = 0; j < tileSizeCols; j++) {
+// assert(tileBndR->isBoundary(i+iMarker, j+jMarker));
+// addBoundaryPoint(i,j);
+// assert(tileBndR->isBoundary(i+iMarker+tileSizeRows-1, j+jMarker));
+// addBoundaryPoint(i + tileSizeRows-1,j);
+// }
+
+ tileBndR->readTileBoundary(iMarker, jMarker, tile);
+
+ //cerr << "fillTile: " << npoints << " internal points" << endl;
+ return 1;
+}
+
+void
+TileFactory::sortTF() {
+
+ internalstr->seek(0); // is this required? RW
+ ijTileCostCompareType fun;
+ fun.setTileSize(tileSizeRows, tileSizeCols);
+ stats->comment("TileFactory: Sorting internalstr...");
+#if 0
+ sort(&internalstr, fun);
+#else
+ cachedSort(&internalstr, fun);
+#endif
+ //internalstr->seek(0); // is this required? RW
+ stats->comment("TileFactory: Sorting internalstr... done.");
+}
+
+void
+TileFactory::insert(ijCostSource in) {
+ AMI_err ae;
+ dimension_type tempI = in.getI();
+ dimension_type tempJ = in.getJ();
+
+ if (IS_BOUNDARY(tempI,tempJ)) {
+ assert(tileBnd);
+ tileBnd->insert(in);
+ //cout << "Boundary: " << out;
+ } else {
+ ae = internalstr->write_item(in);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ //cout << "Cost Stream: " << out;
+ }
+}
+
+/* ************************************************************ */
+
+/*
+ adds a predetermined number of rows and columns to the grid so that
+ the b2b stream can be indexed properly
+*/
+void
+TileFactory::pad() {
+ ijCostSource padding;
+ costSourceType dummyValue = costSourceType(NODATA, 'n');
+
+ size_t padMem = MM_manager.memory_available();
+ *stats << "TileFactory::pad::Pre Padding nrows: " << nrows
+ << " ncols: " << ncols << "\n";
+ *stats << "TileFactory::pad::Memory Available Before Padding: "
+ << formatNumber(NULL, padMem) << ".\n";
+ *stats << "pad::Internal stream length pre Padding: " <<
+ internalstr->stream_len() << endl;
+
+ for (int i = 0; i < nrows; i++) {
+ for (int j = ncols; j < ncolsPad; j++) {
+ padding = ijCostSource(i,j,dummyValue);//can't have a source in padding
+ insert(padding);
+ }
+ }
+
+ for (int j = 0; j < ncols; j++) {
+ for (int i = nrows; i < nrowsPad; i++) {
+ padding = ijCostSource(i,j,dummyValue);//can't have a source in padding
+ insert(padding);
+ }
+ }
+
+ for (int i = nrows; i < nrowsPad; i++) {
+ for (int j = ncols; j < ncolsPad; j++) {
+ padding = ijCostSource(i,j,dummyValue);//can't have a source in padding
+ insert(padding);
+ }
+ }
+
+ padMem = MM_manager.memory_available();
+ *stats << "TileFactory::pad::Post Padding nrows: " << nrowsPad
+ << " ncols: " << ncolsPad << "\n";
+ *stats << "TileFactory::pad::Memory Available After Padding: "
+ << formatNumber(NULL, padMem) << ".\n";
+ stats->recordLength("pad::Internal stream length post Padding", internalstr);
+}
+
+
+/* adds a point from a boundary data structure to a tile being
+ constructed. Called by the fillTile() method. */
+// void
+// TileFactory::addBoundaryPoint(dimension_type i, dimension_type j) {
+// ijCostSource tempijCost;
+// tileBnd->get(i+iMarker, j+jMarker, &tempijCost);
+// tile->insert(i, j, tempijCost);
+// }
+
+/* gets a point from the internal points stream and inserts in into the tile */
+// returns number of points read
+int
+TileFactory::addInternalPoint(dimension_type i, dimension_type j) {
+ ijCostSource* tempijCost;
+ AMI_err ae = internalstr->read_item(&tempijCost);
+ if(ae == AMI_ERROR_END_OF_STREAM) {
+ return 0;
+ }
+ assert(ae == AMI_ERROR_NO_ERROR);
+ assert(i % (tileSizeRows-1) == tempijCost->getI() % (tileSizeRows-1));
+ assert(j % (tileSizeCols-1) == tempijCost->getJ() % (tileSizeCols-1));
+ tile->insert(i, j, *tempijCost);
+
+// fprintf(stderr, "point <%d,%d> added at <%d,%d> %d\n", tempijCost->getI(), tempijCost->getJ(),
+// iMarker+i, jMarker+j, sizeof(ijCostSource));
+ return 1;
+}
+
+/* returns the total number of points in a grid as represented in the
+ internal stream and the BoundaryType data structure */
+
+dimension_type
+TileFactory::getRows() const {
+ return tileSizeRows;
+}
+
+dimension_type
+TileFactory::getCols() const {
+ return tileSizeCols;
+}
+
+int
+TileFactory::getTotalPoints() {
+ // return internalstr->stream_len() + tileBnd->getSize();
+ return -1;
+}
+
+dimension_type
+TileFactory::getBndrows() const {
+ return tileBndR->getBndRows();
+}
+
+dimension_type
+TileFactory::getBndcols() const {
+ return tileBndR->getBndCols();
+}
+
+int
+TileFactory::getNumTiles() const {
+ return (getBndrows()-1) * (getBndcols()-1);
+}
+
+/* returns the i value of the upper left-hand point in the current tile */
+dimension_type
+TileFactory::getIMarker() const {
+ return iMarker;
+}
+
+/* returns the j value of the upper left-hand point in the current tile */
+dimension_type
+TileFactory::getJMarker() const {
+ return jMarker;
+}
+
+int
+TileFactory::getNumTileBndPts() const {
+ return numTileBndPts;
+}
+
+
+/* checks to see if point i,j lies on a bundary in the
+ TileFactory. returns 1 if the point is a boundary and 0
+ otherwise */
+int
+TileFactory::isBoundary(dimension_type i, dimension_type j) const {
+ return IS_BOUNDARY(i,j);
+}
+
+/* There are 8 different types of points in any particular grid as
+ defined in tile.h. this method takes a point i,j and returns its
+ classification */
+
+int
+TileFactory::classifyPoint(dimension_type i, dimension_type j) const {
+
+ //if ((i < 0) || (i >= nrowsPad) || (j < 0) || (j >= ncolsPad))
+ assert(i != dim_undef && j != dim_undef);
+ if ( (i >= nrowsPad) || (j >= ncolsPad))
+ return NOT_IN_GRID;
+
+ if ((i==0 && j==0) || (i == 0 && j == ncolsPad-1) ||
+ (i == nrowsPad-1 && j == 0) || (i == nrowsPad-1 && j == 0))
+ return EXT_CNR;
+
+ if (i == 0 || i == nrowsPad-1) {
+ if (j == 0 || j == ncolsPad-1) {
+ return EXT_BND;
+ }
+ if (j %(tileSizeCols-1) == 0)
+ return EXT_COL_CNR;
+ return EXT_BND;
+ }
+
+ if (j == 0 || j == ncolsPad-1) {
+ if (i%(tileSizeRows-1) == 0)
+ return EXT_ROW_CNR;
+ return EXT_BND;
+ }
+
+ if (i%(tileSizeRows-1) == 0) {
+ if (j %(tileSizeCols-1) == 0)
+ return INT_CNR;
+ return INT_ROW;
+ }
+
+ if (j %(tileSizeCols-1) == 0)
+ return INT_COL;
+
+ return NOT_BND;
+}
+
+
+/* Each different type of boundary point has a different number of
+ boundary neighbors (really this is the reason for classification in
+ the first place). This method takes a point i,j and returns how
+ many boundary neighbors it will have */
+int
+TileFactory::getNumNeighbors(dimension_type i, dimension_type j) const {
+ int mode = classifyPoint(i,j);
+
+ switch(mode) {
+
+ case EXT_BND :
+ return numTileBndPts;
+ case INT_ROW :
+ return 2*numTileBndPts;
+ case INT_COL :
+ return 2*numTileBndPts;
+ case INT_CNR :
+ return 4*numTileBndPts;
+ case EXT_ROW_CNR :
+ return 2*numTileBndPts;
+ case EXT_COL_CNR :
+ return 2*numTileBndPts;
+ case EXT_CNR :
+ return numTileBndPts;
+ case NOT_BND :
+ return 0;
+ case NOT_IN_GRID :
+ return -1;
+ }
+
+ return -1;
+}
+
+void
+TileFactory::printClassification(int in) const {
+ switch(in) {
+
+ case EXT_BND :
+ cout << "Exterior Boundary\n";
+ break;
+ case INT_ROW :
+ cout << "Interior Row\n";
+ break;
+ case INT_COL :
+ cout << "Interior Column\n";
+ break;
+ case INT_CNR :
+ cout << "Interior Corner\n";
+ break;
+ case EXT_ROW_CNR :
+ cout << "Exterior Row Corner\n";
+ break;
+ case EXT_COL_CNR :
+ cout << "Exterior Col Corner\n";
+ break;
+ case EXT_CNR :
+ cout << "Exterior Corner\n";
+ break;
+ case NOT_BND :
+ cout << "Not A Boundary\n";
+ break;
+ case NOT_IN_GRID :
+ cout << "Not In Grid\n";
+ break;
+ }
+}
Added: grass-addons/raster/r.terracost/tile.h
===================================================================
--- grass-addons/raster/r.terracost/tile.h (rev 0)
+++ grass-addons/raster/r.terracost/tile.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,130 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#ifndef _TILE_H
+#define _TILE_H
+
+#include <grass/iostream/ami.h>
+//#include "boundary.h"
+#include "types.h"
+#include "input.h"
+#include "sortutils.h"
+#include <ostream>
+
+#define EXT_BND 0
+#define INT_ROW 1
+#define INT_COL 2
+#define INT_CNR 3
+#define EXT_ROW_CNR 4
+#define EXT_COL_CNR 5
+#define EXT_CNR 6
+#define NOT_BND 7
+#define NOT_IN_GRID 8
+
+
+#include "tileAbs.h"
+#include "boundaryMgr.h"
+
+
+/*
+ The TileFactory is responsible for iterating through each of the tiles
+ in order. It creates a tile by combining data from the tileBnd boundary
+ structure and the internalstr(internal stream) structure.
+*/
+class TileFactory {
+ /* cost grid = bndCost U intCost
+
+ The tile is useful because we can
+ alias the current tile and thus have funtions which operate on
+ the tile through the TileFactory this way any outside methods
+ don't need to know anything about what's going on inside the
+ TileFactory */
+ Tile* tile;
+/* BoundaryType<costSourceType>* tileBnd; */
+ CachedBoundaryMgr<costSourceType>* tileBnd;
+ BoundaryTileReader<costSourceType>* tileBndR;
+ AMI_STREAM<ijCostSource> *internalstr;
+
+ int boundaryMarker, internalMarker, iMarker, jMarker, numTileBndPts;
+ dimension_type tileSizeRows, tileSizeCols;
+
+ protected:
+ int fillTile();
+ void addBoundaryPoint(dimension_type i, dimension_type j);
+ int addInternalPoint(dimension_type i, dimension_type j);
+
+ public:
+ TileFactory(dimension_type gtileSizeRows, dimension_type gtileSizeCols,
+ size_t tilemem);
+
+ TileFactory(dimension_type gtileSizeRows, dimension_type gtileSizeCols,
+ AMI_STREAM<ijCostSource> *dataStream, /* char* internalPath, */
+ const char* bndPath);
+
+ ~TileFactory();
+
+ void markBoundaryAsSorted() { /* tileBnd->markAsSorted(); */}
+
+ int getNextTile(Tile* t);
+
+ void setIMarker(int inI);
+ void setJMarker(int inJ);
+
+ void insert(ijCostSource in);
+
+ void sortTF();
+
+ /*
+ In order to index the b2b stream correctly each tile needs to be
+ the same size. This method adds padding to both the rows and
+ columns to achieve this.
+ */
+ void pad();
+
+ dimension_type getRows() const;
+ dimension_type getCols() const;
+ dimension_type getBndrows() const;
+ dimension_type getBndcols() const;
+ dimension_type getIMarker() const;
+ dimension_type getJMarker() const;
+
+ int getNumTiles() const;
+ int getNumTileBndPts() const;
+ int getTotalPoints();
+
+ int isBoundary(dimension_type i, dimension_type j) const;
+ int classifyPoint(dimension_type i, dimension_type j) const;
+
+ void printClassification(int in) const;
+
+ int getNumNeighbors(dimension_type i, dimension_type j) const;
+
+ void reset();
+
+ void serialize(const char *path) { tileBnd->serialize(path); };
+
+ /* how much memory soes it use? */
+ long memoryUsage() {
+ /* we only count the boundaryMgs */
+ return (tileBnd ? tileBnd->memoryUsage() : 0);
+ }
+
+};
+
+
+#endif
Property changes on: grass-addons/raster/r.terracost/tile.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/tileAbs.cc
===================================================================
--- grass-addons/raster/r.terracost/tileAbs.cc (rev 0)
+++ grass-addons/raster/r.terracost/tileAbs.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,117 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include "tileAbs.h"
+
+#if 0
+/* Initializes the 2D array and the rows and cols variables */
+OldTile::OldTile(dimension_type inRows, dimension_type inCols) {
+
+ rows = inRows;
+ cols = inCols;
+
+ grid = new ijCostSource*[rows];
+ assert(grid);
+ for (int i=0; i<rows; i++) {
+ grid[i] = new ijCostSource[cols];
+ assert(grid[i]);
+ }
+}
+
+/* Should I use some sort of grid copying function here or is the
+ pointer OK? */
+OldTile::OldTile(ijCostSource** inGrid, dimension_type inRows,
+ dimension_type inCols) {
+
+ rows = inRows;
+ cols = inCols;
+
+ grid = inGrid;
+
+}
+
+OldTile::~OldTile() {
+
+ assert(grid);
+
+
+ for (int i=0; i<rows; i++) {
+ //cout << i << endl; cout.flush();
+ assert(grid[i]);
+ delete [] grid[i];
+ }
+
+ assert(grid);
+ delete [] grid;
+
+}
+
+void
+OldTile::insert(dimension_type i, dimension_type j, ijCostSource cost) {
+ grid[i][j] = cost;
+}
+
+
+
+void
+OldTile::printTile() {
+ cout << "Rows: " << rows << " Cols: " << cols << "\n";
+ for (int i = 0; i<rows; i++) {
+ for (int j = 0; j<cols; j++) {
+
+ cout << grid[i][j].getCost() << " ";
+
+ //checking i,j values
+ ijCostSource stored = grid[i][j];
+
+
+ //dimension_type storedI = stored.getI();
+ //dimension_type storedJ = stored.getJ();
+ //cout << "(" << storedI << "," << storedJ << ") ";
+
+ }
+ cout << "\n";
+ }
+}
+#endif
+
+
+#include "formatNumber.h"
+
+void
+Tile::printStats(ostream& str) {
+
+ str << "Tile: "
+ << rows << " x "<< cols << ", total=" << rows * cols
+ << ", elem size =" << sizeof(ijCost)
+ << ", total tile size "
+ << formatNumber(NULL, rows * cols * sizeof(ijCost)) << endl;
+}
+
+void
+Tile::init(Tile *tile) {
+ tile->valid = 0;
+ tile->s2bWriteCount = 0;
+ tile->s2bPQCount = 0;
+}
+
+void
+Tile::dump() {
+ printStats(cout);
+ cout << "Tile: s2bWriteCount = " << s2bWriteCount << endl;
+ cout << "Tile: s2bPQCount = " << s2bPQCount << endl;
+}
Added: grass-addons/raster/r.terracost/tileAbs.h
===================================================================
--- grass-addons/raster/r.terracost/tileAbs.h (rev 0)
+++ grass-addons/raster/r.terracost/tileAbs.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,79 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include <ostream>
+
+#include "types.h"
+#include "input.h"
+#include "genericTile.h"
+#include "config.h"
+
+/* this class bridges the gap between a mappedTile and the original Tile interface
+ * also includes some debug output
+ */
+class Tile : public mappedTile<costSourceType> {
+ /* this is a hack - we use the first point inserted to get the base values */
+ int valid;
+
+ public:
+ Tile(dim_t inRows, dim_t inCols) :
+ mappedTile<costSourceType>(inRows, inCols), valid(0) {};
+
+ /* this is only called from tile.cc, boundaryMgr */
+ void insert(dim_t i, dim_t j, ijCostSource & cost) {
+ if(!valid) {
+ deriveBasis(cost, i, j);
+ valid = 1;
+ }
+ put(i, j, cost);
+ };
+
+ /* debugging */
+ static void init(Tile *);
+ int s2bWriteCount;
+ int s2bPQCount;
+ void dump();
+
+ void printStats(ostream& str);
+
+
+ /*
+ * helpers; -1 on error; only valid inside tile - not on boundary
+ * these are currently not used; perhaps will move soon.
+ */
+
+ /* tile point belongs to; -1 if error/boundary */
+ int tileNum(const basicIJType & point) const {
+ dim_t sizeCols = ((ncols-1)/cols)+1;
+ dim_t tileNumI = point.getI()/(rows-1);
+ dim_t tileNumJ = point.getJ()/(cols-1);
+ return tileNumI + tileNumJ * sizeCols;
+ };
+
+ /* row in tile */
+ dim_t tileRow(const basicIJType & point) const {
+ return (point.getI() % (rows - 1));
+ };
+
+ /* col in tile */
+ dim_t tileCol(const basicIJType & point) const {
+ return (point.getJ() % (cols - 1));
+ };
+
+
+};
+
Property changes on: grass-addons/raster/r.terracost/tileAbs.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/tileSplit.cc
===================================================================
--- grass-addons/raster/r.terracost/tileSplit.cc (rev 0)
+++ grass-addons/raster/r.terracost/tileSplit.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,260 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+/*
+ * split stream into tiles
+ *
+ * rajiv wickremesinghe 2005
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include <grass/iostream/ami.h>
+#include "locator.h"
+#include "input.h"
+#include "config.h"
+#include "queue.h"
+
+
+static void
+usage() {
+ printf("usage: tileSplit [options]\n");
+// printf(" -n<arity>\n");
+ printf(" -i<input> (default=stdin)\n");
+ printf(" -o<outroot>\n");
+ printf(" -c<config>\n");
+}
+
+#define BUFFER_SIZE (32<<10)
+
+static int opencalls = 0;
+
+void
+file_name(char *buf, char *outroot, int id) {
+ sprintf(buf, "%s-%04d", outroot, id);
+}
+
+
+int
+open_file(char *outroot, int id, int truncate) {
+ char buf[BUFSIZ];
+
+ opencalls++;
+
+ file_name(buf, outroot, id);
+ int fd = open(buf, O_WRONLY | O_CREAT | (truncate?O_TRUNC:O_APPEND), 0666);
+ if(fd < 0) {
+ perror(buf);
+ exit(1);
+ }
+ return fd;
+}
+
+typedef struct open_stream_t {
+ int id;
+ TAILQ_ENTRY(open_stream_t) link;
+} open_stream_t;
+
+TAILQ_HEAD(qhead, open_stream_t) qhead = TAILQ_HEAD_INITIALIZER(qhead);
+#define QSIZ 200
+
+void
+qinit() {
+ int i;
+ for(i=0; i<QSIZ; i++) {
+ open_stream_t *strm = (open_stream_t *)malloc(sizeof(open_stream_t));
+ assert(strm);
+ strm->id = -1;
+ TAILQ_INSERT_TAIL(&qhead, strm, link);
+ }
+}
+
+AMI_STREAM<ijCostSource> *
+get_stream(AMI_STREAM<ijCostSource> **outstrms, char *outroot, int id) {
+ int fd;
+ static int inited = 0;
+
+ if(!inited) {
+ qinit();
+ }
+ inited = 1;
+
+ if(!outstrms[id]) { // must open
+ open_stream_t *strm = TAILQ_FIRST(&qhead);
+ if(strm->id >= 0) { // clean head if needed
+ delete outstrms[strm->id];
+ outstrms[strm->id] = NULL;
+ }
+ TAILQ_REMOVE(&qhead, strm, link);
+ strm->id = id;
+ fd = open_file(outroot, id, 0);
+ outstrms[id] = new AMI_STREAM<ijCostSource>(fd, AMI_APPEND_WRITE_STREAM);
+ TAILQ_INSERT_TAIL(&qhead, strm, link);
+ }
+ return outstrms[id];
+}
+
+
+int
+main(int argc, char **argv) {
+ int fdin = STDIN_FILENO;
+ char *path = NULL;
+ int arity=0;
+ int reclen;
+ int off;
+ AMI_STREAM<ijCostSource> **outstrms;
+ char *config_file=NULL;
+ char *outroot = NULL;
+ int ch;
+ int group = 1;
+
+ while ((ch = getopt(argc, argv, "ho:i:c:g:n:")) != -1) {
+ switch (ch) {
+ case 'i':
+ path = optarg;
+ break;
+ case 'o':
+ outroot = strdup(optarg);
+ break;
+ case 'n':
+ arity = atoi(optarg);
+ break;
+ case 'g':
+ group = atoi(optarg);
+ break;
+ case 'c':
+ config_file = strdup(optarg);
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ }
+ }
+
+ if(path) {
+ fdin = open(path, O_RDONLY);
+ if(fdin < 0) {
+ perror(path);
+ exit(1);
+ }
+ }
+
+ if(!outroot || !config_file || group<1) {
+ usage();
+ exit(1);
+ }
+
+ readConfigFile(config_file);
+ if(arity >= g.ntiles) {
+ arity = g.ntiles;
+ group = 1;
+ } else if(arity) {
+ // arity gets precedence
+ group = (g.ntiles + arity - 1) / arity; // roundup
+ } else {
+ assert(group > 0);
+ arity = (g.ntiles + group - 1) / group; // roundup
+ }
+
+ off_t expectedSize = (off_t)(tsr-2) * (tsc-2) * sizeof(ijCostSource) * group;
+ fprintf(stderr, "arity=%d\n", arity);
+ fprintf(stderr, "sizeof(ijCostSource)=%d expected file size=%lld\n",
+ sizeof(ijCostSource), expectedSize);
+ fprintf(stderr, "group=%d\n", group);
+
+ reclen = sizeof(ijCostSource);
+ assert(reclen < BUFFER_SIZE);
+
+ outstrms = (AMI_STREAM<ijCostSource>**)malloc(sizeof(AMI_STREAM<ijCostSource>*) * arity);
+ assert(outstrms);
+
+ for(int i=0; i<arity; i++) {
+ int fd = open_file(outroot, i, 1);
+ close(fd);
+ outstrms[i] = NULL;
+ }
+
+ IJClassifier ijcc(config_file);
+ int nread = 0;
+ int nwrite = 0;
+
+ cerr << "Running split..." << endl;
+
+ AMI_STREAM<ijCostSource> *strm = new AMI_STREAM<ijCostSource>(fdin, AMI_READ_STREAM);
+ while(!strm->eof()) {
+ ijCostSource *record;
+ AMI_err ae;
+
+ ae = strm->read_item(&record);
+ if(ae == AMI_ERROR_END_OF_STREAM) {
+ continue;
+ }
+ assert(ae == AMI_ERROR_NO_ERROR);
+ nread++;
+
+ off = ijcc.classify(record) % arity;
+ //assert(off < arity);
+ //assert(off >= 0);
+
+ ae = get_stream(outstrms, outroot, off)->write_item(*record);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ nwrite++;
+ }
+
+ for(int i=0; i<arity; i++) {
+ //fprintf(stderr, "output [%d] length = %ld\n", i, (long)outstrms[i]->tell());
+ char buf[BUFSIZ];
+ file_name(buf, outroot, i);
+ printf("%s\n", buf);
+ if(outstrms[i]) {
+ delete outstrms[i];
+ }
+ }
+#ifndef NDEBUG
+ fprintf(stderr, "Checking file sizes...");
+ for(int i=0; i<arity; i++) {
+ char buf[BUFSIZ];
+ file_name(buf, outroot, i);
+ struct stat sb;
+ if(stat(buf, &sb)) {
+ perror(buf);
+ exit(1);
+ }
+ if(sb.st_size != expectedSize) {
+ fprintf(stderr, "file size mismatch for %s\n", buf);
+ exit(1);
+ }
+ }
+ fprintf(stderr, " done\n");
+#endif
+ free(outstrms);
+
+ //fprintf(stderr, "%d records read; %d records written\n", nread, nwrite);
+ assert(nread == nwrite);
+ //fprintf(stderr, "input length = %ld\n", (long)strm->tell());
+
+ fprintf(stderr, "open calls = %d\n", opencalls);
+
+ return 0;
+}
Added: grass-addons/raster/r.terracost/types.h
===================================================================
--- grass-addons/raster/r.terracost/types.h (rev 0)
+++ grass-addons/raster/r.terracost/types.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,58 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef _types_H
+#define _types_H
+
+#include <limits.h>
+#include <float.h>
+#include <iostream>
+
+using namespace std;
+
+
+/* represent dimension of the grid */
+
+/* this can deal with grids of dimensions up to 32767 */
+typedef short dim_t;
+static const dim_t dimension_type_max = (SHRT_MAX - 2);
+
+/* this can deal with grids of dimensions up to 65536 */
+/* typedef unsigned short dim_t; */
+/* static const dim_t dimension_type_max = (USHRT_MAX - 2); */
+
+
+
+
+typedef int signed_dim_t; /* should ONLY be used temp structures */
+
+typedef dim_t dimension_type;
+static const dim_t dim_undef = USHRT_MAX;
+
+/* typedef int dimension_type; */ /* represent dimension of the grid */
+/* static const dimension_type dimension_type_max=INT_MAX; */
+
+
+
+typedef float cost_type; /* represent the cost of a cell */
+static const cost_type cost_type_max=FLT_MAX;
+
+
+typedef float dist_type; /* represent the sp(shortest path) of a cell */
+
+#endif
+
Property changes on: grass-addons/raster/r.terracost/types.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/update.cc
===================================================================
--- grass-addons/raster/r.terracost/update.cc (rev 0)
+++ grass-addons/raster/r.terracost/update.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,236 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include "update.h"
+
+/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+*/
+
+
+void normalUpdateNeighbors(costStructure costStr,
+ pqheap_ijCost *pq,
+ cost_type **distGrid,
+ cost_type** costGrid) {
+
+ dimension_type thisRow = costStr.getI();
+ dimension_type thisCol = costStr.getJ();
+ cost_type thisCost = costGrid[thisRow][thisCol];
+ cost_type thisDist = distGrid[thisRow][thisCol];
+
+ cost_type neighborCost;
+ cost_type neighborDist;
+ cost_type oldNeighborDist;
+
+ //cost_type traversalCost;
+ int numNeighbors = 8; // 16 if knight's move is used.
+
+ //Taken from original r.cost module
+ //dimension_type row=dimension_type_max, col=dimension_type_max;
+ for(int neighborIndex=1;neighborIndex<=numNeighbors;neighborIndex++ ) {
+
+ signed_dim_t row = thisRow + deltaRow[neighborIndex];
+ signed_dim_t col = thisCol + deltaCol[neighborIndex];
+
+ assert(row != dimension_type_max && col != dimension_type_max); // -RW
+
+ if ( row < 0 || row >= nrows) {
+ continue ;
+ }
+ if( col < 0 || col >= ncols) {
+ continue;
+ }
+
+ if (costGrid[row][col] == NODATA) {
+ continue;
+ }
+
+ neighborCost = costGrid[row][col];
+ // travMult already include 0.5 factor
+ neighborDist = thisDist + (neighborCost + thisCost) * travMult[neighborIndex];
+ oldNeighborDist = distGrid[row][col];
+
+ if (neighborDist < oldNeighborDist && thisCost != NODATA) {
+ distGrid[row][col] = neighborDist;
+ pq->insert(costStructure(neighborDist,row, col));
+ }
+ }
+}
+
+
+
+
+/* ---------------------------------------------------------------------- */
+ // The following cases(9-16) are only used for the knight's move
+ /*
+
+ case 9:
+ value = &NNW ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(N + NW + NNW + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*V_DIAG_fac ;
+ break ;
+ case 10:
+ value = &NNE ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(N + NE + NNE + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*V_DIAG_fac ;
+ break ;
+ case 11:
+ value = &SSE ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(S + SE + SSE + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*V_DIAG_fac ;
+ break ;
+ case 12:
+ value = &SSW ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(S + SW + SSW + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*V_DIAG_fac ;
+ break ;
+ case 13:
+ value = &WNW ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(W + NW + WNW + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*H_DIAG_fac ;
+ break ;
+ case 14:
+ value = &ENE ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(E + NE + ENE + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*H_DIAG_fac ;
+ break ;
+ case 15:
+ value = &ESE ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(E + SE + ESE + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*H_DIAG_fac ;
+ break ;
+ case 16:
+ value = &WSW ;
+ segment_get(&in_seg,value,row,col);
+ fcost = (double)(W + SW + WSW + my_cost) / 4.0 ;
+ min_cost = thisCell->min_cost+fcost*H_DIAG_fac ;
+ break ;
+
+ */
+
+
+
+
+
+/* ---------------------------------------------------------------------- */
+void
+updateInterNeighbors(costStructureOld cs, const SettleLookup & settled,
+ EMPQueueAdaptive<costStructureOld, costPriorityOld> *pq,
+ AMI_STREAM<distanceType> *b2bstr, const TileFactory *tf,
+ const BoundaryType<cost_type> *phase2Bnd ) {
+
+ AMI_err ae;
+ assert(!isNull(cs.getPriority().getDist()));
+
+ dimension_type thisRow = cs.getI();
+ dimension_type thisCol = cs.getJ();
+ cost_type thisCost = cs.getPriority().getDist();
+ costStructureOld outCS;
+ ijCost neighbor;
+ dimension_type neighborI, neighborJ;
+ cost_type neighborCost, neighborDist;
+ int numNeighbors = tf->getNumNeighbors(thisRow, thisCol);
+ off_t marker = getFromIndex(thisRow,thisCol, tf);
+
+ distanceType *dType;
+// if (marker >= b2bstr->stream_len()) {
+// cout << "ThisRow: " << thisRow << " ThisCol: " << thisCol << endl;
+// cout << "Marker: " << marker << endl; cout.flush();
+// cout << "Index: " << marker << " Stream length: " <<
+// b2bstr->stream_len() << "\n";cout.flush();
+// }
+// assert (marker < b2bstr->stream_len());
+
+ ae = b2bstr->seek(marker);
+
+
+
+ for (int a = 0; a<numNeighbors && ae == AMI_ERROR_NO_ERROR; a++) {
+// if (a+marker >= b2bstr->stream_len()) {
+// cout << "ThisRow: " << thisRow << " ThisCol: " << thisCol << endl;
+// cout << "A: " << a << " Marker: " << marker << endl; cout.flush();
+// cout << "Index: " << a+marker << " Stream length: " <<
+// b2bstr->stream_len() << "\n";cout.flush();
+// }
+// assert (a+marker < b2bstr->stream_len());
+ ae = b2bstr->read_item(&dType);
+ assert(ae == AMI_ERROR_NO_ERROR);
+ neighborI = dType->getToI();
+ neighborJ = dType->getToJ();
+
+ if (dType->getFromI() != cs.getI() || dType->getFromJ() != cs.getJ()) {
+ cerr << "updateInterNeighbors: ERROR Stream: " << *dType << " PQ: "
+ << cs << endl;
+ assert(0);
+ exit(1);
+ }
+
+ if (!isNull(neighborI) && !isNull(neighborJ) &&
+ !isNull(dType->getDistance()) &&
+ !settled.isSettled(neighborI, neighborJ, tf)) {
+ int doInsert = 1;
+ neighborCost = thisCost + dType->getDistance();
+
+ // if we have an in-memory boundary, make use of it!
+ if(phase2Bnd->canGetFast(neighborI, neighborJ)) {
+ ijCost curCost;
+ ((BoundaryType<cost_type>*)phase2Bnd)->get(neighborI, neighborJ, &curCost);
+ if(curCost.getCost() <= neighborCost) {
+ doInsert = 0; // squash insert
+ }
+ }
+
+ if(doInsert) {
+ neighbor = ijCost(neighborI, neighborJ, neighborCost);
+ outCS = costStructureOld(neighbor);
+ pq->insert(outCS);
+ //cout << "updateInterNeighbors::inserting: " << outCS << " from " << cs
+ // << endl;cout.flush();
+ }
+
+ }
+ }
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+SettleLookup::SettleLookup(dim_t nrowsPad, dim_t ncolsPad, const TileFactory *tf) {
+ /*settledSize is the size of the settled index. It is computed by
+ asking for the index of the last item in the array to be inserted
+ in the array*/
+
+ size = getSettledIndex(nrowsPad-1, ncolsPad-1, tf) + 1;
+ cerr << "Settle Size: " << size << " (" << nrowsPad << " x " << ncolsPad << ")" << endl;
+
+ /*settledArray is an array of 1s or 0s depending if a point is
+ settled or not respectivly */
+ arr = new int[size];
+ for (int i = 0; i < size; i++) {
+ arr[i] = 0;
+ }
+}
+
+SettleLookup::~SettleLookup() {
+ delete arr;
+}
Added: grass-addons/raster/r.terracost/update.h
===================================================================
--- grass-addons/raster/r.terracost/update.h (rev 0)
+++ grass-addons/raster/r.terracost/update.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,79 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#ifndef _UPDATE_H
+#define _UPDATE_H
+
+extern "C" {
+#include <grass/gis.h>
+}
+
+#include <grass/iostream/ami.h>
+#include "tile.h"
+#include "pqueue.h"
+#include "types.h"
+#include "distanceType.h"
+#include "pq.h"
+#include "index.h"
+
+#include "updateAbs.h"
+#include "boundary.h"
+
+class SettleLookup {
+ int *arr;
+ int size;
+
+ public:
+ SettleLookup(dim_t nrowsPad, dim_t ncolsPad, const TileFactory *tf);
+ ~SettleLookup();
+
+
+ int isSettled(dim_t i, dim_t j, const TileFactory *tf) const {
+ int index = getSettledIndex(i, j, tf);
+#ifndef NDEBUG
+ if(index >= size) {
+ fprintf(stderr, "index (%d) out of bounds (%d)\n", index, size);
+ fprintf(stderr, "while checking point i=%d, j=%d\n", i, j);
+ fprintf(stderr, "tsr=%d, tsc=%d, nbrows=%d, nbcols=%d\n",
+ tf->getRows(), tf->getCols(), tf->getBndrows(), tf->getBndcols());
+ }
+#endif
+ assert(index < size);
+ return arr[index];
+ };
+
+ void settlePoint(dim_t i, dim_t j, const TileFactory *tf) {
+ int index = getSettledIndex(i, j, tf);
+ assert(index < size);
+ arr[index] = 1;
+ //cout << "Point " << i << "," << j << " settled" << endl;cout.flush();
+ };
+
+};
+
+
+void normalUpdateNeighbors(costStructure costStr,
+ pqheap_ijCost *pq,
+ cost_type **distGrid, cost_type** costGrid);
+
+void updateInterNeighbors(costStructureOld cs, const SettleLookup & ar,
+ EMPQueueAdaptive<costStructureOld, costPriorityOld> *pq,
+ AMI_STREAM<distanceType> *b2bstr,
+ const TileFactory *tf,
+ const BoundaryType<cost_type> *phase2Bnd );
+
+#endif
Property changes on: grass-addons/raster/r.terracost/update.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: grass-addons/raster/r.terracost/updateAbs.cc
===================================================================
--- grass-addons/raster/r.terracost/updateAbs.cc (rev 0)
+++ grass-addons/raster/r.terracost/updateAbs.cc 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,111 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+
+#include "tileAbs.h"
+#include "pq.h"
+#include "pqueue.h"
+#include "types.h"
+#include "distanceType.h"
+#include "updateAbs.h"
+
+const int deltaRow[] = {0, 0, 0,-1,+1,-1,-1,+1,+1,-2,-2,-1,+1,+2,+2,+1,-1};
+const int deltaCol[] = {0,-1,+1, 0, 0,-1,+1,+1,-1,-1,+1,+2,+2,+1,-1,-2,-2};
+cost_type travMult[17] = {};
+
+void
+update_init(cost_type EW_fac, cost_type NS_fac, cost_type DIAG_fac) {
+ travMult[0] = 0;
+ travMult[1] = EW_fac / 2.0;
+ travMult[2] = EW_fac / 2.0;
+ travMult[3] = NS_fac / 2.0;
+ travMult[4] = NS_fac / 2.0;
+ travMult[5] = DIAG_fac / 2.0;
+ travMult[6] = DIAG_fac / 2.0;
+ travMult[7] = DIAG_fac / 2.0;
+ travMult[8] = DIAG_fac / 2.0;
+ //to be filled with knights move
+}
+
+
+void
+updateNeighbors(const Tile* inT, costStructure costStr,
+ pqheap_ijCost *pq,
+ cost_type **dist) {
+
+ dimension_type thisRow = costStr.getI();
+ dimension_type thisCol = costStr.getJ();
+ assert(thisRow != dimension_type_max && thisCol != dimension_type_max);
+ cost_type thisDist = dist[thisRow][thisCol];
+
+ cost_type thisCost = inT->get(thisRow,thisCol).getCost();
+ if (thisCost == NODATA) return;
+
+ //Taken from original r.cost module
+ const int numNeighbors = 8; // 16 if knight's move is used.
+ //dimension_type row=dimension_type_max, col=dimension_type_max;
+ for(int neighborIndex=1; neighborIndex <= numNeighbors; neighborIndex++) {
+
+ signed_dim_t row = thisRow + deltaRow[neighborIndex];
+ signed_dim_t col = thisCol + deltaCol[neighborIndex];
+ if( !(INTILE(inT,row,col)) ) {
+ continue;
+ }
+ cost_type *dp = &dist[row][col]; // current estimate
+ const costSourceType & neighbor = inT->get(row,col);
+ if (neighbor.isNull()) {
+ continue;
+ }
+
+// neighborCost = neighbor.getCost().getCost();
+// traversalCost = (cost_type)(neighborCost + thisCost) / 2.0 ;
+// neighborDist = thisDist + traversalCost * opt->travMult[neighborIndex];
+
+ // travMult already includes 0.5 factor
+ cost_type neighborDist = thisDist + (neighbor.getCost() + thisCost) * travMult[neighborIndex];
+ //At this point we have all of the information for a particular neighbor
+ if (neighborDist < *dp) {
+ *dp = neighborDist;
+ pq->insert(costStructure( neighborDist, row, col));
+ }
+ } //for
+#if 0
+ {
+ dim_t row, col;
+ cost_type *dp;
+ cost_type neighborDist;
+
+ row = thisRow;
+ col = thisCol;
+ dp = &dist[row][col]; // current estimate
+
+ if(INTILE(inT,row,col)) {
+ const costSourceType & neighbor = inT->get(row,col);
+ if(!neighbor.isNull()) {
+ neighborDist = thisDist + (neighbor.getCost() + thisCost) * travMult[neighborIndex];
+ //At this point we have all of the information for a particular neighbor
+ if (neighborDist < *dp) {
+ *dp = neighborDist;
+ pq->insert(costStructure(neighborDist, row, col));
+ }
+ }
+ }
+ }
+#endif
+
+}
+
Added: grass-addons/raster/r.terracost/updateAbs.h
===================================================================
--- grass-addons/raster/r.terracost/updateAbs.h (rev 0)
+++ grass-addons/raster/r.terracost/updateAbs.h 2009-04-08 07:22:12 UTC (rev 36623)
@@ -0,0 +1,27 @@
+/*
+
+ Copyright (C) 2006 Thomas Hazel, Laura Toma, Jan Vahrenhold and
+ Rajiv Wickremesinghe
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+*/
+
+#include "types.h"
+
+extern const int deltaRow[];
+extern const int deltaCol[];
+extern cost_type travMult[17];
+
+void update_init(cost_type EW_fac, cost_type NS_fac, cost_type DIAG_fac);
+
+void updateNeighbors(const Tile* inT, costStructure costStr,
+ pqheap_ijCost *pq, cost_type **dist);
Property changes on: grass-addons/raster/r.terracost/updateAbs.h
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the grass-commit
mailing list