[GRASS-SVN] r40632 - grass/trunk/raster/r.walk

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jan 24 12:22:41 EST 2010


Author: mmetz
Date: 2010-01-24 12:22:41 -0500 (Sun, 24 Jan 2010)
New Revision: 40632

Added:
   grass/trunk/raster/r.walk/heap.c
Removed:
   grass/trunk/raster/r.walk/btree.c
   grass/trunk/raster/r.walk/local_proto.h
   grass/trunk/raster/r.walk/memory.c
   grass/trunk/raster/r.walk/memory.h
Modified:
   grass/trunk/raster/r.walk/cost.h
   grass/trunk/raster/r.walk/main.c
   grass/trunk/raster/r.walk/stash.h
Log:
sync to r.cost

Deleted: grass/trunk/raster/r.walk/btree.c
===================================================================
--- grass/trunk/raster/r.walk/btree.c	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/btree.c	2010-01-24 17:22:41 UTC (rev 40632)
@@ -1,446 +0,0 @@
-/* These routines manage the list of grid-cell candidates for 
- * visiting to calculate distances to surrounding cells.
- * A binary tree (btree) approach is used.  Components are
- * sorted by distance.
- *
- * insert ()
- *   inserts a new row-col with its distance value into the btree
- *
- * delete()
- *   deletes (if possible) a row-col entry in the tree
- *
- * get_lowest()
- *   retrieves the entry with the smallest distance value
- */
-
-
-#include <grass/gis.h>
-#include "local_proto.h"
-#include "memory.h"
-#include <stdlib.h>
-
-static struct cost *start_cell = NULL;
-
-/*  static int show(struct cost *); */
-static int do_quit(double, int, int);
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-struct cost *insert(double min_cost, int row, int col)
-{
-    struct cost *new_cell, *next_cell;
-
-    /*      new_cell = (struct cost *)(G_malloc(sizeof(struct cost))); */
-    new_cell = get();
-    if (new_cell == NULL) {
-	G_fatal_error("new_cell is NULL\n");
-    }
-    new_cell->min_cost = min_cost;
-    new_cell->row = row;
-    new_cell->col = col;
-    new_cell->above = NULL;
-    new_cell->higher = NULL;
-    new_cell->lower = NULL;
-    new_cell->nexttie = NULL;
-    new_cell->previoustie = NULL;
-
-    if (start_cell == NULL) {
-	start_cell = new_cell;
-	return (new_cell);
-    }
-
-    for (next_cell = start_cell;;) {
-	if (min_cost < next_cell->min_cost) {
-	    if (next_cell->lower != NULL) {
-		next_cell = next_cell->lower;
-		continue;
-	    }
-	    new_cell->above = next_cell;
-	    next_cell->lower = new_cell;
-	    return (new_cell);
-	}
-	if (min_cost > next_cell->min_cost) {
-	    if (next_cell->higher != NULL) {
-		next_cell = next_cell->higher;
-		continue;
-	    }
-	    new_cell->above = next_cell;
-	    next_cell->higher = new_cell;
-	    return (new_cell);
-	}
-
-	/* If we find a value that is exactly equal to new value */
-	new_cell->nexttie = next_cell->nexttie;
-	next_cell->nexttie = new_cell;
-	new_cell->previoustie = next_cell;
-	if (new_cell->nexttie != NULL)
-	    new_cell->nexttie->previoustie = new_cell;
-
-	return (new_cell);
-    }
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-struct cost *find(double min_cost, int row, int col)
-{
-    struct cost *next_cell;
-    struct cost *next_tie_cell;
-
-    for (next_cell = start_cell;;) {
-	if (min_cost <= next_cell->min_cost) {
-	    for (next_tie_cell = next_cell;
-		 next_tie_cell != NULL;
-		 next_tie_cell = next_tie_cell->nexttie)
-		if (next_tie_cell->row == row && next_tie_cell->col == col)
-		    return (next_tie_cell);
-	    /*
-	       if (next_cell->row == row && next_cell->col == col)
-	       return(next_cell) ;
-	     */
-
-	    if (next_cell->lower != NULL) {
-		next_cell = next_cell->lower;
-		continue;
-	    }
-	    G_message("1 ");
-	    return NULL;
-	    do_quit(min_cost, row, col);
-	}
-	else {
-	    if (next_cell->higher != NULL) {
-		next_cell = next_cell->higher;
-		continue;
-	    }
-	    G_message("2 ");
-	    return NULL;
-	    do_quit(min_cost, row, col);
-	}
-    }
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-static int do_quit(double min_cost, int row, int col)
-{
-    G_warning("Can't find %d,%d:%f\n", row, col, min_cost);
-    show_all();
-    exit(EXIT_FAILURE);
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-struct cost *get_lowest(void)
-{
-    struct cost *next_cell;
-
-    if (start_cell == NULL)
-	return (NULL);
-
-    for (next_cell = start_cell;
-	 next_cell->lower != NULL; next_cell = next_cell->lower) ;
-
-    /* Grab my first tie instead of me */
-    if (next_cell->nexttie != NULL)
-	next_cell = next_cell->nexttie;
-
-    if (next_cell->row == -1) {
-	/*
-	   G_message("Deleting %d\n", next_cell) ;
-	   show_all() ;
-	 */
-	delete(next_cell);
-	/*
-	   G_message("Deleted %d\n", next_cell) ;
-	   show_all() ;
-	 */
-	return (get_lowest());
-    }
-
-    return (next_cell);
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int delete(struct cost *delete_cell)
-{
-    if (delete_cell == NULL) {
-	G_warning("Illegal delete request\n");
-	return 0;
-    }
-
-    /* Simple remove if I'm a one of the "ties" */
-    if (delete_cell->previoustie != NULL) {
-	delete_cell->previoustie->nexttie = delete_cell->nexttie;
-	if (delete_cell->nexttie != NULL)
-	    delete_cell->nexttie->previoustie = delete_cell->previoustie;
-	give(delete_cell);
-	return 0;
-    }
-    /* If I have a list of ties, link replace me with the first
-       in that list  */
-    if (delete_cell->nexttie != NULL) {
-	delete_cell->nexttie->above = delete_cell->above;
-	if (delete_cell->above != NULL) {
-	    if (delete_cell->above->lower == delete_cell)
-		delete_cell->above->lower = delete_cell->nexttie;
-	    else
-		delete_cell->above->higher = delete_cell->nexttie;
-	}
-
-	delete_cell->nexttie->lower = delete_cell->lower;
-	if (delete_cell->lower != NULL)
-	    delete_cell->lower->above = delete_cell->nexttie;
-
-	delete_cell->nexttie->higher = delete_cell->higher;
-	if (delete_cell->higher != NULL)
-	    delete_cell->higher->above = delete_cell->nexttie;
-	if (start_cell == delete_cell)
-	    start_cell = delete_cell->nexttie;
-	delete_cell->nexttie->previoustie = NULL;
-
-	give(delete_cell);
-	return (0);
-    }
-    /*
-       \      \      \      \   
-       1  X   4  X   7  X   10 X  
-       N N    / N    N \    / \ 
-
-       /      /      /      / 
-       2  X   5  X   8  X   11 X  
-       N N    / N    N \    / \
-
-       N      N      N      N  
-       3  X   6  X   9  X   12 X  
-       N N    / N    N \    / \
-     */
-    if (delete_cell->higher == NULL) {	/* 123456       */
-	if (delete_cell->lower == NULL) {	/* 123          */
-	    if (delete_cell->above == NULL) {	/*   3          */
-		start_cell = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	    if (delete_cell->above->higher == delete_cell) {	/* 1            */
-		delete_cell->above->higher = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	    else {		/*  2           */
-		delete_cell->above->lower = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	}
-	else {			/*    456       */
-
-	    if (delete_cell->above == NULL) {	/*      6       */
-		start_cell = delete_cell->lower;
-		delete_cell->lower->above = NULL;
-		give(delete_cell);
-		return 0;
-	    }
-	    if (delete_cell->above->higher == delete_cell) {	/*    4         */
-		delete_cell->above->higher = delete_cell->lower;
-		delete_cell->lower->above = delete_cell->above;
-		give(delete_cell);
-		return 0;
-	    }
-	    else {		/*     5        */
-		delete_cell->above->lower = delete_cell->lower;
-		delete_cell->lower->above = delete_cell->above;
-		give(delete_cell);
-		return 0;
-	    }
-	}
-    }
-    if (delete_cell->lower == NULL) {	/*       789    */
-	if (delete_cell->above == NULL) {	/*         9    */
-	    start_cell = delete_cell->higher;
-	    delete_cell->higher->above = NULL;
-	    give(delete_cell);
-	    return 0;
-	}
-	if (delete_cell->above->higher == delete_cell) {	/*       7      */
-	    delete_cell->above->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-	else {			/*        8     */
-	    delete_cell->above->lower = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-    }
-    /*
-     * At this point we are left with 10,11,12 which can be expanded
-     *    \   
-     *  10 X         X          X   
-     *    / \       / \        / \  
-     *          A  O   -   B  -   O     C ALL OTHERS
-     *      /     / N            N \
-     *  11 X  
-     *    / \
-     *
-     *     N  
-     *  12 X  
-     *    / \
-     */
-
-    if (delete_cell->lower->higher == NULL) {	/* A */
-	if (delete_cell == start_cell) {	/* 12A */
-	    delete_cell->lower->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->lower;
-	    start_cell = delete_cell->lower;
-	    delete_cell->lower->above = NULL;
-	    give(delete_cell);
-	    return 0;
-	}
-	if (delete_cell->above->higher == delete_cell) {	/* 10A */
-	    delete_cell->lower->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->lower;
-	    delete_cell->above->higher = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-	else {			/* 11A */
-	    delete_cell->lower->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->lower;
-	    delete_cell->above->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-    }
-    if (delete_cell->higher->lower == NULL) {	/* A */
-	if (delete_cell == start_cell) {	/* 12B */
-	    delete_cell->higher->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->higher;
-	    start_cell = delete_cell->higher;
-	    delete_cell->higher->above = NULL;
-	    give(delete_cell);
-	    return 0;
-	}
-	if (delete_cell->above->lower == delete_cell) {	/* 11B */
-	    delete_cell->higher->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->higher;
-	    delete_cell->above->lower = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-	else {			/* 10B */
-	    delete_cell->higher->lower = delete_cell->lower;
-	    delete_cell->lower->above = delete_cell->higher;
-	    delete_cell->above->higher = delete_cell->higher;
-	    delete_cell->higher->above = delete_cell->above;
-	    give(delete_cell);
-	    return 0;
-	}
-    }
-    /* If we get this far, the node cannot be safely removed.  Just leave
-     * an internal mark noting that it is no longer good.
-     */
-    delete_cell->row = -1;
-    return 0;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int show_all(void)
-{
-    if (start_cell == NULL) {
-	G_message("Nothing to show\n");
-	return 1;
-    }
-    show(start_cell);
-
-    return 0;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int show(struct cost *next)
-{
-    struct cost *next_cell;
-
-    if (next == NULL)
-	return 0;
-    for (next_cell = next; next_cell != NULL; next_cell = next_cell->nexttie)
-	G_message("%p %d,%d,%f %p %p %p %p\n",
-		  next_cell,
-		  next_cell->row,
-		  next_cell->col,
-		  next_cell->min_cost,
-		  next_cell->nexttie,
-		  next_cell->lower, next_cell->higher, next_cell->above);
-    show(next->lower);
-    show(next->higher);
-
-    return 0;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int check_all(char *str)
-{
-    G_message("\n");
-    if (start_cell->above != NULL) {
-	G_fatal_error("Bad Start Cell\n");
-    }
-    check(str, start_cell);
-
-    return 0;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int check(char *str, struct cost *start)
-{
-    if (start == NULL)
-	return 0;
-
-    if (start->lower != NULL) {
-	if (start->min_cost < start->lower->min_cost) {
-	    G_warning("%s %f-%f lower cost higher or equal\n", str,
-		      start->min_cost, start->lower->min_cost);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-	if (start->lower->above != start) {
-	    G_warning("%s lower above pointer wrong\n", str);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-    }
-    if (start->higher != NULL) {
-	if (start->min_cost >= start->higher->min_cost) {
-	    G_warning("%s %f-%f higher cost lower\n", str,
-		      start->min_cost, start->higher->min_cost);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-	if (start->higher->above != start) {
-	    G_warning("%s higher above pointer wrong\n", str);
-	    show_all();
-	    exit(EXIT_FAILURE);
-	}
-    }
-    check(str, start->lower);
-    check(str, start->higher);
-
-    return 0;
-}

Modified: grass/trunk/raster/r.walk/cost.h
===================================================================
--- grass/trunk/raster/r.walk/cost.h	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/cost.h	2010-01-24 17:22:41 UTC (rev 40632)
@@ -7,33 +7,24 @@
 /*      point structure containing various attributes of       */
 /*      a grid cell.                                           */
 /*                                                             */
-
 /***************************************************************/
 
-#ifndef __R_COST_H__
-#define __R_COST_H__
+#ifndef __COST_H__
+#define __COST_H__
 
 struct cost
 {
     double min_cost;
+    long age;
     int row;
     int col;
-    struct cost *lower;
-    struct cost *higher;
-    struct cost *above;
-    struct cost *nexttie;
-    struct cost *previoustie;
 };
 
-/* btree.c */
+/* heap.c */
 struct cost *insert(double, int, int);
-struct cost *find(double, int, int);
 struct cost *get_lowest(void);
-int show(struct cost *);
-int show_all();
 int delete(struct cost *);
-int check(char *, struct cost *);
+int init_heap(void);
+int free_heap(void);
 
-#endif
-
-/***************************************************************/
+#endif /* __COST_H__ */

Added: grass/trunk/raster/r.walk/heap.c
===================================================================
--- grass/trunk/raster/r.walk/heap.c	                        (rev 0)
+++ grass/trunk/raster/r.walk/heap.c	2010-01-24 17:22:41 UTC (rev 40632)
@@ -0,0 +1,218 @@
+
+/****************************************************************************
+ *
+ * MODULE:       r.cost
+ *
+ * AUTHOR(S):    Antony Awaida - IESL - M.I.T.
+ *               James Westervelt - CERL
+ *               Pierre de Mouveaux <pmx audiovu com>
+ *               Eric G. Miller <egm2 jps net>
+ *
+ *               min heap by Markus Metz
+ *
+ * PURPOSE:      Outputs a raster map layer showing the cumulative cost
+ *               of moving between different geographic locations on an
+ *               input raster map layer whose cell category values
+ *               represent cost.
+ *
+ * COPYRIGHT:    (C) 2006-2009 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ ***************************************************************************/
+
+/* These routines manage the list of grid-cell candidates for 
+ * visiting to calculate distances to surrounding cells.
+ * A min-heap approach is used.  Components are
+ * sorted first by distance then by the order in which they were added.
+ *
+ * insert ()
+ *   inserts a new row-col with its distance value into the heap
+ *
+ * delete()
+ *   deletes a row-col entry in the heap
+ *
+ * get_lowest()
+ *   retrieves the entry with the smallest distance value
+ */
+
+
+#include <grass/gis.h>
+#include <stdlib.h>
+#include <grass/glocale.h>
+#include "cost.h"
+
+#define GET_PARENT(c) (((c) - 2) / 3 + 1)
+#define GET_CHILD(p) (((p) * 3) - 1)
+
+static long next_point = 0;
+static long heap_size = 0;
+static long heap_alloced = 0;
+static struct cost **heap_index, *free_point;
+
+int init_heap(void)
+{
+    next_point = 0;
+    heap_size = 0;
+    heap_alloced = 1000;
+    heap_index = (struct cost **) G_malloc(heap_alloced * sizeof(struct cost *));
+
+    free_point = NULL;
+    
+    return 0;
+}
+
+int free_heap(void)
+{
+    if (heap_alloced)
+	G_free(heap_index);
+
+    if (free_point)
+	G_free(free_point);
+
+    return 0;
+}
+
+/* compare two costs
+ * return 1 if a < b else 0 */
+int cmp_costs(struct cost *a, struct cost *b)
+{
+    if (a->min_cost < b->min_cost)
+	return 1;
+    else if (a->min_cost == b->min_cost) {
+	if (a->age < b->age)
+	    return 1;
+    }
+
+    return 0;
+}
+
+long sift_up(long start, struct cost * child_pnt)
+{
+    register long parent, child;
+    int r, c;
+
+    r = child_pnt->row;
+    c = child_pnt->col;
+    
+    child = start;
+
+    while (child > 1) {
+	parent = GET_PARENT(child);
+
+	/* child is smaller */
+	if (cmp_costs(child_pnt, heap_index[parent])) {
+	    /* push parent point down */
+	    heap_index[child] = heap_index[parent];
+	    child = parent;
+	}
+	else
+	    /* no more sifting up, found new slot for child */
+	    break;
+    }
+
+    /* put point in new slot */
+    if (child < start) {
+	heap_index[child] = child_pnt;
+    }
+
+    return child;
+}
+
+struct cost *insert(double min_cost, int row, int col)
+{
+    struct cost *new_cell;
+
+    if (free_point) {
+	new_cell = free_point;
+	free_point = NULL;
+    }
+    else
+	new_cell = (struct cost *)(G_malloc(sizeof(struct cost)));
+
+    new_cell->min_cost = min_cost;
+    new_cell->age = next_point;
+    new_cell->row = row;
+    new_cell->col = col;
+
+    next_point++;
+    heap_size++;
+    if (heap_size >= heap_alloced) {
+	heap_alloced += 1000;
+	heap_index = (struct cost **) G_realloc((void *)heap_index, heap_alloced * sizeof(struct cost *));
+    }
+
+    heap_index[heap_size] = new_cell;
+    sift_up(heap_size, new_cell);
+
+    return (new_cell);
+}
+
+struct cost *get_lowest(void)
+{
+    struct cost *next_cell;
+    register long parent, child, childr, i;
+
+    if (heap_size == 0)
+	return NULL;
+	
+    next_cell = heap_index[1];
+    heap_index[0] = next_cell;
+
+    if (heap_size == 1) {
+	heap_size--;
+
+	heap_index[1] = NULL;
+
+	return next_cell;
+    }
+
+    /* start with root */
+    parent = 1;
+
+    /* sift down: move hole back towards bottom of heap */
+
+    while ((child = GET_CHILD(parent)) <= heap_size) {
+	/* select smallest child */
+	if (child < heap_size) {
+	    childr = child + 1;
+	    i = child + 3;
+	    while (childr < i && childr <= heap_size) {
+		/* get smallest child */
+		if (cmp_costs(heap_index[childr], heap_index[child])) {
+		    child = childr;
+		}
+		childr++;
+	    }
+	}
+
+	/* move hole down */
+	heap_index[parent] = heap_index[child];
+	parent = child;
+    }
+
+    /* hole is in lowest layer, move to heap end */
+    if (parent < heap_size) {
+	heap_index[parent] = heap_index[heap_size];
+
+	/* sift up last swapped point, only necessary if hole moved to heap end */
+	sift_up(parent, heap_index[parent]);
+    }
+
+    /* the actual drop */
+    heap_size--;
+
+    return next_cell;
+}
+
+int delete(struct cost *delete_cell)
+{
+    if (free_point)
+	G_free(delete_cell);
+    else
+	free_point = delete_cell;
+
+    return 0;
+}

Deleted: grass/trunk/raster/r.walk/local_proto.h
===================================================================
--- grass/trunk/raster/r.walk/local_proto.h	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/local_proto.h	2010-01-24 17:22:41 UTC (rev 40632)
@@ -1,6 +0,0 @@
-/* btree.c */
-int show_all(void);
-
-/* int check_all(char *); */
-/* main.c */
-/* int time_to_stop(int, int); */

Modified: grass/trunk/raster/r.walk/main.c
===================================================================
--- grass/trunk/raster/r.walk/main.c	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/main.c	2010-01-24 17:22:41 UTC (rev 40632)
@@ -27,6 +27,8 @@
  *                 Glynn Clements <glynn gclements.plus.com>, Soeren Gebbert <soeren.gebbert gmx.de>
  *               Updated for calculation errors and directional surface generation
  *                 Colin Nielsen <colin.nielsen gmail com>
+ *               Updated for GRASS 7
+ *                 Markus Metz
  * PURPOSE:      anisotropic movements on cost surfaces
  * COPYRIGHT:    (C) 1999-2006 by the GRASS Development Team
  *
@@ -103,78 +105,67 @@
 #include <grass/raster.h>
 #include <grass/site.h>
 #include <grass/segment.h>
+#include <grass/glocale.h>
 #include "cost.h"
 #include "stash.h"
-#include "local_proto.h"
-#include <grass/glocale.h>
 
-struct variables
-{
-    char *alias;
-    int position;
-} variables[] = {
-    {"output", CUM_COST_LAYER},
-    {"input", COST_LAYER},
-    {"coor", START_PT},
-    {"outdir", MOVE_DIR_LAYER}
-};
+#define SEGCOLSIZE 	64
 
+struct Cell_head window;
+
 struct start_pt *head_start_pt = NULL;
 struct start_pt *head_end_pt = NULL;
 
-struct Cell_head window;
-
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
 int main(int argc, char *argv[])
 {
     const char *cum_cost_layer, *move_dir_layer;
-    const char *start_layer, *cost_layer, *dtm_layer;
+    const char *cost_layer, *dtm_layer;
+    const char *dtm_mapset, *cost_mapset, *search_mapset;
     void *dtm_cell, *cost_cell, *cum_cell, *dir_cell, *cell2 = NULL;
-    SEGMENT dtm_in_seg, cost_in_seg, out_seg, out_seg2;
-    char *dtm_in_file, *cost_in_file, *out_file, *dir_out_file;
-    double *dtm_value, *cost_value, *value_start_pt;
+    SEGMENT cost_seg, dir_seg;
+    const char *in_file, *dir_out_file;
+    double *value;
     char buf[400];
     extern struct Cell_head window;
     double NS_fac, EW_fac, DIAG_fac, H_DIAG_fac, V_DIAG_fac;
     double fcost_dtm, fcost_cost;
     double min_cost, old_min_cost;
-    double cur_dir, old_cur_dir;
+    double cur_dir;
     double zero = 0.0;
     int at_percent = 0;
     int col = 0, row = 0, nrows = 0, ncols = 0;
     int maxcost, par_number;
-    int maxmem;
     int nseg;
+    int maxmem;
+    int segments_in_memory;
     int cost_fd, cum_fd, dtm_fd, dir_fd;
-    int have_start_points, dir = 0;
-    int have_stop_points;
-    int dtm_in_fd, cost_in_fd, out_fd, dir_out_fd;
-    double my_dtm, my_cost;
-    double null_cost;
+    int have_stop_points = 0, dir = 0;
+    int in_fd, dir_out_fd;
+    double my_dtm, my_cost, check_dtm;
+    double null_cost, dnullval;
     double a, b, c, d, lambda, slope_factor;
     int srows, scols;
     int total_reviewed;
     int keep_nulls = 1;
     int start_with_raster_vals = 1;
     int neighbor;
-    int segments_in_memory;
     long n_processed = 0;
     long total_cells;
     struct GModule *module;
-    struct Flag *flag2, *flag3, *flag4;
+    struct Flag *flag2, *flag3, *flag4, *flag5;
     struct Option *opt1, *opt2, *opt3, *opt4, *opt5, *opt6, *opt7, *opt8;
-    struct Option *opt9, *opt10, *opt11, *opt12, *opt13, *opt14, *opt15,*opt16;
+    struct Option *opt9, *opt10, *opt11, *opt12, *opt13, *opt14, *opt15;
     struct cost *pres_cell, *new_cell;
-    struct History history;
     struct start_pt *pres_start_pt = NULL;
     struct start_pt *pres_stop_pt = NULL;
+    struct cc {
+	double cost_in, cost_out, dtm;
+    } costs;
 
-    void *ptr2;
-    RASTER_MAP_TYPE dtm_data_type, data_type2, cost_data_type, cum_data_type =
-	DCELL_TYPE, dir_data_type = DCELL_TYPE, cat;
+    void *ptr1, *ptr2;
+    RASTER_MAP_TYPE dtm_data_type, cost_data_type, cum_data_type =
+	DCELL_TYPE, dir_data_type = DCELL_TYPE;
+    struct History history;
     double peak = 0.0;
     int dtm_dsize, cost_dsize;
 
@@ -185,6 +176,8 @@
 
     module = G_define_module();
     G_add_keyword(_("raster"));
+    G_add_keyword(_("cost surface"));
+    G_add_keyword(_("cumulative costs"));
     module->description =
 	_("Outputs a raster map layer showing the "
 	  "anisotropic cumulative cost of moving between different "
@@ -193,44 +186,30 @@
 	  "combined with an input raster map layer whose cell "
 	  "values represent friction cost.");
 
-    opt2 = G_define_option();
-    opt2->key = "elevation";
-    opt2->type = TYPE_STRING;
-    opt2->required = YES;
-    opt2->gisprompt = "old,cell,raster";
-    opt2->description = _("Name of elevation input raster map");
-
-    opt12 = G_define_option();
-    opt12->key = "friction";
-    opt12->type = TYPE_STRING;
+    opt12 = G_define_standard_option(G_OPT_R_INPUT);
+    opt12->key = "elevation";
     opt12->required = YES;
-    opt12->gisprompt = "old,cell,raster";
-    opt12->description =
+    opt12->description = _("Name of elevation input raster map");
+
+    opt2 = G_define_standard_option(G_OPT_R_INPUT);
+    opt2->key = "friction";
+    opt2->required = YES;
+    opt2->description =
 	_("Name of input raster map containing friction costs");
 
-    opt1 = G_define_option();
-    opt1->key = "output";
-    opt1->type = TYPE_STRING;
+    opt1 = G_define_standard_option(G_OPT_R_OUTPUT);
     opt1->required = YES;
-    opt1->gisprompt = "new,cell,raster";
-    opt1->description = _("Name of raster map to contain results");
+    opt1->label = _("output map with walking costs");
+    opt1->description = _("Name of output raster map to contain walking costs");
 
-    opt15 = G_define_option();
-    opt15->key = "outdir";
-    opt15->type = TYPE_STRING;
-    opt15->required = NO;
-    opt15->gisprompt = "new,cell,raster";
-    opt15->description =
+    opt11 = G_define_option();
+    opt11->key = "outdir";
+    opt11->type = TYPE_STRING;
+    opt11->required = NO;
+    opt11->gisprompt = "new,cell,raster";
+    opt11->description =
 	_("Name of output raster map to contain movement directions");
 
-    opt16 = G_define_option();
-    opt16->key = "start_map";
-    opt16->type = TYPE_STRING;
-    opt16->required = NO;
-    opt16->gisprompt = "old,cell,raster";
-    opt16->description =
-	_("Name of input raster map containing starting points");
-
     opt7 = G_define_option();
     opt7->key = "start_points";
     opt7->type = TYPE_STRING;
@@ -245,6 +224,14 @@
     opt8->required = NO;
     opt8->description = _("Stop points vector map");
 
+    opt9 = G_define_option();
+    opt9->key = "start_rast";
+    opt9->type = TYPE_STRING;
+    opt9->required = NO;
+    opt9->gisprompt = "old,cell,raster";
+    opt9->description =
+	_("Starting points raster map");
+
     opt3 = G_define_option();
     opt3->key = "coordinate";
     opt3->type = TYPE_STRING;
@@ -277,40 +264,31 @@
     opt6->description =
 	_("Cost assigned to null cells. By default, null cells are excluded");
 
-    opt9 = G_define_option();
-    opt9->key = "percent_memory";
-    opt9->type = TYPE_INTEGER;
-    opt9->required = NO;
-    opt9->multiple = NO;
-    opt9->answer = "100";
-    opt9->description = _("Percent of map to keep in memory");
-
-    opt14 = G_define_option();
-    opt14->key = "nseg";
-    opt14->type = TYPE_INTEGER;
-    opt14->required = NO;
-    opt14->multiple = NO;
-    opt14->answer = "4";
-    opt14->description =
-	_("Number of the segment to create (segment library)");
-
     opt10 = G_define_option();
-    opt10->key = "walk_coeff";
-    opt10->type = TYPE_DOUBLE;
-    opt10->key_desc = "a,b,c,d";
+    opt10->key = "percent_memory";
+    opt10->type = TYPE_INTEGER;
     opt10->required = NO;
     opt10->multiple = NO;
-    opt10->answer = "0.72,6.0,1.9998,-1.9998";
-    opt10->description =
+    opt10->answer = "100";
+    opt10->description = _("Percent of map to keep in memory");
+
+    opt15 = G_define_option();
+    opt15->key = "walk_coeff";
+    opt15->type = TYPE_DOUBLE;
+    opt15->key_desc = "a,b,c,d";
+    opt15->required = NO;
+    opt15->multiple = NO;
+    opt15->answer = "0.72,6.0,1.9998,-1.9998";
+    opt15->description =
 	_("Coefficients for walking energy formula parameters a,b,c,d");
 
-    opt11 = G_define_option();
-    opt11->key = "lambda";
-    opt11->type = TYPE_DOUBLE;
-    opt11->required = NO;
-    opt11->multiple = NO;
-    opt11->answer = "1.0";
-    opt11->description =
+    opt14 = G_define_option();
+    opt14->key = "lambda";
+    opt14->type = TYPE_DOUBLE;
+    opt14->required = NO;
+    opt14->multiple = NO;
+    opt14->answer = "1.0";
+    opt14->description =
 	_("Lambda coefficients for combining walking energy and friction cost");
 
     opt13 = G_define_option();
@@ -335,31 +313,29 @@
     flag4->key = 'r';
     flag4->description = _("Start with values in raster map");
 
-    /*   Parse command line */
+    flag5 = G_define_flag();
+    flag5->key = 'i';
+    flag5->description = _("Only print info about disk space and memory requirements");
+
+    /* Parse options */
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
     /* If no outdir is specified, set flag to skip all dir */
-    if (opt15->answer != NULL)
+    if (opt11->answer != NULL)
 	dir = 1;
 
     /* Initalize access to database and create temporary files */
-
-    dtm_in_file = G_tempfile();
-    cost_in_file = G_tempfile();
-    out_file = G_tempfile();
+    in_file = G_tempfile();
     if (dir == 1)
 	dir_out_file = G_tempfile();
 
-    /*  Get database window parameters      */
-
+    /* Get database window parameters */
     G_get_window(&window);
 
-    /*  Find north-south, east_west and diagonal factors */
-
+    /* Find north-south, east_west and diagonal factors */
     EW_fac = window.ew_res;	/* Must be the physical distance */
     NS_fac = window.ns_res;
-
     DIAG_fac = (double)sqrt((double)(NS_fac * NS_fac + EW_fac * EW_fac));
     V_DIAG_fac =
 	(double)sqrt((double)(4 * NS_fac * NS_fac + EW_fac * EW_fac));
@@ -375,38 +351,55 @@
 
     keep_nulls = flag3->answer;
 
-    have_start_points =
-	process_answers(opt3->answers, &head_start_pt, &pres_start_pt);
+    start_with_raster_vals = flag4->answer;
 
-    have_stop_points =
-	process_answers(opt4->answers, &head_end_pt, &pres_stop_pt);
+    {
+	int count = 0;
 
+	if (opt3->answers)
+	    count++;
+	if (opt7->answers)
+	    count++;
+	if (opt9->answers)
+	    count++;
+
+	if (count != 1)
+	    G_fatal_error(_("Must specify exactly one of start_points, start_rast or coordinate"));
+    }
+
+    if (opt3->answers)
+	if (!process_answers(opt3->answers, &head_start_pt, &pres_start_pt))
+	    G_fatal_error(_("No start points"));
+
+    if (opt4->answers)
+	have_stop_points =
+	    process_answers(opt4->answers, &head_end_pt, &pres_stop_pt);
+
     if (sscanf(opt5->answer, "%d", &maxcost) != 1 || maxcost < 0)
 	G_fatal_error(_("Inappropriate maximum cost: %d"), maxcost);
 
-    if (sscanf(opt9->answer, "%d", &maxmem) != 1 || maxmem < 0 ||
+    if (sscanf(opt10->answer, "%d", &maxmem) != 1 || maxmem < 0 ||
 	maxmem > 100)
 	G_fatal_error(_("Inappropriate percent memory: %d"), maxmem);
 
     /* Getting walking energy formula parameters */
     if ((par_number =
-	 sscanf(opt10->answer, "%lf,%lf,%lf,%lf", &a, &b, &c, &d)) != 4)
+	 sscanf(opt15->answer, "%lf,%lf,%lf,%lf", &a, &b, &c, &d)) != 4)
 	G_fatal_error(_("Missing required value: got %d instead of 4"),
 		      par_number);
     else {
-
 	G_message(_("Walking costs are a=%lf b=%lf c=%lf d=%lf"), a, b, c, d);
     }
 
-    /* Getting  lambda */
-    if ((par_number = sscanf(opt11->answer, "%lf", &lambda)) != 1)
+    /* Getting lambda */
+    if ((par_number = sscanf(opt14->answer, "%lf", &lambda)) != 1)
 	G_fatal_error(_("Missing required value: %d"), par_number);
     else {
 
 	G_message(_("Lambda is %lf"), lambda);
     }
 
-    /*Getting  slope_factor */
+    /* Getting slope_factor */
     if ((par_number = sscanf(opt13->answer, "%lf", &slope_factor)) != 1)
 	G_fatal_error(_("Missing required value: %d"), par_number);
     else {
@@ -414,107 +407,20 @@
 	G_message(_("Slope_factor is %lf"), slope_factor);
     }
 
-    if ((par_number = sscanf(opt14->answer, "%d", &nseg)) != 1)
-	G_fatal_error(_("Missing required value: %d"), par_number);
-    else {
-
-	G_message(_("Nseg is %d"), nseg);
-    }
-
     if ((opt6->answer == NULL) ||
 	(sscanf(opt6->answer, "%lf", &null_cost) != 1)) {
-
-	G_message(_("Null cells excluded from cost evaluation."));
+	G_debug(1, "Null cells excluded from cost evaluation");
 	Rast_set_d_null_value(&null_cost, 1);
     }
     else if (keep_nulls)
-	G_message(_("Input null cell will be retained into output map"));
+	G_debug(1,"Input null cell will be retained into output map");
 
-
     if (opt7->answer) {
-	struct Map_info *fp;
-	struct start_pt *new_start_pt;
-	Site *site = NULL;	/* pointer to Site */
-	int dims, strs, dbls;
-
-	fp = G_fopen_sites_old(opt7->answer, "");
-
-	if (G_site_describe(fp, &dims, &cat, &strs, &dbls))
-	    G_fatal_error("Failed to guess site file format");
-	site = G_site_new_struct(cat, dims, strs, dbls);
-
-	for (; (G_site_get(fp, site) != EOF);) {
-	    if (!G_site_in_region(site, &window))
-		continue;
-	    have_start_points = 1;
-
-	    col = (int)G_easting_to_col(site->east, &window);
-	    row = (int)G_northing_to_row(site->north, &window);
-
-	    new_start_pt =
-		(struct start_pt *)(G_malloc(sizeof(struct start_pt)));
-
-	    new_start_pt->row = row;
-	    new_start_pt->col = col;
-	    new_start_pt->next = NULL;
-
-	    if (head_start_pt == NULL) {
-		head_start_pt = new_start_pt;
-		pres_start_pt = new_start_pt;
-		new_start_pt->next = NULL;
-	    }
-	    else {
-		pres_start_pt->next = new_start_pt;
-		pres_start_pt = new_start_pt;
-	    }
-	}
-
-	G_site_free_struct(site);
-	G_sites_close(fp);
+	search_mapset = G_find_vector2(opt7->answer, "");
+	if (search_mapset == NULL)
+	    G_fatal_error(_("Vector map <%s> not found"), opt7->answer);
     }
 
-    if (opt8->answer) {
-	struct Map_info *fp;
-	struct start_pt *new_start_pt;
-	Site *site = NULL;	/* pointer to Site */
-	int dims, strs, dbls;
-
-	fp = G_fopen_sites_old(opt8->answer, "");
-
-	if (G_site_describe(fp, &dims, &cat, &strs, &dbls))
-	    G_fatal_error("Failed to guess site file format\n");
-	site = G_site_new_struct(cat, dims, strs, dbls);
-
-	for (; (G_site_get(fp, site) != EOF);) {
-	    if (!G_site_in_region(site, &window))
-		continue;
-	    have_stop_points = 1;
-
-	    col = (int)G_easting_to_col(site->east, &window);
-	    row = (int)G_northing_to_row(site->north, &window);
-
-	    new_start_pt =
-		(struct start_pt *)(G_malloc(sizeof(struct start_pt)));
-
-	    new_start_pt->row = row;
-	    new_start_pt->col = col;
-	    new_start_pt->next = NULL;
-
-	    if (head_end_pt == NULL) {
-		head_end_pt = new_start_pt;
-		pres_stop_pt = new_start_pt;
-		new_start_pt->next = NULL;
-	    }
-	    else {
-		pres_stop_pt->next = new_start_pt;
-		pres_stop_pt = new_start_pt;
-	    }
-	}
-
-	G_site_free_struct(site);
-	G_sites_close(fp);
-    }
-
     if (!Rast_is_d_null_value(&null_cost)) {
 	if (null_cost < 0.0) {
 	    G_warning(_("Warning: assigning negative cost to null cell. Null cells excluded."));
@@ -525,67 +431,58 @@
 	keep_nulls = 0;		/* handled automagically... */
     }
 
-    start_layer = opt16->answer;
-    dtm_layer = opt2->answer;
-    cost_layer = opt12->answer;
+    dtm_layer = opt12->answer;
+    cost_layer = opt2->answer;
     cum_cost_layer = opt1->answer;
-    if (dir == 1)
-	move_dir_layer = opt15->answer;
+    move_dir_layer = opt11->answer;
 
-    /*  Find number of rows and columns in window    */
-
+    /* Find number of rows and columns in window */
     nrows = G_window_rows();
     ncols = G_window_cols();
 
-
-    /*  Open cost cell layer for reading  */
-
+    /* Open cost cell layer for reading */
+    dtm_mapset = G_find_raster2(dtm_layer, "");
+    if (dtm_mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), dtm_layer);
     dtm_fd = Rast_open_old(dtm_layer, "");
-    cost_fd = Rast_open_old(cost_layer, "");
 
+    cost_mapset = G_find_raster2(cost_layer, "");
+    if (cost_mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), cost_layer);
+    cost_fd = Rast_open_old(cost_layer, cost_mapset);
+
     Rast_get_cellhd(dtm_layer, "", &dtm_cellhd);
     Rast_get_cellhd(cost_layer, "", &cost_cellhd);
 
-    /*Projection */
-
-    if (dtm_cellhd.proj != cost_cellhd.proj)
-	G_fatal_error(_("Map with different projection"));
-
     dtm_data_type = Rast_get_map_type(dtm_fd);
     cost_data_type = Rast_get_map_type(cost_fd);
-    dtm_cell = Rast_allocate_buf(dtm_data_type);
-    cost_cell = Rast_allocate_buf(cost_data_type);
 
-    /*   Parameters for map submatrices   */
-
-
+    /* Parameters for map submatrices */
     switch (dtm_data_type) {
     case (CELL_TYPE):
-	G_message(_("DTM_Source map is: Integer cell type"));
+	G_debug(1, "DTM_Source map is: Integer cell type");
 	break;
     case (FCELL_TYPE):
-	G_message(_("DTM_Source map is: Floating point (float) cell type"));
+	G_debug(1, "DTM_Source map is: Floating point (float) cell type");
 	break;
     case (DCELL_TYPE):
-	G_message(_("DTM_Source map is: Floating point (double) cell type"));
+	G_debug(1, "DTM_Source map is: Floating point (double) cell type");
 	break;
     }
-    G_message(_(" %d rows, %d cols"), dtm_cellhd.rows, dtm_cellhd.cols);
+    G_debug(1, "DTM %d rows, %d cols", dtm_cellhd.rows, dtm_cellhd.cols);
 
-
-
     switch (cost_data_type) {
     case (CELL_TYPE):
-	G_message(_("COST_Source map is: Integer cell type"));
+	G_debug(1, "COST_Source map is: Integer cell type");
 	break;
     case (FCELL_TYPE):
-	G_message(_("COST_Source map is: Floating point (float) cell type"));
+	G_debug(1, "COST_Source map is: Floating point (float) cell type");
 	break;
     case (DCELL_TYPE):
-	G_message(_("COST_Source map is: Floating point (double) cell type"));
+	G_debug(1, "COST_Source map is: Floating point (double) cell type");
 	break;
     }
-    G_message(_(" %d rows, %d cols"), cost_cellhd.rows, cost_cellhd.cols);
+    G_debug(1, "COST %d rows, %d cols", cost_cellhd.rows, cost_cellhd.cols);
 
     if (cost_data_type != dtm_data_type) {
 	switch (cost_data_type) {
@@ -610,336 +507,394 @@
 	/* Data type are equal, it doesn't matter */
 	cum_data_type = dtm_data_type;
 
-
     switch (cum_data_type) {
     case (CELL_TYPE):
-	G_message(_("Output map is: Integer cell type"));
+	G_debug(1, "Output map is: Integer cell type");
 	break;
     case (FCELL_TYPE):
-	G_message(_("Output map is: Floating point (float) cell type"));
+	G_debug(1, "Output map is: Floating point (float) cell type");
 	break;
     case (DCELL_TYPE):
-	G_message(_("Output map is: Floating point (double) cell type"));
+	G_debug(1, "Output map is: Floating point (double) cell type");
 	break;
     }
-    G_message(_(" %d rows, %d cols"), nrows, ncols);
+    G_debug(1, " %d rows, %d cols", nrows, ncols);
     G_format_resolution(window.ew_res, buf, window.proj);
-    G_message(_(" EW resolution %s (%lf)"), buf, window.ew_res);
+    G_debug(1, " EW resolution %s (%lf)", buf, window.ew_res);
     G_format_resolution(window.ns_res, buf, window.proj);
-    G_message(_(" NS resolution %s (%lf)"), buf, window.ns_res);
+    G_debug(1, " NS resolution %s (%lf)", buf, window.ns_res);
 
+    /* this is most probably the limitation of r.walk for large datasets
+     * segment size needs to be reduced to avoid unecessary disk IO
+     * but it doesn't make sense to go down to 1
+     * so use 64 segment rows and cols for <= 200 million cells
+     * for larger regions, 32 segment rows and cols
+     * maybe go down to 16 for > 500 million cells ? */
+    if ((double) nrows * ncols > 200000000)
+	srows = scols = SEGCOLSIZE / 2;
+    else
+	srows = scols = SEGCOLSIZE;
 
-    srows = nrows / nseg + 1;
-    scols = ncols / nseg + 1;
+    if (maxmem == 100) {
+	srows = scols = 256;
+    }
+
+    /* calculate total number of segments */
+    nseg = ((nrows + srows - 1) / srows) * ((ncols + scols - 1) / scols);
     if (maxmem > 0)
-	segments_in_memory =
-	    2 + maxmem * (nrows / srows) * (ncols / scols) / 100;
+	segments_in_memory = (maxmem * nseg) / 100;
+    /* maxmem = 0 */
     else
 	segments_in_memory = 4 * (nrows / srows + ncols / scols + 2);
 
-    /*   Create segmented format files for cost layer and output layer  */
+    if (segments_in_memory == 0)
+	segments_in_memory = 1;
 
+    /* report disk space and memory requirements */
+    G_message("--------------------------------------------");
+    if (dir == 1) {
+	double disk_mb, mem_mb;
 
-    G_message(_("Creating some temporary files..."));
+	disk_mb = (double) nrows * ncols * 32. / 1048576.;
+	mem_mb  = (double) srows * scols * 32. / 1048576. * segments_in_memory;
+	mem_mb += nrows * ncols * 0.05 * 20. / 1048576.;    /* for Dijkstra search */
+	G_message(_("Will need at least %.2f MB of disk space"), disk_mb);
+	G_message(_("Will need at least %.2f MB of memory"), mem_mb);
+	
+    }
+    else {
+	double disk_mb, mem_mb;
 
-    dtm_in_fd = creat(dtm_in_file, 0600);
-    segment_format(dtm_in_fd, nrows, ncols, srows, scols, sizeof(double));
-    close(dtm_in_fd);
+	disk_mb = (double) nrows * ncols * 24. / 1048576.;
+	mem_mb  = (double) srows * scols * 24. / 1048576. * segments_in_memory;
+	mem_mb += nrows * ncols * 0.05 * 20. / 1048576.;    /* for Dijkstra search */
+	G_message(_("Will need at least %.2f MB of disk space"), disk_mb);
+	G_message(_("Will need at least %.2f MB of memory"), mem_mb);
+    }
+    G_message("--------------------------------------------");
 
-    cost_in_fd = creat(cost_in_file, 0600);
-    segment_format(cost_in_fd, nrows, ncols, srows, scols, sizeof(double));
-    close(cost_in_fd);
+    if (flag5->answer) {
+	Rast_close(cost_fd);
+	Rast_close(dtm_fd);
+	exit(EXIT_SUCCESS);
+    }
 
-    out_fd = creat(out_file, 0600);
-    segment_format(out_fd, nrows, ncols, srows, scols, sizeof(double));
-    close(out_fd);
+    /* Create segmented format file for cost layer and output layer */
+    G_verbose_message(_("Creating some temporary files..."));
 
+    in_fd = creat(in_file, 0600);
+    if (segment_format(in_fd, nrows, ncols, srows, scols, sizeof(struct cc)) != 1)
+    	G_fatal_error("can not create temporary file");
+
+    close(in_fd);
+
     if (dir == 1) {
 	dir_out_fd = creat(dir_out_file, 0600);
-	segment_format(dir_out_fd, nrows, ncols, srows, scols,
-		       sizeof(double));
+	if (segment_format(dir_out_fd, nrows, ncols, srows, scols,
+		       sizeof(double)) != 1)
+	    G_fatal_error("can not create temporary file");
 	close(dir_out_fd);
     }
-    /*   Open initialize and segment all files  */
+    
+    /* Open and initialize all segment files */
+    in_fd = open(in_file, 2);
+    if (segment_init(&cost_seg, in_fd, segments_in_memory) != 1)
+    	G_fatal_error("can not initialize temporary file");
 
-    dtm_in_fd = open(dtm_in_file, 2);
-    segment_init(&dtm_in_seg, dtm_in_fd, segments_in_memory);
-
-    cost_in_fd = open(cost_in_file, 2);
-    segment_init(&cost_in_seg, cost_in_fd, segments_in_memory);
-
-    out_fd = open(out_file, 2);
-    segment_init(&out_seg, out_fd, segments_in_memory);
-
     if (dir == 1) {
 	dir_out_fd = open(dir_out_file, 2);
-	segment_init(&out_seg2, dir_out_fd, segments_in_memory);
+	if (segment_init(&dir_seg, dir_out_fd, segments_in_memory) != 1)
+	    G_fatal_error("can not initialize temporary file");
     }
 
-    /*   Write the cost layer in the segmented file  */
+    /* Write the dtm and cost layers in the segmented file */
+    G_message(_("Reading raster maps <%s> and <%s>, initializing output..."),
+	      G_fully_qualified_name(dtm_layer, dtm_mapset),
+	      G_fully_qualified_name(cost_layer, cost_mapset));
 
+    /* read required maps cost and dtm */
+    {
+	int i, skip_nulls;
+	double p_dtm, p_cost;
 
-    G_message(_("Reading %s..."), dtm_layer);
+	Rast_set_d_null_value(&dnullval, 1);
+	costs.cost_out = dnullval;
 
-    start_with_raster_vals = flag4->answer;
+	total_cells = nrows * ncols;
 
-    {
-	int i;
-	double p;
+	skip_nulls = Rast_is_d_null_value(&null_cost);
 
 	dtm_dsize = Rast_cell_size(dtm_data_type);
-	p = 0.0;
+	cost_dsize = Rast_cell_size(cost_data_type);
+	dtm_cell = Rast_allocate_buf(dtm_data_type);
+	cost_cell = Rast_allocate_buf(cost_data_type);
+	p_dtm = 0.0;
+	p_cost = 0.0;
 
 	for (row = 0; row < nrows; row++) {
-
 	    G_percent(row, nrows, 2);
 	    Rast_get_row(dtm_fd, dtm_cell, row, dtm_data_type);
+	    Rast_get_row(cost_fd, cost_cell, row, cost_data_type);
 	    /* INPUT NULL VALUES: ??? */
+	    ptr1 = cost_cell;
 	    ptr2 = dtm_cell;
-	    switch (dtm_data_type) {
-	    case CELL_TYPE:
-		for (i = 0; i < ncols; i++) {
-		    if (Rast_is_null_value(ptr2, dtm_data_type)) {
-			p = null_cost;
+
+	    for (i = 0; i < ncols; i++) {
+		if (Rast_is_null_value(ptr1, cost_data_type)) {
+		    p_cost = null_cost;
+		    if (skip_nulls) {
+			total_cells--;
 		    }
-		    else {
-			p = *(int *)ptr2;
+		}
+		else {
+		    switch (cost_data_type) {
+		    case CELL_TYPE:
+			p_cost = *(CELL *)ptr1;
+			break;
+		    case FCELL_TYPE:
+			p_cost = *(FCELL *)ptr1;
+			break;
+		    case DCELL_TYPE:
+			p_cost = *(DCELL *)ptr1;
+			break;
 		    }
-		    segment_put(&dtm_in_seg, &p, row, i);
-		    ptr2 = G_incr_void_ptr(ptr2, dtm_dsize);
 		}
-		break;
-	    case FCELL_TYPE:
-		for (i = 0; i < ncols; i++) {
-		    if (Rast_is_null_value(ptr2, dtm_data_type)) {
-			p = null_cost;
+		costs.cost_in = p_cost;
+		
+		if (Rast_is_null_value(ptr2, dtm_data_type)) {
+		    p_dtm = null_cost;
+		    if (skip_nulls && !Rast_is_null_value(ptr1, cost_data_type)) {
+			total_cells--;
 		    }
-		    else {
-			p = *(float *)ptr2;
-		    }
-		    segment_put(&dtm_in_seg, &p, row, i);
-		    ptr2 = G_incr_void_ptr(ptr2, dtm_dsize);
 		}
-		break;
-
-	    case DCELL_TYPE:
-		for (i = 0; i < ncols; i++) {
-		    if (Rast_is_null_value(ptr2, dtm_data_type)) {
-			p = null_cost;
+		else {
+		    switch (dtm_data_type) {
+		    case CELL_TYPE:
+			p_dtm = *(CELL *)ptr2;
+			break;
+		    case FCELL_TYPE:
+			p_dtm = *(FCELL *)ptr2;
+			break;
+		    case DCELL_TYPE:
+			p_dtm = *(DCELL *)ptr2;
+			break;
 		    }
-		    else {
-			p = *(double *)ptr2;
-		    }
-		    segment_put(&dtm_in_seg, &p, row, i);
-		    ptr2 = G_incr_void_ptr(ptr2, dtm_dsize);
 		}
-		break;
+
+		costs.dtm = p_dtm;
+		segment_put(&cost_seg, &costs, row, i);
+		ptr1 = G_incr_void_ptr(ptr1, cost_dsize);
+		ptr2 = G_incr_void_ptr(ptr2, dtm_dsize);
 	    }
 	}
+	G_free(dtm_cell);
+	G_free(cost_cell);
+	G_percent(1, 1, 1);
     }
 
-
-    G_message(_("Reading %s..."), cost_layer);
-
-    {
+    if (dir == 1) {
 	int i;
-	double p;
 
-	cost_dsize = Rast_cell_size(cost_data_type);
-	p = 0.0;
+	G_message(_("Initializing directional output "));
 	for (row = 0; row < nrows; row++) {
-
 	    G_percent(row, nrows, 2);
-	    Rast_get_row(cost_fd, cost_cell, row, cost_data_type);
-	    /* INPUT NULL VALUES: ??? */
-	    ptr2 = cost_cell;
-	    switch (cost_data_type) {
-	    case CELL_TYPE:
-		for (i = 0; i < ncols; i++) {
-		    if (Rast_is_null_value(ptr2, cost_data_type)) {
-			p = null_cost;
-		    }
-		    else {
-			p = *(int *)ptr2;
-		    }
-		    segment_put(&cost_in_seg, &p, row, i);
-		    ptr2 = G_incr_void_ptr(ptr2, cost_dsize);
-		}
-		break;
-	    case FCELL_TYPE:
-		for (i = 0; i < ncols; i++) {
-		    if (Rast_is_null_value(ptr2, cost_data_type)) {
-			p = null_cost;
-		    }
-		    else {
-			p = *(float *)ptr2;
-		    }
-		    segment_put(&cost_in_seg, &p, row, i);
-		    ptr2 = G_incr_void_ptr(ptr2, cost_dsize);
-		}
-		break;
-
-	    case DCELL_TYPE:
-		for (i = 0; i < ncols; i++) {
-		    if (Rast_is_null_value(ptr2, cost_data_type)) {
-			p = null_cost;
-		    }
-		    else {
-			p = *(double *)ptr2;
-		    }
-		    segment_put(&cost_in_seg, &p, row, i);
-		    ptr2 = G_incr_void_ptr(ptr2, cost_dsize);
-		}
-		break;
+	    for (i = 0; i < ncols; i++) {
+		segment_put(&dir_seg, &dnullval, row, i);
 	    }
 	}
+	G_percent(1, 1, 1);
     }
 
-    segment_flush(&dtm_in_seg);
-    segment_flush(&cost_in_seg);
+    /*   Scan the existing cum_cost_layer searching for starting points.
+     *   Create a heap of starting points ordered by increasing costs.
+     */
+    init_heap();
 
+    /* read vector with start points */
+    if (opt7->answer) {
+	struct Map_info *fp;
+	struct start_pt *new_start_pt;
+	Site *site = NULL;	/* pointer to Site */
+	int got_one = 0;
+	int dims, strs, dbls;
+	RASTER_MAP_TYPE cat;
 
-    G_percent(row, nrows, 2);
+	fp = G_fopen_sites_old(opt7->answer, "");
 
-    /* Initialize output map with NULL VALUES */
+	if (G_site_describe(fp, &dims, &cat, &strs, &dbls))
+	    G_fatal_error(_("Failed to guess site file format"));
+	site = G_site_new_struct(cat, dims, strs, dbls);
 
-    /*   Initialize segmented output file  */
+	for (; (G_site_get(fp, site) != EOF);) {
+	    if (!G_site_in_region(site, &window))
+		continue;
+	    got_one = 1;
 
-    G_message(_("Initializing output "));
-    {
-	double *fbuff;
-	int i;
+	    col = (int)G_easting_to_col(site->east, &window);
+	    row = (int)G_northing_to_row(site->north, &window);
 
-	fbuff = (double *)G_malloc((unsigned int)(ncols * sizeof(double)));
+	    new_start_pt =
+		(struct start_pt *)(G_malloc(sizeof(struct start_pt)));
 
-	if (fbuff == NULL)
-	    G_fatal_error(_("Unable to allocate memory for segment fbuff == NULL"));
+	    new_start_pt->row = row;
+	    new_start_pt->col = col;
+	    new_start_pt->next = NULL;
 
-	Rast_set_d_null_value(fbuff, ncols);
-
-	for (row = 0; row < nrows; row++) {
-	    {
-		G_percent(row, nrows, 2);
+	    if (head_start_pt == NULL) {
+		head_start_pt = new_start_pt;
+		pres_start_pt = new_start_pt;
+		new_start_pt->next = NULL;
 	    }
-	    for (i = 0; i < ncols; i++) {
-		segment_put(&out_seg, &fbuff[i], row, i);
+	    else {
+		pres_start_pt->next = new_start_pt;
+		pres_start_pt = new_start_pt;
 	    }
-
 	}
-	segment_flush(&out_seg);
 
-	G_percent(row, nrows, 2);
-	G_free(fbuff);
+	G_site_free_struct(site);
+	G_sites_close(fp);
+
+	if (!got_one)
+	    G_fatal_error(_("No start points found in vector <%s>"), opt7->answer);
     }
-    if (dir == 1) {
-	G_message(_("Initializing directional output "));
-	{
-	    double *fbuff;
-	    int i;
 
-	    fbuff =
-		(double *)G_malloc((unsigned int)(ncols * sizeof(double)));
+    /* read vector with stop points */
+    if (opt8->answer) {
+	struct Map_info *fp;
+	struct start_pt *new_start_pt;
+	Site *site = NULL;	/* pointer to Site */
+	int dims, strs, dbls;
+	RASTER_MAP_TYPE cat;
 
-	    if (fbuff == NULL)
-		G_fatal_error(_("Unable to allocate memory for segment fbuff == NULL"));
+	fp = G_fopen_sites_old(opt8->answer, "");
 
-	    Rast_set_d_null_value(fbuff, ncols);
+	if (G_site_describe(fp, &dims, &cat, &strs, &dbls))
+	    G_fatal_error("Failed to guess site file format\n");
+	site = G_site_new_struct(cat, dims, strs, dbls);
 
-	    for (row = 0; row < nrows; row++) {
-		{
-		    G_percent(row, nrows, 2);
-		}
-		for (i = 0; i < ncols; i++) {
-		    segment_put(&out_seg2, &fbuff[i], row, i);
-		}
+	for (; (G_site_get(fp, site) != EOF);) {
+	    if (!G_site_in_region(site, &window))
+		continue;
+	    have_stop_points = 1;
+
+	    col = (int)G_easting_to_col(site->east, &window);
+	    row = (int)G_northing_to_row(site->north, &window);
+
+	    new_start_pt =
+		(struct start_pt *)(G_malloc(sizeof(struct start_pt)));
+
+	    new_start_pt->row = row;
+	    new_start_pt->col = col;
+	    new_start_pt->next = NULL;
+
+	    if (head_end_pt == NULL) {
+		head_end_pt = new_start_pt;
+		pres_stop_pt = new_start_pt;
+		new_start_pt->next = NULL;
 	    }
-	    segment_flush(&out_seg2);
-	    G_percent(row, nrows, 2);
-	    G_free(fbuff);
+	    else {
+		pres_stop_pt->next = new_start_pt;
+		pres_stop_pt = new_start_pt;
+	    }
 	}
-    }
 
-    /*   Scan the existing cum_cost_layer searching for starting points.
-     *   Create a btree of starting points ordered by increasing costs.
-     */
-    if (!have_start_points) {
+	G_site_free_struct(site);
+	G_sites_close(fp);
 
+	if (!have_stop_points)
+	    G_fatal_error(_("No stop points found in vector <%s>"), opt7->answer);
+    }
+
+    /* read raster with start points */
+    if (opt9->answer) {
 	int dsize2;
+	int fd;
+	RASTER_MAP_TYPE data_type2;
+	int got_one = 0;
 
-	cum_fd = Rast_open_old(start_layer, "");
+	search_mapset = G_find_raster(opt9->answer, "");
 
-	data_type2 = Rast_get_map_type(cum_fd);
+	if (search_mapset == NULL)
+	    G_fatal_error(_("Raster map <%s> not found"), opt9->answer);
 
+	fd = Rast_open_old(opt9->answer, "");
+	data_type2 = Rast_get_map_type(fd);
 	dsize2 = Rast_cell_size(data_type2);
-
 	cell2 = Rast_allocate_buf(data_type2);
+	if (!cell2)
+	    G_fatal_error(_("Unable to allocate memory"));
 
-	G_message(_("Reading %s... "), cum_cost_layer);
+	G_message(_("Reading %s... "), opt9->answer);
 	for (row = 0; row < nrows; row++) {
 
 	    G_percent(row, nrows, 2);
-	    Rast_get_row(cum_fd, cell2, row, data_type2);
+	    Rast_get_row(fd, cell2, row, data_type2);
 	    ptr2 = cell2;
 	    for (col = 0; col < ncols; col++) {
 		/* Did I understand that concept of cummulative cost map? - (pmx) 12 april 2000 */
 		if (!Rast_is_null_value(ptr2, data_type2)) {
 		    double cellval;
 
+		    segment_get(&cost_seg, &costs, row, col);
+
 		    if (start_with_raster_vals == 1) {
 			cellval = Rast_get_d_value(ptr2, data_type2);
 			new_cell = insert(cellval, row, col);
-			segment_put(&out_seg, &cellval, row, col);
+			costs.cost_out = cellval;
+			segment_put(&cost_seg, &costs, row, col);
 		    }
 		    else {
-			value_start_pt = &zero;
+			value = &zero;
 			new_cell = insert(zero, row, col);
-			segment_put(&out_seg, value_start_pt, row, col);
+			costs.cost_out = *value;
+			segment_put(&cost_seg, &costs, row, col);
 		    }
+		    got_one = 1;
 		}
 		ptr2 = G_incr_void_ptr(ptr2, dsize2);
 	    }
 	}
 
-	G_percent(row, nrows, 2);
+	G_percent(1, 1, 1);
 
-	Rast_close(cum_fd);
+	Rast_close(fd);
 	G_free(cell2);
 
+	if (!got_one)
+	    G_fatal_error(_("No start points found in raster <%s>"), opt9->answer);
     }
 
-
     /*  If the starting points are given on the command line start a linked
      *  list of cells ordered by increasing costs
      */
-    else {
+    if (head_start_pt) {
 	struct start_pt *top_start_pt = NULL;
 
 	top_start_pt = head_start_pt;
 	while (top_start_pt != NULL) {
-	    value_start_pt = &zero;
+	    value = &zero;
 	    if (top_start_pt->row < 0 || top_start_pt->row >= nrows
 		|| top_start_pt->col < 0 || top_start_pt->col >= ncols)
 		G_fatal_error(_("Specified starting location outside database window"));
 	    new_cell = insert(zero, top_start_pt->row, top_start_pt->col);
-	    segment_put(&out_seg, value_start_pt, top_start_pt->row,
+	    segment_get(&cost_seg, &costs, top_start_pt->row,
 			top_start_pt->col);
+	    costs.cost_out = *value;
+	    segment_put(&cost_seg, &costs, top_start_pt->row,
+			top_start_pt->col);
 	    top_start_pt = top_start_pt->next;
 	}
     }
 
-    /*  Loop through the btree and perform at each cell the following:
+    /*  Loop through the heap and perform at each cell the following:
      *   1) If an adjacent cell has not already been assigned a value compute
      *      the min cost and assign it.
-     *   2) Insert the adjacent cell in the btree.
+     *   2) Insert the adjacent cell in the heap.
      *   3) Free the memory allocated to the present cell.
      */
 
-
-    /*system("date"); */
     G_message(_("Finding cost path"));
-
     n_processed = 0;
-    total_cells = nrows * ncols;
     at_percent = 0;
 
     pres_cell = get_lowest();
@@ -953,12 +908,19 @@
 	double NNE_cost, ENE_cost, ESE_cost, SSE_cost, SSW_cost, WSW_cost,
 	    WNW_cost, NNW_cost;
 
+	N_dtm = NE_dtm = E_dtm = SE_dtm = S_dtm = SW_dtm = W_dtm = NW_dtm = dnullval;
+	NNE_dtm = ENE_dtm = ESE_dtm = SSE_dtm = SSW_dtm = WSW_dtm = WNW_dtm = NNW_dtm = dnullval;
+
+	N_cost = NE_cost = E_cost = SE_cost = S_cost = SW_cost = W_cost = NW_cost = dnullval;
+	NNE_cost = ENE_cost = ESE_cost = SSE_cost = SSW_cost = WSW_cost = WNW_cost = NNW_cost = dnullval;
+
 	/* If we have surpassed the user specified maximum cost, then quit */
 	if (maxcost && ((double)maxcost < pres_cell->min_cost))
 	    break;
 
 	/* If I've already been updated, delete me */
-	segment_get(&out_seg, &old_min_cost, pres_cell->row, pres_cell->col);
+	segment_get(&cost_seg, &costs, pres_cell->row, pres_cell->col);
+	old_min_cost = costs.cost_out;
 	if (!Rast_is_d_null_value(&old_min_cost)) {
 	    if (pres_cell->min_cost > old_min_cost) {
 		delete(pres_cell);
@@ -967,16 +929,15 @@
 	    }
 	}
 
-	segment_get(&dtm_in_seg, &my_dtm, pres_cell->row, pres_cell->col);
+	my_dtm = costs.dtm;
 	if (Rast_is_d_null_value(&my_dtm))
 	    continue;
-	segment_get(&cost_in_seg, &my_cost, pres_cell->row, pres_cell->col);
+	my_cost = costs.cost_in;
 	if (Rast_is_d_null_value(&my_cost))
 	    continue;
 
+	G_percent(n_processed++, total_cells, 1);
 
-	G_percent(++n_processed, total_cells, 1);
-
 	/*          9    10       Order in which neighbors 
 	 *       13 5  3  6 14    are visited (Knight move).
 	 *          1     2
@@ -1072,307 +1033,284 @@
 	    if (col < 0 || col >= ncols)
 		continue;
 
+	    segment_get(&cost_seg, &costs, row, col);
 	    switch (neighbor) {
 	    case 1:
-		dtm_value = &W_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &W_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		W_dtm = costs.dtm;
+		W_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&W_cost))
 		    continue;
-		if (((W_dtm - my_dtm) / EW_fac) >= 0)
-		    fcost_dtm = (double)((double)(W_dtm - my_dtm) * b);
-		else if (((W_dtm - my_dtm) / EW_fac) < (slope_factor))
-		    fcost_dtm = (double)((double)(W_dtm - my_dtm) * d);
+		check_dtm = (W_dtm - my_dtm) / EW_fac;
+		if (check_dtm >= 0)
+		    fcost_dtm = (double)(W_dtm - my_dtm) * b;
+		else if (check_dtm < (slope_factor))
+		    fcost_dtm = (double)(W_dtm - my_dtm) * d;
 		else
-		    fcost_dtm = (double)((double)(W_dtm - my_dtm) * c);
-		fcost_cost = (double)((W_cost / 2.0) + (my_cost / 2.0));
+		    fcost_dtm = (double)(W_dtm - my_dtm) * c;
+		fcost_cost = (double)(W_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (EW_fac * a) +
 		    lambda * fcost_cost * EW_fac;
 		break;
 	    case 2:
-		dtm_value = &E_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &E_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		E_dtm = costs.dtm;
+		E_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&E_cost))
 		    continue;
-		if (((E_dtm - my_dtm) / EW_fac) >= 0)
+		check_dtm = (E_dtm - my_dtm) / EW_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(E_dtm - my_dtm) * b;
-		else if (((E_dtm - my_dtm) / EW_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(E_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(E_dtm - my_dtm) * c;
-		fcost_cost = (double)((E_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(E_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (EW_fac * a) +
 		    lambda * fcost_cost * EW_fac;
 		break;
 	    case 3:
-		dtm_value = &N_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &N_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		N_dtm = costs.dtm;
+		N_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&N_cost))
 		    continue;
-		if (((N_dtm - my_dtm) / NS_fac) >= 0)
+		check_dtm = (N_dtm - my_dtm) / NS_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(N_dtm - my_dtm) * b;
-		else if (((N_dtm - my_dtm) / NS_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(N_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(N_dtm - my_dtm) * c;
-		fcost_cost = (double)((N_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(N_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (NS_fac * a) +
 		    lambda * fcost_cost * NS_fac;
 		break;
 	    case 4:
-		dtm_value = &S_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &S_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		S_dtm = costs.dtm;
+		S_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&S_cost))
 		    continue;
-		if (((S_dtm - my_dtm) / NS_fac) >= 0)
+		check_dtm = (S_dtm - my_dtm) / NS_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(S_dtm - my_dtm) * b;
-		else if (((S_dtm - my_dtm) / NS_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(S_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(S_dtm - my_dtm) * c;
-		fcost_cost = (double)((S_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(S_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (NS_fac * a) +
 		    lambda * fcost_cost * NS_fac;
 		break;
 	    case 5:
-		dtm_value = &NW_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &NW_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		NW_dtm = costs.dtm;
+		NW_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&NW_cost))
 		    continue;
-		if (((NW_dtm - my_dtm) / DIAG_fac) >= 0)
+		check_dtm = (NW_dtm - my_dtm) / DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(NW_dtm - my_dtm) * b;
-		else if (((NW_dtm - my_dtm) / DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(NW_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(NW_dtm - my_dtm) * c;
-		fcost_cost = (double)((NW_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(NW_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (DIAG_fac * a) +
 		    lambda * fcost_cost * DIAG_fac;
 		break;
 	    case 6:
-		dtm_value = &NE_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &NE_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		NE_dtm = costs.dtm;
+		NE_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&NE_cost))
 		    continue;
-		if (((NE_dtm - my_dtm) / DIAG_fac) >= 0)
+		check_dtm = (NE_dtm - my_dtm) / DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(NE_dtm - my_dtm) * b;
-		else if (((NE_dtm - my_dtm) / DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(NE_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(NE_dtm - my_dtm) * c;
-		fcost_cost = (double)((NE_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(NE_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (DIAG_fac * a) +
 		    lambda * fcost_cost * DIAG_fac;
 		break;
 	    case 7:
-		dtm_value = &SE_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &SE_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		SE_dtm = costs.dtm;
+		SE_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&SE_cost))
 		    continue;
-		if (((SE_dtm - my_dtm) / DIAG_fac) >= 0)
+		check_dtm = (SE_dtm - my_dtm) / DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(SE_dtm - my_dtm) * b;
-		else if (((SE_dtm - my_dtm) / DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(SE_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(SE_dtm - my_dtm) * c;
-		fcost_cost = (double)((SE_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(SE_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (DIAG_fac * a) +
 		    lambda * fcost_cost * DIAG_fac;
 		break;
 	    case 8:
-		dtm_value = &SW_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &SW_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		SW_dtm = costs.dtm;
+		SW_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&SW_cost))
 		    continue;
-		if (((SW_dtm - my_dtm) / DIAG_fac) >= 0)
+		check_dtm = (SW_dtm - my_dtm) / DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(SW_dtm - my_dtm) * b;
-		else if (((SW_dtm - my_dtm) / DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(SW_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(SW_dtm - my_dtm) * c;
-		fcost_cost = (double)((SW_cost / 2.0) + (my_cost / 2.0));
+		fcost_cost = (double)(SW_cost + my_cost) / 2.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (DIAG_fac * a) +
 		    lambda * fcost_cost * DIAG_fac;
 		break;
 	    case 9:
-		dtm_value = &NNW_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &NNW_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		NNW_dtm = costs.dtm;
+		NNW_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&NNW_cost))
 		    continue;
-		if (((NNW_dtm - my_dtm) / V_DIAG_fac) >= 0)
+		check_dtm = (NNW_dtm - my_dtm) / V_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(NNW_dtm - my_dtm) * b;
-		else if (((NNW_dtm - my_dtm) / V_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(NNW_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(NNW_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((N_cost / 4.0) + (NW_cost / 4.0) +
-			     (NNW_cost / 4.0) + (my_cost / 4.0));
+		    (double)(N_cost + NW_cost + NNW_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (V_DIAG_fac * a) +
 		    lambda * fcost_cost * V_DIAG_fac;
 		break;
 	    case 10:
-		dtm_value = &NNE_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &NNE_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		NNE_dtm = costs.dtm;
+		NNE_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&NNE_cost))
 		    continue;
-		if (((NNE_dtm - my_dtm) / V_DIAG_fac) >= 0)
+		check_dtm = ((NNE_dtm - my_dtm) / V_DIAG_fac);
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(NNE_dtm - my_dtm) * b;
-		else if (((NNE_dtm - my_dtm) / V_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(NNE_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(NNE_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((N_cost / 4.0) + (NE_cost / 4.0) +
-			     (NNE_cost / 4.0) + (my_cost / 4.0));
+		    (double)(N_cost + NE_cost + NNE_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (V_DIAG_fac * a) +
 		    lambda * fcost_cost * V_DIAG_fac;
 		break;
 	    case 11:
-		dtm_value = &SSE_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &SSE_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		SSE_dtm = costs.dtm;
+		SSE_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&SSE_cost))
 		    continue;
-		if (((SSE_dtm - my_dtm) / V_DIAG_fac) >= 0)
+		check_dtm = (SSE_dtm - my_dtm) / V_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(SSE_dtm - my_dtm) * b;
-		else if (((SSE_dtm - my_dtm) / V_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(SSE_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(SSE_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((S_cost / 4.0) + (SE_cost / 4.0) +
-			     (SSE_cost / 4.0) + (my_cost / 4.0));
+		    (double)(S_cost + SE_cost + SSE_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (V_DIAG_fac * a) +
 		    lambda * fcost_cost * V_DIAG_fac;
 		break;
 	    case 12:
-		dtm_value = &SSW_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &SSW_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		SSW_dtm = costs.dtm;
+		SSW_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&SSW_cost))
 		    continue;
-		if (((SSW_dtm - my_dtm) / V_DIAG_fac) >= 0)
+		check_dtm = (SSW_dtm - my_dtm) / V_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(SSW_dtm - my_dtm) * b;
-		else if (((SSW_dtm - my_dtm) / V_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(SSW_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(SSW_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((S_cost / 4.0) + (SW_cost / 4.0) +
-			     (SSW_cost / 4.0) + (my_cost / 4.0));
+		    (double)(S_cost + SW_cost +	SSW_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (V_DIAG_fac * a) +
 		    lambda * fcost_cost * V_DIAG_fac;
 		break;
 	    case 13:
-		dtm_value = &WNW_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &WNW_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		WNW_dtm = costs.dtm;
+		WNW_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&WNW_cost))
 		    continue;
-		if (((WNW_dtm - my_dtm) / H_DIAG_fac) >= 0)
+		check_dtm = (WNW_dtm - my_dtm) / H_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(WNW_dtm - my_dtm) * b;
-		else if (((WNW_dtm - my_dtm) / H_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(WNW_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(WNW_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((W_cost / 4.0) + (NW_cost / 4.0) +
-			     (WNW_cost / 4.0) + (my_cost / 4.0));
+		    (double)(W_cost + NW_cost + WNW_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (H_DIAG_fac * a) +
 		    lambda * fcost_cost * H_DIAG_fac;
 		break;
 	    case 14:
-		dtm_value = &ENE_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &ENE_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		ENE_dtm = costs.dtm;
+		ENE_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&ENE_cost))
 		    continue;
-		if (((ENE_dtm - my_dtm) / H_DIAG_fac) >= 0)
+		check_dtm = (ENE_dtm - my_dtm) / H_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(ENE_dtm - my_dtm) * b;
-		else if (((ENE_dtm - my_dtm) / H_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(ENE_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(ENE_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((E_cost / 4.0) + (NE_cost / 4.0) +
-			     (ENE_cost / 4.0) + (my_cost / 4.0));
+		    (double)(E_cost + NE_cost + ENE_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (H_DIAG_fac * a) +
 		    lambda * fcost_cost * H_DIAG_fac;
 		break;
 	    case 15:
-		dtm_value = &ESE_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &ESE_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		ESE_dtm = costs.dtm;
+		ESE_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&ESE_cost))
 		    continue;
-		if (((ESE_dtm - my_dtm) / H_DIAG_fac) >= 0)
+		check_dtm = (ESE_dtm - my_dtm) / H_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(ESE_dtm - my_dtm) * b;
-		else if (((ESE_dtm - my_dtm) / H_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(ESE_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(ESE_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((E_cost / 4.0) + (SE_cost / 4.0) +
-			     (ESE_cost / 4.0) + (my_cost / 4.0));
+		    (double)(E_cost + SE_cost + ESE_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (H_DIAG_fac * a) +
 		    lambda * fcost_cost * H_DIAG_fac;
 		break;
 	    case 16:
-		dtm_value = &WSW_dtm;
-		segment_get(&dtm_in_seg, dtm_value, row, col);
-		cost_value = &WSW_cost;
-		segment_get(&cost_in_seg, cost_value, row, col);
-		if (Rast_is_d_null_value(cost_value))
+		WSW_dtm = costs.dtm;
+		WSW_cost = costs.cost_in;
+		if (Rast_is_d_null_value(&WSW_cost))
 		    continue;
-		if (((WSW_dtm - my_dtm) / H_DIAG_fac) >= 0)
+		check_dtm = (WSW_dtm - my_dtm) / H_DIAG_fac;
+		if (check_dtm >= 0)
 		    fcost_dtm = (double)(WSW_dtm - my_dtm) * b;
-		else if (((WSW_dtm - my_dtm) / H_DIAG_fac) < (slope_factor))
+		else if (check_dtm < (slope_factor))
 		    fcost_dtm = (double)(WSW_dtm - my_dtm) * d;
 		else
 		    fcost_dtm = (double)(WSW_dtm - my_dtm) * c;
 		fcost_cost =
-		    (double)((W_cost / 4.0) + (SW_cost / 4.0) +
-			     (WSW_cost / 4.0) + (my_cost / 4.0));
+		    (double)(W_cost + SW_cost +	WSW_cost + my_cost) / 4.0;
 		min_cost =
 		    pres_cell->min_cost + fcost_dtm + (H_DIAG_fac * a) +
 		    lambda * fcost_cost * H_DIAG_fac;
@@ -1382,22 +1320,24 @@
 	    if (Rast_is_d_null_value(&min_cost))
 		continue;
 
-	    segment_get(&out_seg, &old_min_cost, row, col);
+	    old_min_cost = costs.cost_out;
 	    if (dir == 1)
-		segment_get(&out_seg2, &old_cur_dir, row, col);
+		segment_put(&dir_seg, &cur_dir, row, col);
 
 	    if (Rast_is_d_null_value(&old_min_cost)) {
-		segment_put(&out_seg, &min_cost, row, col);
+		costs.cost_out = min_cost;
+		segment_put(&cost_seg, &costs, row, col);
 		new_cell = insert(min_cost, row, col);
 		if (dir == 1)
-		    segment_put(&out_seg2, &cur_dir, row, col);
+		    segment_put(&dir_seg, &cur_dir, row, col);
 	    }
 	    else {
 		if (old_min_cost > min_cost) {
-		    segment_put(&out_seg, &min_cost, row, col);
+		costs.cost_out = min_cost;
+		segment_put(&cost_seg, &costs, row, col);
 		    new_cell = insert(min_cost, row, col);
 		    if (dir == 1)
-			segment_put(&out_seg2, &cur_dir, row, col);
+			segment_put(&dir_seg, &cur_dir, row, col);
 		}
 		else {
 		}
@@ -1409,49 +1349,31 @@
 
 	ct = pres_cell;
 	delete(pres_cell);
-
 	pres_cell = get_lowest();
-	if (pres_cell == NULL) {
-
-	    G_message(_("End of map!"));
-	    goto OUT;
-	}
 	if (ct == pres_cell)
 	    G_warning(_("Error, ct == pres_cell"));
     }
-  OUT:
-    /*  Open cumulative cost layer for writing   */
+    G_percent(1, 1, 1);
 
+    /* free heap */
+    free_heap();
+    
+    /* Open cumulative cost layer for writing */
     cum_fd = Rast_open_new(cum_cost_layer, cum_data_type);
     cum_cell = Rast_allocate_buf(cum_data_type);
-    if (dir == 1) {
-	dir_fd = Rast_open_new(move_dir_layer, dir_data_type);
-	dir_cell = Rast_allocate_buf(dir_data_type);
-    }
 
-    /*  Write pending updates by segment_put() to output map   */
-
-    segment_flush(&out_seg);
-    if (dir == 1)
-	segment_flush(&out_seg2);
-
-    /*  Copy segmented map to output map  */
-
-    /* system("date"); */
+    /* Copy segmented map to output map */
     G_message(_("Writing output raster map %s... "), cum_cost_layer);
 
-    if (keep_nulls) {
+    cell2 = Rast_allocate_buf(dtm_data_type);
+    {
+	void *p;
+	void *p2;
+	int cum_dsize = Rast_cell_size(cum_data_type);
 
-	G_message(_("Will copy input map null values into output map"));
-	cell2 = Rast_allocate_buf(dtm_data_type);
-    }
-    if (cum_data_type == CELL_TYPE) {
-	int *p;
-	int *p2;
+	Rast_set_null_value(cell2, ncols, dtm_data_type);
 
-	G_message(_("Integer cell type.\nWriting..."));
 	for (row = 0; row < nrows; row++) {
-
 	    G_percent(row, nrows, 2);
 	    if (keep_nulls)
 		Rast_get_row(dtm_fd, cell2, row, dtm_data_type);
@@ -1460,131 +1382,91 @@
 	    p2 = cell2;
 	    for (col = 0; col < ncols; col++) {
 		if (keep_nulls) {
-		    if (Rast_is_null_value(p2++, dtm_data_type)) {
-			Rast_set_null_value((p + col), 1, dtm_data_type);
+		    if (Rast_is_null_value(p2, dtm_data_type)) {
+			Rast_set_null_value(p, 1, cum_data_type);
+			p = G_incr_void_ptr(p, cum_dsize);
+			p2 = G_incr_void_ptr(p2, dtm_dsize);
 			continue;
 		    }
 		}
-		segment_get(&out_seg, &min_cost, row, col);
+		segment_get(&cost_seg, &costs, row, col);
+		min_cost = costs.cost_out;
 		if (Rast_is_d_null_value(&min_cost)) {
-		    Rast_set_null_value((p + col), 1, cum_data_type);
+		    Rast_set_null_value((p), 1, cum_data_type);
 		}
 		else {
 		    if (min_cost > peak)
 			peak = min_cost;
-		    *(p + col) = (int)(min_cost + .5);
-		}
-	    }
-	    Rast_put_row(cum_fd, cum_cell, cum_data_type);
-	}
-    }
-    else if (cum_data_type == FCELL_TYPE) {
-	float *p;
-	float *p2;
 
-	G_message(_("Float cell type.\nWriting..."));
-	for (row = 0; row < nrows; row++) {
-
-	    G_percent(row, nrows, 2);
-	    if (keep_nulls)
-		Rast_get_row(dtm_fd, cell2, row, dtm_data_type);
-
-	    p = cum_cell;
-	    p2 = cell2;
-	    for (col = 0; col < ncols; col++) {
-		if (keep_nulls) {
-		    if (Rast_is_null_value(p2++, dtm_data_type)) {
-			Rast_set_null_value((p + col), 1, dtm_data_type);
-			continue;
+		    switch (cum_data_type) {
+		    case CELL_TYPE:
+			*(CELL *)p = (CELL)(min_cost + .5);
+			break;
+		    case FCELL_TYPE:
+			*(FCELL *)p = (FCELL)(min_cost);
+			break;
+		    case DCELL_TYPE:
+			*(DCELL *)p = (DCELL)(min_cost);
+			break;
 		    }
 		}
-		segment_get(&out_seg, &min_cost, row, col);
-		if (Rast_is_d_null_value(&min_cost)) {
-		    Rast_set_null_value((p + col), 1, cum_data_type);
-		}
-		else {
-		    if (min_cost > peak)
-			peak = min_cost;
-		    *(p + col) = (float)(min_cost);
-		}
+		p = G_incr_void_ptr(p, cum_dsize);
+		p2 = G_incr_void_ptr(p2, dtm_dsize);
 	    }
 	    Rast_put_row(cum_fd, cum_cell, cum_data_type);
 	}
+	G_percent(1, 1, 1);
+	G_free(cum_cell);
+	G_free(cell2);
     }
-    else if (cum_data_type == DCELL_TYPE) {
+
+    if (dir == 1) {
 	double *p;
-	double *p2;
 
-	G_message(_("Double cell type.\nWriting..."));
-	for (row = 0; row < nrows; row++) {
+	dir_fd = Rast_open_new(move_dir_layer, dir_data_type);
+	dir_cell = Rast_allocate_buf(dir_data_type);
 
-	    G_percent(row, nrows, 2);
-	    if (keep_nulls)
-		Rast_get_row(dtm_fd, cell2, row, dtm_data_type);
-
-	    p = cum_cell;
-	    p2 = cell2;
-	    for (col = 0; col < ncols; col++) {
-		if (keep_nulls) {
-		    if (Rast_is_null_value(p2++, dtm_data_type)) {
-			Rast_set_null_value((p + col), 1, dtm_data_type);
-			continue;
-		    }
-		}
-		segment_get(&out_seg, &min_cost, row, col);
-		if (Rast_is_d_null_value(&min_cost)) {
-		    Rast_set_null_value((p + col), 1, cum_data_type);
-		}
-		else {
-		    if (min_cost > peak)
-			peak = min_cost;
-		    *(p + col) = min_cost;
-		}
-	    }
-	    Rast_put_row(cum_fd, cum_cell, cum_data_type);
-	}
-    }
-
-    double *p;
-
-    if (dir == 1) {
 	G_message(_("Writing movement direction file %s..."), move_dir_layer);
 	for (row = 0; row < nrows; row++) {
 	    p = dir_cell;
 	    for (col = 0; col < ncols; col++) {
-		segment_get(&out_seg2, &cur_dir, row, col);
+		segment_get(&dir_seg, &cur_dir, row, col);
 		*(p + col) = cur_dir;
 	    }
 	    Rast_put_row(dir_fd, dir_cell, dir_data_type);
 	}
-	G_percent(row, nrows, 2);
+	G_percent(1, 1, 1);
+	G_free(dir_cell);
     }
 
-
-    G_message(_("Peak cost value: %f"), peak);
-
-    segment_release(&dtm_in_seg);	/* release memory  */
-    segment_release(&out_seg);
+    segment_release(&cost_seg);	/* release memory  */
     if (dir == 1)
-	segment_release(&out_seg2);
+	segment_release(&dir_seg);
     Rast_close(dtm_fd);
     Rast_close(cost_fd);
     Rast_close(cum_fd);
     if (dir == 1)
 	Rast_close(dir_fd);
-    close(dtm_in_fd);		/* close all files */
-    close(out_fd);
-    close(cost_in_fd);
+    close(in_fd);		/* close all files */
     if (dir == 1)
 	close(dir_out_fd);
-    unlink(dtm_in_file);	/* remove submatrix files  */
-    unlink(cost_in_file);
-    unlink(out_file);
+    unlink(in_file);	/* remove submatrix files  */
     if (dir == 1)
 	unlink(dir_out_file);
 
-    /*  Create colours for output map    */
+    /* writing history file */
+    Rast_short_history(cum_cost_layer, "raster", &history);
+    Rast_command_history(&history);
+    Rast_write_history(cum_cost_layer, &history);
 
+    if (dir == 1) {
+	Rast_short_history(move_dir_layer, "raster", &history);
+	Rast_command_history(&history);
+	Rast_write_history(move_dir_layer, &history);
+    }
+
+    /* Create colours for output map */
+
     /*
      * Rast_read_range (cum_cost_layer, "", &range);
      * Rast_get_range_min_max(&range, &min, &max);
@@ -1592,17 +1474,8 @@
      * Rast_write_colors (cum_cost_layer,"",&colors);
      */
 
-    /* writing history file */
-    Rast_short_history(cum_cost_layer, "raster", &history);
-    Rast_command_history(&history);
-    Rast_write_history(cum_cost_layer, &history);
+    G_done_msg(_("Peak cost value: %f."), peak);
 
-    if (dir == 1) {
-	Rast_short_history(move_dir_layer, "raster", &history);
-    Rast_command_history(&history);
-    Rast_write_history(move_dir_layer, &history);
-	}
-
     exit(EXIT_SUCCESS);
 }
 

Deleted: grass/trunk/raster/r.walk/memory.c
===================================================================
--- grass/trunk/raster/r.walk/memory.c	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/memory.c	2010-01-24 17:22:41 UTC (rev 40632)
@@ -1,131 +0,0 @@
-/* -*-c-basic-offset: 4;-*-
- *  Chained memory allocator 
- *  memory.c
- *
- *  Pierre de Mouveaux (pmx)  
- *  pmx at audiovu.com  - 10 april 2000.  
- *
- *  Used in GRASS 5.0 r.cost module
- *
- *  Released under GPL
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <grass/gis.h>
-#include "memory.h"
-
-#define NUM_IN_BLOCK	1024*8
-
-
-struct cost *first_free = NULL;
-struct cost *first = NULL;
-struct cost *last = NULL;
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int allocate(void)
-{
-    struct cost *data, *p1, *p2;
-    int i;
-
-    G_debug(2, "allocate()\n");
-
-    data = (struct cost *)G_malloc(NUM_IN_BLOCK * sizeof(struct cost));
-
-    if (data == NULL) {
-	G_warning("allocat(): error %s\n", strerror(errno));
-	return 0;
-    }
-
-    if (last != NULL) {
-	last->lower = data;
-	data->higher = last;
-    }
-
-
-    p1 = p2 = data;
-    p2++;
-
-    for (i = 1; i < NUM_IN_BLOCK - 1; i++, p1++, p2++) {
-	p1->lower = p2;
-	p2->higher = p1;
-	p1->above = NULL;
-    }
-    p2->higher = p1;
-    p2->above = NULL;
-    p2->lower = NULL;
-    last = p2;
-
-    if (first == NULL) {
-	first_free = data;
-	first = data;
-    }
-    else {
-	first_free->lower = data;
-    }
-
-    return 1;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int release(void)
-{
-    struct cost *p = first;
-    struct cost *next;
-
-    if (p == NULL)
-	return 1;
-
-    do {
-	next = (p + NUM_IN_BLOCK)->lower;
-	G_free(p);
-	p = next;
-    } while (next != NULL);
-
-    first = last = first_free = NULL;
-
-    return 1;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-struct cost *get(void)
-{
-    struct cost *p;
-
-    if (first_free == NULL) {
-	allocate();
-    }
-
-    p = first_free;
-    first_free = p->lower;
-    if (first_free->lower == NULL) {
-	allocate();
-    }
-    return p;
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
-int give(struct cost *p)
-{
-    if (p == NULL)
-	return 0;
-
-    p->lower = first_free;
-    first_free->above = p;
-    first_free = p;
-    p->above = NULL;		/* not used in this chain - (pmx) */
-
-    return 1;
-}

Deleted: grass/trunk/raster/r.walk/memory.h
===================================================================
--- grass/trunk/raster/r.walk/memory.h	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/memory.h	2010-01-24 17:22:41 UTC (rev 40632)
@@ -1,23 +0,0 @@
-/* -*-c-basic-offset: 4;-*-
- *  Chained memory allocator 
- *  memory.h
- *
- *  Pierre de Mouveaux (pmx)  
- *  pmx at audiovu.com  - 10 april 2000.  
- *
- *  Used in GRASS 5.0 r.cost module
- *
- *  Released under GPL
- */
-
-#ifndef  __R_COST_MEMORY__
-#define  __R_COST_MEMORY__
-
-#include "cost.h"
-
-int allocate(void);
-int release(void);
-struct cost *get(void);
-int give(struct cost *p);
-
-#endif /* __R_COST_MEMORY__ */

Modified: grass/trunk/raster/r.walk/stash.h
===================================================================
--- grass/trunk/raster/r.walk/stash.h	2010-01-24 17:21:01 UTC (rev 40631)
+++ grass/trunk/raster/r.walk/stash.h	2010-01-24 17:22:41 UTC (rev 40632)
@@ -10,8 +10,8 @@
 
 /***************************************************************/
 
-#ifndef __R_COST_STASH_H__
-#define __R_COST_STASH_H__
+#ifndef __STASH_H__
+#define __STASH_H__
 
 #include <stdio.h>
 #define      CUM_COST_LAYER        1
@@ -33,5 +33,3 @@
 int time_to_stop(int, int);
 
 #endif
-
-/****************END OF "GCOST_CMD_LINE.H"**********************/



More information about the grass-commit mailing list