[GRASS-SVN] r43163 - in grass-addons/grass7/raster/r.stream: . r.stream.basins r.stream.distance r.stream.order r.stream.stats

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Aug 19 05:50:26 EDT 2010


Author: jarekj71
Date: 2010-08-19 09:50:26 +0000 (Thu, 19 Aug 2010)
New Revision: 43163

Added:
   grass-addons/grass7/raster/r.stream/makefile
   grass-addons/grass7/raster/r.stream/notes
   grass-addons/grass7/raster/r.stream/r.stream.basins/
   grass-addons/grass7/raster/r.stream/r.stream.basins/Makefile
   grass-addons/grass7/raster/r.stream/r.stream.basins/basins_fill.c
   grass-addons/grass7/raster/r.stream/r.stream.basins/basins_inputs.c
   grass-addons/grass7/raster/r.stream/r.stream.basins/io.c
   grass-addons/grass7/raster/r.stream/r.stream.basins/io.h
   grass-addons/grass7/raster/r.stream/r.stream.basins/local_proto.h
   grass-addons/grass7/raster/r.stream/r.stream.basins/local_vars.h
   grass-addons/grass7/raster/r.stream/r.stream.basins/main.c
   grass-addons/grass7/raster/r.stream/r.stream.basins/r.stream.basins.html
   grass-addons/grass7/raster/r.stream/r.stream.distance/
   grass-addons/grass7/raster/r.stream/r.stream.distance/Makefile
   grass-addons/grass7/raster/r.stream/r.stream.distance/distance_calc.c
   grass-addons/grass7/raster/r.stream/r.stream.distance/distance_init.c
   grass-addons/grass7/raster/r.stream/r.stream.distance/io.c
   grass-addons/grass7/raster/r.stream/r.stream.distance/io.h
   grass-addons/grass7/raster/r.stream/r.stream.distance/local_proto.h
   grass-addons/grass7/raster/r.stream/r.stream.distance/local_vars.h
   grass-addons/grass7/raster/r.stream/r.stream.distance/main.c
   grass-addons/grass7/raster/r.stream/r.stream.distance/r.stream.distance.html
   grass-addons/grass7/raster/r.stream/r.stream.order/
   grass-addons/grass7/raster/r.stream/r.stream.order/Makefile
   grass-addons/grass7/raster/r.stream/r.stream.order/io.c
   grass-addons/grass7/raster/r.stream/r.stream.order/io.h
   grass-addons/grass7/raster/r.stream/r.stream.order/local_proto.h
   grass-addons/grass7/raster/r.stream/r.stream.order/local_vars.h
   grass-addons/grass7/raster/r.stream/r.stream.order/main.c
   grass-addons/grass7/raster/r.stream/r.stream.order/orders.png
   grass-addons/grass7/raster/r.stream/r.stream.order/r.stream.order.html
   grass-addons/grass7/raster/r.stream/r.stream.order/stream_init.c
   grass-addons/grass7/raster/r.stream/r.stream.order/stream_order.c
   grass-addons/grass7/raster/r.stream/r.stream.order/stream_raster_close.c
   grass-addons/grass7/raster/r.stream/r.stream.order/stream_topology.c
   grass-addons/grass7/raster/r.stream/r.stream.order/stream_vector.c
   grass-addons/grass7/raster/r.stream/r.stream.stats/
   grass-addons/grass7/raster/r.stream/r.stream.stats/Makefile
   grass-addons/grass7/raster/r.stream/r.stream.stats/io.c
   grass-addons/grass7/raster/r.stream/r.stream.stats/io.h
   grass-addons/grass7/raster/r.stream/r.stream.stats/local_proto.h
   grass-addons/grass7/raster/r.stream/r.stream.stats/local_vars.h
   grass-addons/grass7/raster/r.stream/r.stream.stats/main.c
   grass-addons/grass7/raster/r.stream/r.stream.stats/r.stream.stats.html
   grass-addons/grass7/raster/r.stream/r.stream.stats/stats_calculate.c
   grass-addons/grass7/raster/r.stream/r.stream.stats/stats_prepare.c
   grass-addons/grass7/raster/r.stream/r.stream.stats/stats_print.c
Log:
modules


Added: grass-addons/grass7/raster/r.stream/makefile
===================================================================
--- grass-addons/grass7/raster/r.stream/makefile	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/makefile	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../..
+
+SUBDIRS = \
+	r.stream.order \
+	r.stream.baisns \
+	r.stream.distance \
+	r.stream.stats
+
+include $(MODULE_TOPDIR)/include/Make/Dir.make
+
+default: parsubdirs

Added: grass-addons/grass7/raster/r.stream/notes
===================================================================
--- grass-addons/grass7/raster/r.stream/notes	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/notes	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1 @@
+this is only a working version and backup copy of incoming r.stream version for GRASS 7. We not support it as well as do not fix bugs till release. However we are iterested in proposition of new features.

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/Makefile
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/Makefile	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/Makefile	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,14 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.stream.basins
+
+LIBES = $(GISLIB) $(RASTERLIB) $(SEGMENTLIB) $(VECTLIB) $(DBMILIB)
+DEPENDENCIES = $(GISDEP) $(RASTERDEP) $(SEGMENTDEP) $(VECTDEP) $(DBMIDEP)
+
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
+

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/basins_fill.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/basins_fill.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/basins_fill.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,179 @@
+/* 
+   Link: a channel between junction
+   Ooutlet: is final cell of every segment
+   Segment: a channel which order remains unchanged in spite it pass through junction or not
+   Number of outlets shall be equal the number of segments
+   Number of junction shall be less than number of links
+ */
+
+/*
+   find outlets create table of outlets point, with r, c and value. depending of flag:
+   if flag -l is as anly last points of segment is added to table and uses the value is the category as value for whole basins
+   if flag -l = flase (default) last points of every link is added to table and uses the value is the category as value for subbasin
+   In both cases if flag -c is used it add out_num+1 value as value of point. That structure is next used in reset_catchments and fill_catchments fuctions
+ */
+
+/* fifo functions */
+/* insertion point: tail -> tail must always be unused */
+/* removal point: head + 1 */
+/* head == tail if last point removed or if only one free slot left */
+
+#include "local_proto.h"
+static int tail, head, fifo_count;
+
+int fifo_insert(POINT point)
+{
+    if (fifo_count == fifo_max)
+	G_fatal_error("fifo queue: circular buffer too small");
+
+    fifo_points[tail++] = point;
+    if (tail > fifo_max) {
+	G_debug(1, "tail > fifo_max");
+	tail = 0;
+    }
+    fifo_count++;
+    return 0;
+}
+
+POINT fifo_return_del(void)
+{
+    if (head >= fifo_max) {
+	G_debug(1, "head >= fifo_max");
+	head = -1;
+    }
+    fifo_count--;
+	
+    return fifo_points[++head];
+}
+
+/*
+   this function adds points from outlet structure 
+   The lines below from function fill_catchments makes that 
+   outlet is not added do fifo
+   queue and basin is limited by next outlet
+
+   if (catchments[NR(i)][NR(i)]>0)
+   continue; 
+
+   It is simple trick but allow gives module its real funcionality
+   
+   Buffer is an correction wchich allow to delinate basins even if vector point 
+   or coordinates do not lie exactly on stream. In that case a small one pixel buffer
+   is created. This is little risk functionality and must be used carefully.
+ */
+
+int ram_add_outlets(CELL** basins, int outlets_num)
+{
+  int i;
+
+			for (i = 0; i < outlets_num; ++i)
+	basins[outlets[i].r][outlets[i].c] = outlets[i].val;
+
+	return 0;
+}
+
+int seg_add_outlets(SEGMENT* basins, int outlets_num)
+{
+
+  int i;
+	int* basins_cell;
+ 
+		for (i = 0; i < outlets_num; ++i) {
+	basins_cell=&outlets[i].val;
+	segment_put(basins,basins_cell,outlets[i].r,outlets[i].c);
+    }
+    return 0;
+}
+
+/*
+   algorithm uses fifo queue for determining basins area. 
+ */
+
+int ram_fill_basins(OUTLET outlet, CELL** basins, CELL** dirs)
+{
+    int next_r, next_c;
+    int r, c, val, i, j;
+    POINT n_cell;
+
+    tail = 0;
+    head = -1;
+    fifo_count = 0;
+		r=outlet.r;
+		c=outlet.c;
+    val = outlet.val;
+
+    G_debug(1, "processing outlet at row %d col %d", r, c);
+
+    basins[r][c] = val;
+
+    while (tail != head) {
+	for (i = 1; i < 9; i++) {
+	    next_r = NR(i);
+	    next_c = NC(i);
+
+	    if (NOT_IN_REGION(i)) 
+		continue;
+		j = DIAG(i);
+
+		/* countributing cell, not yet assigned to a basin */
+		if (dirs[next_r][next_c] == j && basins[next_r][next_c] == 0) {
+		    basins[next_r][next_c] = val;
+				n_cell.r = next_r;
+				n_cell.c = next_c;
+		    fifo_insert(n_cell);
+		}
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+    } /* end while */
+    return 0;
+}
+
+int seg_fill_basins(OUTLET outlet, SEGMENT* basins, SEGMENT* dirs)
+{
+    int next_r, next_c;
+    int r, c, val, i, j;
+    POINT n_cell;
+		int dirs_cell, basins_cell;
+    tail = 0;
+    head = -1;
+    fifo_count = 0;
+		r=outlet.r;
+		c=outlet.c;
+    val = outlet.val;
+
+    G_debug(1, "processing outlet at row %d col %d", r, c);
+
+    segment_put(basins,&val,r,c);
+    
+    while (tail != head) {
+	for (i = 1; i < 9; i++) {
+	    next_r = NR(i);
+	    next_c = NC(i);
+
+	    if (NOT_IN_REGION(i)) 
+		continue;
+		j = DIAG(i);
+
+		/* countributing cell, not yet assigned to a basin */
+		segment_get(basins,&basins_cell,next_r,next_c);
+		segment_get(dirs,&dirs_cell,next_r,next_c);
+		
+		if (dirs_cell == j && basins_cell == 0) {
+				segment_put(basins,&val,next_r,next_c);
+				n_cell.r = next_r;
+				n_cell.c = next_c;
+		    fifo_insert(n_cell);
+		}
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+
+    } /* end while */
+
+    return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/basins_inputs.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/basins_inputs.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/basins_inputs.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,265 @@
+#include "local_proto.h"
+int process_coors(char **answers)
+{
+
+  int n, outlets_num;
+  int r, c;
+  double X, Y;
+  struct Cell_head window;
+	
+    if (!answers)
+	G_fatal_error(_("At least one pair of coordinates must pe send"));
+	
+	G_get_window(&window);
+	
+  for (n = 0, outlets_num = 0; answers[n] != NULL; n += 2, outlets_num++);
+
+  outlets = (OUTLET *)G_malloc(outlets_num * sizeof(OUTLET));
+
+  for (n = 0, outlets_num = 0; answers[n] != NULL; n += 2, outlets_num++) {
+	
+	if (!G_scan_easting(answers[n], &X, G_projection()))
+	    G_fatal_error("Wrong coordinate <%s>", answers[n]);
+	
+	if (!answers[n + 1])
+	    G_fatal_error("Missing north coordinate for east %g", X);
+	
+	if (!G_scan_northing(answers[n + 1], &Y, G_projection()))
+	    G_fatal_error("Wrong coordinate <%s>", answers[n + 1]);
+
+	if (X < window.west || X > window.east || 
+			Y < window.south || Y > window.north)
+				G_fatal_error("Coordinates outside window");
+
+	outlets[outlets_num].r = (window.north - Y) / window.ns_res;
+	outlets[outlets_num].c = (X - window.west) / window.ew_res;
+	outlets[outlets_num].val = outlets_num + 1;
+    }
+
+  return outlets_num;
+}
+
+int process_vector(char *in_point)
+{
+    char *mapset;
+    struct Cell_head window;
+    struct Map_info Map;
+    struct bound_box box;
+    int num_point = 0;
+    int type, i, cat;
+    int r,c;
+    struct line_pnts *sites;
+    struct line_cats *cats;
+
+    sites = Vect_new_line_struct();
+    cats = Vect_new_cats_struct();
+
+    mapset = G_find_vector2(in_point, "");
+    if (mapset == NULL)
+	G_fatal_error(_("Vector map <%s> not found"), in_point);
+
+    if (Vect_open_old(&Map, in_point, mapset) < 0)
+	G_fatal_error("Cannot open vector map <%s>", in_point);
+
+    G_get_window(&window);
+    Vect_region_box(&window, &box);
+
+    while ((type = Vect_read_next_line(&Map, sites, cats)) > -1) {
+				if (type != GV_POINT)
+			continue;
+				if (Vect_point_in_box(sites->x[0], sites->y[0], sites->z[0], &box)) {
+	    num_point++;
+		}
+    }
+
+    outlets = (OUTLET *) G_malloc(num_point * sizeof(OUTLET));
+
+    for (i = 0; i < num_point; ++i) {
+
+	type = Vect_read_line(&Map, sites, cats, i + 1);
+	if (type != GV_POINT)
+	    continue;
+
+	if (!Vect_point_in_box(sites->x[0], sites->y[0], sites->z[0], &box))
+	    continue;
+
+	Vect_cat_get(cats, 1, &cat);
+
+	outlets[i].r = (int)Rast_northing_to_row(sites->y[0], &window);
+	outlets[i].c = (int)Rast_easting_to_col(sites->x[0], &window);
+	outlets[i].val = cat;
+    }
+    return num_point;
+}
+
+int ram_process_streams(char** cat_list, CELL** streams, int number_of_streams, CELL** dirs, int lasts, int cats)
+{
+  int i, cat;
+	int r, c, d; /* d: direction */
+	int outlets_num=0, border_outlets_num=0;
+  int next_stream = -1, cur_stream;
+  int out_max = ncols + nrows;
+	
+	categories=NULL;
+
+		if (cat_list) { /* only if there are at least one category */
+	categories = G_malloc((number_of_streams) * sizeof(int));
+	memset(categories,-1,(number_of_streams) * sizeof(int));
+
+	for (i = 0; cat_list[i] != NULL; ++i) {
+		cat = atoi(cat_list[i]);
+			if (cat < 1 || cat > number_of_streams)
+		G_fatal_error(_
+			("Stream categories must be > 0 and < maximum stream category"));
+		categories[cat] = cat;
+	}
+		}
+
+   G_message("Finding nodes...");
+  outlets = (OUTLET *) G_malloc((out_max) * sizeof(OUTLET));
+
+		   for (r = 0; r < nrows; ++r) 
+		for (c = 0; c < ncols; ++c)
+	if (streams[r][c]>0) {
+
+			if (outlets_num > 2 * (out_max - 1))
+		G_fatal_error(_
+				("Stream and direction maps probably do not match"));
+			if (outlets_num > (out_max - 1))
+		outlets = (OUTLET *)G_realloc(outlets,out_max*2*sizeof(OUTLET));
+
+		d = abs(dirs[r][c]);	/* r.watershed */
+
+			if (NOT_IN_REGION(d))
+		next_stream = -1;	/* border */
+			else 
+		next_stream = (streams[NR(d)][NC(d)]>0) ? 
+			streams[NR(d)][NC(d)]: -1;
+
+			if (d == 0)
+		next_stream = -1;
+
+		cur_stream = streams[r][c];
+
+			if (lasts) {
+		if (next_stream < 0) {	/* is outlet! */
+
+			if (categories)
+				if (categories[cur_stream] == -1) /* but not in list */
+		continue;
+
+		outlets[outlets_num].r = r;
+		outlets[outlets_num].c = c;
+		outlets[outlets_num].val = 	  
+			(cats) ? outlets_num + 1 : streams[r][c];
+		outlets_num++;
+		    }
+			} else { /* not lasts */
+
+		if (cur_stream != next_stream) {	/* is node or outlet! */
+
+			if (categories)
+				if (categories[cur_stream] == -1) /* but not in list */
+		continue;
+		
+		outlets[outlets_num].r = r;
+		outlets[outlets_num].c = c;
+		outlets[outlets_num].val =
+		    (cats) ? outlets_num + 1 : streams[r][c];
+		outlets_num++;
+		    }
+				}		/* end if else lasts */
+	    }			/* end if streams */
+
+    return outlets_num;
+}
+
+int seg_process_streams(char **cat_list,  SEGMENT* streams, int number_of_streams, SEGMENT* dirs, int lasts, int cats)
+{
+  int i, cat;
+	int r, c, d; /* d: direction */
+  int outlets_num;
+  int next_stream = -1, cur_stream;
+	int streams_cell, dirs_cell,streams_next_cell;
+  int out_max = ncols + nrows;
+
+		categories=NULL;  
+
+		if (cat_list) {
+	categories = G_malloc((number_of_streams) * sizeof(int));
+	memset(categories,-1,(number_of_streams) * sizeof(int));
+
+	for (i = 0; cat_list[i] != NULL; ++i) {
+		cat = atoi(cat_list[i]);
+			if (cat < 1 || cat > number_of_streams)
+		G_fatal_error(_
+			("Stream categories must be > 0 and < maximum stream category"));
+		categories[cat] = cat;
+  }
+		}
+   G_message("Finding nodes...");
+   outlets = (OUTLET *) G_malloc((out_max) * sizeof(OUTLET));
+   outlets_num = 0;
+
+		   for (r = 0; r < nrows; ++r) 
+		for (c = 0; c < ncols; ++c) {
+
+	segment_get(streams,&streams_cell,r,c);
+	if (streams_cell>0) {
+
+			if (outlets_num > 2 * (out_max - 1))
+		G_fatal_error
+				("Stream and direction maps probably do not match");
+			if (outlets_num > (out_max - 1))
+		outlets = (OUTLET *)G_realloc(outlets,out_max*2*sizeof(OUTLET));
+
+		segment_get(dirs,&dirs_cell,r,c);
+		d = abs(dirs_cell);	/* abs */
+
+			if (NOT_IN_REGION(d))
+		next_stream = -1;	/* border */
+			else {
+		segment_get(streams,&streams_next_cell,NR(d),NC(d));
+		next_stream = (streams_next_cell > 0) ? streams_next_cell : -1;
+			}
+
+			if (d == 0)
+		next_stream = -1;
+
+		cur_stream = streams_cell;
+
+	if (lasts) {
+
+		if (next_stream < 0) {	/* is outlet! */
+				if (categories)
+			if (categories[cur_stream] == -1) /* but not in list */
+		continue;
+
+		outlets[outlets_num].r = r;
+		outlets[outlets_num].c = c;
+		outlets[outlets_num].val = 	  
+			(cats) ? outlets_num + 1 : cur_stream;
+		outlets_num++;
+		    }
+	} else { /* not lasts */
+
+		if (cur_stream != next_stream) {	/* is outlet or node! */
+				if (categories)
+			if (categories[cur_stream] == -1) /* but not in list */
+		continue;
+		
+		outlets[outlets_num].r = r;
+		outlets[outlets_num].c = c;
+		outlets[outlets_num].val =
+		    (cats) ? outlets_num + 1 : cur_stream;
+		outlets_num++;
+		  }
+	}		/* end if else lasts */
+	  }			/* end if streams */
+			} /* end for */
+    return outlets_num;
+}
+
+
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/io.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/io.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/io.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,523 @@
+#include "io.h"
+/* all in ram functions section */
+
+int ram_create_map(MAP* map, RASTER_MAP_TYPE data_type) {
+	
+	/* 
+	 * allocates 0 filled nrows*ncols map of type void;
+	 * map parameters are stored in structure;
+	 * map: map to be created;
+	 * map type to be created must be CELL, FCELL, DCELL;
+	 * */
+		
+	int r, c;
+		
+		if(data_type < 0 || data_type > 2)
+	G_fatal_error(_("ram_creat: Cannot create map of unrecognised type"));
+	
+	map->data_type=data_type;
+	map->map_name=NULL;
+	map->nrows = Rast_window_rows();
+  map->ncols = Rast_window_cols();
+  map->data_size=Rast_cell_size(data_type);
+
+/* preparing internal map */
+	switch (map->data_type) { 
+		case CELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(CELL *));
+			break;
+
+		case FCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(FCELL *));
+			break;
+		
+		case DCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(DCELL *));
+			break;
+	}
+
+		for (r = 0; r < map->nrows; ++r)
+	(map->map)[r] = G_calloc(map->ncols,map->data_size);	
+	
+	return 0;
+}
+
+int ram_read_map(MAP* map, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+/*
+ * Funciton read external map and put it in MAP structure (created with create_map)
+ * map: map to be read can be of any data type, read map is converted to target map if neccesary.
+ * input_map_name: name of the map to be read;
+ * map pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+
+	int r, c;
+  char *mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+  int input_map_fd;
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+  void* input_buffer=NULL;
+  void* input_pointer;
+
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+	    if (mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), input_map_name);
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+  Rast_get_cellhd(input_map_name, mapset, &cellhd);
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || 
+			this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+	/* checking if input map is of required type */
+		if(check_data_type != map->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1)
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+
+  input_map_fd  = Rast_open_old(input_map_name, mapset);
+  input_data_size = Rast_cell_size(input_data_type);
+	
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	map->min=(double)min;
+	map->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(map->min), &(map->max));
+		}
+}
+/* end opening and checking */
+
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+  /* start reading */
+  G_message(_("Reading map <%s>"),input_map_name);
+
+			for (r = 0; r < map->nrows; ++r) {
+					G_percent(r, map->nrows, 2);
+
+			Rast_get_row(input_map_fd, input_buffer, r,input_data_type);
+			input_pointer=input_buffer;
+
+						for (c = 0; c < map->ncols; ++c)
+					if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type))
+				switch (map->data_type) {
+					case CELL_TYPE:
+						((CELL**)map->map)[r][c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL**)map->map)[r][c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL**)map->map)[r][c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("ram_open:Wrong internal data type"));
+						break;
+				}
+			}		/*end for r */
+
+  G_free(input_buffer);
+	G_percent(r, map->nrows, 2);
+	Rast_close(input_map_fd);
+  return 0;
+}				/* end create floating point map */
+
+int ram_reset_map(MAP* map, int value) {
+ /*
+	* set all cells in the map to value
+	*/
+	int r;
+
+		for (r=0;r<map->nrows;++r) 
+	memset((map->map)[r],value,map->ncols*map->data_size);
+	return 0;
+}
+
+int ram_write_map(MAP* map, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write map to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */
+	
+  int r, c;
+  int output_fd = 0;
+  struct History history;
+  void* row;
+
+	/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = map->data_type;
+
+		if(output_data_type != map->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+  
+  G_message(_("Writing map <%s>"),output_map_name);
+  output_fd = Rast_open_new(output_map_name, output_data_type);
+		
+		/* writing */
+		for (r = 0; r < map->nrows; ++r) {
+			G_percent(r, map->nrows, 2);
+					
+					if(convert_to_null) {
+			row = map->map[r];
+				switch (map->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((CELL*)row)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(map->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((FCELL*)row)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(map->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((DCELL*)row)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(map->data_size), 1);
+				break;
+			default: 
+					G_debug(1,"ram_null:Cannot convert to null at: %d %d",r,c);
+					}
+				}
+		
+	Rast_put_row(output_fd, (map->map)[r], output_data_type);
+		}
+	G_percent(r, map->nrows, 2);	
+  Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("<%s> Done"), output_map_name);
+  return 0;
+}
+
+int ram_release_map (MAP* map) {
+	/* 
+	 * free memory allocated for map, set pointer to null;
+	 */ 
+	 int r;
+
+			for (r = 0; r < map->nrows; ++r)
+		G_free((map->map)[r]);
+  G_free(map->map);
+  map=NULL;
+  return 0;
+}
+
+
+/* memory swap functions section */
+
+
+int seg_create_map(SEG * seg, int srows, int scols, int number_of_segs, RASTER_MAP_TYPE data_type) {
+	/* create segment  and returns pointer to it;
+	 * seg must be declared first;
+	 * parameters are stored in structure;
+	 * seg: segment to be created;
+	 * srows, scols segment size
+	 * number of segs max number of segs stored in memory
+	 * data_type to be created must be CELL, FCELL, DCELL;
+	 */
+
+	char* filename;
+	int fd;
+	int local_number_of_segs;
+
+	seg->fd=-1;
+	seg->filename = NULL;
+	seg->map_name = NULL;
+	seg->mapset = NULL;
+	seg->data_type = data_type;
+	seg->nrows = Rast_window_rows();
+	seg->ncols = Rast_window_cols();
+
+	local_number_of_segs=(seg->nrows/srows+1)*(seg->ncols/scols+1);
+	number_of_segs=(number_of_segs>local_number_of_segs) ?
+		local_number_of_segs : number_of_segs;
+	
+	G_debug(3,"seg_creat:number of segments %d",number_of_segs);
+	
+	switch (seg->data_type) {
+		case CELL_TYPE:
+			seg->data_size=sizeof(CELL);
+			break;
+		case FCELL_TYPE:
+			seg->data_size=sizeof(FCELL);
+			break;
+		case DCELL_TYPE:
+			seg->data_size=sizeof(DCELL);
+			break;
+		default:
+		G_fatal_error(_("seg_create: unrecognisabe data type"));
+	}
+	
+	filename=G_tempfile();
+	fd=creat(filename,0666);
+	
+	if(0 > segment_format(fd,seg->nrows,seg->ncols,srows,scols,seg->data_size)) {
+		close(fd);
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot format segment"));
+	}
+	
+	close(fd);
+	if(0 > (fd = open(filename,2))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot re-open file"));
+	}
+	
+	if(0>(fd = segment_init(&(seg->seg),fd,number_of_segs))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot init segment file or out of memory"));
+	}
+	
+	seg->filename = G_store(filename);
+	seg->fd = fd;
+	return 0;
+}
+
+int seg_read_map(SEG* seg, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+	
+/*
+ * Funciton read external map and put it in SEG structure (created with seg_create_map)
+ * map to be read can be of any data type, read map is converted if neccesary.
+ * input_map_name: name of the map to be read;
+ * seg: pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+	
+	int input_fd;
+	int r,c;
+	char* mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+	void* input_buffer=NULL;
+	void* target_buffer=NULL;
+	void* input_pointer=NULL;
+	
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+    if (mapset == NULL)
+	G_fatal_error(_("seg_read:Raster map <%s> not found"), input_map_name);
+	seg->mapset=mapset;
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+	Rast_get_cellhd(input_map_name, mapset, &cellhd);
+	
+	/* check resolution equal anyinteger check;  equal 0 no check*/
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+		if(check_data_type != seg->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1) 
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+	
+	input_fd = Rast_open_old(input_map_name,mapset);
+	input_data_size = Rast_cell_size(input_data_type);
+
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	seg->min=(double)min;
+	seg->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(seg->min), &(seg->max));
+		}
+}
+
+	/* end opening and checking */
+	
+	G_message(_("Reading map <%s>"),input_map_name);
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+	target_buffer=Rast_allocate_buf(seg->data_type); 
+
+		for (r=0; r<seg->nrows; ++r) {
+			G_percent(r, seg->nrows, 2);
+			Rast_get_row(input_fd,input_buffer,r,input_data_type);
+			input_pointer=input_buffer;
+			memset(target_buffer,0,seg->ncols*seg->data_size);
+
+							for (c = 0; c < seg->ncols; ++c) 
+						if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type)) {
+				switch (seg->data_type) {
+					case CELL_TYPE:
+						((CELL*)target_buffer)[c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL*)target_buffer)[c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL*)target_buffer)[c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("Wrong internal data type"));
+						break;
+				}
+					}
+
+		if(0>segment_put_row(&(seg->seg),target_buffer,r)) {
+			G_free(input_buffer);
+			G_free(target_buffer);
+			Rast_close(input_fd);
+			G_fatal_error(_("seg_read: Cannot segment put row %d for map %s"),
+				r,input_map_name);
+				}
+	} /* end for row */
+		
+	G_percent(r, seg->nrows, 2);
+	Rast_close(input_fd);
+	G_free(input_buffer);
+	G_free(target_buffer);
+	
+	seg->map_name=G_store(input_map_name);
+	seg->mapset=G_store(mapset);
+	
+	return 0;
+}
+
+int seg_reset_map (SEG* seg, int value) {
+	/*
+	* set all cells in the map to value
+	*/
+int r,c;
+    for (r=0;r<seg->nrows;++r)
+  for (c=0;c<seg->ncols;++c)
+segment_put(&(seg->seg),&value,r,c);
+ }
+
+int seg_write_map(SEG* seg, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write seg to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */	
+	int output_fd;
+	int r, c;
+	void* output_buffer;
+	void* row;
+	struct History history;
+	
+		/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = seg->data_type;
+
+		if(output_data_type !=  seg->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+	
+	G_message(_("Writing map <%s>"),output_map_name);
+	output_fd=Rast_open_new(output_map_name,output_data_type);
+	output_buffer=Rast_allocate_buf(output_data_type);
+	segment_flush(&(seg->seg));
+	
+	/* writing */
+		for(r=0;r<seg->nrows;++r) {
+
+	G_percent(r, seg->nrows, 2);
+		if(0>segment_get_row(&(seg->seg),output_buffer,r)) 
+	G_warning(_("seg_write: Cannot segment read row %d for map %s"),
+		r,output_map_name);
+
+		if(convert_to_null) {
+
+				row = output_buffer;
+				switch (seg->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((CELL*)output_buffer)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(seg->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((FCELL*)output_buffer)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(seg->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((DCELL*)output_buffer)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(seg->data_size), 1);
+				break;
+			default: 
+					G_warning(_("ram_null:Cannot convert to null at: %d %d"),r,c);
+				}
+		}
+	Rast_put_row(output_fd, output_buffer, output_data_type);
+		}	
+
+	G_percent(r, seg->nrows, 2);
+	G_free(output_buffer);
+	Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("%s Done"), output_map_name);
+	
+	return 0;
+}
+
+int seg_release_map(SEG* seg) {
+/* 
+ * release segment close files, set pointers to null;
+ */ 
+	segment_release(&(seg->seg));
+	close(seg->fd);
+	unlink(seg->filename);
+
+		if(seg->map_name)
+	G_free(seg->map_name);
+		if(seg->mapset)
+	G_free(seg->mapset);
+
+return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/io.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/io.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/io.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/segment.h>
+
+#define NOT_IN_REGION(x) (r+nextr[(x)] < 0 || r+nextr[(x)] > (nrows-1) || c+nextc[(x)] < 0 || c+nextc[(x)] > (ncols-1))
+#define NR(x) r + nextr[(x)]
+#define NC(x) c + nextc[(x)]
+#define INDEX(r,c) (r)*ncols+(c)
+#define DIAG(x) (((x) + 4) > 8 ? ((x) - 4) : ((x) + 4));
+
+#define SROWS 256
+#define SCOLS 256
+
+typedef struct {
+	void** map; /* matrix of data */
+	double min, max; /* data range : may requre casting */
+	int nrows, ncols;
+	char* map_name; /* map name, unused */
+	RASTER_MAP_TYPE data_type; /* type of data */
+	size_t data_size; /* type of data */
+} MAP;
+
+typedef struct {
+	SEGMENT seg;		/* segmented data store */
+	int fd;					/* segment temporary file name descriptor */
+	char* filename; /* segment temporary file name */
+	char* map_name; /* map name converted to segment */
+	char* mapset;
+	int nrows, ncols; /* store nrows and rcols */
+	RASTER_MAP_TYPE data_type; /* data type of the map */
+	size_t data_size; /* size of cell returned by sizeof */
+	double min, max; /* data range */
+} SEG;
+
+
+/* all in ram functions */
+int ram_create_map(MAP*, RASTER_MAP_TYPE);
+int ram_read_map	(MAP* , char*, int, RASTER_MAP_TYPE);
+int ram_reset_map	(MAP*, int);
+int ram_write_map	(MAP*, char*, RASTER_MAP_TYPE, int, double);
+int ram_destory_map(MAP*);
+
+/* memory swap functions */
+int seg_create_map(SEG*, int, int, int, RASTER_MAP_TYPE);
+int seg_read_map	(SEG*, char*, int, RASTER_MAP_TYPE);
+int seg_reset_map (SEG*, int);
+int seg_write_map	(SEG*, char*, RASTER_MAP_TYPE, int, double);
+int seg_release_map(SEG*);
+

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/local_proto.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,3 @@
+#include "io.h"
+#include "local_vars.h"
+

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/local_vars.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/local_vars.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/local_vars.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+
+#ifdef MAIN
+#  define GLOBAL
+#else
+#  define GLOBAL extern
+#endif
+
+typedef struct {
+	int r,c;
+	int val;
+} OUTLET;
+
+typedef struct {
+	int r,c;
+	} POINT;
+
+GLOBAL int nextr[9];
+GLOBAL int nextc[9];
+
+GLOBAL OUTLET* outlets;
+GLOBAL OUTLET* border_outlets;
+GLOBAL int* categories;
+GLOBAL int nrows, ncols;
+GLOBAL int fifo_max;
+GLOBAL POINT* fifo_points;
+
+
+
+
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/main.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/main.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/main.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,251 @@
+/****************************************************************************
+ *
+ * MODULE:       r.stream.basins
+ * AUTHOR(S):    Jarek Jasiewicz jarekj amu.edu.pl
+ *               
+ * PURPOSE:      Calculate basins according user' input data.
+ *               It uses multiple type of inputs:
+ * 							 r.stream.order, r.stream.extract or r.watershed stream  map 
+ *               list of categoires to create basins (require stream map);
+ *               vector file containing outputs;
+ *               list of coordinates;
+ *               with analogous  direction map;
+ *
+ * COPYRIGHT:    (C) 2002,2010 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.
+ *
+ *****************************************************************************/
+#define MAIN
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int nextr[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
+int nextc[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
+
+int main(int argc, char *argv[])
+{
+	
+	struct GModule *module;	
+  struct Option *in_dir_opt, 
+								*in_coor_opt, 
+								*in_stm_opt, 
+								*in_stm_cat_opt, 
+								*in_point_opt, 
+								*opt_basins,
+								*opt_swapsize;	
+
+  struct Flag 	*flag_zerofill, 
+								*flag_cats, 
+								*flag_lasts,
+								*flag_segmentation;
+  
+  int b_test = 0;		/* test which option have been choosed: like chmod */
+  int segmentation, zerofill, lasts, cats;
+  int i, outlets_num;
+  int max_number_of_streams;
+      
+  G_gisinit(argv[0]);
+
+  module = G_define_module();
+  module->description = _("Delineate basins according user' input. \
+	Input can be stream network, point file with outlets or outlet coordinates");
+	G_add_keyword("basins creation");
+	
+	in_dir_opt = G_define_standard_option(G_OPT_R_INPUT);	/* input directon file */
+  in_dir_opt->key = "dirs";
+  in_dir_opt->description = _("Name of flow direction input map");
+  
+  in_coor_opt = G_define_option();	/* input coordinates de outlet */
+  in_coor_opt->key = "coors";
+  in_coor_opt->type = TYPE_STRING;
+  in_coor_opt->key_desc = "x,y";
+  in_coor_opt->answers = NULL;
+  in_coor_opt->required = NO;
+  in_coor_opt->multiple = YES;
+  in_coor_opt->description = _("Basin's outlet's coordinates: E,N");
+  
+  in_stm_opt = G_define_standard_option(G_OPT_R_INPUT);	/* input stream file file */
+  in_stm_opt->key = "streams";
+  in_stm_opt->required = NO;
+  in_stm_opt->description = _("Name of stream mask input map");
+  
+  in_stm_cat_opt = G_define_option();	/* input stream category - optional */
+  in_stm_cat_opt->key = "cats";
+  in_stm_cat_opt->type = TYPE_STRING;
+  in_stm_cat_opt->required = NO;
+  in_stm_cat_opt->description = _("Create basins only for these categories:");
+  
+  in_point_opt = G_define_standard_option(G_OPT_V_INPUT);	/* input point outputs - optional */
+  in_point_opt->key = "points";
+  in_point_opt->required = NO;
+  in_point_opt->description = _("Name of vector points map");
+  
+  opt_swapsize = G_define_option();
+	opt_swapsize->key="memory";
+	opt_swapsize->type = TYPE_INTEGER;
+	opt_swapsize->answer = "300";
+	opt_swapsize->description =_("Max memory used in memory swap mode (MB)");
+	opt_swapsize->guisection=_("Optional");	
+  
+  opt_basins = G_define_standard_option(G_OPT_R_OUTPUT);
+  opt_basins->key = "basins";
+  opt_basins->description = _("Output basin map");  
+	
+	/*flags */
+  flag_zerofill = G_define_flag();
+  flag_zerofill->key = 'z';
+  flag_zerofill->description = _("Create zero-value background instead of NULL");
+
+  flag_cats = G_define_flag();
+  flag_cats->key = 'c';
+  flag_cats->description =
+	_("Use unique category sequence instead of input streams");
+
+  flag_lasts = G_define_flag();
+  flag_lasts->key = 'l';
+  flag_lasts->description = _("Create basins only for last stream links");
+  
+  flag_segmentation = G_define_flag();
+  flag_segmentation->key = 'm';
+  flag_segmentation->description = _("Use memory swap (operation is slow)");
+
+    if (G_parser(argc, argv))	/* parser */
+	exit(EXIT_FAILURE);
+
+  zerofill = (flag_zerofill->answer == 0);
+  cats = (flag_cats->answer != 0);
+  lasts = (flag_lasts->answer != 0);
+  segmentation=(flag_segmentation->answer != 0);
+   
+    if (!in_coor_opt->answers && !in_stm_opt->answer && !in_point_opt->answer)
+	G_fatal_error(_("One basin's outlet definition is required"));
+
+	  if (in_stm_cat_opt->answers && !in_stm_opt->answer)
+	G_fatal_error(_("With cats, stream file is required"));
+
+		if (in_coor_opt->answers)
+	b_test += 1;
+    if (in_stm_opt->answer)
+	b_test += 2;
+    if (in_point_opt->answer)
+	b_test += 4;
+
+	  if (b_test != 1 && b_test != 2 && b_test != 4)
+	G_fatal_error("Only one outlet definition is allowed");
+	
+	nrows = Rast_window_rows();
+  ncols = Rast_window_cols();
+  
+     if (G_legal_filename(opt_basins->answer) < 0)
+	G_fatal_error(_("<%s> is an illegal basin name"), opt_basins->answer);
+	
+	
+	/* ALL IN RAM VERSION */	
+if (!segmentation) {
+	MAP map_dirs, map_streams, map_basins;
+	CELL **streams=NULL, **dirs, **basins;
+	
+	G_message("ALL IN RAM CALCULATION");
+	
+	ram_create_map(&map_dirs,CELL_TYPE);
+	ram_read_map(&map_dirs,in_dir_opt->answer,1,CELL_TYPE);
+	dirs=(CELL**)map_dirs.map;
+
+		
+	  switch (b_test) {
+    case 1:
+	G_message("Calculate basins using coordinates...");
+	outlets_num = process_coors(in_coor_opt->answers);
+	break;
+
+    case 2:
+	G_message("Calculate basins using streams...");
+	ram_create_map(&map_streams,CELL_TYPE);
+	ram_read_map(&map_streams,in_stm_opt->answer,1,CELL_TYPE);
+	streams=(CELL**)map_streams.map;
+	max_number_of_streams=(int)map_streams.max+1;
+	outlets_num=ram_process_streams(in_stm_cat_opt->answers,
+		streams, max_number_of_streams, dirs,lasts,cats);
+	ram_release_map (&map_streams);
+	break;
+
+    case 4:
+	G_message("Calculate basins using point file...");
+	outlets_num = process_vector(in_point_opt->answer);
+	break;
+    }
+
+	ram_create_map(&map_basins,CELL_TYPE);
+	basins=(CELL**)map_basins.map;
+	ram_add_outlets(basins, outlets_num);	
+	fifo_max = 4 * (nrows + ncols);
+	fifo_points = (POINT *) G_malloc((fifo_max + 1) * sizeof(POINT));
+
+		for (i = 0; i < outlets_num; ++i) 
+	ram_fill_basins(outlets[i],basins,dirs);
+	
+	G_free(fifo_points);
+	ram_write_map	(&map_basins, opt_basins->answer, CELL_TYPE, zerofill, 0);
+	ram_release_map (&map_dirs);
+	ram_release_map (&map_basins);
+	
+} /* end ram */
+
+	/* SEGMENT VERSION */	
+
+if (segmentation) {
+	SEG map_dirs, map_streams, map_basins;
+	SEGMENT *streams=NULL, *dirs, *basins;
+	int number_of_segs;
+
+	G_message("MEMORY SWAP CALCULATION: MAY TAKE SOME TIME!");
+	
+	number_of_segs = (int)atof(opt_swapsize->answer);
+	number_of_segs < 32 ? (int)(32/0.12) : number_of_segs/0.12;
+	
+	seg_create_map(&map_dirs,SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	seg_read_map(&map_dirs,in_dir_opt->answer,1,CELL_TYPE);
+	dirs = &map_dirs.seg;
+	
+	switch (b_test) {
+    case 1:
+	G_message("Calculate basins using coordinates...");
+	outlets_num = process_coors(in_coor_opt->answers);
+	break;
+
+    case 2:
+	G_message("Calculate basins using streams...");
+	seg_create_map(&map_streams,SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	seg_read_map(&map_streams,in_stm_opt->answer,1,CELL_TYPE);
+	streams = &map_streams.seg;
+	max_number_of_streams=(int)map_streams.max+1;
+	outlets_num=seg_process_streams(in_stm_cat_opt->answers,
+		streams,max_number_of_streams,dirs,lasts,cats);
+	seg_release_map (&map_streams);
+	break;
+
+    case 4:
+	G_message("Calculate basins using point file...");
+	outlets_num = process_vector(in_point_opt->answer);
+	break;
+    }
+    
+	seg_create_map(&map_basins, SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	basins=&map_basins.seg,
+	seg_add_outlets(basins, outlets_num);	
+	fifo_max = 4 * (nrows + ncols);
+	fifo_points = (POINT *) G_malloc((fifo_max + 1) * sizeof(POINT));
+
+		for (i = 0; i < outlets_num; ++i) 
+	seg_fill_basins(outlets[i],basins, dirs);
+	G_free(fifo_points);
+	seg_write_map	(&map_basins, opt_basins->answer, CELL_TYPE, zerofill, 0);
+	seg_release_map (&map_dirs);
+	seg_release_map (&map_basins); 
+}
+
+exit(EXIT_SUCCESS);	
+	}

Added: grass-addons/grass7/raster/r.stream/r.stream.basins/r.stream.basins.html
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.basins/r.stream.basins.html	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.basins/r.stream.basins.html	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,115 @@
+<h2>OPTIONS</h2>
+<DL>
+<DT><b>-z</b></DT>
+<DD>Creates zero-value background instead of NULL. For some reason (like map algebra calculation) zero-valued background may be required. This flag produces zero-filled background instead of null (default).</DD>
+<DT><b>-c</b></DT>
+<DD>By default r.stream.basins uses streams category as basin category. In some cases - for example if stream map is product of map algebra and separete streams may not have unique values this option will create new category sequence for each basin (do not work in vector point mode)
+</DD>
+<DT><b>-l</b></DT>
+<DD>By default r.stream.basins create basins for all unique streams. This option delinate basins only for last streams ignoring upstreams (do not work in vector point mode).
+</DD>
+
+<DT><b>dirs</b></DT>
+<DD>Flow direction: name of input direction map produced by r.watershed or r.stream.extract. If r.stream.extract output map is used, it only has non-NULL values in places where streams occur. NULL (nodata) cells are ignored, zero and negative values are valid direction data if they vary from -8 to 8 (CCW from East in steps of 45 degrees). Direction map shall be of type CELL values. Region resolution and map resoultion must be the same. 
+Also <em>stream</em> network map (if used) and direction map must have the same resolution. It is checked by default. If resolutions differ the module informs about it and stops. Region boundary and maps boundary may be differ but it may lead to unexpected results.</DD>
+
+<DT><b>coors</b></DT>
+<DD>East and north coordinates for basin outlet. It can delinate only one basin using that option. This option simply copies funcionality of <a href="r.water.outlet.html">r.water.outlet</a>.
+</DD>
+<DT><b>streams</b></DT>
+<DD>Stream network: name of input stream map on which ordering will be performed produced by r.watershed or r.stream.extract. Because streams network produced by r.watershed and r.stream.extract may slighty differ in detail it is required to use both stream and direction map produced by the same module. Stream background shall have NULL value or zero value. Background values of NULL are by default produced by r.watershed and r.stream.extract. If not 0 or NULL use <a href="r.mapcalc.html">r.mapcalc</a> to set background values to null.  
+</DD>
+
+<DT><b>cats</b></DT>
+<DD>Stream categories to delineate basins for: All categories which are not in stream map are ignored. It can be used with stream network created by r.watershed, r.stream.extract or r.stream.order. For r.stream.order use category of order for which basins must be created. For example to delineate only basins for order two use cats=2. If you need unique category for every basin use -c flag.
+</DD>
+
+<DT><b>points</b></DT>
+<DD>Vector file containing basins outlet as vector points. Only point's categories are used to prepare basins. Table attached to it is ignored. Every point shall heve his own unique category. In that mode flags -l and -c are ignored
+</DD>
+</DL>
+
+
+<h2>OUTPUTS</h2>
+<P>The module produces one raster map with basins acording user's rules</p>
+
+
+<h2>DESCRIPTION</h2>
+
+Module r.stream.basins is prepared to delineate basins and subasins with different input data. Module is prepared to delineate unrestricted number of basins in one step. It can delineate basins with three methods:
+<UL>
+<LI>Using coordinates: his option simply copies funcionality of <a href="r.water.outlet.html">r.water.outlet</a>.
+<LI>Using vector points: it allow to mannually point outlets with any method
+<LI>Using streams (most advanced) it allow on lots of modifications. See examples for more details.
+</UL>
+Only one method can be used at once. Methods cannot be mixed.
+<P>
+The most recommended method require two maps: direction and streams. In spite of in stream map we can store information required to proper delineation, we can also enumarate stream categories for which basins are to be created (cats option). Module is prepared to work with output data of <em>r.watershed, r.stream.extract, r.stream.order</em> also with modification done by <em>r.recalss</em> and <em>r.mapcalc</em>. r.stream.basin can delineate basins according outlets marked by raster streams, and polygons, vector points and numerical coordinates. If outlets are marked by points or coordinates it delineate basins which cells contribute to that points, if outlets are marked by streams it delineate cells which contribute to the last (downstream) cell of the every stream. If outlets are marked by polygon it delineate cells contributing to most downstream cell of the polygon. If polygon covers more outlets than of one basins it will create collective basin for all outlets  with c
 ommon category.
+
+
+<h2>NOTES</h2>
+<P>
+To receive good results outlets markers created by user shall overlapping with streams. On the other way basins could results with very small area. Input maps must be in CELL format (default output of r.watershed, r.stream.order  and r.stream.extract)<P>
+Module can work only if direction map, stream map and region map has same settings. It is also required that stream map and direction map come from the same source. For lots of reason this limitation probably cannot be omitted.   this means if stream map comes from r.stream.extract also direction map from r.stream.extract must be used. If stream network was generated with MFD method also MFD direction map must be used. Nowadays f direction map comes from r.stream.extract  must be patched by direction map from r.watershed. (with r.patch). 
+
+<h2>EXAMPLES</h2>
+<P>
+To delineate all basins with categories of streams:
+<P>
+<CODE>r.stream.basins dir=dirs stream=streams basins=bas_basins_elem</CODE>
+<P>
+To determine major and minor basins in area, definied by outlets, ignoring subbasins use  - l flag. That flag ignores all nodes and uses only real outlets (in most cases that on map border):
+<P>
+<CODE>r.stream.basins -l dir=dirs stream=streams basins=bas_basins_last</CODE>
+
+<P>
+<CODE>r.stream.basins dir=dirs coors=639936.623832,216939.836449</CODE>
+
+<P>
+To delineate one or more particular basins defined by given streams, add simply stream categories:
+<CODE>
+r.stream.basins -lc dirs=dirs streams=streams cats=2,7,184 basins=bas_basin
+</CODE>
+
+<P>
+Do delineate basins of particular order we must use the following procedure: 
+
+<CODE>
+r.stream.basins -lc dirs=dirs streams=strahler cats=2 basins=bas_basin_strahler_2
+</CODE>
+
+<P>
+The usage of polygons as outlets markers is very useful when exact stream course cannot be cleary determined before running analysis, but the area of its occurrence can be determined (mostly in iterative simulations) Example uses r.circle but can be substituted by any polygon created for example  with v.digit:
+<CODE>
+r.circle -b output=circle coordinate=639936.623832,216939.836449 max=200
+r.stream.basins -c dirs=dirs streams=circle basins=bas_simul
+</CODE>
+<P>
+To determine areas of contribution to streams of particular order  use as streams the result of ordering:
+<P>
+<CODE>r.stream.basins dirs=dirs streams=ord_strahler basins=bas_basin_strahler</CODE>
+<P>
+Determination of areas of potential source of pollution. The example will be done for lake marked with FULL_HYDR 8056 in North Carolina sample dataset. The lake shall be extracted and converted to binary raster map.
+
+<CODE>
+v.extract -d input=lakes at PERMANENT output=lake8056 type=area layer=1 'where=FULL_HYDRO = 8056' new=-1 
+v.to.rast input=lake8056 output=lake8056 use=val type=area layer=1 value=1
+r.stream.basins dirs=dirs streams=lake8056 basins=bas_basin_lake
+</CODE>
+<P>
+See aslo tutorial: <a href="http://grass.osgeo.org/wiki/R.stream.*">http://grass.osgeo.org/wiki/R.stream.*</a>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.watershed.html">r.watershed</a>,
+<a href="r.stream.extract.html">r.stream.extract</a>,
+<a href="r.stream.order.html">r.stream.order</a>,
+<a href="r.stream.stats.html">r.stream.stats</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+<a href="r.reclass.html">r.reclass</a>,
+<a href="r.patch.html">r.patch</a>
+</em>
+
+<h2>AUTHOR</h2>
+Jarek Jasiewicz, Adam Mickiewicz University, Geoecology and Geoinformation Institute.

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/Makefile
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/Makefile	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/Makefile	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.stream.distance
+
+LIBES = $(GISLIB) $(RASTERLIB) $(SEGMENTLIB)
+DEPENDENCIES = $(GISDEP) $(RASTERDEP) $(SEGMENTDEP) $(VECTDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
+

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/distance_calc.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/distance_calc.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/distance_calc.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,594 @@
+#include "local_proto.h"
+static int tail, head, fifo_count;
+
+int fifo_insert(POINT point)
+{
+    if (fifo_count == fifo_max)
+	G_fatal_error("fifo queue: circular buffer too small");
+
+    fifo_points[tail++] = point;
+    if (tail > fifo_max) {
+	G_debug(1, "tail > fifo_max");
+	tail = 0;
+    }
+    fifo_count++;
+    return 0;
+}
+
+POINT fifo_return_del(void)
+{
+    if (head >= fifo_max) {
+	G_debug(1, "head >= fifo_max");
+	head = -1;
+    }
+    fifo_count--;
+	
+    return fifo_points[++head];
+}
+
+
+int ram_calculate_downstream (CELL** dirs, FCELL** distance, FCELL** elevation, OUTLET outlet, int outs) {
+	
+	int r, c,  i, j;
+	int next_r,next_c;
+  POINT n_cell;
+  float cur_dist = 0;
+  float tmp_dist = 0;
+  float target_elev;		/* eleavation at stream or outlet */
+  float easting, northing;
+  float cell_easting, cell_northing;
+  struct Cell_head window;
+  
+  Rast_get_window(&window);
+
+  tail = 0;
+  head = -1;
+  r = outlet.r;
+  c = outlet.c;
+
+    if (elevation) {
+	target_elev = elevation[r][c];
+	elevation[r][c] = 0.;
+    }
+
+    while (tail != head) {
+	easting = window.west + (c + .5) * window.ew_res;
+	northing = window.north - (r + .5) * window.ns_res;
+
+	for (i = 1; i < 9; ++i) {
+
+			if (NOT_IN_REGION(i))
+		continue;	/* border */
+
+	j = DIAG(i);
+	next_r=NR(i);
+	next_c=NC(i);
+  if (dirs[NR(i)][NC(i)] == j) {	/* countributing cell, reset distance and elevation */
+		
+		if (outs) {	/* outlet mode */
+
+				if (distance[NR(i)][NC(i)] == 0) 
+			continue;	/* continue loop, point is not added to the queue! */
+				else {
+			cell_northing = window.north - (next_r +.5) * window.ns_res;
+			cell_easting =  window.west +  (next_c +.5) * window.ew_res;
+			cur_dist = tmp_dist + 
+				G_distance(easting,northing,cell_easting,cell_northing);
+			distance[NR(i)][NC(i)] = cur_dist;
+				}
+
+		}	else {		/* stream mode */
+		    
+		  if (distance[next_r][next_c] == 0) {
+				cur_dist = 0;
+					if (elevation)
+			  target_elev =	elevation[next_r][next_c];
+		  } else {
+			cell_northing = window.north - (next_r +.5) * window.ns_res;
+			cell_easting =  window.west +  (next_c +.5) * window.ew_res;
+			cur_dist = tmp_dist + 
+				G_distance(easting,northing,cell_easting,cell_northing);
+			distance[NR(i)][NC(i)] = cur_dist;
+		    }
+		}		/* end stream mode */
+
+		if (elevation) {
+		  elevation[next_r][next_c] =
+				elevation[next_r][next_c] - target_elev;
+		  n_cell.target_elev = target_elev;
+		}
+
+		n_cell.r = next_r;
+		n_cell.c = next_c;
+		n_cell.cur_dist = cur_dist;
+		fifo_insert(n_cell);
+	    }
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+	tmp_dist = n_cell.cur_dist;
+	target_elev = n_cell.target_elev;
+
+    }				/* end while */
+  return 0;
+}
+
+int seg_calculate_downstream (SEGMENT* dirs, SEGMENT* distance, SEGMENT* elevation, OUTLET outlet, int outs) {
+	
+	int r, c,  i, j;
+	int next_r, next_c;
+  POINT n_cell;
+  float cur_dist = 0;
+  float tmp_dist = 0;
+  float target_elev;		/* eleavation at stream or outlet */
+  float easting, northing;
+  float cell_easting, cell_northing;
+  CELL dirs_cell;
+  FCELL distance_cell, elevation_cell;
+  FCELL zero_cell=0;
+  struct Cell_head window;
+  
+  Rast_get_window(&window);
+
+  tail = 0;
+  head = -1;
+  r = outlet.r;
+  c = outlet.c;
+
+    if (elevation) {
+	segment_get(elevation,&target_elev,r,c);
+	segment_put(elevation,&zero_cell,r,c);
+    }
+
+    while (tail != head) {
+	easting = window.west + (c + .5) * window.ew_res;
+	northing = window.north - (r + .5) * window.ns_res;
+
+	for (i = 1; i < 9; ++i) {
+
+			if (NOT_IN_REGION(i))
+		continue;	/* border */
+
+	  j = DIAG(i);
+	  next_r=NR(i);
+	  next_c=NC(i);
+	    
+		segment_get(dirs,&dirs_cell,next_r,next_c);
+		if (dirs_cell == j) {	/* countributing cell, reset distance and elevation */
+		
+		if (outs) {	/* outlet mode */
+			segment_get(distance,&distance_cell,next_r,next_c);
+				if (distance_cell == 0) 
+			continue;	/* continue loop, point is not added to the queue! */
+				else {
+			cell_northing = window.north - (next_r +.5) * window.ns_res;
+			cell_easting =  window.west +  (next_c +.5) * window.ew_res;
+			cur_dist = tmp_dist + 
+				G_distance(easting,northing,cell_easting,cell_northing);
+			segment_put(distance,&cur_dist,next_r,next_c);
+			
+				}
+
+		}	else {		/* stream mode */
+		  segment_get(distance,&distance_cell,next_r,next_c);  
+					if (distance_cell == 0) {
+				cur_dist = 0;
+					if (elevation)
+			  segment_get(elevation,&target_elev,next_r,next_c);
+					} else {
+			cell_northing = window.north - (next_r +.5) * window.ns_res;
+			cell_easting =  window.west +  (next_c +.5) * window.ew_res;
+			cur_dist = tmp_dist + 
+				G_distance(easting,northing,cell_easting,cell_northing);
+			segment_put(distance,&cur_dist,next_r,next_c);
+		    }
+		}		/* end stream mode */
+
+		if (elevation) {
+			segment_get(elevation,&elevation_cell,next_r,next_c);
+			elevation_cell -= target_elev;
+			segment_put(elevation,&elevation_cell,next_r,next_c);
+		  n_cell.target_elev = target_elev;
+		}
+
+		n_cell.r = next_r;
+		n_cell.c = next_c;
+		n_cell.cur_dist = cur_dist;
+		fifo_insert(n_cell);
+	    }
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+	tmp_dist = n_cell.cur_dist;
+	target_elev = n_cell.target_elev;
+
+    }	/* end while */ 
+  return 0;
+}
+
+int ram_fill_basins(OUTLET outlet, FCELL** distance, CELL** dirs)
+{
+/* fill empty spaces with zeros but leave -1 as a markers of NULL */
+  int r, c, i, j;
+  int next_r, next_c;
+  float stop, val;
+  POINT n_cell;
+
+  tail = 0;
+  head = -1;
+  r = outlet.r;
+  c = outlet.c;
+  val = 1;
+  stop = 0;
+
+	distance[r][c] = stop;
+	
+    while (tail != head) {
+	for (i = 1; i < 9; ++i) {
+	    if (NOT_IN_REGION(i))
+		continue;	/* out of border */
+	  
+	  j = DIAG(i);
+	  next_r=NR(i);
+	  next_c=NC(i);
+	 
+	    if (dirs[next_r][next_c] == j) {	/* countributing cell */
+
+		distance[next_r][next_c] =
+		  (distance[next_r][next_c] == stop) ? stop : val;
+		n_cell.r = next_r;
+		n_cell.c = next_c;
+		fifo_insert(n_cell);
+	    }
+	    
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+    }
+
+    return 0;
+}
+
+int seg_fill_basins(OUTLET outlet, SEGMENT* distance, SEGMENT* dirs)
+{
+/* fill empty spaces with zeros but leave -1 as a markers of NULL */
+  int r, c, i, j;
+  int next_r, next_c;
+  float stop, val;
+  POINT n_cell;
+  CELL dirs_cell;
+  FCELL distance_cell;
+
+  tail = 0;
+  head = -1;
+  r = outlet.r;
+  c = outlet.c;
+  val = 1;
+  stop = 0;
+
+	segment_put(distance,&stop,r,c);
+	
+    while (tail != head) {
+
+	for (i = 1; i < 9; ++i) {
+	    if (NOT_IN_REGION(i))
+		continue;	/* out of border */
+	  
+	  j = DIAG(i);
+	  next_r=NR(i);
+	  next_c=NC(i);
+	    
+	  segment_get(dirs,&dirs_cell,next_r,next_c);
+	  
+			if (dirs_cell == j) {	/* countributing cell */
+		
+		segment_get(distance,&distance_cell,next_r,next_c);
+		distance_cell= (distance_cell == stop) ? stop : val;
+		segment_put(distance,&distance_cell,next_r,next_c);
+		n_cell.r = next_r;
+		n_cell.c = next_c;
+		fifo_insert(n_cell);
+	    
+	    }
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+    }
+
+    return 0;
+}
+
+int ram_calculate_upstream(FCELL** distance, CELL** dirs, FCELL** elevation, FCELL** tmp_elevation, int near)
+{
+  int r, c;
+  int next_r, next_c;
+  float easting, northing;
+  float cell_easting, cell_northing;
+  int i, j, k, d;
+  int done;
+  int counter;
+  int n_inits = 0;
+  float cur_dist;
+  POINT *d_inits;
+  float tmp_dist = 0;
+  float target_elev = 0;
+  size_t elevation_data_size;
+	struct Cell_head window;
+	
+	Rast_get_window(&window);
+	
+				if(elevation) {
+		elevation_data_size=Rast_cell_size(FCELL_TYPE);			
+		  for (r = 0; r < nrows; ++r) 
+		memcpy(tmp_elevation[r],elevation[r],ncols*elevation_data_size);
+				}
+				
+    for (r = 0; r < nrows; ++r) 
+	for (c = 0; c < ncols; ++c) {
+
+	    for (i = 1; i < 9; ++i) {
+		if (NOT_IN_REGION(i)) 
+		    continue;	/* out of border */
+
+		j = DIAG(i);
+		next_r=NR(i);
+		next_c=NC(i);
+				if (dirs[next_r][next_c] == j && distance[r][c] != 0) {	/* is contributing cell */
+		  distance[r][c] = -1;
+		  break;
+				}
+	    }
+	  if (distance[r][c] == 1 && dirs[r][c] > 0)
+				n_inits++;
+	  else if (dirs[r][c] > 0)
+				distance[r][c] = -1;
+	}
+
+  d_inits = (POINT *) G_malloc(n_inits * sizeof(POINT));
+
+    k = 0;
+    for (r = 0; r < nrows; ++r) 
+	for (c = 0; c < ncols; ++c) {
+
+	    if (distance[r][c] == 1) {
+		
+		distance[r][c] = 0;
+			if (elevation)
+		elevation[r][c] = 0;
+
+		d=dirs[r][c];
+	
+		if (dirs[NR(d)][NC(d)]<0)
+		    continue;
+		
+		d_inits[k].r = r;
+		d_inits[k].c = c;
+		d_inits[k].cur_dist = 0;
+
+			if (elevation)
+		d_inits[k].target_elev = tmp_elevation[r][c];
+
+		k++;
+	    }
+	}
+
+    counter = n_inits = k;
+
+	G_message("Calculate upstream parameters...");		
+    while (n_inits > 0) {
+	k = 0;
+	G_percent((counter-n_inits),counter,10);
+	for (i = 0; i < n_inits; ++i) {
+	    r = d_inits[i].r;
+	    c = d_inits[i].c;
+	    d=dirs[r][c];
+	    next_r = NR(d);
+	    next_c = NC(d);
+	    tmp_dist = d_inits[i].cur_dist;
+
+	    if (elevation)
+		target_elev = d_inits[i].target_elev;
+
+	  easting = window.west + (c + 0.5) * window.ew_res;
+	  northing = window.north - (r + 0.5) * window.ns_res;
+	  cell_easting = window.west + (next_c + 0.5) * window.ew_res;
+	  cell_northing = window.north - (next_r + 0.5) * window.ns_res;
+
+	  cur_dist =	tmp_dist + 
+			G_distance(easting, northing, cell_easting, cell_northing);
+		
+		
+	    if (near)
+		done = (distance[next_r][next_c] > cur_dist ||
+			distance[next_r][next_c] <=0) ? 1 : 0;
+	    else
+		done = (distance[next_r][next_c] < cur_dist ||
+			distance[next_r][next_c] <=0) ? 1 : 0;
+
+	    if (done) {
+		distance[next_r][next_c] = cur_dist;
+			if (elevation) {
+		elevation[next_r][next_c] =
+				target_elev - tmp_elevation[next_r][next_c];
+		}	
+		if (dirs[NR(d)][NC(d)] < 1)
+		    continue;
+
+		d_inits[k].r = next_r;
+		d_inits[k].c = next_c;
+		d_inits[k].cur_dist = cur_dist;
+
+			if (elevation)
+		d_inits[k].target_elev = target_elev;
+		k++;
+	    }			/* end of if done */
+	}
+	n_inits = k;
+    }
+  G_percent((counter-n_inits),counter,10);
+    return 0;
+}
+
+
+int seg_calculate_upstream(SEGMENT* distance, SEGMENT* dirs, SEGMENT* elevation, SEGMENT* tmp_elevation, int near)
+{
+  int r, c;
+  int next_r, next_c;
+  float easting, northing;
+  float cell_easting, cell_northing;
+  int i, j, k, d, d_next;
+  FCELL minus_one_cell = -1;
+  FCELL zero_cell = 0;
+  int done;
+  int counter;
+  int n_inits = 0;
+  float cur_dist;
+  POINT *d_inits;
+  float tmp_dist = 0;
+  float target_elev = 0;
+  CELL dirs_cell;
+  FCELL distance_cell, elevation_cell, tmp_elevation_cell;
+  size_t elevation_data_size;
+	struct Cell_head window;
+
+	Rast_get_window(&window);
+	
+					if(elevation) {
+		elevation_data_size=Rast_cell_size(FCELL_TYPE);			
+		  for (r = 0; r < nrows; ++r)
+		for(c = 0; c<ncols; ++c)  {
+	segment_get(elevation,&elevation_cell,r,c);
+	segment_put(tmp_elevation,&elevation_cell,r,c);
+		}
+			}
+				
+    for (r = 0; r < nrows; ++r) 
+	for (c = 0; c < ncols; ++c) {
+
+		segment_get(distance,&distance_cell,r,c);
+
+	    for (i = 1; i < 9; ++i) {
+		if (NOT_IN_REGION(i)) 
+		    continue;	/* out of border */
+
+		j = DIAG(i);
+		next_r = NR(i);
+		next_c = NC(i);
+		
+		segment_get(dirs,&dirs_cell,next_r,next_c);
+		
+				if (dirs_cell == j && distance_cell != 0) {	/* is contributing cell */
+			segment_put(distance,&minus_one_cell,r,c);
+			break;
+				}
+	    } /* end for i */
+	    
+	  segment_get(distance,&distance_cell,r,c);
+	  segment_get(dirs,&dirs_cell,r,c);
+		if(distance_cell== 1)
+			if(distance_cell == 1 && dirs_cell >0)
+	  n_inits++;
+			else if (dirs_cell > 0)
+		segment_put(distance,&minus_one_cell,r,c);
+		
+		}
+
+  d_inits = (POINT *) G_malloc(n_inits * sizeof(POINT));
+
+    k = 0;
+    for (r = 0; r < nrows; ++r) 
+	for (c = 0; c < ncols; ++c) {
+	
+	segment_get(distance,&distance_cell,r,c);
+	    if (distance_cell == 1) {
+		
+		segment_put(distance,&zero_cell,r,c);
+			if (elevation)
+		segment_put(elevation,&zero_cell,r,c);
+
+		segment_get(dirs,&d,r,c);	
+		segment_get(dirs,&d_next,NR(d),NR(d));	
+	
+			if (d_next<0)
+		continue;
+
+		d_inits[k].r = r;
+		d_inits[k].c = c;
+		d_inits[k].cur_dist = 0;
+
+			if (elevation) 
+		segment_get(tmp_elevation,&(d_inits[k].target_elev),r,c);	
+		k++;
+	    }
+	}
+
+    counter = n_inits = k;
+
+	G_message("Calculate upstream parameters...");		
+    while (n_inits > 0) {
+	k = 0;
+	G_percent((counter-n_inits),counter,10);
+	
+	for (i = 0; i < n_inits; ++i) {
+	    r = d_inits[i].r;
+	    c = d_inits[i].c;
+   
+	    segment_get(dirs,&d,r,c);	
+	    next_r = NR(d);
+	    next_c = NC(d);
+	    tmp_dist = d_inits[i].cur_dist;
+
+	    if (elevation)
+		target_elev = d_inits[i].target_elev;
+
+	  easting = window.west + (c + 0.5) * window.ew_res;
+	  northing = window.north - (r + 0.5) * window.ns_res;
+	  cell_easting = window.west + (next_c + 0.5) * window.ew_res;
+	  cell_northing = window.north - (next_r + 0.5) * window.ns_res;
+
+	  cur_dist =	tmp_dist + 
+			G_distance(easting, northing, cell_easting, cell_northing);
+
+		segment_get(distance,&distance_cell,next_r,next_c);	
+  
+	    if (near)
+		done = (distance_cell > cur_dist ||
+			distance_cell <=0) ? 1 : 0;
+	    else
+		done = (distance_cell < cur_dist ||
+			distance_cell <=0) ? 1 : 0;
+
+	    if (done) {
+		segment_put(distance,&cur_dist,next_r,next_c);
+				if (elevation) {
+			segment_get(tmp_elevation,&tmp_elevation_cell,next_r,next_c);
+			tmp_elevation_cell = target_elev-tmp_elevation_cell;
+			segment_put(elevation,&tmp_elevation_cell,next_r,next_c);
+		}	
+		
+		segment_get(dirs,&dirs_cell,NR(d),NC(d));
+		if (dirs_cell < 1)
+		    continue;
+
+		d_inits[k].r = next_r;
+		d_inits[k].c = next_c;
+		d_inits[k].cur_dist = cur_dist;
+
+			if (elevation)
+		d_inits[k].target_elev = target_elev;
+		k++;
+	    }			/* end of if done */
+	}
+	n_inits = k;
+    }
+  G_percent((counter-n_inits),counter,10);
+    return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/distance_init.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/distance_init.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/distance_init.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,191 @@
+#include "local_proto.h"
+
+int ram_find_outlets(CELL** streams, int number_of_streams, CELL** dirs, int subs, int outs)
+{
+    int d;		/* d: direction */
+    int r, c;
+    int i,j, cat;
+    int next_stream = -1, cur_stream;
+    int out_max = ncols + nrows;
+    int outlets_num;
+
+    G_message(_("Finding nodes..."));
+    outlets = (OUTLET *) G_malloc((out_max) * sizeof(OUTLET));
+
+	  outlets_num = 0;
+
+			for (r = 0; r < nrows; ++r) 
+		for (c = 0; c < ncols; ++c) 
+	if (streams[r][c]>0) {
+
+			if (outlets_num > 2 * (out_max - 1))
+		G_fatal_error(_
+				("Stream and direction maps probably do not match"));
+			if (outlets_num > (out_max - 1))
+		outlets = (OUTLET *)G_realloc(outlets,out_max*2*sizeof(OUTLET));
+	
+		d = abs(dirs[r][c]);	/* r.watershed */
+
+			if (NOT_IN_REGION(d)) {
+		next_stream = -1;	
+			}
+			else {
+		next_stream = streams[NR(d)][NC(d)];
+				if (next_stream < 1)
+			next_stream = -1;
+			}
+
+			if (d == 0)
+		next_stream = -1;
+		
+		cur_stream = streams[r][c];
+
+		if (subs && outs) {	/* in stream mode subs is ignored */
+		  if (cur_stream != next_stream) {	/* is outlet or node! */
+		outlets[outlets_num].r = r;
+		outlets[outlets_num++].c = c;
+		  }
+		}
+		else {
+		  if (next_stream < 0) {	/* is outlet! */
+		outlets[outlets_num].r = r;
+		outlets[outlets_num++].c = c;
+		  }
+		}		/* end lasts */
+	}			/* end if streams */
+
+    return outlets_num;
+}
+
+
+int seg_find_outlets(SEGMENT* streams, int number_of_streams, SEGMENT* dirs, int subs, int outs)
+{
+    int d;		/* d: direction */
+    int r, c;
+    int i,j, cat;
+    int next_stream = -1, cur_stream;
+    int out_max = ncols + nrows;
+    int outlets_num;
+    CELL streams_cell, streams_next_cell;
+    CELL dirs_cell;
+
+    G_message(_("Finding nodes..."));
+    outlets = (OUTLET *) G_malloc((out_max) * sizeof(OUTLET));
+
+	  outlets_num = 0;
+
+			for (r = 0; r < nrows; ++r) 
+		for (c = 0; c < ncols; ++c) {
+	segment_get(streams,&streams_cell,r,c);
+	
+	if (streams_cell>0) {
+
+			if (outlets_num > 2 * (out_max - 1))
+		G_fatal_error(_
+				("Stream and direction maps probably do not match"));
+			if (outlets_num > (out_max - 1))
+		outlets = (OUTLET *)G_realloc(outlets,out_max*2*sizeof(OUTLET));
+	
+		segment_get(dirs,&dirs_cell,r,c);
+		d = abs(dirs_cell);	/* r.watershed */
+
+			if (NOT_IN_REGION(d)) {
+		next_stream = -1;	
+			}
+			else {
+		segment_get(streams,&next_stream,NR(d),NC(d));
+				if (next_stream < 1)
+			next_stream = -1;
+			}
+
+			if (d == 0)
+		next_stream = -1;
+		
+		if (subs && outs) {	/* in stream mode subs is ignored */
+		  if (streams_cell != next_stream) {	/* is outlet or node! */
+		outlets[outlets_num].r = r;
+		outlets[outlets_num++].c = c;
+		  }
+		}
+		else {
+		  if (next_stream < 0) {	/* is outlet! */
+		outlets[outlets_num].r = r;
+		outlets[outlets_num++].c = c;
+		  }
+		}		/* end lasts */
+	}			/* end if streams */
+	} /* end for c */
+    return outlets_num;
+}
+
+int ram_init_distance(CELL** streams, FCELL** distance, int outlets_num, int outs) {
+  int r, c, i;
+  size_t  data_size;
+  data_size = Rast_cell_size(FCELL_TYPE);
+
+  if (!outs) {		/* stream mode */
+				for (r = 0; r < nrows; ++r) 
+			for (c = 0; c < ncols; ++c) 
+		distance[r][c] = (streams[r][c]) ? 0 : -1;		
+  }
+  else {			/* outlets mode */
+				for (r=0;r<nrows;++r) 
+			for (c = 0; c < ncols; ++c) 
+		distance[r][c]=-1;
+		
+			for (i = 0; i < outlets_num; ++i)
+		distance[outlets[i].r][outlets[i].c] = 0;			
+}
+  
+  return 0;
+}
+
+int seg_init_distance(SEGMENT* streams, SEGMENT* distance, int outlets_num, int outs) {
+  int r, c, i;
+  CELL streams_cell;
+  FCELL distance_cell;
+  FCELL minus_one_cell=-1;
+  FCELL zero_cell=0;
+
+  if (!outs) {		/* stream mode */
+				for (r = 0; r < nrows; ++r) 
+			for (c = 0; c < ncols; ++c) {
+		segment_get(streams,&streams_cell,r,c);
+		distance_cell=(streams_cell) ? 0 : -1;
+		segment_put(distance,&distance_cell,r,c);
+			}
+  }
+  else {			/* outlets mode */
+				for (r=0;r<nrows;++r)
+			for (c = 0; c < ncols; ++c)
+		segment_put(distance,&minus_one_cell,r,c);
+
+			for (i = 0; i < outlets_num; ++i)
+		segment_put(distance,&zero_cell,outlets[i].r,outlets[i].c);
+	}
+  return 0;
+}
+
+int ram_prep_null_elevation (FCELL** distance, FCELL** elevation) {
+
+		int r,c;
+		for (r=0;r<nrows;++r)
+	for (c=0;c<ncols;++c)
+			if(distance[r][c]==-1) {
+	elevation[r][c]=-1;
+			}
+}	
+
+
+int seg_prep_null_elevation (SEGMENT* distance, SEGMENT* elevation) {
+	int r,c;
+  FCELL distance_cell;
+	
+		for (r=0;r<nrows;++r)
+	for (c=0;c<ncols;++c) {
+		segment_get(distance,&distance_cell,r,c);
+			if(distance_cell==-1)
+		segment_put(elevation,&distance_cell,r,c);
+		}
+}	
+

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/io.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/io.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/io.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,523 @@
+#include "io.h"
+/* all in ram functions section */
+
+int ram_create_map(MAP* map, RASTER_MAP_TYPE data_type) {
+	
+	/* 
+	 * allocates 0 filled nrows*ncols map of type void;
+	 * map parameters are stored in structure;
+	 * map: map to be created;
+	 * map type to be created must be CELL, FCELL, DCELL;
+	 * */
+		
+	int r, c;
+		
+		if(data_type < 0 || data_type > 2)
+	G_fatal_error(_("ram_creat: Cannot create map of unrecognised type"));
+	
+	map->data_type=data_type;
+	map->map_name=NULL;
+	map->nrows = Rast_window_rows();
+  map->ncols = Rast_window_cols();
+  map->data_size=Rast_cell_size(data_type);
+
+/* preparing internal map */
+	switch (map->data_type) { 
+		case CELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(CELL *));
+			break;
+
+		case FCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(FCELL *));
+			break;
+		
+		case DCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(DCELL *));
+			break;
+	}
+
+		for (r = 0; r < map->nrows; ++r)
+	(map->map)[r] = G_calloc(map->ncols,map->data_size);	
+	
+	return 0;
+}
+
+int ram_read_map(MAP* map, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+/*
+ * Funciton read external map and put it in MAP structure (created with create_map)
+ * map: map to be read can be of any data type, read map is converted to target map if neccesary.
+ * input_map_name: name of the map to be read;
+ * map pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+
+	int r, c;
+  char *mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+  int input_map_fd;
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+  void* input_buffer=NULL;
+  void* input_pointer;
+
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+	    if (mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), input_map_name);
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+  Rast_get_cellhd(input_map_name, mapset, &cellhd);
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || 
+			this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+	/* checking if input map is of required type */
+		if(check_data_type != map->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1)
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+
+  input_map_fd  = Rast_open_old(input_map_name, mapset);
+  input_data_size = Rast_cell_size(input_data_type);
+	
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	map->min=(double)min;
+	map->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(map->min), &(map->max));
+		}
+}
+/* end opening and checking */
+
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+  /* start reading */
+  G_message(_("Reading map <%s>"),input_map_name);
+
+			for (r = 0; r < map->nrows; ++r) {
+					G_percent(r, map->nrows, 2);
+
+			Rast_get_row(input_map_fd, input_buffer, r,input_data_type);
+			input_pointer=input_buffer;
+
+						for (c = 0; c < map->ncols; ++c)
+					if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type))
+				switch (map->data_type) {
+					case CELL_TYPE:
+						((CELL**)map->map)[r][c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL**)map->map)[r][c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL**)map->map)[r][c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("ram_open:Wrong internal data type"));
+						break;
+				}
+			}		/*end for r */
+
+  G_free(input_buffer);
+	G_percent(r, map->nrows, 2);
+	Rast_close(input_map_fd);
+  return 0;
+}				/* end create floating point map */
+
+int ram_reset_map(MAP* map, int value) {
+ /*
+	* set all cells in the map to value
+	*/
+	int r;
+
+		for (r=0;r<map->nrows;++r) 
+	memset((map->map)[r],value,map->ncols*map->data_size);
+	return 0;
+}
+
+int ram_write_map(MAP* map, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write map to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */
+	
+  int r, c;
+  int output_fd = 0;
+  struct History history;
+  void* row;
+
+	/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = map->data_type;
+
+		if(output_data_type != map->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+  
+  G_message(_("Writing map <%s>"),output_map_name);
+  output_fd = Rast_open_new(output_map_name, output_data_type);
+		
+		/* writing */
+		for (r = 0; r < map->nrows; ++r) {
+			G_percent(r, map->nrows, 2);
+					
+					if(convert_to_null) {
+			row = map->map[r];
+				switch (map->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((CELL*)row)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(map->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((FCELL*)row)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(map->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((DCELL*)row)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(map->data_size), 1);
+				break;
+			default: 
+					G_debug(1,"ram_null:Cannot convert to null at: %d %d",r,c);
+					}
+				}
+		
+	Rast_put_row(output_fd, (map->map)[r], output_data_type);
+		}
+	G_percent(r, map->nrows, 2);	
+  Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("<%s> Done"), output_map_name);
+  return 0;
+}
+
+int ram_release_map (MAP* map) {
+	/* 
+	 * free memory allocated for map, set pointer to null;
+	 */ 
+	 int r;
+
+			for (r = 0; r < map->nrows; ++r)
+		G_free((map->map)[r]);
+  G_free(map->map);
+  map=NULL;
+  return 0;
+}
+
+
+/* memory swap functions section */
+
+
+int seg_create_map(SEG * seg, int srows, int scols, int number_of_segs, RASTER_MAP_TYPE data_type) {
+	/* create segment  and returns pointer to it;
+	 * seg must be declared first;
+	 * parameters are stored in structure;
+	 * seg: segment to be created;
+	 * srows, scols segment size
+	 * number of segs max number of segs stored in memory
+	 * data_type to be created must be CELL, FCELL, DCELL;
+	 */
+
+	char* filename;
+	int fd;
+	int local_number_of_segs;
+
+	seg->fd=-1;
+	seg->filename = NULL;
+	seg->map_name = NULL;
+	seg->mapset = NULL;
+	seg->data_type = data_type;
+	seg->nrows = Rast_window_rows();
+	seg->ncols = Rast_window_cols();
+
+	local_number_of_segs=(seg->nrows/srows+1)*(seg->ncols/scols+1);
+	number_of_segs=(number_of_segs>local_number_of_segs) ?
+		local_number_of_segs : number_of_segs;
+	
+	G_debug(3,"seg_creat:number of segments %d",number_of_segs);
+	
+	switch (seg->data_type) {
+		case CELL_TYPE:
+			seg->data_size=sizeof(CELL);
+			break;
+		case FCELL_TYPE:
+			seg->data_size=sizeof(FCELL);
+			break;
+		case DCELL_TYPE:
+			seg->data_size=sizeof(DCELL);
+			break;
+		default:
+		G_fatal_error(_("seg_create: unrecognisabe data type"));
+	}
+	
+	filename=G_tempfile();
+	fd=creat(filename,0666);
+	
+	if(0 > segment_format(fd,seg->nrows,seg->ncols,srows,scols,seg->data_size)) {
+		close(fd);
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot format segment"));
+	}
+	
+	close(fd);
+	if(0 > (fd = open(filename,2))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot re-open file"));
+	}
+	
+	if(0>(fd = segment_init(&(seg->seg),fd,number_of_segs))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot init segment file or out of memory"));
+	}
+	
+	seg->filename = G_store(filename);
+	seg->fd = fd;
+	return 0;
+}
+
+int seg_read_map(SEG* seg, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+	
+/*
+ * Funciton read external map and put it in SEG structure (created with seg_create_map)
+ * map to be read can be of any data type, read map is converted if neccesary.
+ * input_map_name: name of the map to be read;
+ * seg: pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+	
+	int input_fd;
+	int r,c;
+	char* mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+	void* input_buffer=NULL;
+	void* target_buffer=NULL;
+	void* input_pointer=NULL;
+	
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+    if (mapset == NULL)
+	G_fatal_error(_("seg_read:Raster map <%s> not found"), input_map_name);
+	seg->mapset=mapset;
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+	Rast_get_cellhd(input_map_name, mapset, &cellhd);
+	
+	/* check resolution equal anyinteger check;  equal 0 no check*/
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+		if(check_data_type != seg->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1) 
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+	
+	input_fd = Rast_open_old(input_map_name,mapset);
+	input_data_size = Rast_cell_size(input_data_type);
+
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	seg->min=(double)min;
+	seg->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(seg->min), &(seg->max));
+		}
+}
+
+	/* end opening and checking */
+	
+	G_message(_("Reading map <%s>"),input_map_name);
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+	target_buffer=Rast_allocate_buf(seg->data_type); 
+
+		for (r=0; r<seg->nrows; ++r) {
+			G_percent(r, seg->nrows, 2);
+			Rast_get_row(input_fd,input_buffer,r,input_data_type);
+			input_pointer=input_buffer;
+			memset(target_buffer,0,seg->ncols*seg->data_size);
+
+							for (c = 0; c < seg->ncols; ++c) 
+						if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type)) {
+				switch (seg->data_type) {
+					case CELL_TYPE:
+						((CELL*)target_buffer)[c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL*)target_buffer)[c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL*)target_buffer)[c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("Wrong internal data type"));
+						break;
+				}
+					}
+
+		if(0>segment_put_row(&(seg->seg),target_buffer,r)) {
+			G_free(input_buffer);
+			G_free(target_buffer);
+			Rast_close(input_fd);
+			G_fatal_error(_("seg_read: Cannot segment put row %d for map %s"),
+				r,input_map_name);
+				}
+	} /* end for row */
+		
+	G_percent(r, seg->nrows, 2);
+	Rast_close(input_fd);
+	G_free(input_buffer);
+	G_free(target_buffer);
+	
+	seg->map_name=G_store(input_map_name);
+	seg->mapset=G_store(mapset);
+	
+	return 0;
+}
+
+int seg_reset_map (SEG* seg, int value) {
+	/*
+	* set all cells in the map to value
+	*/
+int r,c;
+    for (r=0;r<seg->nrows;++r)
+  for (c=0;c<seg->ncols;++c)
+segment_put(&(seg->seg),&value,r,c);
+ }
+
+int seg_write_map(SEG* seg, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write seg to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */	
+	int output_fd;
+	int r, c;
+	void* output_buffer;
+	void* row;
+	struct History history;
+	
+		/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = seg->data_type;
+
+		if(output_data_type !=  seg->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+	
+	G_message(_("Writing map <%s>"),output_map_name);
+	output_fd=Rast_open_new(output_map_name,output_data_type);
+	output_buffer=Rast_allocate_buf(output_data_type);
+	segment_flush(&(seg->seg));
+	
+	/* writing */
+		for(r=0;r<seg->nrows;++r) {
+
+	G_percent(r, seg->nrows, 2);
+		if(0>segment_get_row(&(seg->seg),output_buffer,r)) 
+	G_warning(_("seg_write: Cannot segment read row %d for map %s"),
+		r,output_map_name);
+
+		if(convert_to_null) {
+
+				row = output_buffer;
+				switch (seg->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((CELL*)output_buffer)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(seg->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((FCELL*)output_buffer)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(seg->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((DCELL*)output_buffer)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(seg->data_size), 1);
+				break;
+			default: 
+					G_warning(_("ram_null:Cannot convert to null at: %d %d"),r,c);
+				}
+		}
+	Rast_put_row(output_fd, output_buffer, output_data_type);
+		}	
+
+	G_percent(r, seg->nrows, 2);
+	G_free(output_buffer);
+	Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("%s Done"), output_map_name);
+	
+	return 0;
+}
+
+int seg_release_map(SEG* seg) {
+/* 
+ * release segment close files, set pointers to null;
+ */ 
+	segment_release(&(seg->seg));
+	close(seg->fd);
+	unlink(seg->filename);
+
+		if(seg->map_name)
+	G_free(seg->map_name);
+		if(seg->mapset)
+	G_free(seg->mapset);
+
+return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/io.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/io.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/io.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/segment.h>
+
+#define NOT_IN_REGION(x) (r+nextr[(x)] < 0 || r+nextr[(x)] > (nrows-1) || c+nextc[(x)] < 0 || c+nextc[(x)] > (ncols-1))
+#define NR(x) r + nextr[(x)]
+#define NC(x) c + nextc[(x)]
+#define INDEX(r,c) (r)*ncols+(c)
+#define DIAG(x) (((x) + 4) > 8 ? ((x) - 4) : ((x) + 4));
+
+#define SROWS 256
+#define SCOLS 256
+
+typedef struct {
+	void** map; /* matrix of data */
+	double min, max; /* data range : may requre casting */
+	int nrows, ncols;
+	char* map_name; /* map name, unused */
+	RASTER_MAP_TYPE data_type; /* type of data */
+	size_t data_size; /* type of data */
+} MAP;
+
+typedef struct {
+	SEGMENT seg;		/* segmented data store */
+	int fd;					/* segment temporary file name descriptor */
+	char* filename; /* segment temporary file name */
+	char* map_name; /* map name converted to segment */
+	char* mapset;
+	int nrows, ncols; /* store nrows and rcols */
+	RASTER_MAP_TYPE data_type; /* data type of the map */
+	size_t data_size; /* size of cell returned by sizeof */
+	double min, max; /* data range */
+} SEG;
+
+
+/* all in ram functions */
+int ram_create_map(MAP*, RASTER_MAP_TYPE);
+int ram_read_map	(MAP* , char*, int, RASTER_MAP_TYPE);
+int ram_reset_map	(MAP*, int);
+int ram_write_map	(MAP*, char*, RASTER_MAP_TYPE, int, double);
+int ram_destory_map(MAP*);
+
+/* memory swap functions */
+int seg_create_map(SEG*, int, int, int, RASTER_MAP_TYPE);
+int seg_read_map	(SEG*, char*, int, RASTER_MAP_TYPE);
+int seg_reset_map (SEG*, int);
+int seg_write_map	(SEG*, char*, RASTER_MAP_TYPE, int, double);
+int seg_release_map(SEG*);
+

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/local_proto.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,22 @@
+#include "io.h"
+#include "local_vars.h"
+
+/* inits */
+int ram_find_outlets(CELL** streams, int number_of_streams, CELL** dirs, int subs, int outs);
+int ram_init_distance(CELL** streams, FCELL** distance, int outlets_num, int outs);
+int ram_prep_null_elevation (FCELL** distance, FCELL** elevation);
+
+int seg_find_outlets(SEGMENT* streams, int number_of_streams, SEGMENT* dirs, int subs, int outs);
+int seg_prep_null_elevation (SEGMENT* distance, SEGMENT* elevation);
+int seg_init_distance(SEGMENT* streams, SEGMENT* distance, int outlets_num, int outs);
+
+/* calculate */
+int ram_calculate_downstream (CELL** dirs, FCELL** distance, FCELL** elevation, OUTLET outlet, int outs);
+int ram_fill_basins(OUTLET outlet, FCELL** distance, CELL** dirs);
+int ram_calculate_upstream(FCELL** distance, CELL** dirs, FCELL** elevation, FCELL** tmp_elevation, int near);
+
+int seg_calculate_downstream (SEGMENT* dirs, SEGMENT* distance, SEGMENT* elevation, OUTLET outlet, int outs);
+int seg_fill_basins(OUTLET outlet, SEGMENT* distance, SEGMENT* dirs);
+int seg_calculate_upstream(SEGMENT* distance, SEGMENT* dirs, SEGMENT* elevation, SEGMENT* tmp_elevation, int near);
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/local_vars.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/local_vars.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/local_vars.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+
+#ifdef MAIN
+#  define GLOBAL
+#else
+#  define GLOBAL extern
+#endif
+
+#define SQRT2 1.414214
+#define UPSTREAM 0
+#define DOWNSTREAM 1
+
+typedef struct {
+	int r,c;
+} OUTLET;
+
+typedef struct {
+	int r,c;
+  float cur_dist;
+  float target_elev;
+} POINT;
+
+GLOBAL int nextr[9];
+GLOBAL int nextc[9];
+
+GLOBAL OUTLET* outlets;
+GLOBAL int nrows, ncols;
+GLOBAL int fifo_max;
+GLOBAL POINT* fifo_points;
+
+
+
+
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/main.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/main.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/main.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,301 @@
+/****************************************************************************
+ *
+ * MODULE:       r.stream.distance
+ * AUTHOR(S):    Jarek Jasiewicz jarekj amu.edu.pl
+ *               
+ * PURPOSE:      Calculate distance and elevation over the streams and outlets 
+ *               according user's input data. The elevation and distance is calculated
+ *               along watercourses
+ *               It uses any stream map  and r.watershed or .stream.extreact direction map.
+ *               Stram input map shall contains streams or points outlets with or
+ *               without unique categories
+ *
+ * COPYRIGHT:    (C) 2002,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.
+ *
+ *****************************************************************************/
+#define MAIN
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int nextr[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
+int nextc[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
+
+int process_cat(char** cat_list);
+int main(int argc, char *argv[])
+{
+
+    struct GModule *module;	
+    struct Option *in_dir_opt, 
+									*in_stm_opt,
+									*in_stm_cats_opt,
+									*in_elev_opt, 
+									*in_method_opt,
+									*opt_swapsize, 
+									*out_dist_opt, 
+									*out_diff_opt;
+    struct Flag 				*flag_outs, 
+									*flag_sub, 
+									*flag_near,
+									*flag_segmentation;	
+    char *method_name[] = { "UPSTREAM", "DOWNSTREAM" };
+    int method;
+    int number_of_segs;
+    int outlets_num;
+    int number_of_streams;
+    int outs, subs, near, segmentation; /*flags */
+    int j;
+    
+    G_gisinit(argv[0]);
+
+  module = G_define_module();
+  module->description =
+	_("Calculate distance to and alavation above streams \
+    and outlets according user' input. It can work in stream mode where target are streams and outlets mode \
+    where targets are outlets");
+
+	G_add_keyword("watercourse distance");
+	G_add_keyword("relative elevation");
+	
+	in_stm_opt = G_define_standard_option(G_OPT_R_INPUT);
+  in_stm_opt->key = "stream";
+  in_stm_opt->description = "Name of streams (outlets) mask input map";
+  
+  in_dir_opt = G_define_standard_option(G_OPT_R_INPUT);
+  in_dir_opt->key = "dirs";
+  in_dir_opt->description = "Name of flow direction input map";
+
+  in_elev_opt = G_define_standard_option(G_OPT_R_INPUT);
+  in_elev_opt->key = "elevation";
+  in_elev_opt->required = NO;
+  in_elev_opt->description = "Name of elevation map";
+
+  in_method_opt = G_define_option();
+  in_method_opt->key = "method";
+  in_method_opt->description = "Calculation method";
+  in_method_opt->type = TYPE_STRING;
+  in_method_opt->required = YES;
+  in_method_opt->options = "upstream,downstream";
+  in_method_opt->answer = "downstream";
+  
+  opt_swapsize = G_define_option();
+	opt_swapsize->key="memory";
+	opt_swapsize->type = TYPE_INTEGER;
+	opt_swapsize->answer = "300";
+	opt_swapsize->description =_("Max memory used in memory swap mode (MB)");
+	opt_swapsize->guisection=_("Optional");	
+
+  out_dist_opt = G_define_standard_option(G_OPT_R_OUTPUT);
+  out_dist_opt->key = "distance";
+  out_dist_opt->required=NO;
+  out_dist_opt->description = "Output distance map";
+
+  out_diff_opt = G_define_standard_option(G_OPT_R_OUTPUT);
+  out_diff_opt->key = "difference";
+  out_diff_opt->required=NO;
+  out_diff_opt->description = "Output elevation difference map";
+	
+	flag_outs = G_define_flag();
+  flag_outs->key = 'o';
+  flag_outs->description =
+	_("Calculate parameters for outlets (outlet mode) instead of (default) streams");
+
+  flag_sub = G_define_flag();
+  flag_sub->key = 's';
+  flag_sub->description =
+	_("Calculate parameters for subbasins (ignored in stream mode)");
+
+  flag_near = G_define_flag();
+  flag_near->key = 'n';
+  flag_near->description =
+	_("Calculate nearest local maximum (ignored in downstream calculation)");
+	
+	flag_segmentation = G_define_flag();
+  flag_segmentation->key = 'm';
+  flag_segmentation->description = _("Use memory swap (operation is slow)");
+    
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+	
+    if (!out_diff_opt->answer && !out_dist_opt->answer)
+	G_fatal_error(_("You must select at least one output maps: distance and (or) elevation"));
+    if (out_diff_opt->answer && !in_elev_opt->answer)
+	G_fatal_error(_("If you select elevation output, elevation is required"));
+  
+			if(out_dist_opt->answer)
+    if (G_legal_filename(out_dist_opt->answer) < 0)
+	G_fatal_error(_("<%s> is an illegal distance name"), out_dist_opt->answer);
+		
+			if(out_diff_opt->answer)
+		if (G_legal_filename(out_diff_opt->answer) < 0)
+	G_fatal_error(_("<%s> is an illegal elevation difference name"), out_diff_opt->answer);
+	
+	    if (!strcmp(in_method_opt->answer, "upstream"))
+	method = UPSTREAM;
+    else if (!strcmp(in_method_opt->answer, "downstream"))
+	method = DOWNSTREAM;
+	
+	outs = (flag_outs->answer != 0);
+  subs = (flag_sub->answer != 0);
+  near = (flag_near->answer != 0);
+  segmentation = (flag_segmentation->answer != 0);
+		
+	nrows = Rast_window_rows();
+  ncols = Rast_window_cols();
+	G_begin_distance_calculations();
+
+	fifo_max=4* nrows*ncols;
+	fifo_points=(POINT *)G_malloc((fifo_max+1)*sizeof(POINT));
+	
+if(!segmentation) {
+	G_message(_("ALL IN RAM CALCULATION - METHOD: %s"),method_name[method]);
+	MAP map_dirs, map_streams, map_distance, map_elevation, map_tmp_elevation;
+	CELL **streams, **dirs;
+  FCELL **distance;
+  FCELL** elevation=NULL;
+	FCELL** tmp_elevation=NULL;
+
+	ram_create_map(&map_streams,CELL_TYPE);
+	ram_read_map(&map_streams,in_stm_opt->answer,1,CELL_TYPE);
+	ram_create_map(&map_dirs,CELL_TYPE);
+	ram_read_map(&map_dirs,in_dir_opt->answer,1,CELL_TYPE);
+	ram_create_map(&map_distance,FCELL_TYPE);
+	
+	streams=(CELL**)map_streams.map;
+	dirs=(CELL**)map_dirs.map;
+	distance=(FCELL**)map_distance.map;
+	number_of_streams = (int)map_streams.max+1;
+
+	outlets_num=ram_find_outlets(streams, number_of_streams, dirs,subs,outs);
+	ram_init_distance(streams, distance,outlets_num, outs);
+	ram_release_map(&map_streams);
+
+			if(in_elev_opt->answer) {
+	ram_create_map(&map_elevation,FCELL_TYPE);
+	ram_read_map(&map_elevation,in_elev_opt->answer,0,-1);
+	elevation=(FCELL**)map_elevation.map;
+		} /* map elevation will be replaced by elevation difference map */
+		
+	
+			if(method == DOWNSTREAM) {
+	G_message(_("Calculate downstream parameters..."));
+		for(j=0; j<outlets_num;++j) {
+	G_percent(j,outlets_num,1);
+	ram_calculate_downstream(dirs, distance, elevation, outlets[j],outs);
+		}
+	G_percent(j,outlets_num,1);
+			
+		}	else if(method == UPSTREAM) {
+
+				if(out_diff_opt->answer) {
+	ram_create_map(&map_tmp_elevation,FCELL_TYPE);
+	tmp_elevation=(FCELL**)map_tmp_elevation.map;
+				}
+
+		for(j=0; j<outlets_num;++j)
+	ram_fill_basins(outlets[j],distance,dirs);
+	ram_calculate_upstream(distance,dirs,elevation,tmp_elevation, near);
+
+		} else {
+	G_fatal_error(_("Unrecognised method of processing"));
+		} /* end methods */
+
+		if(out_diff_opt->answer) {
+	ram_prep_null_elevation(distance,elevation);
+	ram_write_map(&map_elevation, out_diff_opt->answer, FCELL_TYPE, 1, -1);
+		} 
+
+		if(out_dist_opt->answer)
+	ram_write_map(&map_distance, out_dist_opt->answer, FCELL_TYPE, 1, -1);
+
+	ram_release_map(&map_dirs);
+	ram_release_map(&map_distance);
+
+		if(in_elev_opt->answer)
+	ram_release_map(&map_elevation);
+		if(in_elev_opt->answer && method==UPSTREAM)
+	ram_release_map(&map_tmp_elevation);
+}
+
+if(segmentation) {
+	G_message(_("MEMORY SWAP CALCULATION - METHOD: %s MAY TAKE SOME TIME"),method_name[method]);
+	SEG map_dirs, map_streams, map_distance, map_elevation, map_tmp_elevation;
+	SEGMENT *streams, *dirs, *distance;
+	SEGMENT *elevation=NULL; 
+	SEGMENT *tmp_elevation=NULL;
+	
+	number_of_segs = (int)atof(opt_swapsize->answer);
+		if (method==DOWNSTREAM)
+	number_of_segs < 32 ? (int)(32/0.18) : number_of_segs/0.18;
+		else /* two elevation maps */
+	number_of_segs < 32 ? (int)(32/0.24) : number_of_segs/0.24;
+	
+	seg_create_map(&map_streams,SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	seg_read_map(&map_streams,in_stm_opt->answer,1,CELL_TYPE);
+	seg_create_map(&map_dirs,SROWS, SCOLS, number_of_segs,CELL_TYPE);
+	seg_read_map(&map_dirs,in_dir_opt->answer,1,CELL_TYPE);
+	seg_create_map(&map_distance,SROWS, SCOLS, number_of_segs,FCELL_TYPE);
+	
+	streams=&map_streams.seg;
+	dirs=&map_dirs.seg;
+	distance=&map_distance.seg;
+	number_of_streams = (int)map_streams.max+1;
+	
+	outlets_num = seg_find_outlets(streams,number_of_streams,dirs,subs,outs);
+	seg_init_distance(streams,distance,outlets_num,outs);
+	seg_release_map(&map_streams);
+
+			if(in_elev_opt->answer) {
+	seg_create_map(&map_elevation,SROWS, SCOLS, number_of_segs,FCELL_TYPE);
+	seg_read_map(&map_elevation,in_elev_opt->answer,0,-1);
+	elevation = &map_elevation.seg;
+		} /* map elevation will be replaced by elevation difference map */
+	
+	if(method == DOWNSTREAM) {
+	G_message(_("Calculate downstream parameters..."));
+		for(j=0; j<outlets_num;++j) {
+	G_percent(j,outlets_num,1);
+	seg_calculate_downstream(dirs, distance, elevation, outlets[j],outs);
+		}
+	G_percent(j,outlets_num,1);
+			
+		}	else if(method == UPSTREAM) {
+
+				if(out_diff_opt->answer) {
+	seg_create_map(&map_tmp_elevation,SROWS, SCOLS, number_of_segs,FCELL_TYPE);
+	tmp_elevation=&map_tmp_elevation.seg;
+				}
+
+		for(j=0; j<outlets_num;++j) 
+	seg_fill_basins(outlets[j],distance,dirs);
+	seg_calculate_upstream(distance,dirs,elevation,tmp_elevation, near);
+
+		} else {
+	G_fatal_error(_("Unrecognised method of processing"));
+		} /* end methods */
+
+		if(out_dist_opt->answer)
+	seg_write_map(&map_distance, out_dist_opt->answer, FCELL_TYPE, 1, -1);
+
+		if(out_diff_opt->answer) {
+	seg_prep_null_elevation(distance,elevation);
+	seg_write_map(&map_elevation, out_diff_opt->answer, FCELL_TYPE, 1, -1);
+		} 
+
+	seg_release_map(&map_dirs);
+	seg_release_map(&map_distance);
+
+		if(in_elev_opt->answer)
+	seg_release_map(&map_elevation);
+		if(in_elev_opt->answer && method==UPSTREAM)
+	seg_release_map(&map_tmp_elevation);
+}
+
+	G_free(fifo_points);
+	exit(EXIT_SUCCESS);	
+}
+
+	

Added: grass-addons/grass7/raster/r.stream/r.stream.distance/r.stream.distance.html
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.distance/r.stream.distance.html	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.distance/r.stream.distance.html	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,61 @@
+<h2>OPTIONS</h2>
+<DL>
+<DT><b>-o</b></DT>
+<DD>Outlets. Downstream method only. Calculate distance and relative  elevation to basin outlets instead of streams. It choose only last outlets in the network ignoring nodes.</DD>
+<DT><b>-s</b></DT>
+<DD>Subbasins. Downstream method only. Calculate distance and elevation to stream nodes instead of streams. It create distance and elevation parameters not for whole basins but for all elementary subbasins.</DD>
+<DT><b>-n</b></DT>
+<DD>Near. For upstram method only. Calculate distance and elevation to the nearest local maximum/divide. With the default option distance/elevation is calculated to the farthest possible maximum/divide
+</DD>
+<DT><b>streams</b></DT>
+<DD>Stream network: name of input stream map on which ordering will be performed produced by r.watershed or r.stream.extract. Because streams network produced by r.watershed and r.stream.extract may slighty differ in detail it is required to use both stream and direction map produced by the same module. Stream background shall have NULL value or zero value. Background values of NULL are by default produced by r.watershed and r.stream.extract. If not 0 or NULL use <a href="r.mapcalc.html">r.mapcalc</a> to set background values to null.  
+</DD>
+<DT><b>dirs</b></DT>
+<DD>Flow direction: name of input direction map produced by r.watershed or r.stream.extract. If r.stream.extract output map is used, it only has non-NULL values in places where streams occur. NULL (nodata) cells are ignored, zero and negative values are valid direction data if they vary from -8 to 8 (CCW from East in steps of 45 degrees). Direction map shall be of type CELL values. Region resolution and map resoultion must be the same. Also <em>stream</em> network map must have the same resolution. It is checked by default. If resolutions differ the module informs about it and stops. Region boundary and maps boundary may be differ but it may lead to unexpected results.</DD>
+<DT><b>elevation</b></DT>
+<DD>Elevation: name of input elevation map. Map can be of type CELL, FCELL or DCELL. It is not restricted to resolution of region settings as stream and dir.</DD>
+<DT><b>method</b></DT>
+<DD>It is possible to calculate distance with two method: <b>downstream</b> from any raster cell to the nearest stream cell/ junction cell or outlet or <b>upstream</b> from any cell upstream to the nearest maximum or divide</DD>
+</DL>
+
+<h2>OUTPUTS</h2>
+<DL>
+<DT><b>difference</b></DT>
+<DD>Returns elevation difference to the targer (outlet, node, stream, divide, maximum) along watercoures. The map is of FCELL type</DD>
+<DT><b>distance</b></DT>
+<DD>Returns distance to the targer (outlet, node, stream, divide, maximum) along watercoures. The map is of FCELL type</DD>
+</DL>
+
+<h2>DESCRIPTION</h2>
+<P>
+Module r.stream.distance may calculate distance using two methods: downstream and upstream.
+<P>
+The default is downstream method when it  calculate distance to streams and outlets and relative elevation to streams and outlets. The distance and elevation is calculated along watercourses. In outlets mode it can also calculate parameters for subbasins.
+<P>
+In streams mode (default) it calculates that parameters downstream to streams which are added as stream mask. In outlets mode there are some additional possibilities. If subbasin is off it calculate parameters only for last point of last (downstream) CELL. In subbasin mode it calculates parameters for every subbasin separately. Subbasin mode acts similar to subbasin mask. Streams file prepared to create basins and subbasins with r.stream.basins can use to to calculate distance and elevation parameters.
+<P>
+With upstream method it calculate distance to the local maximum or divide. Opposite to downstream method, where every cell has one and only one downstream cell in upstream method every cell has usssualy more than one upstream cell. So it is impossible to determine nterchangeable path from any cell. The upstream method offers two alternative modes switched with -n flag: nearest local maximum/divide:  means the shortest path to local maximum and default option farthest maximum/divide means the longest path. In hydrological sense nearest mode means the shortest path which particle of water must run from divide to reach particular cell, while farthest mode means the possible longest path.
+
+<h2>NOTES</h2>
+<P>
+If there are more than one point or one stream networks and some separate points or separate streams networks are in catchment area defined by others it will results as in subbasin mode.  In stream mode subbasin options is ommited. Input maps must be in CELL format (default output of r.watershed, r.stream.order  and r.stream.extract)
+The distance are calculated in meters both for planimeters and Latitude-Longitude projections. The distance is calculated for flat areas not corrected by topography. Distance correction by topography may be done with following mapcalc formula:
+<P>
+<CODE>echo 'dist_corrected = sqrt(distance^2 + elevation ^2)'|r.mapcalc<CODE>
+<P>
+Module can work only if direction map, stream map and region has same settings. It is also required that stream map and direction map come from the same source. For lots of reason this limitation probably cannot be omitted.   this means if stream map comes from r.stream.extract also direction map from r.stream.extract must be used. If stream network was generated with MFD method also MFD direction map must be used.
+<P>
+Probably one of the most imortant features of r.stream.extract is the ability to calculate distnace not only for streams generated with r.stream.order, but also to any CELL map with resoultion coresponding to dirs map. It can be a lake, swamp, depression and lake boundaries even divided into smaller fragments each with its own category.
+
+<h2>SEE ALSO</h2>
+<em>
+<a href="r.watershed.html">r.watershed</a>,
+<a href="r.stream.extract.html">r.stream.extract</a>,
+<a href="r.stream.order.html">r.stream.order</a>,
+<a href="r.stream.basins.html">r.stream.basins</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+<a href="r.reclass.html">r.reclass</a>,
+</em>
+
+<h2>AUTHOR</h2>
+Jarek Jasiewicz, Adam Mickiewicz University, Geoecology and Geoinformation Institute.

Added: grass-addons/grass7/raster/r.stream/r.stream.order/Makefile
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/Makefile	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/Makefile	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,14 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.stream.order
+
+LIBES = $(GISLIB) $(RASTERLIB) $(SEGMENTLIB) $(VECTLIB) $(DBMILIB)
+DEPENDENCIES = $(GISDEP) $(RASTERDEP) $(SEGMENTDEP) $(VECTDEP) $(DBMIDEP)
+
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
+

Added: grass-addons/grass7/raster/r.stream/r.stream.order/io.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/io.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/io.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,523 @@
+#include "io.h"
+/* all in ram functions section */
+
+int ram_create_map(MAP* map, RASTER_MAP_TYPE data_type) {
+	
+	/* 
+	 * allocates 0 filled nrows*ncols map of type void;
+	 * map parameters are stored in structure;
+	 * map: map to be created;
+	 * map type to be created must be CELL, FCELL, DCELL;
+	 * */
+		
+	int r, c;
+		
+		if(data_type < 0 || data_type > 2)
+	G_fatal_error(_("ram_creat: Cannot create map of unrecognised type"));
+	
+	map->data_type=data_type;
+	map->map_name=NULL;
+	map->nrows = Rast_window_rows();
+  map->ncols = Rast_window_cols();
+  map->data_size=Rast_cell_size(data_type);
+
+/* preparing internal map */
+	switch (map->data_type) { 
+		case CELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(CELL *));
+			break;
+
+		case FCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(FCELL *));
+			break;
+		
+		case DCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(DCELL *));
+			break;
+	}
+
+		for (r = 0; r < map->nrows; ++r)
+	(map->map)[r] = G_calloc(map->ncols,map->data_size);	
+	
+	return 0;
+}
+
+int ram_read_map(MAP* map, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+/*
+ * Funciton read external map and put it in MAP structure (created with create_map)
+ * map: map to be read can be of any data type, read map is converted to target map if neccesary.
+ * input_map_name: name of the map to be read;
+ * map pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+
+	int r, c;
+  char *mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+  int input_map_fd;
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+  void* input_buffer=NULL;
+  void* input_pointer;
+
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+	    if (mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), input_map_name);
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+  Rast_get_cellhd(input_map_name, mapset, &cellhd);
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || 
+			this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+	/* checking if input map is of required type */
+		if(check_data_type != map->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1)
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+
+  input_map_fd  = Rast_open_old(input_map_name, mapset);
+  input_data_size = Rast_cell_size(input_data_type);
+	
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	map->min=(double)min;
+	map->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(map->min), &(map->max));
+		}
+}
+/* end opening and checking */
+
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+  /* start reading */
+  G_message(_("Reading map <%s>"),input_map_name);
+
+			for (r = 0; r < map->nrows; ++r) {
+					G_percent(r, map->nrows, 2);
+
+			Rast_get_row(input_map_fd, input_buffer, r,input_data_type);
+			input_pointer=input_buffer;
+
+						for (c = 0; c < map->ncols; ++c)
+					if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type))
+				switch (map->data_type) {
+					case CELL_TYPE:
+						((CELL**)map->map)[r][c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL**)map->map)[r][c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL**)map->map)[r][c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("ram_open:Wrong internal data type"));
+						break;
+				}
+			}		/*end for r */
+
+  G_free(input_buffer);
+	G_percent(r, map->nrows, 2);
+	Rast_close(input_map_fd);
+  return 0;
+}				/* end create floating point map */
+
+int ram_reset_map(MAP* map, int value) {
+ /*
+	* set all cells in the map to value
+	*/
+	int r;
+
+		for (r=0;r<map->nrows;++r) 
+	memset((map->map)[r],value,map->ncols*map->data_size);
+	return 0;
+}
+
+int ram_write_map(MAP* map, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write map to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */
+	
+  int r, c;
+  int output_fd = 0;
+  struct History history;
+  void* row;
+
+	/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = map->data_type;
+
+		if(output_data_type != map->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+  
+  G_message(_("Writing map <%s>"),output_map_name);
+  output_fd = Rast_open_new(output_map_name, output_data_type);
+		
+		/* writing */
+		for (r = 0; r < map->nrows; ++r) {
+			G_percent(r, map->nrows, 2);
+					
+					if(convert_to_null) {
+			row = map->map[r];
+				switch (map->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((CELL*)row)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(map->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((FCELL*)row)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(map->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((DCELL*)row)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(map->data_size), 1);
+				break;
+			default: 
+					G_debug(1,"ram_null:Cannot convert to null at: %d %d",r,c);
+					}
+				}
+		
+	Rast_put_row(output_fd, (map->map)[r], output_data_type);
+		}
+	G_percent(r, map->nrows, 2);	
+  Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("<%s> Done"), output_map_name);
+  return 0;
+}
+
+int ram_release_map (MAP* map) {
+	/* 
+	 * free memory allocated for map, set pointer to null;
+	 */ 
+	 int r;
+
+			for (r = 0; r < map->nrows; ++r)
+		G_free((map->map)[r]);
+  G_free(map->map);
+  map=NULL;
+  return 0;
+}
+
+
+/* memory swap functions section */
+
+
+int seg_create_map(SEG * seg, int srows, int scols, int number_of_segs, RASTER_MAP_TYPE data_type) {
+	/* create segment  and returns pointer to it;
+	 * seg must be declared first;
+	 * parameters are stored in structure;
+	 * seg: segment to be created;
+	 * srows, scols segment size
+	 * number of segs max number of segs stored in memory
+	 * data_type to be created must be CELL, FCELL, DCELL;
+	 */
+
+	char* filename;
+	int fd;
+	int local_number_of_segs;
+
+	seg->fd=-1;
+	seg->filename = NULL;
+	seg->map_name = NULL;
+	seg->mapset = NULL;
+	seg->data_type = data_type;
+	seg->nrows = Rast_window_rows();
+	seg->ncols = Rast_window_cols();
+
+	local_number_of_segs=(seg->nrows/srows+1)*(seg->ncols/scols+1);
+	number_of_segs=(number_of_segs>local_number_of_segs) ?
+		local_number_of_segs : number_of_segs;
+	
+	G_debug(3,"seg_creat:number of segments %d",number_of_segs);
+	
+	switch (seg->data_type) {
+		case CELL_TYPE:
+			seg->data_size=sizeof(CELL);
+			break;
+		case FCELL_TYPE:
+			seg->data_size=sizeof(FCELL);
+			break;
+		case DCELL_TYPE:
+			seg->data_size=sizeof(DCELL);
+			break;
+		default:
+		G_fatal_error(_("seg_create: unrecognisabe data type"));
+	}
+	
+	filename=G_tempfile();
+	fd=creat(filename,0666);
+	
+	if(0 > segment_format(fd,seg->nrows,seg->ncols,srows,scols,seg->data_size)) {
+		close(fd);
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot format segment"));
+	}
+	
+	close(fd);
+	if(0 > (fd = open(filename,2))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot re-open file"));
+	}
+	
+	if(0>(fd = segment_init(&(seg->seg),fd,number_of_segs))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot init segment file or out of memory"));
+	}
+	
+	seg->filename = G_store(filename);
+	seg->fd = fd;
+	return 0;
+}
+
+int seg_read_map(SEG* seg, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+	
+/*
+ * Funciton read external map and put it in SEG structure (created with seg_create_map)
+ * map to be read can be of any data type, read map is converted if neccesary.
+ * input_map_name: name of the map to be read;
+ * seg: pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+	
+	int input_fd;
+	int r,c;
+	char* mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+	void* input_buffer=NULL;
+	void* target_buffer=NULL;
+	void* input_pointer=NULL;
+	
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+    if (mapset == NULL)
+	G_fatal_error(_("seg_read:Raster map <%s> not found"), input_map_name);
+	seg->mapset=mapset;
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+	Rast_get_cellhd(input_map_name, mapset, &cellhd);
+	
+	/* check resolution equal anyinteger check;  equal 0 no check*/
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+		if(check_data_type != seg->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1) 
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+	
+	input_fd = Rast_open_old(input_map_name,mapset);
+	input_data_size = Rast_cell_size(input_data_type);
+
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	seg->min=(double)min;
+	seg->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(seg->min), &(seg->max));
+		}
+}
+
+	/* end opening and checking */
+	
+	G_message(_("Reading map <%s>"),input_map_name);
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+	target_buffer=Rast_allocate_buf(seg->data_type); 
+
+		for (r=0; r<seg->nrows; ++r) {
+			G_percent(r, seg->nrows, 2);
+			Rast_get_row(input_fd,input_buffer,r,input_data_type);
+			input_pointer=input_buffer;
+			memset(target_buffer,0,seg->ncols*seg->data_size);
+
+							for (c = 0; c < seg->ncols; ++c) 
+						if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type)) {
+				switch (seg->data_type) {
+					case CELL_TYPE:
+						((CELL*)target_buffer)[c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL*)target_buffer)[c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL*)target_buffer)[c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("Wrong internal data type"));
+						break;
+				}
+					}
+
+		if(0>segment_put_row(&(seg->seg),target_buffer,r)) {
+			G_free(input_buffer);
+			G_free(target_buffer);
+			Rast_close(input_fd);
+			G_fatal_error(_("seg_read: Cannot segment put row %d for map %s"),
+				r,input_map_name);
+				}
+	} /* end for row */
+		
+	G_percent(r, seg->nrows, 2);
+	Rast_close(input_fd);
+	G_free(input_buffer);
+	G_free(target_buffer);
+	
+	seg->map_name=G_store(input_map_name);
+	seg->mapset=G_store(mapset);
+	
+	return 0;
+}
+
+int seg_reset_map (SEG* seg, int value) {
+	/*
+	* set all cells in the map to value
+	*/
+int r,c;
+    for (r=0;r<seg->nrows;++r)
+  for (c=0;c<seg->ncols;++c)
+segment_put(&(seg->seg),&value,r,c);
+ }
+
+int seg_write_map(SEG* seg, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write seg to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */	
+	int output_fd;
+	int r, c;
+	void* output_buffer;
+	void* row;
+	struct History history;
+	
+		/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = seg->data_type;
+
+		if(output_data_type !=  seg->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+	
+	G_message(_("Writing map <%s>"),output_map_name);
+	output_fd=Rast_open_new(output_map_name,output_data_type);
+	output_buffer=Rast_allocate_buf(output_data_type);
+	segment_flush(&(seg->seg));
+	
+	/* writing */
+		for(r=0;r<seg->nrows;++r) {
+
+	G_percent(r, seg->nrows, 2);
+		if(0>segment_get_row(&(seg->seg),output_buffer,r)) 
+	G_warning(_("seg_write: Cannot segment read row %d for map %s"),
+		r,output_map_name);
+
+		if(convert_to_null) {
+
+				row = output_buffer;
+				switch (seg->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((CELL*)output_buffer)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(seg->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((FCELL*)output_buffer)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(seg->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((DCELL*)output_buffer)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(seg->data_size), 1);
+				break;
+			default: 
+					G_warning(_("ram_null:Cannot convert to null at: %d %d"),r,c);
+				}
+		}
+	Rast_put_row(output_fd, output_buffer, output_data_type);
+		}	
+
+	G_percent(r, seg->nrows, 2);
+	G_free(output_buffer);
+	Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("%s Done"), output_map_name);
+	
+	return 0;
+}
+
+int seg_release_map(SEG* seg) {
+/* 
+ * release segment close files, set pointers to null;
+ */ 
+	segment_release(&(seg->seg));
+	close(seg->fd);
+	unlink(seg->filename);
+
+		if(seg->map_name)
+	G_free(seg->map_name);
+		if(seg->mapset)
+	G_free(seg->mapset);
+
+return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.order/io.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/io.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/io.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/segment.h>
+
+#define NOT_IN_REGION(x) (r+nextr[(x)] < 0 || r+nextr[(x)] > (nrows-1) || c+nextc[(x)] < 0 || c+nextc[(x)] > (ncols-1))
+#define NR(x) r + nextr[(x)]
+#define NC(x) c + nextc[(x)]
+#define INDEX(r,c) (r)*ncols+(c)
+#define DIAG(x) (((x) + 4) > 8 ? ((x) - 4) : ((x) + 4));
+
+#define SROWS 256
+#define SCOLS 256
+
+typedef struct {
+	void** map; /* matrix of data */
+	double min, max; /* data range : may requre casting */
+	int nrows, ncols;
+	char* map_name; /* map name, unused */
+	RASTER_MAP_TYPE data_type; /* type of data */
+	size_t data_size; /* type of data */
+} MAP;
+
+typedef struct {
+	SEGMENT seg;		/* segmented data store */
+	int fd;					/* segment temporary file name descriptor */
+	char* filename; /* segment temporary file name */
+	char* map_name; /* map name converted to segment */
+	char* mapset;
+	int nrows, ncols; /* store nrows and rcols */
+	RASTER_MAP_TYPE data_type; /* data type of the map */
+	size_t data_size; /* size of cell returned by sizeof */
+	double min, max; /* data range */
+} SEG;
+
+
+/* all in ram functions */
+int ram_create_map(MAP*, RASTER_MAP_TYPE);
+int ram_read_map	(MAP* , char*, int, RASTER_MAP_TYPE);
+int ram_reset_map	(MAP*, int);
+int ram_write_map	(MAP*, char*, RASTER_MAP_TYPE, int, double);
+int ram_destory_map(MAP*);
+
+/* memory swap functions */
+int seg_create_map(SEG*, int, int, int, RASTER_MAP_TYPE);
+int seg_read_map	(SEG*, char*, int, RASTER_MAP_TYPE);
+int seg_reset_map (SEG*, int);
+int seg_write_map	(SEG*, char*, RASTER_MAP_TYPE, int, double);
+int seg_release_map(SEG*);
+

Added: grass-addons/grass7/raster/r.stream/r.stream.order/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/local_proto.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,29 @@
+#include "io.h"
+#include "local_vars.h"
+
+/* stream init */
+int stream_init(int min_index_of_stream, int max_index_of_stream);
+int stream_sample_map(char* input_map_name, int number_of_streams, int what);
+
+/* stream topology */
+int ram_stream_topology(CELL** streams, CELL** dirs, int number_of_streams);
+int ram_stream_geometry(CELL** streams, CELL** dirs);
+int seg_stream_topology(SEGMENT* streams, SEGMENT* dirs, int number_of_streams);
+int seg_stream_geometry(SEGMENT* streams, SEGMENT* dirs);
+
+/* stream order */
+int strahler(int* strahler);
+int shreve(int* shreve);
+int horton(const int* strahler, int* horton, int number_of_streams);
+int hack(int* hack, int* topo_dim, int number_of_streams);
+
+/* stream raster close */
+int ram_close_raster_order(CELL** streams, int number_of_streams, int zerofill);
+int seg_close_raster_order(SEGMENT* streams, int number_of_streams, int zerofill);
+
+/* stream vector */
+int ram_create_vector(CELL** streams, CELL** dirs, char* out_vector, int number_of_streams);
+int seg_create_vector(SEGMENT* streams, SEGMENT* dirs, char* out_vector, int number_of_streams);
+int stream_add_table (int number_of_streams);
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.order/local_vars.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/local_vars.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/local_vars.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+
+#ifdef MAIN
+#  define GLOBAL
+#else
+#  define GLOBAL extern
+#endif
+
+typedef enum {o_streams, o_dirs, o_elev, o_accum, input_size } inputs;
+/* eny new oredering systems must be also declared here before orders_size*/
+typedef enum {o_strahler, o_horton, o_shreve, o_hack, o_topo, orders_size } orders;
+
+typedef struct {
+	char* name;
+	int required;
+	char* description;
+} IO;
+
+typedef struct {
+    int stream;	/* topology */
+    int next_stream;
+    int trib_num;
+    int trib[5];
+    int cells_num;
+    int init; /* index to recalculate into r,c*/
+    int outlet; /* index to recalculate into r,c */
+    double length;   /* geometry */ 
+    double accum_length;
+    double distance; /* distance to outlet */
+    double stright; /* use next to calculate sinusoid */
+    double accum;
+    double init_elev;
+    double outlet_elev; /* use next to calculate drop and gradient */
+} STREAM;
+
+GLOBAL char** output_map_names;
+GLOBAL int ** all_orders;
+
+GLOBAL int nextr[9];
+GLOBAL int nextc[9];
+GLOBAL int nrows, ncols;
+GLOBAL int use_vector, use_accum;
+
+
+/* stream topo */
+GLOBAL int init_num, outlet_num;
+GLOBAL STREAM* stream_attributes;
+GLOBAL unsigned int* init_streams;
+GLOBAL unsigned int* outlet_streams;
+GLOBAL unsigned long int* init_cells;
+
+/* output vector */
+GLOBAL struct Map_info Out; 
+
+
+
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.order/main.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/main.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/main.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,276 @@
+/****************************************************************************
+ *
+ * MODULE:			r.stream.order
+ * AUTHOR(S):		Jarek Jasiewicz jarekj amu.edu.pl
+ *							 
+ * PURPOSE:			Calculate Strahler's and more streams hierarchy
+ *							It use r.stream.extract or r.watershed output files: 
+ * 							stream, direction, accumulation and elevation. 
+ * 							The output are set of raster maps and vector file containing
+ * 							addational stream attributes.
+ *
+ * COPYRIGHT:		(C) 2009,2010 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.
+ *
+ *****************************************************************************/
+#define MAIN
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int nextr[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
+int nextc[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
+
+
+int main(int argc, char *argv[])
+{
+
+  IO input[] = {
+			{"streams",YES,"output of r.stream.extract or r.watershed"},
+			{"dirs",YES,"output of r.stream.extract or r.watershed"},
+			{"elevation",NO,"any type digital elevation model"},
+			{"accum",NO,"any type acc map created by r.watershed or used in r.stream.extract"}
+		};
+			
+		/* add new basic rdering here and in local_vars.h declaration 
+		 * it will be added to output without addational programing.
+		 * Ordering functions are to be added in stream_order.c file.
+		 * Addational operations may shall be done in common part sections
+		 * derivative orders (like Scheideggers/Shreve) shall be added only 
+		 * to table definition as a formula and to description file. */
+	IO output[] = {
+			{"strahler",NO,"Strahler's stream order"},
+			{"horton",NO,"Original Hortons's stream order"},
+			{"shreve",NO,"Shereve's stream magnitude"},
+			{"hack",NO,"Hack's streams or Gravelius stream hierarchy"},
+			{"topo",NO,"Topological dimension of streams"}
+		};
+  struct GModule *module;	/* GRASS module for parsing arguments */
+    
+	struct Option *opt_input[input_size];
+	struct Option *opt_output[orders_size];
+	struct Option *opt_swapsize;
+	struct Option *opt_vector;
+	struct Flag *flag_zerofill,	* flag_accum, *flag_segmentation;
+	
+	int output_num;		
+	int num_seg; /* number of segments */
+	int segmentation, zerofill;
+	int i; /* iteration vars */
+	int number_of_segs;
+	int number_of_streams;
+	char *in_streams=NULL, *in_dirs=NULL, *in_elev=NULL, *in_accum=NULL;
+	char *out_vector=NULL;
+	
+  G_gisinit(argv[0]);		
+
+  module = G_define_module();
+  module->description =
+	_("Calculate Strahler's and more streams hierarchy. Basic module for topological analysis of drainage network");
+	G_add_keyword("Strahler Stream Order");
+	G_add_keyword("Hack Streams");
+	G_add_keyword("Stream network topology");
+	G_add_keyword("Stream network geometry");
+	G_add_keyword("Nework vectorisation");
+
+		for (i=0;i<input_size;++i) {
+	opt_input[i] = G_define_standard_option(G_OPT_R_INPUT);
+  opt_input[i]->key = input[i].name;
+  opt_input[i]->required = input[i].required;
+  opt_input[i]->description = _(input[i].description);
+		}
+	
+	opt_vector = G_define_standard_option(G_OPT_V_OUTPUT);
+	opt_vector->key="vector";
+	opt_vector->required = NO;
+	opt_vector->description =_("OUTPUT vector file to write stream atributes");
+	opt_vector->guisection=_("Optional");
+
+			for (i=0;i<orders_size;++i) {
+	opt_output[i] = G_define_standard_option(G_OPT_R_OUTPUT);
+  opt_output[i]->key = output[i].name;
+  opt_output[i]->required = NO;
+  opt_output[i]->description = _(output[i].description);
+  opt_output[i]->guisection = _("Output orders");
+		}
+	
+	opt_swapsize = G_define_option();
+	opt_swapsize->key="memory";
+	opt_swapsize->type = TYPE_INTEGER;
+	opt_swapsize->answer = "300";
+	opt_swapsize->description =_("Max memory used in memory swap mode (MB)");
+	opt_swapsize->guisection=_("Optional");	
+
+	flag_zerofill = G_define_flag();
+  flag_zerofill->key = 'z';
+  flag_zerofill->description = _("Create zero-valued background instead of NULL");
+
+	flag_segmentation = G_define_flag();
+  flag_segmentation->key = 'm';
+  flag_segmentation->description = _("Use memory swap (operation is slow)");
+  
+  flag_accum = G_define_flag();
+  flag_accum->key = 'a';
+  flag_accum->description = _("Use flow accumulation to trace horton and hack models");
+	
+    if (G_parser(argc, argv))	/* parser */
+	exit(EXIT_FAILURE);
+	
+
+	/* check output names */	
+  zerofill=(flag_zerofill->answer != 0);
+  segmentation=(flag_segmentation->answer != 0);
+  use_accum = (flag_accum->answer != 0);
+  use_vector = (opt_vector->answer!=NULL);
+  
+  number_of_segs = (int)atof(opt_swapsize->answer);
+	number_of_segs < 32 ? (int)(32/0.12) : number_of_segs/0.12;
+
+			if(use_vector) 
+		if(!opt_input[o_elev]->answer || !opt_input[o_accum]->answer)
+	G_fatal_error(_("To calculate vector file both accum and elev are required"));
+			if(use_accum) 
+		if(!opt_input[o_accum]->answer)
+	G_fatal_error(_("with -a (use accumulation) accum map is required"));
+	
+			for (i=0;i<orders_size;++i) {
+		if(!opt_output[i]->answer)
+			continue;
+		if (G_legal_filename(opt_output[i]->answer) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), opt_output[i]->answer);
+	output_num++;
+			} /* end for */
+		if (!output_num && !opt_vector->answer)
+	G_fatal_error(_("You must select one or more output orders maps or insert the table name"));
+  
+    /* start */
+  in_streams=opt_input[o_streams]->answer;
+	in_dirs=opt_input[o_dirs]->answer;
+	in_elev=opt_input[o_elev]->answer;
+	in_accum=opt_input[o_accum]->answer;
+	out_vector=opt_vector->answer;
+	
+	output_map_names=(char**)G_malloc(orders_size*sizeof(char*));
+		for(i=0;i<orders_size;++i)
+	output_map_names[i]	= opt_output[i]->answer;
+	 
+  nrows = Rast_window_rows();
+  ncols = Rast_window_cols();
+    
+	/* ALL IN RAM VERSION */	
+		if (!segmentation) {
+	G_message("ALL IN RAM CALCULATION");
+	MAP map_streams, map_dirs;
+	CELL **streams, **dirs;
+
+	ram_create_map(&map_streams,CELL_TYPE);
+	ram_read_map(&map_streams,in_streams,1,CELL_TYPE);
+	ram_create_map(&map_dirs,CELL_TYPE);
+	ram_read_map(&map_dirs,in_dirs,1,CELL_TYPE);
+	stream_init((int)map_streams.min,(int)map_streams.max);
+	number_of_streams=(int)(map_streams.max+1);
+	streams=(CELL**)map_streams.map;
+	dirs=(CELL**)map_dirs.map;
+	
+	ram_stream_topology(streams,dirs,number_of_streams);
+	
+		if(out_vector || output_map_names[o_horton] || 
+			output_map_names[o_hack] || output_map_names[o_topo])
+	ram_stream_geometry(streams,dirs);
+
+/* common part */
+		if(use_vector) {
+	stream_sample_map(in_elev, number_of_streams, 0);
+	stream_sample_map(in_elev, number_of_streams, 1);
+		}
+		if(use_accum || use_vector)
+	stream_sample_map(in_accum, number_of_streams, 2);
+
+		if( output_map_names[o_strahler] || output_map_names[o_horton] || out_vector)
+	strahler(all_orders[o_strahler]);
+
+		if(output_map_names[o_horton] || out_vector)
+	horton(all_orders[o_strahler],all_orders[o_horton], number_of_streams);
+
+		if(output_map_names[o_shreve] || out_vector)
+	shreve(all_orders[o_shreve]);	
+
+		if(output_map_names[o_hack] || output_map_names[o_topo] || out_vector)
+	hack(all_orders[o_hack],all_orders[o_topo],number_of_streams);
+/* end of common part */
+
+		if(out_vector)
+	ram_create_vector(streams, dirs, out_vector, number_of_streams);
+	
+	ram_close_raster_order(streams, number_of_streams, zerofill);
+	ram_release_map(&map_streams);
+	ram_release_map(&map_dirs);
+	/* end ram section */
+}
+
+	/* SEGMENTATION VERSION */
+if (segmentation) {  
+  G_message("MEMORY SWAP CALCULATION: MAY TAKE SOME TIME!");
+  
+	SEG map_streams, map_dirs;
+	SEGMENT *streams, *dirs;
+		
+	seg_create_map(&map_streams,SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	seg_read_map(&map_streams,in_streams,1,CELL_TYPE);
+	seg_write_map(&map_streams,"test_streams",CELL_TYPE,0,0);
+	seg_create_map(&map_dirs,SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	seg_read_map(&map_dirs,in_dirs,1,CELL_TYPE);
+	stream_init((int)map_streams.min,(int)map_streams.max);
+	number_of_streams=(int)(map_streams.max+1);
+	streams=&map_streams.seg;
+	dirs=&map_dirs.seg;
+
+	seg_stream_topology(streams,dirs, number_of_streams);
+
+		if(out_vector || output_map_names[o_horton] || 
+			output_map_names[o_hack] || output_map_names[o_topo])
+	seg_stream_geometry(streams,dirs);
+
+/* common part */
+		if(use_vector) {
+	stream_sample_map(in_elev, number_of_streams, 0);
+	stream_sample_map(in_elev, number_of_streams, 1);
+		}
+		if(use_accum || use_vector)
+	stream_sample_map(in_accum, number_of_streams, 2);
+
+		if( output_map_names[o_strahler] || output_map_names[o_horton] || out_vector)
+	strahler(all_orders[o_strahler]);
+
+		if(output_map_names[o_horton] || out_vector)
+	horton(all_orders[o_strahler],all_orders[o_horton], number_of_streams);
+
+		if(output_map_names[o_shreve] || out_vector)
+	shreve(all_orders[o_shreve]);	
+
+		if(output_map_names[o_hack] || output_map_names[o_topo] || out_vector)
+	hack(all_orders[o_hack],all_orders[o_topo],number_of_streams);	
+/* end of common part */
+
+		if(out_vector)
+	seg_create_vector(streams,dirs, out_vector, number_of_streams);		
+	
+	seg_close_raster_order(streams, number_of_streams, zerofill);
+	seg_release_map(&map_streams);
+	seg_release_map(&map_dirs);
+	/* end segmentation section */
+}
+
+
+/* free */
+G_free(stream_attributes);
+G_free(init_streams);
+G_free(outlet_streams);
+G_free(init_cells);
+
+    exit(EXIT_SUCCESS);
+
+}
+

Added: grass-addons/grass7/raster/r.stream/r.stream.order/orders.png
===================================================================
(Binary files differ)


Property changes on: grass-addons/grass7/raster/r.stream/r.stream.order/orders.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: grass-addons/grass7/raster/r.stream/r.stream.order/r.stream.order.html
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/r.stream.order.html	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/r.stream.order.html	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,152 @@
+<h2>OPTIONS</h2>
+<DL>
+<DT><b>-z</b></DT>
+<DD>Creates zero-value background instead of NULL. For some reason (like map algebra calculation) zero-valued background may be required. This flag produces zero-filled background instead of null (default).</DD>
+<DT><b>-a</b></DT>
+<DD>Uses accumulation map instead of cumulated stream length to determine main branch at bifuraction. Works well only with SFD networks</DD>
+<DT><b>-m</b></DT>
+<DD>Only for very large data sets. Use segment library to optimise memory consumption during analysis</DD>
+<DT><b>stream network map</b></DT>
+<DD>Name of input stream map on which ordering will be performed produced by r.watershed or r.stream.extract. Because streams network produced by r.watershed and r.stream.extract may slighty differ in detail it is required to 
+use both stream and direction map produced by the same module. Stream background shall have NULL value or zero value. 
+Background values of NULL are by default produced by r.watershed and r.stream.extract. If not 0 or NULL use <a href="r.mapcalc.html">r.mapcalc</a> to set background values to null.  
+</DD>
+<DT><b>flow direction map</b></DT>
+<DD>Name of input direction map produced by r.watershed or r.stream.extract. If r.stream.extract output map is used, it only has non-NULL values in places where streams occur. NULL (nodata) cells are ignored, zero and negative values are valid direction data if they vary from -8 to 8 (CCW from East in steps of 45 degrees). Direction map shall be of type CELL values. Region resolution and map resoultion must be the same. 
+Also <em>stream</em> network and <em>direction</em> maps must have the same resolution. It is checked by default. If resolutions differ the module informs about it and stops. Region boundary
+and maps boundary may be differ but it may lead to unexpected results.</DD>
+<DT><b>accumulation map</b></DT>
+<DD>Flow accumulation (optional, not recommended): name of flow accumulation file produced by r.watershed or used in r.stream.extract. This map is an option only if Horton's or Hack's ordering is performed. Normally both Horton and Hack ordering is calculated on cumulative stream lrngth wchich is calculated internaly. Flow accumulation can be used if user want to calculate main stream as most accumulated stream. Flow accumulation map shall be of DCELL type, as is by default produced by r.watershed or converted do DCELL with r.mapcalc.</DD>
+<DT><b>elevation map</b></DT>
+<DD>Used to calculate geometrical properites of the network stored in the table.</DD>
+</DL>
+<h2>OUTPUTS</h2>
+
+<P>At least one output map is required: </p>
+<DL>
+<DT><b>vector</b></DT>
+<DD>Vector network with table where stream network topology can be stored. Because r.stream.order is prepared to work both with r.watershed and r.stream.extract, it may be yused to create correct vector from r.watershed results.<DD>
+
+<DT><b>strahler</b></DT>
+<DD>Name of Strahler's stream order output map: see notes for detail. </DD>
+
+<DT><b>shreve</b></DT>
+<DD>Name of Shreve's stream magnitude output map: see notes for detail.</DD>
+
+<DT><b>horton</b></DT>
+<DD>Name of Horton's stream order output map (require accum file): see notes for detail.</DD>
+
+<DT><b>hack</b></DT>
+<DD>Name of Hack's main streams output map : see notes for detail.</DD>
+
+<DT><b>top</b></DT>
+<DD>Name of topological dimensions streams output map: see notes for detail.</DD>
+</DL>
+
+<h2>DESCRIPTION</h2>
+<center>
+<h3>Stream ordering example:<h3>
+<img src=orders.png border=1><br>
+</center>
+
+<P>
+<H4>Strahler's stream order</H4>
+Strahler's stream order is a modification of Horton's streams order which fixes the ambiguity of Horton's ordering. 
+In Strahler's ordering the main channel is not determined; instead the ordering is based on the hierarchy of tributaries. The 	
+ordering follows these rules:
+<OL>
+<li>if the node has no children, its Strahler order is 1.
+<li>if the node has one and only one tributuary with Strahler greatest order i, and all other tributuaries have order less than i, then the order remains i.
+<li>if the node has two or more tributuaries with greatest order i, then the Strahler order of the node is i + 1.
+</OL>
+Strahler's stream ordering starts in initial links which assigns order one. It proceeds downstream. At every node it verifies that there are at least 2 equal tributaries with maximum order. If not it continues with highest order, if yes it increases the node's order by 1 and continues downstream with new order. 
+<BR>
+<B>Advantages and disadvantages of Strahler's ordering: </B>
+ Strahler's stream order has a good mathematical background. All catchments with streams in this context are directed graphs, oriented from the root towards the leaves. Equivalent definition of the Strahler number of a tree is that it is the height of the largest complete binary tree that can be homeomorphically embedded into the given tree; the Strahler number of a node in a tree is equivalent to the height of the largest complete binary tree that can be embedded below that node. The disadvantage of that methods is the lack of distinguishing a main channel which may interfere with the analytical process in highly elongated catchments
+
+<H4>Horton's stream order</H4>
+Horton's stream order applies to the stream as a whole but not to segments or links since the order on any channel remains unchanged from source till it "dies" in the higher order stream or in the outlet of the catchment. The main segment of the catchment gets the order of the whole catchment, while its tributaries get the order of their own subcatchments. The main difficulties of the Horton's order are criteria to be considered to distinguish between "true" first order segments and extension of higher order segments. Thqat is the reason why Horton's ordering has rather historical sense and is substituted by the more unequivocal Strahler's ordering system. There are no natural algorithms to order stream network according to Horton' paradigm. The algorithm used in r.stream.order requires to first calculate Strahler's stream order (downstream) and next recalculate to Horton ordering (upstream). To make a decision about proper ordering it uses first Strahler ordering, and next,
  if both branches have the same orders it uses flow accumulation to choose the actual link. The algorithm starts with the outlet, where the outlet link is assigned the corresponding Strahler order. Next it goes upstream and determines links according to Strahler ordering. If the orders of tributaries differ, the algorithm proceeds with the channel of highest order, if all orders are the same, it chooses that one with higher flow length rate or higher catchment area if accumulation is used. When it reaches the initial channel it goes back to the last undetermined branch, assign its Strahler order as Horton order and goes upstream to the next initial links. In that way stream orders remain unchanged from the point where Horton's order have been determined to the source. 
+  
+<BR>
+<B>Advantages and disadvantages of Horton's ordering:</B> 
+The main advantages of Horton's ordering is that it produces natural stream ordering with main streams and its tributaries. The main disadvantage is that it requires prior Strahler's ordering. In some cases this may result in unnatural ordering, where the highest order will be ascribed not to the channel with higher accumulation but to the channel which leads to the most branched parts of the the catchment. 
+<P>
+<H4>Shreve's stream magnitude</H4>
+That ordering method is similar to Consisted Associated Integers proposed by Scheidegger. It assigns magnitude of 1 for every initial channel. The magnitude of the following channel is the sum of magnitudes of its tributaries. The number of a particular link is the number of initials which contribute to it. 
+
+<H4>Scheidegger's stream magnitude</H4>
+That ordering method is similar to Shreve's stream magnitude. It assigns magnitude of 2 for every initial channel. The magnitude of the following channel is the sum of magnitudes of its tributaries. The number of a particular link is the number of streams -1 contributing to it. Consisted Associated Integers (Scheidegger) is aviallable only in attribute table. To achive Consisted Associated Integers (Scheidegger) raster the result of Shreve's magnitude is to be multiplied by 2: 
+<P>
+<code>r.mapcalc scheidegger=shreve*2</code>
+<P>
+<H4>Drwal's stream hierarchy (old style)</H4>
+That ordering method is a compromise between Strahler ordering and Shreve magnitude. It assigns order of 1 for every initial channel. The order of the following channel is calculated according Strahler formula, except, that streams which do not increase order of next channel are not lost. To increase next channel to the hiher order R+1 are require two channels of order R, or one R and two R-1 or one R, and four R-2 or one R, one R-1 and two R-2 etc. The the order of particular link show the possible value of Strahler'order if the network was close to idealised binary tree. Drwal's order is aviallable only in attribute table.To achive Drwal's raster the result of Shreve's magnitude is to be recalculated according formula: <b>floor(log(shreve,2))+1</b>
+<P>
+<code>r.mapcalc drwal=int(log(shreve,2))+1</code>
+<P>
+<B>Advantages and disadvantages of Drwal's hierarhy:</B> 
+The main advantages of Drwal's hierarchy is that it produces natural stream ordering with whcich takes into advantage both ordering and magnitude. It shows the real impact of particular links of the network run-off. The main desadvantage is that it minimise bifuraction ratio ot the network.
+
+<P>
+<H4>Hack's main streams or Gravelius order</H4>
+This method of ordering calculates main streams of main catchment and every subcatchments. Main stream of every catchment is set to 1, and consequently all its tributaries receive order 2. Their tributaries receive order 3 etc. The order of every stream remains constant up to its initial link. The route of every main stream is determined according to the maximum flow length value of particular streams. So the main stream of every subcatchment is the longest stream or strean with highest accumulation rate if accumulation map is used. In most cases the main stream is the longest watercourse of the catchment, but in some cases, when a catchment consists of both rounded and elongated subcatchments these rules may not be maintained. The algorithm assigns 1 to every outlets stream and goes upstream according to maximum flow accumulation of every branch. When it reaches an initial stream it step back to the first unassigned confluence. It assigns order 2 to unordered tributaries an
 d again goes upstream to the next initial stream. The process runs until all branches of all outlets are ordered. 
+<BR>
+<B>Advantages and disadvantages of main stream ordering:</B>
+The biggest advantage of that method is the possibility to compare and analyze topology upstream, according to main streams. Because all tributaries of main channel have order of 2, streams can be quickly and easily filtered and its proprieties and relation to main stream determined. The main disadvantage of that method is the problem with the comparison of subcatchment topology of the same order. Subcatchments of the same order may be both highly branched and widespread in the catchment area and a small subcatchment with only one stream. 
+<H4>Topological dimension streams order</H4>
+This method of ordering calculates topological distance of every stream from catchment outlet.
+<BR>
+
+<H4>Stream network topology table description connected with vector file</H4>
+<ul>
+	<li><b>cat</b> integer: category;
+	<li><b>stream</b>integer: stream number, usually equal to cat;
+	<li><b>next_stream</b> integer: stream to which contribute current stream (downstream);
+	<li><b>prev_streams</b>; two or more contributing streams (upstream);
+	<li><b>strahler</b> integer: Strahler's stream order:
+	<li><b>horton</b> integer: Hortons's stream order:
+	<li><b>shreve</b> integer: Shreve's stream magnitude;
+	<li><b>scheidegger</b> integer: Scheidegger's Consisted Associated Integers;
+	<li><b>drwal</b> integer: Drwal's stream hierarchy;
+	<li><b>hack</b> integer: Hack's main streams or Gravelius order;
+	<li><b>topo</b> integer: Topological dimension streams order;
+	<li><b>length</b> double precision: stream length;
+	<li><b>cum_length</b> double precision: length of stream from source;
+	<li><b>out_dist</b> double precision: distance of current stream init from outlet;
+	<li><b>stright</b> double precision: length of stream as stright line;
+	<li><b>sinusiod</b> double precision: fractal dimention: stream length/stright stream length;
+	<li><b>elev_init</b> double precision: elevation of  stream init;
+	<li><b>elev_outlet</b> double precision: elevation of  stream outlet;
+	<li><b>drop</b> double precision: difference between stream init and outlet + drop outlet;
+	<li><b>out_drop</b> double precision: drop at the outlet of the stream;
+	<li><b>gradient</b> double precision: drop/length;
+</ul>
+<h2>NOTES</H2>
+<P>
+Module can work only if direction map, stream map and region map has same settings. It is also required that stream map and direction map come from the same source. For lots of reason this limitation probably cannot be omitted. This means if stream map comes from r.stream.extract also direction map from r.stream.extract must be used. If stream network was generated with MFD method also MFD direction map must be used. Nowadays f direction map comes from r.stream.extract  must be patched by direction map from r.watershed. (with r.patch). 
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.watershed.html">r.watershed</a>,
+<a href="r.stream.extract.html">r.stream.extract</a>,
+<a href="r.stream.basins.html">r.stream.basins</a>,
+<a href="r.stream.stats.html">r.stream.stats</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+</em>
+
+<h2>REFERENCES</h2>
+Drwal, J., (1982), <i>Wykształecenie i organizacja sieci hydrograficznej jako podstawa oceny struktury odpływu na terenach młodoglacjalnych</i>, <b>Rozprawy i monografie</b>, Gdańsk 1982, 130 pp (in Polish)<p>
+Hack, J., (1957), <i>Studies of longitudinal stream profiles in Virginia and Maryland</i>, 
+<b>U.S. Geological Survey Professional Paper</b>, 294-B<p>
+Horton, R. E. (1945), <i>Erosional development of streams and their drainage basins: hydro-physical approach to quantitative morphology</i>,<b>Geological Society of America Bulletin</b> 56 (3): 275-370<BR>
+Scheidegger A. E., (1966), <i>Statistical Description of River Networks</i>. <b>Water Resour. Res.</b>, 2(4): 785-790
+Shreve, R.,  (1966),<i>Statistical Law of Stream Numbers</i>, <b>J. Geol.</b>, 74, 17-37.<p>
+Strahler, A. N. (1952), <i>Hypsometric (area-altitude) analysis of erosional topology</i>,<b>Geological Society of America Bulletin</b> 63 (11): 1117–1142<p>
+Strahler, A. N. (1957), <i>Quantitative analysis of watershed geomorphology</i>,<b>Transactions of the American Geophysical Union</b> 8 (6): 913–920.<p>
+Woldenberg, M. J., (1967), <i>Geography and properties of surfaces,</i> <b>Harvard Papers in Theoretical Geography</b>, 1: 95–189.
+
+<h2>AUTHOR</h2>
+Jarek  Jasiewicz
+</body>
+</html>

Added: grass-addons/grass7/raster/r.stream/r.stream.order/stream_init.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/stream_init.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/stream_init.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,122 @@
+#include "local_proto.h"
+int stream_init(int min_index_of_stream, int max_index_of_stream) {
+  int i,j;
+  int number_of_streams=max_index_of_stream;
+
+		if(max_index_of_stream==0)
+	G_fatal_error(_("Empty stream input map: check if a stream map"));
+		if(min_index_of_stream<0)
+	G_fatal_error(_("Stream map has negative values: check if a stream map"));
+
+	stream_attributes = (STREAM *) G_malloc((number_of_streams + 1) * sizeof(STREAM));
+    for (i = 0; i < max_index_of_stream+1; ++i) {
+	stream_attributes[i].next_stream = -1;
+	stream_attributes[i].stream = -1;
+	stream_attributes[i].trib_num = -1;
+	stream_attributes[i].trib[0] = 0;
+	stream_attributes[i].trib[1] = 0;
+	stream_attributes[i].trib[2] = 0;
+	stream_attributes[i].trib[3] = 0;
+	stream_attributes[i].trib[4] = 0;
+	stream_attributes[i].cells_num=0;
+	stream_attributes[i].init=0;
+	stream_attributes[i].outlet=0;
+	stream_attributes[i].length = 0.;
+	stream_attributes[i].accum_length = 0.;
+	stream_attributes[i].distance = 0.;
+	stream_attributes[i].stright = 0.;
+	stream_attributes[i].accum = 0.;
+	stream_attributes[i].init_elev = -10000;
+	stream_attributes[i].outlet_elev = -10000;
+    }
+    
+  all_orders=(int**)G_malloc(orders_size*sizeof(int*));
+		for(i=0;i<orders_size;++i)
+	all_orders[i]=(int*)G_malloc((number_of_streams+1)*sizeof(int));
+
+			for(i=0;i<orders_size;++i)
+		for(j=0;j<number_of_streams;++j)
+	all_orders[i][j]=-1;
+
+    return 0;
+}
+
+int compare_inits (const void *a, const void *b) {
+	return (*(STREAM **)a)->init - (*(STREAM **)b)->init;
+}
+
+int compare_outlets (const void *a, const void *b) {
+	return (*(STREAM **)a)->outlet - (*(STREAM **)b)->outlet;
+}
+
+int stream_sample_map(char* input_map_name, int number_of_streams, int what) {
+		
+	/* if what == 2 sample outputs only for accum map */
+	/* if what == 1 sample outputs only for elev map */
+	/* if what == 0 sample inits only for elev map) */
+	
+	char* mapset;
+	int input_map_fd;
+	int i;
+	int r, c, cur_row=-1;
+	RASTER_MAP_TYPE 	input_data_type;
+	size_t input_data_size;
+	void* input_buffer;
+	void* input_ptr;
+		
+	STREAM** pointers_to_stream;
+	pointers_to_stream=(STREAM**)G_malloc(sizeof(STREAM*)*(number_of_streams));
+		for (i=0;i<(number_of_streams);++i)
+	*(pointers_to_stream+i)=stream_attributes+i;
+	
+		if(what)
+	qsort(pointers_to_stream, (number_of_streams), sizeof(STREAM*), compare_outlets);
+		else
+	qsort(pointers_to_stream, (number_of_streams), sizeof(STREAM*), compare_inits);
+
+
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+	  if (mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), input_map_name);
+	input_map_fd  = Rast_open_old(input_map_name,mapset);
+	input_data_type = Rast_map_type(input_map_name,mapset);
+	input_data_size = Rast_cell_size(input_data_type);
+	input_buffer=Rast_allocate_buf(input_data_type);
+
+					for (i=0;i<(number_of_streams);++i) {
+				if (pointers_to_stream[i]->stream ==-1)
+			continue;	
+		
+			if(what) {
+		r = (int)pointers_to_stream[i]->outlet / ncols;
+		c = (int)pointers_to_stream[i]->outlet % ncols;
+			} else {
+		r = (int)pointers_to_stream[i]->init / ncols;
+		c = (int)pointers_to_stream[i]->init % ncols;	
+			}
+	
+			if(r>cur_row) {
+		Rast_get_row(input_map_fd,input_buffer,r,input_data_type);
+		input_ptr=input_buffer;
+			}
+			switch (what) {
+				case 0: /* inits for elev */
+		pointers_to_stream[i]->init_elev=
+			Rast_get_d_value(input_ptr+c*input_data_size, input_data_type);
+			break;
+				case 1: /* outlets for elev */
+		pointers_to_stream[i]->outlet_elev=
+			Rast_get_d_value(input_ptr+c*input_data_size, input_data_type);
+			break;
+				case 2: /* outlets for accum */
+		pointers_to_stream[i]->accum=
+			Rast_get_d_value(input_ptr+c*input_data_size, input_data_type);
+			break;
+		}	
+	}
+G_free(input_buffer);
+G_free(pointers_to_stream);
+return 0;
+}
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.order/stream_order.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/stream_order.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/stream_order.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,267 @@
+/* 
+   All algorithms used in analysis ar not recursive. For Strahler order and Shreve magnitude starts from initial channel and  proceed downstream. Algortitms try to assgin order for branch and if it is imposible start from next initial channel, till all branches are ordered.
+   For Hortor and Hack ordering it proceed upstream and uses stack data structure to determine unordered branch. 
+   Algorithm of Hack main stram according idea of Markus Metz.
+*/
+
+#include "local_proto.h"
+int strahler(int* strahler)
+{
+
+  int i, j, done = 1;
+  int cur_stream, next_stream;
+  int max_strahler = 0, max_strahler_num;
+  STREAM* SA=stream_attributes; /* for better code readability */
+
+    G_message(_("Calculating Strahler's stream order ..."));
+
+    for (j = 0; j < init_num; ++j) {	/* main loop on inits */
+
+	cur_stream = SA[init_streams[j]].stream;
+	do {			/* we must go at least once, if stream is of first order and is outlet */
+	    max_strahler_num = 1;
+	    max_strahler = 0;
+	    next_stream = SA[cur_stream].next_stream;
+
+	    if (SA[cur_stream].trib_num == 0) {	/* assign 1 for spring stream */
+		strahler[cur_stream] = 1;
+		cur_stream = next_stream;
+		done = 1;
+	    }
+	    else {
+		done = 1;
+
+		for (i = 0; i < SA[cur_stream].trib_num; ++i) {	/* loop for determining strahler */
+		    if (strahler[SA[cur_stream].trib[i]] < 0) {
+			done = 0;
+			break;	/* strahler is not determined, break for loop */
+		    }
+		    else if (strahler[SA[cur_stream].trib[i]] > max_strahler) {
+			max_strahler =  strahler[SA[cur_stream].trib[i]];
+			max_strahler_num = 1;
+		    }
+		    else if (strahler[SA[cur_stream].trib[i]] == max_strahler) {
+			++max_strahler_num;
+		    }
+		}		/* end determining strahler */
+
+			if (done == 1) {
+		strahler[cur_stream] =	(max_strahler_num >1) ?
+			 ++max_strahler : max_strahler;
+		   cur_stream = next_stream;	/* if next_stream<0 we in outlet stream */
+			}	
+
+	    }
+	} while (done && next_stream > 0);
+    }				/* end for of main loop */
+    return 0;
+}				/* end strahler */
+
+int shreve(int* shreve)
+{
+
+    int i, j, done = 1;
+    int cur_stream, next_stream;
+    int max_shreve = 0;
+    STREAM* SA=stream_attributes; /* for better code readability */
+
+    G_message(_("Calculating Shreve's stream magnitude, Scheidegger's consistent integer and Drwal's streams hierarchy (old style) ..."));
+
+    for (j = 0; j < init_num; ++j) {	/* main loop on inits */
+
+	cur_stream = SA[init_streams[j]].stream;
+	do {			/* we must go at least once, if stream is of first order and is outlet */
+
+	    max_shreve = 0;
+	    next_stream = SA[cur_stream].next_stream;
+
+	    if (SA[cur_stream].trib_num == 0) {	/* assign 1 for spring stream */
+
+		shreve[cur_stream] = 1;
+		cur_stream = next_stream;
+		done = 1;
+
+	    }
+	    else {
+		done = 1;
+
+		for (i = 0; i < SA[cur_stream].trib_num; ++i) {	/* loop for determining shreve */
+		    if (shreve[SA[cur_stream].trib[i]] < 0) {
+			done = 0;
+			break;	/* shreeve is not determined, break for loop */
+		    }
+		    else {
+			max_shreve += shreve[SA[cur_stream].trib[i]];
+		    }
+		}		/* end determining shreve */
+
+		if (done == 1) {
+		    shreve[cur_stream] = max_shreve;
+		    cur_stream = next_stream;	/* if next_stream<0 we in outlet stream */
+		}
+	    }
+
+	} while (done && next_stream > 0);
+    }				/* end main loop */
+    return 0;
+}				/* end shreeve */
+
+int horton(const int* strahler, int* horton, int number_of_streams) {
+
+  int *stack;
+  int stack_max=number_of_streams;
+  int top, i, j;
+  int cur_stream, cur_horton;
+  int max_strahler;
+  double max_accum, accum;
+  int up_stream = 0;
+  STREAM* SA=stream_attributes; /* for better code readability */
+
+    G_message(_("Calculating Hortons's stream order ..."));
+    stack = (int *)G_malloc(stack_max * sizeof(int));
+
+    for (j = 0; j < outlet_num; ++j) {
+	cur_stream = SA[outlet_streams[j]].stream;	/* outlet: init */
+	cur_horton = strahler[cur_stream];
+	stack[0] = 0;
+	stack[1] = cur_stream;
+	top = 1;
+
+	do {			/* on every stream */
+	    max_strahler = 0;
+	    max_accum = 0;
+
+	    if (SA[cur_stream].trib_num == 0) {	/* spring: go back on stack */
+
+		horton[cur_stream] = cur_horton;
+		cur_stream = stack[--top];
+
+	    }
+	    else if (SA[cur_stream].trib_num > 1) {	/* node */
+
+		up_stream = 0;	/* calculating up_stream */
+		for (i = 0; i < SA[cur_stream].trib_num; ++i) {
+		    if (horton[SA[cur_stream].trib[i]] < 0) {
+
+			if (strahler[SA[cur_stream].trib[i]] > max_strahler) {
+			    max_strahler =strahler[SA[cur_stream].trib[i]];
+			    max_accum =	(use_accum) ? SA[SA[cur_stream].trib[i]].accum :
+						SA[SA[cur_stream].trib[i]].accum_length;
+			    up_stream = SA[cur_stream].trib[i];
+
+			}
+			else if (strahler[SA[cur_stream].trib[i]] == max_strahler) {
+
+			accum = (use_accum) ? SA[SA[cur_stream].trib[i]].accum :
+						SA[SA[cur_stream].trib[i]].accum_length;
+			
+			   if (accum > max_accum) {
+			  max_accum =	(use_accum) ? SA[SA[cur_stream].trib[i]].accum :
+						SA[SA[cur_stream].trib[i]].accum_length;
+
+				up_stream = SA[cur_stream].trib[i];
+			    }
+			}
+		    }
+		}		/* end determining up_stream */
+
+		if (up_stream) {	/* at least one branch is not assigned */
+		    if (horton[cur_stream] < 0) {
+			horton[cur_stream] = cur_horton;
+		    }
+		    else {
+			cur_horton = strahler[up_stream];
+		    }
+		    cur_stream = up_stream;
+		    stack[++top] = cur_stream;
+
+		}
+		else {		/* all asigned, go downstream */
+		    cur_stream = stack[--top];
+
+		}		/* end up_stream */
+	    }			/* end spring/node */
+	} while (cur_stream);
+    }				/* end for outlets */
+    G_free(stack);
+    return 0;
+}
+
+int hack(int* hack, int* topo_dim, int number_of_streams) /* also calculate topological dimension */
+{
+
+    int *stack;
+    int top, i, j;
+    int cur_stream, cur_hack;
+    double accum, max_accum;
+    int up_stream = 0;
+		int stack_max=number_of_streams;  
+    double cur_distance=0;
+    int cur_topo_dim=0;
+		STREAM* SA=stream_attributes; /* for better code readability */
+
+    G_message(_("Calculating Hack's main streams and topological dimension..."));
+    stack = (int *)G_malloc(stack_max * sizeof(int));
+
+    for (j = 0; j < outlet_num; ++j) {
+
+	cur_stream = SA[outlet_streams[j]].stream;	/* outlet: init */
+	cur_hack = 1;
+	stack[0] = 0;
+	stack[1] = cur_stream;
+	top = 1;
+	
+	topo_dim[cur_stream]=top;
+	cur_distance=SA[cur_stream].distance=SA[cur_stream].length;
+	do {
+	    max_accum = 0;
+
+	    if (SA[cur_stream].trib_num == 0) {	/* spring: go back on stack */
+
+		hack[cur_stream] = cur_hack;
+		cur_stream = stack[--top];
+
+	    }
+	    else if (SA[cur_stream].trib_num > 1) {	/* node */
+		up_stream = 0;	/* calculating up_stream */
+
+		for (i = 0; i < SA[cur_stream].trib_num; ++i) {	/* determining upstream */
+		    if (hack[SA[cur_stream].trib[i]] < 0) {
+			
+			accum = (use_accum) ? SA[SA[cur_stream].trib[i]].accum :
+						SA[SA[cur_stream].trib[i]].accum_length;			
+			
+			if (accum > max_accum) {
+			  max_accum =	(use_accum) ? SA[SA[cur_stream].trib[i]].accum :
+						SA[SA[cur_stream].trib[i]].accum_length;
+				up_stream = SA[cur_stream].trib[i];
+			}
+		    }
+		}		/* end determining up_stream */
+
+		if (up_stream) {	/* at least one branch is not assigned */
+
+		    if (hack[cur_stream] < 0) {
+			hack[cur_stream] = cur_hack;
+				 }
+		    else {
+			cur_hack = hack[cur_stream];
+			++cur_hack;
+		    }
+
+			cur_distance=SA[cur_stream].distance;
+		  cur_stream = up_stream;
+		  stack[++top] = cur_stream;
+			SA[cur_stream].distance=cur_distance+SA[cur_stream].length;
+			topo_dim[cur_stream]=top;
+		}
+		else {		/* all asigned, go downstream */
+		    cur_stream = stack[--top];
+
+		}		/* end up_stream */
+	    }			/* end spring/node */
+	} while (cur_stream);
+    }				/* end for outlets */
+    G_free(stack);
+    return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.order/stream_raster_close.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/stream_raster_close.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/stream_raster_close.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,128 @@
+#include "local_proto.h"
+int ram_close_raster_order(CELL** streams, int number_of_streams, int zerofill) {
+	
+	G_message("Closing maps...");
+	int* output_fd;
+	int r, c, i, j;
+	CELL *output_buffer, *streams_buffer;
+	void* row;
+	struct History history;
+	size_t data_size;
+		
+	output_fd=(int*)G_malloc(orders_size*sizeof(int));
+		for(i=0;i<orders_size;++i) {
+			if(output_map_names[i]==NULL)
+				continue;
+	output_fd[i]=Rast_open_c_new(output_map_names[i]);
+	}
+
+	/* this is not very elegant but use for compatibility with seg version */
+	
+	data_size=Rast_cell_size(CELL_TYPE);
+	output_buffer=Rast_allocate_c_buf();
+
+			for(r=0;r<nrows;++r) {
+		streams_buffer=streams[r];
+
+	for(i=0;i<orders_size;++i) {
+	
+			if(output_map_names[i]==NULL)
+		continue;
+
+			if(zerofill)
+		memset(output_buffer,0,ncols*data_size);
+			else
+		Rast_set_c_null_value(output_buffer,ncols);	
+
+				for(c=0;c<ncols;++c)
+			if(streams_buffer[c]) 
+		output_buffer[c]=all_orders[i][streams_buffer[c]];
+		
+		Rast_put_c_row(output_fd[i], output_buffer);
+	} /* end i */
+			}		
+
+	G_free(output_buffer);
+		for(i=0;i<orders_size;++i)
+	G_free(all_orders[i]);
+	G_free(all_orders);
+
+	
+		for(i=0;i<orders_size;++i) {
+			if(output_map_names[i]==NULL)
+		continue;
+	Rast_close(output_fd[i]);
+  Rast_short_history(output_map_names[i], "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_names[i], &history);
+  G_message(_("%s Done"), output_map_names[i]);
+		}
+	
+	G_free(output_fd);
+  return 0;
+ }
+
+
+int seg_close_raster_order(SEGMENT* streams, int number_of_streams, int zerofill) {
+
+	int* output_fd;
+	int r, c, i, j;
+	CELL *output_buffer, *streams_buffer;
+	void* row;
+	struct History history;
+	size_t data_size;
+		
+	output_fd=(int*)G_malloc(orders_size*sizeof(int));
+		for(i=0;i<orders_size;++i) {
+			if(output_map_names[i]==NULL)
+				continue;
+	output_fd[i]=Rast_open_c_new(output_map_names[i]);
+	}
+		
+	data_size=Rast_cell_size(CELL_TYPE);
+	output_buffer=Rast_allocate_c_buf();
+	streams_buffer=Rast_allocate_c_buf();
+	segment_flush(streams);
+	
+			for(r=0;r<nrows;++r) {
+		if(0>segment_get_row(streams,streams_buffer,r)) 
+	G_warning(_("seg_write: Cannot segment read row %d for map %s"),
+		r,output_map_names[i]);
+	
+	for(i=0;i<orders_size;++i) {
+
+		if(output_map_names[i]==NULL)
+				continue;
+
+			if(zerofill)
+		memset(output_buffer,0,ncols*data_size);
+			else
+		Rast_set_c_null_value(output_buffer,ncols);	
+
+			for(c=0;c<ncols;++c)
+				if(!Rast_is_c_null_value(&streams_buffer[c]))
+		output_buffer[c]=all_orders[i][streams_buffer[c]];
+	
+	Rast_put_c_row(output_fd[i], output_buffer);
+	} /* end i */
+			}		
+
+	G_free(output_buffer);
+	G_free(streams_buffer);
+		for(i=0;i<orders_size;++i)
+	G_free(all_orders[i]);
+	G_free(all_orders);
+
+		for(i=0;i<orders_size;++i) {	
+			if(output_map_names[i]==NULL)
+		continue;
+	Rast_close(output_fd[i]);
+  Rast_short_history(output_map_names[i], "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_names[i], &history);
+  G_message(_("%s Done"), output_map_names[i]);
+		}
+	
+	G_free(output_fd);
+  return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.order/stream_topology.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/stream_topology.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/stream_topology.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,411 @@
+#include "local_proto.h"
+int ram_number_of_tribs (int r, int c, CELL** streams, CELL** dirs) {
+	
+	int trib = 0;
+  int i, j;
+ 
+			for (i = 1; i < 9; ++i) {
+				if(NOT_IN_REGION(i))
+		continue;
+		j = DIAG(i);
+				if (streams[NR(i)][NC(i)] && dirs[NR(i)][NC(i)] == j)
+		trib++;
+    }
+
+    if (trib > 5)
+	G_fatal_error(_("Error finding nodes. \
+		Stream and direction maps probably do not match..."));
+    if (trib > 3)
+	G_warning(_("Stream network may be too dense..."));
+
+   return trib;
+}
+
+int ram_stream_topology(CELL** streams, CELL** dirs, int number_of_streams) {
+
+  int d, i, j;		/* d: direction, i: iteration */
+  int r, c;
+  int next_r, next_c;
+  int trib_num, trib = 0;
+  int next_stream = -1, cur_stream;
+  STREAM* SA=stream_attributes; /* for better code readability */
+	
+  init_num = 0, outlet_num = 0;
+  
+  G_message(_("Finding nodes..."));
+
+  outlet_streams = (unsigned int *)G_malloc((number_of_streams) * 
+  sizeof(unsigned int));
+  init_streams = (unsigned int*)G_malloc((number_of_streams) * 
+  sizeof(unsigned int));
+  init_cells = (unsigned 
+  long int *)G_malloc((number_of_streams) * sizeof(unsigned 
+  long int));
+    // free at the end
+
+			for (r = 0; r < nrows; ++r)
+		for (c = 0; c < ncols; ++c)
+	if (streams[r][c]) {
+		trib_num=ram_number_of_tribs (r,c,streams,dirs);
+		trib = 0;
+		d = abs(dirs[r][c]);	/* r.watershed! */
+			if(d<1 || NOT_IN_REGION(d) || !streams[NR(d)][NC(d)])
+		next_stream = -1;
+			else 
+    next_stream = streams[NR(d)][NC(d)];
+
+		cur_stream = streams[r][c];
+
+		if (cur_stream != next_stream) {	/* junction: building topology */
+
+		    if (outlet_num > (number_of_streams - 1))
+			G_fatal_error(_("Error finding nodes. \
+				Stream and direction maps probably do not match..."));
+
+			SA[cur_stream].stream = cur_stream;
+			SA[cur_stream].next_stream = next_stream;
+
+				if (next_stream < 0) /* is outlet stream */
+			outlet_streams[outlet_num++] = cur_stream;
+		}
+		
+		if (trib_num == 0) {	/* is init */
+				if (init_num > (number_of_streams - 1))
+			G_fatal_error(_("Error finding nodes. \
+				Stream and direction maps probably do not match..."));
+
+			SA[cur_stream].trib_num = 0;
+			init_cells[init_num]=r*ncols+c;
+			init_streams[init_num++] = cur_stream;	/* collecting inits */
+		}
+
+		if (trib_num > 1) {	/* adding tributuaries */
+					SA[cur_stream].trib_num = trib_num;
+		    
+					for (i = 1; i < 9; ++i) {
+						if (trib > 4)
+				G_fatal_error(_("Error finding nodes. \
+					Stream and direction maps probably do not match..."));
+						if(NOT_IN_REGION(i))
+			  continue;
+				j = DIAG(i);
+				next_r=NR(i);
+				next_c=NC(i);
+						if (streams[next_r][next_c] &&	dirs[next_r][next_c] == j)
+				SA[cur_stream].trib[trib++] = streams[next_r][next_c];
+		    }		/* end for i... */
+		}
+	}			/* end if streams */
+    return 0;
+}
+
+int ram_stream_geometry(CELL** streams, CELL** dirs) {
+
+	int i, s, d;		/* s - streams index; d - direction */
+  int done = 1;
+  int r, c;
+  int next_r, next_c;
+  int prev_r, prev_c;
+  int cur_stream;
+  float cur_northing, cur_easting;
+  float next_northing, next_easting;
+  float init_northing, init_easting;
+  double cur_length=0.;
+  double cur_accum_length=0.;
+  STREAM* SA=stream_attributes; /* for better code readability */
+  struct Cell_head window;
+  
+  G_get_window(&window);
+	
+	G_message(_("Finding longest streams..."));
+	G_begin_distance_calculations();
+	
+	for (s=0; s<init_num; ++s) { /* main loop on springs */
+		r = (int)init_cells[s]/ncols;
+		c = (int)init_cells[s]%ncols;
+		cur_stream=streams[r][c];
+		cur_length=0;
+		done=1;
+		
+		SA[cur_stream].init=init_cells[s]; /* stored as index */
+		
+		init_northing = window.north - (r + .5) * window.ns_res;
+	  init_easting = window.west + (c + .5) * window.ew_res;
+		
+	while(done) {
+		 cur_northing = window.north - (r + .5) * window.ns_res;
+	   cur_easting = window.west + (c + .5) * window.ew_res;
+	
+		 d=abs(dirs[r][c]);
+		 next_r=NR(d);
+	   next_c=NC(d);
+
+		if (d<1 || NOT_IN_REGION(d) || !streams[next_r][next_c]) {
+			cur_length=(window.ns_res+window.ew_res)/2;
+			SA[cur_stream].accum_length += cur_length;
+			SA[cur_stream].length += cur_length;
+			SA[cur_stream].stright =
+				G_distance(cur_easting, cur_northing, init_easting,  init_northing);
+			SA[cur_stream].outlet=(r*ncols+c); /* add outlet to sorting */
+			break;
+		}
+
+		next_northing = window.north - (next_r + .5) * window.ns_res;
+		next_easting = 	window.west + (next_c + .5) * window.ew_res;
+		cur_length =	G_distance(next_easting, next_northing, cur_easting, cur_northing);
+		SA[cur_stream].accum_length += cur_length;
+		SA[cur_stream].length += cur_length;
+		prev_r=r;
+		prev_c=c;
+		r=next_r;
+		c=next_c;
+		 
+			if (streams[next_r][next_c] != cur_stream) {
+		SA[cur_stream].stright =
+		G_distance(next_easting, next_northing, init_easting,  init_northing);
+		init_northing = cur_northing;
+		init_easting = cur_easting;
+
+		SA[cur_stream].outlet=(prev_r*ncols+prev_c);
+		cur_stream=streams[next_r][next_c];
+
+		cur_accum_length=0;
+		SA[cur_stream].init=(r*ncols+c);
+
+				for (i = 0; i < SA[cur_stream].trib_num; ++i) {
+						if (SA[SA[cur_stream].trib[i]].accum_length == 0) {
+					done=0;
+					cur_accum_length=0;
+					break; /* do not pass accum*/
+						} 
+						if(SA[SA[cur_stream].trib[i]].accum_length>cur_accum_length) 
+					cur_accum_length=SA[SA[cur_stream].trib[i]].accum_length;
+				} /* end for i */
+			SA[cur_stream].accum_length=cur_accum_length;
+			}/* end if */
+		} /* end while */
+	} /* end for s*/
+return 0;
+}
+
+int seg_number_of_tribs (int r, int c, SEGMENT* streams, SEGMENT* dirs) {
+	
+	int trib = 0;
+  int i, j;
+  int streams_cell=0;
+  int dirs_cell=0;
+ 
+    for (i = 1; i < 9; ++i) {
+		if(NOT_IN_REGION(i))
+			continue;
+	
+	j = DIAG(i);
+
+	segment_get(streams,&streams_cell,NR(i),NC(i));
+	segment_get(dirs,&dirs_cell,NR(i),NC(i));
+			
+		if (streams_cell && dirs_cell == j)
+	trib++;
+    }
+    
+    if (trib > 5)
+	G_fatal_error(_("Error finding nodes. \
+		Stream and direction maps probably do not match..."));
+    if (trib > 3)
+	G_warning(_("Stream network may be too dense..."));
+
+   return trib;
+}
+
+int seg_stream_topology(SEGMENT* streams, SEGMENT* dirs, int number_of_streams) {
+
+  int d, i, j;		/* d: direction, i: iteration */
+  int r, c;
+  int next_r, next_c;
+  int trib_num, trib = 0;
+  int next_stream = -1, cur_stream;
+  int streams_cell, dirs_cell;
+  int next_streams_cell, trib_dirs_cell, trib_stream_cell;
+  STREAM* SA=stream_attributes; /* for better code readability */
+	
+  init_num = 0, outlet_num = 0;
+  
+  G_message(_("Finding nodes..."));
+
+  outlet_streams = (unsigned int *)G_malloc((number_of_streams) * 
+  sizeof(unsigned int));
+  init_streams = (unsigned int*)G_malloc((number_of_streams) * 
+  sizeof(unsigned int));
+  init_cells = (unsigned 
+  long int *)G_malloc((number_of_streams) * sizeof(unsigned 
+  long int));
+
+			for (r = 0; r < nrows; ++r) {
+			G_percent(r, nrows, 2);	
+		for (c = 0; c < ncols; ++c) {
+	segment_get(streams,&streams_cell,r,c);
+	segment_get(dirs,&dirs_cell,r,c);
+	
+	if (streams_cell) {
+		trib_num=seg_number_of_tribs (r,c,streams,dirs);
+		trib = 0;
+
+		d = abs(dirs_cell);	/* r.watershed! */
+			if(NOT_IN_REGION(d))
+		next_stream=-1;
+			else 
+		segment_get(streams,&next_streams_cell,NR(d),NC(d));
+		
+			if(d<1 || NOT_IN_REGION(d) || !next_streams_cell)
+		next_stream = -1;
+			else 
+		segment_get(streams,&next_stream,NR(d),NC(d));
+		
+		cur_stream = streams_cell;
+		
+		if (cur_stream != next_stream) {	/* junction: building topology */
+		    if (outlet_num > (number_of_streams - 1))
+			G_fatal_error(_("Error finding nodes. \
+				Stream and direction maps probably do not match..."));
+
+			SA[cur_stream].stream = cur_stream;
+			SA[cur_stream].next_stream = next_stream;
+
+				if (next_stream < 0) /* is outlet stream */
+			outlet_streams[outlet_num++] = cur_stream;
+		}
+		
+		if (trib_num == 0) {	/* is init */
+				if (init_num > (number_of_streams - 1))
+			G_fatal_error(_("Error finding nodes. \
+				Stream and direction maps probably do not match..."));
+
+			SA[cur_stream].trib_num = 0;
+			init_cells[init_num]=r*ncols+c;
+			init_streams[init_num++] = cur_stream;	/* collecting inits */
+		}
+
+		if (trib_num > 1) {	/* adding tributuaries */
+					SA[cur_stream].trib_num = trib_num;
+		    
+					for (i = 1; i < 9; ++i) {
+
+						if (trib > 4)
+				G_fatal_error(_("Error finding nodes. \
+					Stream and direction maps probably do not match..."));
+						if(NOT_IN_REGION(i))
+			  continue;
+				j = DIAG(i);
+				next_r = NR(i);
+				next_c = NC(i);
+				segment_get(streams,&trib_stream_cell,next_r,next_c);		
+				segment_get(dirs,&trib_dirs_cell,next_r,next_c);			
+						
+						if (trib_stream_cell &&
+							trib_dirs_cell == j)
+				SA[cur_stream].trib[trib++] = trib_stream_cell;
+		    }		/* end for i... */
+		}
+	}	/* end if streams */
+	}	} /* end r, c */
+    G_percent(r, nrows, 2);
+    return 0;
+}
+
+int seg_stream_geometry(SEGMENT* streams, SEGMENT* dirs) {
+
+	int i, s, d;		/* s - streams index; d - direction */
+  int done = 1;
+  int r, c;
+  int next_r, next_c;
+  int prev_r, prev_c;
+  int attrib_cells_num=0;
+  int cur_stream, next_stream, dirs_cell;
+  float cur_northing, cur_easting;
+  float next_northing, next_easting;
+  float init_northing, init_easting;
+  double cur_length=0.;
+  double cur_accum_length=0.;
+  STREAM* SA=stream_attributes; /* for better code readability */
+  struct Cell_head window;
+  
+  G_get_window(&window);
+	
+	G_message(_("Finding longest streams..."));
+	G_begin_distance_calculations();
+	
+	for (s=0; s<init_num; ++s) { /* main loop on springs */
+	G_percent(s, init_num, 2);
+		r = (int)init_cells[s]/ncols;
+		c = (int)init_cells[s]%ncols;
+		segment_get(streams,&cur_stream,r,c);
+		cur_length=0;
+		done=1;
+		
+		SA[cur_stream].init=init_cells[s]; /* stored as index */
+		
+		init_northing = window.north - (r + .5) * window.ns_res;
+	  init_easting = window.west + (c + .5) * window.ew_res;
+		
+		while(done) {
+		 cur_northing = window.north - (r + .5) * window.ns_res;
+	   cur_easting = window.west + (c + .5) * window.ew_res;
+		 		 
+		segment_get(dirs,&dirs_cell,r,c);
+		d=abs(dirs_cell);
+		next_r=NR(d);
+	  next_c=NC(d);
+			if(NOT_IN_REGION(d))
+		Rast_set_c_null_value(&next_stream,1);
+			else 
+		segment_get(streams,&next_stream,next_r,next_c);
+				
+		if (d<1|| NOT_IN_REGION(d) || !next_stream) {
+			cur_length=(window.ns_res+window.ew_res)/2;
+			SA[cur_stream].accum_length += cur_length;
+			SA[cur_stream].length += cur_length;
+			SA[cur_stream].stright =
+				G_distance(cur_easting, cur_northing, init_easting,  init_northing);
+			SA[cur_stream].outlet=(r*ncols+c); /* add outlet to sorting */
+			break;
+		}
+
+		next_northing = window.north - (next_r + .5) * window.ns_res;
+		next_easting = 	window.west + (next_c + .5) * window.ew_res;
+		cur_length =	G_distance(next_easting, next_northing, cur_easting, cur_northing);
+		SA[cur_stream].accum_length += cur_length;
+		SA[cur_stream].length += cur_length;
+		prev_r=r;
+		prev_c=c;
+		r=next_r;
+		c=next_c;
+		 
+			if (next_stream != cur_stream) {
+		SA[cur_stream].stright =
+		G_distance(next_easting, next_northing, init_easting,  init_northing);
+		init_northing = cur_northing;
+		init_easting = cur_easting;
+
+		SA[cur_stream].outlet=(prev_r*ncols+prev_c);
+		cur_stream=next_stream;
+		cur_accum_length=0;
+		SA[cur_stream].init=(r*ncols+c);
+						
+				for (i = 0; i < SA[cur_stream].trib_num; ++i) {
+						if (SA[SA[cur_stream].trib[i]].accum_length == 0) {
+					done=0;
+					cur_accum_length=0;
+					break; /* do not pass accum*/
+						} 
+						if(SA[SA[cur_stream].trib[i]].accum_length>cur_accum_length) 
+					cur_accum_length=SA[SA[cur_stream].trib[i]].accum_length;
+				} /* end for i */
+			SA[cur_stream].accum_length=cur_accum_length;
+			}/* end if */
+		} /* end while */
+	} /* end for s*/
+G_percent(s, init_num, 2);
+return 0;
+}
+
+	

Added: grass-addons/grass7/raster/r.stream/r.stream.order/stream_vector.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.order/stream_vector.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.order/stream_vector.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,377 @@
+#include "local_proto.h"
+int ram_create_vector(CELL** streams, CELL** dirs, char* out_vector, int number_of_streams) {
+
+	int i,j,d;
+	int r,c;
+	int next_r, next_c;
+	int index_cat=0;
+	int add_outlet=0;
+	int cur_stream;
+	float northing, easting;
+	struct Cell_head window;
+	struct line_pnts *Segments;
+	struct line_cats *Cats;
+  STREAM* SA=stream_attributes; /* for better code readability */
+	
+	G_get_window(&window);
+	Segments = Vect_new_line_struct();
+  Cats = Vect_new_cats_struct();
+	Vect_open_new(&Out, out_vector, 0);
+		
+	Vect_reset_line(Segments);
+	Vect_reset_cats(Cats);
+	
+	for (i=0;i<number_of_streams;++i) {
+
+			if(SA[i].stream==-1)
+		continue;	/* empty category */
+
+		add_outlet=0;
+		r = (int)SA[i].init / ncols;
+		c = (int)SA[i].init % ncols;
+
+		cur_stream=SA[i].stream;
+		Vect_cat_set(Cats,1,cur_stream);
+	  easting = window.west + (c + .5) * window.ew_res;		
+		northing = window.north - (r + .5) * window.ns_res;
+	  Vect_append_point(Segments, easting,northing, 0);
+	  Vect_write_line(&Out, GV_POINT, Segments, Cats);
+	  Vect_reset_line(Segments);
+	  Vect_append_point(Segments, easting,northing, 0);
+		
+				while (streams[r][c]==cur_stream) {
+			
+			d=abs(dirs[r][c]);
+			next_r=NR(d);
+			next_c=NC(d);
+			
+			easting = window.west + (next_c + .5) * window.ew_res;
+			northing = window.north - (next_r + .5) * window.ns_res;
+			Vect_append_point(Segments, easting, northing, 0);
+
+				if (d<1 || NOT_IN_REGION(d) || !streams[next_r][next_c]) {
+			add_outlet=1;
+			break;
+				}
+			r=next_r;
+			c=next_c;
+				} /* end while */
+		
+		Vect_cat_set(Cats, 1, cur_stream);
+		Vect_write_line(&Out, GV_LINE, Segments, Cats);
+		Vect_reset_line(Segments);
+		Vect_reset_cats(Cats);
+
+				if(add_outlet) {
+		Vect_cat_set(Cats, 1, 0);	
+		Vect_reset_line(Segments);
+		Vect_append_point(Segments, easting, northing, 0);
+		Vect_write_line(&Out, GV_POINT, Segments, Cats);
+		Vect_reset_line(Segments);
+		Vect_reset_cats(Cats);	
+			}
+	}
+
+/* build vector after adding table */
+	if(0<stream_add_table(number_of_streams))
+ G_warning(_("Cannot add table to vector %s"),out_vector);
+Vect_hist_command(&Out);
+Vect_build(&Out);
+Vect_close(&Out);
+
+return 0;
+}	
+
+int seg_create_vector(SEGMENT* streams, SEGMENT* dirs, char* out_vector, int number_of_streams) {
+
+	int i,j,d;
+	int r,c;
+	int next_r, next_c;
+	int index_cat=0;
+	int add_outlet;
+	int streams_cell, dirs_cell;
+	int cur_stream, next_stream;
+	float northing, easting;
+	struct Cell_head window;
+	struct line_pnts *Segments;
+	struct line_cats *Cats;
+  STREAM* SA=stream_attributes; /* for better code readability */
+	
+	G_get_window(&window);
+	Segments = Vect_new_line_struct();
+  Cats = Vect_new_cats_struct();
+	Vect_open_new(&Out, out_vector, 0); 
+	
+	Vect_reset_line(Segments);
+	Vect_reset_cats(Cats);
+	
+	for (i=0;i<number_of_streams;++i) {
+			if(SA[i].stream==-1)
+		continue;	
+
+		add_outlet=0;
+		r = (int)SA[i].init / ncols;
+		c = (int)SA[i].init % ncols;
+		
+		cur_stream=SA[i].stream;
+		Vect_cat_set(Cats,1,cur_stream);
+	  easting = window.west + (c + .5) * window.ew_res;		
+		northing = window.north - (r + .5) * window.ns_res;
+	  Vect_append_point(Segments, easting,northing, 0);
+	  Vect_write_line(&Out, GV_POINT, Segments, Cats);
+	  Vect_reset_line(Segments);
+	  Vect_append_point(Segments, easting,northing, 0);
+		
+		segment_get(streams,&streams_cell,r,c);
+				while (streams_cell==cur_stream) {
+			
+			segment_get(dirs,&dirs_cell,r,c);
+			d=abs(dirs_cell);
+			next_r=NR(d);
+			next_c=NC(d);
+			
+			easting = window.west + (next_c + .5) * window.ew_res;
+			northing = window.north - (next_r + .5) * window.ns_res;
+			Vect_append_point(Segments, easting, northing, 0);
+
+				if(NOT_IN_REGION(d))
+			Rast_set_c_null_value(&next_stream,1);
+				else 
+			segment_get(streams,&next_stream,next_r,next_c);
+			
+				if (d<1 || NOT_IN_REGION(d) ||!next_stream) {
+			add_outlet=1;
+			break;
+				}
+			r=next_r;
+			c=next_c;
+			segment_get(streams,&streams_cell,r,c);
+				} /* end while */
+		
+		Vect_cat_set(Cats, 1, cur_stream);
+		Vect_write_line(&Out, GV_LINE, Segments, Cats);
+		Vect_reset_line(Segments);
+		Vect_reset_cats(Cats);	
+		
+			if(add_outlet) {
+		Vect_cat_set(Cats, 1, 0);	
+		Vect_reset_line(Segments);
+		Vect_append_point(Segments, easting, northing, 0);
+		Vect_write_line(&Out, GV_POINT, Segments, Cats);
+		Vect_reset_line(Segments);
+		Vect_reset_cats(Cats);	
+			}		
+	}
+
+/* build vector after adding table */
+//	if(0<stream_add_table(number_of_streams))
+//G_warning(_("Cannot add table to vector %s"),out_vector);
+Vect_hist_command(&Out);
+Vect_build(&Out);
+Vect_close(&Out);
+return 0;
+}
+
+int stream_add_table (int number_of_streams) {	
+	
+	int i,j;
+	int max_trib=0;
+	struct field_info *Fi;
+	STREAM* SA=stream_attributes; /* for better code readability */
+	dbDriver *driver;
+	dbHandle handle;
+	dbString table_name, db_sql, val_string;
+	char *cat_col_name="cat";
+	char buf[1000];
+	char ins_prev_streams[50]; /* insert */
+		/* rest of table definition */
+	char* tab_cat_col_name="cat integer";
+	char* tab_stream="stream integer";
+	char* tab_next_stream="next_stream integer";
+	char* tab_prev_streams;
+	char* 	tab_orders="strahler integer, horton integer, shreve integer, hack integer, topo_dim integer";
+	char* tab_scheidegger="scheidegger integer";
+	char* tab_drwal_old="drwal_old integer";
+	char* tab_length="length double precision";
+	char* tab_stright="stright double precision";
+	char* tab_sinusoid="sinosoid double precision";
+	char* tab_cumlength="cum_length double precision";
+	char* tab_accum="flow_accum double precision";
+	char* tab_distance="out_dist double precision";
+	char* tab_elev_init="source_elev double precision";
+	char* tab_elev_outlet="outlet_elev double precision";
+	char* tab_drop="elev_drop double precision";
+	char* tab_out_drop="out_drop double precision";
+	char* tab_gradient="gradient double precision";
+		/* addational atrributes */
+	int scheidegger, drwal_old=-1;
+	double sinusoid=1, elev_drop, out_drop=0, gradient=-1;
+	double flow_accum;
+	char insert_orders[20]; /* must have to be increased if new orders are added */
+
+	db_init_string(&db_sql);
+	db_init_string(&val_string);
+	db_init_string(&table_name);
+	db_init_handle(&handle);
+	
+	Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE);
+  driver = db_start_driver_open_database(Fi->driver, Fi->database);
+
+	/* create table */
+			for (i=0;i<number_of_streams;++i) 
+		if (SA[i].trib_num>max_trib) 
+	max_trib=SA[i].trib_num;
+
+	switch (max_trib) {
+		case 2:
+	tab_prev_streams="prev_str01 integer, prev_str02 integer";
+	break;
+		case 3:
+	tab_prev_streams="prev_str01 integer, prev_str02 integer, prev_str03 integer";
+	break;
+		case 4:
+	tab_prev_streams="prev_str01 integer, prev_str02 integer, prev_str03 integer prev_str04 integer";
+	break;
+		case 5:
+	tab_prev_streams="prev_str01 integer, prev_str02 integer, prev_str03 integer prev_str04 integer, prev_str05 integer";
+	break;
+		default:
+	G_fatal_error("Error with number of tributuaries");
+	break;
+	}
+
+	sprintf(buf,"create table %s (%s, %s, %s, %s, %s, \
+																%s, %s, %s, %s, %s, \
+																%s, %s, %s, %s, %s, \
+																%s,	%s,	%s)",
+	Fi->table,
+	tab_cat_col_name, /* 1 */
+	tab_stream,
+	tab_next_stream,
+	tab_prev_streams,
+	tab_orders,				/* 5 */
+	tab_scheidegger,
+	tab_drwal_old,
+	tab_length,
+	tab_stright,			
+	tab_sinusoid, 		/* 10 */
+	tab_cumlength,
+	tab_accum, 
+	tab_distance,
+	tab_elev_init,		
+	tab_elev_outlet, 	/* 15 */
+	tab_drop, 
+	tab_out_drop,
+	tab_gradient 			/* 18 */
+		);
+	
+	db_set_string(&db_sql, buf);
+
+		if(db_execute_immediate(driver,&db_sql) !=DB_OK) {
+	db_close_database(driver);
+	db_shutdown_driver(driver);
+	G_warning("Cannot create table %s", db_get_string(&db_sql));
+	return -1;
+		}
+
+		if (db_create_index2(driver,Fi->table,cat_col_name) !=DB_OK)
+	G_warning(_("cannot create index on table"), Fi->table);
+	
+		if (db_grant_on_table(driver,Fi->table,
+			DB_PRIV_SELECT, DB_GROUP|DB_PUBLIC) !=DB_OK) {
+	G_warning(_("cannot grant privileges on table %s"), Fi->table);
+	return -1;
+	}
+	db_begin_transaction(driver);
+	
+	for (i=0;i<number_of_streams;++i) {
+		
+			if(SA[i].stream<0)
+		continue;
+		
+	/* calc addational parameters */
+		
+	scheidegger=(all_orders[o_shreve][i])*2;
+
+		if(all_orders[o_shreve][i]>0)
+	drwal_old = (int)(log(all_orders[o_shreve][i])/log(2))+1;
+	
+	sinusoid=-1;
+		if(SA[i].stright>0)
+	sinusoid = SA[i].length/SA[i].stright;
+
+	out_drop=0;
+		if(SA[i].next_stream>0)
+	out_drop = SA[i].outlet_elev - SA[SA[i].next_stream].init_elev;
+
+	elev_drop = (SA[i].init_elev-SA[i].outlet_elev)+out_drop;
+		if(elev_drop<0)
+	elev_drop=0;
+	
+	gradient = -1;	
+		if(SA[i].length>0)
+	gradient = elev_drop / SA[i].length;
+	
+	switch (max_trib) {
+			case 2:
+			sprintf(ins_prev_streams,"%d, %d",SA[i].trib[0],SA[i].trib[1]);
+		break;
+			case 3:
+			sprintf(ins_prev_streams,"%d ,%d, %d",SA[i].trib[0],SA[i].trib[1],SA[i].trib[2]);
+		break;
+			case 4:
+		sprintf(ins_prev_streams,"%d, %d, %d, %d",SA[i].trib[0],SA[i].trib[1],SA[i].trib[2],SA[i].trib[3]);
+		break;
+			case 5:
+		sprintf(ins_prev_streams,"%d, %d, %d, %d, %d",SA[i].trib[0],SA[i].trib[1],SA[i].trib[2],SA[i].trib[3],SA[i].trib[4]);
+		break;
+			default:
+			G_fatal_error("Error with number of tributuaries");
+		break;
+	}
+	
+	sprintf(insert_orders, "%d, %d, %d, %d, %d",
+		all_orders[0][i],all_orders[1][i],
+		all_orders[2][i],all_orders[3][i],all_orders[4][i]);	
+	
+		sprintf(buf,"insert into %s values(	%d, %d, %d, %s, %s, \
+																				%d, %d, %f, %f, %f, \
+																				%f, %f, %f, %f, %f, \
+																				%f,	%f, %f)",
+	Fi->table,
+	i, 									/* 1 */
+	SA[i].stream, 
+	SA[i].next_stream, 
+	ins_prev_streams,								/* buffer created before */
+	insert_orders,			/* 5 */			/* buffer created before */
+	scheidegger,
+	drwal_old,
+	SA[i].length,
+	SA[i].stright,			
+	sinusoid, 					/* 10 */
+	SA[i].accum_length,
+	fabs(SA[i].accum), 
+	SA[i].distance,
+	SA[i].init_elev,		
+	SA[i].outlet_elev, 	/* 15 */	
+	elev_drop, 
+	out_drop,
+	gradient 						/* 18 */
+		);
+
+	db_set_string(&db_sql,buf);
+
+		if(db_execute_immediate(driver,&db_sql) !=DB_OK) {
+	db_close_database(driver);
+	db_shutdown_driver(driver);
+	G_warning(_("Cannot inset new row: %s"), db_get_string(&db_sql));
+	return -1;
+		}
+	} /* end for */
+	
+	db_commit_transaction(driver);
+	db_close_database_shutdown_driver(driver);
+	Vect_map_add_dblink(&Out, 1, NULL, Fi->table,
+		cat_col_name, Fi->database, Fi->driver);
+	return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/Makefile
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/Makefile	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/Makefile	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../../..
+
+PGM = r.stream.stats
+
+LIBES = $(GISLIB) $(RASTERLIB) $(SEGMENTLIB)
+DEPENDENCIES = $(GISDEP) $(RASTERDEP) $(SEGMENTDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
+

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/io.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/io.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/io.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,523 @@
+#include "io.h"
+/* all in ram functions section */
+
+int ram_create_map(MAP* map, RASTER_MAP_TYPE data_type) {
+	
+	/* 
+	 * allocates 0 filled nrows*ncols map of type void;
+	 * map parameters are stored in structure;
+	 * map: map to be created;
+	 * map type to be created must be CELL, FCELL, DCELL;
+	 * */
+		
+	int r, c;
+		
+		if(data_type < 0 || data_type > 2)
+	G_fatal_error(_("ram_creat: Cannot create map of unrecognised type"));
+	
+	map->data_type=data_type;
+	map->map_name=NULL;
+	map->nrows = Rast_window_rows();
+  map->ncols = Rast_window_cols();
+  map->data_size=Rast_cell_size(data_type);
+
+/* preparing internal map */
+	switch (map->data_type) { 
+		case CELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(CELL *));
+			break;
+
+		case FCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(FCELL *));
+			break;
+		
+		case DCELL_TYPE:
+		map->map = G_calloc(map->nrows,sizeof(DCELL *));
+			break;
+	}
+
+		for (r = 0; r < map->nrows; ++r)
+	(map->map)[r] = G_calloc(map->ncols,map->data_size);	
+	
+	return 0;
+}
+
+int ram_read_map(MAP* map, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+/*
+ * Funciton read external map and put it in MAP structure (created with create_map)
+ * map: map to be read can be of any data type, read map is converted to target map if neccesary.
+ * input_map_name: name of the map to be read;
+ * map pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+
+	int r, c;
+  char *mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+  int input_map_fd;
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+  void* input_buffer=NULL;
+  void* input_pointer;
+
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+	    if (mapset == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), input_map_name);
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+  Rast_get_cellhd(input_map_name, mapset, &cellhd);
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || 
+			this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+	/* checking if input map is of required type */
+		if(check_data_type != map->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1)
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+
+  input_map_fd  = Rast_open_old(input_map_name, mapset);
+  input_data_size = Rast_cell_size(input_data_type);
+	
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	map->min=(double)min;
+	map->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(map->min), &(map->max));
+		}
+}
+/* end opening and checking */
+
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+  /* start reading */
+  G_message(_("Reading map <%s>"),input_map_name);
+
+			for (r = 0; r < map->nrows; ++r) {
+					G_percent(r, map->nrows, 2);
+
+			Rast_get_row(input_map_fd, input_buffer, r,input_data_type);
+			input_pointer=input_buffer;
+
+						for (c = 0; c < map->ncols; ++c)
+					if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type))
+				switch (map->data_type) {
+					case CELL_TYPE:
+						((CELL**)map->map)[r][c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL**)map->map)[r][c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL**)map->map)[r][c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("ram_open:Wrong internal data type"));
+						break;
+				}
+			}		/*end for r */
+
+  G_free(input_buffer);
+	G_percent(r, map->nrows, 2);
+	Rast_close(input_map_fd);
+  return 0;
+}				/* end create floating point map */
+
+int ram_reset_map(MAP* map, int value) {
+ /*
+	* set all cells in the map to value
+	*/
+	int r;
+
+		for (r=0;r<map->nrows;++r) 
+	memset((map->map)[r],value,map->ncols*map->data_size);
+	return 0;
+}
+
+int ram_write_map(MAP* map, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write map to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */
+	
+  int r, c;
+  int output_fd = 0;
+  struct History history;
+  void* row;
+
+	/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = map->data_type;
+
+		if(output_data_type != map->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+  
+  G_message(_("Writing map <%s>"),output_map_name);
+  output_fd = Rast_open_new(output_map_name, output_data_type);
+		
+		/* writing */
+		for (r = 0; r < map->nrows; ++r) {
+			G_percent(r, map->nrows, 2);
+					
+					if(convert_to_null) {
+			row = map->map[r];
+				switch (map->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((CELL*)row)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(map->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((FCELL*)row)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(map->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < map->ncols; ++c) 
+					if (((DCELL*)row)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(map->data_size), 1);
+				break;
+			default: 
+					G_debug(1,"ram_null:Cannot convert to null at: %d %d",r,c);
+					}
+				}
+		
+	Rast_put_row(output_fd, (map->map)[r], output_data_type);
+		}
+	G_percent(r, map->nrows, 2);	
+  Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("<%s> Done"), output_map_name);
+  return 0;
+}
+
+int ram_release_map (MAP* map) {
+	/* 
+	 * free memory allocated for map, set pointer to null;
+	 */ 
+	 int r;
+
+			for (r = 0; r < map->nrows; ++r)
+		G_free((map->map)[r]);
+  G_free(map->map);
+  map=NULL;
+  return 0;
+}
+
+
+/* memory swap functions section */
+
+
+int seg_create_map(SEG * seg, int srows, int scols, int number_of_segs, RASTER_MAP_TYPE data_type) {
+	/* create segment  and returns pointer to it;
+	 * seg must be declared first;
+	 * parameters are stored in structure;
+	 * seg: segment to be created;
+	 * srows, scols segment size
+	 * number of segs max number of segs stored in memory
+	 * data_type to be created must be CELL, FCELL, DCELL;
+	 */
+
+	char* filename;
+	int fd;
+	int local_number_of_segs;
+
+	seg->fd=-1;
+	seg->filename = NULL;
+	seg->map_name = NULL;
+	seg->mapset = NULL;
+	seg->data_type = data_type;
+	seg->nrows = Rast_window_rows();
+	seg->ncols = Rast_window_cols();
+
+	local_number_of_segs=(seg->nrows/srows+1)*(seg->ncols/scols+1);
+	number_of_segs=(number_of_segs>local_number_of_segs) ?
+		local_number_of_segs : number_of_segs;
+	
+	G_debug(3,"seg_creat:number of segments %d",number_of_segs);
+	
+	switch (seg->data_type) {
+		case CELL_TYPE:
+			seg->data_size=sizeof(CELL);
+			break;
+		case FCELL_TYPE:
+			seg->data_size=sizeof(FCELL);
+			break;
+		case DCELL_TYPE:
+			seg->data_size=sizeof(DCELL);
+			break;
+		default:
+		G_fatal_error(_("seg_create: unrecognisabe data type"));
+	}
+	
+	filename=G_tempfile();
+	fd=creat(filename,0666);
+	
+	if(0 > segment_format(fd,seg->nrows,seg->ncols,srows,scols,seg->data_size)) {
+		close(fd);
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot format segment"));
+	}
+	
+	close(fd);
+	if(0 > (fd = open(filename,2))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot re-open file"));
+	}
+	
+	if(0>(fd = segment_init(&(seg->seg),fd,number_of_segs))) {
+		unlink(filename);
+		G_fatal_error(_("seg_create: cannot init segment file or out of memory"));
+	}
+	
+	seg->filename = G_store(filename);
+	seg->fd = fd;
+	return 0;
+}
+
+int seg_read_map(SEG* seg, char* input_map_name, int check_res, RASTER_MAP_TYPE check_data_type) {
+	
+/*
+ * Funciton read external map and put it in SEG structure (created with seg_create_map)
+ * map to be read can be of any data type, read map is converted if neccesary.
+ * input_map_name: name of the map to be read;
+ * seg: pointer to map stucture (created with create_map);
+ * check_res: [1]: check res correspondence between region and map [0 no check];
+ * check_data_type [CELL, FCELL, DCELL] check if reading map is of particular type, [-1] no check;
+ */
+	
+	int input_fd;
+	int r,c;
+	char* mapset;
+	struct Cell_head cellhd, this_window;
+	char* maptypes[]= { "CELL", "FCELL", "DCELL" };
+	RASTER_MAP_TYPE input_data_type;
+	size_t input_data_size;
+	void* input_buffer=NULL;
+	void* target_buffer=NULL;
+	void* input_pointer=NULL;
+	
+	/* checking if map exist */
+	mapset = (char*)G_find_raster2(input_map_name, "");	
+    if (mapset == NULL)
+	G_fatal_error(_("seg_read:Raster map <%s> not found"), input_map_name);
+	seg->mapset=mapset;
+	
+	/* checking if region and input are the same */
+	G_get_window(&this_window);
+	Rast_get_cellhd(input_map_name, mapset, &cellhd);
+	
+	/* check resolution equal anyinteger check;  equal 0 no check*/
+			if(check_res)
+		if (this_window.ew_res != cellhd.ew_res || this_window.ns_res != cellhd.ns_res)
+	G_fatal_error(_("Region resolution and map %s resolution differs. \
+		Run g.region rast=%s to set proper region resolution"),
+		input_map_name, input_map_name);
+
+		if(check_data_type != seg->data_type)
+	G_debug(1,"ram_open:required map type and internal map type differs: conversion forced!");
+	input_data_type = Rast_map_type(input_map_name,mapset);	
+			if(check_data_type !=-1) 
+		if (input_data_type != check_data_type)
+	G_fatal_error(_("<%s> is not of type %s"), 
+		input_map_name, maptypes[check_data_type]);
+	
+	input_fd = Rast_open_old(input_map_name,mapset);
+	input_data_size = Rast_cell_size(input_data_type);
+
+{/* reading range */
+	struct Range map_range;
+	struct FPRange map_fp_range;
+	int min, max;
+
+		if(input_data_type==CELL_TYPE) {
+	Rast_init_range(&map_range);
+	Rast_read_range(input_map_name,mapset,&map_range);
+	Rast_get_range_min_max(&map_range, &min, &max);
+	seg->min=(double)min;
+	seg->max=(double)max;
+		}	
+		else {
+	Rast_init_fp_range(&map_fp_range);	
+	Rast_read_fp_range(input_map_name,mapset,&map_fp_range);
+	Rast_get_fp_range_min_max(&map_fp_range, &(seg->min), &(seg->max));
+		}
+}
+
+	/* end opening and checking */
+	
+	G_message(_("Reading map <%s>"),input_map_name);
+	input_buffer=Rast_allocate_buf(input_data_type);
+	
+	target_buffer=Rast_allocate_buf(seg->data_type); 
+
+		for (r=0; r<seg->nrows; ++r) {
+			G_percent(r, seg->nrows, 2);
+			Rast_get_row(input_fd,input_buffer,r,input_data_type);
+			input_pointer=input_buffer;
+			memset(target_buffer,0,seg->ncols*seg->data_size);
+
+							for (c = 0; c < seg->ncols; ++c) 
+						if(!Rast_is_null_value(input_pointer+c*input_data_size,input_data_type)) {
+				switch (seg->data_type) {
+					case CELL_TYPE:
+						((CELL*)target_buffer)[c] = 
+							Rast_get_c_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case FCELL_TYPE:
+						((FCELL*)target_buffer)[c] = 
+							Rast_get_f_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					case DCELL_TYPE:
+						((DCELL*)target_buffer)[c] = 
+							Rast_get_d_value(input_pointer+c*input_data_size, input_data_type);
+						break;
+					default:
+						G_fatal_error(_("Wrong internal data type"));
+						break;
+				}
+					}
+
+		if(0>segment_put_row(&(seg->seg),target_buffer,r)) {
+			G_free(input_buffer);
+			G_free(target_buffer);
+			Rast_close(input_fd);
+			G_fatal_error(_("seg_read: Cannot segment put row %d for map %s"),
+				r,input_map_name);
+				}
+	} /* end for row */
+		
+	G_percent(r, seg->nrows, 2);
+	Rast_close(input_fd);
+	G_free(input_buffer);
+	G_free(target_buffer);
+	
+	seg->map_name=G_store(input_map_name);
+	seg->mapset=G_store(mapset);
+	
+	return 0;
+}
+
+int seg_reset_map (SEG* seg, int value) {
+	/*
+	* set all cells in the map to value
+	*/
+int r,c;
+    for (r=0;r<seg->nrows;++r)
+  for (c=0;c<seg->ncols;++c)
+segment_put(&(seg->seg),&value,r,c);
+ }
+
+int seg_write_map(SEG* seg, char* output_map_name, RASTER_MAP_TYPE output_data_type, int convert_to_null, double value) {
+	/* 
+	 * write seg to disk with output_map_name and output_data_type [CELL, FCELL, DCELL];
+	 * if output_data_type = -1 than internal map type is used for output;
+	 * if output map != -1 and types differ data_type, conversion is forced
+	 * convert to null: check if convert to null a particular value in dataset;
+	 */	
+	int output_fd;
+	int r, c;
+	void* output_buffer;
+	void* row;
+	struct History history;
+	
+		/* check for output format */
+		if(output_data_type == -1)
+	output_data_type = seg->data_type;
+
+		if(output_data_type !=  seg->data_type)
+	G_debug(1,"ram_write:required map type and internal map type differs: conversion forced!");	
+	
+	G_message(_("Writing map <%s>"),output_map_name);
+	output_fd=Rast_open_new(output_map_name,output_data_type);
+	output_buffer=Rast_allocate_buf(output_data_type);
+	segment_flush(&(seg->seg));
+	
+	/* writing */
+		for(r=0;r<seg->nrows;++r) {
+
+	G_percent(r, seg->nrows, 2);
+		if(0>segment_get_row(&(seg->seg),output_buffer,r)) 
+	G_warning(_("seg_write: Cannot segment read row %d for map %s"),
+		r,output_map_name);
+
+		if(convert_to_null) {
+
+				row = output_buffer;
+				switch (seg->data_type) {
+			case CELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((CELL*)output_buffer)[c] == (CELL)value)
+				Rast_set_c_null_value(row+c*(seg->data_size), 1);
+				break;
+			case FCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((FCELL*)output_buffer)[c] == (FCELL)value)
+				Rast_set_f_null_value(row+c*(seg->data_size), 1);
+				break;
+			case DCELL_TYPE:
+				for (c = 0; c < seg->ncols; ++c) 
+					if (((DCELL*)output_buffer)[c] == (DCELL)value)
+				Rast_set_d_null_value(row+c*(seg->data_size), 1);
+				break;
+			default: 
+					G_warning(_("ram_null:Cannot convert to null at: %d %d"),r,c);
+				}
+		}
+	Rast_put_row(output_fd, output_buffer, output_data_type);
+		}	
+
+	G_percent(r, seg->nrows, 2);
+	G_free(output_buffer);
+	Rast_close(output_fd);
+  Rast_short_history(output_map_name, "raster", &history);
+  Rast_command_history(&history);
+  Rast_write_history(output_map_name, &history);
+  G_message(_("%s Done"), output_map_name);
+	
+	return 0;
+}
+
+int seg_release_map(SEG* seg) {
+/* 
+ * release segment close files, set pointers to null;
+ */ 
+	segment_release(&(seg->seg));
+	close(seg->fd);
+	unlink(seg->filename);
+
+		if(seg->map_name)
+	G_free(seg->map_name);
+		if(seg->mapset)
+	G_free(seg->mapset);
+
+return 0;
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/io.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/io.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/io.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/segment.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+
+#define NOT_IN_REGION(x) (r+nextr[(x)] < 0 || r+nextr[(x)] > (nrows-1) || c+nextc[(x)] < 0 || c+nextc[(x)] > (ncols-1))
+#define NR(x) r + nextr[(x)]
+#define NC(x) c + nextc[(x)]
+#define INDEX(r,c) (r)*ncols+(c)
+#define DIAG(x) (((x) + 4) > 8 ? ((x) - 4) : ((x) + 4));
+
+#define SROWS 256
+#define SCOLS 256
+
+typedef struct {
+	void** map; /* matrix of data */
+	double min, max; /* data range : may requre casting */
+	int nrows, ncols;
+	char* map_name; /* map name, unused */
+	RASTER_MAP_TYPE data_type; /* type of data */
+	size_t data_size; /* type of data */
+} MAP;
+
+typedef struct {
+	SEGMENT seg;		/* segmented data store */
+	int fd;					/* segment temporary file name descriptor */
+	char* filename; /* segment temporary file name */
+	char* map_name; /* map name converted to segment */
+	char* mapset;
+	int nrows, ncols; /* store nrows and rcols */
+	RASTER_MAP_TYPE data_type; /* data type of the map */
+	size_t data_size; /* size of cell returned by sizeof */
+	double min, max; /* data range */
+} SEG;
+
+
+/* all in ram functions */
+int ram_create_map(MAP*, RASTER_MAP_TYPE);
+int ram_read_map	(MAP* , char*, int, RASTER_MAP_TYPE);
+int ram_reset_map	(MAP*, int);
+int ram_write_map	(MAP*, char*, RASTER_MAP_TYPE, int, double);
+int ram_destory_map(MAP*);
+
+/* memory swap functions */
+int seg_create_map(SEG*, int, int, int, RASTER_MAP_TYPE);
+int seg_read_map	(SEG*, char*, int, RASTER_MAP_TYPE);
+int seg_reset_map (SEG*, int);
+int seg_write_map	(SEG*, char*, RASTER_MAP_TYPE, int, double);
+int seg_release_map(SEG*);
+

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/local_proto.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,26 @@
+#include "io.h"
+#include "local_vars.h"
+
+/* stats prepare */
+int fifo_insert(POINT point);
+POINT fifo_return_del(void);
+/* ram version */
+int ram_init_streams(CELL** streams, CELL** dirs, FCELL** elevation);
+int ram_calculate_streams(CELL** streams, CELL** dirs, FCELL** elevation);
+double ram_calculate_basins_area(CELL** dirs, int r, int c);
+int ram_calculate_basins(CELL** dirs);
+/* seg version */
+int seg_init_streams(SEGMENT* streams, SEGMENT* dirs, SEGMENT* elevation);
+int seg_calculate_streams(SEGMENT* streams, SEGMENT* dirs, SEGMENT* elevation);
+double seg_calculate_basins_area(SEGMENT* dirs, int r, int c);
+int seg_calculate_basins(SEGMENT* dirs);
+
+/* stats calculate */
+double stats_linear_reg(int max_order, double* statistic);
+int stats(int order_max);
+
+/* stats print */
+int print_stats(int order_max);
+int print_stats_total(void);
+int print_stats_orders(int order_max);
+

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/local_vars.h
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/local_vars.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/local_vars.h	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/glocale.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/vector.h>
+#include <grass/dbmi.h>
+
+#define SQRT2 1.414214
+	
+typedef struct {
+	int r, c;
+	int is_outlet;
+	} POINT;
+	
+typedef struct { 
+	int index;
+	int is_outlet;
+	int r, c; /* outlet */
+	float elev_diff;
+	float elev_spring, elev_outlet;
+	float slope; /* cumulative */
+	float gradient;
+	float length; /* cumulative */
+	int order;
+	double basin_area; /* basin order */
+	int cell_num;
+	} STREAM;	
+	
+typedef struct {
+	int order;
+	int stream_num;
+	double sum_length;
+	double avg_length;
+	double std_length;
+	float avg_slope;
+	float std_slope;
+	float avg_gradient;
+	float std_gradient;
+	double sum_area;
+	double avg_area;
+	double std_area;
+	float avg_elev_diff;
+	float std_elev_diff;
+	float bifur_ratio;
+	float std_bifur_ratio;
+	float reg_bifur_ratio;
+	float length_ratio;
+	float std_length_ratio;
+	float reg_length_ratio;
+	float area_ratio;
+	float std_area_ratio;
+	float reg_area_ratio;
+	float slope_ratio;
+	float std_slope_ratio;
+	float reg_slope_ratio;
+	float gradient_ratio;
+	float std_gradient_ratio;
+	float reg_gradient_ratio;
+	float stream_frequency;
+	float drainage_density;
+} STATS;
+
+
+
+#ifdef MAIN
+#	define GLOBAL
+#else
+#	define GLOBAL extern
+#endif
+
+GLOBAL int nextr[9];
+GLOBAL int nextc[9];
+
+GLOBAL double total_basins;
+GLOBAL int nrows, ncols; 
+
+GLOBAL POINT *fifo_points;
+GLOBAL int fifo_max;
+	
+GLOBAL int outlets_num; /* number outlets: index for stream statistics*/
+GLOBAL STREAM *stat_streams;
+GLOBAL STATS *ord_stats;
+GLOBAL STATS stats_total;
+
+
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/main.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/main.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/main.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,195 @@
+
+/****************************************************************************
+ *
+ * MODULE:       r.stream.stats
+ * AUTHOR(S):    Jarek Jasiewicz jarekj amu.edu.pl
+ *               
+ * PURPOSE:      Calculate Horton's statistics according stream network and elevation map.
+ *               Program calculates: Bifuarcation ratio, length ratio, area ratio, 
+ *               slope ratio and drainage density
+ *               It uses r.stream.order stream map map, r.watershed  direction map. and DEM
+ *               Stram input map shall contains streams ordered according Strahler's or
+ *               Horton's orders. It also can calculate Hack's laws as an option.
+ *               If input stream comes from r.stream.exteract direction map 
+ *               from r.stream.extract dir map must be patched with that of r.watersheed.
+ *
+ * COPYRIGHT:    (C) 2002,2010 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.
+ *
+ *****************************************************************************/
+#define MAIN
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+  int nextr[9] = { 0, -1, -1, -1, 0, 1, 1, 1, 0 };
+  int nextc[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 };
+
+
+int main(int argc, char *argv[])
+{
+
+  struct GModule *module;	
+  struct Option *in_dir_opt, /* options */
+								*in_stm_opt, 
+								*in_elev_opt,	
+								*opt_swapsize,
+								*opt_output;
+	
+	struct Flag		*flag_segmentation,
+								*flag_catchment_total,
+								*flag_orders_summary;
+														
+	char* filename;
+	int number_of_segs;
+  int outlets_num;
+  int order_max;
+  int segmentation, catchment_total, orders_summary; /*flags */
+
+    /* initialize GIS environment */
+    G_gisinit(argv[0]);		
+
+    /* initialize module */
+  module = G_define_module();
+  G_add_keyword("Horton statisctics");
+  module->description =
+	_("Calculate Horton's statistics for Strahler and Horton ordered networks created with r.stream.");
+  G_add_keyword("Horton's statistics");
+  G_add_keyword("Bifuracation ratio");
+  G_add_keyword("Drainege density");
+  G_add_keyword("Catchment statistics");
+
+  in_stm_opt = G_define_standard_option(G_OPT_R_INPUT);	
+  in_stm_opt->key = "streams";
+  in_stm_opt->description = "Name of streams mask input map";
+
+  in_dir_opt = G_define_standard_option(G_OPT_R_INPUT);	
+  in_dir_opt->key = "dirs";
+  in_dir_opt->description = "Name of flow direction input map";
+
+  in_elev_opt = G_define_standard_option(G_OPT_R_INPUT);	
+  in_elev_opt->key = "elevation";
+  in_elev_opt->description = "Name of elevation map";
+  
+  opt_swapsize = G_define_option();
+	opt_swapsize->key="memory";
+	opt_swapsize->type = TYPE_INTEGER;
+	opt_swapsize->answer = "300";
+	opt_swapsize->description =_("Max memory used in memory swap mode (MB)");
+	opt_swapsize->guisection=_("Optional");
+	
+	opt_output = G_define_standard_option(G_OPT_F_OUTPUT);
+  opt_output->required = NO;
+  opt_output->description =
+	_("Name for output file (if omitted output to stdout)");
+
+	flag_segmentation = G_define_flag();
+  flag_segmentation->key = 'm';
+  flag_segmentation->description = _("Use memory swap (operation is slow)");
+  
+  flag_catchment_total = G_define_flag();
+  flag_catchment_total->key = 'c';
+  flag_catchment_total->description = _("Print only catchment's statistics");
+  
+  flag_orders_summary = G_define_flag();
+  flag_orders_summary->key = 'o';
+  flag_orders_summary->description = _("Print only orders' statistics");
+
+    if (G_parser(argc, argv))	/* parser */
+	exit(EXIT_FAILURE);
+
+  segmentation = (flag_segmentation->answer != 0);
+  catchment_total = (flag_catchment_total->answer != 0);
+  orders_summary = (flag_orders_summary->answer !=0);
+
+  filename = opt_output->answer;
+			if (filename != NULL)
+		if (NULL == freopen(filename, "w", stdout))
+	G_fatal_error(_("Unable to open file <%s> for writing"), filename);
+  
+  nrows = Rast_window_rows();
+  ncols = Rast_window_cols();
+
+if(!segmentation) {
+	G_message(_("ALL IN RAM CALCULATION"));
+	MAP map_dirs, map_streams, map_distance, map_elevation;
+	CELL **streams, **dirs;
+  FCELL **elevation;
+
+	ram_create_map(&map_streams,CELL_TYPE);
+	ram_read_map(&map_streams,in_stm_opt->answer,1,CELL_TYPE);    
+  ram_create_map(&map_dirs,CELL_TYPE);
+	ram_read_map(&map_dirs,in_dir_opt->answer,1,CELL_TYPE);
+	ram_create_map(&map_elevation,FCELL_TYPE);
+	ram_read_map(&map_elevation,in_elev_opt->answer,0,-1);
+
+	streams=(CELL**)map_streams.map;
+	dirs=(CELL**)map_dirs.map;
+	elevation=(FCELL**)map_elevation.map;
+	order_max = (int)map_streams.max;
+	
+	ram_init_streams(streams,dirs,elevation);
+	ram_calculate_streams(streams,dirs,elevation);
+	ram_calculate_basins(dirs);
+	
+	stats(order_max);
+		if(!catchment_total && !orders_summary)
+  print_stats(order_max);
+		if(catchment_total)
+	print_stats_total();
+		if(orders_summary)
+	print_stats_orders(order_max);
+	
+	G_free(stat_streams);
+	G_free(ord_stats);
+	
+	ram_release_map(&map_streams);
+	ram_release_map(&map_dirs);
+	ram_release_map(&map_elevation);
+} 
+
+if(segmentation) {
+	G_message(_("MEMORY SWAP CALCULATION - MAY TAKE SOME TIME"));
+	SEG map_dirs, map_streams, map_elevation;
+	SEGMENT *streams, *dirs, *elevation;
+
+	number_of_segs = (int)atof(opt_swapsize->answer);
+	number_of_segs < 32 ? (int)(32/0.18) : number_of_segs/0.18;
+
+	seg_create_map(&map_streams,SROWS, SCOLS, number_of_segs, CELL_TYPE);
+	seg_read_map(&map_streams,in_stm_opt->answer,1,CELL_TYPE);
+	seg_create_map(&map_dirs,SROWS, SCOLS, number_of_segs,CELL_TYPE);
+	seg_read_map(&map_dirs,in_dir_opt->answer,1,CELL_TYPE);
+	seg_create_map(&map_elevation,SROWS, SCOLS, number_of_segs,FCELL_TYPE);
+	seg_read_map(&map_elevation,in_elev_opt->answer,0,-1);
+	
+	streams=&map_streams.seg;
+	dirs=&map_dirs.seg;
+	elevation=&map_elevation.seg;
+	order_max = (int)map_streams.max;
+
+	seg_init_streams(streams,dirs,elevation);
+	seg_calculate_streams(streams,dirs,elevation);
+	seg_calculate_basins(dirs);
+
+  stats(order_max);
+
+		if(!catchment_total && !orders_summary)
+  print_stats(order_max);
+		if(catchment_total)
+	print_stats_total();
+		if(orders_summary)
+	print_stats_orders(order_max);
+	
+	G_free(stat_streams);
+	G_free(ord_stats);
+
+	seg_release_map(&map_streams);
+	seg_release_map(&map_dirs);
+	seg_release_map(&map_elevation);
+
+}  
+  exit(EXIT_SUCCESS);
+}

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/r.stream.stats.html
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/r.stream.stats.html	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/r.stream.stats.html	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,106 @@
+<h2>OPTIONS</h2>
+<DL>
+<DT><b>-c</b></DT>
+<DD>Print only catchment's characteristics. Useful for shell script calculation or collecting data in external tables</DD>
+<DT><b>-o</b></DT>
+<DD>Print only prameters for every order. Usefull to visualise Horton's law with external software (see example)</DD>
+<DT><b>-m</b></DT>
+<DD>Only for very large data sets. Use segment library to optimise memory consumption during analysis</DD>
+<DT><b>stream</b></DT>
+<DD>Stream network: name of input stream map on which ordering will be performed produced by r.watershed or r.stream.extract. Because streams network produced by r.watershed and r.stream.extract may slighty differ in detail it is required to use both stream and direction map produced by the same module. Stream background shall have NULL value or zero value. Background values of NULL are by default produced by r.watershed and r.stream.extract. If not 0 or NULL use <a href="r.mapcalc.html">r.mapcalc</a> to set background values to null.  
+</DD>
+<DT><b>dir</b></DT>
+<DD>Flow direction: name of input direction map produced by r.watershed or r.stream.extract. If r.stream.extract output map is used, it only has non-NULL values in places where streams occur. NULL (nodata) cells are ignored, zero and negative values are valid direction data if they vary from -8 to 8 (CCW from East in steps of 45 degrees). Direction map shall be of type CELL values. Region resolution and map resoultion must be the same. 
+Also <em>stream</em> network map must have the same resolution. It is checked by default. If resolutions differ the module informs about it and stops. Region boundary and maps boundary may be differ but it may lead to unexpected results.</DD>
+
+<DT><b>elevation</b></DT>
+<DD>Elevation: name of input elevation map. Map can be of type CELL, FCELL or DCELL. It is not restricted to resolution of region settings as streams and dirs.</DD>
+
+<h2>OUTPUTS</h2>
+Output statistics are send to standard output. To redirect output to file use redirection operators: > or >>. If redirection is used, output messages are printed on stderr (ussually terminal) while statistics are written to the file. Statistics can be print as a formatted summary information with number of parameters or as a catchement's descriptive statistics and table with statistics for every order. 
+
+
+<h2>DESCRIPTION</h2>
+<P>
+Module r.stream.stats is prepared to calculate Hotron's statistics of drainage network.
+<P>
+These statistics are calculated according formulas given by R.Horton (1945). Because Horton do not defined precisely what is stream slope, it has been proposed  proposed 2 different approaches: first (slope) use cell-by-cell slope calculation, second (gradient) use difference between elevation of outlet and source of every channel to its length to calculate formula. Bifurcation ratio for every order is calculated acording formula: 
+<CODE>n_streams[1]/n_stream[i+1]</CODE>
+where i the current order and i+1 next higher order. For max order of the map number of streams is zero. Rest of the ratios are calculated in similar mode. The bifurcation and other ratios for the whole catchment (map) is calculated as mean i.e sum of all bifurcation ratio / max_order-1 (for max_order stream bifurcation ratio = 0)
+It is strongly recommended to extract stream network using basin map created with r.stream.basin. If whole stream order map is used the calculation will be performed but results may not have hydrological sense.
+
+For every order (std) means that statstic is calculated with standard deviation:
+<UL>
+<li>number of streams
+<li>total length of streams of  given order
+<li>total area of basins of given order 
+<li>drainage density
+<li>stream density
+
+<li>average length of streams of given order (std)
+<li>average slope (cell by cell inclination) of streams of given order (std)
+<li>average gradient (spring to outlet inclination ) of streams of given order (std)
+<li>average area of basins of given order (std)
+<li>avarage elevation difference of given order (std)
+<P>ratios:
+<li>bifuracation ratio
+<li>length ratio
+<li>sloope and gradient ratios
+<li>area ratio
+</UL>
+for the whole basin:
+<UL>
+<li>total number of streams
+<li>total length of streams 
+<li>total basin area
+<li>drainage density
+<li>stream density
+<P>ratios:
+<li>bifurcation ratio (std)
+<li>length ratio (std)
+<li>slope and gradient ratios (std)
+<li>area ratio (std)
+</ul>
+<P>
+For the whole basins ratios are calculated acording two formulas: as a mean of ratios for every order, or as a antilog of slope coeficient of the regression model: order vs. log10(parameter)
+
+<h2>NOTES</h2>
+<P>
+Module calculates statistics for all streams in input stream map.It is strongly recomended to extract only network of one basin, but it is not necessary for computation.  Streams for desired basin first can be extracted  with following mapcalc formula:
+
+<P>
+<CODE>echo 'sel_streams=if(basin==xxx,streams,null())'|r.mapcalc #xxx category of desired basin</CODE>
+<P>
+
+It is also possible to calculate Horton's statistics for Shreve ordering but it has no hydrological sense. Hack (or Gravelius hierarchy) main stream is not the same what so called Horton's reverse ordering (see: Horton 1945).
+<P>
+Module can work only if direction map, stream map and region map has same settings. It is also required that stream map and direction map come from the same source. For lots of reason this limitation probably cannot be omitted.   this means if stream map comes from r.stream.extract also direction map from r.stream.extract must be used. If stream network was generated with MFD method also MFD direction map must be used.
+
+<h2>EXAMPLE</h2>
+Create table with order statistics. This table can easily sended to exteranl program (like R) to be visulised:
+<PRE>
+<CODE>
+r.stream.stats -o streams=horton dirs=dirs elevation=elevation.10m > tmp_file
+R
+r=read.csv("tmp_file",skip=1,header=TRUE)
+plot(num_of_streams~order,data=r,log="y", 
+	main="Sperafish area", 
+	sub=paste("Bifurcation ratio: ",
+		round(1/10^model$coefficients[2],3)))
+model=lm(log10(num_of_streams)~order,data=r)
+abline(model)
+
+</CODE>
+</PRE>
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.watershed.html">r.watershed</a>,
+<a href="r.stream.extract.html">r.stream.extract</a>,
+<a href="r.stream.order.html">r.stream.order</a>,
+<a href="r.stream.basins.html">r.stream.basins</a>,
+<a href="r.mapcalc.html">r.mapcalc</a>,
+</em>
+
+<h2>AUTHOR</h2>
+Jarek Jasiewicz, Adam Mickiewicz University, Geoecology and Geoinformation Institute.

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/stats_calculate.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/stats_calculate.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/stats_calculate.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,270 @@
+#include "local_proto.h"
+double stats_linear_reg(int max_order, double* statistic) {
+
+int i;	
+double avg_x=0, avg_y=0;
+double sum_x_square=0;
+double sum_x_y=0;
+double sum_x=0;
+double avg_x_y=0;
+double avg_x_square;
+double result;
+
+	for (i=1;i<=max_order;++i) {
+		avg_y += statistic[i];
+		sum_x += i;
+		sum_x_square += i*i;
+		sum_x_y += i*statistic[i];
+	}	
+	avg_y /= (float)max_order;
+	avg_x = sum_x/(float)max_order;
+	avg_x_y = sum_x_y/(float)max_order;
+	avg_x_square = sum_x_square/max_order;
+	
+
+	result = (avg_x_y - avg_x * avg_y) / (avg_x_square - avg_x * avg_x);
+	return result;
+}
+
+int stats(order_max)
+{
+  int i;
+  int num, ord_num;
+  float snum, ord_snum;
+  float tmp_num;
+  double* statistic;
+  double tmp_bif_ratio;
+
+    ord_stats = (STATS *) G_malloc((order_max + 1) * sizeof(STATS));
+
+  stats_total.order = 0;
+  stats_total.stream_num = 0;
+  stats_total.sum_length = 0.;
+  stats_total.avg_length = 0.;
+  stats_total.std_length = 0.;
+  stats_total.avg_slope = 0.;
+  stats_total.std_slope = 0.;
+  stats_total.avg_gradient = 0.;
+  stats_total.std_gradient = 0.;
+  stats_total.sum_area = 0.;
+  stats_total.avg_area = 0.;
+  stats_total.std_area = 0.;
+  stats_total.avg_elev_diff = 0.;
+  stats_total.std_elev_diff = 0.;
+  stats_total.bifur_ratio = 0.;
+  stats_total.std_bifur_ratio = 0.;
+  stats_total.reg_bifur_ratio = 0.;
+  stats_total.length_ratio = 0.;
+  stats_total.std_length_ratio = 0.;
+  stats_total.reg_length_ratio = 0.;
+  stats_total.area_ratio = 0.;
+  stats_total.std_area_ratio = 0.;
+  stats_total.reg_area_ratio = 0.;
+  stats_total.slope_ratio = 0.;
+  stats_total.std_slope_ratio = 0.;
+  stats_total.reg_slope_ratio = 0.;
+  stats_total.gradient_ratio = 0.;
+  stats_total.std_gradient_ratio = 0.;
+  stats_total.reg_gradient_ratio = 0.;
+  stats_total.stream_frequency = 0.;
+  stats_total.drainage_density = 0.;
+
+    for (i = 0; i <= order_max; ++i) {
+	ord_stats[i].order = i;
+	ord_stats[i].stream_num = 0;
+	ord_stats[i].sum_length = 0.;
+	ord_stats[i].avg_length = 0.;
+	ord_stats[i].std_length = 0.;
+	ord_stats[i].avg_slope = 0.;
+	ord_stats[i].std_slope = 0.;
+	ord_stats[i].avg_gradient = 0.;
+	ord_stats[i].std_gradient = 0.;
+	ord_stats[i].sum_area = 0.;
+	ord_stats[i].avg_area = 0.;
+	ord_stats[i].std_area = 0.;
+	ord_stats[i].avg_elev_diff = 0.;
+	ord_stats[i].std_elev_diff = 0.;
+	ord_stats[i].bifur_ratio = 0.;
+	ord_stats[i].std_bifur_ratio = 0.;
+	ord_stats[i].length_ratio = 0.;
+	ord_stats[i].std_length_ratio = 0.;
+	ord_stats[i].area_ratio = 0.;
+	ord_stats[i].std_area_ratio = 0.;
+	ord_stats[i].slope_ratio = 0.;
+	ord_stats[i].std_slope_ratio = 0.;
+	ord_stats[i].gradient_ratio = 0.;
+	ord_stats[i].std_gradient_ratio = 0.;
+	ord_stats[i].stream_frequency = 0.;
+	ord_stats[i].drainage_density = 0.;
+    }
+    for (i = 0; i < outlets_num; ++i) {	/* recalculate and unify */
+	stat_streams[i].elev_diff =
+	    stat_streams[i].elev_spring - stat_streams[i].elev_outlet;
+	tmp_num =
+	    ((stat_streams[i].cell_num - 1) <
+	     1) ? 1 : stat_streams[i].cell_num - 1;
+	stat_streams[i].slope /= tmp_num;
+	stat_streams[i].gradient =
+	    stat_streams[i].elev_diff / stat_streams[i].length;
+
+	/* calculation */
+	ord_stats[stat_streams[i].order].stream_num++;
+	ord_stats[stat_streams[i].order].sum_length += stat_streams[i].length;
+	ord_stats[stat_streams[i].order].std_length +=
+	    (stat_streams[i].length * stat_streams[i].length);
+	ord_stats[stat_streams[i].order].avg_slope += stat_streams[i].slope;
+	ord_stats[stat_streams[i].order].std_slope +=
+	    (stat_streams[i].slope * stat_streams[i].slope);
+	ord_stats[stat_streams[i].order].avg_gradient +=
+	    stat_streams[i].gradient;
+	ord_stats[stat_streams[i].order].std_gradient +=
+	    (stat_streams[i].gradient * stat_streams[i].gradient);
+	ord_stats[stat_streams[i].order].sum_area +=
+	    stat_streams[i].basin_area;
+	ord_stats[stat_streams[i].order].std_area +=
+	    (stat_streams[i].basin_area * stat_streams[i].basin_area);
+	ord_stats[stat_streams[i].order].avg_elev_diff +=
+	    stat_streams[i].elev_diff;
+	ord_stats[stat_streams[i].order].std_elev_diff +=
+	    (stat_streams[i].elev_diff * stat_streams[i].elev_diff);
+    }
+
+    for (i = 1; i <= order_max; ++i) {
+
+	num = ord_stats[i].stream_num;
+	snum = (ord_stats[i].stream_num > 1) ?
+	    ((float)ord_stats[i].stream_num) / (ord_stats[i].stream_num -
+						1) : 0.;
+
+	ord_stats[i].avg_length = ord_stats[i].sum_length / num;
+	ord_stats[i].avg_slope = ord_stats[i].avg_slope / num;
+	ord_stats[i].avg_gradient = ord_stats[i].avg_gradient / num;
+	ord_stats[i].avg_area = ord_stats[i].sum_area / num;
+	ord_stats[i].avg_elev_diff = ord_stats[i].avg_elev_diff / num;
+
+	ord_stats[i].std_length = sqrt((ord_stats[i].std_length / num -
+					(ord_stats[i].avg_length *
+					 ord_stats[i].avg_length)) * snum);
+
+	ord_stats[i].std_slope = sqrt((ord_stats[i].std_slope / num -
+		(ord_stats[i].avg_slope *	ord_stats[i].avg_slope)) * snum);
+
+	ord_stats[i].std_gradient = sqrt((ord_stats[i].std_gradient / num -
+		(ord_stats[i].avg_gradient * ord_stats[i].avg_gradient)) * snum);
+
+	ord_stats[i].std_area = sqrt((ord_stats[i].std_area / num -
+		(ord_stats[i].avg_area * ord_stats[i].avg_area)) * snum);
+
+	ord_stats[i].std_elev_diff = sqrt((ord_stats[i].std_elev_diff / num -
+		(ord_stats[i].avg_elev_diff * ord_stats[i].avg_elev_diff)) * snum);
+
+	ord_stats[i - 1].bifur_ratio =
+	    ord_stats[i - 1].stream_num / (float)ord_stats[i].stream_num;
+	
+	ord_stats[i - 1].length_ratio =  (i==1) ? 0 :
+	    ord_stats[i].avg_length / ord_stats[i-1].avg_length;
+	
+	ord_stats[i].area_ratio =	(i==1) ? 0 :
+	    ord_stats[i].avg_area / ord_stats[i-1].avg_area;
+	
+	ord_stats[i - 1].slope_ratio =
+	    ord_stats[i - 1].avg_slope / ord_stats[i].avg_slope;
+	
+	ord_stats[i - 1].gradient_ratio =
+	    ord_stats[i - 1].avg_gradient / ord_stats[i].avg_gradient;
+	
+	ord_stats[i].stream_frequency =
+	    ord_stats[i].stream_num / ord_stats[i].sum_area;
+	
+	ord_stats[i].drainage_density =
+	    ord_stats[i].sum_length / ord_stats[i].sum_area;
+
+	/* total */
+	stats_total.stream_num += ord_stats[i].stream_num;
+	stats_total.sum_length += ord_stats[i].sum_length;
+
+	stats_total.bifur_ratio += ord_stats[i - 1].bifur_ratio;
+	stats_total.length_ratio += ord_stats[i - 1].length_ratio;
+	stats_total.area_ratio += ord_stats[i - 1].area_ratio;
+	stats_total.slope_ratio += ord_stats[i - 1].slope_ratio;
+	stats_total.gradient_ratio += ord_stats[i - 1].gradient_ratio;
+
+	stats_total.std_bifur_ratio +=
+	  (ord_stats[i - 1].bifur_ratio * ord_stats[i - 1].bifur_ratio);
+	stats_total.std_length_ratio +=
+	  (ord_stats[i - 1].length_ratio * ord_stats[i - 1].length_ratio);
+	stats_total.std_area_ratio +=
+	  (ord_stats[i - 1].area_ratio * ord_stats[i - 1].area_ratio);
+	stats_total.std_slope_ratio +=
+	  (ord_stats[i - 1].slope_ratio * ord_stats[i - 1].slope_ratio);
+	stats_total.std_gradient_ratio +=
+	  (ord_stats[i - 1].gradient_ratio * ord_stats[i - 1].gradient_ratio);
+
+    }				/* end for ... orders */
+  ord_num = order_max - 1;
+  ord_snum = (ord_num == 1) ? 0 : (float)ord_num / (ord_num - 1);
+
+  stats_total.order = order_max;
+  stats_total.sum_area = total_basins;
+  stats_total.sum_length = stats_total.sum_length;
+
+  stats_total.bifur_ratio = stats_total.bifur_ratio / ord_num;
+  stats_total.length_ratio = stats_total.length_ratio / ord_num;
+  stats_total.area_ratio = stats_total.area_ratio / ord_num;
+  stats_total.slope_ratio = stats_total.slope_ratio / ord_num;
+  stats_total.gradient_ratio = stats_total.gradient_ratio / ord_num;
+
+
+  stats_total.std_bifur_ratio =
+		sqrt((stats_total.std_bifur_ratio / ord_num -
+	  (stats_total.bifur_ratio * stats_total.bifur_ratio)) * ord_snum);
+
+  stats_total.std_length_ratio = sqrt((stats_total.std_length_ratio / ord_num -
+	  (stats_total.length_ratio * stats_total.length_ratio)) * ord_snum);
+
+  stats_total.std_area_ratio = sqrt((stats_total.std_area_ratio / ord_num -
+		(stats_total.area_ratio * stats_total.area_ratio)) * ord_snum);
+
+  stats_total.std_slope_ratio =
+		sqrt((stats_total.std_slope_ratio / ord_num -
+	  (stats_total.slope_ratio * stats_total.slope_ratio)) * ord_snum);
+
+  stats_total.std_gradient_ratio =
+		sqrt((stats_total.std_gradient_ratio / ord_num -
+	  (stats_total.gradient_ratio * stats_total.gradient_ratio)) * ord_snum);
+
+  stats_total.stream_frequency =
+		stats_total.stream_num / stats_total.sum_area;
+  stats_total.drainage_density =
+		stats_total.sum_length / stats_total.sum_area;
+		
+		
+	/* linerar regresion statistics */
+		statistic = (double*)G_malloc((order_max+1)*sizeof(double));
+
+		for (i=1;i<=order_max;++i)
+	statistic[i]=log10((double)ord_stats[i].stream_num);
+	stats_total.reg_bifur_ratio=1/pow(10,stats_linear_reg(order_max,statistic));
+			
+		for (i=1;i<=order_max;++i)
+	statistic[i]=log10((double)ord_stats[i].avg_length);
+	stats_total.reg_length_ratio=pow(10,stats_linear_reg(order_max,statistic));
+	
+		for (i=1;i<=order_max;++i)
+	statistic[i]=log10((double)ord_stats[i].avg_area);
+	stats_total.reg_area_ratio=pow(10,stats_linear_reg(order_max,statistic));
+
+		for (i=1;i<=order_max;++i)
+	statistic[i]=log10((double)ord_stats[i].avg_slope);
+	stats_total.reg_slope_ratio=1/pow(10,stats_linear_reg(order_max,statistic));
+	
+		for (i=1;i<=order_max;++i)
+	statistic[i]=log10((double)ord_stats[i].avg_gradient);
+	stats_total.reg_gradient_ratio=1/pow(10,stats_linear_reg(order_max,statistic));
+
+	G_free(statistic);
+
+return 0;
+}
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/stats_prepare.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/stats_prepare.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/stats_prepare.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,463 @@
+#include "local_proto.h"
+static int tail, head, fifo_count;
+
+int fifo_insert(POINT point)
+{
+    if (fifo_count == fifo_max)
+	G_fatal_error("fifo queue: circular buffer too small");
+
+    fifo_points[tail++] = point;
+    if (tail > fifo_max) {
+	G_debug(1, "tail > fifo_max");
+	tail = 0;
+    }
+    fifo_count++;
+    return 0;
+}
+
+POINT fifo_return_del(void)
+{
+    if (head >= fifo_max) {
+	G_debug(1, "head >= fifo_max");
+	head = -1;
+    }
+    fifo_count--;
+	
+    return fifo_points[++head];
+}
+
+int ram_init_streams(CELL** streams, CELL** dirs, FCELL** elevation)
+{
+    int d, i, j;		/* d: direction, i: iteration */
+    int r, c;
+    int next_stream = -1, cur_stream;
+    int out_max = ncols + nrows;
+    POINT *outlets;
+
+    outlets = (POINT *) G_malloc((out_max) * sizeof(POINT));
+    outlets_num = 0;
+
+			for (r = 0; r < nrows; ++r) 
+		for (c = 0; c < ncols; ++c) 
+	if (streams[r][c] > 0) {
+
+			if (outlets_num > 2 * (out_max - 1))
+		G_fatal_error(_
+				("Stream and direction maps probably do not match"));
+			if (outlets_num > (out_max - 1))
+		outlets = (POINT *)G_realloc(outlets,out_max*2*sizeof(POINT));
+		
+		d = abs(dirs[r][c]);	
+			if (NOT_IN_REGION(d)) 
+		next_stream = -1;	/* border */
+			else {
+		    next_stream = streams[NR(d)][NC(d)];
+					if (next_stream < 1)
+				next_stream = -1;
+			}
+		
+			if (d == 0)
+		next_stream = -1;
+		cur_stream = streams[r][c];
+		
+		if (cur_stream != next_stream) {	/* is outlet or node! */
+		    outlets[outlets_num].r = r;
+		    outlets[outlets_num].c = c;
+				
+					if (next_stream==-1)
+				outlets[outlets_num].is_outlet=1;
+					else
+				outlets[outlets_num].is_outlet=0;	
+		    
+		    outlets_num++;
+		    
+		}
+	}			/* end if streams */
+
+    stat_streams = (STREAM *) G_malloc((outlets_num) * sizeof(STREAM));
+
+    for (i = 0; i < outlets_num; ++i) {
+	stat_streams[i].r = outlets[i].r;
+	stat_streams[i].c = outlets[i].c;
+	stat_streams[i].is_outlet = outlets[i].is_outlet;
+	stat_streams[i].index = i;
+	stat_streams[i].slope = 0.;
+	stat_streams[i].gradient = 0.;
+	stat_streams[i].length = 0.;
+	stat_streams[i].elev_diff = 0.;
+	stat_streams[i].elev_spring = 0.;
+	stat_streams[i].elev_outlet = elevation[outlets[i].r][outlets[i].c];
+	stat_streams[i].order = streams[outlets[i].r][outlets[i].c];
+	stat_streams[i].basin_area = 0.;
+	stat_streams[i].cell_num = 0;
+    }
+
+  G_free(outlets);
+  return 0;
+}
+
+
+int seg_init_streams(SEGMENT* streams, SEGMENT* dirs, SEGMENT* elevation)
+{
+    int d, i, j;		/* d: direction, i: iteration */
+    int r, c;
+    int next_stream = -1, cur_stream;
+    int out_max = ncols + nrows;
+    CELL streams_cell, dirs_cell, stream_next_cell;
+    FCELL elevation_cell;
+    POINT *outlets;
+
+    outlets = (POINT *) G_malloc((out_max) * sizeof(POINT));
+    outlets_num = 0;
+
+			for (r = 0; r < nrows; ++r) 
+		for (c = 0; c < ncols; ++c) {
+			segment_get(streams,&streams_cell,r,c);
+
+			if (outlets_num > 2 * (out_max - 1))
+		G_fatal_error(_
+				("Stream and direction maps probably do not match"));
+			if (outlets_num > (out_max - 1))
+		outlets = (POINT *)G_realloc(outlets,out_max*2*sizeof(POINT));
+		
+		segment_get(dirs,&dirs_cell,r,c);
+		d = abs(dirs_cell);	
+			if (NOT_IN_REGION(d)) 
+		next_stream = -1;	/* border */
+			else {
+		    segment_get(streams,&next_stream,NR(d),NC(d));
+					if (next_stream < 1)
+				next_stream = -1;
+			}
+		
+			if (d == 0)
+		next_stream = -1;
+		cur_stream=streams_cell;
+		
+		if (cur_stream != next_stream) {	/* is outlet or node! */
+		    outlets[outlets_num].r = r;
+		    outlets[outlets_num].c = c;
+				
+					if (next_stream==-1)
+				outlets[outlets_num].is_outlet=1;
+					else
+				outlets[outlets_num].is_outlet=0;	
+    
+		    outlets_num++;
+		    
+		}
+	}			/* end if streams */
+		
+
+    stat_streams = (STREAM *) G_malloc((outlets_num) * sizeof(STREAM));
+
+    for (i = 0; i < outlets_num; ++i) {
+	stat_streams[i].r = outlets[i].r;
+	stat_streams[i].c = outlets[i].c;
+	stat_streams[i].is_outlet = outlets[i].is_outlet;
+	stat_streams[i].index = i;
+	stat_streams[i].slope = 0.;
+	stat_streams[i].gradient = 0.;
+	stat_streams[i].length = 0.;
+	stat_streams[i].elev_diff = 0.;
+	stat_streams[i].elev_spring = 0.;
+	segment_get(elevation,&(stat_streams[i].elev_outlet),outlets[i].r,outlets[i].c);
+	segment_get(streams,&(stat_streams[i].order),outlets[i].r,outlets[i].c);	
+	stat_streams[i].basin_area = 0.;
+	stat_streams[i].cell_num = 0;
+    }
+
+  G_free(outlets);
+  return 0;
+}
+
+
+int ram_calculate_streams(CELL** streams, CELL** dirs, FCELL** elevation)
+{
+
+  int i, j, s, d;		/* s - streams index */
+  int done = 1;
+  int r, c;
+  int next_r, next_c;
+  float cur_northing, cur_easting;
+  float next_northing, next_easting;
+  float diff_elev;
+  double cur_length;
+  int cur_stream_order;
+	struct Cell_head window;
+	
+	G_get_window(&window);
+  G_begin_distance_calculations();
+
+    for (s = 0; s < outlets_num; ++s) {
+	r = stat_streams[s].r;
+	c = stat_streams[s].c;
+	
+	cur_northing = window.north - (r + .5) * window.ns_res;
+	cur_easting = window.west + (c + .5) * window.ew_res;
+	d= (dirs[r][c]==0) ? 2 : abs(dirs[r][c]);
+	
+	next_northing =
+		window.north - (NR(d) + .5) * window.ns_res;
+	next_easting =
+		window.west + (NC(d) + .5) * window.ew_res;
+
+	stat_streams[s].length=
+		G_distance(next_easting, next_northing, cur_easting,cur_northing);
+	
+	done = 1;
+
+	while (done) {
+		done = 0;
+		cur_northing = window.north - (r + .5) * window.ns_res;
+		cur_easting = window.west + (c + .5) * window.ew_res;
+
+		stat_streams[s].cell_num++;
+		stat_streams[s].elev_spring = elevation[r][c];
+
+	  for (i = 1; i < 9; ++i) {
+				if (NOT_IN_REGION(i))
+		  continue;	/* border */
+		
+		j = DIAG(i);
+		next_r=NR(i);
+		next_c=NC(i);
+			
+			if (streams[next_r][next_c] == stat_streams[s].order && 
+				dirs[next_r][next_c] == j) {
+
+		next_northing =
+			window.north - (next_r + .5) * window.ns_res;
+		next_easting =
+			window.west + (next_c + .5) * window.ew_res;
+		cur_length =
+			G_distance(next_easting, next_northing, cur_easting,cur_northing);
+		diff_elev =
+			elevation[next_r][next_c] -	elevation[r][c];
+		diff_elev = (diff_elev < 0) ? 0. : diff_elev;	/* water cannot flow up */
+
+		stat_streams[s].length += cur_length;
+		stat_streams[s].slope += (diff_elev / cur_length);
+
+		  r = next_r;
+		  c = next_c;
+		  done = 1;
+		  break;
+			}		/* end if */
+		}			/* end for i */
+	}			/* end while */
+    } /* end for s */
+  return 0;
+}
+
+
+////
+
+
+int seg_calculate_streams(SEGMENT* streams, SEGMENT* dirs, SEGMENT* elevation)
+{
+
+  int i, j, s, d;		/* s - streams index */
+  int done = 1;
+  int r, c;
+  int next_r, next_c;
+  float cur_northing, cur_easting;
+  float next_northing, next_easting;
+  float diff_elev;
+  double cur_length;
+  int cur_stream_order;
+	CELL streams_cell, dirs_cell;
+	FCELL elevation_cell, elevation_next_cell;
+	struct Cell_head window;
+	
+	G_get_window(&window);
+  G_begin_distance_calculations();
+
+    for (s = 0; s < outlets_num; ++s) {
+	r = stat_streams[s].r;
+	c = stat_streams[s].c;
+	
+	cur_northing = window.north - (r + .5) * window.ns_res;
+	cur_easting = window.west + (c + .5) * window.ew_res;
+	
+	segment_get(dirs,&dirs_cell,r,c);
+	d= (dirs_cell==0) ? 2 : abs(dirs_cell);
+	
+	next_northing =
+		window.north - (NR(d) + .5) * window.ns_res;
+	next_easting =
+		window.west + (NC(d) + .5) * window.ew_res;
+
+	stat_streams[s].length=
+		G_distance(next_easting, next_northing, cur_easting,cur_northing);
+	
+	done = 1;
+
+	while (done) {
+		done = 0;
+		cur_northing = window.north - (r + .5) * window.ns_res;
+		cur_easting = window.west + (c + .5) * window.ew_res;
+
+		stat_streams[s].cell_num++;
+		segment_get(elevation,&(stat_streams[s].elev_spring),r,c);
+
+	  for (i = 1; i < 9; ++i) {
+				if (NOT_IN_REGION(i))
+		  continue;	/* border */
+		
+		j = DIAG(i);
+		next_r=NR(i);
+		next_c=NC(i);
+	
+		segment_get(streams,&streams_cell,next_r,next_c);
+		segment_get(dirs,&dirs_cell,next_r,next_c);
+			
+			if (streams_cell == stat_streams[s].order && 
+				dirs_cell == j) {
+
+		next_northing =
+			window.north - (next_r + .5) * window.ns_res;
+		next_easting =
+			window.west + (next_c + .5) * window.ew_res;
+		cur_length =
+			G_distance(next_easting, next_northing, cur_easting,cur_northing);
+	
+		segment_get(elevation,&elevation_next_cell,next_r,next_c);
+		segment_get(elevation,&elevation_cell,r,c);
+		diff_elev =	elevation_next_cell -	elevation_cell;
+		diff_elev = (diff_elev < 0) ? 0. : diff_elev;	/* water cannot flow up */
+
+		stat_streams[s].length += cur_length;
+		stat_streams[s].slope += (diff_elev / cur_length);
+
+		  r = next_r;
+		  c = next_c;
+		  done = 1;
+		  break;
+			}		/* end if */
+		}			/* end for i */
+	}			/* end while */
+    } /* end for s */
+  return 0;
+}
+double ram_calculate_basins_area(CELL** dirs, int r, int c)
+{
+  int i, j;
+  int next_r, next_c;
+  double area;
+  POINT n_cell;
+
+  tail = 0;
+  head = -1;
+
+  area = G_area_of_cell_at_row(r);
+
+    while (tail != head) {
+	for (i = 1; i < 9; ++i) {
+	
+	    if (NOT_IN_REGION(i))
+		continue;	/* border */
+	
+	j = DIAG(i);
+	next_r=NR(i);
+	next_c=NC(i);	
+		
+		if (dirs[next_r][next_c] == j) {	/* countributing cell */
+	area += G_area_of_cell_at_row(r);
+	n_cell.r = next_r;
+	n_cell.c = next_c;
+	fifo_insert(n_cell);
+	  }
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+    } /* end while */
+  return area;
+}
+
+
+int ram_calculate_basins(CELL** dirs)
+{
+  int i;
+  total_basins=0.;
+
+  G_begin_cell_area_calculations();
+  fifo_max = 4 * (nrows + ncols);
+  fifo_points = (POINT *) G_malloc((fifo_max + 1) * sizeof(POINT));
+
+    for (i = 0; i < outlets_num; ++i) {
+	stat_streams[i].basin_area =
+		ram_calculate_basins_area(dirs, stat_streams[i].r, stat_streams[i].c);
+
+		if (stat_streams[i].is_outlet)
+	total_basins += stat_streams[i].basin_area;
+		}
+    
+  G_free(fifo_points);
+  return 0;
+}
+
+double seg_calculate_basins_area(SEGMENT* dirs, int r, int c)
+{
+  int i, j;
+  int next_r, next_c;
+  double area;
+  CELL dirs_cell;
+  POINT n_cell;
+
+  tail = 0;
+  head = -1;
+
+  area = G_area_of_cell_at_row(r);
+
+    while (tail != head) {
+	for (i = 1; i < 9; ++i) {
+	
+	  if (NOT_IN_REGION(i))
+	continue;	/* border */
+	
+	j = DIAG(i);
+	next_r=NR(i);
+	next_c=NC(i);	
+	
+	segment_get(dirs,&dirs_cell,next_r,next_c);
+	
+		if (dirs_cell == j) {	/* countributing cell */
+	area += G_area_of_cell_at_row(r);
+	n_cell.r = next_r;
+	n_cell.c = next_c;
+	fifo_insert(n_cell);
+	  }
+	}			/* end for i... */
+
+	n_cell = fifo_return_del();
+	r = n_cell.r;
+	c = n_cell.c;
+    } /* end while */
+  return area;
+}
+
+int seg_calculate_basins(SEGMENT* dirs)
+{
+  int i;
+  total_basins=0.;
+
+  G_begin_cell_area_calculations();
+  fifo_max = 4 * (nrows + ncols);
+  fifo_points = (POINT *) G_malloc((fifo_max + 1) * sizeof(POINT));
+
+    for (i = 0; i < outlets_num; ++i) {
+	stat_streams[i].basin_area =
+	  seg_calculate_basins_area(dirs, stat_streams[i].r, stat_streams[i].c);
+		if (stat_streams[i].is_outlet)
+	total_basins += stat_streams[i].basin_area;
+		}
+    
+  G_free(fifo_points);
+  return 0;
+}
+
+
+

Added: grass-addons/grass7/raster/r.stream/r.stream.stats/stats_print.c
===================================================================
--- grass-addons/grass7/raster/r.stream/r.stream.stats/stats_print.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.stream/r.stream.stats/stats_print.c	2010-08-19 09:50:26 UTC (rev 43163)
@@ -0,0 +1,135 @@
+#include "local_proto.h"
+
+int print_stats(int order_max)
+{
+	
+    int i;
+
+    /* summary statistics */
+    fprintf(stdout, "\n");
+    fprintf(stdout, "Summary:\n");
+    fprintf(stdout,
+	    "Max order | Tot.N.str. | Tot.str.len. | Tot.area. | Dr.dens. | Str.freq. \n");
+    fprintf(stdout,
+	    "  (num)   |    (num)   |     (km)     |   (km2)   | (km/km2) | (num/km2) \n");
+    fprintf(stdout, " %8d | %10d | %12.4f | %9.4f | %8.4f | %7.4f \n",
+	    stats_total.order, stats_total.stream_num,
+	    stats_total.sum_length / 1000, stats_total.sum_area / 1000000,
+	    stats_total.drainage_density * 1000,
+	    stats_total.stream_frequency * 1000000);
+
+    fprintf(stdout, "\n");
+    fprintf(stdout, "Stream ratios based on regresion coefficient:\n");
+    fprintf(stdout, " Bif.rt. | Len.rt. | Area.rt. | Slo.rt. | Grd.rt. \n");
+    fprintf(stdout, " %7.4f | %7.4f | %8.4f | %7.4f | %7.4f\n",
+	    stats_total.reg_bifur_ratio,
+	    stats_total.reg_length_ratio,
+	    stats_total.reg_area_ratio,
+	    stats_total.reg_slope_ratio, 
+	    stats_total.reg_gradient_ratio);    
+    fprintf(stdout, "\n");    
+    fprintf(stdout, "Avaraged stream ratios with standard deviations:\n");
+    fprintf(stdout, " Bif.rt. | Len.rt. | Area.rt. | Slo.rt. | Grd.rt. \n");
+    fprintf(stdout, " %7.4f | %7.4f | %8.4f | %7.4f | %7.4f\n",
+	    stats_total.bifur_ratio,
+	    stats_total.length_ratio,
+	    stats_total.area_ratio,
+	    stats_total.slope_ratio, 
+	    stats_total.gradient_ratio);
+
+    fprintf(stdout, " %7.4f | %7.4f | %8.4f | %7.4f | %7.4f\n",
+	    stats_total.std_bifur_ratio,
+	    stats_total.std_length_ratio,
+	    stats_total.std_area_ratio,
+	    stats_total.std_slope_ratio, 
+	    stats_total.std_gradient_ratio);
+    fprintf(stdout, "\n");
+
+    /* base parameters */
+    fprintf(stdout,
+	    "Order | Avg.len |  Avg.ar  |  Avg.sl |  Avg.grad. | Avg.el.dif\n");
+    fprintf(stdout,
+	    " num  |   (km)  |  (km2)   |  (m/m)  |    (m/m)   |     (m)   \n");
+    for (i = 1; i <= order_max; ++i) {
+	fprintf(stdout, "%5d | %7.4f | %8.4f | %7.4f | %10.4f | %7.4f\n",
+		ord_stats[i].order,
+		ord_stats[i].avg_length / 1000,
+		ord_stats[i].avg_area / 1000000,
+		ord_stats[i].avg_slope,
+		ord_stats[i].avg_gradient, ord_stats[i].avg_elev_diff);
+    }
+    fprintf(stdout, "\n");
+    /* std dev of base parameters */
+    fprintf(stdout,
+	    "Order | Std.len |  Std.ar  |  Std.sl |  Std.grad. | Std.el.dif\n");
+    fprintf(stdout,
+	    " num  |   (km)  |  (km2)   |  (m/m)  |    (m/m)   |     (m)   \n");
+    for (i = 1; i <= order_max; ++i) {
+	fprintf(stdout, "%5d | %7.4f | %8.4f | %7.4f | %10.4f | %7.4f\n",
+		ord_stats[i].order,
+		ord_stats[i].std_length / 1000,
+		ord_stats[i].std_area / 1000000,
+		ord_stats[i].std_slope,
+		ord_stats[i].std_gradient, ord_stats[i].std_elev_diff);
+    }
+    /* sum statistics of orders */
+    fprintf(stdout, "\n");
+    fprintf(stdout, "Order | N.streams | Tot.len (km) | Tot.area (km2)\n");
+    for (i = 1; i <= order_max; ++i) {
+	fprintf(stdout, "%5d | %9d | %12.4f | %7.4f\n",
+		ord_stats[i].order,
+		ord_stats[i].stream_num,
+		ord_stats[i].sum_length / 1000,
+		ord_stats[i].sum_area / 1000000);
+    }
+    /* order ratios */
+    fprintf(stdout, "\n");
+    fprintf(stdout,
+	    "Order | Bif.rt. | Len.rt. | Area.rt. | Slo.rt. | Grd.rt. | d.dens. | str.freq.\n");
+    for (i = 1; i <= order_max; ++i) {
+	fprintf(stdout,
+		"%5d | %7.4f | %7.4f | %8.4f | %7.4f | %7.4f | %7.4f | %7.4f\n",
+		ord_stats[i].order, ord_stats[i].bifur_ratio,
+		ord_stats[i].length_ratio, ord_stats[i].area_ratio,
+		ord_stats[i].slope_ratio, ord_stats[i].gradient_ratio,
+		ord_stats[i].drainage_density * 1000,
+		ord_stats[i].stream_frequency * 1000000);
+    }
+}
+
+int print_stats_total(void) {
+	fprintf(stdout,"Catchment's characteristics (based on regresion):  \n");
+  fprintf(stdout,"Max order: %d \n",stats_total.order); 
+  fprintf(stdout,"Total number of streams: %d \n",stats_total.stream_num);
+  fprintf(stdout,"Total stream length (km): %2.4f \n",stats_total.sum_length / 1000);
+  fprintf(stdout,"Total cachment area (km2): %2.4f \n",stats_total.sum_area / 1000000);
+  fprintf(stdout,"Drainage density: %2.4f\n",stats_total.drainage_density * 1000); 
+  fprintf(stdout,"Stream frequency: %2.4f \n",stats_total.stream_frequency * 1000000);
+  fprintf(stdout,"Bifurcation ratio: %2.4f \n",stats_total.reg_bifur_ratio); 
+  fprintf(stdout,"Length ratio: %2.4f \n",stats_total.reg_length_ratio);
+  fprintf(stdout,"Area ratio: %2.4f \n",stats_total.reg_area_ratio);
+  fprintf(stdout,"Slope ratio: %2.4f \n",stats_total.reg_slope_ratio);
+  fprintf(stdout,"Gradient ratio: %2.4f \n",stats_total.reg_gradient_ratio); 
+  return 0;
+}
+
+int print_stats_orders(int order_max) {
+
+	int i;
+  fprintf(stdout,"Order's summary: \n");
+  fprintf(stdout,"order,num_of_streams,avg_length,avg_area,avg_slope,avg_grad,avg_elev.diff,sum_length,sum_area\n");
+
+    for (i = 1; i <= order_max; ++i) {
+	fprintf(stdout, "%d,%d,%f,%f,%f,%f,%f,%f,%f\n",
+		ord_stats[i].order,
+		ord_stats[i].stream_num,
+		ord_stats[i].avg_length / 1000,
+		ord_stats[i].avg_area / 1000000,
+		ord_stats[i].avg_slope,
+		ord_stats[i].avg_gradient, 
+		ord_stats[i].avg_elev_diff,
+		ord_stats[i].sum_length / 1000,
+		ord_stats[i].sum_area / 1000000);
+    }
+  return 0;
+}



More information about the grass-commit mailing list