[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(&currentVertex);
+	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