[GRASS-SVN] r48495 - in grass-addons/raster/r.pi: . r.pi.corearea r.pi.corrwin r.pi.corrwindow r.pi.csr.mw r.pi.energy r.pi.energy.iter r.pi.enn r.pi.enn.iter r.pi.export r.pi.fnn r.pi.graph r.pi.graph.dec r.pi.graph.iter r.pi.graph.red r.pi.grow r.pi.import r.pi.index r.pi.lm r.pi.neigh r.pi.nlm r.pi.nlm.circ r.pi.nlm.stats r.pi.odc r.pi.prob.mw r.pi.prox r.pi.rectangle r.pi.searchtime r.pi.searchtime.iter r.pi.searchtime.mw

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Sep 27 07:32:35 EDT 2011


Author: neteler
Date: 2011-09-27 04:32:34 -0700 (Tue, 27 Sep 2011)
New Revision: 48495

Added:
   grass-addons/raster/r.pi/FIXES_markus.txt
   grass-addons/raster/r.pi/TODO.txt
   grass-addons/raster/r.pi/r.pi.corearea/
   grass-addons/raster/r.pi/r.pi.corearea/Makefile
   grass-addons/raster/r.pi/r.pi.corearea/description.html
   grass-addons/raster/r.pi/r.pi.corearea/description_TO_BE_integrated.html
   grass-addons/raster/r.pi/r.pi.corearea/frag.c
   grass-addons/raster/r.pi/r.pi.corearea/func.c
   grass-addons/raster/r.pi/r.pi.corearea/helpers.c
   grass-addons/raster/r.pi/r.pi.corearea/local_proto.h
   grass-addons/raster/r.pi/r.pi.corearea/main.c
   grass-addons/raster/r.pi/r.pi.corearea/prop_method.c
   grass-addons/raster/r.pi/r.pi.corearea/stat_method.c
   grass-addons/raster/r.pi/r.pi.corrwindow/
   grass-addons/raster/r.pi/r.pi.corrwindow/Makefile
   grass-addons/raster/r.pi/r.pi.corrwindow/bufs.c
   grass-addons/raster/r.pi/r.pi.corrwindow/description.html
   grass-addons/raster/r.pi/r.pi.corrwindow/divr_cats.c
   grass-addons/raster/r.pi/r.pi.corrwindow/gather.c
   grass-addons/raster/r.pi/r.pi.corrwindow/intr_cats.c
   grass-addons/raster/r.pi/r.pi.corrwindow/local_proto.h
   grass-addons/raster/r.pi/r.pi.corrwindow/main.c
   grass-addons/raster/r.pi/r.pi.corrwindow/ncb.h
   grass-addons/raster/r.pi/r.pi.corrwindow/null_cats.c
   grass-addons/raster/r.pi/r.pi.corrwindow/readcell.c
   grass-addons/raster/r.pi/r.pi.csr.mw/
   grass-addons/raster/r.pi/r.pi.csr.mw/Makefile
   grass-addons/raster/r.pi/r.pi.csr.mw/analysis.c
   grass-addons/raster/r.pi/r.pi.csr.mw/description.html
   grass-addons/raster/r.pi/r.pi.csr.mw/frag.c
   grass-addons/raster/r.pi/r.pi.csr.mw/helpers.c
   grass-addons/raster/r.pi/r.pi.csr.mw/local_proto.h
   grass-addons/raster/r.pi/r.pi.csr.mw/main.c
   grass-addons/raster/r.pi/r.pi.csr.mw/stat_method.c
   grass-addons/raster/r.pi/r.pi.energy.iter/
   grass-addons/raster/r.pi/r.pi.energy.iter/Makefile
   grass-addons/raster/r.pi/r.pi.energy.iter/description.html
   grass-addons/raster/r.pi/r.pi.energy.iter/frag.c
   grass-addons/raster/r.pi/r.pi.energy.iter/helpers.c
   grass-addons/raster/r.pi/r.pi.energy.iter/local_proto.h
   grass-addons/raster/r.pi/r.pi.energy.iter/main.c
   grass-addons/raster/r.pi/r.pi.energy.iter/search.c
   grass-addons/raster/r.pi/r.pi.energy.iter/stat_method.c
   grass-addons/raster/r.pi/r.pi.energy/
   grass-addons/raster/r.pi/r.pi.energy/Makefile
   grass-addons/raster/r.pi/r.pi.energy/description.html
   grass-addons/raster/r.pi/r.pi.energy/frag.c
   grass-addons/raster/r.pi/r.pi.energy/helpers.c
   grass-addons/raster/r.pi/r.pi.energy/local_proto.h
   grass-addons/raster/r.pi/r.pi.energy/main.c
   grass-addons/raster/r.pi/r.pi.energy/search.c
   grass-addons/raster/r.pi/r.pi.energy/stat_method.c
   grass-addons/raster/r.pi/r.pi.enn.iter/
   grass-addons/raster/r.pi/r.pi.enn.iter/Makefile
   grass-addons/raster/r.pi/r.pi.enn.iter/description.html
   grass-addons/raster/r.pi/r.pi.enn.iter/frag.c
   grass-addons/raster/r.pi/r.pi.enn.iter/func.c
   grass-addons/raster/r.pi/r.pi.enn.iter/local_proto.h
   grass-addons/raster/r.pi/r.pi.enn.iter/main.c
   grass-addons/raster/r.pi/r.pi.enn.iter/statmethods.c
   grass-addons/raster/r.pi/r.pi.enn/
   grass-addons/raster/r.pi/r.pi.enn/Makefile
   grass-addons/raster/r.pi/r.pi.enn/description.html
   grass-addons/raster/r.pi/r.pi.enn/frag.c
   grass-addons/raster/r.pi/r.pi.enn/func.c
   grass-addons/raster/r.pi/r.pi.enn/local_proto.h
   grass-addons/raster/r.pi/r.pi.enn/main.c
   grass-addons/raster/r.pi/r.pi.enn/matrix.c
   grass-addons/raster/r.pi/r.pi.enn/parser.c
   grass-addons/raster/r.pi/r.pi.fnn/
   grass-addons/raster/r.pi/r.pi.fnn/.Makefile.kate-swp
   grass-addons/raster/r.pi/r.pi.fnn/Makefile
   grass-addons/raster/r.pi/r.pi.fnn/description.html
   grass-addons/raster/r.pi/r.pi.fnn/frag.c
   grass-addons/raster/r.pi/r.pi.fnn/func.c
   grass-addons/raster/r.pi/r.pi.fnn/heap.c
   grass-addons/raster/r.pi/r.pi.fnn/local_proto.h
   grass-addons/raster/r.pi/r.pi.fnn/main.c
   grass-addons/raster/r.pi/r.pi.fnn/matrix.c
   grass-addons/raster/r.pi/r.pi.fnn/parser.c
   grass-addons/raster/r.pi/r.pi.graph.dec/
   grass-addons/raster/r.pi/r.pi.graph.dec/Makefile
   grass-addons/raster/r.pi/r.pi.graph.dec/choice.c
   grass-addons/raster/r.pi/r.pi.graph.dec/description.html
   grass-addons/raster/r.pi/r.pi.graph.dec/draw.c
   grass-addons/raster/r.pi/r.pi.graph.dec/frag.c
   grass-addons/raster/r.pi/r.pi.graph.dec/func.c
   grass-addons/raster/r.pi/r.pi.graph.dec/local_proto.h
   grass-addons/raster/r.pi/r.pi.graph.dec/main.c
   grass-addons/raster/r.pi/r.pi.graph.iter/
   grass-addons/raster/r.pi/r.pi.graph.iter/Makefile
   grass-addons/raster/r.pi/r.pi.graph.iter/description.html
   grass-addons/raster/r.pi/r.pi.graph.iter/draw.c
   grass-addons/raster/r.pi/r.pi.graph.iter/frag.c
   grass-addons/raster/r.pi/r.pi.graph.iter/func.c
   grass-addons/raster/r.pi/r.pi.graph.iter/local_proto.h
   grass-addons/raster/r.pi/r.pi.graph.iter/main.c
   grass-addons/raster/r.pi/r.pi.graph.red/
   grass-addons/raster/r.pi/r.pi.graph.red/Makefile
   grass-addons/raster/r.pi/r.pi.graph.red/description.html
   grass-addons/raster/r.pi/r.pi.graph.red/draw.c
   grass-addons/raster/r.pi/r.pi.graph.red/frag.c
   grass-addons/raster/r.pi/r.pi.graph.red/func.c
   grass-addons/raster/r.pi/r.pi.graph.red/local_proto.h
   grass-addons/raster/r.pi/r.pi.graph.red/main.c
   grass-addons/raster/r.pi/r.pi.graph.red/stat_method.c
   grass-addons/raster/r.pi/r.pi.graph/
   grass-addons/raster/r.pi/r.pi.graph/Makefile
   grass-addons/raster/r.pi/r.pi.graph/description.html
   grass-addons/raster/r.pi/r.pi.graph/draw.c
   grass-addons/raster/r.pi/r.pi.graph/frag.c
   grass-addons/raster/r.pi/r.pi.graph/func.c
   grass-addons/raster/r.pi/r.pi.graph/hull.c
   grass-addons/raster/r.pi/r.pi.graph/local_proto.h
   grass-addons/raster/r.pi/r.pi.graph/main.c
   grass-addons/raster/r.pi/r.pi.grow/
   grass-addons/raster/r.pi/r.pi.grow/Makefile
   grass-addons/raster/r.pi/r.pi.grow/description.html
   grass-addons/raster/r.pi/r.pi.grow/func.c
   grass-addons/raster/r.pi/r.pi.grow/local_proto.h
   grass-addons/raster/r.pi/r.pi.grow/main.c
   grass-addons/raster/r.pi/r.pi.lm/
   grass-addons/raster/r.pi/r.pi.lm/Makefile
   grass-addons/raster/r.pi/r.pi.lm/description.html
   grass-addons/raster/r.pi/r.pi.lm/frag.c
   grass-addons/raster/r.pi/r.pi.lm/func.c
   grass-addons/raster/r.pi/r.pi.lm/local_proto.h
   grass-addons/raster/r.pi/r.pi.lm/main.c
   grass-addons/raster/r.pi/r.pi.neigh/
   grass-addons/raster/r.pi/r.pi.neigh/.Makefile.kate-swp
   grass-addons/raster/r.pi/r.pi.neigh/Makefile
   grass-addons/raster/r.pi/r.pi.neigh/description.html
   grass-addons/raster/r.pi/r.pi.neigh/frag.c
   grass-addons/raster/r.pi/r.pi.neigh/func.c
   grass-addons/raster/r.pi/r.pi.neigh/local_proto.h
   grass-addons/raster/r.pi/r.pi.neigh/main.c
   grass-addons/raster/r.pi/r.pi.neigh/stat_method.c
   grass-addons/raster/r.pi/r.pi.nlm.circ/
   grass-addons/raster/r.pi/r.pi.nlm.circ/Makefile
   grass-addons/raster/r.pi/r.pi.nlm.circ/description.html
   grass-addons/raster/r.pi/r.pi.nlm.circ/list.c
   grass-addons/raster/r.pi/r.pi.nlm.circ/local_proto.h
   grass-addons/raster/r.pi/r.pi.nlm.circ/main.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/
   grass-addons/raster/r.pi/r.pi.nlm.stats/Makefile
   grass-addons/raster/r.pi/r.pi.nlm.stats/description.html
   grass-addons/raster/r.pi/r.pi.nlm.stats/fractal.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/frag.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/func.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/helpers.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/local_proto.h
   grass-addons/raster/r.pi/r.pi.nlm.stats/main.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/method.c
   grass-addons/raster/r.pi/r.pi.nlm.stats/stat_method.c
   grass-addons/raster/r.pi/r.pi.nlm/
   grass-addons/raster/r.pi/r.pi.nlm/Makefile
   grass-addons/raster/r.pi/r.pi.nlm/description.html
   grass-addons/raster/r.pi/r.pi.nlm/func.c
   grass-addons/raster/r.pi/r.pi.nlm/helpers.c
   grass-addons/raster/r.pi/r.pi.nlm/list.c
   grass-addons/raster/r.pi/r.pi.nlm/local_proto.h
   grass-addons/raster/r.pi/r.pi.nlm/main.c
   grass-addons/raster/r.pi/r.pi.odc/
   grass-addons/raster/r.pi/r.pi.odc/Makefile
   grass-addons/raster/r.pi/r.pi.odc/compensation.c
   grass-addons/raster/r.pi/r.pi.odc/description.html
   grass-addons/raster/r.pi/r.pi.odc/frag.c
   grass-addons/raster/r.pi/r.pi.odc/helpers.c
   grass-addons/raster/r.pi/r.pi.odc/local_proto.h
   grass-addons/raster/r.pi/r.pi.odc/main.c
   grass-addons/raster/r.pi/r.pi.odc/stat_method.c
   grass-addons/raster/r.pi/r.pi.odc/voronoi.c
   grass-addons/raster/r.pi/r.pi.prob.mw/
   grass-addons/raster/r.pi/r.pi.prob.mw/Makefile
   grass-addons/raster/r.pi/r.pi.prob.mw/analysis.c
   grass-addons/raster/r.pi/r.pi.prob.mw/description.html
   grass-addons/raster/r.pi/r.pi.prob.mw/frag.c
   grass-addons/raster/r.pi/r.pi.prob.mw/helpers.c
   grass-addons/raster/r.pi/r.pi.prob.mw/local_proto.h
   grass-addons/raster/r.pi/r.pi.prob.mw/main.c
   grass-addons/raster/r.pi/r.pi.prob.mw/stat_method.c
   grass-addons/raster/r.pi/r.pi.prox/
   grass-addons/raster/r.pi/r.pi.prox/.main.c.kate-swp
   grass-addons/raster/r.pi/r.pi.prox/Makefile
   grass-addons/raster/r.pi/r.pi.prox/description.html
   grass-addons/raster/r.pi/r.pi.prox/frag.c
   grass-addons/raster/r.pi/r.pi.prox/func.c
   grass-addons/raster/r.pi/r.pi.prox/local_proto.h
   grass-addons/raster/r.pi/r.pi.prox/main.c
   grass-addons/raster/r.pi/r.pi.prox/old/
   grass-addons/raster/r.pi/r.pi.searchtime.iter/
   grass-addons/raster/r.pi/r.pi.searchtime.iter/Makefile
   grass-addons/raster/r.pi/r.pi.searchtime.iter/description.html
   grass-addons/raster/r.pi/r.pi.searchtime.iter/frag.c
   grass-addons/raster/r.pi/r.pi.searchtime.iter/helpers.c
   grass-addons/raster/r.pi/r.pi.searchtime.iter/local_proto.h
   grass-addons/raster/r.pi/r.pi.searchtime.iter/main.c
   grass-addons/raster/r.pi/r.pi.searchtime.iter/search.c
   grass-addons/raster/r.pi/r.pi.searchtime.iter/stat_method.c
   grass-addons/raster/r.pi/r.pi.searchtime.mw/
   grass-addons/raster/r.pi/r.pi.searchtime.mw/Makefile
   grass-addons/raster/r.pi/r.pi.searchtime.mw/description.html
   grass-addons/raster/r.pi/r.pi.searchtime.mw/frag.c
   grass-addons/raster/r.pi/r.pi.searchtime.mw/helpers.c
   grass-addons/raster/r.pi/r.pi.searchtime.mw/local_proto.h
   grass-addons/raster/r.pi/r.pi.searchtime.mw/main.c
   grass-addons/raster/r.pi/r.pi.searchtime.mw/search.c
   grass-addons/raster/r.pi/r.pi.searchtime.mw/stat_method.c
   grass-addons/raster/r.pi/r.pi.searchtime/
   grass-addons/raster/r.pi/r.pi.searchtime/Makefile
   grass-addons/raster/r.pi/r.pi.searchtime/description.html
   grass-addons/raster/r.pi/r.pi.searchtime/frag.c
   grass-addons/raster/r.pi/r.pi.searchtime/helpers.c
   grass-addons/raster/r.pi/r.pi.searchtime/local_proto.h
   grass-addons/raster/r.pi/r.pi.searchtime/main.c
   grass-addons/raster/r.pi/r.pi.searchtime/search.c
   grass-addons/raster/r.pi/r.pi.searchtime/stat_method.c
Modified:
   grass-addons/raster/r.pi/Makefile
   grass-addons/raster/r.pi/description.html
   grass-addons/raster/r.pi/r.pi.corrwin/description.html
   grass-addons/raster/r.pi/r.pi.corrwin/main.c
   grass-addons/raster/r.pi/r.pi.export/description.html
   grass-addons/raster/r.pi/r.pi.export/frag.c
   grass-addons/raster/r.pi/r.pi.export/helpers.c
   grass-addons/raster/r.pi/r.pi.export/local_proto.h
   grass-addons/raster/r.pi/r.pi.export/main.c
   grass-addons/raster/r.pi/r.pi.export/stat_method.c
   grass-addons/raster/r.pi/r.pi.import/description.html
   grass-addons/raster/r.pi/r.pi.import/frag.c
   grass-addons/raster/r.pi/r.pi.import/helpers.c
   grass-addons/raster/r.pi/r.pi.import/local_proto.h
   grass-addons/raster/r.pi/r.pi.import/main.c
   grass-addons/raster/r.pi/r.pi.import/parse.c
   grass-addons/raster/r.pi/r.pi.index/description.html
   grass-addons/raster/r.pi/r.pi.index/frag.c
   grass-addons/raster/r.pi/r.pi.index/func.c
   grass-addons/raster/r.pi/r.pi.index/local_proto.h
   grass-addons/raster/r.pi/r.pi.index/main.c
   grass-addons/raster/r.pi/r.pi.rectangle/description.html
   grass-addons/raster/r.pi/r.pi.rectangle/main.c
Log:
wegmann: New moduleset for analysis of spatial attributes of a landscape

Added: grass-addons/raster/r.pi/FIXES_markus.txt
===================================================================
--- grass-addons/raster/r.pi/FIXES_markus.txt	                        (rev 0)
+++ grass-addons/raster/r.pi/FIXES_markus.txt	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,40 @@
+Hi authors,
+
+I have made a series of fixes.
+
+major stuff
+- added r.pi.corrwin r.pi.index r.pi.rectangle to this copy in Dropbox for completion
+- renamed since caps letters are undesired:
+   r.fragment.NN -> r.fragment.nn
+   r.fragment.ENN -> r.fragment.enn
+- corrected all global variable definitions, in order to make code
+  compilable with these flags: -Wall  -fno-common -fexceptions (a test
+  for code portability)
+- fixed include file order: first system, then grass includes
+- use M_PI instead of private PI definition
+- use GNAME_MAX instead of 256 chars length
+- mv man_pages/rpi_overview.html description.html
+  in order to autogenerate main description page
+- updated ./description.html
+   - all HTML tags should be minor case, not caps
+   - linked modules
+   - broken long lines
+
+minor stuff
+- added GRASS GPL header in all main.c files, PURPOSE field yet to be compiled
+- fixed file permissions
+- fixed main Makefile
+- removed empty directories and cruft
+- removed superfluous */makeit.sh files. For compilation, simply use
+   make MODULE_TOPDIR=$HOME/grass64/
+   make MODULE_TOPDIR=$HOME/grass64/ install
+ and
+   make MODULE_TOPDIR=$HOME/grass64/ clean
+- fixed C code layout with this helper script:
+   grass64/tools/grass_indent.sh
+
+
+Cheers
+Markus Neteler
+4/2011
+http://gis.cri.fmach.it


Property changes on: grass-addons/raster/r.pi/FIXES_markus.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Modified: grass-addons/raster/r.pi/Makefile
===================================================================
--- grass-addons/raster/r.pi/Makefile	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,11 +1,37 @@
 MODULE_TOPDIR = ..
 
+PGM = r.pi
+
 SUBDIRS = \
+	r.pi.corearea \
 	r.pi.corrwin \
+	r.pi.corrwindow \
+	r.pi.csr.mw \
+	r.pi.energy \
+	r.pi.energy.iter \
+	r.pi.enn \
+	r.pi.enn.iter \
 	r.pi.export \
+	r.pi.fnn \
+	r.pi.graph \
+	r.pi.graph.dec \
+	r.pi.graph.iter \
+	r.pi.graph.red \
+	r.pi.grow \
 	r.pi.import \
 	r.pi.index \
-	r.pi.rectangle
+	r.pi.lm \
+	r.pi.neigh \
+	r.pi.nlm \
+	r.pi.nlm.circ \
+	r.pi.nlm.stats \
+	r.pi.odc \
+	r.pi.prob.mw \
+	r.pi.prox \
+	r.pi.rectangle \
+	r.pi.searchtime \
+	r.pi.searchtime.iter \
+	r.pi.searchtime.mw
 
 include $(MODULE_TOPDIR)/include/Make/Dir.make
 

Added: grass-addons/raster/r.pi/TODO.txt
===================================================================
--- grass-addons/raster/r.pi/TODO.txt	                        (rev 0)
+++ grass-addons/raster/r.pi/TODO.txt	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,45 @@
+@ Martin
+
+- renaming:
+  - a name concept should be discussed
+  - I renamed all modules to r.pi.*
+
+#####################################
+C-code:
+
+- fix all the unused variables
+- fix compiler warnings
+- there are LOTs of cloned files, put them into a r.pi library (example:
+  ~/grass64/vector/lidar/lidarlib/)
+  
+  File counts:
+  - draw.c 4
+  - search.c 5
+  - helpers.c 13
+  - stat_method.c 13
+  - func.c 16
+  - frag.c 24
+
+  To compare:
+   for i in draw.c search.c helpers.c stat_method.c func.c frag.c ; do
+       echo "####### $i:"
+       ls -l */$i
+   done
+
+
+- fix SVN propsets with this helper script when uploading to Addons (Markus will do):
+   grass-addons/tools/module_svn_propset.sh
+
+- some modules use
+#define TYPE_NOTHING 0
+ while others use
+#define TYPE_NOTHING -1
+  --> suggestion: use -1 everywhere
+
+#####################################
+HTML Descriptions TODO:
+
+- Add North Carolina example to each module, a section has been included everywhere
+- ./description.html (overview): polish and update to current module names
+- module/description.html files: still TOO GENERAL
+


Property changes on: grass-addons/raster/r.pi/TODO.txt
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Modified: grass-addons/raster/r.pi/description.html
===================================================================
--- grass-addons/raster/r.pi/description.html	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -19,78 +19,95 @@
 prompt (CLI) and might be implemented in e.g. a bash-script.
 <p>
 It is highly recommended to read the help pages or e.g the overview 
-documents of <A HREF="http://www.umass.edu/landeco/research/fragstats/documents/fragstats_documents.html">Fragstats</A>
+documents of
+<a href="http://www.umass.edu/landeco/research/fragstats/documents/fragstats_documents.html">Fragstats</a>
 to get a better impression of problems, possibilities and caveats.
 
 
 <h2>OVERVIEW</h2>
 
+<li><em>r.pi.rectangle</em>  - Performs statistical analysis on values of patches from the given raster map.
+<li><em>r.pi.corrwindow</em>  - Calculates correlation of two raster maps by calculating correlation function of two corresponding rectangular areas for each raster point and writing the result into a new raster map.
+<li><em>r.pi.energy</em>  - Individual-based dispersal model for connectivity analysis - energy based.
+<li><em>r.pi.energy.iter</em>  - Individual-based dispersal model for connectivity analysis (energy based) using iterative patch removal.
+<li><em>r.pi.fragment.dist</em>  - Calculates correlation of two raster maps by calculating correlation function of two corresponding rectangular areas for each raster point and writing the result into a new raster map.
+<li><em>r.pi.enn</em>  - Determines patches of given value and performs a nearest-neighbor analysis.
+<li><em>r.pi.index</em>  - Computation of fragmentation indices.
+<li><em>r.pi.enn.iter</em>  - Patch relevance for Euclidean Nearest Neighbor patches.
+<li><em>r.pi.neigh</em>  - Neighbourhood analysis - value of patches within a defined range.
+<li><em>r.pi.enn</em>  - Analysis of n-th Euclidean Nearest Neighbor distance.
+<li><em>r.pi.nlm</em>  - Creates a random generated map with values 0 or 1by given landcover and fragment count.
+<li><em>r.pi.nlm.circ</em>  - Creates a random landscape with defined attributes.
+<li><em>r.pi.nlm.stats</em>  - Neutral Landscape Generator - index statistics
+<li><em>r.pi.corearea</em>  - Variable edge effects and core area analysis
+<li><em>r.pi.corrwin</em>  - Moving window correlation analysis.
+<li><em>r.pi.csr.mw</em>  - Complete Spatial Randomness analysis on moving window.
+<li><em>r.pi.export</em>  - Export of patch based information.
+<li><em>r.pi.graph</em>  - Graph Theory for connectivity analysis.
+<li><em>r.pi.graph.iter</em>  - Graph Theory - iterative removal (patch relevance analysis).
+<li><em>r.pi.graph.red</em>  - Graph Theory - decreasing distance threshold option.
+<li><em>r.pi.grow</em>  - Size and suitability based region growing.
+<li><em>r.pi.import</em>  - Import and generation of patch raster data
+<li><em>r.pi.index</em>  - Basic patch based indices
+<li><em>r.pi.lm</em>  - Linear regression analysis for patches.
+<li><em>r.pi.prob.mw</em>  - Probability analysis of 2 random points being in the same patch.
+<li><em>r.pi.rectangle</em>  - Generates a rectangle based on a corner coordinate.
+<li><em>r.pi.searchtime</em>  - Individual-based dispersal model for connectivity analysis (time-based)
+<li><em>r.pi.searchtime.iter</em>  - Individual-based dispersal model for connectivity analysis (time-based) using iterative removal of patches
+<li><em>r.pi.searchtime.mw</em>  - Individual-based dispersal model for connectivity analysis (time-based) using moving window
+
+<p>
+<b>TODO: update below with above...</b>
+
 <h3>General and Connectivity Indices</h3>
 
  <ul>
-   <li><b>r.pi.index</b>: Calculations of basic indices (area, SHAPE etc.) </li>
-   <li><b>r.pi.enn</b>:  Area, SHAPE and distance to n-th Euclidean Nearest Neighbor</li>
-   <li><b>r.pi.fnn</b>:  Area, SHAPE and distance to n-th Functional Nearest Neighbor</li>
-   <li><b>r.pi.odc</b>: Area and distance to omnidirectional n-th Nearest Neighbors</li>
-   <li><b>r.pi.neigh</b>: Extraction of values of patches in defined buffer region</li>
-   <li><b>r.pi.prox</b>: Calculation of Proximity and Modified Proximity Index for patches in buffer region</li>
-   <li><b>r.pi.graph</b>: Various connectivity indices within the Graph Theory </li>
+
+<li><b><a href="r.pi.index.html">r.pi.index</a></b>: Calculations of basic indices (area, SHAPE etc.) </li>
+<li><b><a href="r.pi.enn.html">r.pi.enn</a></b>:  Area, SHAPE and distance to n-th Euclidean Nearest Neighbor</li>
+<li><b><a href="r.pi.fnn.html">r.pi.fnn</a></b>:  Area, SHAPE and distance to n-th Functional Nearest Neighbor</li>
+<li><b><a href="r.pi.odc.html">r.pi.odc</a></b>: Area and distance to omnidirectional n-th Nearest Neighbors</li>
+<li><b><a href="r.pi.neigh.html">r.pi.neigh</a></b>: Extraction of values of patches in defined buffer region</li>
+<li><b><a href="r.pi.prox.html">r.pi.prox</a></b>: Calculation of Proximity and Modified Proximity Index for patches in buffer region</li>
+<li><b><a href="r.pi.graph.html">r.pi.graph</a></b>: Various connectivity indices within the Graph Theory </li>
  </ul>
 
 
-<h3>Individual-based migration models</h3>
+<h3>Individual-based dispersal models</h3>
  <ul>
-   <li><b>r.pi.searchtime</b>:Searchtime and Immigration rate</li>
-   <li><b>r.pi.energy</b>: Immigration, Migration and successfull emigration rate</li>
+<li><b><a href="r.pi.searchtime.html">r.pi.searchtime</a></b>:Searchtime and Immigration rate</li>
+<li><b><a href="r.pi.energy.html">r.pi.energy</a></b>: Immigration, Migration and successfull emigration rate</li>
+<li><b><a href="r.pi.searchtime.mw.html">r.pi.searchtime.mw</a></b>:Related to <em>r.pi.searchtime</em> but using a Moving Windows approach</li>
  </ul>
 
 <h3>Patch-Relevance</h3>
  <ul>
-   <li><b>r.pi.enn.iter</b>:Relevance of patches for maintenance of distance to first Nearest Neighbor</li>
-   <li><b>r.pi.searchtime.iter</b>:Relevance of patches for maintenance of searchtime</li>
-   <li><b>r.pi.energy.iter</b>:Relevance of patches for maintenance of immigration rate</li>
-   <li><b>r.pi.graph.red</b>:Relevance of patches ....</li>
-   <li><b>r.pi.graph.dec</b>:Relevance of patches ....</li>
+<li><b><a href="r.pi.enn.iter.html">r.pi.enn.iter</a></b>:Relevance of patches for maintenance of distance to first Nearest Neighbor</li>
+<li><b><a href="r.pi.searchtime.iter.html">r.pi.searchtime.iter</a></b>:Relevance of patches for maintenance of searchtime</li>
+<li><b><a href="r.pi.energy.iter.html">r.pi.energy.iter</a></b>:Relevance of patches for maintenance of immigration rate</li>
+<li><b><a href="r.pi.graph.red.html">r.pi.graph.red</a></b>:Relevance of patches ....</li>
+<li><b><a href="r.pi.graph.dec.html">r.pi.graph.dec</a></b>:Relevance of patches ....</li>
  </ul>
 
 <h3>Neutral Landscape Model</h3>
  <ul>
-   <li><b>r.pi.nlm</b>: Generation of a neutral landscape</li>
-   <li><b>r.pi.nlm.stats</b>:Statistical analysis of landscapes based on permutation of neutral landscapes</li>
+<li><b><a href="r.pi.nlm.html">r.pi.nlm</a></b>: Generation of a neutral landscape (fractal)</li>
+<li><b><a href="r.pi.nlm.stats.html">r.pi.nlm.stats</a></b>:Statistical analysis of landscapes based on permutation of neutral landscapes</li>
+<li><b><a href="r.pi.nlm.circ.html">r.pi.nlm.circ</a>c</b>:Generation of a neutral landscape (circular)</li>
  </ul>
 
 <h3>various modules</h3>
  <ul>
-   <li><b>r.pi.corearea</b>:Calculation of core area based on costmatrix</li>
-   <li><b>r.pi.searchtime.mw</b>:Related to <em>r.pi.searchtime</em> but using a Moving Windows approach</li>
-   <li><b>r.pi.prob.mw</b>:Probability of two random points being in the same patch</li>
-   <li><b>r.pi.rectangle</b>: Generation of rectangles based on coordinate points</li>
-   <li><b>r.pi.import</b>:Import of values to corresponding patches</li>
-   <li><b>r.pi.export</b>:Export of values from patches</li>
-   <li><b>r.pi.lm</b>:Residuals of a Linear Regression between 2 rasters are provided as raster</li>
-   <li><b>r.pi.corrwin</b>:A correlation between the pixels of two raster
+<li><b><a href="r.pi.corearea.html">r.pi.corearea</a></b>:Calculation of core area based on costmatrix</li>
+<li><b><a href="r.pi.prob.mw.html">r.pi.prob.mw</a></b>:Probability of two random points being in the same patch</li>
+<li><b><a href="r.pi.rectangle.html">r.pi.rectangle</a></b>: Generation of rectangles based on coordinate points</li>
+<li><b><a href="r.pi.import.html">r.pi.import</a></b>:Import of values to corresponding patches</li>
+<li><b><a href="r.pi.export.html">r.pi.export</a></b>:Export of values from patches</li>
+<li><b><a href="r.pi.lm.html">r.pi.lm</a></b>:Residuals of a Linear Regression between 2 rasters are provided as raster</li>
+<li><b><a href="r.pi.corrwin.html">r.pi.corrwin</a></b>:A correlation between the pixels of two raster
 files inside a moving analysis is calculated</li>
  </ul>
 
-
-
-
-<h2>Disclaimer</h2>
-
-This software is released under the GPL license, hence also the limitation 
-of liability. This software was designed for a certain project and its research
-questions. Its nomenclature might not be concordant with other software packages.
-Moreover its capabilities are yet limited and can not be compared to such of e.g.
-Fragstats, however every user is invited to extend, modify or fix the
-functionality of <em>r.pi</em> as long as the new code comply with the GPL.
-
-
-<h2>REFERENCES</h2>
-
-Wegmann, M., E. Shirinov, M. Schmidt and XXXX, S. Dech (2011) " Titel ...." 
-<em>Journal</em> pages
-
-
 <h2>EXAMPLES</h2>
 
 <h4>Calculation of the SHAPE-Index</h4>
@@ -133,10 +150,59 @@
 <h2>SEE ALSO</h2>
 
 <em>
-<A HREF="r.le.html">r.le</A>,
-<A HREF="r.li.html">r.li</A>
+<a href="r.buffer.rect.html">r.buffer.rect</a>,
+<a href="r.corrwindow.html">r.corrwindow</a>,
+<a href="r.energy.html">r.energy</a>,
+<a href="r.energy.iter.html">r.energy.iter</a>,
+<a href="r.fragment.html">r.fragment</a>,
+<a href="r.fragment.dist.html">r.fragment.dist</a>,
+<a href="r.fragment.enn.html">r.fragment.enn</a>,
+<a href="r.fragment.iter.html">r.fragment.iter</a>,
+<a href="r.fragment.neighbors.html">r.fragment.neighbors</a>,
+<a href="r.fragment.nn.html">r.fragment.nn</a>,
+<a href="r.nlm.html">r.nlm</a>,
+<a href="r.nlm.fractal.html">r.nlm.fractal</a>,
+<a href="r.nlm.stats.html">r.nlm.stats</a>,
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.searchtime.html">r.searchtime</a>,
+<a href="r.searchtime.iter.html">r.searchtime.iter</a>,
+<a href="r.searchtime.mw.html">r.searchtime.mw</a>
+<p>
+<a href="r.le.html">r.le</a>,
+<a href="r.li.html">r.li</a>
 </em>
 
+<h2>REFERENCES</h2>
+
+<ul>
+<li>Wegmann, M., Shirinova, E., Neteler, M., Rocchini, D., Schmidt, M.,
+Dech, S.: r.pi: Semi-automatic spatial pattern analysis of remotely
+sensed land cover data. Software review. Submitted.</li>
+</ul>
+
+<h2>Disclaimer</h2>
+
+This software is released under the GPL license, hence also the limitation
+of liability. This software was designed for a certain project and its research
+questions. Its nomenclature might not be concordant with other software packages.
+Moreover its capabilities are yet limited and can not be compared to such of e.g.
+Fragstats, however every user is invited to extend, modify or fix the
+functionality of <em>r.pi</em> as long as the new code comply with the GPL.
+
 <h2>AUTHORS</h2>
 Programming: Elshad Shirinov<br>
 Scientific concept: Martin Wegmann <br>

Added: grass-addons/raster/r.pi/r.pi.corearea/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.corearea
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,100 @@
+<h2>DESCRIPTION</h2>
+
+Variable edge effects and core area analysis 
+
+<h2>NOTES</h2>
+
+This module is generating core areas based on defined edge depths. The edge depths can be increased by the values of a <em>costmap</em> (e.g. urban areas could have a more severe impact than secondary forest on forest fragments). Moreover a friction map (<em> propmap</em> within the fragments can lower the impact of surrounding landcover types and hence an increased edge depth (e.g. a river or escarpment which might lower the edge effects). Moreover a <em> dist_weight</em> can be assigned in order to stress that closer pixel values are higher weighted.
+
+
+# propmap infos:
+# if 0 is taken, values will be propagated infinitely
+#
+# propmethod=linear: propagated value = actual value - (propmap value at this position)
+# propmethod=exponential: propagated value = actual value / (propmap value at this position)
+
+# if 0 using the linear method, then propagated value=actual value and hence everything will be buffered
+# in order to minimize the impact of the propagation the value must be larger than 1. for the exponential value a value of below 1 should not be chosen, otherwise it will be propagated infinitely
+
+
+#dist_weight infos:
+w(d) = 1 - (d / d_max)^(tan(dist_weight * 0.5 * pi))
+
+dabei ist:
+
+d - die Distanz der jeweiligen Zelle
+d_max - die angegebene maximale Distanz
+dist_weight - der Parameter
+
+Es schaut damit wie folgt aus:
+
+0 < dist_weight < 0.5: die Bewertungskurve ist am Anfang steil
+abfallend und wird flacher bis zum Wert 0 bei d = d_max
+
+dist_weight = 0.5: linearer Abstieg zum Wert 0 bei d = d_max
+
+0.5 < dist_weight < 1: Kurve fällt flach und dann immer steiler bis
+zum Wert 0 bei d = d_max
+
+dist_weight = 1: Keine Distanzbewertung, d.h. so wie vorher
+
+
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset using class 5 (forest):
+
+For the computation of variable edge effects a costmap is necessary which need to be defined by the user. Higher costs are resulting in higher edge depths:
+<div class="code"><pre>
+# class - type - costs
+#   1	- developed - 3
+#   2	- agriculture - 2
+#   3	- herbaceous - 1
+#   4	- shrubland - 1
+#   5	- forest - 0
+#   6	- water - 0
+#   7	- sediment - 0
+
+<b>r.mapcalc</b> "costmap_for_corearea = if(landclass96==1,3,if(landclass96==2,2,if(landclass96==3,1,if(landclass96==4,1,if(landclass96==5,0,if(landclass96==6,0,if(landclass96==7,0)))))))"
+
+</pre></div>
+
+
+now the edge depth and the resulting core area can be computed:
+<div class="code"><pre>
+<b>r.pi.corearea input=</b>landclass96 <b>costmap=costmap_for_corearea</b>  <b>output=</b>landcover96_corearea <b>keyval=</b>5 <b>buffer=</b>5 <b>distance=</b>5 <b>angle=</b>90 <b>stats=</b>average <b>propmethod=</b>linear
+
+
+the results consist of 2 files:
+landclass96_corearea: the actual resulting core areas
+landclass96_corearea_map: a map showing the edge depths
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/description_TO_BE_integrated.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/description_TO_BE_integrated.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/description_TO_BE_integrated.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,200 @@
+</head>
+<body bgcolor="white">
+
+<img src="grass_logo.png" alt="GRASS logo"><hr align=center size=6 noshade>
+
+<h2>NAME</h2>
+<em><b>r.pi.index</b></em>  - is part of a patch based fragmentation analysis package (<EM>r.pi</EM>) providing basic patch based indices, like area, SHAPE or Nearest Neighbour distance.
+<h2>KEYWORDS</h2>
+raster, patch index, landscape ecology
+<h2>SYNOPSIS</h2>
+<b>r.pi.index</b><br>
+<b>r.pi.index help</b><br>
+<b>r.pi.index</b> [-<b>a</b>] <b>input</b>=<em>name</em> <b>output</b>=<em>name</em> 
+<b>keyval</b>=<em>val</em>   <b>method</b>=<em>name</em> [<b>title</b>=<em>name</em>]   [--<b>overwrite</b>]  [--<b>verbose</b>]  [--<b>quiet</b>] 
+
+<h3>Flags:</h3>
+<DL>
+<DT><b>-a</b></DT>
+<DD>use 8-neighbour rules (Queen-Typ) instead of 4-neighbour rule (Rook-Typ)</DD>
+
+<DT><b>--overwrite</b></DT>
+<DD>Allow output files to overwrite existing files</DD>
+<DT><b>--verbose</b></DT>
+<DD>Verbose module output</DD>
+<DT><b>--quiet</b></DT>
+<DD>Quiet module output</DD>
+</DL>
+
+
+
+<h3>Parameters:</h3>
+<DL>
+<DT><b>input</b>=<em>name</em></DT>
+<DD>Name of existing raster map containing categories</DD>
+
+<DT><b>output</b>=<em>name</em></DT>
+<DD>Output patch-based result raster map</DD>
+
+<DT><b>keyval</b>=<em>val</em></DT>
+<DD>The value of the class to analyse</DD>
+
+<DT><b>method</b>=<em>name</em></DT>
+<DD>The index to compute. Options: area, perimeter (perim), SHAPE, Border-Index (bor), Compactness (comp), Asymmetry (asym), area-perimeter ratio (apr), fractal dimension (fract), distance to euclidean nearest neighbour (ENN)</DD>
+
+<DT><b>title</b>=<em>name</em></DT>
+<DD>Optional title of output map</DD>
+
+</DL>
+
+
+
+<H2>DESCRIPTION</H2>
+
+<P>
+
+The program will be run non-interactively if the user specifies program arguments (see OPTIONS) on the command
+line.  Alternately, the user can simply type <B>r.pi.index</B> on the command line, without program
+arguments.  In this case, the user will be prompted for flag settings and parameter values.
+
+> Was die propmap angeht:
+>
+> Wenn du nur 0 Werte nimmst, dann werden die Werte immer unendlich
+> propagiert. Es geht nämlich so:
+>
+> propmethod=linear: propagierter Wert = aktueller Wert - (propmap an
+> dieser Stelle)
+>
+> propmethod=exponential: propagierter Wert = aktueller Wert / (propmap
+> an dieser Stelle)
+>
+> Bei 0 in der map ist also bei linearer Methode immer
+> propagierter Wert = aktueller Wert und daher wird eigentlich alles
+> weggebuffert. Dass da einige übriggeblieben sind, hing mit dem anderen
+> Bug zusammen (oder vllt. gibt's noch einen Bug?). Jedenfalls sollten
+> dann wirklich alle Patches weg sein.
+>
+> Um die Weite der Propagierung abzuschwächen muss man die Werte in der
+> Propmap größer als 1 wählen. Bei der exponentiellen Methode sollte
+> grundsätzlich nie ein Wert unter 1 gewählt werden, denn sonst wird
+> auch ins Unendliche propagiert.
+
+
+
+
+w(d) = 1 - (d / d_max)^(tan(dist_weight * 0.5 * pi))
+
+dabei ist:
+
+d - die Distanz der jeweiligen Zelle
+d_max - die angegebene maximale Distanz
+dist_weight - der Parameter
+
+Es schaut damit wie folgt aus:
+
+0 < dist_weight < 0.5: die Bewertungskurve ist am Anfang steil
+abfallend und wird flacher bis zum Wert 0 bei d = d_max
+
+dist_weight = 0.5: linearer Abstieg zum Wert 0 bei d = d_max
+
+0.5 < dist_weight < 1: Kurve fällt flach und dann immer steiler bis
+zum Wert 0 bei d = d_max
+
+dist_weight = 1: Keine Distanzbewertung, d.h. so wie vorher
+
+<DT><B>Area</B> 
+
+<DD>The <EM>Area</EM> (area) computes the area of each patch.
+
+
+<DT><B>Perimeter</B> 
+
+<DD>The <EM>Perimeter (perim)</EM> computes the perimeter of each patch.
+
+
+<DT><B>Area-Perimeter ratio </B> 
+
+<DD>The <EM>Area-Perimeter ratio</EM> (apr) divides the patch perimeter by the area.
+
+
+<DT><B>SHAPE Index </B> 
+
+<DD>The <EM>SHAPE Index</EM> (shape) divides the patch perimete by the minimum perimeter 
+possible for a maximally compact patch of the corresponding patch area.
+
+
+
+<DT><B>Border Index </B> 
+
+<DD>The <EM>Border Index</EM> (bor)....
+
+
+<DT><B>Compactness Index </B> 
+
+<DD>The <EM>Compactness Index</EM> (comp)....
+
+
+<DT><B>Asymmetry Index </B> 
+
+<DD>The <EM>Border Index</EM> (asym)....
+
+
+<DT><B>Fractal Dimension Index </B> 
+
+<DD>The <EM>Fractal Dimension Index</EM> (fract)....
+
+
+<DT><B>Nearest Neighbour Index </B> 
+
+<DD>The <EM>Nearest Neighbour Index</EM> (ENN) ....
+
+
+<!-- Bsp um Pseudo code or Bsp einzufügen -->
+<!--<div class="code"><pre>
+Input:                          Output:
+  ELEVATION SURFACE               LEAST COST PATH
+. . ----- . . . . . . . . . .    . . . . . . . . . . . . . . .
+. 20| 19| 17. 16. 17. 16. 16.    .   . 1 . 1 . 1 .   .   .   .
+. . |___| . . . . . . . . . .    . . . . . . . . . . . . . . .
+. 18. 18. 24. 18. 15. 12. 11.    .   .   .   .   . 1 .   .   .
+. . . . . . . . . . . . . . .    . . . . . . . . . . . . . . .
+. 22. 16. 16. 18. 10. 10. 10.    .   .   .   .   . 1 .   .   .
+. . . . . . . . . . . . . . .    . . . . . . . . . . . . . . .
+. 17. 15. 15. 15. 10. 8 . 8 .    .   .   .   .   .   . 1 .   .
+. . . . . . . . . . . . . . .    . . . . . . . . . . . . . . .
+. 24. 16. 8 . 7 . 8 . 0 .12 .    .   .   .   .   .   . 1 .   .
+. . . . . . . . . . . . . . .    . . . . . . . . . . . . . . .
+. 17. 9 . 8 . 7 . 8 . 6 .12 .    .   .   .   .   .   .   .   .
+. . . . . . . . . . . . . . .    . . . . . . . . . . . . . . .
+</pre></div>-->
+
+
+
+
+</DL>
+<H2>NOTES</H2>
+
+
+
+
+<P>
+
+<H2>BUGS</H2>
+
+
+
+<H2>SEE ALSO</H2>
+
+<EM><A HREF="r.pi.ENN.html">r.pi.ENN</A></EM><br>
+<EM><A HREF="r.pi.FNN.html">r.pi.FNN</A></EM><br>
+<EM><A HREF="r.pi.dist.html">r.pi.dist</A></EM><br>
+<EM><A HREF="r.li.setup.html">r.li.setup</A></EM><br>
+
+<H2>AUTHOR</H2>
+
+Programming: Elshad Shirinov<br>
+Scientific concept: Martin Wegmann <br>
+University of Wuerzburg<br>
+
+
+<p><i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/description_TO_BE_integrated.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,163 @@
+#include "local_proto.h"
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,576 @@
+#include "local_proto.h"
+
+void valmap_output()
+{
+    int out_fd;
+    DCELL *result;
+
+    result = G_allocate_c_raster_buf();
+
+    /* write output */
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new("test_valmap", DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file test_valmap\n"));
+	exit(EXIT_FAILURE);
+    }
+
+    /* write the output file */
+    int row, i;
+    Position *p;
+
+    for (row = 0; row < nrows; row++) {
+	G_put_d_raster_row(out_fd, &valmap[row * ncols]);
+    }
+
+    G_free(result);
+}
+
+/* find one contour strting at the given cell poition */
+Position *find_contour(int *flagbuf, Position start, int dirx, int diry,
+		       Position * list, int patch)
+{
+    /* start with the given cell */
+    int x = start.x;
+    int y = start.y;
+    int dx = dirx;
+    int dy = diry;
+
+    int curpos = 0;
+
+    list[curpos].x = x;
+    list[curpos].y = y;
+
+    while (1) {			// sorry for this while(true) loop
+	x += dx;
+	y += dy;
+
+	if (x >= 0 && x < ncols && y >= 0 && y < nrows) {
+	    if (flagbuf[y * ncols + x] == patch + 1) {
+		/* a patch cell is encountered */
+		int neighbors;
+
+		/* if it is not the current cell again */
+		if (!(x == list[curpos].x && y == list[curpos].y)) {
+		    /* test if this cell is the first one again */
+		    if (x == start.x && y == start.y) {
+			/* if the entry vector is the opposite of the initial
+			   exit vector then end search */
+			if (dx == -dirx && dy == -diry) {
+			    break;
+			}
+		    }
+		    else {
+			/* new border cell found */
+			curpos++;
+			list[curpos].x = x;
+			list[curpos].y = y;
+		    }
+		}
+
+		/* step back */
+		x -= dx;
+		y -= dy;
+
+		/* turn left */
+		int tmp = dx;
+
+		dx = dy;
+		dy = -tmp;
+	    }
+	    else {
+		/* a non-patch cell is encountered */
+		/* turn right */
+		int tmp = dx;
+
+		dx = -dy;
+		dy = tmp;
+
+		/* mark this cell as visited */
+		if (flagbuf[y * ncols + x] == 0) {
+		    flagbuf[y * ncols + x] = -1;
+		}
+	    }
+	}
+	else {
+	    /* a cell out of range is encountered */
+	    /* turn right */
+	    int tmp = dx;
+
+	    dx = -dy;
+	    dy = tmp;
+	}
+    }				// while(1)
+
+    /* adjust the patch border references */
+    curpos++;
+
+    return list + curpos;
+}
+
+/* find borders of a patch and sort cells accordingly */
+void find_borders_patch(int *flagbuf, int patch)
+{
+    /* copy border cells into a separate border array */
+    int cell_count = fragments[patch + 1] - fragments[patch];
+    Position border[cell_count * 2];
+    int border_count = 0;
+    Coords *p;
+
+    for (p = fragments[patch]; p < fragments[patch + 1]; p++) {
+	if (p->neighbors < 4) {
+	    border[border_count].x = p->x;
+	    border[border_count].y = p->y;
+	    border_count++;
+	}
+    }
+
+    /* test output */
+    int i;
+
+    /*fprintf(stderr, "Border cells for patch %d:", patch);
+       for(i = 0; i < border_count; i++) {
+       fprintf(stderr, " (%d,%d)", border[i].x, border[i].y);
+       }
+       fprintf(stderr, "\n"); */
+
+    //G_message("Allocating for patch %d, border_count = %d", patch, border_count);
+
+    /* initialize current patch border list */
+    PatchBorderList *list = patch_borders + patch;
+
+    list->positions =
+	(Position *) G_malloc(2 * border_count * sizeof(Position));
+    list->borders =
+	(Position **) G_malloc((border_count + 1) * sizeof(Position *));
+    list->borders[0] = list->positions;
+    list->count = 0;
+
+    /* if this is a 1-cell-patch then return here */
+    if (cell_count == 1) {
+	list->positions[0] = border[0];
+	list->borders[1] = list->borders[0] + 1;
+	list->count = 1;
+	return;
+    }
+
+    /* find the top-left border cell */
+    int curpos = 0;
+    int first;
+
+    for (first = i = curpos; i < border_count; i++) {
+	if (border[i].y < border[first].y ||
+	    (border[i].y == border[first].y &&
+	     border[i].x < border[first].x)) {
+	    first = i;
+	}
+    }
+
+    //G_message("top-left border cell: (%d,%d)", border[first].x, border[first].y);
+
+    /* set direction for the first run */
+    int dx = 0;
+    int dy = -1;
+
+    /* repeat until all borders have been found */
+    Position *nextpos = list->positions;
+
+    do {
+	/* find next contour */
+	list->borders[list->count + 1] =
+	    find_contour(flagbuf, border[first], dx, dy,
+			 list->borders[list->count], patch);
+
+	list->count++;
+
+	/*G_message("Flagbuf:");
+	   int fx, fy;
+	   for(fy = 13; fy < 17; fy++) {
+	   for(fx = 30; fx < 40; fx++) {
+	   if(flagbuf[fy * ncols + fx] >= 0) {
+	   fprintf(stderr, "%x", flagbuf[fy * ncols + fx]);
+	   } else {
+	   fprintf(stderr, "*");
+	   }
+	   }
+	   fprintf(stderr, "\n");
+	   } */
+
+	/*              G_message("Found contour:");
+	   Position *p;
+	   for(p = list->borders[list->count - 1]; p < list->borders[list->count]; p++) {
+	   fprintf(stderr, "(%d,%d) ", p->x, p->y);
+	   }
+	   fprintf(stderr, "\n"); */
+
+	/* find a border cell which still has at least one unvisited empty neighbor */
+	first = -1;
+	int pos;
+
+	for (pos = 0; pos < border_count; pos++) {
+	    Position *p = border + pos;
+
+	    int nx, ny;		// neighbor
+	    int x = p->x;
+	    int y = p->y;
+
+	    /* test right neighbor */
+	    nx = x + 1;
+	    ny = y;
+	    if (nx >= 0 && nx < ncols && ny >= 0 && ny < nrows &&
+		flagbuf[ny * ncols + nx] == 0) {
+		first = pos;
+		dx = nx - x;
+		dy = ny - y;
+		break;
+	    }
+	    /* test left neighbor */
+	    nx = x - 1;
+	    ny = y;
+	    if (nx >= 0 && nx < ncols && ny >= 0 && ny < nrows &&
+		flagbuf[ny * ncols + nx] == 0) {
+		first = pos;
+		dx = nx - x;
+		dy = ny - y;
+		break;
+	    }
+	    /* test top neighbor */
+	    nx = x;
+	    ny = y + 1;
+	    if (nx >= 0 && nx < ncols && ny >= 0 && ny < nrows &&
+		flagbuf[ny * ncols + nx] == 0) {
+		first = pos;
+		dx = nx - x;
+		dy = ny - y;
+		break;
+	    }
+	    /* test bottom neighbor */
+	    nx = x;
+	    ny = y - 1;
+	    if (nx >= 0 && nx < ncols && ny >= 0 && ny < nrows &&
+		flagbuf[ny * ncols + nx] == 0) {
+		first = pos;
+		dx = nx - x;
+		dy = ny - y;
+		break;
+	    }
+	}
+
+	/*if(first >= 0) {
+	   G_message("Another contour starting at: (%d,%d), dir: (%d,%d)", border[first].x, border[first].y, dx, dy);
+	   } */
+    } while (first >= 0 && list->count < 3);
+}
+
+/* find borders of all patches and sort cells accordingly */
+void find_borders(int *flagbuf)
+{
+    int i;
+
+    for (i = 0; i < fragcount; i++) {
+	//    for(i = 10; i < 11; i++) {
+	//G_message("Border %d", i);
+	find_borders_patch(flagbuf, i);
+
+	G_percent(i + 1, fragcount, 1);
+	//G_message("%d of %d", i, fragcount);
+    }
+
+    //valmap_output();    
+}
+
+/* gets normal to the patch border in the given cell's position */
+Vector2 normal(int patch, int border_index, int cell)
+{
+    PatchBorderList list = patch_borders[patch];
+    Position *border = list.borders[border_index];
+    int cell_count =
+	list.borders[border_index + 1] - list.borders[border_index];
+
+    //G_message("Enter: patch = %d, cell_cnt = %d", patch, cell_count);
+
+    /* handle 1-pixel patches separately */
+    if (cell_count <= 1) {
+	return (Vector2) {
+	1.0, 0.0};
+    }
+
+    //    G_message("first cells: (%d, %d)", border[0].x, border[0].y);
+
+    /* get three consequtive cells */
+    Position cell1 = border[((cell - 1) + cell_count) % cell_count];
+    Position cell2 = border[cell];
+    Position cell3 = border[(cell + 1) % cell_count];
+
+    //    G_message("Middle");
+
+    int dx1 = cell2.x - cell1.x;
+    int dy1 = cell2.y - cell1.y;
+    int dx2 = cell3.x - cell2.x;
+    int dy2 = cell3.y - cell2.y;
+
+    Vector2 res;
+
+    res.x = 0.5 * (dy1 + dy2);
+    res.y = -0.5 * (dx1 + dx2);
+
+    if (res.x == 0 && res.y == 0) {
+	res.x = dx1;
+	res.y = dy1;
+    }
+
+    /* normalize resulting vector */
+    double l = sqrt(res.x * res.x + res.y * res.y);
+
+    res.x /= l;
+    res.y /= l;
+
+    //    G_message("Exit");
+    return res;
+}
+
+/* returns a value from the cost map */
+DCELL get_cost_value(int x, int y)
+{
+    if (x >= 0 && x < ncols && y >= 0 && y < nrows) {
+	return map[y * ncols + x];
+    }
+    else {
+	return -1.0;
+    }
+}
+
+/* gets an array with values of the cost matrix cells in the range of the effect cone of */
+/* the given cell with the given normal */
+int get_cost_values(DCELL * res, Position cell, Vector2 n, double distance,
+		    double angle, double weight_param)
+{
+    int d = (int)distance;
+    double ref = cos(0.5 * angle);
+
+    //fprintf(stderr, "Cell (%d, %d): ", cell.x, cell.y);
+
+    int x, y;
+    int count = 0;
+
+    for (x = cell.x - d; x <= cell.x + d; x++) {
+	for (y = cell.y - d; y <= cell.y + d; y++) {
+	    /* test if position is in the effect cone */
+	    double dx = x - cell.x;
+	    double dy = y - cell.y;
+	    double l = sqrt(dx * dx + dy * dy);
+
+	    double angcos = (dx * n.x + dy * n.y) / l;
+
+	    DCELL val = get_cost_value(x, y);
+
+	    if (angcos >= ref && l <= distance && val >= 0) {
+		/* incorporate distance */
+		if (weight_param < MAX_DOUBLE) {
+		    /* use l-1 as 1 is the smallest possible distance between two pixels */
+		    val *= 1.0 - pow((l - 1.0) / distance, weight_param);
+		}
+
+		res[count] = val;
+		count++;
+
+		//fprintf(stderr, "%0.2f ", val);
+	    }
+	}
+    }
+
+    //fprintf(stderr, "\n");
+
+    return count;
+}
+
+/* initializes border cell values for propagation */
+void init_border_values(double distance, double angle, int buffer,
+			f_statmethod stat, double dist_weight)
+{
+    int patch;
+    int size = (int)distance * 2 + 1;
+
+    size *= size;
+    DCELL *cost_values = (DCELL *) G_malloc(size * sizeof(DCELL));
+
+    double weight_param = tan(dist_weight * 0.5 * M_PI);
+
+    for (patch = 0; patch < fragcount; patch++) {
+	PatchBorderList list = patch_borders[patch];
+
+	int contour;
+
+	for (contour = 0; contour < list.count; contour++) {
+	    int cell;
+	    Position *p;
+
+	    for (p = list.borders[contour], cell = 0;
+		 p < list.borders[contour + 1]; p++, cell++) {
+		Vector2 n = normal(patch, contour, cell);
+
+		int border_count =
+		    list.borders[contour + 1] - list.borders[contour];
+
+		int count;
+
+		if (border_count == 1) {
+		    count =
+			get_cost_values(cost_values, *p, n, distance,
+					2 * M_PI, weight_param);
+		}
+		else {
+		    count =
+			get_cost_values(cost_values, *p, n, distance, angle,
+					weight_param);
+		}
+
+		int value = Round(stat(cost_values, count) * (DCELL) buffer);
+
+		DCELL *buf = &valmap[p->y * ncols + p->x];
+
+		if (*buf >= 0 && *buf < value) {
+		    *buf = value;
+		}
+
+		//G_message("Value for (%d, %d) = %d", p->x, p->y, value);
+
+		//G_message("Normal to (%d, %d) is (%0.2f, %0.2f)", p->x, p->y, n.x, n.y);
+	    }
+	}
+    }
+
+    /*fprintf(stderr, "VALMAP:\n");
+       int i, j;
+       for(j = 0; j < nrows; j++) {
+       for(i = 0; i < ncols; i++) {
+       fprintf(stderr, "%03d ", (int)valmap[j * ncols + i]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    G_free(cost_values);
+}
+
+int get_neighbors(Position * res, int x, int y, int nx, int ny, int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && valmap[y * nx + x - 1] >= 0.0) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && valmap[(y - 1) * nx + x] >= 0.0) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && valmap[y * nx + x + 1] >= 0.0) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && valmap[(y + 1) * nx + x] >= 0.0) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && valmap[j * nx + i] >= 0.0) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+/* propagates border values of a patch with a linear decrease */
+void propagate_patch(int patch, int neighbor_count, f_propmethod prop_method)
+{
+    PatchBorderList list = patch_borders[patch];
+
+    Position *nbr_list =
+	(Position *) G_malloc(neighbor_count * sizeof(Position));
+    int cell_count = fragments[patch + 1] - fragments[patch];
+    Position *stack =
+	(Position *) G_malloc(2 * cell_count * sizeof(Position));
+    Position *top = stack;
+
+    /* put all border cells on the stack */
+    Coords *p;
+
+    for (p = fragments[patch]; p < fragments[patch + 1]; p++) {
+	if (valmap[p->y * ncols + p->x] > 0.0) {
+	    top->x = p->x;
+	    top->y = p->y;
+	    top++;
+	}
+    }
+
+    /* propagate values */
+    while (top > stack) {
+	/* pop from stack */
+	top--;
+	int x = top->x;
+	int y = top->y;
+	DCELL value = valmap[y * ncols + x];
+
+	/* get neighbors */
+	int nbr_cnt =
+	    get_neighbors(nbr_list, x, y, ncols, nrows, neighbor_count);
+
+	/* for each neighbor */
+	int i;
+
+	for (i = 0; i < nbr_cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+	    DCELL nbr_val = valmap[y * ncols + x];
+
+	    //int pass_val = value - 1 >= 0 ? value - 1 : 0;
+	    DCELL pass_val = prop_method(value, propmap[y * ncols + x]);
+
+	    if (pass_val > nbr_val) {
+		/* pass value and push neighbor on stack */
+		valmap[y * ncols + x] = pass_val;
+		*top = nbr_list[i];
+		top++;
+	    }
+	}
+    }
+
+    G_free(stack);
+    G_free(nbr_list);
+}
+
+/* propagates border values with a linear decrease */
+void propagate(int neighbor_count, f_propmethod prop_method)
+{
+    G_message("Propagating Values ...");
+
+    int patch;
+
+    for (patch = 0; patch < fragcount; patch++) {
+	propagate_patch(patch, neighbor_count, prop_method);
+
+	G_percent(patch + 1, fragcount, 1);
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,76 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING 0
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+typedef struct
+{
+    double x, y;
+} Vector2;
+
+typedef struct
+{
+    Position *positions;
+    Position **borders;
+    int count;
+} PatchBorderList;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef DCELL(*f_propmethod) (DCELL, DCELL);
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* func.c */
+void find_borders(int *flagbuf);
+void init_border_values(double distance, double angle, int buffer,
+			f_statmethod stat, double dist_weight);
+void propagate(int neighbor_count, f_propmethod prop_method);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+
+/* prop_method.c */
+DCELL linear(DCELL value, DCELL propcost);
+DCELL exponential(DCELL value, DCELL propcost);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL Coords *cells;
+GLOBAL Coords **fragments;
+GLOBAL int fragcount;
+GLOBAL int *flagbuf;
+GLOBAL DCELL *map;
+GLOBAL DCELL *valmap;
+GLOBAL DCELL *propmap;
+GLOBAL PatchBorderList *patch_borders;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,510 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.corearea
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Non-linear core area analysis
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {median, "median", "median of values", "med"},
+    {0, 0, 0, 0}
+};
+
+struct propmethod
+{
+    f_propmethod method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct propmethod propmethods[] = {
+    {linear, "linear", "linear decrease of the propagation value", "lin"},
+    {exponential, "exponential",
+     "exponential decrease of the propagation value", "exp"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset, *costname, *costmapset,
+	*propname, *propmapset;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+
+    /* parameters */
+    int keyval;
+    int nbr_count;
+    int buffer;
+    double distance;
+    double angle;
+    f_statmethod method;
+    f_propmethod prop_method;
+    double dist_weight;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    char *str;
+    int row, col, i, j, n;
+    DCELL *values;
+    CELL *result;
+    DCELL *d_res;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *propmap, *output;
+	struct Option *keyval, *buffer;
+	struct Option *distance, *angle;
+	struct Option *stats, *propmethod, *dist_weight;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent;
+    } flag;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Variable edge effects and core area analysis");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = YES;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->description = _("Name of the cost map raster file");
+
+    parm.propmap = G_define_option();
+    parm.propmap->key = "propmap";
+    parm.propmap->type = TYPE_STRING;
+    parm.propmap->required = NO;
+    parm.propmap->gisprompt = "old,cell,raster";
+    parm.propmap->description =
+	_("Name of the propagation cost map raster file");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.buffer = G_define_option();
+    parm.buffer->key = "buffer";
+    parm.buffer->type = TYPE_INTEGER;
+    parm.buffer->required = YES;
+    parm.buffer->description = _("Buffer size");
+
+    parm.distance = G_define_option();
+    parm.distance->key = "distance";
+    parm.distance->type = TYPE_DOUBLE;
+    parm.distance->required = YES;
+    parm.distance->description = _("Cone of effect radius");
+
+    parm.angle = G_define_option();
+    parm.angle->key = "angle";
+    parm.angle->type = TYPE_DOUBLE;
+    parm.angle->required = YES;
+    parm.angle->description = _("Cone of effect angle");
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    str = parm.stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[n].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the values");
+
+    parm.propmethod = G_define_option();
+    parm.propmethod->key = "propmethod";
+    parm.propmethod->type = TYPE_STRING;
+    parm.propmethod->required = YES;
+    str = parm.propmethod->options = G_malloc(1024);
+    for (n = 0; propmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, propmethods[n].name);
+    }
+    parm.propmethod->description = _("Propagation method");
+
+    parm.dist_weight = G_define_option();
+    parm.dist_weight->key = "dist_weight";
+    parm.dist_weight->type = TYPE_DOUBLE;
+    parm.dist_weight->required = NO;
+    parm.dist_weight->description =
+	_("Parameter for distance weighting. <0.5 - rapid decrease; 0.5 - linear decrease; > 0.5 - slow decrease; 1 - no decrease");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+    costname = parm.costmap->answer;
+    propname = parm.propmap->answer;
+
+    /* test input file existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* test costmap file existance */
+    costmapset = G_find_cell2(costname, "");
+	if (costmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), costname);
+
+    /* test propmap file existance */
+    if (propname && NULL == (propmapset = G_find_cell2(propname, "")))
+	    G_fatal_error(_("Raster map <%s> not found"), propname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    G_message("rows = %d, cols = %d", nrows, ncols);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get key value */
+    sscanf(parm.buffer->answer, "%d", &buffer);
+
+    /* get distance */
+    sscanf(parm.distance->answer, "%lf", &distance);
+
+    /* get angle and convert to radian */
+    sscanf(parm.angle->answer, "%lf", &angle);
+    angle *= M_PI / 180.0;
+
+    /* get statistical method */
+    for (i = 0; (str = statmethods[i].name) != 0; i++) {
+	if (strcmp(str, parm.stats->answer) == 0) {
+	    method = statmethods[i].method;
+	    break;
+	}
+    }
+
+    /* get propagation method */
+    for (i = 0; (str = propmethods[i].name) != 0; i++) {
+	if (strcmp(str, parm.propmethod->answer) == 0) {
+	    prop_method = propmethods[i].method;
+	    break;
+	}
+    }
+
+    /* get distance weighting parameter */
+    if (parm.dist_weight->answer) {
+	sscanf(parm.dist_weight->answer, "%lf", &dist_weight);
+    }
+    else {
+	dist_weight = 1.0;
+    }
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    fragments[0] = cells;
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    map = (DCELL *) G_malloc(nrows * ncols * sizeof(DCELL));
+    valmap = (DCELL *) G_malloc(nrows * ncols * sizeof(DCELL));
+    propmap = (DCELL *) G_malloc(nrows * ncols * sizeof(DCELL));
+    result = G_allocate_c_raster_buf();
+    d_res = G_allocate_d_raster_buf();
+
+    G_message("Loading Input files ... ");
+
+    /* open input file */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read patch map */
+    for (row = 0; row < nrows; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval) {
+		flagbuf[row * ncols + col] = 1;
+	    }
+	}
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /* open costmap file */
+    in_fd = G_open_cell_old(costname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), costname);
+
+    /* read patch map */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, &map[row * ncols], row);
+
+	for (col = 0; col < ncols; col++) {
+	    if (G_is_d_null_value(&map[row * ncols + col])) {
+		map[row * ncols + col] = 0.0;
+	    }
+	}
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /* open propmap file */
+    if (propname) {
+	in_fd = G_open_cell_old(propname, propmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), propname);
+
+	/* read propagation map */
+	for (row = 0; row < nrows; row++) {
+	    G_get_d_raster_row(in_fd, &propmap[row * ncols], row);
+
+	    for (col = 0; col < ncols; col++) {
+		if (G_is_d_null_value(&propmap[row * ncols + col])) {
+		    propmap[row * ncols + col] = 0.0;
+		}
+	    }
+	}
+
+	/* close cell file */
+	G_close_cell(in_fd);
+    }
+    else {
+	for (row = 0; row < nrows; row++) {
+	    for (col = 0; col < ncols; col++) {
+		propmap[row * ncols + col] = 1.0;
+	    }
+	}
+    }
+
+    /*G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%0.2f ", map[row * ncols + col]);           
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find fragments */
+    writeFragments(flagbuf, nrows, ncols, nbr_count);
+
+    /* create a patch map */
+    for (i = 0; i < fragcount; i++) {
+	Coords *cell;
+
+	for (cell = fragments[i]; cell < fragments[i + 1]; cell++) {
+	    int x = cell->x;
+	    int y = cell->y;
+
+	    flagbuf[y * ncols + x] = i + 1;
+	}
+    }
+
+    /* allocate memory for border arrays */
+    int cell_cnt = fragments[fragcount] - fragments[0];
+
+    patch_borders =
+	(PatchBorderList *) G_malloc((fragcount + 1) *
+				     sizeof(PatchBorderList));
+
+    /* find borders */
+    G_message("Identifying borders...");
+    find_borders(flagbuf);
+
+    /* flagbuf is not needed any more */
+    G_free(flagbuf);
+
+    /* test output */
+    int patch;
+
+    /*G_message("Borders:");
+       for(patch = 0; patch < fragcount; patch++) {
+       fprintf(stderr, "patch %d\n", patch);
+
+       PatchBorderList list = patch_borders[patch]; 
+
+       int contour;
+       for(contour = 0; contour < list.count; contour++) {
+       fprintf(stderr, "Contour %d: ", contour);
+
+       Position *p;
+       for(p = list.borders[contour]; p < list.borders[contour + 1]; p++) {
+       fprintf(stderr, "(%d, %d)", p->x, p->y);
+       }
+       fprintf(stderr, "\n");
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* fill value map with -1 for empty space and 0 for patches */
+    for (i = 0; i < nrows * ncols; i++) {
+	valmap[i] = -1.0;
+    }
+    for (i = 0; i < fragcount; i++) {
+	Coords *cell;
+
+	for (cell = fragments[i]; cell < fragments[i + 1]; cell++) {
+	    int x = cell->x;
+	    int y = cell->y;
+
+	    valmap[y * ncols + x] = 0.0;
+	}
+    }
+
+    /* initialize border values for propagation */
+    init_border_values(distance, angle, buffer, method, dist_weight);
+
+    propagate(nbr_count, prop_method);
+
+    /*G_message("costmap");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%0.0f ", map[row * ncols + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* test output */
+    /*G_message("patch mask");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       if(flagbuf[row * ncols + col] >= 0) {
+       fprintf(stderr, "%d", flagbuf[row * ncols + col]);
+       } else {
+       fprintf(stderr, "*");
+       }
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* OUTPUT */
+    G_message("Writing Output ...");
+
+    /* write output */
+    /* open the new cellfile  */
+	out_fd = G_open_raster_new(newname, CELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_c_null_value(result, ncols);
+
+	for (i = 0; i < fragcount; i++) {
+	    Coords *p;
+
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    if (valmap[p->y * ncols + p->x] <= 0.0) {
+			result[p->x] = 1;
+		    }
+		}
+	    }
+	}
+
+	G_put_c_raster_row(out_fd, result);
+
+	G_percent(row + 1, 2 * nrows, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* write map */
+    /* open the new cellfile  */
+    sprintf(fullname, "%s_%s", newname, "map");
+    out_fd = G_open_raster_new(fullname, DCELL_TYPE);
+    if (out_fd < 0)
+        G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_put_d_raster_row(out_fd, &valmap[row * ncols]);
+
+	G_percent(nrows + row + 1, 2 * nrows, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* free all buffers */
+    for (patch = 0; patch < fragcount; patch++) {
+	G_free(patch_borders[patch].positions);
+	G_free(patch_borders[patch].borders);
+    }
+    G_free(patch_borders);
+
+    G_free(cells);
+    G_free(fragments);
+    G_free(map);
+    G_free(valmap);
+    G_free(propmap);
+    G_free(result);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/prop_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/prop_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/prop_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,17 @@
+#include "local_proto.h"
+
+DCELL linear(DCELL value, DCELL propcost)
+{
+    value -= propcost;
+    return value >= 0.0 ? value : 0.0;
+}
+
+DCELL exponential(DCELL value, DCELL propcost)
+{
+    if (propcost == 0.0) {
+	return MAX_DOUBLE;
+    }
+    else {
+	return value / propcost;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/prop_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corearea/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corearea/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corearea/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corearea/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass-addons/raster/r.pi/r.pi.corrwin/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwin/description.html	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.corrwin/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,30 +1,44 @@
-<H2>DESCRIPTION</H2>
+<h2>DESCRIPTION</h2>
 
-<P>
 This module computes the correlation between two raster files but unlike
-<EM>r.pi.lm</EM> for moving windows of a specific size. This module used code sniplets from r.neighbours and r.covar.
+<em>r.pi.lm</em> for moving windows of a specific size. This module used
+code sniplets from <em>r.neighbours</em> and <em>r.covar</em>.
 
-The program will be run non-interactively if the user specifies program
-arguments (see OPTIONS) on the command
-line.  Alternately, the user can simply type <B>r.pi.corrwin</B> on the command line, without program
-arguments.  In this case, the user will be prompted for flag settings and parameter values.
+<h2>EXAMPLE</h2>
 
-<H2>NOTES</H2>
+An example for the North Carolina sample dataset:
 
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
 
-<H2>BUGS</H2>
+<h2>SEE ALSO</h2>
 
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
 
-<H2>SEE ALSO</H2>
-
-<EM><A HREF="r.pi.lm.html">r.pi.ENN</A></EM><br>
-<EM><A HREF="r.pi.probmw.html">r.pi.FNN</A></EM><br>
-<EM><A HREF="r.li.setup.html">r.li.setup</A></EM><br>
-
-<H2>AUTHOR</H2>
+<h2>AUTHORS</h2>
 Programming: Elshad Shirinov<br>
-Scientific concept: Dr. Martin Wegmann <br>
-Department of Remote Sensing <br>Remote Sensing and Biodiversity Unit<br> University of Wuerzburg, Germany
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
 
-<p><i>Last changed: $Date$</i>
-
+<p>
+<i>Last changed: $Date$</i>

Modified: grass-addons/raster/r.pi/r.pi.corrwin/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwin/main.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.corrwin/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,19 +1,30 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.corrwin
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Moving window correlation analysis
+ *               Put together from pieces of r.covar and r.neighbors
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
+
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <math.h>
 #include <grass/gis.h>
 #include <grass/glocale.h>
 #include <grass/stats.h>
 #include "ncb.h"
 #include "local_proto.h"
-#include <math.h>
 
-/*
-   Moving window correlation analyse.
 
-   Put together from pieces of r.covar and r.neighbors by Elshad Shirinov.
- */
-
 typedef int (*ifunc) (void);
 
 struct ncb ncb;
@@ -67,32 +78,17 @@
 
     module = G_define_module();
     module->keywords = _("raster");
-    module->description =
-	_("Calculates correlation of two raster maps "
-	  "by calculating correlation function of two "
-	  "corresponding rectangular areas for each "
-	  "raster point and writing the result into a new raster map.");
+    module->description = _("Moving window correlation analysis.");
 
-    parm.input1 = G_define_option();
+    parm.input1 = G_define_standard_option(G_OPT_R_INPUT);
     parm.input1->key = "input1";
-    parm.input1->type = TYPE_STRING;
-    parm.input1->required = YES;
     parm.input1->gisprompt = "old,cell,raster,1";
-    parm.input1->description = _("Name of existing raster file");
 
-    parm.input2 = G_define_option();
+    parm.input2 = G_define_standard_option(G_OPT_R_INPUT);
     parm.input2->key = "input2";
-    parm.input2->type = TYPE_STRING;
-    parm.input2->required = YES;
     parm.input2->gisprompt = "old,cell,raster,2";
-    parm.input2->description = _("Name of existing raster file");
 
-    parm.output = G_define_option();
-    parm.output->key = "output";
-    parm.output->type = TYPE_STRING;
-    parm.output->required = YES;
-    parm.output->gisprompt = "new,cell,raster";
-    parm.output->description = _("Name of the new raster file");
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
 
     parm.size = G_define_option();
     parm.size->key = "size";
@@ -113,64 +109,47 @@
     parm.title->key_desc = "\"phrase\"";
     parm.title->type = TYPE_STRING;
     parm.title->required = NO;
-    parm.title->description = _("Title of the output raster file");
+    parm.title->description = _("Title for resultant raster map");
 
     flag.quiet = G_define_flag();
     flag.quiet->key = 'q';
     flag.quiet->description = _("Run quietly");
 
     if (G_parser(argc, argv))
-	exit(1);
+	exit(EXIT_FAILURE);
 
-    // get names of input files
+    /* get names of input files */
     p1 = ncb.oldcell1.name = parm.input1->answer;
     p2 = ncb.oldcell2.name = parm.input2->answer;
-    // test input files existance
-    if (NULL == (ncb.oldcell1.mapset = G_find_cell2(p1, ""))) {
-	fprintf(stderr, "%s: <%s> raster file not found\n",
-		G_program_name(), p1);
-	exit(1);
-    }
-    if (NULL == (ncb.oldcell2.mapset = G_find_cell2(p2, ""))) {
-	fprintf(stderr, "%s: <%s> raster file not found\n",
-		G_program_name(), p2);
-	exit(1);
-    }
-    // check if new file name is correct
+    /* test input files existance */
+    ncb.oldcell1.mapset = G_find_cell2(p1, "");
+    if (ncb.oldcell1.mapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), p1);
+    ncb.oldcell2.mapset = G_find_cell2(p2, "");
+    if (ncb.oldcell2.mapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), p2);
+
+    /* check if new file name is correct */
     p = ncb.newcell.name = parm.output->answer;
-    if (G_legal_filename(p) < 0) {
-	fprintf(stderr, "%s: <%s> illegal file name\n", G_program_name(), p);
-	exit(1);
-    }
+    if (G_legal_filename(p) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), p);
     ncb.newcell.mapset = G_mapset();
 
-    // get window size
+    /* get window size */
     nrows = G_window_rows();
     ncols = G_window_cols();
 
     fprintf(stderr, "%d x %d ", nrows, ncols);
 
     /* open cell files */
-    if ((in_fd1 =
-	 G_open_cell_old(ncb.oldcell1.name, ncb.oldcell1.mapset)) < 0) {
-	char msg[200];
+    in_fd1 = G_open_cell_old(ncb.oldcell1.name, ncb.oldcell1.mapset);
+	if (in_fd1 < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), ncb.oldcell1.name);
+    in_fd2 = G_open_cell_old(ncb.oldcell2.name, ncb.oldcell2.mapset);
+	if (in_fd2 < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), ncb.oldcell2.name);
 
-	sprintf(msg, "can't open cell file <%s> in mapset %s\n",
-		ncb.oldcell1.name, ncb.oldcell1.mapset);
-	G_fatal_error(msg);
-	exit(-1);
-    }
-    if ((in_fd2 =
-	 G_open_cell_old(ncb.oldcell2.name, ncb.oldcell2.mapset)) < 0) {
-	char msg[200];
-
-	sprintf(msg, "can't open cell file <%s> in mapset %s\n",
-		ncb.oldcell2.name, ncb.oldcell2.mapset);
-	G_fatal_error(msg);
-	exit(-1);
-    }
-
-    // get map types
+    /* get map types */
     map_type1 = G_raster_map_type(ncb.oldcell1.name, ncb.oldcell1.mapset);
     map_type2 = G_raster_map_type(ncb.oldcell2.name, ncb.oldcell2.mapset);
 
@@ -208,10 +187,10 @@
 	readrow++;
     }
 
-    /*open the new cellfile */
+    /* open the new cellfile */
     out_fd = G_open_raster_new(ncb.newcell.name, map_type1);
     if (out_fd < 0)
-	exit(1);
+	    G_fatal_error(_("Cannot create raster map <%s>"), ncb.newcell.name);
 
     if (verbose = !flag.quiet->answer)
 	fprintf(stderr, "Percent complete ... ");
@@ -219,7 +198,7 @@
     for (row = 0; row < nrows; row++) {
 	if (verbose)
 	    G_percent(row, nrows, 2);
-	// read the next row into buffer
+	/* read the next row into buffer */
 	readcell(in_fd1, 1, readrow, nrows, ncols);
 	readcell(in_fd2, 2, readrow, nrows, ncols);
 	readrow++;
@@ -235,15 +214,15 @@
 
 	    DCELL ii, jj;
 
-	    // set pointer to actual position in the result
+	    /* set pointer to actual position in the result */
 	    DCELL *rp = &result[col];
 
-	    // gather values from actual window
+	    /* gather values from actual window */
 	    gather(values1, 1, col);
 	    gather(values2, 2, col);
-	    // go through all values of the window
+	    /* go through all values of the window */
 	    for (i = 0; i < ncb.nsize * ncb.nsize; i++) {
-		// ignore values if both are nan
+		/* ignore values if both are nan */
 		if (!
 		    (G_is_d_null_value(&values1[i]) &&
 		     G_is_d_null_value(&values2[i]))) {
@@ -258,7 +237,7 @@
 		    if (!G_is_d_null_value(&values1[i]) &&
 			!G_is_d_null_value(&values2[i]))
 			mul += values1[i] * values2[i];
-		    // count the number of values actually processed
+		    /* count the number of values actually processed */
 		    count++;
 		}
 	    }
@@ -266,18 +245,18 @@
 		*rp = 0;
 		continue;
 	    }
-	    // calculate normalization
+	    /* calculate normalization */
 	    ii = sqrt((mul1 - sum1 * sum1 / count) / (count - 1.0));
 	    jj = sqrt((mul2 - sum2 * sum2 / count) / (count - 1.0));
 
-	    // set result
+	    /* set result */
 	    *rp =
 		maxval * (mul -
 			  sum1 * sum2 / count) / (ii * jj * (count - 1.0));
 	    if (G_is_d_null_value(rp))
 		G_set_d_null_value(rp, 1);
 	}
-	// write actual result row to the output file
+	/* write actual result row to the output file */
 	G_put_d_raster_row(out_fd, result);
     }
     if (verbose)
@@ -290,5 +269,5 @@
     if (copycolr)
 	G_write_colors(ncb.newcell.name, ncb.newcell.mapset, &colr);
 
-    exit(0);
+    exit(EXIT_SUCCESS);
 }

Added: grass-addons/raster/r.pi/r.pi.corrwindow/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.corrwindow
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/bufs.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/bufs.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/bufs.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,59 @@
+#include <grass/gis.h>
+#include "ncb.h"
+
+/*
+   allocate the i/o bufs
+
+   the i/o bufs will be rotated by the read operation so that the
+   last row read will be in the last i/o buf
+
+ */
+
+int allocate_bufs(void)
+{
+    int i;
+    int bufsize;
+
+    bufsize = (G_window_cols() + 2 * ncb.nsize) * sizeof(DCELL);
+
+    ncb.buf1 = (DCELL **) G_malloc(ncb.nsize * sizeof(DCELL *));
+    ncb.buf2 = (DCELL **) G_malloc(ncb.nsize * sizeof(DCELL *));
+    for (i = 0; i < ncb.nsize; i++) {
+	ncb.buf1[i] = (DCELL *) G_malloc(bufsize);
+	ncb.buf2[i] = (DCELL *) G_malloc(bufsize);
+	G_set_d_null_value(ncb.buf1[i], G_window_cols() + 2 * ncb.nsize);
+	G_set_d_null_value(ncb.buf2[i], G_window_cols() + 2 * ncb.nsize);
+    }
+
+    return 0;
+}
+
+int rotate_bufs(int bufnumber)
+{
+    DCELL *temp;
+    int i;
+
+    if (bufnumber < 1 || bufnumber > 2)
+	return -1;
+
+    if (bufnumber == 1) {
+	temp = ncb.buf1[0];
+
+	for (i = 1; i < ncb.nsize; i++) {
+	    ncb.buf1[i - 1] = ncb.buf1[i];
+	}
+
+	ncb.buf1[ncb.nsize - 1] = temp;
+    }
+    else {
+	temp = ncb.buf2[0];
+
+	for (i = 1; i < ncb.nsize; i++) {
+	    ncb.buf2[i - 1] = ncb.buf2[i];
+	}
+
+	ncb.buf2[ncb.nsize - 1] = temp;
+    }
+
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/bufs.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,38 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.corrwindow</em> provides information concerning the correlation
+of pixels inside a moving window between two raster files.
+<p>
+It calculates correlation of two raster maps by calculating correlation
+function of two corresponding rectangular areas for each raster point and
+writing the result into a new raster map.
+
+<h2>NOTES</h2>
+
+This module computes the correlation between two raster files but unlike
+<em>r.pi.lm</em> for moving windows of a specific size.
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/divr_cats.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/divr_cats.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/divr_cats.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,9 @@
+#include <grass/gis.h>
+#include "ncb.h"
+int divr_cats(void)
+{
+    G_set_cats_fmt("$1 $?different categories$category$", 1.0, 0.0, 0.0, 0.0,
+		   &ncb.cats);
+
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/divr_cats.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/gather.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/gather.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/gather.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,38 @@
+#include <grass/gis.h>
+#include "ncb.h"
+
+/*
+   given the starting col of the neighborhood,
+   copy the cell values from the bufs into the array of values
+   and return the number of values copied.
+ */
+
+int gather(DCELL * values, int bufnumber, int offset)
+{
+    if (bufnumber < 1 || bufnumber > 2)
+	return -1;
+
+    int row, col;
+    int n = 0;
+
+    *values = 0;
+
+    for (row = 0; row < ncb.nsize; row++)
+	for (col = 0; col < ncb.nsize; col++) {
+	    DCELL *c;
+
+	    if (bufnumber == 1)
+		c = &ncb.buf1[row][offset + col];
+	    else
+		c = &ncb.buf2[row][offset + col];
+
+	    if (G_is_d_null_value(c))
+		G_set_d_null_value(&values[n], 1);
+	    else
+		values[n] = *c;
+
+	    n++;
+	}
+
+    return n ? n : -1;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/gather.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/intr_cats.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/intr_cats.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/intr_cats.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,9 @@
+#include <grass/gis.h>
+#include "ncb.h"
+
+int intr_cats(void)
+{
+    G_set_cats_fmt("$1% dispersion", 1.0, -1.0, 0.0, 0.0, &ncb.cats);
+
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/intr_cats.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,18 @@
+/* bufs.c */
+extern int allocate_bufs(void);
+extern int rotate_bufs(int);
+
+/* gather */
+extern int gather(DCELL *, int, int);
+
+/* readcell.c */
+extern int readcell(int, int, int, int, int);
+
+/* divr_cats.c */
+extern int divr_cats(void);
+
+/* intr_cats.c */
+extern int intr_cats(void);
+
+/* null_cats.c */
+extern int null_cats(void);


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,259 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.corrwindow
+ * AUTHOR(S):    Elshad Shirinov, Martin Wegmann
+ * PURPOSE:      Moving window correlation analyse
+ *               Put together from pieces of r.covar and r.neighbors by Elshad Shirinov
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include "ncb.h"
+#include "local_proto.h"
+
+typedef int (*ifunc) (void);
+
+struct ncb ncb;
+
+int main(int argc, char *argv[])
+{
+    char *p, *p1, *p2;
+    int verbose;
+
+    int in_fd1, in_fd2;
+    int out_fd;
+    DCELL *result;
+
+    RASTER_MAP_TYPE map_type1, map_type2;
+
+    int row, col, i, j;
+    int readrow;
+    int maxval;
+
+    int nrows, ncols;
+    int n;
+    int copycolr;
+    struct Colors colr;
+    struct GModule *module;
+    struct
+    {
+	struct Option *input1, *input2, *output;
+	struct Option *size, *max;
+	struct Option *title;
+    } parm;
+    struct
+    {
+	struct Flag *quiet;
+    } flag;
+
+    DCELL *values1, *values2;	/* list of neighborhood values */
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Calculates correlation of two raster maps "
+	  "by calculating correlation function of two "
+	  "corresponding rectangular areas for each "
+	  "raster point and writing the result into a new raster map.");
+
+    parm.input1 = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input1->key = "input1";
+    parm.input1->gisprompt = "old,cell,raster,1";
+
+    parm.input2 = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input2->key = "input2";
+    parm.input2->gisprompt = "old,cell,raster,2";
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.size = G_define_option();
+    parm.size->key = "size";
+    parm.size->type = TYPE_INTEGER;
+    parm.size->required = YES;
+    parm.size->options = "1,3,5,7,9,11,13,15,17,19,21,23,25";
+    parm.size->description = _("Neighborhood size");
+
+    parm.max = G_define_option();
+    parm.max->key = "max";
+    parm.max->type = TYPE_INTEGER;
+    parm.max->required = YES;
+    parm.max->description = _("Correlation maximum value");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	    exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    p1 = ncb.oldcell1.name = parm.input1->answer;
+    p2 = ncb.oldcell2.name = parm.input2->answer;
+    /* test input files existance */
+    ncb.oldcell1.mapset = G_find_cell2(p1, "");
+    if (ncb.oldcell1.mapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), p1);
+    ncb.oldcell2.mapset = G_find_cell2(p2, "");
+    if (ncb.oldcell2.mapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), p2);
+    /* check if new file name is correct */
+    p = ncb.newcell.name = parm.output->answer;
+    if (G_legal_filename(p) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), p);
+    ncb.newcell.mapset = G_mapset();
+
+    /* get window size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    fprintf(stderr, "%d x %d ", nrows, ncols);
+
+    /* open cell files */
+    in_fd1 = G_open_cell_old(ncb.oldcell1.name, ncb.oldcell1.mapset);
+	if (in_fd1 < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), ncb.oldcell1.name);
+    in_fd2 = G_open_cell_old(ncb.oldcell2.name, ncb.oldcell2.mapset);
+	if (in_fd2 < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), ncb.oldcell2.name);
+
+    /* get map types */
+    map_type1 = G_raster_map_type(ncb.oldcell1.name, ncb.oldcell1.mapset);
+    map_type2 = G_raster_map_type(ncb.oldcell2.name, ncb.oldcell2.mapset);
+
+    /* copy color table? */
+    copycolr =
+	(G_read_colors(ncb.oldcell1.name, ncb.oldcell1.mapset, &colr) > 0);
+
+    /* get the neighborhood size */
+    sscanf(parm.size->answer, "%d", &ncb.nsize);
+    ncb.dist = ncb.nsize / 2;
+
+    /* get correlation maximum */
+    sscanf(parm.max->answer, "%d", &maxval);
+
+    /* allocate the cell buffers */
+    allocate_bufs();
+    values1 = (DCELL *) G_malloc(ncb.nsize * ncb.nsize * sizeof(DCELL));
+    values2 = (DCELL *) G_malloc(ncb.nsize * ncb.nsize * sizeof(DCELL));
+    result = G_allocate_d_raster_buf();
+
+    /* get title, initialize the category and stat info */
+    if (parm.title->answer)
+	strcpy(ncb.title, parm.title->answer);
+    else
+	sprintf(ncb.title, "%dx%d neighborhood correlation: %s and %s",
+		ncb.nsize, ncb.nsize, ncb.oldcell1.name, ncb.oldcell2.name);
+
+
+    /* initialize the cell bufs with 'dist' rows of the old cellfile */
+
+    readrow = 0;
+    for (row = 0; row < ncb.dist; row++) {
+	readcell(in_fd1, 1, readrow, nrows, ncols);
+	readcell(in_fd2, 2, readrow, nrows, ncols);
+	readrow++;
+    }
+
+    /*open the new cellfile */
+    out_fd = G_open_raster_new(ncb.newcell.name, map_type1);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), ncb.newcell.name);
+
+    if (verbose = !flag.quiet->answer)
+	fprintf(stderr, "Percent complete ... ");
+
+    for (row = 0; row < nrows; row++) {
+	if (verbose)
+	    G_percent(row, nrows, 2);
+	/* read the next row into buffer */
+	readcell(in_fd1, 1, readrow, nrows, ncols);
+	readcell(in_fd2, 2, readrow, nrows, ncols);
+	readrow++;
+	for (col = 0; col < ncols; col++) {
+	    DCELL sum1 = 0;
+	    DCELL sum2 = 0;
+	    DCELL mul, mul1, mul2;
+
+	    mul = mul1 = mul2 = 0;
+	    double count = 0;
+	    DCELL ii, jj;
+
+	    /* set pointer to actual position in the result */
+	    DCELL *rp = &result[col];
+
+	    /* gather values from actual window */
+	    gather(values1, 1, col);
+	    gather(values2, 2, col);
+	    /* go through all values of the window */
+	    for (i = 0; i < ncb.nsize * ncb.nsize; i++) {
+		/* ignore values if both are nan */
+		if (!
+		    (G_is_d_null_value(&values1[i]) &&
+		     G_is_d_null_value(&values2[i]))) {
+		    if (!G_is_d_null_value(&values1[i])) {
+			sum1 += values1[i];
+			mul1 += values1[i] * values1[i];
+		    }
+		    if (!G_is_d_null_value(&values2[i])) {
+			sum2 += values2[i];
+			mul2 += values2[i] * values2[i];
+		    }
+		    if (!G_is_d_null_value(&values1[i]) &&
+			!G_is_d_null_value(&values2[i]))
+			mul += values1[i] * values2[i];
+		    /* count the number of values actually processed */
+		    count++;
+		}
+	    }
+	    if (count <= 1.1) {
+		*rp = 0;
+		continue;
+	    }
+	    /* calculate normalization */
+	    ii = sqrt((mul1 - sum1 * sum1 / count) / (count - 1.0));
+	    jj = sqrt((mul2 - sum2 * sum2 / count) / (count - 1.0));
+
+	    /* set result */
+	    *rp =
+		maxval * (mul -
+			  sum1 * sum2 / count) / (ii * jj * (count - 1.0));
+	    if (G_is_d_null_value(rp))
+		G_set_d_null_value(rp, 1);
+	}
+	/* write actual result row to the output file */
+	G_put_d_raster_row(out_fd, result);
+    }
+    if (verbose)
+	G_percent(row, nrows, 2);
+
+    G_close_cell(out_fd);
+    G_close_cell(in_fd1);
+    G_close_cell(in_fd2);
+
+    if (copycolr)
+	G_write_colors(ncb.newcell.name, ncb.newcell.mapset, &colr);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/ncb.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/ncb.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/ncb.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,19 @@
+
+struct ncb			/* neighborhood control block */
+{
+    DCELL **buf1, **buf2;	/* for reading cell file */
+    int *value;			/* neighborhood values */
+    int nsize;			/* size of the neighborhood */
+    int dist;			/* nsize/2 */
+    struct Categories cats;
+    char title[1024];
+    FILE *out;
+    struct
+    {
+	char *name;
+	char *mapset;
+    }
+    oldcell1, oldcell2, newcell;
+};
+
+extern struct ncb ncb;


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/ncb.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/null_cats.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/null_cats.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/null_cats.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,12 @@
+#include <grass/gis.h>
+#include "ncb.h"
+
+int null_cats(void)
+{
+    int ncats;
+
+    ncats = G_number_of_cats(ncb.newcell.name, ncb.newcell.mapset);
+    G_init_cats(ncats, ncb.title, &ncb.cats);
+
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/null_cats.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.corrwindow/readcell.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.corrwindow/readcell.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.corrwindow/readcell.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,27 @@
+#include <unistd.h>
+#include <grass/gis.h>
+#include "ncb.h"
+#include "local_proto.h"
+
+int readcell(int fd, int bufnumber, int row, int nrows, int ncols)
+{
+    if (bufnumber < 1 || bufnumber > 2)
+	return -1;
+
+    if (bufnumber == 1)
+	rotate_bufs(1);
+    else
+	rotate_bufs(2);
+
+    if (row < nrows)
+	if (bufnumber == 1)
+	    G_get_d_raster_row(fd, ncb.buf1[ncb.nsize - 1] + ncb.dist, row);
+	else
+	    G_get_d_raster_row(fd, ncb.buf2[ncb.nsize - 1] + ncb.dist, row);
+    else if (bufnumber == 1)
+	G_set_d_null_value(ncb.buf1[ncb.nsize - 1] + ncb.dist, ncols);
+    else
+	G_set_d_null_value(ncb.buf2[ncb.nsize - 1] + ncb.dist, ncols);
+
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.corrwindow/readcell.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.csr.mw
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/analysis.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/analysis.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/analysis.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,281 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int gather_positions(Position * res, int *map, int value, int x, int y,
+		     int sizex, int sizey)
+{
+    int i, j;
+    int count = 0;
+
+    for (j = y; j < y + sizey; j++) {
+	for (i = x; i < x + sizex; i++) {
+	    /* test if position should be considered */
+	    if (map[j * sx + i] == value) {
+		res[count].x = i;
+		res[count].y = j;
+		count++;
+	    }
+	}
+    }
+
+    return count;
+}
+
+/* returns an array with n random positions from the free positions array */
+void get_random_positions(Position * res, int pos_count, Position * free_arr,
+			  int free_count)
+{
+    /* this will save the size of the temporal array */
+    int cur_size = free_count;
+    int cur_pos = 0;
+    int i;
+
+    /* create a temporal copy of the free positions array */
+    Position *temp = (Position *) G_malloc(free_count * sizeof(Position));
+
+    memcpy(temp, free_arr, free_count * sizeof(Position));
+
+    /* choose n random positions */
+    /* delete used positions, to prevent DCELL choice */
+    for (i = 0; i < pos_count; i++) {
+	Position tmp;
+	int pos = Random(cur_size);
+
+	res[cur_pos].x = temp[pos].x;
+	res[cur_pos].y = temp[pos].y;
+
+	cur_size--;
+	cur_pos++;
+
+	/* replace current position with the last one */
+	temp[pos] = temp[cur_size];
+    }
+
+    G_free(temp);
+
+    return;
+}
+
+void get_dist_matrix(DCELL * res, Position * positions, int count)
+{
+    int i, j;
+
+    for (i = 0; i < count; i++) {
+	res[i * count + i] = 0.0;
+	for (j = i + 1; j < count; j++) {
+	    Position *pos1 = positions + i;
+	    Position *pos2 = positions + j;
+	    DCELL dx = pos2->x - pos1->x;
+	    DCELL dy = pos2->y - pos1->y;
+	    DCELL val = sqrt(dx * dx + dy * dy);
+
+	    res[i * count + j] = val;
+	    res[j * count + i] = val;
+	}
+    }
+
+    return;
+}
+
+void get_n_smallest(DCELL * res, DCELL * dist_matrix, int count, int index,
+		    int n)
+{
+    int i, j;
+    int min;
+    int cur_size = count - 1;
+    DCELL *temp = (DCELL *) G_malloc(count * sizeof(DCELL));
+    int border = n < count ? n : count;
+
+    /* copy the index distance row to a temp array */
+    memcpy(temp, dist_matrix + index * count, count * sizeof(DCELL));
+    temp[index] = temp[cur_size];
+
+    /* get n smallest values */
+    for (i = 0; i < border; i++) {
+	res[i] = MAX_DOUBLE;
+	for (j = 0; j < cur_size; j++) {
+	    if (temp[j] < res[i]) {
+		res[i] = temp[j];
+		min = j;
+	    }
+	}
+
+	/* delete i-th minimum */
+	cur_size--;
+	temp[i] = temp[cur_size];
+    }
+
+    G_free(temp);
+}
+
+/* performs actual analysis for one window */
+DCELL perform_test(Position * positions, int count)
+{
+    int i;
+    DCELL *dist_matrix = (DCELL *) G_malloc(count * count * sizeof(DCELL));
+
+    /* TODO: support m-nearest neighbors analysis */
+    DCELL nn_dist;
+    DCELL sum = 0;
+
+    get_dist_matrix(dist_matrix, positions, count);
+
+    for (i = 0; i < count; i++) {
+	get_n_smallest(&nn_dist, dist_matrix, count, i, 1 /* later m */ );
+	sum += nn_dist;
+    }
+
+    G_free(dist_matrix);
+
+    return sum / count;
+}
+
+void clark_evans(DCELL * values, int *map, int *mask, int n, int size)
+{
+    int x, y, nx, ny, sizex, sizey, i;
+    Position *free_arr, *pos_arr;
+    int free_count, pos_count;
+    DCELL value;
+    int progress = 0;
+
+    DCELL *reference;
+    DCELL ref_value;
+    Position *rand_arr;
+
+    /* calculate window size */
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+    sizex = size > 0 ? size : sx;
+    sizey = size > 0 ? size : sy;
+
+    /* allocate memory */
+    free_arr = (Position *) G_malloc(sizex * sizey * sizeof(Position));
+    pos_arr = (Position *) G_malloc(sizex * sizey * sizeof(Position));
+    reference = (DCELL *) G_malloc(n * sizeof(DCELL));
+    rand_arr = (Position *) G_malloc(sizex * sizey * sizeof(Position));
+
+    /* for each window */
+    for (y = 0; y < ny; y++) {
+	for (x = 0; x < nx; x++) {
+	    /* get relevant positions */
+	    free_count =
+		gather_positions(free_arr, mask, 1, x, y, sizex, sizey);
+	    pos_count = gather_positions(pos_arr, map, 1, x, y, sizex, sizey);
+
+	    if (free_count >= pos_count && pos_count > 1) {
+		/* calculate reference value n times */
+		for (i = 0; i < n; i++) {
+		    get_random_positions(rand_arr, pos_count, free_arr,
+					 free_count);
+		    reference[i] = perform_test(rand_arr, pos_count);
+		    progress++;
+		    G_percent(progress, n * nx * ny, 1);
+		}
+
+		/* calculate real value */
+		value = perform_test(pos_arr, pos_count);
+		ref_value = average(reference, n);
+
+		value = value / ref_value;
+	    }
+	    else {
+		value = -1;
+		progress += n;
+		G_percent(progress, n * nx * ny, 1);
+	    }
+
+	    values[y * nx + x] = value;
+	}
+    }
+
+    G_free(pos_arr);
+    G_free(free_arr);
+    G_free(reference);
+    G_free(rand_arr);
+
+    return;
+}
+
+void donnelly(DCELL * values, int *map, int *mask, int n, int size)
+{
+    int x, y, nx, ny, sizex, sizey, i;
+    Position *free_arr, *pos_arr;
+    int free_count, pos_count;
+    DCELL value;
+    int progress = 0;
+
+    DCELL *reference;
+    DCELL ref_value;
+    Position *rand_arr;
+    DCELL correction;
+
+    /* calculate window size */
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+    sizex = size > 0 ? size : sx;
+    sizey = size > 0 ? size : sy;
+
+    /* allocate memory */
+    free_arr = (Position *) G_malloc(sizex * sizey * sizeof(Position));
+    pos_arr = (Position *) G_malloc(sizex * sizey * sizeof(Position));
+    reference = (DCELL *) G_malloc(n * sizeof(DCELL));
+    rand_arr = (Position *) G_malloc(sizex * sizey * sizeof(Position));
+
+    /* for each window */
+    for (y = 0; y < ny; y++) {
+	for (x = 0; x < nx; x++) {
+	    /* get relevant positions */
+	    free_count =
+		gather_positions(free_arr, mask, 1, x, y, sizex, sizey);
+	    pos_count = gather_positions(pos_arr, map, 1, x, y, sizex, sizey);
+
+	    correction =
+		(0.051 + 0.041 / sqrt(pos_count)) * 2 * (nx + ny) / pos_count;
+
+	    if (free_count >= pos_count && pos_count > 1) {
+		/* calculate reference value n times */
+		for (i = 0; i < n; i++) {
+		    DCELL tmp;
+
+		    get_random_positions(rand_arr, pos_count, free_arr,
+					 free_count);
+		    tmp = perform_test(rand_arr, pos_count);
+
+		    /* donnelly correction */
+		    reference[i] = 0.5 * tmp + correction;
+
+		    progress++;
+		    G_percent(progress, n * nx * ny, 1);
+		}
+
+		/* calculate real value */
+		value = perform_test(pos_arr, pos_count);
+
+		/* donnelly correction */
+		value = 0.5 * value + correction;
+
+		ref_value = average(reference, n);
+
+		value = value / ref_value;
+	    }
+	    else {
+		G_set_d_null_value(&value, 1);
+		progress += n;
+		G_percent(progress, n * nx * ny, 1);
+	    }
+
+	    values[y * nx + x] = value;
+	}
+    }
+
+    G_free(pos_arr);
+    G_free(free_arr);
+    G_free(reference);
+    G_free(rand_arr);
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/analysis.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Complete Spatial Randomness analysis on moving window. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,148 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, double distance);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 double distance);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 double distance)
+{
+    int left, right, top, bottom;
+    int i, j;
+    double dist_q = distance * distance;
+    int cnt = 0;
+
+    left = x - distance < 0 ? 0 : Round(x - distance);
+    right = x + distance > nx - 1 ? nx - 1 : Round(x + distance);
+    top = y - distance < 0 ? 0 : Round(y - distance);
+    bottom = y + distance > ny - 1 ? ny - 1 : Round(y + distance);
+
+    for (i = left; i <= right; i++) {
+	for (j = top; j <= bottom; j++) {
+	    if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		int dx = i - x;
+		int dy = j - y;
+		int q_sum = dx * dx + dy * dy;
+
+		if (q_sum <= dist_q) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, double distance)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    int neighb_max_count = Round(4 * distance * distance);
+    Position *nbr_list =
+	(Position *) G_malloc(neighb_max_count * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, distance);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, double distance)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, distance);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,66 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef void (*f_method) (DCELL * values, int *map, int *mask, int n,
+			  int size);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* analysis.c */
+void clark_evans(DCELL * values, int *map, int *mask, int n, int size);
+void donnelly(DCELL * values, int *map, int *mask, int n, int size);
+
+/* global parameters */
+GLOBAL int sx, sy;
+
+/* global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,342 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.csr.mw
+ * AUTHOR(S):    Elshad Shirinov, Martin Wegmann
+ * PURPOSE:      Analysis of CSR (complete spatial randomness) based on movinw window
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct method
+{
+    f_method *method;		/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct method methods[] = {
+    {clark_evans, "clark_evans",
+     "Simple Clark&Evans method without correction."},
+    {donnelly, "donnelly", "Clark&Evans with correction for border bias."},
+    {0, 0, 0}
+};
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* output */
+    char *newname, *newmapset;
+
+    /* mask */
+    char *maskname, *maskmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+
+    /* parameters */
+    int keyval;
+    int n;
+    int size;
+    int method;
+    f_method method_func;
+
+    /* maps */
+    int *map;
+    int *mask;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    DCELL *values;
+    int i, j;
+    Coords *p;
+    char *str;
+    int m;
+    int nx, ny;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output, *mask;
+	struct Option *keyval, *n, *method;
+	struct Option *size;
+    } parm;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Complete Spatial Randomness analysis on moving window.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.mask = G_define_option();
+    parm.mask->key = "mask";
+    parm.mask->type = TYPE_STRING;
+    parm.mask->required = NO;
+    parm.mask->gisprompt = "old,cell,raster";
+    parm.mask->description = _("Name of the mask raster file");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Category value of the patches");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->description =
+	_("Number of repetitions to calculate reference value");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    parm.method->multiple = NO;
+    str = parm.method->options = G_malloc(1024);
+    for (n = 0; methods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, methods[n].name);
+    }
+    parm.method->description = _("Method to calculate resulting index");
+
+    parm.size = G_define_option();
+    parm.size->key = "size";
+    parm.size->type = TYPE_INTEGER;
+    parm.size->required = NO;
+    parm.size->description = _("Size of the output matrix");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    srand(time(NULL));
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of mask */
+    maskname = parm.mask->answer;
+
+    /* test costmap existance */
+    if (maskname && (maskmapset = G_find_cell2(maskname, "")) == NULL)
+	        G_fatal_error(_("Raster map <%s> not found"), maskname);
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get size */
+    if (parm.size->answer) {
+	sscanf(parm.size->answer, "%d", &size);
+    }
+    else {
+	size = 0;
+    }
+
+    /* scan all method answers */
+    for (m = 0; (str = methods[m].name) != NULL; m++) {
+	if (strcmp(str, parm.method->answer) == 0)
+	    break;
+    }
+    if (str == NULL) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.method->key, parm.method->answer, parm.method->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* set method */
+    method_func = methods[m].method;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    map_type = DCELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* test output */
+    /*      G_message("TEST OUTPUT :");
+       G_message("input = %s", oldname);
+       G_message("output = %s", newname);
+       G_message("mask = %s", maskname);
+       G_message("keyval = %d", keyval);    
+       G_message("n = %d", n);
+       G_message("size = %d", size);
+       G_message("distance = %0.2f", distance);
+       G_message("patch_only = %d", patch_only); */
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    mask = (DCELL *) G_malloc(sx * sy * sizeof(int));
+
+    result = G_allocate_c_raster_buf();
+    d_res = G_allocate_d_raster_buf();
+
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+    values = (DCELL *) G_malloc(nx * ny * sizeof(Coords));
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row, sy, 2);
+    }
+    G_percent(1, 1, 2);
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if mask specified, read mask */
+    if (maskname) {
+	/* open mask file */
+	in_fd = G_open_cell_old(maskname, maskmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), maskname);
+
+	/* read mask */
+	G_message("Reading mask file:");
+	for (row = 0; row < sy; row++) {
+	    G_get_c_raster_row(in_fd, result, row);
+	    for (col = 0; col < sx; col++) {
+		mask[row * sx + col] = result[col];
+	    }
+
+	    G_percent(row, sy, 2);
+	}
+	G_percent(1, 1, 2);
+
+	/* close mask */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill mask with 1 */
+	for (i = 0; i < sx * sy; i++) {
+	    mask[i] = 1;
+	}
+    }
+
+    G_message("Performing analysis:");
+
+    method_func(values, map, mask, n, size);
+
+    /* test output */
+    /*G_message("Values: ");
+       for(j = 0; j < ny; j++) {
+       for(i = 0; i < nx; i++) {
+       fprintf(stderr, "%0.2f ", values[j * nx + i]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    if (size > 0) {
+	G_message("Writing output...");
+
+	/* open the new cellfile  */
+	out_fd = G_open_raster_new(newname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    if (row >= size / 2 && row < ny + size / 2) {
+		for (col = 0; col < nx; col++) {
+		    d_res[col + size / 2] =
+			values[(row - size / 2) * nx + col];
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+    }
+    else {
+	fprintf(stdout, "\n\noutput = %lf\n\n", values[0]);
+    }
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(mask);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.csr.mw/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.csr.mw/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.csr.mw/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.csr.mw/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.energy
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.energy/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,33 @@
+<h2>DESCRIPTION</h2>
+
+Individual-based dispersal model for connectivity analysis - energy based. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.energy.iter.html">r.energy.iter</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.energy/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,113 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    DCELL energy;
+    int finished;
+    int immigrated;
+    int last_cat;
+    int lost;
+} Individual;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    double weight;
+} WeightedCoords;
+
+typedef struct
+{
+    int x, y;
+} Displacement;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* search.c */
+void perform_search(int *map, DCELL * costmap, DCELL * suitmap);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* parameters */
+GLOBAL int sx, sy;
+GLOBAL int keyval;
+GLOBAL int n;
+GLOBAL double energy;
+GLOBAL double percent;
+GLOBAL int step_length;
+GLOBAL int out_freq;
+GLOBAL int perception_range;
+GLOBAL double multiplicator;
+GLOBAL int setback;
+GLOBAL double step_range;
+
+/* more global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+GLOBAL Individual *indi_array;
+GLOBAL int *immigrants;
+GLOBAL int *migrants;
+GLOBAL int *emigrants;
+GLOBAL int *patch_registry;	// ( patch1(indi1, indi2, ...), patch2(...), ... )
+GLOBAL int *lost;
+GLOBAL int *migrants_succ;
+GLOBAL int *immi_matrix;
+GLOBAL int *mig_matrix;
+
+GLOBAL char *newname, *newmapset;
+GLOBAL char outname[GNAME_MAX];
+
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.energy/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,1212 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.energy
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Individual-based dispersal model for connectivity analysis - energy-based
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* costmap */
+    char *costname, *costmapset;
+
+    /* suitability map */
+    char *suitname, *suitmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+    FILE *out_fp;
+
+    /* maps */
+    int *map;
+    DCELL *costmap;
+    DCELL *suitmap;
+
+    /* other parameters */
+    DCELL threshold;
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    int neighb_count;
+    int i, j;
+    Coords *p;
+    char *str;
+    int method;
+    char outname[GNAME_MAX];
+    int sum;
+    int out_progress, out_max;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *suitability, *output, *out_immi;
+	struct Option *keyval, *step_length, *step_range, *perception,
+	    *multiplicator, *n;
+	struct Option *energy, *percent, *out_freq, *immi_matrix, *mig_matrix,
+	    *binary_matrix;
+	struct Option *threshold, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *setback, *diversity, *indices;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Individual-based dispersal model for connectivity analysis - energy based.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = NO;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->guisection = "Optional";
+    parm.costmap->description = _("Name of the costmap");
+
+    parm.suitability = G_define_option();
+    parm.suitability->key = "suitability";
+    parm.suitability->type = TYPE_STRING;
+    parm.suitability->required = NO;
+    parm.suitability->gisprompt = "old,cell,raster";
+    parm.suitability->guisection = "Optional";
+    parm.suitability->description =
+	_("Name of the suitability raster with values from 0-100");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.out_immi = G_define_option();
+    parm.out_immi->key = "out_immi";
+    parm.out_immi->type = TYPE_STRING;
+    parm.out_immi->required = NO;
+    parm.out_immi->gisprompt = "new,cell,raster";
+    parm.out_immi->guisection = "Optional";
+    parm.out_immi->description =
+	_("Name of the optional raster file for patch immigrants count");
+
+    parm.immi_matrix = G_define_option();
+    parm.immi_matrix->key = "immi_matrix";
+    parm.immi_matrix->type = TYPE_STRING;
+    parm.immi_matrix->required = NO;
+    parm.immi_matrix->gisprompt = "new_file,file,output";
+    parm.immi_matrix->guisection = "Optional";
+    parm.immi_matrix->description =
+	_("Name for immigrants matrix ASCII-file");
+
+    parm.mig_matrix = G_define_option();
+    parm.mig_matrix->key = "mig_matrix";
+    parm.mig_matrix->type = TYPE_STRING;
+    parm.mig_matrix->required = NO;
+    parm.mig_matrix->gisprompt = "new_file,file,output";
+    parm.mig_matrix->guisection = "Optional";
+    parm.mig_matrix->description = _("Name for migrants matrix ASCII-file");
+
+    parm.binary_matrix = G_define_option();
+    parm.binary_matrix->key = "binary_matrix";
+    parm.binary_matrix->type = TYPE_STRING;
+    parm.binary_matrix->required = NO;
+    parm.binary_matrix->gisprompt = "new_file,file,output";
+    parm.binary_matrix->description =
+	_("Name for binary immigrants(migrants) matrix ASCII-file");
+    parm.binary_matrix->guisection = "Optional";
+
+    parm.threshold = G_define_option();
+    parm.threshold->key = "threshold";
+    parm.threshold->type = TYPE_DOUBLE;
+    parm.threshold->required = NO;
+    parm.threshold->description =
+	_("Percentage of individuals which must have immigrated(migrated)"
+	  " successfully to be considered for the binary immigrants(migrants) matrix");
+    parm.threshold->guisection = "Optional";
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->guisection = "Required";
+    parm.keyval->description = _("Category value of the patches");
+
+    parm.step_length = G_define_option();
+    parm.step_length->key = "step_length";
+    parm.step_length->type = TYPE_INTEGER;
+    parm.step_length->required = YES;
+    parm.step_length->guisection = "Required";
+    parm.step_length->description =
+	_("Length of a single step measured in pixels");
+
+    parm.step_range = G_define_option();
+    parm.step_range->key = "step_range";
+    parm.step_range->type = TYPE_DOUBLE;
+    parm.step_range->required = NO;
+    parm.step_range->description =
+	_("Range to choose the next step direction from, in degrees"
+	  " [default = 180°]");
+    parm.step_range->guisection = "Optional";
+
+    parm.perception = G_define_option();
+    parm.perception->key = "perception";
+    parm.perception->type = TYPE_INTEGER;
+    parm.perception->required = NO;
+    parm.perception->guisection = "Optional";
+    parm.perception->description = _("Perception range");
+
+    parm.multiplicator = G_define_option();
+    parm.multiplicator->key = "multiplicator";
+    parm.multiplicator->type = TYPE_DOUBLE;
+    parm.multiplicator->required = NO;
+    parm.multiplicator->guisection = "Optional";
+    parm.multiplicator->description = _("Attractivity of patches [1-inf]");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->guisection = "Required";
+    parm.n->description = _("Number of individuals");
+
+    parm.energy = G_define_option();
+    parm.energy->key = "energy";
+    parm.energy->type = TYPE_DOUBLE;
+    parm.energy->required = YES;
+    parm.energy->guisection = "Required";
+    parm.energy->description = _("Initial energy of the individuals");
+
+    parm.percent = G_define_option();
+    parm.percent->key = "percent";
+    parm.percent->type = TYPE_DOUBLE;
+    parm.percent->required = YES;
+    parm.percent->guisection = "Required";
+    parm.percent->description =
+	_("Percentage of finished individuals desired before simulation ends");
+
+    parm.out_freq = G_define_option();
+    parm.out_freq->key = "out_freq";
+    parm.out_freq->type = TYPE_INTEGER;
+    parm.out_freq->required = NO;
+    parm.out_freq->guisection = "Optional";
+    parm.out_freq->description =
+	_("Output an intermediate state of simulation each [out_freq] steps");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->guisection = "Optional";
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->guisection = "Required";
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.setback = G_define_flag();
+    flag.setback->key = 'b';
+    flag.setback->guisection = "Required";
+    flag.setback->description =
+	_("Set if individuals should be set back after leaving area");
+
+    flag.diversity = G_define_flag();
+    flag.diversity->key = 'd';
+    flag.diversity->description = _("Output diversity map");
+
+    flag.indices = G_define_flag();
+    flag.indices->key = 'i';
+    flag.indices->description = _("Output Shannon- and Simpson-index");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    srand(time(NULL));
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input file existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of costmap */
+    costname = parm.costmap->answer;
+
+    /* test costmap existance */
+    if (costname && (costmapset = G_find_cell2(costname, "")) == NULL) {
+	G_warning(_("%s: <%s> raster file not found\n"), G_program_name(),
+		  costname);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* get name of suitability map */
+    suitname = parm.suitability->answer;
+
+    /* test costmap existance */
+    if (suitname && (suitmapset = G_find_cell2(suitname, "")) == NULL) {
+	G_warning(_("%s: <%s> raster file not found\n"), G_program_name(),
+		  suitname);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get step_length */
+    sscanf(parm.step_length->answer, "%d", &step_length);
+
+    /* get step_range */
+    if (parm.step_range->answer) {
+	sscanf(parm.step_range->answer, "%lf", &step_range);
+	step_range /= 180.0;
+    }
+    else {
+	step_range = 1.0;
+    }
+
+    /* get perception_range */
+    if (parm.perception->answer) {
+	sscanf(parm.perception->answer, "%d", &perception_range);
+    }
+    else {
+	perception_range = step_length;
+    }
+
+    /* get multiplicator */
+    if (parm.multiplicator->answer) {
+	sscanf(parm.multiplicator->answer, "%lf", &multiplicator);
+    }
+    else {
+	multiplicator = 1.0;
+    }
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get energy */
+    sscanf(parm.energy->answer, "%lf", &energy);
+
+    /* get percent */
+    sscanf(parm.percent->answer, "%lf", &percent);
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get setback flag */
+    setback = flag.adjacent->answer;
+
+    /* get out_freq */
+    if (parm.out_freq->answer != NULL) {
+	sscanf(parm.out_freq->answer, "%d", &out_freq);
+    }
+    else {
+	out_freq = 0;
+    }
+
+    /* get threshold */
+    if (parm.threshold->answer) {
+	sscanf(parm.threshold->answer, "%lf", &threshold);
+    }
+    else {
+	threshold = 0.0;
+    }
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* test output */
+    /*fprintf(stderr, "TEST OUTPUT : \n");
+       fprintf(stderr, "input = %s\n", oldname);
+       fprintf(stderr, "output = %s\n", newname);
+       fprintf(stderr, "costmap = %s\n", costname);
+       fprintf(stderr, "keyval = %d\n", keyval);
+       fprintf(stderr, "step_length = %d\n", step_length);
+       fprintf(stderr, "n = %d\n", n);
+       fprintf(stderr, "energy = %0.2f\n", energy);
+       fprintf(stderr, "Stats: ");
+       for(i = 0; i < stat_count; i++) {
+       fprintf(stderr, statmethods[stats[i]].name);
+       } */
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    costmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    suitmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    d_res = G_allocate_d_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row + 1, sy, 1);
+    }
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if costmap specified, read costmap */
+    if (costname != NULL) {
+	/* open costmap */
+	if ((in_fd = G_open_cell_old(costname, costmapset)) < 0) {
+	    G_fatal_error(_("can't open cell file <%s> in mapset %s\n"),
+			  costname, costmapset);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	/* read costmap */
+	G_message("Reading costmap:");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		costmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close costmap */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill costmap with 1 */
+	for (i = 0; i < sx * sy; i++) {
+	    costmap[i] = 1;
+	}
+    }
+
+    /* if suitability map specified, read it */
+    if (suitname != NULL) {
+	/* open suitability map */
+	if ((in_fd = G_open_cell_old(suitname, suitmapset)) < 0) {
+	    G_fatal_error(_("can't open cell file <%s> in mapset %s\n"),
+			  suitname, suitmapset);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	/* read suitability map */
+	G_message("Reading suitability map file:\n");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		suitmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close suitability map */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no suitability map specified, fill it with 100 */
+	for (i = 0; i < sx * sy; i++) {
+	    suitmap[i] = 100;
+	}
+    }
+
+    /* test output */
+    /*      G_message("costmap:\n");
+       print_d_buffer(costmap, sx, sy); */
+
+    /* find fragments */
+    writeFragments(map, sy, sx, neighb_count);
+
+    /* test output */
+    /*      print_fragments(); */
+
+    /* mark each fragment with its number */
+    for (i = 0; i < sx * sy; i++) {
+	map[i] = -1;
+    }
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    map[p->y * sx + p->x] = i;
+	}
+    }
+
+    /* test output */
+    /*      print_buffer(map, sx, sy); */
+    G_message("Performing search runs:");
+
+    /* allocate space for patch immigrants */
+    immigrants = (int *)G_malloc(fragcount * sizeof(int));
+    migrants = (int *)G_malloc(fragcount * sizeof(int));
+    migrants_succ = (int *)G_malloc(fragcount * sizeof(int));
+    emigrants = (int *)G_malloc(fragcount * sizeof(int));
+    lost = (int *)G_malloc(fragcount * sizeof(int));
+
+    memset(immigrants, 0, fragcount * sizeof(int));
+    memset(migrants, 0, fragcount * sizeof(int));
+    memset(migrants_succ, 0, fragcount * sizeof(int));
+    memset(emigrants, 0, fragcount * sizeof(int));
+    memset(lost, 0, fragcount * sizeof(int));
+
+    /* perform search */
+    perform_search(map, costmap, suitmap);
+
+    /* test output */
+    /*G_message("Results:");
+       for(j = 0; j < stat_count; j++) {
+       G_message("%s: ", statmethods[stats[j]].name);
+       for(i = 0; i < fragcount; i++) {
+       fprintf(stderr, "frag%d: %0.2f ", i, values[j * fragcount + i]);
+       }
+       fprintf(stderr, "\n");
+       }
+       G_message(""); */
+
+    G_message("Writing output...");
+
+    /* set up progress display vaiables */
+    out_progress = 0;
+    out_max = sy * 7;
+
+    /* write immigrants */
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_imi", newname);
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write the output file */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] = immigrants[i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(++out_progress, out_max, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* write immigrants percentual */
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_imi_percent", newname);
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* count all imigrants */
+    sum = 0;
+    for (i = 0; i < fragcount; i++) {
+	sum += immigrants[i];
+    }
+
+    /* write the output file */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] =
+			sum >
+			0 ? 100.0 * (DCELL) immigrants[i] / (DCELL) sum : 0;
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(++out_progress, out_max, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* write migrants */
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_mig", newname);
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write the output file */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] = migrants[i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(++out_progress, out_max, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* write successful migrants */
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_mig_succ", newname);
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write the output file */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] =
+			migrants[i] >
+			0 ? 100.0 * (DCELL) migrants_succ[i] /
+			(DCELL) migrants[i] : 0;
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(++out_progress, out_max, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* write successful migrants */
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_mig_unsucc", newname);
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write the output file */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] =
+			migrants[i] >
+			0 ? 100.0 -
+			100.0 * (DCELL) migrants_succ[i] /
+			(DCELL) migrants[i] : 0;
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(++out_progress, out_max, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* write emigrants */
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_emi", newname);
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write the output file */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] =
+			n > 0 ? 100.0 * (DCELL) emigrants[i] / (DCELL) n : 0;
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(++out_progress, out_max, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    if (!setback) {
+	/* write lost */
+
+	/* open the new cellfile  */
+	sprintf(outname, "%s_lost", newname);
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    n > 0 ? 100.0 * (DCELL) lost[i] / (DCELL) n : 0;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(++out_progress, out_max, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* open ASCII-file or use stdout */
+    if (parm.immi_matrix->answer) {
+	if (strcmp(parm.immi_matrix->answer, "-") != 0) {
+	    if (!(out_fp = fopen(parm.immi_matrix->answer, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"),
+			      parm.immi_matrix->answer);
+	    }
+	}
+	else {
+	    out_fp = stdout;
+	}
+
+	/* write data */
+	for (i = 0; i < fragcount; i++) {
+	    for (j = 0; j < fragcount; j++) {
+		fprintf(out_fp, "%d ", immi_matrix[i * fragcount + j]);
+	    }
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close file */
+	if (strcmp(parm.immi_matrix->answer, "-") != 0) {
+	    fclose(out_fp);
+	}
+    }
+
+    /* open ASCII-file or use stdout */
+    if (parm.mig_matrix->answer) {
+	if (strcmp(parm.mig_matrix->answer, "-") != 0) {
+	    if (!(out_fp = fopen(parm.mig_matrix->answer, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"),
+			      parm.mig_matrix->answer);
+	    }
+	}
+	else {
+	    out_fp = stdout;
+	}
+
+	/* write data */
+	for (i = 0; i < fragcount; i++) {
+	    for (j = 0; j < fragcount; j++) {
+		fprintf(out_fp, "%d ", mig_matrix[i * fragcount + j]);
+	    }
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close file */
+	if (strcmp(parm.mig_matrix->answer, "-") != 0) {
+	    fclose(out_fp);
+	}
+    }
+
+    /* write binary immigrants matrix ASCII file */
+    if (parm.binary_matrix->answer) {
+	if (strcmp(parm.binary_matrix->answer, "-") != 0) {
+	    sprintf(outname, "%s_immi", parm.binary_matrix->answer);
+	    if (!(out_fp = fopen(outname, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"), outname);
+	    }
+	}
+	else {
+	    out_fp = stdout;
+	}
+
+	/* write data */
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants from patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += immi_matrix[j * fragcount + i];
+	    }
+
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (immi_matrix[i * fragcount + j] > threshold_count) {
+		    fprintf(out_fp, "1 ");
+		}
+		else {
+		    fprintf(out_fp, "0 ");
+		}
+	    }
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close file */
+	if (strcmp(parm.binary_matrix->answer, "-") != 0) {
+	    fclose(out_fp);
+	}
+    }
+
+    /* write binary immigrants matrix ASCII file */
+    if (parm.binary_matrix->answer) {
+	if (strcmp(parm.binary_matrix->answer, "-") != 0) {
+	    sprintf(outname, "%s_mig", parm.binary_matrix->answer);
+	    if (!(out_fp = fopen(outname, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"), outname);
+	    }
+	}
+	else {
+	    out_fp = stdout;
+	}
+
+	/* write data */
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants from patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += mig_matrix[j * fragcount + i];
+	    }
+
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (mig_matrix[i * fragcount + j] > threshold_count) {
+		    fprintf(out_fp, "1 ");
+		}
+		else {
+		    fprintf(out_fp, "0 ");
+		}
+	    }
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close file */
+	if (strcmp(parm.binary_matrix->answer, "-") != 0) {
+	    fclose(out_fp);
+	}
+    }
+
+    /* write diversity maps */
+    if (flag.diversity->answer) {
+	/* calculate diversity */
+	DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants in patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += immi_matrix[j * fragcount + i];
+	    }
+
+	    /* calculate threshold count */
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    DCELL value = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (immi_matrix[j * fragcount + i] > threshold_count) {
+		    value++;
+		}
+	    }
+
+	    values[i] = value;
+	}
+
+	/* diversity */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s_immi", newname, "diversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* diversity percentual */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s_immi_percentual", newname, "diversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    values[i] / (DCELL) (fragcount - 1) * 100.0;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write antidiversity maps */
+    if (flag.diversity->answer) {
+	/* calculate antidiversity */
+	DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants from patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += immi_matrix[i * fragcount + j];
+	    }
+
+	    /* calculate threshold count */
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    DCELL value = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (immi_matrix[i * fragcount + j] > threshold_count) {
+		    value++;
+		}
+	    }
+
+	    values[i] = value;
+	}
+
+	/* antidiversity */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "antidiversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* antidiversity percentual */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "antidiversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    values[i] / (DCELL) (fragcount - 1) * 100.0;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write diversity map for migrants */
+    if (flag.diversity->answer) {
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s_mig", newname, "diversity");
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		/* calculate sum of all migrants from patch i */
+		int sum = 0;
+
+		for (j = 0; j < fragcount; j++) {
+		    sum += mig_matrix[j * fragcount + i];
+		}
+
+		/* calculate threshold count */
+		int threshold_count = (int)(threshold * (double)sum) / 100;
+
+		DCELL value = 0;
+
+		for (j = 0; j < fragcount; j++) {
+		    if (mig_matrix[j * fragcount + i] > threshold_count) {
+			value++;
+		    }
+		}
+
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = value;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write indices for immigrants */
+    if (flag.indices->answer) {
+	/* SHANNON */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "shannon");
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	fprintf(stderr, "Immigrant matrix:\n");
+	for (i = 0; i < fragcount; i++) {
+	    for (j = 0; j < fragcount; j++) {
+		fprintf(stderr, " %d", immi_matrix[j * fragcount + i]);
+	    }
+	    fprintf(stderr, "\n");
+	}
+	fprintf(stderr, "\n");
+
+	/* calculate indices */
+	DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	for (i = 0; i < fragcount; i++) {
+	    int N = 0;
+	    DCELL sum = 0.0;
+
+	    for (j = 0; j < fragcount; j++) {
+		int immi = immi_matrix[i * fragcount + j];
+
+		if (immi > 0) {
+		    N += immi;
+		    sum += (DCELL) immi *log((DCELL) immi);
+		}
+	    }
+
+	    values[i] = log((DCELL) N) - sum / (DCELL) N;
+	}
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* SIMPSON */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "simpson");
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* calculate indices */
+	for (i = 0; i < fragcount; i++) {
+	    int N = 0;
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		int immi = immi_matrix[j * fragcount + i];
+
+		N += immi;
+		sum += immi * (immi - 1);
+	    }
+
+	    values[i] = (DCELL) sum / (DCELL) (N * (N - 1));
+	}
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	G_free(values);
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(costmap);
+    G_free(cells);
+    G_free(fragments);
+    G_free(immigrants);
+    G_free(migrants);
+    G_free(migrants_succ);
+    G_free(emigrants);
+    G_free(lost);
+    G_free(immi_matrix);
+    G_free(mig_matrix);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/search.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/search.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/search.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,591 @@
+#include "local_proto.h"
+
+/* globals */
+
+int global_progress = 0;
+int pickpos_count;
+int perception_count;
+WeightedCoords *pos_arr;
+Displacement *displacements;
+Displacement *perception;
+DCELL *indi_steps;
+
+/*
+   output raster with current simulation state
+ */
+void test_output(int *map, int patch, int step, int n)
+{
+    int out_fd;
+    int row, col, i;
+    char outname[GNAME_MAX];
+    DCELL *outmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_patch%d_step%d", newname, patch, step);
+
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write map */
+
+    for (i = 0; i < sx * sy; i++) {
+	outmap[i] = 0;
+    }
+
+    for (i = 0; i < n; i++) {
+	int x, y;
+	Individual *indi = indi_array + i;
+
+	x = indi->x;
+	y = indi->y;
+
+	//              fprintf(stderr, "indi%d: (%d, %d)\n", i, x, y);
+	if (!indi->lost) {
+	    outmap[x + y * sx]++;
+	}
+    }
+
+    for (i = 0; i < sx * sy; i++) {
+	if (map[i] != TYPE_NOTHING && outmap[i] == 0) {
+	    outmap[i] = -1;
+	}
+    }
+
+    /*      for(row = 0; row < sy; row++) {
+       for(col = 0; col < sx; col++) {
+       fprintf(stderr, "%0.0f", outmap[row * sx + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* write output */
+    for (row = 0; row < sy; row++) {
+	G_put_d_raster_row(out_fd, outmap + row * sx);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+    G_free(outmap);
+}
+
+/*
+   sorts cells in a fragment, so that border cells come first
+ */
+int sort_frag(Coords * frag, int size)
+{
+    int i, j;
+    Coords temp;
+
+    i = 0;
+    j = size - 1;
+
+    while (i <= j) {
+	while (frag[i].neighbors < 4 && i < size)
+	    i++;
+	while (frag[j].neighbors == 4 && j >= 0)
+	    j--;
+
+	if (i < j) {
+	    temp = frag[i];
+	    frag[i] = frag[j];
+	    frag[j] = temp;
+	}
+    }
+
+    /*      fprintf(stderr, "Sorted fragment: (%d, %d: %d)", frag->x, frag->y, frag->neighbors);
+       for(j = 1; j < size; j++) {
+       fprintf(stderr, " (%d, %d: %d)", frag[j].x, frag[j].y, frag[j].neighbors);
+       }
+       fprintf(stderr, "\n"); */
+
+    return i;
+}
+
+/*
+   picks a random direction pointing outwards a patch
+ */
+double pick_dir(int *map, Coords * frag)
+{
+    double dirs[4];
+    int i;
+    double pick;
+
+    int x = frag->x;
+    int y = frag->y;
+    int count = 0;
+
+    if (x < sx - 1 && map[x + 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.0;
+    if (y > 0 && map[x + (y + 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.25;
+    if (x > 0 && map[x - 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.5;
+    if (y < sy - 1 && map[x + (y - 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.75;
+
+    pick = count * Randomf();
+
+    for (i = count - 1; i >= 0; i--) {
+	if (pick > i) {
+	    double res = 0.25 * (pick - i) + dirs[i] - 0.125;
+
+	    if (res < 0) {
+		res++;
+	    }
+	    //                      res = res < 0 ? 2 * M_PI + res : res;
+	    return res;
+	}
+    }
+
+    return -1;			// error
+}
+
+/*
+   initializes all individuals for a fragment
+ */
+void init_individuals(int *map, int frag, int size, int n)
+{
+    int i, border_count, index;
+    Coords *cell;
+    Coords *fragment = fragments[frag];
+
+    border_count = sort_frag(fragment, size);
+
+    //      G_message("Initializing");
+
+    for (i = 0; i < n; i++) {
+	//              G_message("border_count = %d", border_count);
+
+	/* pick border cell */
+	index = Random(border_count);
+	cell = fragment + index;
+
+	indi_array[i].x = cell->x + 0.5;
+	indi_array[i].y = cell->y + 0.5;
+	indi_array[i].dir = pick_dir(map, cell);	//2 * M_PI * Randomf();
+	indi_array[i].energy = energy;
+	indi_array[i].finished = 0;
+	indi_array[i].immigrated = 0;
+	indi_array[i].last_cat = frag;
+	indi_array[i].lost = 0;
+
+	//              fprintf(stderr, "indi%d: ", i);
+	//              fprintf(stderr, "x=%0.2f, y=%0.2f, dir=%0.2f, finished=%d\n",
+	//                              indi_array[i].x, indi_array[i].y, indi_array[i].dir, indi_array[i].finished);
+    }
+    //      G_message("End initialization");
+}
+
+/*
+   sets back an individual, when position is illegal
+ */
+void set_back(int *map, int indi, int frag)
+{
+    int index;
+    Coords *cell;
+    int border_count =
+	sort_frag(fragments[frag], fragments[frag + 1] - fragments[frag]);
+
+    /* pick border cell */
+    index = Random(border_count);
+    cell = fragments[frag] + index;
+
+    indi_array[indi].x = cell->x;
+    indi_array[indi].y = cell->y;
+    indi_array[indi].dir = pick_dir(map, cell);
+    indi_array[indi].finished = 0;
+    indi_array[indi].last_cat = frag;
+}
+
+/*
+   sets displacement pixels taking advantage of symmetry
+ */
+void set_pixels(Displacement * values, int x, int y, int r)
+{
+    if (y == 0) {
+	values[0].x = x;
+	values[0].y = 0;
+	values[2 * r].x = 0;
+	values[2 * r].y = x;
+	values[4 * r].x = -x;
+	values[4 * r].y = 0;
+	values[6 * r].x = 0;
+	values[6 * r].y = -x;
+    }
+    else if (y == x) {
+	values[r].x = y;
+	values[r].y = y;
+	values[3 * r].x = -y;
+	values[3 * r].y = y;
+	values[5 * r].x = -y;
+	values[5 * r].y = -y;
+	values[7 * r].x = y;
+	values[7 * r].y = -y;
+    }
+    else if (y < x) {
+	values[r - x + y].x = x;
+	values[r - x + y].y = y;
+	values[r + x - y].x = y;
+	values[r + x - y].y = x;
+	values[3 * r - x + y].x = -y;
+	values[3 * r - x + y].y = x;
+	values[3 * r + x - y].x = -x;
+	values[3 * r + x - y].y = y;
+	values[5 * r - x + y].x = -x;
+	values[5 * r - x + y].y = -y;
+	values[5 * r + x - y].x = -y;
+	values[5 * r + x - y].y = -x;
+	values[7 * r - x + y].x = y;
+	values[7 * r - x + y].y = -x;
+	values[7 * r + x - y].x = x;
+	values[7 * r + x - y].y = -y;
+    }
+}
+
+/*
+   calculates displacements for a circle of given radius
+ */
+void calculate_displacement(Displacement * values, int radius)
+{
+    int dx = radius;
+    int dy = 0;
+    float dx_ = (float)dx - 0.5f;
+    float dy_ = (float)dy + 0.5f;
+    float f = 0.5f - (float)radius;
+
+    set_pixels(values, dx, dy, radius);
+
+    while (dx > dy) {
+	if (f < 0) {
+	    f += 2 * dy_ + 1;
+	    dy_++;
+	    dy++;
+	}
+	else {
+	    f += 1 - 2 * dx_;
+	    dx_--;
+	    dx--;
+	}
+
+	set_pixels(values, dx, dy, radius);
+    }
+}
+
+/*
+   fills a weighted array with possible next positions
+ */
+void pick_nextpos(WeightedCoords * result, int indi, int *map,
+		  DCELL * suitmap, int frag)
+{
+    int i;
+    double ex_step, ex_pos;
+    Individual *individual = indi_array + indi;
+    int actx = individual->x;
+    int acty = individual->y;
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+    int pos = dir_index - 2 * step_length * step_range;
+
+    if (pos < 0) {
+	pos += 8 * step_length;
+    }
+
+    for (i = 0; i < pickpos_count; i++, pos++) {
+	result[i].x = actx + displacements[pos].x;
+	result[i].y = acty + displacements[pos].y;
+	result[i].dir = (double)pos / (8.0 * (double)step_length);
+	if (result[i].dir >= 1) {
+	    result[i].dir--;
+	}
+
+	/* if out of limits, use weight=1 until better handling */
+	if (actx < 0 || actx >= sx || acty < 0 || acty >= sy) {
+	    result[i].weight = 1;
+	}
+	else {
+	    /* get weight from suitmap */
+	    result[i].weight = suitmap[(int)acty * sx + (int)actx];
+	}
+    }
+
+    /* apply perception multiplicator */
+    dir_index = Round(individual->dir * 8.0 * (double)perception_range);
+    pos = dir_index - 2 * perception_range;
+    ex_step = (double)perception_range / (double)step_length;
+    ex_pos = (double)pos;
+    for (i = 0; i < pickpos_count; i++) {
+	int patch_flag = 0;
+
+	ex_pos += ex_step;
+	while (pos < ex_pos) {
+	    int x = actx + perception[pos].x;
+	    int y = acty + perception[pos].y;
+
+	    if (x >= 0 && x < sx && y >= 0 && y < sy) {
+		int val = map[x + y * sx];
+
+		patch_flag |= (val > TYPE_NOTHING && val != frag);
+	    }
+	    pos++;
+	}
+
+	if (patch_flag) {
+	    result[i].weight *= multiplicator;
+
+	}
+    }
+
+    return;
+}
+
+/*
+   performs a single step for an individual
+ */
+void indi_step(int indi, int frag, int *map, DCELL * costmap, double step)
+{
+    int i;
+    double sum;
+    Individual *individual = indi_array + indi;
+    double rnd;
+    double newx, newy;
+    int act_cell, last_cell;
+
+    /* make a step in the current direction */
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+
+    newx = individual->x + displacements[dir_index].x;
+    newy = individual->y + displacements[dir_index].y;
+
+    /* if new position is out of limits, then set back */
+    if (newx < 0 || newx >= sx || newy < 0 || newy >= sy) {
+	if (setback) {
+	    set_back(map, indi, frag);
+	}
+	else {
+	    /* individual is lost */
+	    lost[frag]++;
+	    individual->lost = 1;
+	    individual->finished = 1;
+	}
+
+	return;
+    }
+
+    /* set new position, which is now approved */
+    individual->x = newx;
+    individual->y = newy;
+
+    act_cell = map[(int)newy * sx + (int)newx];
+    last_cell = individual->last_cat;
+
+    /* decrease energy of the individual */
+    individual->energy -= step_length * costmap[(int)newy * sx + (int)newx];
+
+    /* if energy is depleted, then set finished */
+    if (individual->energy <= 0.0) {
+	individual->finished = 1;
+
+	/* if individual is in a patch mark individual as immigrated */
+	if (act_cell != frag && act_cell > -1) {
+	    /* increase emigrants and immigrants and set detail_matrix */
+	    emigrants[frag]++;
+	    immigrants[act_cell]++;
+	    immi_matrix[frag * fragcount + act_cell]++;
+	    individual->immigrated = 1;
+	}
+    }
+
+    /* if category change takes place */
+    if (act_cell != last_cell) {
+
+	/* if emigrating from a patch */
+	if (last_cell > -1 && last_cell != frag) {
+	    patch_registry[last_cell * n + indi] = 2;	// now migrant
+	    //immigrants[last_cell]--;
+	    migrants[last_cell]++;
+	    mig_matrix[frag * fragcount + last_cell]++;
+	}
+
+	/* if immigrating into a patch */
+	if (act_cell > -1 && act_cell != frag) {
+	    /* if individual is a migrant coming in again */
+	    if (patch_registry[act_cell * n + indi] == 2) {
+		migrants[act_cell]--;
+		mig_matrix[frag * fragcount + act_cell]--;
+	    }
+
+	    /* mark as immigrant */
+	    patch_registry[act_cell * n + indi] = 1;
+	}
+    }
+
+    individual->last_cat = act_cell;
+
+    /* write an array with possible next positions */
+    pick_nextpos(pos_arr, indi, map, costmap, frag);
+
+    /* if no next position is possible, then set back */
+    sum = 0;
+    for (i = 0; i < pickpos_count; i++) {
+	sum += pos_arr[i].weight;
+    }
+    if (sum == 0) {
+	if (setback) {
+	    set_back(map, indi, frag);
+	}
+	else {
+	    /* individual is lost */
+	    lost[frag]++;
+	    individual->lost = 1;
+	    individual->finished = 1;
+	}
+
+	return;
+    }
+
+    /* pick a next position randomly, considering the weights */
+    pos_arr[0].weight = pos_arr[0].weight / sum;
+    for (i = 1; i < pickpos_count; i++) {
+	pos_arr[i].weight = pos_arr[i - 1].weight + pos_arr[i].weight / sum;
+    }
+    rnd = Randomf();
+    for (i = 0; i < pickpos_count; i++) {
+	if (pos_arr[i].weight > rnd)
+	    break;
+    }
+
+    individual->dir = pos_arr[i].dir;
+
+    return;
+}
+
+/*
+   performs a search run for a single fragment
+ */
+DCELL frag_run(int *map, DCELL * costmap, int frag)
+{
+    int i, j;
+    DCELL res = 0;
+    int step_cnt = 0;
+    int finished_cnt = 0;
+    int limit = 0.01 * percent * n;
+
+    //      fprintf(stderr, "\nstarting run:\n");
+    //      fprintf(stderr, "limit = %d\n", limit); 
+
+    init_individuals(map, frag, fragments[frag + 1] - fragments[frag], n);
+
+    memset(patch_registry, 0, fragcount * n * sizeof(int));
+
+    /* perform a step for each individual */
+    finished_cnt = 0;
+    while (finished_cnt < limit) {
+	if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	    test_output(map, frag, step_cnt, n);
+	}
+
+	for (i = 0; i < n; i++) {
+	    if (!indi_array[i].finished) {
+
+		indi_step(i, frag, map, costmap, step_length);
+
+		/* test if new individuum finished */
+		if (indi_array[i].finished) {
+		    indi_steps[i] = step_cnt;
+
+		    finished_cnt++;
+
+		    global_progress++;
+		    G_percent(global_progress, fragcount * limit, 1);
+
+		    if (finished_cnt >= limit)
+			break;
+		}
+	    }
+	}
+
+	step_cnt++;
+    }
+
+    /* count successful migrants */
+    for (i = 0; i < fragcount; i++) {
+	for (j = 0; j < n; j++) {
+	    /* if individual is migrant and immigrated in another patch */
+	    if (patch_registry[i * n + j] == 2 && indi_array[j].immigrated) {
+		migrants_succ[i]++;
+	    }
+	}
+    }
+
+    if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	test_output(map, frag, step_cnt, n);
+    }
+
+    //      fprintf(stderr, "stepcnt = %d\n", step_cnt);
+    return (DCELL) step_cnt;
+}
+
+/*
+   performs a search run for each fragment
+ */
+void perform_search(int *map, DCELL * costmap, DCELL * suitmap)
+{
+    int fragment, i;
+    int steps;
+    f_statmethod func;
+
+    /* allocate paths array */
+    indi_steps = (DCELL *) G_malloc(n * sizeof(DCELL));
+
+    /* allocate individuals array */
+    indi_array = (Individual *) G_malloc(n * sizeof(Individual));
+
+    /* allocate pickpos result array */
+    pickpos_count = 4 * step_length * step_range + 1;
+    pos_arr =
+	(WeightedCoords *) G_malloc(pickpos_count * sizeof(WeightedCoords));
+
+    /* allocate displacement arrays */
+    displacements =
+	(Displacement *) G_malloc(16 * step_length * sizeof(Displacement));
+    perception =
+	(Displacement *) G_malloc(16 * perception_range *
+				  sizeof(Displacement));
+
+    /* calculate displacements */
+    calculate_displacement(displacements, step_length);
+    memcpy(displacements + 8 * step_length, displacements,
+	   8 * step_length * sizeof(Displacement));
+
+    calculate_displacement(perception, perception_range);
+    memcpy(perception + 8 * perception_range, perception,
+	   8 * perception_range * sizeof(Displacement));
+
+    /* allocate patch_registry */
+    patch_registry = (int *)G_malloc(fragcount * n * sizeof(int));
+
+    /* allocate immi_matrix and mig_matrix */
+    immi_matrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+    memset(immi_matrix, 0, fragcount * fragcount * sizeof(int));
+    mig_matrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+    memset(mig_matrix, 0, fragcount * fragcount * sizeof(int));
+
+    /*      fprintf(stderr, "Displacements:");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, " (%d, %d)", displacements[i].x, displacements[i].y);
+       } */
+
+    /* perform a search run for each fragment */
+    for (fragment = 0; fragment < fragcount; fragment++) {
+	frag_run(map, costmap, fragment);
+    }
+
+    G_free(indi_steps);
+    G_free(indi_array);
+    G_free(pos_arr);
+    G_free(displacements);
+    G_free(patch_registry);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy/search.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.energy.iter
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,31 @@
+<h2>DESCRIPTION</h2>
+
+Individual-based dispersal model for connectivity analysis (energy based)
+using iterative patch removal. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+<div class="code"><pre>
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.energy.iter.html">r.energy.iter</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,104 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_double_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_int_array(char *title, int *buffer, int size)
+{
+    int i;
+
+    fprintf(stderr, "%s: ", title);
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%d ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,113 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    DCELL energy;
+    int finished;
+    int immigrated;
+    int last_cat;
+    int lost;
+} Individual;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    double weight;
+} WeightedCoords;
+
+typedef struct
+{
+    int x, y;
+} Displacement;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_double_array(DCELL * buffer, int size);
+void print_int_array(char *title, int *buffer, int size);
+void print_fragments();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* search.c */
+void perform_search(int *map, DCELL * costmap, DCELL * suitmap,
+		    int remove_indi);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* parameters */
+GLOBAL int sx, sy;
+GLOBAL int keyval;
+GLOBAL int n;
+GLOBAL double energy;
+GLOBAL double percent;
+GLOBAL int step_length;
+GLOBAL int out_freq;
+GLOBAL int perception_range;
+GLOBAL double multiplicator;
+GLOBAL int setback;
+
+/* more global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+GLOBAL Individual *indi_array;
+GLOBAL int *immigrants;
+GLOBAL int *migrants;
+GLOBAL int *emigrants;
+GLOBAL int *patch_registry;	// ( patch1(indi1, indi2, ...), patch2(...), ... )
+GLOBAL int *lost;
+GLOBAL int *migrants_succ;
+GLOBAL char *deleted_arr;
+
+GLOBAL char *newname, *newmapset;
+GLOBAL char outname[GNAME_MAX];
+
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,831 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.energy.iter
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Individual-based dispersal model for connectivity analysis 
+ *                              - energy-based - iterative removal of paches for patch relevance analysis
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* costmap */
+    char *costname, *costmapset;
+
+    /* suitability map */
+    char *suitname, *suitmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+
+    /* maps */
+    int *map;
+    DCELL *costmap;
+    DCELL *suitmap;
+
+    /* parameters */
+    int stats[GNAME_MAX];
+    int stat_count;
+    int percentual;
+    int remove_indi;
+    int seed;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    int neighb_count;
+    int i, j;
+    Coords *p;
+    char *str;
+    int method;
+    char outname[GNAME_MAX];
+    int sum;
+    int out_progress, out_max;
+    int frag;
+
+    int *dif_immi;
+    int *dif_mig;
+    int *dif_mig_succ;
+    int *dif_emi;
+    int *dif_lost;
+
+    DCELL *out_immi;
+    DCELL *out_mig;
+    DCELL *out_mig_succ;
+    DCELL *out_emi;
+    DCELL *out_lost;
+
+    DCELL *dummy;
+    DCELL *ref;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *suitability, *output;
+	struct Option *keyval, *step_length, *perception, *multiplicator, *n;
+	struct Option *energy, *percent, *stats, *out_freq, *seed;
+	struct Option *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *setback;
+	struct Flag *percentual, *remove_indi;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Individual-based dispersal model for connectivity analysis (energy based) using iterative patch removal.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = NO;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->guisection = "Optional";
+    parm.costmap->description = _("Name of the costmap");
+
+    parm.suitability = G_define_option();
+    parm.suitability->key = "suitability";
+    parm.suitability->type = TYPE_STRING;
+    parm.suitability->required = NO;
+    parm.suitability->gisprompt = "old,cell,raster";
+    parm.suitability->guisection = "Optional";
+    parm.suitability->description =
+	_("Name of the suitability raster with values from 0-100");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->guisection = "Required";
+    parm.keyval->description = _("Category value of the patches");
+
+    parm.step_length = G_define_option();
+    parm.step_length->key = "step_length";
+    parm.step_length->type = TYPE_INTEGER;
+    parm.step_length->required = YES;
+    parm.step_length->guisection = "Required";
+    parm.step_length->description =
+	_("Length of a single step measured in pixels");
+
+    parm.perception = G_define_option();
+    parm.perception->key = "perception";
+    parm.perception->type = TYPE_INTEGER;
+    parm.perception->required = NO;
+    parm.perception->guisection = "Optional";
+    parm.perception->description = _("Perception range");
+
+    parm.multiplicator = G_define_option();
+    parm.multiplicator->key = "multiplicator";
+    parm.multiplicator->type = TYPE_DOUBLE;
+    parm.multiplicator->required = NO;
+    parm.multiplicator->guisection = "Optional";
+    parm.multiplicator->description = _("Attractivity of patches [1-inf]");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->guisection = "Required";
+    parm.n->description = _("Number of individuals");
+
+    parm.energy = G_define_option();
+    parm.energy->key = "energy";
+    parm.energy->type = TYPE_DOUBLE;
+    parm.energy->required = YES;
+    parm.energy->guisection = "Required";
+    parm.energy->description = _("Initial energy of the individuals");
+
+    parm.percent = G_define_option();
+    parm.percent->key = "percent";
+    parm.percent->type = TYPE_DOUBLE;
+    parm.percent->required = YES;
+    parm.percent->guisection = "Required";
+    parm.percent->description =
+	_("Percentage of finished individuals desired before simulation ends");
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    parm.stats->multiple = YES;
+    str = parm.stats->options = G_malloc(1024);
+    for (method = 0; statmethods[method].name; method++) {
+	if (method)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[method].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the pathlengths of the individuals");
+    parm.stats->guisection = _("Required");
+
+    parm.out_freq = G_define_option();
+    parm.out_freq->key = "out_freq";
+    parm.out_freq->type = TYPE_INTEGER;
+    parm.out_freq->required = NO;
+    parm.out_freq->guisection = "Optional";
+    parm.out_freq->description =
+	_("Output an intermediate state of simulation each [out_freq] steps");
+
+    parm.seed = G_define_option();
+    parm.seed->key = "seed";
+    parm.seed->type = TYPE_INTEGER;
+    parm.seed->required = NO;
+    parm.seed->guisection = "Optional";
+    parm.seed->description = _("Seed for random number generator");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->guisection = "Optional";
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->guisection = "Required";
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.setback = G_define_flag();
+    flag.setback->key = 'b';
+    flag.setback->guisection = "Required";
+    flag.setback->description =
+	_("Set if individuals should be set back after leaving area");
+
+    flag.remove_indi = G_define_flag();
+    flag.remove_indi->key = 'r';
+    flag.remove_indi->guisection = "Required";
+    flag.remove_indi->description =
+	_("Set to remove individuals which start in the deleted patch");
+
+    flag.percentual = G_define_flag();
+    flag.percentual->key = 'p';
+    flag.percentual->guisection = "Required";
+    flag.percentual->description =
+	_("Set to output values as percentual of the value from the reference run");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    if (parm.seed->answer) {
+	sscanf(parm.seed->answer, "%d", &seed);
+    }
+    else {
+	seed = time(NULL);
+    }
+    srand(seed);
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input file existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of costmap */
+    costname = parm.costmap->answer;
+
+    /* test costmap existance */
+    if (costname && (costmapset = G_find_cell2(costname, "")) == NULL)
+	G_fatal_error(_("Raster map <%s> not found"), costname);
+
+    /* get name of suitability map */
+    suitname = parm.suitability->answer;
+
+    /* test costmap existance */
+    if (suitname && (suitmapset = G_find_cell2(suitname, "")) == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), suitname);
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get step_length */
+    sscanf(parm.step_length->answer, "%d", &step_length);
+
+    /* get perception_range */
+    if (parm.perception->answer) {
+	sscanf(parm.perception->answer, "%d", &perception_range);
+    }
+    else {
+	perception_range = step_length;
+    }
+
+    /* get multiplicator */
+    if (parm.multiplicator->answer) {
+	sscanf(parm.multiplicator->answer, "%lf", &multiplicator);
+    }
+    else {
+	multiplicator = 1.0;
+    }
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get energy */
+    sscanf(parm.energy->answer, "%lf", &energy);
+
+    /* get percent */
+    sscanf(parm.percent->answer, "%lf", &percent);
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get setback flag */
+    setback = flag.adjacent->answer;
+
+    /* get out_freq */
+    if (parm.out_freq->answer != NULL) {
+	sscanf(parm.out_freq->answer, "%d", &out_freq);
+    }
+    else {
+	out_freq = 0;
+    }
+
+    /* scan all statmethod answers */
+    stat_count = 0;
+    while (parm.stats->answers[stat_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (str = statmethods[method].name); method++)
+	    if (strcmp(str, parm.stats->answers[stat_count]) == 0)
+		break;
+	if (!str) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.stats->key, parm.stats->answers[stat_count],
+		      parm.stats->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	stats[stat_count] = method;
+
+	stat_count++;
+    }
+
+    remove_indi = flag.remove_indi->answer;
+    percentual = flag.percentual->answer;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* test output */
+    /*fprintf(stderr, "TEST OUTPUT : \n");
+       fprintf(stderr, "input = %s\n", oldname);
+       fprintf(stderr, "output = %s\n", newname);
+       fprintf(stderr, "costmap = %s\n", costname);
+       fprintf(stderr, "keyval = %d\n", keyval);
+       fprintf(stderr, "step_length = %d\n", step_length);
+       fprintf(stderr, "n = %d\n", n);
+       fprintf(stderr, "energy = %0.2f\n", energy);
+       fprintf(stderr, "Stats: "); 
+       for(i = 0; i < stat_count; i++) {
+       fprintf(stderr, statmethods[stats[i]].name);
+       }
+       fprintf(stderr, "\n"); */
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    costmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    suitmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    d_res = G_allocate_d_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row + 1, sy, 1);
+    }
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if costmap specified, read costmap */
+    if (costname != NULL) {
+	/* open costmap */
+	in_fd = G_open_cell_old(costname, costmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), costname);
+
+	/* read costmap */
+	G_message("Reading costmap:");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		costmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close costmap */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill costmap with 1 */
+	for (i = 0; i < sx * sy; i++) {
+	    costmap[i] = 1;
+	}
+    }
+
+    /* if suitability map specified, read it */
+    if (suitname != NULL) {
+	/* open suitability map */
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), suitname);
+
+	/* read suitability map */
+	G_message("Reading suitability map file:");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		suitmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close suitability map */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no suitability map specified, fill it with 100 */
+	for (i = 0; i < sx * sy; i++) {
+	    suitmap[i] = 100;
+	}
+    }
+
+    /* test output */
+    /*      G_message("costmap:\n");
+       print_d_buffer(costmap, sx, sy); */
+
+    /* find fragments */
+    writeFragments(map, sy, sx, neighb_count);
+
+    /* test output */
+    /*      print_fragments(); */
+
+    /* mark each fragment with its number */
+    for (i = 0; i < sx * sy; i++) {
+	map[i] = -1;
+    }
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    map[p->y * sx + p->x] = i;
+	}
+    }
+
+    /* test output */
+    /*      print_buffer(map, sx, sy); */
+    G_message("Performing search runs:");
+
+    /* allocate arrays */
+    immigrants = (int *)G_malloc(fragcount * sizeof(int));
+    migrants = (int *)G_malloc(fragcount * sizeof(int));
+    migrants_succ = (int *)G_malloc(fragcount * sizeof(int));
+    emigrants = (int *)G_malloc(fragcount * sizeof(int));
+    lost = (int *)G_malloc(fragcount * sizeof(int));
+    deleted_arr = (char *)G_malloc(fragcount * sizeof(char));
+
+    memset(deleted_arr, 0, fragcount * sizeof(char));
+
+    /* allocate difference arrays */
+    dif_immi = (int *)G_malloc((fragcount + 1) * fragcount * sizeof(int));
+    dif_mig = (int *)G_malloc((fragcount + 1) * fragcount * sizeof(int));
+    dif_mig_succ = (int *)G_malloc((fragcount + 1) * fragcount * sizeof(int));
+    dif_emi = (int *)G_malloc((fragcount + 1) * fragcount * sizeof(int));
+    dif_lost = (int *)G_malloc((fragcount + 1) * fragcount * sizeof(int));
+
+    /* perform first reference search run */
+    perform_search(map, costmap, suitmap, remove_indi);
+
+    /* test output */
+    /* G_message("Reference run:");
+       print_int_array("immigrants", immigrants, fragcount);
+       print_int_array("migrants", migrants, fragcount);
+       print_int_array("migrants successful", migrants_succ, fragcount);
+       print_int_array("emigrants", emigrants, fragcount);
+       print_int_array("lost", lost, fragcount);
+       G_message(""); */
+
+    /* copy values */
+    memcpy(dif_immi, immigrants, fragcount * sizeof(int));
+    memcpy(dif_mig, migrants, fragcount * sizeof(int));
+    memcpy(dif_mig_succ, migrants_succ, fragcount * sizeof(int));
+    memcpy(dif_emi, emigrants, fragcount * sizeof(int));
+    memcpy(dif_lost, lost, fragcount * sizeof(int));
+
+    /* perform test runs */
+    for (frag = 0; frag < fragcount; frag++) {
+	deleted_arr[frag] = 1;
+	perform_search(map, costmap, suitmap, remove_indi);
+	deleted_arr[frag] = 0;
+
+	/* G_message("Frag %d deleted:", frag);
+	   print_int_array("immigrants", immigrants, fragcount);
+	   print_int_array("migrants", migrants, fragcount);
+	   print_int_array("migrants successful", migrants_succ, fragcount);
+	   print_int_array("emigrants", emigrants, fragcount);
+	   print_int_array("lost", lost, fragcount);
+	   G_message(""); */
+
+	/* calculate differences */
+	for (i = 0; i < fragcount; i++) {
+	    dif_immi[(frag + 1) * fragcount + i] =
+		immigrants[i] - dif_immi[i];
+	    dif_mig[(frag + 1) * fragcount + i] = migrants[i];
+	    dif_mig_succ[(frag + 1) * fragcount + i] = migrants_succ[i];
+	    dif_emi[(frag + 1) * fragcount + i] = emigrants[i] - dif_emi[i];
+	    dif_lost[(frag + 1) * fragcount + i] = lost[i] - dif_lost[i];
+	}
+    }
+
+    /* allolcate output arrays */
+    out_immi = (DCELL *) G_malloc(stat_count * fragcount * sizeof(DCELL));
+    out_mig = (DCELL *) G_malloc(stat_count * fragcount * sizeof(DCELL));
+    out_mig_succ = (DCELL *) G_malloc(stat_count * fragcount * sizeof(DCELL));
+    out_emi = (DCELL *) G_malloc(stat_count * fragcount * sizeof(DCELL));
+    out_lost = (DCELL *) G_malloc(stat_count * fragcount * sizeof(DCELL));
+    dummy = (DCELL *) G_malloc(5 * (fragcount - 1) * sizeof(DCELL));
+    ref = (DCELL *) G_malloc(5 * (fragcount - 1) * sizeof(DCELL));
+
+    /* calculate output results */
+    for (frag = 0; frag < fragcount; frag++) {
+	int offset = (frag + 1) * fragcount;
+	int index = 0;
+
+	for (i = 0; i < fragcount; i++) {
+	    if (i != frag) {
+		dummy[index] = dif_immi[offset + i];
+		dummy[fragcount - 1 + index] =
+		    dif_mig[offset + i] - dif_mig[i];
+		dummy[2 * (fragcount - 1) + index] =
+		    dif_mig[offset + i] >
+		    0 ? 100.0 * ((DCELL) dif_mig_succ[offset + i] /
+				 (DCELL) dif_mig[offset + i] -
+				 (DCELL) dif_mig_succ[i] /
+				 (DCELL) dif_mig[i]) : 0;
+		dummy[3 * (fragcount - 1) + index] =
+		    n >
+		    0 ? 100.0 * (DCELL) dif_emi[offset + i] / (DCELL) n : 0;
+		dummy[4 * (fragcount - 1) + index] =
+		    n >
+		    0 ? 100.0 * (DCELL) dif_lost[offset + i] / (DCELL) n : 0;
+
+		ref[index] = dif_immi[i];
+		ref[fragcount - 1 + index] = dif_mig[i];
+		ref[2 * (fragcount - 1) + index] =
+		    dif_mig[i] >
+		    0 ? 100.0 * (DCELL) dif_mig_succ[i] /
+		    (DCELL) dif_mig[i] : 0;
+		ref[3 * (fragcount - 1) + index] =
+		    n > 0 ? 100.0 * (DCELL) dif_emi[i] / (DCELL) n : 0;
+		ref[4 * (fragcount - 1) + index] =
+		    n > 0 ? 100.0 * (DCELL) dif_lost[i] / (DCELL) n : 0;
+		index++;
+	    }
+	}
+	for (method = 0; method < stat_count; method++) {
+	    f_statmethod func = statmethods[stats[method]].method;
+	    int index = method * fragcount + frag;
+
+	    out_immi[index] = func(dummy, fragcount - 1);
+	    out_mig[index] = func(dummy + fragcount - 1, fragcount - 1);
+	    out_mig_succ[index] =
+		func(dummy + 2 * (fragcount - 1), fragcount - 1);
+	    out_emi[index] = func(dummy + 3 * (fragcount - 1), fragcount - 1);
+	    out_lost[index] =
+		func(dummy + 4 * (fragcount - 1), fragcount - 1);
+
+	    if (percentual) {
+		DCELL ref_immi = func(ref, fragcount - 1);
+		DCELL ref_mig = func(ref + fragcount - 1, fragcount - 1);
+		DCELL ref_mig_succ =
+		    func(ref + 2 * (fragcount - 1), fragcount - 1);
+		DCELL ref_emi =
+		    func(ref + 3 * (fragcount - 1), fragcount - 1);
+		DCELL ref_lost =
+		    func(ref + 4 * (fragcount - 1), fragcount - 1);
+
+		out_immi[index] = out_immi[index] * 100.0 / ref_immi;
+		out_mig[index] = out_mig[index] * 100.0 / ref_mig;
+		out_mig_succ[index] =
+		    out_mig_succ[index] * 100.0 / ref_mig_succ;
+		out_emi[index] = out_emi[index] * 100.0 / ref_emi;
+		out_lost[index] = out_lost[index] * 100.0 / ref_lost;
+	    }
+	}
+    }
+
+    /* test output */
+    /*G_message("Results:");
+       for(j = 0; j < stat_count; j++) {
+       G_message("%s: ", statmethods[stats[j]].name);
+       for(i = 0; i < fragcount; i++) {
+       fprintf(stderr, "frag%d: %0.2f ", i, values[j * fragcount + i]);
+       }
+       fprintf(stderr, "\n");
+       }
+       G_message(""); */
+
+    G_message("Writing output...");
+
+    /* set up progress display vaiables */
+    out_progress = 0;
+    out_max = stat_count * sy * (setback ? 4 : 5);
+
+    /* write immigrants */
+
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cellfile  */
+	sprintf(outname, "%s_imi_%s", newname,
+		statmethods[stats[method]].suffix);
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (frag = 0; frag < fragcount; frag++) {
+		for (p = fragments[frag]; p < fragments[frag + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = out_immi[method * fragcount + frag];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(++out_progress, out_max, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write migrants */
+
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cellfile  */
+	sprintf(outname, "%s_mig_%s", newname,
+		statmethods[stats[method]].suffix);
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (frag = 0; frag < fragcount; frag++) {
+		for (p = fragments[frag]; p < fragments[frag + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = out_mig[method * fragcount + frag];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(++out_progress, out_max, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write successful migrants */
+
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cellfile  */
+	sprintf(outname, "%s_mig_succ_%s", newname,
+		statmethods[stats[method]].suffix);
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (frag = 0; frag < fragcount; frag++) {
+		for (p = fragments[frag]; p < fragments[frag + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = out_mig_succ[method * fragcount + frag];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(++out_progress, out_max, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write emigrants */
+
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cellfile  */
+	sprintf(outname, "%s_emi_%s", newname,
+		statmethods[stats[method]].suffix);
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (frag = 0; frag < fragcount; frag++) {
+		for (p = fragments[frag]; p < fragments[frag + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = out_emi[method * fragcount + frag];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(++out_progress, out_max, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    if (!setback) {
+	/* write lost */
+
+	for (method = 0; method < stat_count; method++) {
+	    /* open the new cellfile  */
+	    sprintf(outname, "%s_lost_%s", newname,
+		    statmethods[stats[method]].suffix);
+	    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	    if (out_fd < 0)
+		    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	    /* write the output file */
+	    for (row = 0; row < sy; row++) {
+		G_set_d_null_value(d_res, sx);
+
+		for (frag = 0; frag < fragcount; frag++) {
+		    for (p = fragments[frag]; p < fragments[frag + 1]; p++) {
+			if (p->y == row) {
+			    d_res[p->x] = out_lost[method * fragcount + frag];
+			}
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, d_res);
+
+		G_percent(++out_progress, out_max, 1);
+	    }
+
+	    /* close output */
+	    G_close_cell(out_fd);
+	}
+    }
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(costmap);
+    G_free(cells);
+    G_free(fragments);
+    G_free(immigrants);
+    G_free(migrants);
+    G_free(migrants_succ);
+    G_free(emigrants);
+    G_free(lost);
+    G_free(dif_immi);
+    G_free(dif_mig);
+    G_free(dif_mig_succ);
+    G_free(dif_emi);
+    G_free(dif_lost);
+    G_free(out_immi);
+    G_free(out_mig);
+    G_free(out_mig_succ);
+    G_free(out_emi);
+    G_free(out_lost);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/search.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/search.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/search.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,600 @@
+#include "local_proto.h"
+
+/* globals */
+
+int global_progress = 0;
+int pickpos_count;
+int perception_count;
+WeightedCoords *pos_arr;
+Displacement *displacements;
+Displacement *perception;
+DCELL *indi_steps;
+
+/*
+   output raster with current simulation state
+ */
+void test_output(int *map, int patch, int step, int n)
+{
+    int out_fd;
+    int row, col, i;
+    char outname[GNAME_MAX];
+    DCELL *outmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_patch%d_step%d", newname, patch, step);
+
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write map */
+
+    for (i = 0; i < sx * sy; i++) {
+	outmap[i] = 0;
+    }
+
+    for (i = 0; i < n; i++) {
+	int x, y;
+	Individual *indi = indi_array + i;
+
+	x = indi->x;
+	y = indi->y;
+
+	//              fprintf(stderr, "indi%d: (%d, %d)\n", i, x, y);
+	if (!indi->lost) {
+	    outmap[x + y * sx]++;
+	}
+    }
+
+    for (i = 0; i < sx * sy; i++) {
+	if (map[i] != TYPE_NOTHING && outmap[i] == 0) {
+	    outmap[i] = -1;
+	}
+    }
+
+    /*      for(row = 0; row < sy; row++) {
+       for(col = 0; col < sx; col++) {
+       fprintf(stderr, "%0.0f", outmap[row * sx + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* write output */
+    for (row = 0; row < sy; row++) {
+	G_put_d_raster_row(out_fd, outmap + row * sx);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+    G_free(outmap);
+}
+
+/*
+   sorts cells in a fragment, so that border cells come first
+ */
+int sort_frag(Coords * frag, int size)
+{
+    int i, j;
+    Coords temp;
+
+    i = 0;
+    j = size - 1;
+
+    while (i <= j) {
+	while (frag[i].neighbors < 4 && i < size)
+	    i++;
+	while (frag[j].neighbors == 4 && j >= 0)
+	    j--;
+
+	if (i < j) {
+	    temp = frag[i];
+	    frag[i] = frag[j];
+	    frag[j] = temp;
+	}
+    }
+
+    /*      fprintf(stderr, "Sorted fragment: (%d, %d: %d)", frag->x, frag->y, frag->neighbors);
+       for(j = 1; j < size; j++) {
+       fprintf(stderr, " (%d, %d: %d)", frag[j].x, frag[j].y, frag[j].neighbors);
+       }
+       fprintf(stderr, "\n"); */
+
+    return i;
+}
+
+/*
+   picks a random direction pointing outwards a patch
+ */
+double pick_dir(int *map, Coords * frag)
+{
+    double dirs[4];
+    int i;
+    double pick;
+
+    int x = frag->x;
+    int y = frag->y;
+    int count = 0;
+
+    if (x < sx - 1 && map[x + 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.0;
+    if (y > 0 && map[x + (y + 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.25;
+    if (x > 0 && map[x - 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.5;
+    if (y < sy - 1 && map[x + (y - 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.75;
+
+    pick = count * Randomf();
+
+    for (i = count - 1; i >= 0; i--) {
+	if (pick > i) {
+	    double res = 0.25 * (pick - i) + dirs[i] - 0.125;
+
+	    if (res < 0) {
+		res++;
+	    }
+	    //                      res = res < 0 ? 2 * M_PI + res : res;
+	    return res;
+	}
+    }
+
+    return -1;			// error
+}
+
+/*
+   initializes all individuals for a fragment
+ */
+void init_individuals(int *map, int frag, int size, int n)
+{
+    int i, border_count, index;
+    Coords *cell;
+    Coords *fragment = fragments[frag];
+
+    border_count = sort_frag(fragment, size);
+
+    //      G_message("Initializing");
+
+    for (i = 0; i < n; i++) {
+	//              G_message("border_count = %d", border_count);
+
+	/* pick border cell */
+	index = Random(border_count);
+	cell = fragment + index;
+
+	indi_array[i].x = cell->x + 0.5;
+	indi_array[i].y = cell->y + 0.5;
+	indi_array[i].dir = pick_dir(map, cell);	//2 * M_PI * Randomf();
+	indi_array[i].energy = energy;
+	indi_array[i].finished = 0;
+	indi_array[i].immigrated = 0;
+	indi_array[i].last_cat = frag;
+	indi_array[i].lost = 0;
+
+	//              fprintf(stderr, "indi%d: ", i);
+	//              fprintf(stderr, "x=%0.2f, y=%0.2f, dir=%0.2f, finished=%d\n",
+	//                              indi_array[i].x, indi_array[i].y, indi_array[i].dir, indi_array[i].finished);
+    }
+    //      G_message("End initialization");
+}
+
+/*
+   sets back an individual, when position is illegal
+ */
+void set_back(int *map, int indi, int frag)
+{
+    int index;
+    Coords *cell;
+    int border_count =
+	sort_frag(fragments[frag], fragments[frag + 1] - fragments[frag]);
+
+    /* pick border cell */
+    index = Random(border_count);
+    cell = fragments[frag] + index;
+
+    indi_array[indi].x = cell->x;
+    indi_array[indi].y = cell->y;
+    indi_array[indi].dir = pick_dir(map, cell);
+    indi_array[indi].finished = 0;
+    indi_array[indi].last_cat = frag;
+}
+
+/*
+   sets displacement pixels taking advantage of symmetry
+ */
+void set_pixels(Displacement * values, int x, int y, int r)
+{
+    if (y == 0) {
+	values[0].x = x;
+	values[0].y = 0;
+	values[2 * r].x = 0;
+	values[2 * r].y = x;
+	values[4 * r].x = -x;
+	values[4 * r].y = 0;
+	values[6 * r].x = 0;
+	values[6 * r].y = -x;
+    }
+    else if (y == x) {
+	values[r].x = y;
+	values[r].y = y;
+	values[3 * r].x = -y;
+	values[3 * r].y = y;
+	values[5 * r].x = -y;
+	values[5 * r].y = -y;
+	values[7 * r].x = y;
+	values[7 * r].y = -y;
+    }
+    else if (y < x) {
+	values[r - x + y].x = x;
+	values[r - x + y].y = y;
+	values[r + x - y].x = y;
+	values[r + x - y].y = x;
+	values[3 * r - x + y].x = -y;
+	values[3 * r - x + y].y = x;
+	values[3 * r + x - y].x = -x;
+	values[3 * r + x - y].y = y;
+	values[5 * r - x + y].x = -x;
+	values[5 * r - x + y].y = -y;
+	values[5 * r + x - y].x = -y;
+	values[5 * r + x - y].y = -x;
+	values[7 * r - x + y].x = y;
+	values[7 * r - x + y].y = -x;
+	values[7 * r + x - y].x = x;
+	values[7 * r + x - y].y = -y;
+    }
+}
+
+/*
+   calculates displacements for a circle of given radius
+ */
+void calculate_displacement(Displacement * values, int radius)
+{
+    int dx = radius;
+    int dy = 0;
+    float dx_ = (float)dx - 0.5f;
+    float dy_ = (float)dy + 0.5f;
+    float f = 0.5f - (float)radius;
+
+    set_pixels(values, dx, dy, radius);
+
+    while (dx > dy) {
+	if (f < 0) {
+	    f += 2 * dy_ + 1;
+	    dy_++;
+	    dy++;
+	}
+	else {
+	    f += 1 - 2 * dx_;
+	    dx_--;
+	    dx--;
+	}
+
+	set_pixels(values, dx, dy, radius);
+    }
+}
+
+/*
+   fills a weighted array with possible next positions
+ */
+void pick_nextpos(WeightedCoords * result, int indi, int *map,
+		  DCELL * suitmap, int frag)
+{
+    int i;
+    double ex_step, ex_pos;
+    Individual *individual = indi_array + indi;
+    int actx = individual->x;
+    int acty = individual->y;
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+    int pos = dir_index - 2 * step_length;
+
+    if (pos < 0) {
+	pos += 8 * step_length;
+    }
+
+    for (i = 0; i < pickpos_count; i++, pos++) {
+	result[i].x = actx + displacements[pos].x;
+	result[i].y = acty + displacements[pos].y;
+	result[i].dir = (double)pos / (8.0 * (double)step_length);
+	if (result[i].dir >= 1) {
+	    result[i].dir--;
+	}
+
+	/* if out of limits, use weight=1 until better handling */
+	if (actx < 0 || actx >= sx || acty < 0 || acty >= sy) {
+	    result[i].weight = 1;
+	}
+	else {
+	    /* get weight from suitmap */
+	    result[i].weight = suitmap[(int)acty * sx + (int)actx];
+	}
+    }
+
+    /* apply perception multiplicator */
+    dir_index = Round(individual->dir * 8.0 * (double)perception_range);
+    pos = dir_index - 2 * perception_range;
+    ex_step = (double)perception_range / (double)step_length;
+    ex_pos = (double)pos;
+    for (i = 0; i < pickpos_count; i++) {
+	int patch_flag = 0;
+
+	ex_pos += ex_step;
+	while (pos < ex_pos) {
+	    int x = actx + perception[pos].x;
+	    int y = acty + perception[pos].y;
+
+	    if (x >= 0 && x < sx && y >= 0 && y < sy) {
+		int val = map[x + y * sx];
+
+		patch_flag |= (val > TYPE_NOTHING && val != frag &&
+			       !deleted_arr[val]);
+	    }
+	    pos++;
+	}
+
+	if (patch_flag) {
+	    result[i].weight *= multiplicator;
+
+	}
+    }
+
+    return;
+}
+
+/*
+   performs a single step for an individual
+ */
+void indi_step(int indi, int frag, int *map, DCELL * costmap, double step)
+{
+    int i;
+    double sum;
+    Individual *individual = indi_array + indi;
+    double rnd;
+    double newx, newy;
+    int act_cell, last_cell;
+
+    /* make a step in the current direction */
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+
+    newx = individual->x + displacements[dir_index].x;
+    newy = individual->y + displacements[dir_index].y;
+
+    /* if new position is out of limits, then set back */
+    if (newx < 0 || newx >= sx || newy < 0 || newy >= sy) {
+	if (setback) {
+	    set_back(map, indi, frag);
+	}
+	else {
+	    /* individual is lost */
+	    lost[frag]++;
+	    individual->lost = 1;
+	    individual->finished = 1;
+	}
+
+	return;
+    }
+
+    /* set new position, which is now approved */
+    individual->x = newx;
+    individual->y = newy;
+
+    act_cell = map[(int)newy * sx + (int)newx];
+    last_cell = individual->last_cat;
+
+    /* don't consider own patch and deleted patches as patches */
+    if (act_cell == frag || (act_cell > -1 && deleted_arr[act_cell])) {
+	act_cell = -1;
+    }
+
+    /* decrease energy of the individual */
+    individual->energy -= step_length * costmap[(int)newy * sx + (int)newx];
+
+    /* if energy is depleted, then set finished */
+    if (individual->energy <= 0.0) {
+	individual->finished = 1;
+
+	/* if individual is in a patch mark individual as immigrated */
+	if (act_cell != frag && act_cell > -1 && !deleted_arr[act_cell]) {
+	    /* increase emigrants and immigrants */
+	    emigrants[frag]++;
+	    immigrants[act_cell]++;
+	    individual->immigrated = 1;
+	}
+    }
+
+    /* if category change takes place */
+    if (act_cell != last_cell && act_cell != frag && last_cell != frag) {
+
+	/* if emigrating from a patch */
+	if (last_cell > -1) {
+	    patch_registry[last_cell * n + indi] = 2;	// now migrant
+	    //immigrants[last_cell]--;
+	    migrants[last_cell]++;
+	}
+
+	/* if immigrating into a patch */
+	if (act_cell > -1) {
+	    /* if individual is a migrant coming in again */
+	    if (patch_registry[act_cell * n + indi] == 2) {
+		migrants[act_cell]--;
+	    }
+
+	    /* mark as immigrant */
+	    patch_registry[act_cell * n + indi] = 1;
+	}
+    }
+
+    /* remember last category */
+    individual->last_cat = act_cell;
+
+    /* write an array with possible next positions */
+    pick_nextpos(pos_arr, indi, map, costmap, frag);
+
+    /* if no next position is possible, then set back */
+    sum = 0;
+    for (i = 0; i < pickpos_count; i++) {
+	sum += pos_arr[i].weight;
+    }
+    if (sum == 0) {
+	if (setback) {
+	    set_back(map, indi, frag);
+	}
+	else {
+	    /* individual is lost */
+	    lost[frag]++;
+	    individual->lost = 1;
+	    individual->finished = 1;
+	}
+
+	return;
+    }
+
+    /* pick a next position randomly, considering the weights */
+    pos_arr[0].weight = pos_arr[0].weight / sum;
+    for (i = 1; i < pickpos_count; i++) {
+	pos_arr[i].weight = pos_arr[i - 1].weight + pos_arr[i].weight / sum;
+    }
+    rnd = Randomf();
+    for (i = 0; i < pickpos_count; i++) {
+	if (pos_arr[i].weight > rnd)
+	    break;
+    }
+
+    individual->dir = pos_arr[i].dir;
+
+    return;
+}
+
+/*
+   performs a search run for a single fragment
+ */
+DCELL frag_run(int *map, DCELL * costmap, int frag)
+{
+    int i, j;
+    DCELL res = 0;
+    int step_cnt = 0;
+    int finished_cnt = 0;
+    int limit = 0.01 * percent * n;
+
+    //      fprintf(stderr, "\nstarting run:\n");
+    //      fprintf(stderr, "limit = %d\n", limit); 
+
+    init_individuals(map, frag, fragments[frag + 1] - fragments[frag], n);
+
+    memset(patch_registry, 0, fragcount * n * sizeof(int));
+
+    /* perform a step for each individual */
+    finished_cnt = 0;
+    while (finished_cnt < limit) {
+	if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	    test_output(map, frag, step_cnt, n);
+	}
+
+	for (i = 0; i < n; i++) {
+	    if (!indi_array[i].finished) {
+
+		indi_step(i, frag, map, costmap, step_length);
+
+		/* test if new individuum finished */
+		if (indi_array[i].finished) {
+		    indi_steps[i] = step_cnt;
+
+		    finished_cnt++;
+
+		    global_progress++;
+		    G_percent(global_progress,
+			      (fragcount + 1) * fragcount * limit, 1);
+
+		    if (finished_cnt >= limit)
+			break;
+		}
+	    }
+	}
+
+	step_cnt++;
+    }
+
+    /* count successful migrants */
+    for (i = 0; i < fragcount; i++) {
+	for (j = 0; j < n; j++) {
+	    /* if individual is migrant and immigrated in another patch */
+	    if (patch_registry[i * n + j] == 2 && indi_array[j].immigrated) {
+		migrants_succ[i]++;
+	    }
+	}
+    }
+
+    if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	test_output(map, frag, step_cnt, n);
+    }
+
+    //      fprintf(stderr, "stepcnt = %d\n", step_cnt);
+    return (DCELL) step_cnt;
+}
+
+/*
+   performs a search run for each fragment
+ */
+void perform_search(int *map, DCELL * costmap, DCELL * suitmap,
+		    int remove_indi)
+{
+    int fragment, i;
+    int steps;
+    f_statmethod func;
+
+    /* allocate paths array */
+    indi_steps = (DCELL *) G_malloc(n * sizeof(DCELL));
+
+    /* allocate individuals array */
+    indi_array = (Individual *) G_malloc(n * sizeof(Individual));
+
+    /* allocate pickpos result array */
+    pickpos_count = 4 * step_length + 1;
+    pos_arr =
+	(WeightedCoords *) G_malloc(pickpos_count * sizeof(WeightedCoords));
+
+    /* allocate displacement arrays */
+    displacements =
+	(Displacement *) G_malloc(16 * step_length * sizeof(Displacement));
+    perception =
+	(Displacement *) G_malloc(16 * perception_range *
+				  sizeof(Displacement));
+
+    /* calculate displacements */
+    calculate_displacement(displacements, step_length);
+    memcpy(displacements + 8 * step_length, displacements,
+	   8 * step_length * sizeof(Displacement));
+
+    calculate_displacement(perception, perception_range);
+    memcpy(perception + 8 * perception_range, perception,
+	   8 * perception_range * sizeof(Displacement));
+
+    /* allocate patch_registry */
+    patch_registry = (int *)G_malloc(fragcount * n * sizeof(int));
+
+    /* clear migrant arrays */
+    memset(immigrants, 0, fragcount * sizeof(int));
+    memset(migrants, 0, fragcount * sizeof(int));
+    memset(migrants_succ, 0, fragcount * sizeof(int));
+    memset(emigrants, 0, fragcount * sizeof(int));
+    memset(lost, 0, fragcount * sizeof(int));
+
+    /*      fprintf(stderr, "Displacements:");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, " (%d, %d)", displacements[i].x, displacements[i].y);
+       } */
+
+    /* perform a search run for each fragment */
+    for (fragment = 0; fragment < fragcount; fragment++) {
+	if (!(remove_indi && deleted_arr[fragment])) {
+	    frag_run(map, costmap, fragment);
+	}
+    }
+
+    G_free(indi_steps);
+    G_free(indi_array);
+    G_free(pos_arr);
+    G_free(displacements);
+    G_free(patch_registry);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/search.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.energy.iter/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.energy.iter/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.energy.iter/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.energy.iter/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.enn
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.enn/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,133 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.pi.enn</em> computes the euclidean distance between patches (1-n NN).
+
+Analysis of n-th euclidean nearest neighbour distance. 
+
+<h2>NOTES</h2>
+
+The user must specify the names of the raster map layers to
+be used for <em>input</em> and <em>output</em>, the <em>keyval</em> the
+<em>method</em> (e.g. distance, area) and <em>statmethod</em> used (i.e.,
+average).
+<p>
+
+Within <em>r.pi.enn</em> the following setting have to be set:
+
+<h3>keyval setting:</h3>
+
+The <em>keyval</em> operator determines which category value is taken for the Patch Index analysis.
+
+<h3>Method setting:</h3>
+
+The <em>method</em> operators determine what measure is applied 
+on the nth NN.
+
+<p>
+<dt><b>Distance</b> 
+
+<dd>The <em>Average</em> computes the average distance of the n NN.
+
+
+<dt><b>Path distance</b> 
+
+<dd>The <em>path_distance</em> computes the actual distance to the n NN.
+
+
+<dt><b>Area</b> 
+
+<dd>The <em>area</em> computes the area of the n NN.
+
+<dt><b>Perimeter</b> 
+
+<dd>The <em>perimeter</em> computes the perimeter of the n NN.
+
+<dt><b>SHAPE Index</b> 
+
+<dd>The <em>shapeindex</em> computes the SHAPE Index of the n NN.
+
+
+<h3>Statmethod setting:</h3>
+
+The <em>statmethod</em> operators determine what statistic measure is applied 
+on the nth NN.
+
+<p>
+<dt><b>Average</b> 
+
+<dd>The <em>Average</em> computes the average distance of the n NN.
+
+
+<dt><b>Variance</b> 
+
+<dd>The <em>Variance</em> computes the variance of the distance of the n NN.
+
+
+<dt><b>Std. Dev.</b> 
+
+<dd>The <em>Std. Dev</em> computes the std. dev. of the distance of the n NN.
+
+
+
+<h3>Number:</h3>
+
+The <em>keyval</em> operator determines which or how many Nearest Neighbour are analysed.
+
+<em> 1,2,5 </em> will analyse the 1, 2 and 5th Nearest Neigbour.
+
+<em> 1-10 </em> will analyse the 1, 2, 3, ... 10th Nearest Neighbour.
+
+<em> 0 </em> will analyse all Nearest Neighbours.
+
+
+<h3>Distancematrix:</h3>
+
+The <em>dmout</em> operator is optional and determines if a distance matrix is written (first NN only).
+
+<em> 1,2,5 </em> will analyse the 1, 2 and 5th Nearest Neigbour.
+
+<em> 1-10 </em> will analyse the 1, 2, 3, ... 10th Nearest Neighbour.
+
+<em> 0 </em> will analyse all Nearest Neighbours.
+
+
+</dl>
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+r.pi.enn input=landclass96 output=dist1.c5 keyval=5 method=distance number=1 statmethod=average 
+# -> gives a map of patches (all of category of 5) with the average distance to their first NN
+
+r.pi.enn input=landclass96 output=dist10.c5 keyval=5 method=distance number=10 statmethod=average 
+# -> gives a map of patches (all of category of 5) with the average distance to their first-10th NN
+
+r.pi.enn input=landclass96 output=dist1.5.10,c5 keyval=5 method=distance number=1,5,10 statmethod=average 
+# -> gives a map of patches (all of category of 5) with the average distance to their first, first-to-fifth and first-to-10th NN
+
+r.pi.enn input=landclass96 output=dist10b.c5 keyval=5 method=path_distance number=10 statmethod=average 
+# -> gives a map of patches (all of category of 5) with the actual distance to the 10th NN
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.fragment.dist.html">r.fragment.dist</a>,
+<a href="r.pi.enn.html">r.pi.enn</a>,
+<a href="r.pi.enn.iter.html">r.pi.enn.iter</a>,
+<a href="r.fragment.neighbors.html">r.fragment.neighbors</a>,
+<a href="r.li.setup.html">r.li</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.enn/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,143 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int getNeighbors(Position * res, int x, int y, int nx, int ny, int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+void writeFrag(int row, int col, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt = getNeighbors(nbr_list, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,379 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL res = 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL value(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return vals[count - 1];
+}
+
+DCELL sum(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL res = 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res;
+}
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+int get_dist_matrix(int count)
+{
+    int i, j;
+
+    distmatrix = (DCELL *) G_malloc(count * count * sizeof(DCELL));
+
+    /* fill distance matrix */
+    for (i = 0; i < count; i++) {
+	for (j = i + 1; j < count; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * count + j] = d;
+	    distmatrix[j * count + i] = d;
+	}
+    }
+
+    return 0;
+}
+
+void get_smallest_n_indices(int *row, DCELL * matrix, int n, int count,
+			    int focal)
+{
+    int i, j;
+    int min;
+    int tmpI;
+    DCELL tmp;
+
+    /* get row from distance matrix */
+    DCELL *distrow = (DCELL *) G_malloc(count * sizeof(DCELL));
+    int *indexrow = (int *)G_malloc(count * sizeof(int));
+
+    for (i = 0; i < count; i++) {
+	distrow[i] = matrix[focal * count + i];
+	indexrow[i] = i;
+    }
+    distrow[focal] = MAX_DOUBLE;
+
+    /* perform n-times selection sort step */
+    for (i = 0; i < n; i++) {
+	min = i;
+	for (j = i; j < count; j++)
+	    if (distrow[j] < distrow[min])
+		min = j;
+	/* exchange minimum element and i-th element */
+	tmp = distrow[min];
+	distrow[min] = distrow[i];
+	distrow[i] = tmp;
+	tmpI = indexrow[min];
+	indexrow[min] = indexrow[i];
+	indexrow[i] = tmpI;
+    }
+
+    /* copy n smallest values to row */
+    for (i = 0; i < n; i++) {
+	row[i] = indexrow[i];
+    }
+
+    /*fprintf(stderr, "\ndistrow =");
+       for(i = 0; i < n; i++)
+       fprintf(stderr, " %0.2f", distrow[i]);
+       fprintf(stderr, "\n"); */
+
+    G_free(distrow);
+    G_free(indexrow);
+}
+
+int get_max_index(int *array, int size)
+{
+    int i;
+    int max = 0;
+
+    if (size <= 0)
+	return -1;
+
+    for (i = 0; i < size; i++) {
+	if (array[i] > array[max])
+	    max = i;
+    }
+
+    return max;
+}
+
+int get_nearest_indices(int count, int *num_array, int num_count)
+{
+    int i, j, tmp;
+    int max = 0;
+
+    /* get maximum number */
+    max = get_max_index(num_array, num_count);
+
+    patch_n = num_array[max] < count - 1 ? num_array[max] : count - 1;
+
+    //      fprintf(stderr, "\n%d nearest patches taken into account.\n\n", patch_n);
+
+    nearest_indices = (int *)G_malloc(count * patch_n * sizeof(int));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	/* display progress */
+	if (verbose)
+	    G_percent(i, count, 2);
+
+	get_smallest_n_indices(nearest_indices + i * patch_n, distmatrix,
+			       patch_n, count, i);
+
+	/*              fprintf(stderr, "\npatch %d:", i);
+	   for(j = 0; j < patch_n; j++)
+	   fprintf(stderr, " %d", nearest_indices[i * patch_n + j]);
+	   fprintf(stderr, "\n"); */
+
+    }
+
+    return 0;
+}
+
+int f_dist(DCELL * vals, int count, int *num_array, int num_count,
+	   f_statmethod statmethod)
+{
+    int n;
+    int i, j, index;
+
+    DCELL *distances = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    index = nearest_indices[i * patch_n + j];
+	    distances[j] = distmatrix[i * count + index];
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(distances, n);
+	}
+    }
+
+    G_free(distances);
+    return 0;
+}
+
+int f_area(DCELL * vals, int count, int *num_array, int num_count,
+	   f_statmethod statmethod)
+{
+    int n;
+    int i, j, index;
+
+    DCELL *areas = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    index = nearest_indices[i * patch_n + j];
+	    areas[j] = (DCELL) (fragments[index + 1] - fragments[index]);
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(areas, n);
+	}
+    }
+
+    G_free(areas);
+    return 0;
+}
+
+int f_perim(DCELL * vals, int count, int *num_array, int num_count,
+	    f_statmethod statmethod)
+{
+    int n;
+    int i, j, index, border;
+    Coords *p;
+
+    DCELL *perims = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    border = 0;
+
+	    index = nearest_indices[i * patch_n + j];
+
+	    /* for all cells in a patch */
+	    for (p = fragments[index]; p < fragments[index + 1]; p++) {
+		border += 4 - p->neighbors;
+	    }
+	    perims[j] = (DCELL) (border);
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(perims, n);
+	}
+    }
+
+    G_free(perims);
+    return 0;
+}
+
+int f_shapeindex(DCELL * vals, int count, int *num_array, int num_count,
+		 f_statmethod statmethod)
+{
+    int n;
+    int i, j, index, border, area;
+    Coords *p;
+
+    DCELL *shapes = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    border = 0;
+
+	    index = nearest_indices[i * patch_n + j];
+
+	    /* for all cells in a patch */
+	    for (p = fragments[index]; p < fragments[index + 1]; p++) {
+		border += 4 - p->neighbors;
+	    }
+	    area = (int)(fragments[index + 1] - fragments[index]);
+
+	    shapes[j] = (DCELL) border / (4 * sqrt((DCELL) area));
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(shapes, n);
+	}
+    }
+
+    G_free(shapes);
+    return 0;
+}
+
+int f_path_dist(DCELL * vals, int count, int *num_array, int num_count,
+		f_statmethod statmethod)
+{
+    int n;
+    int i, j, k, index;
+
+    DCELL *distances = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+    int *flags = (int *)G_malloc(count * sizeof(int));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	// clear flags array
+	memset(flags, 0, count * sizeof(int));
+	int act_patch = i;
+
+	for (j = 0; j < patch_n; j++) {
+	    // get nearest patch for the act_patch
+	    // ignore those already marked in flags
+	    k = 0;
+	    do {
+		index = nearest_indices[act_patch * patch_n + k++];
+	    } while (flags[index] == 1);
+	    // mark current patch
+	    flags[act_patch] = 1;
+
+	    distances[j] = distmatrix[act_patch * count + index];
+	    act_patch = index;
+	}
+
+	/*              fprintf(stderr, "\ndistances for patch %d", i);
+	   for(j = 0; j < patch_n; j++)
+	   fprintf(stderr, " %0.2f", distances[j]); */
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(distances, n);
+	}
+    }
+
+    G_free(distances);
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,64 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef int (*f_func) (DCELL *, int, int *, int, f_statmethod);
+
+void writeFrag(int row, int col, int nbr_cnt);
+
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL value(DCELL * vals, int count);
+DCELL sum(DCELL * vals, int count);
+
+int get_dist_matrix(int count);
+
+int get_nearest_indices(int count, int *num_array, int num_count);
+
+int f_dist(DCELL *, int, int *, int, f_statmethod);
+int f_area(DCELL *, int, int *, int, f_statmethod);
+int f_perim(DCELL *, int, int *, int, f_statmethod);
+int f_shapeindex(DCELL *, int, int *, int, f_statmethod);
+int f_path_dist(DCELL *, int, int *, int, f_statmethod);
+
+int parseToken(int *res, int pos, char *token);
+
+/* matrix.c */
+int writeDistMatrixAndID(char *name, Coords ** frags, int count);
+int writeAdjacencyMatrix(char *name, Coords ** frags, int count, int *nns,
+			 int nn_count);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL Coords **fragments;
+GLOBAL int *flagbuf;
+GLOBAL Coords *actpos;
+GLOBAL int verbose;
+GLOBAL DCELL *distmatrix;
+GLOBAL int *nearest_indices;
+GLOBAL int patch_n;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.enn/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,415 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.enn
+ * AUTHOR(S):    Elshad Shirinov, Martin Wegmann
+ * PURPOSE:      Analysis of n-th euclidean nearest neighbour distance
+ *                               and spatial attributes of nearest neighbour patches
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+int recur_test(int, int, int);
+
+struct menu
+{
+    f_func *method;
+    char *name;
+    char *text;
+};
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct menu menu[] = {
+    {f_dist, "distance", "distance to the patch"},
+    {f_path_dist, "path_distance", "path distance from patch to patch"},
+    {f_area, "area", "area of the patch"},
+    {f_perim, "perimeter", "perimeter of the patch"},
+    {f_shapeindex, "shapeindex", "shapeindex of the patch"},
+    {0, 0, 0}
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values"},
+    {variance, "variance", "variance of values"},
+    {std_deviat, "standard deviation", "standard deviation of values"},
+    {value, "value", "according value for the patch"},
+    {sum, "sum", "sum of values"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char fullname[GNAME_MAX];
+    char title[1024];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+    DCELL *result;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+    struct Categories cats;
+
+    int statmethod;
+    int method;
+    int methods[GNAME_MAX];
+    f_func compute_values;
+    f_func compute_stat;
+
+    char *p;
+
+    /* neighbors count */
+    int neighb_count;
+
+    int row, col, i, j, m;
+    int method_count;
+    int readrow;
+    int keyval;
+    DCELL range = MAX_DOUBLE;
+
+    int n;
+    int copycolr;
+    struct Colors colr;
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output;
+	struct Option *keyval, *method;
+	struct Option *number, *statmethod;
+	struct Option *dmout, *adj_matrix, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    DCELL *values;
+    Coords *cells;
+    int fragcount = 0;
+    int parseres[1024];
+    int number;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Analysis of n-th Euclidean Nearest Neighbor distance.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    p = parm.method->options = G_malloc(1024);
+    for (n = 0; menu[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, menu[n].name);
+    }
+    parm.method->multiple = YES;
+    parm.method->description = _("Operation to perform on fragments");
+
+    parm.number = G_define_option();
+    parm.number->key = "number";
+    parm.number->key_desc = "num[-num]";
+    parm.number->type = TYPE_STRING;
+    parm.number->required = YES;
+    parm.number->multiple = YES;
+    parm.number->description = _("Number of nearest neighbors to analyse");
+
+    parm.statmethod = G_define_option();
+    parm.statmethod->key = "statmethod";
+    parm.statmethod->type = TYPE_STRING;
+    parm.statmethod->required = YES;
+    p = parm.statmethod->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, statmethods[n].name);
+    }
+    parm.statmethod->description =
+	_("Statistical method to perform on the values");
+
+    parm.dmout = G_define_option();
+    parm.dmout->key = "dmout";
+    parm.dmout->type = TYPE_STRING;
+    parm.dmout->required = NO;
+    parm.dmout->gisprompt = "new,cell,raster";
+    parm.dmout->description =
+	_("Output name for distance matrix and id-map (performed if not empty)");
+
+    parm.adj_matrix = G_define_option();
+    parm.adj_matrix->key = "adj_matrix";
+    parm.adj_matrix->type = TYPE_STRING;
+    parm.adj_matrix->required = NO;
+    parm.adj_matrix->gisprompt = "new,cell,raster";
+    parm.adj_matrix->description =
+	_("Output name for adjacency matrix (performed if not empty)");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	    exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* copy color table */
+    copycolr = (G_read_colors(oldname, oldmapset, &colr) > 0);
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get number of nearest neighbors to analyse */
+    for (i = 0, number = 0; parm.number->answers[i] != NULL; i++) {
+	number += parseToken(parseres, number, parm.number->answers[i]);
+    }
+
+    /*      sscanf(parm.number->answer, "%d", &number); */
+
+    /* scan all method answers */
+    method_count = 0;
+    while (parm.method->answers[method_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (p = menu[method].name); method++)
+	    if ((strcmp(p, parm.method->answers[method_count]) == 0))
+		break;
+	if (!p) {
+	    G_fatal_error("<%s=%s> unknown %s", parm.method->key,
+			  parm.method->answers[method_count],
+			  parm.method->key);
+	    exit(EXIT_FAILURE);
+	}
+
+	methods[method_count] = method;
+
+	method_count++;
+    }
+
+    /* get the statmethod */
+    for (statmethod = 0; (p = statmethods[statmethod].name); statmethod++)
+	if ((strcmp(p, parm.statmethod->answer) == 0))
+	    break;
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.statmethod->key,
+		      parm.statmethod->answer, parm.statmethod->key);
+	exit(EXIT_FAILURE);
+    }
+
+    /* establish the stat routine */
+    compute_stat = statmethods[statmethod].method;
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    actpos = cells;
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    fragments[0] = cells;
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    result = G_allocate_d_raster_buf();
+
+    /* get title, initialize the category and stat info */
+    if (parm.title->answer)
+	strcpy(title, parm.title->answer);
+    else
+	sprintf(title, "Fragmentation of file: %s", oldname);
+
+    if (verbose = !flag.quiet->answer)
+	G_message("Loading patches...");
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+
+	if (verbose)
+	    G_percent(row, nrows, 2);
+    }
+
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+		writeFrag(row, col, neighb_count);
+		fragments[fragcount] = actpos;
+	    }
+	}
+    }
+    if (verbose)
+	G_percent(nrows, nrows, 2);
+
+    /* generate the distance matrix */
+    get_dist_matrix(fragcount);
+
+    /* replace 0 count with (all - 1) patches */
+    for (i = 0; i < number; i++)
+	if (parseres[i] == 0)
+	    parseres[i] = fragcount - 1;
+
+    /* get indices of the nearest n patches (where n is the maximum number of patches to analyse) */
+    get_nearest_indices(fragcount, parseres, number);
+
+    /* for each method */
+    for (m = 0; m < method_count; m++) {
+
+	/* establish the newvalue routine */
+	compute_values = menu[methods[m]].method;
+
+	/* perform current function on the patches */
+	if (verbose = !flag.quiet->answer)
+	    G_message("Performing operation %s ... ", menu[methods[m]].name);
+	values = (DCELL *) G_malloc(fragcount * number * sizeof(DCELL));
+	compute_values(values, fragcount, parseres, number, compute_stat);
+
+	if (verbose)
+	    G_percent(fragcount, fragcount, 2);
+
+	/* write output files */
+	if (verbose = !flag.quiet->answer)
+	    G_message("Writing output...");
+
+	/* for all requested patches */
+	for (j = 0; j < number; j++) {
+	    /* open the new cellfile */
+	    sprintf(fullname, "%s.NN%d.%s", newname, parseres[j],
+		    menu[methods[m]].name);
+	    out_fd = G_open_raster_new(fullname, DCELL_TYPE);
+	    if (out_fd < 0)
+	        G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+	    /* write data */
+	    for (row = 0; row < nrows; row++) {
+		G_set_d_null_value(result, ncols);
+
+		for (i = 0; i < fragcount; i++) {
+		    for (actpos = fragments[i]; actpos < fragments[i + 1];
+			 actpos++) {
+			if (actpos->y == row) {
+			    result[actpos->x] = values[i + j * fragcount];
+			}
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, result);
+
+		if (verbose)
+		    G_percent(row + nrows * j + nrows * number * m,
+			      nrows * number * method_count, 2);
+	    }
+
+	    G_close_cell(out_fd);
+	}
+
+    }				/* for each method */
+
+    if (verbose)
+	G_percent(100, 100, 2);
+
+    if (parm.dmout->answer) {
+	exitres =
+	    writeDistMatrixAndID(parm.dmout->answer, fragments, fragcount);
+    }
+
+    if (parm.adj_matrix->answer) {
+	exitres =
+	    writeAdjacencyMatrix(parm.adj_matrix->answer, fragments,
+				 fragcount, parseres, number);
+    }
+
+    G_close_cell(in_fd);
+
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+    G_free(result);
+
+    G_free(distmatrix);
+    G_free(nearest_indices);
+
+    G_init_cats(0, title, &cats);
+    G_write_cats(newname, &cats);
+
+    if (copycolr)
+	G_write_colors(newname, newmapset, &colr);
+
+    exit(exitres);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/matrix.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/matrix.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/matrix.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,103 @@
+#include "local_proto.h"
+
+int writeDistMatrixAndID(char *name, Coords ** frags, int count)
+{
+    FILE *out_fp;
+    int res = 0;
+    char *mapset;
+    int out_fd;
+    int row, col, i;
+    DCELL *result;
+
+    /* allocate memory for result-row */
+    result = G_allocate_d_raster_buf();
+
+    /* open ASCII-file or use stdout */
+    if (!(out_fp = fopen(name, "w"))) {
+	fprintf(stderr, "Error creating file <%s>.", name);
+	res = 1;
+    }
+    else {
+	/* write distance matrix */
+	for (row = 0; row < count; row++) {
+	    for (col = 0; col < count; col++) {
+		fprintf(out_fp, "%f ", distmatrix[row * count + col]);
+	    }
+	    fprintf(out_fp, "\n");
+	}
+	fclose(out_fp);
+
+	/* check if the new file name is correct */
+    if (G_legal_filename(name) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), name);
+	mapset = G_mapset();
+
+	/* open the new cellfile */
+	out_fd = G_open_raster_new(name, DCELL_TYPE);
+	if (out_fd < 0) {
+	    char msg[200];
+
+	    sprintf(msg, "can't create new cell file <%s> in mapset %s\n",
+		    name, mapset);
+	    G_fatal_error(msg);
+	    res = 1;
+	}
+	else {
+	    /* write data */
+	    for (row = 0; row < nrows; row++) {
+		G_set_d_null_value(result, ncols);
+
+		for (i = 0; i < count; i++) {
+		    for (actpos = frags[i]; actpos < frags[i + 1]; actpos++) {
+			if (actpos->y == row) {
+			    result[actpos->x] = i;
+			}
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, result);
+	    }
+	}
+	G_close_cell(out_fd);
+    }
+
+    /* free memory */
+    G_free(result);
+
+    return res;
+}
+
+int writeAdjacencyMatrix(char *name, Coords ** frags, int count, int *nns,
+			 int nn_count)
+{
+    FILE *out_fp;
+    int row, col, i;
+    char fullname[GNAME_MAX];
+    int res = EXIT_SUCCESS;
+
+    /* open ASCII-file or use stdout */
+    for (i = 0; i < nn_count; i++) {
+	sprintf(fullname, "%s_%d", name, nns[i]);
+	if (!(out_fp = fopen(fullname, "w"))) {
+	    G_fatal_error("Error creating file <%s>.", name);
+	    res = EXIT_FAILURE;
+	}
+	else {
+	    /* write distance matrix */
+	    for (row = 0; row < count; row++) {
+		for (col = 0; col < count; col++) {
+		    if (nearest_indices[row * patch_n + nns[i] - 1] == col) {
+			fprintf(out_fp, "1 ");
+		    }
+		    else {
+			fprintf(out_fp, "0 ");
+		    }
+		}
+		fprintf(out_fp, "\n");
+	    }
+	    fclose(out_fp);
+	}
+    }
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn/matrix.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn/parser.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn/parser.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn/parser.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,69 @@
+#include "local_proto.h"
+
+int parseToken(int *res, int pos, char *token)
+{
+    char begin[GNAME_MAX];
+    char end[GNAME_MAX];
+    char *c, *tb, *te;
+    int i, count;
+
+    /* clear begin and end */
+    memset(begin, 0, GNAME_MAX);
+    memset(end, 0, GNAME_MAX);
+
+    c = token;
+    tb = begin;
+    while (*c != '-' && *c != 0) {
+	*tb = *c;
+	c++;
+	tb++;
+    }
+    G_strip(begin);
+
+    if (*c == 0) {
+	res[pos] = atoi(begin);
+	return 1;
+    }
+    c++;
+
+    te = end;
+    while (*c != 0) {
+	*te = *c;
+	c++;
+	te++;
+    }
+
+    G_strip(end);
+
+    for (i = atoi(begin), count = 0; i <= atoi(end); i++, count++) {
+	res[pos + count] = i;
+    }
+    return count;
+}
+
+int parseInput(int *res, char *input)
+{
+    char token[GNAME_MAX];
+    char *c, *t;
+    int actPos = 0;
+
+    c = input;
+    while (*c != 0) {
+	/* clear token */
+	memset(token, 0, GNAME_MAX);
+	t = token;
+
+
+	/* read token */
+	while (*c != ',' && *c != 0) {
+	    *t = *c;
+	    c++;
+	    t++;
+	}
+	c++;
+
+	actPos += parseToken(res, actPos, token);
+    }
+
+    return actPos;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn/parser.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.fragment.iter
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,63 @@
+<h2>DESCRIPTION</h2>
+
+Patch relevance for Euclidean Nearest Neighbor patches.
+
+<em>r.pi.enn.iter</em> is part of the patch based fragmentation analysis
+package r.pi.* (Patch Index). It computes distance and area
+differences for the first NN after removal of patch i.
+
+
+<h2>NOTES</h2>
+
+The user must specify the names of the raster map layers to
+be used for <em>input</em> and <em>output</em>, the <em>keyval</em> the
+<em>method</em> (e.g. distance, area) and <em>statmethod</em> used (i.e., average).
+<p>
+
+Within <em>r.fragment.NN</em> the following setting have to be set:
+
+<h3>keyval setting:</h3>
+
+The <em>keyval</em> operator determines which category value is taken for
+the Patch Index analysis.
+
+<h3>Method setting:</h3>
+
+The <em>method</em> operators determine what measure is applied 
+on the nth NN.
+
+<h2>Output</h2>
+
+Differences of distance/area after removal of patch i.<br>
+Amount of patches to be affected by removal (percent) (PP)<br>
+Amount of area in these patches (PA - Percent Area)
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.fragment.dist.html">r.fragment.dist</a>,
+<a href="r.pi.enn.html">r.pi.enn</a>,
+<a href="r.fragment.neighbors.html">r.fragment.neighbors</a>,
+<a href="r.fragment.nn.html">r.fragment.nn</a>,
+<a href="r.li.setup.html">r.li</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,169 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    fragments[0] = cells;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,204 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL *get_dist_matrix(int count)
+{
+    int i, j;
+    DCELL *distmatrix;
+
+    distmatrix = (DCELL *) G_malloc(count * count * sizeof(DCELL));
+
+    /* fill distance matrix */
+    for (i = 0; i < count; i++) {
+	for (j = i + 1; j < count; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * count + j] = d;
+	    distmatrix[j * count + i] = d;
+	}
+    }
+
+    return distmatrix;
+}
+
+void get_smallest_n_indices(int *row, DCELL * matrix, int n, int count,
+			    int focal)
+{
+    int i, j;
+    int min;
+    int tmpI;
+    DCELL tmp;
+
+    /* get row from distance matrix */
+    DCELL *distrow = (DCELL *) G_malloc(count * sizeof(DCELL));
+    int *indexrow = (int *)G_malloc(count * sizeof(int));
+
+    for (i = 0; i < count; i++) {
+	distrow[i] = matrix[focal * count + i];
+	indexrow[i] = i;
+    }
+    distrow[focal] = MAX_DOUBLE;
+
+    /* perform n-times selection sort step */
+    for (i = 0; i < n; i++) {
+	min = i;
+	for (j = i; j < count; j++)
+	    if (distrow[j] < distrow[min])
+		min = j;
+	/* exchange minimum element and i-th element */
+	tmp = distrow[min];
+	distrow[min] = distrow[i];
+	distrow[i] = tmp;
+	tmpI = indexrow[min];
+	indexrow[min] = indexrow[i];
+	indexrow[i] = tmpI;
+    }
+
+    /* copy n smallest values to row */
+    for (i = 0; i < n; i++) {
+	row[i] = indexrow[i];
+    }
+
+    G_free(distrow);
+    G_free(indexrow);
+}
+
+int get_area(Coords ** frags, int patch)
+{
+    return frags[patch + 1] - frags[patch];
+}
+
+void f_distance(DCELL * vals, Coords ** frags, int count,
+		f_statmethod statmethod)
+{
+    int i, j, index1, index2;
+    DCELL d1, d2;
+    int diffcount, area, allarea;
+    DCELL *distmatrix = get_dist_matrix(count);
+    int *neighb_indices = (int *)G_malloc(count * 2 * sizeof(int));
+    DCELL *differences = (DCELL *) G_malloc(count * sizeof(DCELL));
+    int *actpos;
+
+    /* collect 2 nearest neighbor indices and measure overall area */
+    allarea = 0;
+    for (i = 0, actpos = neighb_indices; i < count; i++, actpos += 2) {
+	get_smallest_n_indices(actpos, distmatrix, 2, count, i);
+	allarea += get_area(fragments, i);
+    }
+
+    /* calculate differences */
+    for (i = 0; i < count; i++) {
+	area = 0;
+	diffcount = 0;
+	for (j = 0; j < count; j++) {
+	    if (neighb_indices[2 * j] == i) {
+		index1 = neighb_indices[2 * j];
+		index2 = neighb_indices[2 * j + 1];
+		d1 = distmatrix[j * count + index1];
+		d2 = distmatrix[j * count + index2];
+
+		differences[diffcount] = d2 - d1;
+		diffcount++;
+		area += get_area(fragments, j);
+	    }
+	}
+
+	vals[3 * i] = statmethod(differences, diffcount);
+	vals[3 * i + 1] = (DCELL) diffcount / (DCELL) count;
+	vals[3 * i + 2] = (DCELL) area / (DCELL) allarea;
+    }
+
+    G_free(distmatrix);
+    G_free(neighb_indices);
+    G_free(differences);
+    return;
+}
+
+void f_area(DCELL * vals, Coords ** frags, int count, f_statmethod statmethod)
+{
+    int i, j, index1, index2;
+    DCELL d1, d2;
+    int diffcount, area, allarea;
+    DCELL *distmatrix = get_dist_matrix(count);
+    int *neighb_indices = (int *)G_malloc(count * 2 * sizeof(int));
+    DCELL *differences = (DCELL *) G_malloc(count * sizeof(DCELL));
+    int *actpos;
+
+    /* collect 2 nearest neighbor indices and measure overall area */
+    allarea = 0;
+    for (i = 0, actpos = neighb_indices; i < count; i++, actpos += 2) {
+	get_smallest_n_indices(actpos, distmatrix, 2, count, i);
+	allarea += get_area(fragments, i);
+    }
+
+    /* calculate differences */
+    for (i = 0; i < count; i++) {
+	area = 0;
+	diffcount = 0;
+	for (j = 0; j < count; j++) {
+	    if (neighb_indices[2 * j] == i) {
+		index1 = neighb_indices[2 * j];
+		index2 = neighb_indices[2 * j + 1];
+		/* get areas */
+		d1 = get_area(fragments, index1);
+		d2 = get_area(fragments, index2);
+
+		differences[diffcount] = d2 - d1;
+		diffcount++;
+		area += get_area(fragments, j);
+	    }
+	}
+
+	vals[3 * i] = statmethod(differences, diffcount);
+	vals[3 * i + 1] = (DCELL) diffcount / (DCELL) count;
+	vals[3 * i + 2] = (DCELL) area / (DCELL) allarea;
+    }
+
+    G_free(distmatrix);
+    G_free(neighb_indices);
+    G_free(differences);
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,60 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING 0
+#define TYPE_NOGO -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+} Point;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef int (*f_func) (DCELL *, Coords **, int, f_statmethod);
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* func.c */
+void f_distance(DCELL * vals, Coords ** frags, int count,
+		f_statmethod statmethod);
+void f_area(DCELL * vals, Coords ** frags, int count,
+	    f_statmethod statmethod);
+
+/* statmethods.c */
+DCELL sum(DCELL * vals, int count);
+DCELL average(DCELL * vals, int count);
+
+/* global parameters */
+GLOBAL int verbose;
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,326 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.iter
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Iterative removal of patches and analysis of patch relevance
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct method
+{
+    f_func *method;		/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct statmethod
+{
+    f_func *statmethod;		/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct method methods[] = {
+    {f_distance, "distance", "distance to the nearest patch"},
+    {f_area, "area", "area of the nearest patch"},
+    {0, 0, 0}
+};
+
+static struct statmethod statmethods[] = {
+    {sum, "sum", "sum of diferences"},
+    {average, "average", "average of diferences"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset, *newname, *newmapset;
+    char outname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;			/* raster - input */
+    int out_fd;			/* raster - output */
+
+    /* parameters */
+    int keyval;
+    int neighb_count;
+    int method;
+    f_func perform_method;
+    int statmethod;
+    f_func perform_statmethod;
+
+    /* other parameters */
+    char *title[1024];
+
+    /* helper variables */
+    RASTER_MAP_TYPE map_type;
+    int i, j;
+    int row, col;
+    int nrows, ncols;
+    int act_method;
+    DCELL *result;
+    struct Cell_head ch, window;
+    char *p;
+
+    int *flagbuf;
+    DCELL *values;
+    Coords *actpos;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output;
+	struct Option *keyval, *method;
+	struct Option *statmethod, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Patch relevance for Euclidean Nearest Neighbor patches.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value of patches in the input file");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    p = parm.method->options = G_malloc(1024);
+    for (act_method = 0; methods[act_method].name; act_method++) {
+	if (act_method > 0)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, methods[act_method].name);
+    }
+    parm.method->description = _("Aspect of the nearest patch to use.");
+
+    parm.statmethod = G_define_option();
+    parm.statmethod->key = "statmethod";
+    parm.statmethod->type = TYPE_STRING;
+    parm.statmethod->required = YES;
+    p = parm.statmethod->options = G_malloc(1024);
+    for (act_method = 0; statmethods[act_method].name; act_method++) {
+	if (act_method > 0)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, statmethods[act_method].name);
+    }
+    parm.statmethod->description =
+	_("Statistical method to perform on differences.");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    if (oldname && NULL == (oldmapset = G_find_cell2(oldname, ""))) {
+	G_warning(_("%s: <%s> raster file not found\n"),
+		  G_program_name(), oldname);
+	exit(EXIT_FAILURE);
+    }
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get method */
+    for (method = 0; (p = methods[method].name); method++)
+	if ((strcmp(p, parm.method->answer) == 0))
+	    break;
+    if (!p) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.method->key, parm.method->answer, parm.method->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* establish the method routine */
+    perform_method = methods[method].method;
+
+    /* get statmethod */
+    for (statmethod = 0; (p = statmethods[statmethod].name); statmethod++)
+	if ((strcmp(p, parm.statmethod->answer) == 0))
+	    break;
+    if (!p) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.statmethod->key, parm.statmethod->answer,
+		  parm.statmethod->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* establish the statmethod routine */
+    perform_statmethod = statmethods[statmethod].statmethod;
+
+    /* get title */
+    if (parm.title->answer)
+	strcpy(title, parm.title->answer);
+    else
+	sprintf(title, "Fragmentation of file: %s", oldname);
+
+    /* allocate the cell buffers */
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    result = G_allocate_d_raster_buf();
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+    }
+
+    writeFragments(flagbuf, nrows, ncols, neighb_count);
+
+    /* perform actual function on the patches */
+    values = (DCELL *) G_malloc(3 * fragcount * sizeof(DCELL));
+    perform_method(values, fragments, fragcount, perform_statmethod);
+
+    /* open new cellfile  */
+    strcpy(outname, newname);
+    strcat(outname, ".diff");
+    out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(result, ncols);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (actpos = fragments[i]; actpos < fragments[i + 1]; actpos++) {
+		if (actpos->y == row) {
+		    result[actpos->x] = values[3 * i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, result);
+    }
+    G_close_cell(out_fd);
+
+    /* open new cellfile  */
+    strcpy(outname, newname);
+    strcat(outname, ".PP");
+    out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(result, ncols);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (actpos = fragments[i]; actpos < fragments[i + 1]; actpos++) {
+		if (actpos->y == row) {
+		    result[actpos->x] = values[3 * i + 1];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, result);
+    }
+    G_close_cell(out_fd);
+
+    /* open new cellfile  */
+    strcpy(outname, newname);
+    strcat(outname, ".PA");
+    out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(result, ncols);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (actpos = fragments[i]; actpos < fragments[i + 1]; actpos++) {
+		if (actpos->y == row) {
+		    result[actpos->x] = values[3 * i + 2];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, result);
+    }
+    G_close_cell(out_fd);
+
+    if (verbose)
+	G_percent(1, 1, 2);
+
+    G_close_cell(in_fd);
+
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.enn.iter/statmethods.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.enn.iter/statmethods.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.enn.iter/statmethods.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,29 @@
+#include "local_proto.h"
+
+DCELL sum(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL res = 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res;
+}
+
+DCELL average(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL res = 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.enn.iter/statmethods.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass-addons/raster/r.pi/r.pi.export/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.export/description.html	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.export/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,28 +1,58 @@
-<H2>DESCRIPTION</H2>
+<h2>DESCRIPTION</h2>
 
-The <EM>r.pi.export</EM> module computes statistics of values within a patch and exports them to an ascii file. Additionally the raw patch values split up by patch ID are exported. The <EM>patch ID</EM> 
-raster can be generated in order to visually link patch statistics and individual patches.
+This module exports raster patch values (no single pixels, but single individual patch values), which can be used for subsequent analysis in R and later import into GRASS again, using <a href="r.pi.import.html">r.pi.import</a>.
 
-<P>
+<h2>NOTES</h2>
 
-The program will be run non-interactively if the user specifies program arguments (see OPTIONS) on the command
-line.  Alternately, the user can simply type <B>r.pi.export</B> on the command line, without program
-arguments.  In this case, the user will be prompted for flag settings and parameter values.
+This module...
 
+<h2>EXAMPLE</h2>
 
-<H2>NOTES</H2>
+An example for the North Carolina sample dataset:
 
-For export and import of patch values after e.g. R calculation <EM>r.pi.export</EM> and <EM>r.pi.import</EM> can be applied using the same raster (same extent, resolution is mandatory).
+generating a patch index map for later export:
+<div class="code"><pre>
+<b> r.pi.index input=</b>landclass96 <b>output=</b>landclass96_forestclass5_area <b>keyval=</b>5 <b>method=</b>area
+</pre></div>
 
+export this resulting map:
+<div class="code"><pre>
+<b>r.pi.export input=</b>landclass96_forestclass5_area <b>output=</b>patch_area_out <b>values=</b>patch_area_values <b>id_raster=</b>forestclass5_ID <b>stats=</b>average,variance,min
+</pre></div>
 
-<H2>SEE ALSO</H2>
+various resulting files are generated:<br>
+<em>patch_area_out</em>: a text file with the <em>average</em>, <em>variance</em> and <em>minimum</em> statistics as defined above and additionally informaton about the percentage coverage (<em>landcover</em>) and the number of fragments (<em>number</em>) of the analysed landcover.
 
-<EM><A HREF="r.pi.import.html">r.pi.import</A></EM><br>
+<br>
 
-<H2>AUTHOR</H2>
+<em>patch_area_values</em>: a text file with the actual patch values not the statistics. The first column is providing the corresponding patch ID, which is also existing in the <em>forestclass5_ID</em> raster map (here:0-878). The second column is providing the percentage cover of each patch (sum is equal the overall coverage: 0.506). The third column is holding the actual patch index value (here area; e.g. patch 0: 12).
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
 Programming: Elshad Shirinov<br>
-Scientific concept: Dr. Martin Wegmann <br>
-Department of Remote Sensing <br>Remote Sensing and Biodiversity Unit<br> University of Wuerzburg, Germany
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
 
-<p><i>Last changed: $Date$</i>
-
+<p>
+<i>Last changed: $Date$</i>

Modified: grass-addons/raster/r.pi/r.pi.export/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.export/frag.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.export/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -14,9 +14,7 @@
 		 int ny, int nbr_cnt)
 {
     int left, right, top, bottom;
-
     int i, j;
-
     int cnt = 0;
 
     switch (nbr_cnt) {
@@ -67,13 +65,9 @@
 		  int nrows, int ncols, int nbr_cnt)
 {
     int x, y, i;
-
     Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
-
     Position *first = list;
-
     Position *last = list;
-
     Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
 
     /* count neighbors */
@@ -111,17 +105,13 @@
     while (first < last) {
 	/* get position from fifo-list */
 	int r = first->y;
-
 	int c = first->x;
 
 	first++;
 
 	int left = c > 0 ? c - 1 : 0;
-
 	int top = r > 0 ? r - 1 : 0;
-
 	int right = c < ncols - 1 ? c + 1 : ncols - 1;
-
 	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
 
 	/* add neighbors to fifo-list */
@@ -173,7 +163,6 @@
 void writeFragments(DCELL * flagbuf, int nrows, int ncols, int nbr_cnt)
 {
     int row, col, i;
-
     Coords *p;
 
     fragcount = 0;

Modified: grass-addons/raster/r.pi/r.pi.export/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.export/helpers.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.export/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -68,7 +68,6 @@
 void print_fragments()
 {
     int f;
-
     Coords *p;
 
     for (f = 0; f < fragcount; f++) {

Modified: grass-addons/raster/r.pi/r.pi.export/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.export/local_proto.h	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.export/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -23,35 +23,38 @@
 #define MIN_DOUBLE -1000000
 #define MAX_DOUBLE 1000000
 
-typedef struct {
-	int x, y;
-	int neighbors;
-	DCELL value;
+typedef struct
+{
+    int x, y;
+    int neighbors;
+    DCELL value;
 } Coords;
 
-typedef struct {
-	int x, y;
+typedef struct
+{
+    int x, y;
 } Point;
 
-typedef struct {
-	int x, y;
-	int patch;
+typedef struct
+{
+    int x, y;
+    int patch;
 } PatchPoint;
 
-typedef DCELL (*f_statmethod)(DCELL*, int);
+typedef DCELL(*f_statmethod) (DCELL *, int);
 
 /* helpers.c */
 int Round(double d);
 int Random(int max);
 double Randomf();
 void print_buffer(int *buffer, int sx, int sy);
-void print_d_buffer(DCELL *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
 void print_map(double *map, int size);
-void print_array(DCELL *buffer, int size);
+void print_array(DCELL * buffer, int size);
 void print_fragments();
 
 /* frag.c */
-void writeFragments(DCELL *flagbuf, int nrows, int ncols, int nbr_cnt);
+void writeFragments(DCELL * flagbuf, int nrows, int ncols, int nbr_cnt);
 
 /* stat_method.c */
 DCELL average(DCELL * vals, int count);

Modified: grass-addons/raster/r.pi/r.pi.export/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.export/main.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.export/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,12 +1,22 @@
-#define MAIN
-#include "local_proto.h"
-
 /*
-   Export of patch based values
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.export
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Export of patch based raster information
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
 
-   by Elshad Shirinov.
- */
+#define MAIN
 
+#include "local_proto.h"
+
 struct statmethod
 {
     f_statmethod *method;	/* routine to compute new value */
@@ -16,13 +26,12 @@
 };
 
 static struct statmethod statmethods[] = {
-    {average, "average", "average of patch values", "avg"},
-    {variance, "variance", "variance of patch values", "var"},
-    {std_deviat, "standard deviation", "standard deviation of patch values",
-     "dev"},
-    {median, "median", "median of patch values", "med"},
-    {min, "min", "minimum of patch values", "min"},
-    {max, "max", "maximum of patch values", "max"},
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
     {0, 0, 0, 0}
 };
 
@@ -39,20 +48,15 @@
 
     /* in and out file pointers */
     int in_fd;
-
     FILE *out_fp;		/* ASCII - output */
 
     int out_fd;
 
     /* parameters */
     int keyval;
-
-    int stats[256];
-
+    int stats[GNAME_MAX];
     int stat_count;
-
     int ratio_flag;
-
     int neighb_count;
 
     /* maps */
@@ -63,39 +67,24 @@
 
     /* helper variables */
     int row, col;
-
     int *result;
-
     DCELL *d_res;
-
     int i, j, n;
-
     int x, y;
-
     Coords *p;
-
-    char output_name[256];
-
+    char output_name[GNAME_MAX];
     char *str;
-
     int method;
-
     f_statmethod perform_method;
-
     DCELL val;
-
     DCELL *values;
-
     int count;
-
     int area;
 
     RASTER_MAP_TYPE map_type;
-
     struct Cell_head ch, window;
 
     struct GModule *module;
-
     struct
     {
 	struct Option *input, *output;
@@ -103,7 +92,6 @@
 	struct Option *patch_rast, *stats;
 	struct Option *title;
     } parm;
-
     struct
     {
 	struct Flag *adjacent, *quiet;
@@ -113,23 +101,16 @@
 
     module = G_define_module();
     module->keywords = _("raster");
-    module->description =
-	_("Performs statistical analysis and export of values within a patch");
+    module->description = _("Export of patch based information.");
 
-    parm.input = G_define_option();
-    parm.input->key = "input";
-    parm.input->type = TYPE_STRING;
-    parm.input->required = YES;
-    parm.input->gisprompt = "old,cell,raster";
-    parm.input->description = _("Name of existing raster file");
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
 
     parm.output = G_define_option();
     parm.output->key = "output";
     parm.output->type = TYPE_STRING;
     parm.output->required = YES;
     parm.output->gisprompt = "new_file,file,output";
-    parm.output->description =
-	_("Name for the output ASCII-file with statistical values");
+    parm.output->description = _("Name for the output ASCII-file");
 
     parm.values = G_define_option();
     parm.values->key = "values";
@@ -144,14 +125,14 @@
     parm.id_rast->type = TYPE_STRING;
     parm.id_rast->required = NO;
     parm.id_rast->gisprompt = "new,cell,raster";
-    parm.id_rast->description = _("Name for the id raster");
+    parm.id_rast->description = _("Name for the ID raster map");
 
     parm.patch_rast = G_define_option();
     parm.patch_rast->key = "patch_raster";
     parm.patch_rast->type = TYPE_STRING;
     parm.patch_rast->required = NO;
     parm.patch_rast->gisprompt = "new,cell,raster";
-    parm.patch_rast->description = _("Name for the binary patch raster");
+    parm.patch_rast->description = _("Name for the patch raster map");
 
     parm.stats = G_define_option();
     parm.stats->key = "stats";
@@ -174,12 +155,12 @@
     parm.title->key_desc = "\"phrase\"";
     parm.title->type = TYPE_STRING;
     parm.title->required = NO;
-    parm.title->description = _("Title of the output raster file");
+    parm.title->description = _("Title for resultant raster map");
 
     flag.adjacent = G_define_flag();
     flag.adjacent->key = 'a';
     flag.adjacent->description =
-	_("Set for 8 cell-neighbors. 4 cell-neighbors are default.");
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
 
     flag.quiet = G_define_flag();
     flag.quiet->key = 'q';
@@ -192,12 +173,9 @@
     oldname = parm.input->answer;
 
     /* test input files existance */
-    if ((oldmapset = G_find_cell2(oldname, "")) == NULL) {
-	G_fatal_error(_("%s: <%s> raster file not found\n"), G_program_name(),
-		      oldname);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
 
     /* get verbose */
     verbose = !flag.quiet->answer;
@@ -207,27 +185,15 @@
 
     /* check if the id file name is correct */
     idname = parm.id_rast->answer;
-    if (idname) {
-	if (G_legal_filename(idname) < 0) {
-	    G_fatal_error(_("%s: <%s> illegal file name\n"), G_program_name(),
-			  idname);
-	    G_usage();
-	    exit(EXIT_FAILURE);
-	}
+    if (G_legal_filename(idname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), idname);
 	idmapset = G_mapset();
-    }
 
     /* check if the patch file name is correct */
     patchname = parm.patch_rast->answer;
-    if (patchname) {
-	if (G_legal_filename(patchname) < 0) {
-	    G_fatal_error(_("%s: <%s> illegal file name\n"), G_program_name(),
-			  patchname);
-	    G_usage();
-	    exit(EXIT_FAILURE);
-	}
+    if (G_legal_filename(patchname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), patchname);
 	patchmapset = G_mapset();
-    }
 
     /* get size */
     sx = G_window_cols();
@@ -265,16 +231,13 @@
     G_set_c_null_value(id_map, sx * sy);
 
     /* open map */
-    if ((in_fd = G_open_cell_old(oldname, oldmapset)) < 0) {
-	G_fatal_error(_("can't open cell file <%s> in mapset %s\n"), oldname,
-		      oldmapset);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
 
     /* read map */
     if (verbose)
-	G_message("Reading map file:\n");
+	G_message("Reading map:");
     for (row = 0; row < sy; row++) {
 	G_get_d_raster_row(in_fd, map + row * sx, row);
 
@@ -291,13 +254,13 @@
     writeFragments(map, sy, sx, neighb_count);
 
     if (verbose)
-	G_message("Writing output ... ");
+	G_message("Writing output...");
 
     /* open ASCII-file or use stdout */
     if (parm.values->answer) {
 	if (strcmp(parm.values->answer, "-") != 0) {
 	    if (!(out_fp = fopen(parm.values->answer, "w"))) {
-		G_fatal_error(_("Error creating file <%s>."),
+		G_fatal_error(_("Error creating file <%s>"),
 			      parm.values->answer);
 	    }
 	}
@@ -343,7 +306,7 @@
     /* open ASCII-file or use stdout */
     if (parm.output->answer && strcmp(parm.output->answer, "-") != 0) {
 	if (!(out_fp = fopen(parm.output->answer, "w"))) {
-	    G_fatal_error(_("Error creating file <%s>."),
+	    G_fatal_error(_("Error creating file <%s>"),
 			  parm.output->answer);
 	}
     }
@@ -386,11 +349,8 @@
     if (idname) {
 	/* open new cellfile  */
 	out_fd = G_open_raster_new(idname, CELL_TYPE);
-	if (out_fd < 0) {
-	    G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
-			  idname, idmapset);
-	    exit(EXIT_FAILURE);
-	}
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), idname);
 
 	/* write the output file */
 	for (row = 0; row < sy; row++) {
@@ -407,11 +367,8 @@
     if (patchname) {
 	/* open new cellfile  */
 	out_fd = G_open_raster_new(patchname, CELL_TYPE);
-	if (out_fd < 0) {
-	    G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
-			  patchname, patchmapset);
-	    exit(EXIT_FAILURE);
-	}
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), patchname);
 
 	/* write the output file */
 	for (row = 0; row < sy; row++) {

Modified: grass-addons/raster/r.pi/r.pi.export/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.export/stat_method.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.export/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -3,7 +3,6 @@
 DCELL average(DCELL * vals, int count)
 {
     int i;
-
     DCELL res = 0;
 
     if (count <= 0)
@@ -18,11 +17,8 @@
 DCELL variance(DCELL * vals, int count)
 {
     int i;
-
     DCELL mean;
-
     DCELL s = 0;
-
     DCELL ss = 0;
 
     if (count <= 0)
@@ -50,13 +46,9 @@
 DCELL median(DCELL * vals, int count)
 {
     int k = (count - 1) / 2;
-
     int l = 0;
-
     int h = count - 1;
-
     DCELL pivot, tmp;
-
     int i, j, z;
 
     if (count <= 0)
@@ -93,7 +85,6 @@
 DCELL min(DCELL * vals, int count)
 {
     int i;
-
     DCELL res = 0;
 
     if (count <= 0)
@@ -110,7 +101,6 @@
 DCELL max(DCELL * vals, int count)
 {
     int i;
-
     DCELL res = 0;
 
     if (count <= 0)

Added: grass-addons/raster/r.pi/r.pi.fnn/.Makefile.kate-swp
===================================================================
(Binary files differ)


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/.Makefile.kate-swp
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: grass-addons/raster/r.pi/r.pi.fnn/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.fnn
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,151 @@
+<h2>DESCRIPTION</h2>
+
+Determine the functional nearest-neighbor distance analysis. 
+
+<em>r.pi.fnn</em> is a patch based ecological/functional nearest
+neighbour analysis module. It computes distance based on a friction map. This module is related to <em>r.pi.enn</em> but more adequat if the ecological connectivity should be analysed.
+
+<h2>NOTES</h2>
+
+The user must specify the names of the raster map layers to
+be used for <em>input</em> <em> costmap </em> and <em>output</em>, the
+<em>method</em> used (i.e., distance), the <em>keyval</em>, the
+<em>number</em> and the <em>statmethod</em>.
+
+
+<h3>Input</h3>
+
+<h4>Input</h4>
+
+The calculation of the ecolgogical nearest neighbour is based on a raster
+with start patches. The actual map can be categorical or continuous but
+the value defined in <em>keyval</em> will be the basis for the patches
+to calculate the methods defined below. These patches will also be in
+the output map.
+
+<h4>costmap</h4>
+
+The calculation of the ecolgogical nearest neighbour is based on a costmap
+(* and 1-infinite) - this map can be binary or continous - high values
+are considered to have high cost issues and the shortest path is the
+one with the lowest amount of costs. "null" values can not be traversed,
+hence these values have to be bypassed. "0" values are not accepted and
+will result in "0" distance.
+
+<p>
+e.g. if a binary map(1 and 2) is used, the ENN is the path with the
+lowest amount of "1"
+
+<h3>Methods:</h3>
+The <em>method</em> and the <em>number</em> operators determine what
+algorithm and setting is applied 
+on the patches.
+
+<p>
+
+The <em>number</em> is the amount of nearest neighbours to be taken and
+the calculated distances are processed as assigned in <em>statmethod</em>
+
+<h4>Operations to perform</h4>
+r.pi.enn can perform the following operations:
+
+<p>
+
+<dt><b>Distance</b> 
+
+<dd>The <em>Distance to Nearest</em> computes the nearest edge-to-edge
+distance between patches. Counting from the focus patch.
+
+<dt><b>path Distance</b> 
+
+<dd>The <em>Distance to Nearest</em> computes the nearest edge-to-edge
+distance between patches. Unlike <em>Distance</em> the distance is
+computed based on subsequent NN not from the focus patch onwards. The
+1th NN is the first patch with the minimal edge-to-edge distance from
+the focus patch, while 2th NN is the patch with the minimal edge-to-edge
+distance from the 1th NN patch and so on. 
+
+<dt><b>Area</b> 
+
+<dd>The <em>Area</em> computes the size of the nearest edge-to-edge
+distance patch. It is based on <em>Distance</em> not on <em>path Distance</em>.
+
+<dt><b>Perimeter</b> 
+
+<dd>The <em>Perimeter</em> computes the Perimeter of the nearest
+edge-to-edge distance patch. It is based on <em>Distance</em> not on
+<em> path Distance</em>.
+
+<dt><b>SHAPE</b> 
+
+<dd>The <em>SHAPE</em> computes the SHAPE Index of the nearest edge-to-edge
+distance patch. It is based on <em>Distance</em> not on <em> path Distance</em>.
+
+
+<h4>Statsmethod setting:</h4>
+The <em>statsmethod</em> operators determine calculation is done on the
+distance. <em>Average</em>, <em>Variance</em>,<em>Stddev</em> and
+<em>value</em> can be used.
+
+<dt><b>Average</b> 
+
+<dd>The <em>Average</em> computes the average value defined in
+<em>Operations to perform </em>.
+
+<dt><b>Variance</b> 
+
+<dd>The <em>Variance</em> computes the variance defined in
+<em>Operations to perform </em>.
+
+<dt><b>Stand. Dev.</b> 
+
+<dd>The <em>Stand. Dev.</em> computes the stddev value defined in
+<em>Operations to perform </em>.
+
+<dt><b>Value</b> 
+
+<dd>The <em>patch Distance</em> computes the nearest edge-to-edge distance
+between two patches. The output of <em>value</em> is the actual value.
+E.g. NN==5 of <em>area</em> gives the size of the 5th NN while
+<em>Average</em> gives the average of the area of 1-5th NN.
+
+
+<h4>Number of nearest neighbors to analyse:</h4>
+
+The input options are either one NN: <em>1</em> or several NN separated
+by <em>,</em>: 1,2,5,8 or a range of NN: 1-6.
+
+<p>
+Merging these options is possible as well: 1-5,8,9,13,15-19,22 etc.
+
+</dl>
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.fragment.dist.html">r.fragment.dist</a>,
+<a href="r.pi.enn.iter.html">r.pi.enn.iter</a>,
+<a href="r.fragment.neighbors.html">r.fragment.neighbors</a>,
+<a href="r.fragment.nn.html">r.fragment.nn</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,143 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int getNeighbors(Position * res, int x, int y, int nx, int ny, int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+void writeFrag(int row, int col, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt = getNeighbors(nbr_list, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,481 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL res = 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL value(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return vals[count - 1];
+}
+
+DCELL sum(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    int i;
+    DCELL res = 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res;
+}
+
+DCELL euclid_dist(int x1, int y1, int x2, int y2)
+{
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int stepcounter = 0;
+
+    /* impementation of A* */
+    char *flagmap = (char *)G_malloc(nrows * ncols * sizeof(char));
+
+    memset(flagmap, 0, nrows * ncols * sizeof(char));
+    heap_alloc(nrows * ncols);
+
+    heap_insert(p1->x, p1->y, 0, 0);
+
+    //      fprintf(stderr, "from - (%d, %d) -> (%d, %d)", p1->x, p1->y, p2->x, p2->y);
+
+    while (heapsize > 0) {
+	int upx, upy, downx, downy, dx, dy;
+	Path_Coords actpos = heap_delete(0);
+
+	Path_Coords *p;
+
+	/*              char* c;
+
+	   if(stepcounter < 20) {
+	   for(dy = 0; dy < 4; dy++) {
+	   for(dx = 0; dx < 10; dx++)
+	   fprintf(stderr, "%d", flagmap[dy * ncols + dx]);
+	   fprintf(stderr, "\n");               
+	   }
+	   fprintf(stderr, "\n\n");
+	   stepcounter++;
+	   } */
+
+	/* if actpos on closed */
+	if (flagmap[actpos.x + actpos.y * ncols] != 0)
+	    continue;
+	/* if actpos is goal */
+	if (actpos.x == p2->x && actpos.y == p2->y) {
+	    heap_free();
+	    G_free(flagmap);
+	    return actpos.g;
+	}
+	/* add actpos to closed */
+	flagmap[actpos.x + actpos.y * ncols] = 1;
+
+	/* go through neighbors */
+	downx = actpos.x > 0 ? -1 : 0;
+	downy = actpos.y > 0 ? -1 : 0;
+	upx = actpos.x < ncols - 1 ? 1 : 0;
+	upy = actpos.y < nrows - 1 ? 1 : 0;
+
+	for (dx = downx; dx <= upx; dx++)
+	    for (dy = downy; dy <= upy; dy++)
+		// pick only neighbors, which are trespassable and not on closed list
+		if (!(dx == 0 && dy == 0) &&
+		    !G_is_d_null_value(costmap + actpos.x + dx +
+				       (actpos.y + dy) * ncols) &&
+		    flagmap[actpos.x + dx + (actpos.y + dy) * ncols] == 0) {
+		    DCELL newf, newg;
+		    int i;
+		    int actx = actpos.x + dx;
+		    int acty = actpos.y + dy;
+
+		    /* calculate new path cost */
+		    if (dx == 0 || dy == 0)
+			newg = actpos.g + costmap[actx + acty * ncols];
+		    else
+			newg =
+			    actpos.g + M_SQRT2 * costmap[actx + acty * ncols];
+
+		    /* calculate new estimate */
+		    newf = newg + euclid_dist(actx, acty, p2->x, p2->y);
+
+		    /* if neighbor on open list */
+		    i = heap_search(actx, acty);
+		    if (i > -1) {
+			/*                                              int j;
+			   fprintf(stderr, "element already on open list: (%d,%d), nr %d  ", actx, acty, i); 
+			   fprintf(stderr, "list:");
+			   for(p = heap; p < heap + heapsize; p++)
+			   fprintf(stderr, "x=%d, y=%d -> ", p->x, p->y);
+			   fprintf(stderr, "\n"); */
+
+			if (heap[i].g > newg) {
+			    heap[i].g = newg;
+			    heap[i].f = newf;
+			    upheap(i);
+			}
+		    }
+		    else {
+			/* add neighbor to open list */
+			heap_insert(actx, acty, newf, newg);
+		    }
+		}
+	/*              fprintf(stderr, "\nheapsize = %d\n", heapsize);
+	   for(p = heap; p < heap + heapsize; p++)
+	   fprintf(stderr, "x=%d, y=%d, f=%f, g=%f\n", p->x, p->y, p->f, p->g);
+	   fprintf(stderr, "\n\n"); */
+    }
+
+    heap_free();
+    G_free(flagmap);
+    return 0;
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+int get_dist_matrix(int count)
+{
+    int i, j;
+
+    distmatrix = (DCELL *) G_malloc(count * count * sizeof(DCELL));
+
+    /* fill distance matrix */
+    for (i = 0; i < count; i++) {
+	for (j = i + 1; j < count; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * count + j] = d;
+	    distmatrix[j * count + i] = d;
+	}
+    }
+
+    return 0;
+}
+
+void get_smallest_n_indices(int *row, DCELL * matrix, int n, int count,
+			    int focal)
+{
+    int i, j;
+    int min;
+    int tmpI;
+    DCELL tmp;
+
+    /* get row from distance matrix */
+    DCELL *distrow = (DCELL *) G_malloc(count * sizeof(DCELL));
+    int *indexrow = (int *)G_malloc(count * sizeof(int));
+
+    for (i = 0; i < count; i++) {
+	distrow[i] = matrix[focal * count + i];
+	indexrow[i] = i;
+    }
+    distrow[focal] = MAX_DOUBLE;
+
+    /* perform n-times selection sort step */
+    for (i = 0; i < n; i++) {
+	min = i;
+	for (j = i; j < count; j++)
+	    if (distrow[j] < distrow[min])
+		min = j;
+	/* exchange minimum element and i-th element */
+	tmp = distrow[min];
+	distrow[min] = distrow[i];
+	distrow[i] = tmp;
+	tmpI = indexrow[min];
+	indexrow[min] = indexrow[i];
+	indexrow[i] = tmpI;
+    }
+
+    /* copy n smallest values to row */
+    for (i = 0; i < n; i++) {
+	row[i] = indexrow[i];
+    }
+
+    /*fprintf(stderr, "\ndistrow =");
+       for(i = 0; i < n; i++)
+       fprintf(stderr, " %0.2f", distrow[i]);
+       fprintf(stderr, "\n"); */
+
+    G_free(distrow);
+}
+
+int get_max_index(int *array, int size)
+{
+    int i;
+    int max = 0;
+
+    if (size <= 0)
+	return -1;
+
+    for (i = 0; i < size; i++)
+	if (array[i] > array[max])
+	    max = i;
+
+    return max;
+}
+
+int get_nearest_indices(int count, int *num_array, int num_count)
+{
+    int i, j, tmp;
+    int max = 0;
+
+    /* get maximum number */
+    max = get_max_index(num_array, num_count);
+
+    patch_n = num_array[max] < count - 1 ? num_array[max] : count - 1;
+
+    //      fprintf(stderr, "\n%d nearest patches taken into account.\n\n", patch_n);
+
+    nearest_indices = (int *)G_malloc(count * patch_n * sizeof(int));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	/* display progress */
+	if (verbose)
+	    G_percent(i, count, 2);
+
+	get_smallest_n_indices(nearest_indices + i * patch_n, distmatrix,
+			       patch_n, count, i);
+
+	/*              fprintf(stderr, "\npatch %d:", i);
+	   for(j = 0; j < patch_n; j++)
+	   fprintf(stderr, " %d", nearest_indices[j + i * patch_n]);
+	   fprintf(stderr, "\n"); */
+
+    }
+
+    return 0;
+}
+
+int f_dist(DCELL * vals, int count, int *num_array, int num_count,
+	   f_statmethod statmethod)
+{
+    int n;
+    int i, j, index;
+
+    DCELL *distances = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    index = nearest_indices[i * patch_n + j];
+	    distances[j] = distmatrix[i * count + index];
+	}
+
+	/*              fprintf(stderr, "\ndistances for patch %d", i);
+	   for(j = 0; j < patch_n; j++)
+	   fprintf(stderr, " %0.2f", distances[j]); */
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(distances, n);
+	}
+    }
+
+    G_free(distances);
+    return 0;
+}
+
+int f_area(DCELL * vals, int count, int *num_array, int num_count,
+	   f_statmethod statmethod)
+{
+    int n;
+    int i, j, index;
+
+    DCELL *areas = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    index = nearest_indices[i * patch_n + j];
+	    areas[j] = (DCELL) (fragments[index + 1] - fragments[index]);
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(areas, n);
+	}
+    }
+
+    G_free(areas);
+    return 0;
+}
+
+int f_perim(DCELL * vals, int count, int *num_array, int num_count,
+	    f_statmethod statmethod)
+{
+    int n;
+    int i, j, index, border;
+    Coords *p;
+
+    DCELL *perims = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    border = 0;
+
+	    index = nearest_indices[i * patch_n + j];
+
+	    /* for all cells in a patch */
+	    for (p = fragments[index]; p < fragments[index + 1]; p++) {
+		border += 4 - p->neighbors;
+	    }
+	    perims[j] = (DCELL) (border);
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(perims, n);
+	}
+    }
+
+    G_free(perims);
+    return 0;
+}
+
+int f_shapeindex(DCELL * vals, int count, int *num_array, int num_count,
+		 f_statmethod statmethod)
+{
+    int n;
+    int i, j, index, border, area;
+    Coords *p;
+
+    DCELL *shapes = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < patch_n; j++) {
+	    border = 0;
+
+	    index = nearest_indices[i * patch_n + j];
+
+	    /* for all cells in a patch */
+	    for (p = fragments[index]; p < fragments[index + 1]; p++) {
+		border += 4 - p->neighbors;
+	    }
+	    area = (int)(fragments[index + 1] - fragments[index]);
+
+	    shapes[j] = (DCELL) border / (4 * sqrt((DCELL) area));
+	}
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(shapes, n);
+	}
+    }
+
+    G_free(shapes);
+    return 0;
+}
+
+int f_path_dist(DCELL * vals, int count, int *num_array, int num_count,
+		f_statmethod statmethod)
+{
+    int n;
+    int i, j, k, index;
+
+    DCELL *distances = (DCELL *) G_malloc(patch_n * sizeof(DCELL));
+    int *flags = (int *)G_malloc(count * sizeof(int));
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	// clear flags array
+	memset(flags, 0, count * sizeof(int));
+	int act_patch = i;
+
+	for (j = 0; j < patch_n; j++) {
+	    // get nearest patch for the act_patch
+	    // ignore those already marked in flags
+	    k = 0;
+	    do {
+		index = nearest_indices[act_patch * patch_n + k++];
+	    } while (flags[index] == 1);
+	    // mark current patch
+	    flags[act_patch] = 1;
+
+	    distances[j] = distmatrix[act_patch * count + index];
+	    act_patch = index;
+	}
+
+	/*              fprintf(stderr, "\ndistances for patch %d", i);
+	   for(j = 0; j < patch_n; j++)
+	   fprintf(stderr, " %0.2f", distances[j]); */
+
+	for (j = 0; j < num_count; j++) {
+	    n = num_array[j] < count - 1 ? num_array[j] : count - 1;
+	    vals[i + j * count] = statmethod(distances, n);
+	}
+    }
+
+    G_free(distances);
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/heap.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/heap.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/heap.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,87 @@
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include "local_proto.h"
+
+inline void exchange(int p1, int p2)
+{
+    Path_Coords tmp = heap[p1];
+
+    heap[p1] = heap[p2];
+    heap[p2] = tmp;
+}
+
+void upheap(int pos)
+{
+    int i = pos;
+
+    while (i > 0 && heap[i].f < heap[(i - 1) / 2].f) {
+	exchange(i, (i - 1) / 2);
+	i = (i - 1) / 2;
+    }
+}
+
+void downheap(int pos)
+{
+    int son = pos * 2 + 1;
+
+    // actual element has left son
+    if (son < heapsize) {
+	// actual element has right son, which is the smaller son
+	if (son + 1 < heapsize && heap[son + 1].f < heap[son].f)
+	    son++;
+	// son is now the smaller son
+	// if son smaller then actual element
+	if (heap[pos].f > heap[son].f) {
+	    exchange(pos, son);
+	    downheap(son);
+	}
+    }
+}
+
+void heap_alloc(int size)
+{
+    heap = (Path_Coords *) G_malloc(size * sizeof(Path_Coords));
+}
+
+void heap_free()
+{
+    G_free(heap);
+}
+
+Path_Coords heap_delete(int pos)
+{
+    Path_Coords res = heap[pos];
+
+    heap[pos] = heap[--heapsize];
+    if (pos > 0 && heap[pos].f < heap[(pos - 1) / 2].f)
+	upheap(pos);
+    else
+	downheap(pos);
+    return res;
+}
+
+void heap_insert(int x, int y, DCELL f, DCELL g)
+{
+    Path_Coords *pc = heap + heapsize;
+
+    /* heapsize++; look down */
+    pc->x = x;
+    pc->y = y;
+    pc->f = f;
+    pc->g = g;
+    upheap(heapsize++);
+}
+
+int heap_search(int x, int y)
+{
+    int i;
+
+    for (i = 0; i < heapsize; i++) {
+	Path_Coords *act = heap + i;
+
+	if (act->x == x && act->y == y)
+	    return i;
+    }
+    return -1;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/heap.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,81 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+    DCELL f, g;
+} Path_Coords;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef int (*f_func) (DCELL *, int, int *, int, f_statmethod);
+
+void writeFrag(int row, int col, int nbr_cnt);
+
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL value(DCELL * vals, int count);
+DCELL sum(DCELL * vals, int count);
+
+/* heap.c */
+void heap_alloc(int size);
+void heap_free();
+Path_Coords heap_delete(int pos);
+void heap_insert(int x, int y, DCELL f, DCELL g);
+void upheap(int pos);
+
+int get_dist_matrix(int count);
+
+int get_nearest_indices(int count, int *num_array, int num_count);
+
+int f_dist(DCELL *, int, int *, int, f_statmethod);
+int f_area(DCELL *, int, int *, int, f_statmethod);
+int f_perim(DCELL *, int, int *, int, f_statmethod);
+int f_shapeindex(DCELL *, int, int *, int, f_statmethod);
+int f_path_dist(DCELL *, int, int *, int, f_statmethod);
+
+int parseToken(int *res, int pos, char *token);
+
+/* matrix.c */
+int writeDistMatrixAndID(char *name, Coords ** frags, int count);
+int writeAdjacencyMatrix(char *name, Coords ** frags, int count, int *nns,
+			 int nn_count);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL Coords **fragments;
+GLOBAL int *flagbuf;
+GLOBAL Coords *actpos;
+GLOBAL int verbose;
+GLOBAL DCELL *distmatrix;
+GLOBAL int *nearest_indices;
+GLOBAL int patch_n;
+
+GLOBAL Path_Coords *heap;
+GLOBAL int heapsize;
+GLOBAL DCELL *costmap;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,450 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.fnn
+ * AUTHOR(S):    Elshad Shirinov, Martin Wegmann
+ * PURPOSE:      Analysis of n-th functional/ecological nearest neighbour
+ *                               distance and spatial attributes of nearest neighbour patches
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+int recur_test(int, int, int);
+
+struct menu
+{
+    f_func *method;
+    char *name;
+    char *text;
+};
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct menu menu[] = {
+    {f_dist, "distance", "distance to the patch"},
+    {f_path_dist, "path_distance", "path distance from patch to patch"},
+    {f_area, "area", "area of the patch"},
+    {f_perim, "perimeter", "perimeter of the patch"},
+    {f_shapeindex, "shapeindex", "shapeindex of the patch"},
+    {0, 0, 0}
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values"},
+    {variance, "variance", "variance of values"},
+    {std_deviat, "standard deviation", "standard deviation of values"},
+    {value, "value", "according value for the patch"},
+    {sum, "sum", "sum of values"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char *costname, *costmapset;
+    char fullname[GNAME_MAX];
+    char title[1024];
+
+    /* in and out file pointers */
+    int in_fd, in_cost;
+    int out_fd;
+    DCELL *result, res[30];
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+    struct Categories cats;
+
+    int statmethod;
+    int method;
+    int methods[GNAME_MAX];
+    f_func compute_values;
+    f_func compute_stat;
+
+    char *p;
+
+    /* neighbors count */
+    int neighb_count;
+
+    int row, col, i, j, m;
+    int method_count;
+    int readrow;
+    int keyval;
+    DCELL range = MAX_DOUBLE;
+
+    int n;
+    int copycolr;
+    struct Colors colr;
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *output;
+	struct Option *keyval, *method;
+	struct Option *number, *statmethod;
+	struct Option *dmout, *adj_matrix, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    DCELL *values;
+    Coords *cells;
+    int fragcount = 0;
+    int parseres[1024];
+    int number;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Determines patches of given value and performs "
+	  "a nearest-neighbor analysis.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = YES;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->description =
+	_("Name of existing raster file with path-cost information");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    p = parm.method->options = G_malloc(1024);
+    for (n = 0; menu[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, menu[n].name);
+    }
+    parm.method->multiple = YES;
+    parm.method->description = _("Operation to perform on fragments");
+
+    parm.number = G_define_option();
+    parm.number->key = "number";
+    parm.number->key_desc = "num[-num]";
+    parm.number->type = TYPE_STRING;
+    parm.number->required = YES;
+    parm.number->multiple = YES;
+    parm.number->description = _("Number of nearest neighbors to analyse");
+
+    parm.statmethod = G_define_option();
+    parm.statmethod->key = "statmethod";
+    parm.statmethod->type = TYPE_STRING;
+    parm.statmethod->required = YES;
+    p = parm.statmethod->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, statmethods[n].name);
+    }
+    parm.statmethod->description =
+	_("Statistical method to perform on the values");
+
+    parm.dmout = G_define_option();
+    parm.dmout->key = "dmout";
+    parm.dmout->type = TYPE_STRING;
+    parm.dmout->required = NO;
+    parm.dmout->gisprompt = "new,cell,raster";
+    parm.dmout->description =
+	_("Output name for distance matrix and id-map (performed if not empty)");
+
+    parm.adj_matrix = G_define_option();
+    parm.adj_matrix->key = "adj_matrix";
+    parm.adj_matrix->type = TYPE_STRING;
+    parm.adj_matrix->required = NO;
+    parm.adj_matrix->gisprompt = "new,cell,raster";
+    parm.adj_matrix->description =
+	_("Output name for adjacency matrix (performed if not empty)");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of costmap */
+    costname = parm.costmap->answer;
+
+    /* test costmap existance */
+    costmapset = G_find_cell2(costname, "");
+	if (costmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), costname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* open costmap file */
+	in_cost = G_open_cell_old(costname, costmapset);
+	if (in_cost < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), costname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* copy color table */
+    copycolr = (G_read_colors(oldname, oldmapset, &colr) > 0);
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get number of nearest neighbors to analyse */
+    for (i = 0, number = 0; parm.number->answers[i] != NULL; i++) {
+	number += parseToken(parseres, number, parm.number->answers[i]);
+    }
+    /*      sscanf(parm.number->answer, "%d", &number); */
+
+    /* scan all method answers */
+    method_count = 0;
+    while (parm.method->answers[method_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (p = menu[method].name); method++)
+	    if ((strcmp(p, parm.method->answers[method_count]) == 0))
+		break;
+	if (!p) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.method->key, parm.method->answers[method_count],
+		      parm.method->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	methods[method_count] = method;
+
+	method_count++;
+    }
+
+    /* get the statmethod */
+    for (statmethod = 0; (p = statmethods[statmethod].name); statmethod++)
+	if ((strcmp(p, parm.statmethod->answer) == 0))
+	    break;
+    if (!p) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.statmethod->key, parm.statmethod->answer,
+		  parm.statmethod->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* establish the stat routine */
+    compute_stat = statmethods[statmethod].method;
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    costmap = (DCELL *) G_malloc(nrows * ncols * sizeof(DCELL));
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    actpos = cells;
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    fragments[0] = cells;
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    result = G_allocate_d_raster_buf();
+
+    /* get title, initialize the category and stat info */
+    if (parm.title->answer)
+	strcpy(title, parm.title->answer);
+    else
+	sprintf(title, "Fragmentation of file: %s", oldname);
+
+    if (verbose = !flag.quiet->answer)
+	G_message("Loading patches...");
+
+    /* read costmap */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_cost, result, row);
+	for (col = 0; col < ncols; col++) {
+	    costmap[row * ncols + col] = result[col];
+	}
+    }
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+
+	if (verbose)
+	    G_percent(row, nrows, 2);
+    }
+
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+		writeFrag(row, col, neighb_count);
+		fragments[fragcount] = actpos;
+	    }
+	}
+    }
+    if (verbose)
+	G_percent(nrows, nrows, 2);
+
+    /* generate the distance matrix */
+    get_dist_matrix(fragcount);
+
+    /* replace 0 count with (all - 1) patches */
+    for (i = 0; i < number; i++) {
+	if (parseres[i] == 0)
+	    parseres[i] = fragcount - 1;
+    }
+
+    /* get indices of the nearest n patches (where n is the maximum number of patches to analyse) */
+    get_nearest_indices(fragcount, parseres, number);
+
+    /* for each method */
+    for (m = 0; m < method_count; m++) {
+
+	/* establish the newvalue routine */
+	compute_values = menu[methods[m]].method;
+
+	/* perform actual function on the patches */
+	if (verbose = !flag.quiet->answer)
+	    G_message("Performing operation %s ... ", menu[methods[m]].name);
+	values = (DCELL *) G_malloc(fragcount * number * sizeof(DCELL));
+	compute_values(values, fragcount, parseres, number, compute_stat);
+
+	if (verbose)
+	    G_percent(fragcount, fragcount, 2);
+
+	/* write output files */
+	if (verbose = !flag.quiet->answer)
+	    G_message("Writing output...");
+
+	/* for all requested patches */
+	for (j = 0; j < number; j++) {
+
+	    /* open the new cellfile */
+	    sprintf(fullname, "%s.ENN%d.%s", newname, parseres[j],
+		    menu[methods[m]].name);
+	    out_fd = G_open_raster_new(fullname, DCELL_TYPE);
+	    if (out_fd < 0)
+			G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+	    /* write data */
+	    for (row = 0; row < nrows; row++) {
+		G_set_d_null_value(result, ncols);
+
+		for (i = 0; i < fragcount; i++) {
+		    for (actpos = fragments[i]; actpos < fragments[i + 1];
+			 actpos++) {
+			if (actpos->y == row) {
+			    result[actpos->x] = values[i + j * fragcount];
+			}
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, result);
+
+		if (verbose)
+		    G_percent(row + nrows * j + nrows * number * m,
+			      nrows * number * method_count, 2);
+	    }
+
+	    G_close_cell(out_fd);
+	}
+
+    }				/* for each method */
+
+    if (verbose)
+	G_percent(100, 100, 2);
+
+    if (parm.dmout->answer) {
+	exitres =
+	    writeDistMatrixAndID(parm.dmout->answer, fragments, fragcount);
+    }
+
+    if (parm.adj_matrix->answer) {
+	exitres =
+	    writeAdjacencyMatrix(parm.adj_matrix->answer, fragments,
+				 fragcount, parseres, number);
+    }
+
+    G_close_cell(in_fd);
+
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+
+    G_free(distmatrix);
+    G_free(nearest_indices);
+
+    G_init_cats(0, title, &cats);
+    G_write_cats(newname, &cats);
+
+    if (copycolr)
+	G_write_colors(newname, newmapset, &colr);
+
+    exit(exitres);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/matrix.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/matrix.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/matrix.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,105 @@
+#include "local_proto.h"
+
+int writeDistMatrixAndID(char *name, Coords ** frags, int count)
+{
+    FILE *out_fp;
+    int res = 0;
+    char *mapset;
+    int out_fd;
+    int row, col, i;
+    DCELL *result;
+
+    /* allocate memory for result-row */
+    result = G_allocate_d_raster_buf();
+
+    /* open ASCII-file or use stdout */
+    if (!(out_fp = fopen(name, "w"))) {
+	fprintf(stderr, "Error creating file <%s>.", name);
+	res = 1;
+    }
+    else {
+	/* write distance matrix */
+	for (row = 0; row < count; row++) {
+	    for (col = 0; col < count; col++) {
+		fprintf(out_fp, "%f ", distmatrix[row * count + col]);
+	    }
+	    fprintf(out_fp, "\n");
+	}
+	fclose(out_fp);
+
+	/* check if the new file name is correct */
+    if (G_legal_filename(name) < 0) {
+	    G_warning(_("<%s> is an illegal file name"), name);
+	    res = 1;
+	}
+	mapset = G_mapset();
+
+	/* open the new cellfile */
+	out_fd = G_open_raster_new(name, DCELL_TYPE);
+	if (out_fd < 0) {
+	    char msg[200];
+
+	    sprintf(msg, "can't create new cell file <%s> in mapset %s\n",
+		    name, mapset);
+	    G_fatal_error(msg);
+	    res = 1;
+	}
+	else {
+	    /* write data */
+	    for (row = 0; row < nrows; row++) {
+		G_set_d_null_value(result, ncols);
+
+		for (i = 0; i < count; i++) {
+		    for (actpos = frags[i]; actpos < frags[i + 1]; actpos++) {
+			if (actpos->y == row) {
+			    result[actpos->x] = i;
+			}
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, result);
+	    }
+	}
+	G_close_cell(out_fd);
+    }
+
+    /* free memory */
+    G_free(result);
+
+    return res;
+}
+
+int writeAdjacencyMatrix(char *name, Coords ** frags, int count, int *nns,
+			 int nn_count)
+{
+    FILE *out_fp;
+    int row, col, i;
+    char fullname[GNAME_MAX];
+    int res = EXIT_SUCCESS;
+
+    /* open ASCII-file or use stdout */
+    for (i = 0; i < nn_count; i++) {
+	sprintf(fullname, "%s_%d", name, nns[i]);
+	if (!(out_fp = fopen(fullname, "w"))) {
+	    G_fatal_error("Error creating file <%s>.", name);
+	    res = EXIT_FAILURE;
+	}
+	else {
+	    /* write distance matrix */
+	    for (row = 0; row < count; row++) {
+		for (col = 0; col < count; col++) {
+		    if (nearest_indices[row * patch_n + nns[i] - 1] == col) {
+			fprintf(out_fp, "1 ");
+		    }
+		    else {
+			fprintf(out_fp, "0 ");
+		    }
+		}
+		fprintf(out_fp, "\n");
+	    }
+	    fclose(out_fp);
+	}
+    }
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/matrix.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.fnn/parser.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.fnn/parser.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.fnn/parser.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,69 @@
+#include "local_proto.h"
+
+int parseToken(int *res, int pos, char *token)
+{
+    char begin[GNAME_MAX];
+    char end[GNAME_MAX];
+    char *c, *tb, *te;
+    int i, count;
+
+    /* clear begin and end */
+    memset(begin, 0, GNAME_MAX);
+    memset(end, 0, GNAME_MAX);
+
+    c = token;
+    tb = begin;
+    while (*c != '-' && *c != 0) {
+	*tb = *c;
+	c++;
+	tb++;
+    }
+    G_strip(begin);
+
+    if (*c == 0) {
+	res[pos] = atoi(begin);
+	return 1;
+    }
+    c++;
+
+    te = end;
+    while (*c != 0) {
+	*te = *c;
+	c++;
+	te++;
+    }
+
+    G_strip(end);
+
+    for (i = atoi(begin), count = 0; i <= atoi(end); i++, count++) {
+	res[pos + count] = i;
+    }
+    return count;
+}
+
+int parseInput(int *res, char *input)
+{
+    char token[GNAME_MAX];
+    char *c, *t;
+    int actPos = 0;
+
+    c = input;
+    while (*c != 0) {
+	/* clear token */
+	memset(token, 0, GNAME_MAX);
+	t = token;
+
+
+	/* read token */
+	while (*c != ',' && *c != 0) {
+	    *t = *c;
+	    c++;
+	    t++;
+	}
+	c++;
+
+	actPos += parseToken(res, actPos, token);
+    }
+
+    return actPos;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.fnn/parser.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.graph
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.graph/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,53 @@
+<h2>DESCRIPTION</h2>
+
+Graph Theory for connectivity analysis. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset using class 5 (forest):
+
+Computing a graph of all patches (4 neighbourhood rule) using a maximum distance of 10 pixel, the Gabriel method and as resulting index the <em> largest patch diameter</em>:
+<div class="code"><pre>
+<b>r.pi.graph input=</b>landclass96 <b>output=</b>landclass96_graph <b>keyval=</b>5 <b>distance=</b>10 <b>neighborhood=</b>gabriel <b>index=</b>largest_patch_diameter
+</pre></div>
+
+the results are 2 files:
+landclass96_graph: the information of the index are provided (here a range of 3-589 of patch diameter)
+landclass96_graph_clusters: the generated cluster IDs are provided (here 16 clusters are identified), doing it with a distance of 5 pixel is resulting in a total of 66 cluster.
+
+
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.graph/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/draw.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/draw.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/draw.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,120 @@
+#include "local_proto.h"
+
+inline void swap(int *a, int *b)
+{
+    int zw = *a;
+
+    *a = *b;
+    *b = zw;
+}
+
+void draw_point(int *map, int val, int x, int y, int sx, int sy, int width)
+{
+    if (width <= 0) {
+	return;
+    }
+
+    if (width == 1) {
+	map[y * sx + x] = val;
+    }
+    else {
+    }
+}
+
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width)
+{
+    int steep = abs(y2 - y1) > abs(x2 - x1);
+
+    if (steep) {
+	swap(&x1, &y1);
+	swap(&x2, &y2);
+    }
+
+    if (x1 > x2) {
+	swap(&x1, &x2);
+	swap(&y1, &y2);
+    }
+
+    int deltax = x2 - x1;
+    int deltay = abs(y2 - y1);
+    int error = deltax / 2;
+    int ystep = y1 < y2 ? 1 : -1;
+    int x;
+    int y = y1;
+
+    for (x = x1; x <= x2; x++) {
+	if (steep) {
+	    draw_point(map, val, y, x, sx, sy, width);
+	}
+	else {
+	    draw_point(map, val, x, y, sx, sy, width);
+	}
+
+	error -= deltay;
+	if (error < 0) {
+	    y += ystep;
+	    error += deltax;
+	}
+    }
+}
+
+void flood_fill(int *map, int val, int x, int y, int sx, int sy)
+{
+    /* exit if the position is already set to this value */
+    if (map[y * sx + x] == val) {
+	return;
+    }
+
+    /* setup list of positions to fill */
+    Position *list = (Position *) G_malloc(sx * sy * sizeof(Position));
+    Position *begin = list;
+    Position *end = list + 1;
+
+    /* set first position */
+    begin->x = x;
+    begin->y = y;
+    map[y * sx + x] = val;
+
+    /* while there are still positions to fill do */
+    while (begin < end) {
+	if (end - list >= sx * sy) {
+	    G_message("fill list count: %d", end - list);
+	    break;
+	}
+
+	int cur_x = begin->x;
+	int cur_y = begin->y;
+
+	/* set all four neighbors on the list */
+	if (cur_x > 0 && map[cur_y * sx + cur_x - 1] != val) {
+	    map[cur_y * sx + cur_x - 1] = val;
+	    end->x = cur_x - 1;
+	    end->y = cur_y;
+	    end++;
+	}
+	if (cur_x < sx - 1 && map[cur_y * sx + cur_x + 1] != val) {
+	    map[cur_y * sx + cur_x + 1] = val;
+	    end->x = cur_x + 1;
+	    end->y = cur_y;
+	    end++;
+	}
+	if (cur_y > 0 && map[(cur_y - 1) * sx + cur_x] != val) {
+	    map[(cur_y - 1) * sx + cur_x] = val;
+	    end->x = cur_x;
+	    end->y = cur_y - 1;
+	    end++;
+	}
+	if (cur_y < sy - 1 && map[(cur_y + 1) * sx + cur_x] != val) {
+	    map[(cur_y + 1) * sx + cur_x] = val;
+	    end->x = cur_x;
+	    end->y = cur_y + 1;
+	    end++;
+	}
+
+	/* move to the next one */
+	begin++;
+    }
+
+    G_free(list);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph/draw.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,162 @@
+#include "local_proto.h"
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,676 @@
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL nearest_points(Coords ** frags, int n1, int n2, Coords * np1,
+		     Coords * np2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+			*np1 = *p1;
+			*np2 = *p2;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL min_dist_to_location(Coords ** frags, int patch, double loc_x,
+			   double loc_y)
+{
+    Coords *p;
+    DCELL min = MAX_DOUBLE;
+
+    // for all cells in the first patch
+    for (p = frags[patch]; p < frags[patch + 1]; p++) {
+	// if cell at the border
+	if (p->neighbors < 4) {
+	    DCELL dx = loc_x - p->x;
+	    DCELL dy = loc_y - p->y;
+	    DCELL d = sqrt(dx * dx + dy * dy);
+
+	    if (d < min) {
+		min = d;
+	    }
+	}
+    }
+    return min;
+}
+
+int get_dist_matrix()
+{
+    int i, j;
+
+    distmatrix = (DCELL *) G_malloc(fragcount * fragcount * sizeof(DCELL));
+
+    /* fill distance matrix */
+    for (i = 0; i < fragcount; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * fragcount + j] = d;
+	    distmatrix[j * fragcount + i] = d;
+	}
+    }
+
+    return 0;
+}
+
+int get_nearest_neighbor(int patch)
+{
+    int i;
+    int min = -1;
+    DCELL min_dist = MAX_DOUBLE;
+    int offset = patch * fragcount;
+
+    for (i = 0; i < fragcount; i++) {
+	if ((i != patch) && (distmatrix[offset + i] < min_dist)) {
+	    min_dist = distmatrix[offset + i];
+	    min = i;
+	}
+    }
+
+    return min;
+}
+
+int *FindCluster(int patch, int *curpos, int *flag_arr)
+{
+    int i;
+    int *p;
+    int list[fragcount];
+    int *first = list;
+    int *last = list + 1;
+    int offset;
+
+    list[0] = patch;
+    flag_arr[patch] = 1;
+
+    while (first < last) {
+	/* save patch */
+	*curpos = *first;
+	curpos++;
+
+	/* add unclassified neighbors to the list */
+	offset = *first * fragcount;
+	for (i = 0; i < fragcount; i++) {
+	    if (adjmatrix[offset + i] == 1 && flag_arr[i] == 0) {
+		flag_arr[i] = 1;
+		*last = i;
+		last++;
+	    }
+	}
+
+	/* pass processed patch */
+	first++;
+
+	/* fprintf(stderr, "list:");
+	   for(p = first; p < last; p++) {
+	   fprintf(stderr, " %d", *p);
+	   }
+	   fprintf(stderr, "\n");   */
+    }
+
+    return curpos;
+}
+
+void FindClusters()
+{
+    int i;
+
+    clusters[0] = patches;
+    clustercount = 0;
+
+    int flag_arr[fragcount];
+
+    memset(flag_arr, 0, fragcount * sizeof(int));
+
+    for (i = 0; i < fragcount; i++) {
+	if (flag_arr[i] == 0) {
+	    clustercount++;
+	    clusters[clustercount] =
+		FindCluster(i, clusters[clustercount - 1], flag_arr);
+	}
+    }
+}
+
+void f_nearest_neighbor(DCELL max_dist)
+{
+    int i;
+
+    for (i = 0; i < fragcount; i++) {
+	int nn = get_nearest_neighbor(i);
+
+	if (nn > -1 && distmatrix[i * fragcount + nn] < max_dist) {
+	    adjmatrix[i * fragcount + nn] = 1;
+	    adjmatrix[nn * fragcount + i] = 1;
+	}
+    }
+}
+
+void f_relative_neighbor(DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjmatrix[i * fragcount + j] = 1;
+	    adjmatrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the central lens between i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if (dist1 < dist && dist2 < dist) {
+		    /* i-th and j-th patches are not connected */
+		    adjmatrix[i * fragcount + j] = 0;
+		    adjmatrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_gabriel(DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjmatrix[i * fragcount + j] = 1;
+	    adjmatrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the circle around i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if ((dist1 * dist1 + dist2 * dist2) < (dist * dist)) {
+		    /* i-th and j-th patches are not connected */
+		    adjmatrix[i * fragcount + j] = 0;
+		    adjmatrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_spanning_tree(DCELL max_dist)
+{
+    int i, j;
+    int parents[fragcount];
+    DCELL distances[fragcount];
+    int curmin;
+    int nextmin = 0;
+    int parent;
+
+    /* init parents and distances list */
+    for (i = 0; i < fragcount; i++) {
+	parents[i] = -1;
+	distances[i] = MAX_DOUBLE;
+    }
+
+    /* repeat fragcount times */
+    for (i = 0; i < fragcount; i++) {
+	/* pass on next minimum node */
+	curmin = nextmin;
+	nextmin = 0;
+
+	/* connect current minimum node with its parent and set distance to 0    */
+	/* connect only if parent is assigned and distance is less than max_dist */
+	if ((parent = parents[curmin]) != -1 &&
+	    distmatrix[parent * fragcount + curmin] < max_dist) {
+	    adjmatrix[curmin * fragcount + parent] = 1;
+	    adjmatrix[parent * fragcount + curmin] = 1;
+	}
+	distances[curmin] = 0.0;
+
+	/* debug output */
+	/*G_message("New patch: %d, connecting to patch %d", curmin, parents[curmin]); */
+
+	/* find the next node for minimum spanning tree */
+	for (j = 0; j < fragcount; j++) {
+	    /* skip the current minimum node */
+	    if (j == curmin)
+		continue;
+
+	    /* get distance to the current minimum node */
+	    DCELL dist = distmatrix[curmin * fragcount + j];
+
+	    /* if this distance is smaller than the stored one */
+	    /* then set a new distance and update parent list  */
+	    if (dist < distances[j]) {
+		distances[j] = dist;
+		parents[j] = curmin;
+	    }
+
+	    /* update the next minimum node */
+	    if (distances[nextmin] == 0 ||
+		(distances[j] > 0 && distances[j] < distances[nextmin])) {
+		nextmin = j;
+	    }
+	}
+
+	/* debug output */
+	/*G_message("parent list:");
+	   for(j = 0; j < fragcount; j++) {
+	   fprintf(stderr, "%d ", parents[j]);
+	   }
+	   fprintf(stderr, "\n");
+	   G_message("distance list:");
+	   for(j = 0; j < fragcount; j++) {
+	   fprintf(stderr, "%0.2f ", distances[j]);
+	   }
+	   fprintf(stderr, "\n"); */
+    }
+}
+
+void f_connectance_index(DCELL * values)
+{
+    int i;
+    int *p, *q;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int n = clusters[i + 1] - clusters[i];
+	DCELL c = 100.0 / (n * (n - 1) * 0.5);
+	DCELL val = 0;
+
+	/* single patch is 100% connected */
+	if (n == 1) {
+	    values[i] = 100.0;
+	    continue;
+	}
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1] - 1; p++) {
+	    for (q = p + 1; q < clusters[i + 1]; q++) {
+		if (adjmatrix[*p * fragcount + *q] == 1) {
+		    val++;
+		}
+	    }
+	}
+
+	values[i] = 100.0 * val / (n * (n - 1) * 0.5);
+    }
+}
+
+void f_gyration_radius(DCELL * values)
+{
+    int i;
+    int *p, *q;
+
+    Coords *cell;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int n = clusters[i + 1] - clusters[i];
+	double avg_x = 0.0;
+	double avg_y = 0.0;
+	int count = 0;
+	DCELL val = 0.0;
+
+	/* calculate cluster centroid */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    for (cell = fragments[*p]; cell < fragments[*p + 1]; cell++) {
+		avg_x += cell->x;
+		avg_y += cell->y;
+		count++;
+	    }
+	}
+	avg_x /= (double)count;
+	avg_y /= (double)count;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    val += min_dist_to_location(fragments, *p, avg_x, avg_y);
+	}
+
+	values[i] = val / (double)n;
+    }
+}
+
+void f_cohesion_index(DCELL * values)
+{
+    int i;
+    int *p, *q;
+    Coords *cell;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int n = clusters[i + 1] - clusters[i];
+	int total_area = 0;
+	DCELL num = 0.0;
+	DCELL denom = 0.0;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    int perim = 0;
+	    int area = fragments[*p + 1] - fragments[*p];
+
+	    /* find perimeter */
+	    for (cell = fragments[*p]; cell < fragments[*p + 1]; cell++) {
+		/* if cell is on the edge */
+		if (cell->neighbors < 4) {
+		    perim++;
+		}
+	    }
+
+	    /* update total number of cells in the cluster */
+	    total_area += area;
+
+	    num += (double)perim;
+	    denom += (double)perim *sqrt((double)area);
+	}
+
+	values[i] =
+	    (1.0 - num / denom) / (1.0 -
+				   1.0 / sqrt((double)total_area)) * 100.0;
+    }
+}
+
+void f_percent_patches(DCELL * values)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int patch_count = clusters[i + 1] - clusters[i];
+
+	values[i] = (DCELL) patch_count / (DCELL) fragcount *100.0;
+    }
+}
+
+void f_percent_area(DCELL * values)
+{
+    int i;
+    int *p, *q;
+    Coords *cell;
+
+    int area_all = fragments[fragcount] - fragments[0];
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    area_cluster += fragments[*p + 1] - fragments[*p];
+	}
+
+	values[i] = (DCELL) area_cluster / (DCELL) area_all *100.0;
+    }
+}
+
+void f_number_patches(DCELL * values)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	values[i] = (DCELL) (clusters[i + 1] - clusters[i]);
+    }
+}
+
+void f_number_links(DCELL * values)
+{
+    int i;
+    int *p, *q;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int links = 0;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    /* for each other patch in the cluster */
+	    for (q = p + 1; q < clusters[i + 1]; q++) {
+		if (adjmatrix[*q * fragcount + *p] == 1) {
+		    links++;
+		}
+	    }
+	}
+
+	values[i] = (DCELL) links;
+    }
+}
+
+void f_mean_patch_size(DCELL * values)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int patch_count = clusters[i + 1] - clusters[i];
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    area_cluster += fragments[*p + 1] - fragments[*p];
+	}
+
+	values[i] = (DCELL) area_cluster / (DCELL) patch_count;
+    }
+}
+
+void f_largest_patch_size(DCELL * values)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	int max_area = 0;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    int area = fragments[*p + 1] - fragments[*p];
+
+	    if (area > max_area) {
+		max_area = area;
+	    }
+	}
+
+	values[i] = (DCELL) max_area;
+    }
+}
+
+DCELL get_diameter(Coords ** frags, int n)
+{
+    Coords *p1, *p2;
+    DCELL max = 0.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n]; p1 < frags[n + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = p1 + 1; p2 < frags[n + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d > max) {
+			max = d;
+		    }
+		}
+	    }
+	}
+    }
+    return max;
+}
+
+void f_largest_patch_diameter(DCELL * values)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	DCELL max_diameter = 0;
+
+	/* for each patch in the cluster */
+	for (p = clusters[i]; p < clusters[i + 1]; p++) {
+	    DCELL diameter = get_diameter(fragments, *p);
+
+	    if (diameter > max_diameter) {
+		max_diameter = diameter;
+	    }
+	}
+
+	values[i] = max_diameter;
+    }
+}
+
+/* implements floyd-warshall algorithm for finding shortest pathes */
+void f_graph_diameter_max(DCELL * values)
+{
+    int i, j, k;
+
+    /* initialize path matrix */
+    DCELL pathmatrix[fragcount * fragcount * sizeof(DCELL)];
+
+    for (i = 0; i < fragcount; i++) {
+	pathmatrix[i * fragcount + i] = 0.0;
+
+	int j;
+
+	for (j = i + 1; j < fragcount; j++) {
+	    int index = i * fragcount + j;
+	    int index_mirror = j * fragcount + i;
+
+	    if (adjmatrix[index]) {
+		pathmatrix[index] = pathmatrix[index_mirror] =
+		    distmatrix[index];
+	    }
+	    else {
+		pathmatrix[index] = pathmatrix[index_mirror] = MAX_DOUBLE;
+	    }
+	}
+    }
+
+    /* for each patch */
+    for (k = 0; k < fragcount; k++) {
+	/* for every other patch */
+	for (i = 0; i < fragcount; i++) {
+	    /* for every third patch */
+	    for (j = 0; j < fragcount; j++) {
+		/* get direct path and detour over p3 */
+		DCELL direct = pathmatrix[i * fragcount + j];
+		DCELL indirect =
+		    pathmatrix[i * fragcount + k] + pathmatrix[k * fragcount +
+							       j];
+
+		/* if detour is shorter */
+		if (indirect < direct) {
+		    pathmatrix[i * fragcount + j] = indirect;
+		}
+	    }
+	}
+    }
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	/* search for the maximum distance between two patches in this cluster */
+	DCELL max_dist = 0.0;
+	int *patch;
+
+	for (patch = clusters[i]; patch < clusters[i + 1]; patch++) {
+	    int *other_patch;
+
+	    for (other_patch = patch + 1; other_patch < clusters[i + 1];
+		 other_patch++) {
+		DCELL dist = pathmatrix[*patch * fragcount + *other_patch];
+
+		if (dist > max_dist) {
+		    max_dist = dist;
+		}
+	    }
+	}
+
+	values[i] = max_dist;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/hull.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/hull.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/hull.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,211 @@
+#include "local_proto.h"
+
+int is_less(Position p1, Position p2, Position ref)
+{
+    int dx1 = p1.x - ref.x;
+    int dy1 = p1.y - ref.y;
+    int dx2 = p2.x - ref.x;
+    int dy2 = p2.y - ref.y;
+
+    int cross = dx1 * dy2 - dx2 * dy1;
+
+    return cross > 0 || cross == 0 &&
+	(abs(dx1) + abs(dy1)) > (abs(dx2) + abs(dy2));
+}
+
+int concave(Position p1, Position p2, Position p3)
+{
+    int dx1 = p2.x - p1.x;
+    int dx2 = p3.x - p1.x;
+    int dy1 = p2.y - p1.y;
+    int dy2 = p3.y - p1.y;
+    int cross = dx1 * dy2 - dx2 * dy1;
+
+    return cross < 0;
+}
+
+/* quicksort */
+void sort_vertices(Position * list, int begin, int end, Position ref)
+{
+    if (begin >= end)
+	return;
+
+    int b = begin + 1;
+    int e = end;
+    Position piv = list[begin];
+
+    //G_message("begin=(%d,%d), end=(%d,%d), piv=(%d,%d), ref=(%d,%d)", list[b].x, list[b].y, list[e].x, list[e].y, piv.x, piv.y, ref.x, ref.y);
+
+    while (b <= e) {
+	//G_message("begin=%d, end=%d, piv=(%d,%d), ref=(%d,%d)", b, e, piv.x, piv.y, ref.x, ref.y);
+
+	//G_message("is_less(%d, %d) = %d", list[b].x, list[b].y, is_less(list[b], piv, ref));
+	while (is_less(list[b], piv, ref)) {
+	    b++;
+	}
+	//G_message("is_bigger(%d, %d) = %d", list[e].x, list[e].y, is_less(piv, list[e], ref));
+	while (is_less(piv, list[e], ref)) {
+	    e--;
+	}
+	if (b <= e) {
+	    //G_message("swap %d with %d", b, e);
+
+	    Position tmp = list[b];
+
+	    list[b] = list[e];
+	    list[e] = tmp;
+	}
+    }
+
+    /* put piveau element to its place */
+    //G_message("swap %d with %d", begin, e);
+    Position tmp = list[begin];
+
+    list[begin] = list[e];
+    list[e] = tmp;
+
+    if (begin < e)
+	sort_vertices(list, begin, e - 1, ref);
+    if (b < end)
+	sort_vertices(list, b, end, ref);
+}
+
+void convex_hull_cluster(int *map, int cluster)
+{
+    int i;
+    int *p;
+    int area = 0;
+
+    /* calculate sum of the patch areas */
+    for (p = clusters[cluster]; p < clusters[cluster + 1]; p++) {
+	area += fragments[*p + 1] - fragments[*p];
+    }
+
+    //G_message("Cluster%d area = %d", cluster, area);
+
+    /* allocate memory for the vertex list */
+    Position *vertices = (Position *) G_malloc((area + 1) * sizeof(Position));
+
+    /* fill vertex list */
+    int vertexcount = 0;
+
+    /* for each patch in the cluster */
+    for (p = clusters[cluster]; p < clusters[cluster + 1]; p++) {
+	//G_message("Analyzing Patch%d", *p);
+
+	Coords *c;
+
+	/* for each cell in the patch */
+	for (c = fragments[*p]; c < fragments[*p + 1]; c++) {
+	    /* write border cells to the list */
+	    if (c->neighbors < 4) {
+		vertices[vertexcount].x = c->x;
+		vertices[vertexcount].y = c->y;
+		vertexcount++;
+	    }
+	}
+    }
+
+    /* skip hull building for 1-cell-patches */
+    if (vertexcount > 1) {
+	/* find the top-left cell */
+	int min = 0;
+
+	for (i = 0; i < vertexcount; i++) {
+	    if (vertices[i].y < vertices[min].y ||
+		(vertices[i].y == vertices[min].y &&
+		 vertices[i].x < vertices[min].x)) {
+		min = i;
+	    }
+	}
+
+	/* put min at the first position */
+	Position tmp = vertices[0];
+
+	vertices[0] = vertices[min];
+	vertices[min] = tmp;
+
+	/*G_message("Vertex list:");
+	   for(i = 0; i < vertexcount; i++) {
+	   fprintf(stderr, " (%d,%d)", vertices[i].x, vertices[i].y);
+	   }
+	   fprintf(stderr, "\n"); */
+
+	/* sort cells by the polar angle with the top-left cell */
+	sort_vertices(vertices, 1, vertexcount - 1, vertices[0]);
+
+	/* copy min to the last position */
+	//vertices[vertexcount] = vertices[0];
+	//vertexcount++;
+
+	/*G_message("Vertex list:");
+	   for(i = 0; i < vertexcount; i++) {
+	   fprintf(stderr, " (%d,%d)", vertices[i].x, vertices[i].y);
+	   }
+	   fprintf(stderr, "\n"); */
+
+	/* process points and bridge concave angles */
+	/* first h cells of the result are the hull cells */
+	i = 2;
+	int k;
+
+	for (k = 2; k < vertexcount; k++, i++) {
+	    /* swap cells i and k */
+	    tmp = vertices[i];
+	    vertices[i] = vertices[k];
+	    vertices[k] = tmp;
+
+	    /* while next angle is concave */
+	    while (concave(vertices[i - 2], vertices[i - 1], vertices[i])) {
+		/* swap cells i-1 and i */
+		tmp = vertices[i - 1];
+		vertices[i - 1] = vertices[i];
+		vertices[i] = tmp;
+
+		/* bridge concave angle */
+		i--;
+	    }
+	}
+
+	vertexcount = i;
+    }
+
+    /*G_message("Vertex list:");
+       for(i = 0; i < vertexcount; i++) {
+       fprintf(stderr, " (%d,%d)", vertices[i].x, vertices[i].y);
+       }
+       fprintf(stderr, "\n"); */
+
+    Position centroid = { 0, 0 };
+    for (i = 0; i < vertexcount; i++) {
+	Position p1 = vertices[i];
+	Position p2 = vertices[(i + 1) % vertexcount];
+
+	/* calculate centroid */
+	centroid.x += p1.x;
+	centroid.y += p1.y;
+
+	/* draw borders */
+	draw_line(map, 1, p1.x, p1.y, p2.x, p2.y, ncols, nrows, 1);
+    }
+
+    /* finish calculating centroid and fill the hull */
+    centroid.x = (int)((double)centroid.x / (double)vertexcount);
+    centroid.y = (int)((double)centroid.y / (double)vertexcount);
+
+    G_message("Centroid is at (%d, %d)", centroid.x, centroid.y);
+    flood_fill(map, 1, centroid.x, centroid.y, ncols, nrows);
+    G_message("finished");
+
+    /* free memory */
+    G_free(vertices);
+}
+
+void convex_hull(int *map)
+{
+    int cluster;
+
+    for (cluster = 0; cluster < clustercount; cluster++) {
+	convex_hull_cluster(map, cluster);
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph/hull.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,78 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+typedef void (*f_neighborhood) (DCELL max_dist);
+typedef void (*f_index) ();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* func.c */
+int get_dist_matrix();
+void f_nearest_neighbor(DCELL max_dist);
+void f_relative_neighbor(DCELL max_dist);
+void f_gabriel(DCELL max_dist);
+void f_spanning_tree(DCELL max_dist);
+
+void f_connectance_index(DCELL * values);
+void f_gyration_radius(DCELL * values);
+void f_cohesion_index(DCELL * values);
+void f_percent_patches(DCELL * values);
+void f_percent_area(DCELL * values);
+void f_number_patches(DCELL * values);
+void f_number_links(DCELL * values);
+void f_mean_patch_size(DCELL * values);
+void f_largest_patch_size(DCELL * values);
+void f_largest_patch_diameter(DCELL * values);
+void f_graph_diameter_max(DCELL * values);
+
+void FindClusters();
+
+DCELL nearest_points(Coords ** frags, int n1, int n2, Coords * np1,
+		     Coords * np2);
+
+/* draw.c */
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width);
+void flood_fill(int *map, int val, int x, int y, int sx, int sy);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL Coords *cells;
+GLOBAL Coords **fragments;
+GLOBAL int fragcount;
+GLOBAL int *flagbuf;
+GLOBAL DCELL *distmatrix;
+GLOBAL int *adjmatrix;
+GLOBAL int *patches;
+GLOBAL int **clusters;
+GLOBAL int clustercount;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.graph/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,466 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.graph
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Graph Theory approach for connectivity analysis on patch level
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct neighborhood
+{
+    f_neighborhood *method;	/* routine to build adjacency matrix */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct index
+{
+    f_index *method;		/* routine to calculate cluster index */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct neighborhood neighborhoods[] = {
+    {f_nearest_neighbor, "nearest_neighbor",
+     "patches are connected with their nearest neighbors"},
+    {f_relative_neighbor, "relative_neighbor",
+     "two patches are connected, if no other patch lies in the central lens between them"},
+    {f_gabriel, "gabriel",
+     "two patches are connected, if no other patch lies in the circle on them"},
+    {f_spanning_tree, "spanning_tree",
+     "two patches are connected, if they are neighbors in the minimum spanning tree"},
+    {0, 0, 0}
+};
+
+static struct index indices[] = {
+    {f_connectance_index, "connectance_index", "connectance index"},
+    {f_gyration_radius, "gyration_radius", "radius of gyration"},
+    {f_cohesion_index, "cohesion_index", "cohesion index"},
+    {f_percent_patches, "percent_patches",
+     "percentage of the patches in the cluster"},
+    {f_percent_area, "percent_area",
+     "percentage of the patch area in the cluster"},
+    {f_number_patches, "number_patches", "number of patches in the cluster"},
+    {f_number_links, "number_links", "number of links in the cluster"},
+    {f_mean_patch_size, "mean_patch_size", "mean patch size in the cluster"},
+    {f_largest_patch_size, "largest_patch_size",
+     "largest patch size in the cluster"},
+    {f_largest_patch_diameter, "largest_patch_diameter",
+     "largest patch diameter in the cluster"},
+    {f_graph_diameter_max, "graph_diameter",
+     "longest minimal path in the cluster"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+
+    /* parameters */
+    int keyval;
+    int nbr_count;
+    int index;
+    int neighborhood;
+    DCELL distance;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    char *p;
+    int row, col, i, j, m;
+    int n;
+    f_neighborhood build_graph;
+    f_index calc_index;
+    int *curpos;
+    DCELL *values;
+    CELL *result;
+    DCELL *d_res;
+    CELL *clustermap;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output;
+	struct Option *keyval, *distance;
+	struct Option *neighborhood, *index;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Graph Theory for connectivity analysis.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_option();
+    parm.output->key = "output";
+    parm.output->type = TYPE_STRING;
+    parm.output->required = YES;
+    parm.output->gisprompt = "new,cell,raster";
+    parm.output->description = _("Name of the new raster file");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.distance = G_define_option();
+    parm.distance->key = "distance";
+    parm.distance->type = TYPE_DOUBLE;
+    parm.distance->required = YES;
+    parm.distance->description =
+	_("Bounding distance [0 for maximum distance]");
+
+    parm.neighborhood = G_define_option();
+    parm.neighborhood->key = "neighborhood";
+    parm.neighborhood->type = TYPE_STRING;
+    parm.neighborhood->required = YES;
+    p = parm.neighborhood->options = G_malloc(1024);
+    for (n = 0; neighborhoods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, neighborhoods[n].name);
+    }
+    parm.neighborhood->description = _("Neighborhood definition");
+
+    parm.index = G_define_option();
+    parm.index->key = "index";
+    parm.index->type = TYPE_STRING;
+    parm.index->required = YES;
+    p = parm.index->options = G_malloc(1024);
+    for (n = 0; indices[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, indices[n].name);
+    }
+    parm.index->description = _("Cluster index");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get distance */
+    sscanf(parm.distance->answer, "%lf", &distance);
+    if (distance == 0.0) {
+	distance = MAX_DOUBLE;
+    }
+
+    /* get neighborhood definition */
+    for (neighborhood = 0; (p = neighborhoods[neighborhood].name);
+	 neighborhood++) {
+	if ((strcmp(p, parm.neighborhood->answer) == 0))
+	    break;
+    }
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.neighborhood->key,
+		      parm.neighborhood->answer, parm.neighborhood->key);
+	exit(EXIT_FAILURE);
+    }
+
+    /* get the cluster index */
+    for (index = 0; (p = indices[index].name); index++)
+	if ((strcmp(p, parm.index->answer) == 0))
+	    break;
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.index->key,
+		      parm.index->answer, parm.index->key);
+    }
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    fragments[0] = cells;
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    result = G_allocate_c_raster_buf();
+
+    G_message("Loading patches...");
+
+    /* read map */
+    for (row = 0; row < nrows; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /*G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%d", flagbuf[row * ncols + col]);           
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find fragments */
+    writeFragments(flagbuf, nrows, ncols, nbr_count);
+
+    /* allocate distance matrix */
+    distmatrix = (DCELL *) G_malloc(fragcount * fragcount * sizeof(DCELL));
+    memset(distmatrix, 0, fragcount * fragcount * sizeof(DCELL));
+
+    /* generate the distance matrix */
+    get_dist_matrix(fragcount);
+
+    /* G_message("Distance matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%0.2f ", distmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* build adjacency matrix */
+    adjmatrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+    memset(adjmatrix, 0, fragcount * fragcount * sizeof(int));
+
+    build_graph = neighborhoods[neighborhood].method;
+    build_graph(distance);
+
+    /* G_message("Adjacency matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%d", adjmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find clusters */
+    patches = (int *)G_malloc(fragcount * sizeof(int));
+    clusters = (int **)G_malloc((fragcount + 1) * sizeof(int *));
+
+    FindClusters();
+
+    /*for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, "Cluster_%d:", i);
+       for(curpos = clusters[i]; curpos < clusters[i + 1]; curpos++) {
+       fprintf(stderr, " %d", *curpos);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    values = (DCELL *) G_malloc(clustercount * sizeof(DCELL));
+
+    calc_index = indices[index].method;
+    calc_index(values);
+
+    /*      fprintf(stderr, "Results:");
+       for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, " %0.2f", values[i]);
+       }
+       fprintf(stderr, "\n"); */
+
+    /* write output */
+    G_message("Writing output...");
+
+    /* ================================== 
+       ============  output  ============ 
+       ================================== */
+
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* allocate result row variable */
+    d_res = G_allocate_d_raster_buf();
+
+    /* write values */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(d_res, ncols);
+
+	for (i = 0; i < clustercount; i++) {
+	    for (curpos = clusters[i]; curpos < clusters[i + 1]; curpos++) {
+		Coords *cell;
+
+		for (cell = fragments[*curpos]; cell < fragments[*curpos + 1];
+		     cell++) {
+		    if (cell->y == row) {
+			d_res[cell->x] = values[i];
+		    }
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(row + 1, 2 * nrows, 1);
+    }
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+    /* ================================== 
+       ==========  cluster map  ========= 
+       ================================== */
+
+    /* open the new cellfile  */
+    sprintf(fullname, "%s_clusters", newname);
+    out_fd = G_open_raster_new(fullname, CELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* allocate and initialize the clustermap */
+    clustermap = (CELL *) G_malloc(nrows * ncols * sizeof(CELL));
+    G_set_c_null_value(clustermap, nrows * ncols);
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	/* for each patch in the cluster */
+	int *this;
+
+	for (this = clusters[i]; this < clusters[i + 1]; this++) {
+	    /* for each cell in the patch */
+	    Coords *cell;
+
+	    for (cell = fragments[*this]; cell < fragments[*this + 1]; cell++) {
+		clustermap[cell->y * ncols + cell->x] = i;
+	    }
+
+	    /* for each patch in the cluster */
+	    int *other;
+
+	    for (other = clusters[i]; other < clusters[i + 1]; other++) {
+		if (*other != *this && adjmatrix[*this * fragcount + *other]) {
+		    Coords np1, np2;
+
+		    nearest_points(fragments, *this, *other, &np1, &np2);
+
+		    draw_line(clustermap, -1, np1.x, np1.y, np2.x, np2.y,
+			      ncols, nrows, 1);
+		}
+	    }
+	}
+    }
+
+    /* write output */
+    for (row = 0; row < nrows; row++) {
+	G_put_c_raster_row(out_fd, clustermap + row * ncols);
+
+	G_percent(nrows + row + 1, 2 * nrows, 1);
+    }
+
+    /* G_free(clustermap); */
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+    /* ================================== 
+       ==========  convex hull  ========= 
+       ================================== */
+
+    /* open the new cellfile  */
+    sprintf(fullname, "%s_hull", newname);
+    out_fd = G_open_raster_new(fullname, CELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* clear the clustermap */
+    G_set_c_null_value(clustermap, nrows * ncols);
+
+    /* calculate the convex hull */
+    convex_hull();
+
+    /* write output */
+    for (row = 0; row < nrows; row++) {
+	G_put_c_raster_row(out_fd, clustermap + row * ncols);
+
+	G_percent(nrows + row + 1, 2 * nrows, 1);
+    }
+
+    G_free(clustermap);
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+    /* =====================
+       ==== free memory ====
+       ===================== */
+    G_free(values);
+    G_free(patches);
+    G_free(clusters);
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+    G_free(result);
+    G_free(d_res);
+
+    G_free(distmatrix);
+    G_free(adjmatrix);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.graph.dec
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/choice.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/choice.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/choice.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,204 @@
+#include "local_proto.h"
+
+int f_smallest_first(int cluster_index,
+		     Cluster * cluster_list,
+		     int cluster_count,
+		     int *adjacency_matrix,
+		     Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int min_area = MAX_INT;
+    int min_index = -1;
+
+    int begin = cluster_index >= 0 ? cluster_index : 0;
+    int end = cluster_index >= 0 ? cluster_index : cluster_count - 1;
+    int c;
+
+    for (c = begin; c <= end; c++) {
+	Cluster cluster = cluster_list[c];
+
+	for (i = 0; i < cluster.count; i++) {
+	    int patch_index = cluster.first_patch[i];
+
+	    int area = fragments[patch_index].count;
+
+	    if (area < min_area) {
+		min_area = area;
+		min_index = i;
+
+		if (cluster_index < 0) {
+		    min_index = cluster.first_patch[min_index];
+		}
+	    }
+	}
+    }
+
+    return min_index;
+}
+
+int f_biggest_first(int cluster_index,
+		    Cluster * cluster_list,
+		    int cluster_count,
+		    int *adjacency_matrix,
+		    Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int max_area = -1;
+    int max_index = -1;
+
+    int begin = cluster_index >= 0 ? cluster_index : 0;
+    int end = cluster_index >= 0 ? cluster_index : cluster_count - 1;
+    int c;
+
+    for (c = begin; c <= end; c++) {
+	Cluster cluster = cluster_list[c];
+
+	for (i = 0; i < cluster.count; i++) {
+	    int patch_index = cluster.first_patch[i];
+
+	    int area = fragments[patch_index].count;
+
+	    if (area > max_area) {
+		max_area = area;
+		max_index = i;
+
+		if (cluster_index < 0) {
+		    max_index = cluster.first_patch[max_index];
+		}
+	    }
+	}
+    }
+
+    return max_index;
+}
+
+int f_random(int cluster_index,
+	     Cluster * cluster_list,
+	     int cluster_count,
+	     int *adjacency_matrix,
+	     Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+
+    int begin = cluster_index >= 0 ? cluster_index : 0;
+    int end = cluster_index >= 0 ? cluster_index : cluster_count - 1;
+
+    int patchcount = 0;
+    int c;
+
+    for (c = begin; c <= end; c++) {
+	Cluster cluster = cluster_list[c];
+
+	patchcount += cluster.count;
+    }
+
+    int r = rand() % patchcount;
+
+    for (c = begin; c <= end; c++) {
+	Cluster cluster = cluster_list[c];
+
+	int i;
+
+	for (i = 0; i < cluster.count; i++) {
+	    if (r == 0) {
+		if (cluster_index < 0) {
+		    return cluster.first_patch[i];
+		}
+		else {
+		    return i;
+		}
+	    }
+
+	    r--;
+	}
+    }
+
+    return -1;
+}
+
+int f_link_min(int cluster_index,
+	       Cluster * cluster_list,
+	       int cluster_count,
+	       int *adjacency_matrix,
+	       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int min_links = MAX_INT;
+    int min_index = -1;
+
+    int begin = cluster_index >= 0 ? cluster_index : 0;
+    int end = cluster_index >= 0 ? cluster_index : cluster_count - 1;
+    int c;
+
+    for (c = begin; c <= end; c++) {
+	Cluster cluster = cluster_list[c];
+
+	int i;
+
+	for (i = 0; i < cluster.count; i++) {
+	    int patch_index = cluster.first_patch[i];
+
+	    int links = 0;
+	    int j;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (adjacency_matrix[patch_index * fragcount + j]) {
+		    links++;
+		}
+	    }
+
+	    if (links < min_links) {
+		min_links = links;
+		min_index = i;
+
+		if (cluster_index < 0) {
+		    min_index = cluster.first_patch[min_index];
+		}
+	    }
+	}
+    }
+
+    return min_index;
+}
+
+int f_link_max(int cluster_index,
+	       Cluster * cluster_list,
+	       int cluster_count,
+	       int *adjacency_matrix,
+	       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int max_links = -1;
+    int max_index = -1;
+
+    int begin = cluster_index >= 0 ? cluster_index : 0;
+    int end = cluster_index >= 0 ? cluster_index : cluster_count - 1;
+    int c;
+
+    for (c = begin; c <= end; c++) {
+	Cluster cluster = cluster_list[c];
+
+	int i;
+
+	for (i = 0; i < cluster.count; i++) {
+	    int patch_index = cluster.first_patch[i];
+
+	    int links = 0;
+	    int j;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (adjacency_matrix[patch_index * fragcount + j]) {
+		    links++;
+		}
+	    }
+
+	    if (links > max_links) {
+		max_links = links;
+		max_index = i;
+
+		if (cluster_index < 0) {
+		    max_index = cluster.first_patch[max_index];
+		}
+	    }
+	}
+    }
+
+    return max_index;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/choice.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Graph Theory - successive criteria-based deletion of patches. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/draw.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/draw.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/draw.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,60 @@
+#include "local_proto.h"
+
+inline void swap(int *a, int *b)
+{
+    int zw = *a;
+
+    *a = *b;
+    *b = zw;
+}
+
+void draw_point(int *map, int val, int x, int y, int sx, int sy, int width)
+{
+    if (width <= 0) {
+	return;
+    }
+
+    if (width == 1) {
+	map[y * sx + x] = val;
+    }
+    else {
+    }
+}
+
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width)
+{
+    int steep = abs(y2 - y1) > abs(x2 - x1);
+
+    if (steep) {
+	swap(&x1, &y1);
+	swap(&x2, &y2);
+    }
+
+    if (x1 > x2) {
+	swap(&x1, &x2);
+	swap(&y1, &y2);
+    }
+
+    int deltax = x2 - x1;
+    int deltay = abs(y2 - y1);
+    int error = deltax / 2;
+    int ystep = y1 < y2 ? 1 : -1;
+    int x;
+    int y = y1;
+
+    for (x = x1; x <= x2; x++) {
+	if (steep) {
+	    draw_point(map, val, y, x, sx, sy, width);
+	}
+	else {
+	    draw_point(map, val, x, y, sx, sy, width);
+	}
+
+	error -= deltay;
+	if (error < 0) {
+	    y += ystep;
+	    error += deltax;
+	}
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/draw.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,170 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * curpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * curpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    curpos->x = col;
+    curpos->y = row;
+    curpos->neighbors = neighbors;
+    curpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    curpos->x = x;
+	    curpos->y = y;
+	    curpos->neighbors = neighbors;
+	    curpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return curpos;
+}
+
+int writeFragments(Patch * fragments, int *flagbuf, int nrows, int ncols,
+		   int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+    int fragcount = 0;
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount].first_cell =
+		    writeFrag(flagbuf, fragments[fragcount - 1].first_cell,
+			      row, col, nrows, ncols, nbr_cnt);
+		fragments[fragcount - 1].count =
+		    fragments[fragcount].first_cell - fragments[fragcount -
+								1].first_cell;
+	    }
+	}
+    }
+
+    return fragcount;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,763 @@
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Patch * frags, int n1, int n2)
+{
+    int p1, p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n1].count; p1++) {
+	Coords *c1 = frags[n1].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = 0; p2 < frags[n2].count; p2++) {
+		// if cell at the border
+		Coords *c2 = frags[n2].first_cell + p2;
+
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL nearest_points(Patch * frags, int n1, int n2, Coords * np1,
+		     Coords * np2)
+{
+    int p1, p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n1].count; p1++) {
+	Coords *c1 = frags[n1].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = 0; p2 < frags[n2].count; p2++) {
+		Coords *c2 = frags[n2].first_cell + p2;
+
+		// if cell at the border
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d < min) {
+			min = d;
+			*np1 = *c1;
+			*np2 = *c2;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL min_dist_to_location(Patch * frags, int patch, double loc_x,
+			   double loc_y)
+{
+    int p;
+    DCELL min = MAX_DOUBLE;
+
+    // for all cells in the first patch
+    for (p = 0; p < frags[patch].count; p++) {
+	Coords *cell = frags[patch].first_cell + p;
+
+	// if cell at the border
+	if (cell->neighbors < 4) {
+	    DCELL dx = loc_x - cell->x;
+	    DCELL dy = loc_y - cell->y;
+	    DCELL d = sqrt(dx * dx + dy * dy);
+
+	    if (d < min) {
+		min = d;
+	    }
+	}
+    }
+    return min;
+}
+
+int get_dist_matrix(DCELL * distmatrix, Patch * fragments, int fragcount)
+{
+    int i, j;
+
+    /* fill distance matrix */
+    for (i = 0; i < fragcount; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * fragcount + j] = d;
+	    distmatrix[j * fragcount + i] = d;
+	}
+    }
+
+    return 0;
+}
+
+int get_nearest_neighbor(DCELL * distmatrix, int fragcount, int patch)
+{
+    int i;
+    int min = -1;
+    DCELL min_dist = MAX_DOUBLE;
+    int offset = patch * fragcount;
+
+    for (i = 0; i < fragcount; i++) {
+	if ((i != patch) && (distmatrix[offset + i] < min_dist)) {
+	    min_dist = distmatrix[offset + i];
+	    min = i;
+	}
+    }
+
+    return min;
+}
+
+int *find_cluster(int *adjacency_matrix, int patch, int fragcount,
+		  int *curpos, int *flag_arr)
+{
+    int i;
+    int *p;
+    int list[fragcount];
+    int *first = list;
+    int *last = list + 1;
+    int offset;
+
+    list[0] = patch;
+    flag_arr[patch] = 1;
+
+    while (first < last) {
+	/* save patch */
+	*curpos = *first;
+	curpos++;
+
+	/* add unclassified neighbors to the list */
+	offset = (*first) * fragcount;
+	for (i = 0; i < fragcount; i++) {
+	    if (adjacency_matrix[offset + i] == 1 && flag_arr[i] == 0) {
+		flag_arr[i] = 1;
+		*last = i;
+		last++;
+	    }
+	}
+
+	/* pass processed patch */
+	first++;
+    }
+
+    return curpos;
+}
+
+int find_clusters(Cluster * cluster_list, int *adjacency_matrix,
+		  int fragcount)
+{
+    int i;
+
+    int count = 0;
+
+    int flag_arr[fragcount];
+
+    memset(flag_arr, 0, fragcount * sizeof(int));
+
+    int *curpos = cluster_list[0].first_patch;
+
+    for (i = 0; i < fragcount; i++) {
+	if (flag_arr[i] == 0) {
+	    cluster_list[count].first_patch = curpos;
+	    curpos =
+		find_cluster(adjacency_matrix, i, fragcount, curpos,
+			     flag_arr);
+	    cluster_list[count].count =
+		curpos - cluster_list[count].first_patch;
+	    count++;
+	}
+    }
+
+    /* debug output */
+    /*fprintf(stderr, "Clusters:\n");
+       for(i = 0; i < count; i++) {
+       int j;
+       for(j = 0; j < cluster_list[i].count; j++) {
+       int patch = cluster_list[i].first_patch[j];
+       fprintf(stderr, "%d ", patch);                       
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    return count;
+}
+
+void f_nearest_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			int fragcount, DCELL max_dist)
+{
+    int i;
+
+    for (i = 0; i < fragcount; i++) {
+	int nn = get_nearest_neighbor(distmatrix, fragcount, i);
+
+	if (nn > -1 && distmatrix[i * fragcount + nn] < max_dist) {
+	    adjacency_matrix[i * fragcount + nn] = 1;
+	    adjacency_matrix[nn * fragcount + i] = 1;
+	}
+    }
+}
+
+void f_relative_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			 int fragcount, DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjacency_matrix[i * fragcount + j] = 1;
+	    adjacency_matrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the central lens between i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if (dist1 < dist && dist2 < dist) {
+		    /* i-th and j-th patches are not connected */
+		    adjacency_matrix[i * fragcount + j] = 0;
+		    adjacency_matrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_gabriel(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+	       DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjacency_matrix[i * fragcount + j] = 1;
+	    adjacency_matrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the circle around i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if ((dist1 * dist1 + dist2 * dist2) < (dist * dist)) {
+		    /* i-th and j-th patches are not connected */
+		    adjacency_matrix[i * fragcount + j] = 0;
+		    adjacency_matrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_spanning_tree(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+		     DCELL max_dist)
+{
+    int i, j;
+    int parents[fragcount];
+    DCELL distances[fragcount];
+    int curmin;
+    int nextmin = 0;
+    int parent;
+
+    /* init parents and distances list */
+    for (i = 0; i < fragcount; i++) {
+	parents[i] = -1;
+	distances[i] = MAX_DOUBLE;
+    }
+
+    /* repeat for each patch */
+    for (i = 0; i < fragcount; i++) {
+	/* pass on next minimum node */
+	curmin = nextmin;
+	nextmin = 0;
+
+	/* connect current minimum node with its parent and set distance to 0    */
+	/* connect only if parent is assigned and distance is less than max_dist */
+	if ((parent = parents[curmin]) != -1 &&
+	    distmatrix[parent * fragcount + curmin] < max_dist) {
+	    adjacency_matrix[curmin * fragcount + parent] = 1;
+	    adjacency_matrix[parent * fragcount + curmin] = 1;
+	}
+	distances[curmin] = 0.0;
+
+	/* debug output */
+	/*G_message("New patch: %d, connecting to patch %d", curmin, parents[curmin]); */
+
+	/* find the next node for minimum spanning tree */
+	for (j = 0; j < fragcount; j++) {
+	    /* skip the current minimum node */
+	    if (j == curmin)
+		continue;
+
+	    /* get distance to the current minimum node */
+	    DCELL dist = distmatrix[curmin * fragcount + j];
+
+	    /* if this distance is smaller than the stored one */
+	    /* then set a new distance and update parent list  */
+	    if (dist < distances[j]) {
+		distances[j] = dist;
+		parents[j] = curmin;
+	    }
+
+	    /* update the next minimum node */
+	    if (distances[nextmin] == 0 ||
+		(distances[j] > 0 && distances[j] < distances[nextmin])) {
+		nextmin = j;
+	    }
+	}
+    }
+}
+
+/*********************************
+ *            INDICES            *
+ *********************************/
+
+void f_connectance_index(DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int p, q;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	DCELL c = 100.0 / (n * (n - 1) * 0.5);
+	DCELL val = 0;
+
+	/* no patches are 0% connected */
+	if (n == 0) {
+	    values[i] == 0.0;
+	    continue;
+	}
+
+	/* single patch is 100% connected */
+	if (n == 1) {
+	    values[i] = 100.0;
+	    continue;
+	}
+
+	/* for each patch pair in the cluster */
+	for (p = 0; p < cluster_list[i].count - 1; p++) {
+	    for (q = p + 1; q < cluster_list[i].count; q++) {
+		int patch1 = cluster_list[i].first_patch[p];
+		int patch2 = cluster_list[i].first_patch[q];
+
+		if (adjacency_matrix[patch1 * fragcount + patch2] == 1) {
+		    val++;
+		}
+	    }
+	}
+
+	values[i] = 100.0 * val / (n * (n - 1) * 0.5);
+    }
+}
+
+void f_gyration_radius(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	double avg_x = 0.0;
+	double avg_y = 0.0;
+	int count = 0;
+	DCELL val = 0.0;
+
+	/* calculate cluster centroid */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*p].count;
+		 cell_index++) {
+		Coords *cell = fragments[*p].first_cell + cell_index;
+
+		avg_x += cell->x;
+		avg_y += cell->y;
+		count++;
+	    }
+	}
+	avg_x /= (double)count;
+	avg_y /= (double)count;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    val += min_dist_to_location(fragments, *p, avg_x, avg_y);
+	}
+
+	values[i] = val / (double)n;
+    }
+}
+
+void f_cohesion_index(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	int total_area = 0;
+	DCELL num = 0.0;
+	DCELL denom = 0.0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int perim = 0;
+	    int area = fragments[*p].count;
+
+	    /* find perimeter */
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*p].count;
+		 cell_index++) {
+		Coords *cell = fragments[*p].first_cell + cell_index;
+
+		/* if cell is on the edge */
+		if (cell->neighbors < 4) {
+		    perim++;
+		}
+	    }
+
+	    /* update total number of cells in the cluster */
+	    total_area += area;
+
+	    num += (double)perim;
+	    denom += (double)perim *sqrt((double)area);
+	}
+
+	values[i] =
+	    (1.0 - num / denom) / (1.0 -
+				   1.0 / sqrt((double)total_area)) * 100.0;
+    }
+}
+
+void f_percent_patches(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int patch_count = cluster_list[i].count;
+
+	values[i] = (DCELL) patch_count / (DCELL) fragcount *100.0;
+    }
+}
+
+void f_percent_area(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix)
+{
+    int i;
+    int *p, *q;
+    Coords *cell;
+
+    int area_all = 0;
+
+    for (i = 0; i < fragcount; i++) {
+	area_all += fragments[i].count;
+    }
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    area_cluster += fragments[*p].count;
+	}
+
+	values[i] = (DCELL) area_cluster / (DCELL) area_all *100.0;
+    }
+}
+
+void f_number_patches(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	values[i] = (DCELL) cluster_list[i].count;
+    }
+}
+
+void f_number_links(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix)
+{
+    int i;
+    int *p, *q;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int links = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count - 1;
+	     p++) {
+	    /* for each other patch in the cluster */
+	    for (q = p + 1;
+		 q < cluster_list[i].first_patch + cluster_list[i].count;
+		 q++) {
+		if (adjacency_matrix[*q * fragcount + *p] == 1) {
+		    links++;
+		}
+	    }
+	}
+
+	values[i] = (DCELL) links;
+    }
+}
+
+void f_mean_patch_size(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int patch_count = cluster_list[i].count;
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    area_cluster += fragments[*p].count;
+	}
+
+	if (patch_count > 0) {
+	    values[i] = (DCELL) area_cluster / (DCELL) patch_count;
+	}
+	else {
+	    values[i] = 0.0;
+	}
+    }
+}
+
+void f_largest_patch_size(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int max_area = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int area = fragments[*p].count;
+
+	    if (area > max_area) {
+		max_area = area;
+	    }
+	}
+
+	values[i] = (DCELL) max_area;
+    }
+}
+
+DCELL get_diameter(Patch * frags, int n)
+{
+    int p1, p2;
+    DCELL max = 0.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n].count; p1++) {
+	Coords *c1 = frags[n].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = p1 + 1; p2 < frags[n].count; p2++) {
+		Coords *c2 = frags[n].first_cell + p2;
+
+		// if cell at the border
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d > max) {
+			max = d;
+		    }
+		}
+	    }
+	}
+    }
+    return max;
+}
+
+void f_largest_patch_diameter(DCELL * values, Cluster * cluster_list,
+			      int cluster_count, int *adjacency_matrix,
+			      Patch * fragments, int fragcount,
+			      DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	DCELL max_diameter = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    DCELL diameter = get_diameter(fragments, *p);
+
+	    if (diameter > max_diameter) {
+		max_diameter = diameter;
+	    }
+	}
+
+	values[i] = max_diameter;
+    }
+}
+
+/* implements floyd-warshall algorithm for finding shortest pathes */
+void f_graph_diameter_max(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix)
+{
+    int i, j, k;
+
+    /* initialize path matrix */
+    DCELL pathmatrix[fragcount * fragcount * sizeof(DCELL)];
+
+    for (i = 0; i < fragcount; i++) {
+	pathmatrix[i * fragcount + i] = 0.0;
+
+	int j;
+
+	for (j = i + 1; j < fragcount; j++) {
+	    int index = i * fragcount + j;
+	    int index_mirror = j * fragcount + i;
+
+	    if (adjacency_matrix[index]) {
+		pathmatrix[index] = pathmatrix[index_mirror] =
+		    distmatrix[index];
+	    }
+	    else {
+		pathmatrix[index] = pathmatrix[index_mirror] = MAX_DOUBLE;
+	    }
+	}
+    }
+
+    /* for each patch */
+    for (k = 0; k < fragcount; k++) {
+	/* for every other patch */
+	for (i = 0; i < fragcount; i++) {
+	    /* for every third patch */
+	    for (j = 0; j < fragcount; j++) {
+		/* get direct path and detour over p3 */
+		DCELL direct = pathmatrix[i * fragcount + j];
+		DCELL indirect =
+		    pathmatrix[i * fragcount + k] + pathmatrix[k * fragcount +
+							       j];
+
+		/* if detour is shorter */
+		if (indirect < direct) {
+		    pathmatrix[i * fragcount + j] = indirect;
+		}
+	    }
+	}
+    }
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	/* search for the maximum distance between two patches in this cluster */
+	DCELL max_dist = 0.0;
+	int *patch;
+
+	for (patch = cluster_list[i].first_patch;
+	     patch < cluster_list[i].first_patch + cluster_list[i].count - 1;
+	     patch++) {
+	    int *other_patch;
+
+	    for (other_patch = patch + 1;
+		 other_patch <
+		 cluster_list[i].first_patch + cluster_list[i].count;
+		 other_patch++) {
+		DCELL dist = pathmatrix[*patch * fragcount + *other_patch];
+
+		if (dist < MAX_DOUBLE && dist > max_dist) {
+		    max_dist = dist;
+		}
+	    }
+	}
+
+	values[i] = max_dist;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,131 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+#define MAX_INT 0x7FFFFFFF
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    Coords *first_cell;
+    int count;
+} Patch;
+
+typedef struct
+{
+    int *first_patch;
+    int count;
+} Cluster;
+
+typedef void (*f_neighborhood) (int *adjacency_matrix, DCELL * distmatrix,
+				int fragcount, DCELL max_dist);
+typedef void (*f_index) (DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+typedef int (*f_choice) (int cluster_index, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+
+/* frag.c */
+int writeFragments(Patch * fragments, int *flagbuf, int nrows, int ncols,
+		   int nbr_cnt);
+
+/* func.c */
+int get_dist_matrix(DCELL * distmatrix, Patch * fragments, int fragcount);
+
+void f_nearest_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			int fragcount, DCELL max_dist);
+void f_relative_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			 int fragcount, DCELL max_dist);
+void f_gabriel(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+	       DCELL max_dist);
+void f_spanning_tree(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+		     DCELL max_dist);
+
+void f_connectance_index(DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+void f_gyration_radius(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_cohesion_index(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_percent_patches(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_percent_area(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix);
+void f_number_patches(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_number_links(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix);
+void f_mean_patch_size(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_largest_patch_size(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix);
+void f_largest_patch_diameter(DCELL * values, Cluster * cluster_list,
+			      int cluster_count, int *adjacency_matrix,
+			      Patch * fragments, int fragcount,
+			      DCELL * distmatrix);
+void f_graph_diameter_max(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix);
+
+int find_clusters(Cluster * cluster_list, int *adjacency_matrix,
+		  int fragcount);
+
+DCELL nearest_points(Patch * frags, int n1, int n2, Coords * np1,
+		     Coords * np2);
+
+/* choice.c */
+/* returns index of the patch to delete next in the cluster (or the patch index in the fragments list if landscape wide choice is performed) */
+int f_smallest_first(int cluster_index, Cluster * cluster_list,
+		     int cluster_count, int *adjacency_matrix,
+		     Patch * fragments, int fragcount, DCELL * distmatrix);
+int f_biggest_first(int cluster_index, Cluster * cluster_list,
+		    int cluster_count, int *adjacency_matrix,
+		    Patch * fragments, int fragcount, DCELL * distmatrix);
+int f_random(int cluster_index, Cluster * cluster_list, int cluster_count,
+	     int *adjacency_matrix, Patch * fragments, int fragcount,
+	     DCELL * distmatrix);
+int f_link_min(int cluster_index, Cluster * cluster_list, int cluster_count,
+	       int *adjacency_matrix, Patch * fragments, int fragcount,
+	       DCELL * distmatrix);
+int f_link_max(int cluster_index, Cluster * cluster_list, int cluster_count,
+	       int *adjacency_matrix, Patch * fragments, int fragcount,
+	       DCELL * distmatrix);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.dec/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.dec/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.dec/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,720 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.graph.dec
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Graph Theory approach for connectivity analysis on patch 
+ *                      level - successive removal of patches based on defined criteria
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct neighborhood
+{
+    f_neighborhood method;	/* routine to build adjacency matrix */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct index
+{
+    f_index method;		/* routine to calculate cluster index */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct choice
+{
+    f_choice method;		/* routine to determine the next patch to delete */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct neighborhood neighborhoods[] = {
+    {f_nearest_neighbor, "nearest_neighbor",
+     "patches are connected with their nearest neighbors"},
+    {f_relative_neighbor, "relative_neighbor",
+     "two patches are connected, if no other patch lies in the central lens between them"},
+    {f_gabriel, "gabriel",
+     "two patches are connected, if no other patch lies in the circle on them"},
+    {f_spanning_tree, "spanning_tree",
+     "two patches are connected, if they are neighbors in the minimum spanning tree"},
+    {0, 0, 0}
+};
+
+static struct index indices[] = {
+    {f_connectance_index, "connectance_index", "connectance index"},
+    {f_gyration_radius, "gyration_radius", "radius of gyration"},
+    {f_cohesion_index, "cohesion_index", "cohesion index"},
+    {f_percent_patches, "percent_patches",
+     "percentage of the patches in the cluster"},
+    {f_percent_area, "percent_area",
+     "percentage of the patch area in the cluster"},
+    {f_number_patches, "number_patches", "number of patches in the cluster"},
+    {f_number_links, "number_links", "number of links in the cluster"},
+    {f_mean_patch_size, "mean_patch_size", "mean patch size in the cluster"},
+    {f_largest_patch_size, "largest_patch_size",
+     "largest patch size in the cluster"},
+    {f_largest_patch_diameter, "largest_patch_diameter",
+     "largest patch diameter in the cluster"},
+    {f_graph_diameter_max, "graph_diameter",
+     "longest minimal path in the cluster"},
+    {0, 0, 0}
+};
+
+static struct choice choices[] = {
+    {f_smallest_first, "smallest_first", "smallest patch is deleted first"},
+    {f_biggest_first, "biggest_first", "biggest patch is deleted first"},
+    {f_random, "random", "a random patch is deleted"},
+    {f_link_min, "link_min",
+     "the patch with the least links is deleted first"},
+    {f_link_max, "link_max",
+     "the patch with the most links is deleted first"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *oldname, *oldmapset, *newname, *newmapset, *idname, *idmapset;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+    FILE *out_fp;		/* ASCII - output */
+
+    /* parameters */
+    int keyval;
+    int nbr_count;
+    int index;
+    int neighborhood;
+    int choice;
+    DCELL distance;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    char *p;
+    int row, col, i, j, m;
+    int n;
+    f_neighborhood build_graph;
+    f_index calc_index;
+    f_choice choose_patch;
+    int *curpos;
+    CELL *result;
+    DCELL *d_res;
+    CELL *clustermap;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output, *id;
+	struct Option *keyval, *distance;
+	struct Option *neighborhood, *index;
+	struct Option *choice, *seed;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *landscape;
+    } flag;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Graph Theory - successive criteria-based deletion of patches.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.id = G_define_option();
+    parm.id->key = "id";
+    parm.id->type = TYPE_STRING;
+    parm.id->required = NO;
+    parm.id->gisprompt = "new,cell,raster";
+    parm.id->description = _("Base name for the ID raster files");
+
+    parm.output = G_define_option();
+    parm.output->key = "output";
+    parm.output->type = TYPE_STRING;
+    parm.output->required = YES;
+    parm.output->gisprompt = "new_file,file,output";
+    parm.output->description = _("Name of the output ASCII file");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.distance = G_define_option();
+    parm.distance->key = "distance";
+    parm.distance->type = TYPE_DOUBLE;
+    parm.distance->required = YES;
+    parm.distance->description =
+	_("Bounding distance [0 for maximum distance]");
+
+    parm.neighborhood = G_define_option();
+    parm.neighborhood->key = "neighborhood";
+    parm.neighborhood->type = TYPE_STRING;
+    parm.neighborhood->required = YES;
+    p = parm.neighborhood->options = G_malloc(1024);
+    for (n = 0; neighborhoods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, neighborhoods[n].name);
+    }
+    parm.neighborhood->description = _("Neighborhood definition");
+
+    parm.index = G_define_option();
+    parm.index->key = "index";
+    parm.index->type = TYPE_STRING;
+    parm.index->required = YES;
+    p = parm.index->options = G_malloc(1024);
+    for (n = 0; indices[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, indices[n].name);
+    }
+    parm.index->description = _("Cluster index");
+
+    parm.choice = G_define_option();
+    parm.choice->key = "choice";
+    parm.choice->type = TYPE_STRING;
+    parm.choice->required = YES;
+    p = parm.choice->options = G_malloc(1024);
+    for (n = 0; choices[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, choices[n].name);
+    }
+    parm.choice->description = _("Cluster index");
+
+    parm.seed = G_define_option();
+    parm.seed->key = "seed";
+    parm.seed->type = TYPE_INTEGER;
+    parm.seed->required = NO;
+    parm.seed->description = _("Seed for the random number generation");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.landscape = G_define_flag();
+    flag.landscape->key = 'l';
+    flag.landscape->description =
+	_("Set to perform deletion for the whole landscape rather than cluster-wise");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* check if the id raster file name is correct */
+    idname = parm.id->answer;
+    if (G_legal_filename(idname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), idname);
+    idmapset = G_mapset();
+
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    G_message("rows = %d, cols = %d", nrows, ncols);
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get distance */
+    sscanf(parm.distance->answer, "%lf", &distance);
+    if (distance == 0.0) {
+	distance = MAX_DOUBLE;
+    }
+
+    /* get neighborhood definition */
+    for (neighborhood = 0; (p = neighborhoods[neighborhood].name);
+	 neighborhood++) {
+	if ((strcmp(p, parm.neighborhood->answer) == 0))
+	    break;
+    }
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.neighborhood->key,
+		      parm.neighborhood->answer, parm.neighborhood->key);
+    }
+
+    /* get the cluster index */
+    for (index = 0; (p = indices[index].name); index++)
+	if ((strcmp(p, parm.index->answer) == 0))
+	    break;
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.index->key,
+		      parm.index->answer, parm.index->key);
+    }
+
+    /* get the choice method */
+    for (choice = 0; (p = choices[choice].name); choice++)
+	if ((strcmp(p, parm.choice->answer) == 0))
+	    break;
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.choice->key,
+		      parm.choice->answer, parm.choice->key);
+    }
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* set random seed */
+    int seed = time(NULL);
+
+    if (parm.seed->answer) {
+	sscanf(parm.seed->answer, "%d", &seed);
+    }
+    srand(seed);
+
+    /* allocate the cell buffers */
+    Coords *cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    Patch *fragments = (Patch *) G_malloc(nrows * ncols * sizeof(Patch));
+
+    fragments[0].first_cell = cells;
+    int *flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+
+    result = G_allocate_c_raster_buf();
+
+    G_message("Loading patches...");
+
+    /* read map */
+    for (row = 0; row < nrows; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /*G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%d", flagbuf[row * ncols + col]);           
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find fragments */
+    int fragcount =
+	writeFragments(fragments, flagbuf, nrows, ncols, nbr_count);
+
+    /* allocate distance matrix */
+    DCELL *distmatrix =
+	(DCELL *) G_malloc(fragcount * fragcount * sizeof(DCELL));
+    memset(distmatrix, 0, fragcount * fragcount * sizeof(DCELL));
+
+    /* generate the distance matrix */
+    get_dist_matrix(distmatrix, fragments, fragcount);
+
+    /*G_message("Distance matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%0.2f ", distmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* build adjacency matrix */
+    int *adjmatrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+
+    memset(adjmatrix, 0, fragcount * fragcount * sizeof(int));
+
+    build_graph = neighborhoods[neighborhood].method;
+    build_graph(adjmatrix, distmatrix, fragcount, distance);
+
+    /*G_message("Adjacency matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%d", adjmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find clusters */
+    int *patches = (int *)G_malloc(fragcount * sizeof(int));
+    Cluster *clusters = (Cluster *) G_malloc((fragcount) * sizeof(Cluster));
+
+    clusters[0].first_patch = patches;
+
+    int clustercount = find_clusters(clusters, adjmatrix, fragcount);
+
+    /*for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, "Cluster_%d:", i);
+       for(curpos = clusters[i]; curpos < clusters[i + 1]; curpos++) {
+       fprintf(stderr, " %d", *curpos);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* values: Before Deletion(cluster1, cluster2, ...), After First Deletion(...), After Second Deletion(...), ... */
+    DCELL *values =
+	(DCELL *) G_malloc((fragcount + 1) * clustercount * sizeof(DCELL));
+    int *patch_notes = (int *)G_malloc(fragcount * sizeof(int));
+    int *cluster_notes = (int *)G_malloc(fragcount * sizeof(int));
+
+    calc_index = indices[index].method;
+    choose_patch = choices[choice].method;
+
+    /* write id raster maps */
+
+    if (parm.id->answer) {
+	/* ================================== 
+	   ==========  cluster map  ========= 
+	   ================================== */
+
+	/* open the new cellfile */
+	sprintf(fullname, "%s_clusters", idname);
+    out_fd = G_open_raster_new(fullname, CELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+	/* allocate and initialize the clustermap */
+	clustermap = (CELL *) G_malloc(nrows * ncols * sizeof(CELL));
+	G_set_c_null_value(clustermap, nrows * ncols);
+
+	/* for each cluster */
+	for (i = 0; i < clustercount; i++) {
+	    /* for each patch in the cluster */
+	    int *this;
+
+	    for (this = clusters[i].first_patch;
+		 this < clusters[i].first_patch + clusters[i].count; this++) {
+		/* for each cell in the patch */
+		int cell_index;
+
+		for (cell_index = 0; cell_index < fragments[*this].count;
+		     cell_index++) {
+		    Coords *cell = fragments[*this].first_cell + cell_index;
+
+		    clustermap[cell->y * ncols + cell->x] = i;
+		}
+
+		/* for each patch in the cluster */
+		int *other;
+
+		for (other = this + 1;
+		     other < clusters[i].first_patch + clusters[i].count;
+		     other++) {
+		    if (*other != *this &&
+			adjmatrix[*this * fragcount + *other]) {
+			Coords np1, np2;
+
+			nearest_points(fragments, *this, *other, &np1, &np2);
+
+			draw_line(clustermap, -1, np1.x, np1.y, np2.x, np2.y,
+				  ncols, nrows, 1);
+		    }
+		}
+	    }
+	}
+
+	/* write output */
+	for (row = 0; row < nrows; row++) {
+	    G_put_c_raster_row(out_fd, clustermap + row * ncols);
+	}
+
+	G_free(clustermap);
+
+	/* close output file */
+	G_close_cell(out_fd);
+
+	/* ================================== 
+	   ============  id raster  ============
+	   ================================== */
+
+	/* allocate result row variable */
+	d_res = G_allocate_d_raster_buf();
+
+	/* open new cellfile  */
+	sprintf(fullname, "%s_id", idname);
+    out_fd = G_open_raster_new(fullname, CELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+	/* write the output file */
+	for (row = 0; row < nrows; row++) {
+	    G_set_d_null_value(d_res, ncols);
+
+	    int patch_index;
+
+	    for (patch_index = 0; patch_index < fragcount; patch_index++) {
+		int cell_index;
+
+		for (cell_index = 0;
+		     cell_index < fragments[patch_index].count;
+		     cell_index++) {
+		    Coords *cell =
+			fragments[patch_index].first_cell + cell_index;
+		    if (cell->y == row) {
+			d_res[cell->x] = patch_index;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+	}
+
+	/* free result row */
+	G_free(d_res);
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* calculate indices once before deletion */
+    calc_index(values, clusters, clustercount, adjmatrix, fragments,
+	       fragcount, distmatrix);
+
+    /*fprintf(stderr, "Values:");
+       for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, " %0.2f", values[i]);
+       }
+       fprintf(stderr, "\n"); */
+
+    G_message("Performing iterative deletion...");
+
+    DCELL *cur_values = values + clustercount;
+    int cur_pos = 0;
+
+    if (flag.landscape->answer) {	/* landscape wide deletion */
+	/* for each patch */
+	for (i = 0; i < fragcount; i++) {
+	    /* find next patch to delete */
+	    int patch =
+		choose_patch(-1, clusters, clustercount, adjmatrix, fragments,
+			     fragcount, distmatrix);
+
+	    /* find the appropriate cluster */
+	    int j;
+	    int cluster = -1;
+	    int rel_patch;
+
+	    for (j = 0; j < clustercount; j++) {
+		int p;
+
+		for (p = 0; p < clusters[j].count; p++) {
+		    if (clusters[j].first_patch[p] == patch) {
+			cluster = j;
+			rel_patch = p;
+			break;
+		    }
+		}
+	    }
+
+	    if (cluster == -1) {
+		G_fatal_error("A clusterless patch nr.%d encountered!",
+			      patch);
+	    }
+
+	    /* save which patch from which cluster has been deleted */
+	    cluster_notes[cur_pos] = cluster;
+	    patch_notes[cur_pos] = patch;
+	    cur_pos++;
+
+	    /* delete this patch from the cluster */
+	    clusters[cluster].first_patch[rel_patch] =
+		clusters[cluster].first_patch[clusters[cluster].count - 1];
+	    clusters[cluster].count--;
+
+	    /* and from the adjacency matrix */
+	    int k;
+
+	    for (k = 0; k < fragcount; k++) {
+		adjmatrix[k * fragcount + patch] = 0;
+		adjmatrix[patch * fragcount + k] = 0;
+	    }
+
+	    /* calculate index */
+	    calc_index(cur_values, clusters, clustercount, adjmatrix,
+		       fragments, fragcount, distmatrix);
+	    cur_values += clustercount;
+	}
+    }
+    else {
+	/* for each cluster */
+	for (i = 0; i < clustercount; i++) {
+	    int j;
+
+	    /* patch count times do */
+	    int count = clusters[i].count;
+
+	    for (j = 0; j < count; j++) {
+		/* find next patch to delete */
+		int patch = choose_patch(i, clusters, clustercount, adjmatrix,
+					 fragments, fragcount, distmatrix);
+		int real_patch = clusters[i].first_patch[patch];
+
+		/* save which patch from which cluster has been deleted */
+		cluster_notes[cur_pos] = i;
+		patch_notes[cur_pos] = real_patch;
+		cur_pos++;
+
+		/*int c;
+		   fprintf(stderr, "Patch notes:");
+		   for(c = 0; c < save_fc; c++) {
+		   fprintf(stderr, " %d", patch_notes[c]);
+		   }
+		   fprintf(stderr, "\n"); */
+
+		/* delete this patch from the cluster */
+		clusters[i].first_patch[patch] =
+		    clusters[i].first_patch[clusters[i].count - 1];
+		clusters[i].count--;
+
+		/* and from the adjacency matrix */
+		int k;
+
+		for (k = 0; k < fragcount; k++) {
+		    adjmatrix[k * fragcount + real_patch] = 0;
+		    adjmatrix[real_patch * fragcount + k] = 0;
+		}
+
+		/* calculate index */
+		calc_index(cur_values, clusters, clustercount, adjmatrix,
+			   fragments, fragcount, distmatrix);
+		cur_values += clustercount;
+	    }
+	}
+    }
+
+    /* test output */
+    /*fprintf(stderr, "Splitter patches:");
+       for(i = 0; i < fragcount; i++) {
+       fprintf(stderr, " %d", splitter_patches[i]);
+       }
+       fprintf(stderr, "\n"); */
+
+    /* write output */
+    G_message("Writing output...");
+
+    /* ================================== 
+       ============  output  ============ 
+       ================================== */
+
+    /* open ASCII-file or use stdout */
+    if (strcmp(parm.output->answer, "-") != 0) {
+	if (!(out_fp = fopen(parm.output->answer, "w"))) {
+	    G_fatal_error(_("Error creating file <%s>"),
+			  parm.output->answer);
+	}
+    }
+    else {
+	out_fp = stdout;
+    }
+
+    /* write header */
+    fprintf(out_fp, "cluster patch");
+    for (i = 0; i < clustercount; i++) {
+	fprintf(out_fp, " cluster_index_%d", i);
+    }
+    fprintf(out_fp, " change change_percent change_from_initial");
+    fprintf(out_fp, "\n");
+
+    /* write values */
+    for (i = 0; i < fragcount + 1; i++) {
+	int cluster = i > 0 ? cluster_notes[i - 1] : -1;
+	int patch = i > 0 ? patch_notes[i - 1] : -1;
+
+	fprintf(out_fp, "%d %d", cluster, patch);
+
+	int j;
+
+	for (j = 0; j < clustercount; j++) {
+	    fprintf(out_fp, " %lf", values[i * clustercount + j]);
+	}
+
+	if (i > 0 && cluster >= 0) {
+	    /* print changes */
+	    DCELL initval = values[cluster];
+	    DCELL oldval = values[(i - 1) * clustercount + cluster];
+	    DCELL newval = values[i * clustercount + cluster];
+	    DCELL change = newval - oldval;
+	    DCELL change_pr = change / oldval * 100.0;
+	    DCELL change_from_init = change / initval * 100.0;
+
+	    fprintf(out_fp, " %lf %lf %lf", change, change_pr,
+		    change_from_init);
+	}
+	else {
+	    fprintf(out_fp, " 0 0 0");
+	}
+
+	fprintf(out_fp, "\n");
+    }
+
+    /* close output file */
+    if (strcmp(parm.output->answer, "-") != 0) {
+	fclose(out_fp);
+    }
+
+    /* =============================
+       =======  free memory  =======
+       ============================= */
+    G_free(values);
+    G_free(patches);
+    G_free(clusters);
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+    G_free(result);
+
+    G_free(distmatrix);
+    G_free(adjmatrix);
+
+    G_free(cluster_notes);
+    G_free(patch_notes);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.dec/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.graph.iter
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Graph Theory - iterative removal (patch relevance analysis).
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/draw.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/draw.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/draw.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,60 @@
+#include "local_proto.h"
+
+inline void swap(int *a, int *b)
+{
+    int zw = *a;
+
+    *a = *b;
+    *b = zw;
+}
+
+void draw_point(int *map, int val, int x, int y, int sx, int sy, int width)
+{
+    if (width <= 0) {
+	return;
+    }
+
+    if (width == 1) {
+	map[y * sx + x] = val;
+    }
+    else {
+    }
+}
+
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width)
+{
+    int steep = abs(y2 - y1) > abs(x2 - x1);
+
+    if (steep) {
+	swap(&x1, &y1);
+	swap(&x2, &y2);
+    }
+
+    if (x1 > x2) {
+	swap(&x1, &x2);
+	swap(&y1, &y2);
+    }
+
+    int deltax = x2 - x1;
+    int deltay = abs(y2 - y1);
+    int error = deltax / 2;
+    int ystep = y1 < y2 ? 1 : -1;
+    int x;
+    int y = y1;
+
+    for (x = x1; x <= x2; x++) {
+	if (steep) {
+	    draw_point(map, val, y, x, sx, sy, width);
+	}
+	else {
+	    draw_point(map, val, x, y, sx, sy, width);
+	}
+
+	error -= deltay;
+	if (error < 0) {
+	    y += ystep;
+	    error += deltax;
+	}
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/draw.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,170 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * curpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * curpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    curpos->x = col;
+    curpos->y = row;
+    curpos->neighbors = neighbors;
+    curpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    curpos->x = x;
+	    curpos->y = y;
+	    curpos->neighbors = neighbors;
+	    curpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return curpos;
+}
+
+int writeFragments(Patch * fragments, int *flagbuf, int nrows, int ncols,
+		   int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+    int fragcount = 0;
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount].first_cell =
+		    writeFrag(flagbuf, fragments[fragcount - 1].first_cell,
+			      row, col, nrows, ncols, nbr_cnt);
+		fragments[fragcount - 1].count =
+		    fragments[fragcount].first_cell - fragments[fragcount -
+								1].first_cell;
+	    }
+	}
+    }
+
+    return fragcount;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,757 @@
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Patch * frags, int n1, int n2)
+{
+    int p1, p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n1].count; p1++) {
+	Coords *c1 = frags[n1].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = 0; p2 < frags[n2].count; p2++) {
+		// if cell at the border
+		Coords *c2 = frags[n2].first_cell + p2;
+
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL nearest_points(Patch * frags, int n1, int n2, Coords * np1,
+		     Coords * np2)
+{
+    int p1, p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n1].count; p1++) {
+	Coords *c1 = frags[n1].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = 0; p2 < frags[n2].count; p2++) {
+		Coords *c2 = frags[n2].first_cell + p2;
+
+		// if cell at the border
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d < min) {
+			min = d;
+			*np1 = *c1;
+			*np2 = *c2;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL min_dist_to_location(Patch * frags, int patch, double loc_x,
+			   double loc_y)
+{
+    int p;
+    DCELL min = MAX_DOUBLE;
+
+    // for all cells in the first patch
+    for (p = 0; p < frags[patch].count; p++) {
+	Coords *cell = frags[patch].first_cell + p;
+
+	// if cell at the border
+	if (cell->neighbors < 4) {
+	    DCELL dx = loc_x - cell->x;
+	    DCELL dy = loc_y - cell->y;
+	    DCELL d = sqrt(dx * dx + dy * dy);
+
+	    if (d < min) {
+		min = d;
+	    }
+	}
+    }
+    return min;
+}
+
+int get_dist_matrix(DCELL * distmatrix, Patch * fragments, int fragcount)
+{
+    int i, j;
+
+    /* fill distance matrix */
+    for (i = 0; i < fragcount; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * fragcount + j] = d;
+	    distmatrix[j * fragcount + i] = d;
+	}
+    }
+
+    return 0;
+}
+
+int get_nearest_neighbor(DCELL * distmatrix, int fragcount, int patch)
+{
+    int i;
+    int min = -1;
+    DCELL min_dist = MAX_DOUBLE;
+    int offset = patch * fragcount;
+
+    for (i = 0; i < fragcount; i++) {
+	if ((i != patch) && (distmatrix[offset + i] < min_dist)) {
+	    min_dist = distmatrix[offset + i];
+	    min = i;
+	}
+    }
+
+    return min;
+}
+
+int *find_cluster(int *adjacency_matrix, int patch, int fragcount,
+		  int *curpos, int *flag_arr)
+{
+    int i;
+    int *p;
+    int list[fragcount];
+    int *first = list;
+    int *last = list + 1;
+    int offset;
+
+    list[0] = patch;
+    flag_arr[patch] = 1;
+
+    while (first < last) {
+	/* save patch */
+	*curpos = *first;
+	curpos++;
+
+	/* add unclassified neighbors to the list */
+	offset = (*first) * fragcount;
+	for (i = 0; i < fragcount; i++) {
+	    if (adjacency_matrix[offset + i] == 1 && flag_arr[i] == 0) {
+		flag_arr[i] = 1;
+		*last = i;
+		last++;
+	    }
+	}
+
+	/* pass processed patch */
+	first++;
+    }
+
+    return curpos;
+}
+
+int find_clusters(Cluster * cluster_list, int *adjacency_matrix,
+		  int fragcount)
+{
+    int i;
+
+    int count = 0;
+
+    int flag_arr[fragcount];
+
+    memset(flag_arr, 0, fragcount * sizeof(int));
+
+    int *curpos = cluster_list[0].first_patch;
+
+    for (i = 0; i < fragcount; i++) {
+	if (flag_arr[i] == 0) {
+	    cluster_list[count].first_patch = curpos;
+	    curpos =
+		find_cluster(adjacency_matrix, i, fragcount, curpos,
+			     flag_arr);
+	    cluster_list[count].count =
+		curpos - cluster_list[count].first_patch;
+	    count++;
+	}
+    }
+
+    /* debug output */
+    /*fprintf(stderr, "Clusters:\n");
+       for(i = 0; i < count; i++) {
+       int j;
+       for(j = 0; j < cluster_list[i].count; j++) {
+       int patch = cluster_list[i].first_patch[j];
+       fprintf(stderr, "%d ", patch);                       
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    return count;
+}
+
+void f_nearest_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			int fragcount, DCELL max_dist)
+{
+    int i;
+
+    for (i = 0; i < fragcount; i++) {
+	int nn = get_nearest_neighbor(distmatrix, fragcount, i);
+
+	if (nn > -1 && distmatrix[i * fragcount + nn] < max_dist) {
+	    adjacency_matrix[i * fragcount + nn] = 1;
+	    adjacency_matrix[nn * fragcount + i] = 1;
+	}
+    }
+}
+
+void f_relative_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			 int fragcount, DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjacency_matrix[i * fragcount + j] = 1;
+	    adjacency_matrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the central lens between i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if (dist1 < dist && dist2 < dist) {
+		    /* i-th and j-th patches are not connected */
+		    adjacency_matrix[i * fragcount + j] = 0;
+		    adjacency_matrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_gabriel(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+	       DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjacency_matrix[i * fragcount + j] = 1;
+	    adjacency_matrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the circle around i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if ((dist1 * dist1 + dist2 * dist2) < (dist * dist)) {
+		    /* i-th and j-th patches are not connected */
+		    adjacency_matrix[i * fragcount + j] = 0;
+		    adjacency_matrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_spanning_tree(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+		     DCELL max_dist)
+{
+    int i, j;
+    int parents[fragcount];
+    DCELL distances[fragcount];
+    int curmin;
+    int nextmin = 0;
+    int parent;
+
+    /* init parents and distances list */
+    for (i = 0; i < fragcount; i++) {
+	parents[i] = -1;
+	distances[i] = MAX_DOUBLE;
+    }
+
+    /* repeat for each patch */
+    for (i = 0; i < fragcount; i++) {
+	/* pass on next minimum node */
+	curmin = nextmin;
+	nextmin = 0;
+
+	/* connect current minimum node with its parent and set distance to 0    */
+	/* connect only if parent is assigned and distance is less than max_dist */
+	if ((parent = parents[curmin]) != -1 &&
+	    distmatrix[parent * fragcount + curmin] < max_dist) {
+	    adjacency_matrix[curmin * fragcount + parent] = 1;
+	    adjacency_matrix[parent * fragcount + curmin] = 1;
+	}
+	distances[curmin] = 0.0;
+
+	/* debug output */
+	/*G_message("New patch: %d, connecting to patch %d", curmin, parents[curmin]); */
+
+	/* find the next node for minimum spanning tree */
+	for (j = 0; j < fragcount; j++) {
+	    /* skip the current minimum node */
+	    if (j == curmin)
+		continue;
+
+	    /* get distance to the current minimum node */
+	    DCELL dist = distmatrix[curmin * fragcount + j];
+
+	    /* if this distance is smaller than the stored one */
+	    /* then set a new distance and update parent list  */
+	    if (dist < distances[j]) {
+		distances[j] = dist;
+		parents[j] = curmin;
+	    }
+
+	    /* update the next minimum node */
+	    if (distances[nextmin] == 0 ||
+		(distances[j] > 0 && distances[j] < distances[nextmin])) {
+		nextmin = j;
+	    }
+	}
+    }
+}
+
+/*********************************
+ *            INDICES            *
+ *********************************/
+
+void f_connectance_index(DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int p, q;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	DCELL c = 100.0 / (n * (n - 1) * 0.5);
+	DCELL val = 0;
+
+	/* single patch is 100% connected */
+	if (n == 1) {
+	    values[i] = 100.0;
+	    continue;
+	}
+
+	/* for each patch pair in the cluster */
+	for (p = 0; p < cluster_list[i].count - 1; p++) {
+	    for (q = p + 1; q < cluster_list[i].count; q++) {
+		int patch1 = cluster_list[i].first_patch[p];
+		int patch2 = cluster_list[i].first_patch[q];
+
+		if (adjacency_matrix[patch1 * fragcount + patch2] == 1) {
+		    val++;
+		}
+	    }
+	}
+
+	values[i] = 100.0 * val / (n * (n - 1) * 0.5);
+    }
+}
+
+void f_gyration_radius(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	double avg_x = 0.0;
+	double avg_y = 0.0;
+	int count = 0;
+	DCELL val = 0.0;
+
+	/* calculate cluster centroid */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*p].count;
+		 cell_index++) {
+		Coords *cell = fragments[*p].first_cell + cell_index;
+
+		avg_x += cell->x;
+		avg_y += cell->y;
+		count++;
+	    }
+	}
+	avg_x /= (double)count;
+	avg_y /= (double)count;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    val += min_dist_to_location(fragments, *p, avg_x, avg_y);
+	}
+
+	values[i] = val / (double)n;
+    }
+}
+
+void f_cohesion_index(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	int total_area = 0;
+	DCELL num = 0.0;
+	DCELL denom = 0.0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int perim = 0;
+	    int area = fragments[*p].count;
+
+	    /* find perimeter */
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*p].count;
+		 cell_index++) {
+		Coords *cell = fragments[*p].first_cell + cell_index;
+
+		/* if cell is on the edge */
+		if (cell->neighbors < 4) {
+		    perim++;
+		}
+	    }
+
+	    /* update total number of cells in the cluster */
+	    total_area += area;
+
+	    num += (double)perim;
+	    denom += (double)perim *sqrt((double)area);
+	}
+
+	values[i] =
+	    (1.0 - num / denom) / (1.0 -
+				   1.0 / sqrt((double)total_area)) * 100.0;
+    }
+}
+
+void f_percent_patches(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int patch_count = cluster_list[i].count;
+
+	values[i] = (DCELL) patch_count / (DCELL) fragcount *100.0;
+    }
+}
+
+void f_percent_area(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix)
+{
+    int i;
+    int *p, *q;
+    Coords *cell;
+
+    int area_all = 0;
+
+    for (i = 0; i < fragcount; i++) {
+	area_all += fragments[i].count;
+    }
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    area_cluster += fragments[*p].count;
+	}
+
+	values[i] = (DCELL) area_cluster / (DCELL) area_all *100.0;
+    }
+}
+
+void f_number_patches(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	values[i] = (DCELL) cluster_list[i].count;
+    }
+}
+
+void f_number_links(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix)
+{
+    int i;
+    int *p, *q;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int links = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count - 1;
+	     p++) {
+	    /* for each other patch in the cluster */
+	    for (q = p + 1;
+		 q < cluster_list[i].first_patch + cluster_list[i].count;
+		 q++) {
+		if (adjacency_matrix[*q * fragcount + *p] == 1) {
+		    links++;
+		}
+	    }
+	}
+
+	values[i] = (DCELL) links;
+    }
+}
+
+void f_mean_patch_size(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int patch_count = cluster_list[i].count;
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    area_cluster += fragments[*p].count;
+	}
+
+	if (patch_count > 0) {
+	    values[i] = (DCELL) area_cluster / (DCELL) patch_count;
+	}
+	else {
+	    values[i] = 0.0;
+	}
+    }
+}
+
+void f_largest_patch_size(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int max_area = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int area = fragments[*p].count;
+
+	    if (area > max_area) {
+		max_area = area;
+	    }
+	}
+
+	values[i] = (DCELL) max_area;
+    }
+}
+
+DCELL get_diameter(Patch * frags, int n)
+{
+    int p1, p2;
+    DCELL max = 0.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n].count; p1++) {
+	Coords *c1 = frags[n].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = p1 + 1; p2 < frags[n].count; p2++) {
+		Coords *c2 = frags[n].first_cell + p2;
+
+		// if cell at the border
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d > max) {
+			max = d;
+		    }
+		}
+	    }
+	}
+    }
+    return max;
+}
+
+void f_largest_patch_diameter(DCELL * values, Cluster * cluster_list,
+			      int cluster_count, int *adjacency_matrix,
+			      Patch * fragments, int fragcount,
+			      DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	DCELL max_diameter = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    DCELL diameter = get_diameter(fragments, *p);
+
+	    if (diameter > max_diameter) {
+		max_diameter = diameter;
+	    }
+	}
+
+	values[i] = max_diameter;
+    }
+}
+
+/* implements floyd-warshall algorithm for finding shortest pathes */
+void f_graph_diameter_max(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix)
+{
+    int i, j, k;
+
+    /* initialize path matrix */
+    DCELL pathmatrix[fragcount * fragcount * sizeof(DCELL)];
+
+    for (i = 0; i < fragcount; i++) {
+	pathmatrix[i * fragcount + i] = 0.0;
+
+	int j;
+
+	for (j = i + 1; j < fragcount; j++) {
+	    int index = i * fragcount + j;
+	    int index_mirror = j * fragcount + i;
+
+	    if (adjacency_matrix[index]) {
+		pathmatrix[index] = pathmatrix[index_mirror] =
+		    distmatrix[index];
+	    }
+	    else {
+		pathmatrix[index] = pathmatrix[index_mirror] = MAX_DOUBLE;
+	    }
+	}
+    }
+
+    /* for each patch */
+    for (k = 0; k < fragcount; k++) {
+	/* for every other patch */
+	for (i = 0; i < fragcount; i++) {
+	    /* for every third patch */
+	    for (j = 0; j < fragcount; j++) {
+		/* get direct path and detour over p3 */
+		DCELL direct = pathmatrix[i * fragcount + j];
+		DCELL indirect =
+		    pathmatrix[i * fragcount + k] + pathmatrix[k * fragcount +
+							       j];
+
+		/* if detour is shorter */
+		if (indirect < direct) {
+		    pathmatrix[i * fragcount + j] = indirect;
+		}
+	    }
+	}
+    }
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	/* search for the maximum distance between two patches in this cluster */
+	DCELL max_dist = 0.0;
+	int *patch;
+
+	for (patch = cluster_list[i].first_patch;
+	     patch < cluster_list[i].first_patch + cluster_list[i].count - 1;
+	     patch++) {
+	    int *other_patch;
+
+	    for (other_patch = patch + 1;
+		 other_patch <
+		 cluster_list[i].first_patch + cluster_list[i].count;
+		 other_patch++) {
+		DCELL dist = pathmatrix[*patch * fragcount + *other_patch];
+
+		if (dist > max_dist) {
+		    max_dist = dist;
+		}
+	    }
+	}
+
+	values[i] = max_dist;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,112 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    Coords *first_cell;
+    int count;
+} Patch;
+
+typedef struct
+{
+    int *first_patch;
+    int count;
+} Cluster;
+
+typedef void (*f_neighborhood) (int *adjacency_matrix, DCELL * distmatrix,
+				int fragcount, DCELL max_dist);
+typedef void (*f_index) (DCELL * values, Cluster * cluster_list,
+			 int clustercount, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+
+/* frag.c */
+int writeFragments(Patch * fragments, int *flagbuf, int nrows, int ncols,
+		   int nbr_cnt);
+
+/* func.c */
+int get_dist_matrix(DCELL * distmatrix, Patch * fragments, int fragcount);
+
+void f_nearest_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			int fragcount, DCELL max_dist);
+void f_relative_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			 int fragcount, DCELL max_dist);
+void f_gabriel(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+	       DCELL max_dist);
+void f_spanning_tree(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+		     DCELL max_dist);
+
+void f_connectance_index(DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+void f_gyration_radius(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_cohesion_index(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_percent_patches(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_percent_area(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix);
+void f_number_patches(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_number_links(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix);
+void f_mean_patch_size(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_largest_patch_size(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix);
+void f_largest_patch_diameter(DCELL * values, Cluster * cluster_list,
+			      int cluster_count, int *adjacency_matrix,
+			      Patch * fragments, int fragcount,
+			      DCELL * distmatrix);
+void f_graph_diameter_max(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix);
+
+int find_clusters(Cluster * cluster_list, int *adjacency_matrix,
+		  int fragcount);
+
+DCELL nearest_points(Patch * frags, int n1, int n2, Coords * np1,
+		     Coords * np2);
+
+/* draw.c */
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.iter/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.iter/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.iter/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,678 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.graph.iter
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Graph Theory approach for connectivity analysis on patch 
+ *                              level - iterative patch removal option (patch relevance)
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+int recur_test(int, int, int);
+
+struct neighborhood
+{
+    f_neighborhood method;	/* routine to build adjacency matrix */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct index
+{
+    f_index method;		/* routine to calculate cluster index */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct neighborhood neighborhoods[] = {
+    {f_nearest_neighbor, "nearest_neighbor",
+     "patches are connected with their nearest neighbors"},
+    {f_relative_neighbor, "relative_neighbor",
+     "two patches are connected, if no other patch lies in the central lens between them"},
+    {f_gabriel, "gabriel",
+     "two patches are connected, if no other patch lies in the circle on them"},
+    {f_spanning_tree, "spanning_tree",
+     "two patches are connected, if they are neighbors in the minimum spanning tree"},
+    {0, 0, 0}
+};
+
+static struct index indices[] = {
+    {f_connectance_index, "connectance_index", "connectance index"},
+    {f_gyration_radius, "gyration_radius", "radius of gyration"},
+    {f_cohesion_index, "cohesion_index", "cohesion index"},
+    {f_percent_patches, "percent_patches",
+     "percentage of the patches in the cluster"},
+    {f_percent_area, "percent_area",
+     "percentage of the patch area in the cluster"},
+    {f_number_patches, "number_patches", "number of patches in the cluster"},
+    {f_number_links, "number_links", "number of links in the cluster"},
+    {f_mean_patch_size, "mean_patch_size", "mean patch size in the cluster"},
+    {f_largest_patch_size, "largest_patch_size",
+     "largest patch size in the cluster"},
+    {f_largest_patch_diameter, "largest_patch_diameter",
+     "largest patch diameter in the cluster"},
+    {f_graph_diameter_max, "graph_diameter",
+     "longest minimal path in the cluster"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+
+    /* parameters */
+    int keyval;
+    int nbr_count;
+    int index;
+    int neighborhood;
+    DCELL distance;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    char *p;
+    int row, col, i, j, m;
+    int n;
+    f_neighborhood build_graph;
+    f_index calc_index;
+    int *curpos;
+    CELL *result;
+    DCELL *d_res;
+    CELL *clustermap;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output;
+	struct Option *keyval, *distance;
+	struct Option *neighborhood, *index;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *percent;
+    } flag;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Graph Theory - iterative removal (patch relevance analysis).");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_option();
+    parm.output->key = "output";
+    parm.output->type = TYPE_STRING;
+    parm.output->required = YES;
+    parm.output->gisprompt = "new,cell,raster";
+    parm.output->description = _("Name of the new raster file");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.distance = G_define_option();
+    parm.distance->key = "distance";
+    parm.distance->type = TYPE_DOUBLE;
+    parm.distance->required = YES;
+    parm.distance->description =
+	_("Bounding distance [0 for maximum distance]");
+
+    parm.neighborhood = G_define_option();
+    parm.neighborhood->key = "neighborhood";
+    parm.neighborhood->type = TYPE_STRING;
+    parm.neighborhood->required = YES;
+    p = parm.neighborhood->options = G_malloc(1024);
+    for (n = 0; neighborhoods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, neighborhoods[n].name);
+    }
+    parm.neighborhood->description = _("Neighborhood definition");
+
+    parm.index = G_define_option();
+    parm.index->key = "index";
+    parm.index->type = TYPE_STRING;
+    parm.index->required = YES;
+    p = parm.index->options = G_malloc(1024);
+    for (n = 0; indices[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, indices[n].name);
+    }
+    parm.index->description = _("Cluster index");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.percent = G_define_flag();
+    flag.percent->key = 'p';
+    flag.percent->description =
+	_("Defines, if the output should be a percentual of the cluster index values.");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    G_message("rows = %d, cols = %d", nrows, ncols);
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get distance */
+    sscanf(parm.distance->answer, "%lf", &distance);
+    if (distance == 0.0) {
+	distance = MAX_DOUBLE;
+    }
+
+    /* get neighborhood definition */
+    for (neighborhood = 0; (p = neighborhoods[neighborhood].name);
+	 neighborhood++) {
+	if ((strcmp(p, parm.neighborhood->answer) == 0))
+	    break;
+    }
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.neighborhood->key,
+		      parm.neighborhood->answer, parm.neighborhood->key);
+    }
+
+    /* get the cluster index */
+    for (index = 0; (p = indices[index].name); index++)
+	if ((strcmp(p, parm.index->answer) == 0))
+	    break;
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.index->key,
+		      parm.index->answer, parm.index->key);
+    }
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    Coords *cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    Patch *fragments = (Patch *) G_malloc(nrows * ncols * sizeof(Patch));
+
+    fragments[0].first_cell = cells;
+    int *flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+
+    result = G_allocate_c_raster_buf();
+
+    G_message("Loading patches...");
+
+    /* read map */
+    for (row = 0; row < nrows; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /*G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%d", flagbuf[row * ncols + col]);           
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find fragments */
+    int fragcount =
+	writeFragments(fragments, flagbuf, nrows, ncols, nbr_count);
+
+    /* allocate distance matrix */
+    DCELL *distmatrix =
+	(DCELL *) G_malloc(fragcount * fragcount * sizeof(DCELL));
+    memset(distmatrix, 0, fragcount * fragcount * sizeof(DCELL));
+
+    /* generate the distance matrix */
+    get_dist_matrix(distmatrix, fragments, fragcount);
+
+    /*G_message("Distance matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%0.2f ", distmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* build adjacency matrix */
+    int *adjmatrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+
+    memset(adjmatrix, 0, fragcount * fragcount * sizeof(int));
+
+    build_graph = neighborhoods[neighborhood].method;
+    build_graph(adjmatrix, distmatrix, fragcount, distance);
+
+    /*G_message("Adjacency matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%d", adjmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find clusters */
+    int *patches = (int *)G_malloc(fragcount * sizeof(int));
+    Cluster *clusters = (Cluster *) G_malloc((fragcount) * sizeof(Cluster));
+
+    clusters[0].first_patch = patches;
+
+    int clustercount = find_clusters(clusters, adjmatrix, fragcount);
+
+    /*for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, "Cluster_%d:", i);
+       for(curpos = clusters[i]; curpos < clusters[i + 1]; curpos++) {
+       fprintf(stderr, " %d", *curpos);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+    DCELL *ref_values = (DCELL *) G_malloc(clustercount * sizeof(DCELL));
+    DCELL *temp_values = (DCELL *) G_malloc(clustercount * sizeof(DCELL));
+
+    calc_index = indices[index].method;
+    calc_index(ref_values, clusters, clustercount, adjmatrix, fragments,
+	       fragcount, distmatrix);
+
+    /*fprintf(stderr, "Reference values:");
+       for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, " %0.2f", ref_values[i]);
+       }
+       fprintf(stderr, "\n"); */
+
+    /* perform iterative deletion analysis */
+    int *splitter_patches = (int *)G_malloc(fragcount * sizeof(int));
+
+    memset(splitter_patches, 0, fragcount * sizeof(int));
+
+    /* for each patch */
+    G_message("Performing iterative deletion...");
+    for (i = 0; i < fragcount; i++) {
+	int temp_fragcount = fragcount - 1;
+
+	/* delete i-th patch... */
+
+	/* from fragment list */
+	Patch *temp_frags =
+	    (Patch *) G_malloc(temp_fragcount * sizeof(Patch));
+
+	memcpy(temp_frags, fragments, i * sizeof(Patch));
+	memcpy(temp_frags + i, fragments + i + 1,
+	       (fragcount - i - 1) * sizeof(Patch));
+
+	/* from distance matrix */
+	DCELL *temp_distm =
+	    (DCELL *) G_malloc(temp_fragcount * temp_fragcount *
+			       sizeof(DCELL));
+	memset(temp_distm, 0,
+	       temp_fragcount * temp_fragcount * sizeof(DCELL));
+
+	int p1, p2;
+	int tp1 = 0;
+
+	for (p1 = 0; p1 < fragcount; p1++) {
+	    if (p1 != i) {
+		int tp2 = 0;
+
+		for (p2 = 0; p2 < fragcount; p2++) {
+		    if (p2 != i) {
+			DCELL dist = distmatrix[p1 * fragcount + p2];
+
+			temp_distm[tp1 * temp_fragcount + tp2] = dist;
+
+			tp2++;
+		    }
+		    else {
+			continue;
+		    }
+		}
+
+		tp1++;
+	    }
+	    else {
+		continue;
+	    }
+	}
+
+	/* build graph and see if the cluster is splitted */
+	int *temp_adjm = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+
+	memset(temp_adjm, 0, fragcount * fragcount * sizeof(int));
+
+	build_graph(temp_adjm, temp_distm, temp_fragcount, distance);
+
+	/*fprintf(stderr, "\nAdjacency matrix with deleted patch %d\n", i);
+	   for(p1 = 0; p1 < temp_fragcount; p1++) {
+	   for(p2 = 0; p2 < temp_fragcount; p2++) {
+	   fprintf(stderr, "%d ", temp_adjm[p1 * temp_fragcount + p2]);
+	   }
+	   fprintf(stderr, "\n");
+	   } */
+
+	int *temp_p = (int *)G_malloc(fragcount * sizeof(int));
+	Cluster *temp_c = (Cluster *) G_malloc(fragcount * sizeof(Cluster));
+
+	temp_c[0].first_patch = temp_p;
+
+	int temp_cc = find_clusters(temp_c, temp_adjm, temp_fragcount);
+
+	/* G_message("Clustercount = %d", temp_cc); */
+
+	/* if cluster count changed mark patch as splitter */
+	if (temp_cc > clustercount) {
+	    splitter_patches[i] = 1;
+	}
+
+	/* now compare the cluster index with and without patch i */
+	/* delete i-th patch ... */
+
+	/* from adjacency matrix */
+	memcpy(temp_adjm, adjmatrix, fragcount * fragcount * sizeof(int));
+
+	int index;
+
+	for (index = 0; index < fragcount; index++) {
+	    temp_adjm[index * fragcount + i] = 0;
+	    temp_adjm[i * fragcount + index] = 0;
+	}
+
+	/*fprintf(stderr, "\nAdjacency matrix with deleted patch %d\n", i);
+	   for(p1 = 0; p1 < fragcount; p1++) {
+	   for(p2 = 0; p2 < fragcount; p2++) {
+	   fprintf(stderr, "%d ", temp_adjm[p1 * fragcount + p2]);
+	   }
+	   fprintf(stderr, "\n");
+	   } */
+
+	/* from cluster list */
+
+	/* for each cluster */
+	int c;
+	int focal_cluster = -1;
+	int *curpos = temp_p;
+
+	for (c = 0; c < clustercount; c++) {
+	    temp_c[c].first_patch = curpos;
+
+	    /* for each patch in the cluster */
+	    int *patch;
+
+	    for (patch = clusters[c].first_patch;
+		 patch < clusters[c].first_patch + clusters[c].count;
+		 patch++) {
+		/* if patch is deleted */
+		if (*patch == i) {
+		    *curpos = clusters[c].first_patch[clusters[c].count - 1];
+		    focal_cluster = c;
+		}
+		else {
+		    *curpos = *patch;
+		}
+		curpos++;
+	    }
+
+	    temp_c[c].count = clusters[c].count;
+	    if (focal_cluster == c) {
+		temp_c[c].count--;
+	    }
+	}
+
+	calc_index(temp_values, temp_c, clustercount, temp_adjm, fragments,
+		   fragcount, distmatrix);
+
+	/*fprintf(stderr, "Values without patch %d:", i);
+	   for(c = 0; c < clustercount; c++) {
+	   fprintf(stderr, " %0.2f", temp_values[c]);
+	   }
+	   fprintf(stderr, "\n"); */
+
+	values[i] = temp_values[focal_cluster] - ref_values[focal_cluster];
+
+	if (flag.percent->answer) {
+	    values[i] *= 100.0 / ref_values[focal_cluster];
+	}
+
+	G_percent(i + 1, fragcount, 1);
+
+	G_free(temp_frags);
+	G_free(temp_distm);
+	G_free(temp_adjm);
+	G_free(temp_p);
+	G_free(temp_c);
+    }
+
+    G_free(ref_values);
+    G_free(temp_values);
+
+    /* test output */
+    /*fprintf(stderr, "Splitter patches:");
+       for(i = 0; i < fragcount; i++) {
+       fprintf(stderr, " %d", splitter_patches[i]);
+       }
+       fprintf(stderr, "\n"); */
+
+    /* write output */
+    G_message("Writing output...");
+
+    /* ================================== 
+       ============  output  ============ 
+       ================================== */
+
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* allocate result row variable */
+    d_res = G_allocate_d_raster_buf();
+
+    /* write values */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(d_res, ncols);
+
+	int patch_index;
+
+	for (patch_index = 0; patch_index < fragcount; patch_index++) {
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[patch_index].count;
+		 cell_index++) {
+		Coords *cell = fragments[patch_index].first_cell + cell_index;
+
+		if (cell->y == row) {
+		    d_res[cell->x] = values[patch_index];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(row + 1, 2 * nrows, 1);
+    }
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+    /* write splitter patch map */
+    /* open the new cellfile  */
+    sprintf(fullname, "%s_split", newname);
+    out_fd = G_open_raster_new(fullname, CELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+    /* allocate result row variable */
+    d_res = G_allocate_d_raster_buf();
+
+    /* write values */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(d_res, ncols);
+
+	for (i = 0; i < clustercount; i++) {
+	    for (curpos = clusters[i].first_patch;
+		 curpos < clusters[i].first_patch + clusters[i].count;
+		 curpos++) {
+		int cell_index;
+
+		for (cell_index = 0; cell_index < fragments[*curpos].count;
+		     cell_index++) {
+		    Coords *cell = fragments[*curpos].first_cell + cell_index;
+
+		    if (cell->y == row) {
+			d_res[cell->x] =
+			    splitter_patches[*curpos] ? -(i + 1) : i + 1;
+		    }
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(row + 1, 2 * nrows, 1);
+    }
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+    /* ================================== 
+       ==========  cluster map  ========= 
+       ================================== */
+
+    /* open the new cellfile */
+    sprintf(fullname, "%s_clusters", newname);
+    out_fd = G_open_raster_new(fullname, CELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), fullname);
+
+    /* allocate and initialize the clustermap */
+    clustermap = (CELL *) G_malloc(nrows * ncols * sizeof(CELL));
+    G_set_c_null_value(clustermap, nrows * ncols);
+
+    /* for each cluster */
+    for (i = 0; i < clustercount; i++) {
+	/* for each patch in the cluster */
+	int *this;
+
+	for (this = clusters[i].first_patch;
+	     this < clusters[i].first_patch + clusters[i].count; this++) {
+	    /* for each cell in the patch */
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*this].count;
+		 cell_index++) {
+		Coords *cell = fragments[*this].first_cell + cell_index;
+
+		clustermap[cell->y * ncols + cell->x] = i;
+	    }
+
+	    /* for each patch in the cluster */
+	    int *other;
+
+	    for (other = this + 1;
+		 other < clusters[i].first_patch + clusters[i].count;
+		 other++) {
+		if (*other != *this && adjmatrix[*this * fragcount + *other]) {
+		    Coords np1, np2;
+
+		    nearest_points(fragments, *this, *other, &np1, &np2);
+
+		    draw_line(clustermap, -1, np1.x, np1.y, np2.x, np2.y,
+			      ncols, nrows, 1);
+		}
+	    }
+	}
+    }
+
+    /* write output */
+    for (row = 0; row < nrows; row++) {
+	G_put_c_raster_row(out_fd, clustermap + row * ncols);
+
+	G_percent(nrows + row + 1, 2 * nrows, 1);
+    }
+
+    G_free(clustermap);
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+
+    /* =============================
+       =======  free memory  =======
+       ============================= */
+    G_free(values);
+    G_free(patches);
+    G_free(clusters);
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+    G_free(result);
+    G_free(d_res);
+    G_free(splitter_patches);
+
+    G_free(distmatrix);
+    G_free(adjmatrix);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.iter/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.graph.red
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Graph Theory - decreasing distance threshold option. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/draw.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/draw.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/draw.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,60 @@
+#include "local_proto.h"
+
+inline void swap(int *a, int *b)
+{
+    int zw = *a;
+
+    *a = *b;
+    *b = zw;
+}
+
+void draw_point(int *map, int val, int x, int y, int sx, int sy, int width)
+{
+    if (width <= 0) {
+	return;
+    }
+
+    if (width == 1) {
+	map[y * sx + x] = val;
+    }
+    else {
+    }
+}
+
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width)
+{
+    int steep = abs(y2 - y1) > abs(x2 - x1);
+
+    if (steep) {
+	swap(&x1, &y1);
+	swap(&x2, &y2);
+    }
+
+    if (x1 > x2) {
+	swap(&x1, &x2);
+	swap(&y1, &y2);
+    }
+
+    int deltax = x2 - x1;
+    int deltay = abs(y2 - y1);
+    int error = deltax / 2;
+    int ystep = y1 < y2 ? 1 : -1;
+    int x;
+    int y = y1;
+
+    for (x = x1; x <= x2; x++) {
+	if (steep) {
+	    draw_point(map, val, y, x, sx, sy, width);
+	}
+	else {
+	    draw_point(map, val, x, y, sx, sy, width);
+	}
+
+	error -= deltay;
+	if (error < 0) {
+	    y += ystep;
+	    error += deltax;
+	}
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/draw.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,170 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * curpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * curpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    curpos->x = col;
+    curpos->y = row;
+    curpos->neighbors = neighbors;
+    curpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    curpos->x = x;
+	    curpos->y = y;
+	    curpos->neighbors = neighbors;
+	    curpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return curpos;
+}
+
+int writeFragments(Patch * fragments, int *flagbuf, int nrows, int ncols,
+		   int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+    int fragcount = 0;
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount].first_cell =
+		    writeFrag(flagbuf, fragments[fragcount - 1].first_cell,
+			      row, col, nrows, ncols, nbr_cnt);
+		fragments[fragcount - 1].count =
+		    fragments[fragcount].first_cell - fragments[fragcount -
+								1].first_cell;
+	    }
+	}
+    }
+
+    return fragcount;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,757 @@
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Patch * frags, int n1, int n2)
+{
+    int p1, p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n1].count; p1++) {
+	Coords *c1 = frags[n1].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = 0; p2 < frags[n2].count; p2++) {
+		// if cell at the border
+		Coords *c2 = frags[n2].first_cell + p2;
+
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL nearest_points(Patch * frags, int n1, int n2, Coords * np1,
+		     Coords * np2)
+{
+    int p1, p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n1].count; p1++) {
+	Coords *c1 = frags[n1].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = 0; p2 < frags[n2].count; p2++) {
+		Coords *c2 = frags[n2].first_cell + p2;
+
+		// if cell at the border
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d < min) {
+			min = d;
+			*np1 = *c1;
+			*np2 = *c2;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL min_dist_to_location(Patch * frags, int patch, double loc_x,
+			   double loc_y)
+{
+    int p;
+    DCELL min = MAX_DOUBLE;
+
+    // for all cells in the first patch
+    for (p = 0; p < frags[patch].count; p++) {
+	Coords *cell = frags[patch].first_cell + p;
+
+	// if cell at the border
+	if (cell->neighbors < 4) {
+	    DCELL dx = loc_x - cell->x;
+	    DCELL dy = loc_y - cell->y;
+	    DCELL d = sqrt(dx * dx + dy * dy);
+
+	    if (d < min) {
+		min = d;
+	    }
+	}
+    }
+    return min;
+}
+
+int get_dist_matrix(DCELL * distmatrix, Patch * fragments, int fragcount)
+{
+    int i, j;
+
+    /* fill distance matrix */
+    for (i = 0; i < fragcount; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * fragcount + j] = d;
+	    distmatrix[j * fragcount + i] = d;
+	}
+    }
+
+    return 0;
+}
+
+int get_nearest_neighbor(DCELL * distmatrix, int fragcount, int patch)
+{
+    int i;
+    int min = -1;
+    DCELL min_dist = MAX_DOUBLE;
+    int offset = patch * fragcount;
+
+    for (i = 0; i < fragcount; i++) {
+	if ((i != patch) && (distmatrix[offset + i] < min_dist)) {
+	    min_dist = distmatrix[offset + i];
+	    min = i;
+	}
+    }
+
+    return min;
+}
+
+int *find_cluster(int *adjacency_matrix, int patch, int fragcount,
+		  int *curpos, int *flag_arr)
+{
+    int i;
+    int *p;
+    int list[fragcount];
+    int *first = list;
+    int *last = list + 1;
+    int offset;
+
+    list[0] = patch;
+    flag_arr[patch] = 1;
+
+    while (first < last) {
+	/* save patch */
+	*curpos = *first;
+	curpos++;
+
+	/* add unclassified neighbors to the list */
+	offset = (*first) * fragcount;
+	for (i = 0; i < fragcount; i++) {
+	    if (adjacency_matrix[offset + i] == 1 && flag_arr[i] == 0) {
+		flag_arr[i] = 1;
+		*last = i;
+		last++;
+	    }
+	}
+
+	/* pass processed patch */
+	first++;
+    }
+
+    return curpos;
+}
+
+int find_clusters(Cluster * cluster_list, int *adjacency_matrix,
+		  int fragcount)
+{
+    int i;
+
+    int count = 0;
+
+    int flag_arr[fragcount];
+
+    memset(flag_arr, 0, fragcount * sizeof(int));
+
+    int *curpos = cluster_list[0].first_patch;
+
+    for (i = 0; i < fragcount; i++) {
+	if (flag_arr[i] == 0) {
+	    cluster_list[count].first_patch = curpos;
+	    curpos =
+		find_cluster(adjacency_matrix, i, fragcount, curpos,
+			     flag_arr);
+	    cluster_list[count].count =
+		curpos - cluster_list[count].first_patch;
+	    count++;
+	}
+    }
+
+    /* debug output */
+    /*fprintf(stderr, "Clusters:\n");
+       for(i = 0; i < count; i++) {
+       int j;
+       for(j = 0; j < cluster_list[i].count; j++) {
+       int patch = cluster_list[i].first_patch[j];
+       fprintf(stderr, "%d ", patch);                       
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    return count;
+}
+
+void f_nearest_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			int fragcount, DCELL max_dist)
+{
+    int i;
+
+    for (i = 0; i < fragcount; i++) {
+	int nn = get_nearest_neighbor(distmatrix, fragcount, i);
+
+	if (nn > -1 && distmatrix[i * fragcount + nn] < max_dist) {
+	    adjacency_matrix[i * fragcount + nn] = 1;
+	    adjacency_matrix[nn * fragcount + i] = 1;
+	}
+    }
+}
+
+void f_relative_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			 int fragcount, DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjacency_matrix[i * fragcount + j] = 1;
+	    adjacency_matrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the central lens between i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if (dist1 < dist && dist2 < dist) {
+		    /* i-th and j-th patches are not connected */
+		    adjacency_matrix[i * fragcount + j] = 0;
+		    adjacency_matrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_gabriel(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+	       DCELL max_dist)
+{
+    int i, j, k;
+
+    for (i = 0; i < fragcount - 1; i++) {
+	for (j = i + 1; j < fragcount; j++) {
+	    DCELL dist = distmatrix[i * fragcount + j];
+
+	    /* not connected, if distance is too big */
+	    if (dist >= max_dist)
+		continue;
+
+	    /* assume i-th and j-th patches are connected */
+	    adjacency_matrix[i * fragcount + j] = 1;
+	    adjacency_matrix[j * fragcount + i] = 1;
+
+	    /* test if other patch is in the circle around i-th and j-th patches */
+	    for (k = 0; k < fragcount; k++) {
+		DCELL dist1, dist2;
+		int offset;
+
+		/* skip i-th and j-th patches */
+		if (k == i || k == j)
+		    continue;
+
+		offset = k * fragcount;
+		dist1 = distmatrix[offset + i];
+		dist2 = distmatrix[offset + j];
+
+		if ((dist1 * dist1 + dist2 * dist2) < (dist * dist)) {
+		    /* i-th and j-th patches are not connected */
+		    adjacency_matrix[i * fragcount + j] = 0;
+		    adjacency_matrix[j * fragcount + i] = 0;
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+void f_spanning_tree(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+		     DCELL max_dist)
+{
+    int i, j;
+    int parents[fragcount];
+    DCELL distances[fragcount];
+    int curmin;
+    int nextmin = 0;
+    int parent;
+
+    /* init parents and distances list */
+    for (i = 0; i < fragcount; i++) {
+	parents[i] = -1;
+	distances[i] = MAX_DOUBLE;
+    }
+
+    /* repeat for each patch */
+    for (i = 0; i < fragcount; i++) {
+	/* pass on next minimum node */
+	curmin = nextmin;
+	nextmin = 0;
+
+	/* connect current minimum node with its parent and set distance to 0    */
+	/* connect only if parent is assigned and distance is less than max_dist */
+	if ((parent = parents[curmin]) != -1 &&
+	    distmatrix[parent * fragcount + curmin] < max_dist) {
+	    adjacency_matrix[curmin * fragcount + parent] = 1;
+	    adjacency_matrix[parent * fragcount + curmin] = 1;
+	}
+	distances[curmin] = 0.0;
+
+	/* debug output */
+	/*G_message("New patch: %d, connecting to patch %d", curmin, parents[curmin]); */
+
+	/* find the next node for minimum spanning tree */
+	for (j = 0; j < fragcount; j++) {
+	    /* skip the current minimum node */
+	    if (j == curmin)
+		continue;
+
+	    /* get distance to the current minimum node */
+	    DCELL dist = distmatrix[curmin * fragcount + j];
+
+	    /* if this distance is smaller than the stored one */
+	    /* then set a new distance and update parent list  */
+	    if (dist < distances[j]) {
+		distances[j] = dist;
+		parents[j] = curmin;
+	    }
+
+	    /* update the next minimum node */
+	    if (distances[nextmin] == 0 ||
+		(distances[j] > 0 && distances[j] < distances[nextmin])) {
+		nextmin = j;
+	    }
+	}
+    }
+}
+
+/*********************************
+ *            INDICES            *
+ *********************************/
+
+void f_connectance_index(DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int p, q;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	DCELL c = 100.0 / (n * (n - 1) * 0.5);
+	DCELL val = 0;
+
+	/* single patch is 100% connected */
+	if (n == 1) {
+	    values[i] = 100.0;
+	    continue;
+	}
+
+	/* for each patch pair in the cluster */
+	for (p = 0; p < cluster_list[i].count - 1; p++) {
+	    for (q = p + 1; q < cluster_list[i].count; q++) {
+		int patch1 = cluster_list[i].first_patch[p];
+		int patch2 = cluster_list[i].first_patch[q];
+
+		if (adjacency_matrix[patch1 * fragcount + patch2] == 1) {
+		    val++;
+		}
+	    }
+	}
+
+	values[i] = 100.0 * val / (n * (n - 1) * 0.5);
+    }
+}
+
+void f_gyration_radius(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	double avg_x = 0.0;
+	double avg_y = 0.0;
+	int count = 0;
+	DCELL val = 0.0;
+
+	/* calculate cluster centroid */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*p].count;
+		 cell_index++) {
+		Coords *cell = fragments[*p].first_cell + cell_index;
+
+		avg_x += cell->x;
+		avg_y += cell->y;
+		count++;
+	    }
+	}
+	avg_x /= (double)count;
+	avg_y /= (double)count;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    val += min_dist_to_location(fragments, *p, avg_x, avg_y);
+	}
+
+	values[i] = val / (double)n;
+    }
+}
+
+void f_cohesion_index(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int n = cluster_list[i].count;
+	int total_area = 0;
+	DCELL num = 0.0;
+	DCELL denom = 0.0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int perim = 0;
+	    int area = fragments[*p].count;
+
+	    /* find perimeter */
+	    int cell_index;
+
+	    for (cell_index = 0; cell_index < fragments[*p].count;
+		 cell_index++) {
+		Coords *cell = fragments[*p].first_cell + cell_index;
+
+		/* if cell is on the edge */
+		if (cell->neighbors < 4) {
+		    perim++;
+		}
+	    }
+
+	    /* update total number of cells in the cluster */
+	    total_area += area;
+
+	    num += (double)perim;
+	    denom += (double)perim *sqrt((double)area);
+	}
+
+	values[i] =
+	    (1.0 - num / denom) / (1.0 -
+				   1.0 / sqrt((double)total_area)) * 100.0;
+    }
+}
+
+void f_percent_patches(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int patch_count = cluster_list[i].count;
+
+	values[i] = (DCELL) patch_count / (DCELL) fragcount *100.0;
+    }
+}
+
+void f_percent_area(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix)
+{
+    int i;
+    int *p, *q;
+    Coords *cell;
+
+    int area_all = 0;
+
+    for (i = 0; i < fragcount; i++) {
+	area_all += fragments[i].count;
+    }
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    area_cluster += fragments[*p].count;
+	}
+
+	values[i] = (DCELL) area_cluster / (DCELL) area_all *100.0;
+    }
+}
+
+void f_number_patches(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	values[i] = (DCELL) cluster_list[i].count;
+    }
+}
+
+void f_number_links(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix)
+{
+    int i;
+    int *p, *q;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int links = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count - 1;
+	     p++) {
+	    /* for each other patch in the cluster */
+	    for (q = p + 1;
+		 q < cluster_list[i].first_patch + cluster_list[i].count;
+		 q++) {
+		if (adjacency_matrix[*q * fragcount + *p] == 1) {
+		    links++;
+		}
+	    }
+	}
+
+	values[i] = (DCELL) links;
+    }
+}
+
+void f_mean_patch_size(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int patch_count = cluster_list[i].count;
+	int area_cluster = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    area_cluster += fragments[*p].count;
+	}
+
+	if (patch_count > 0) {
+	    values[i] = (DCELL) area_cluster / (DCELL) patch_count;
+	}
+	else {
+	    values[i] = 0.0;
+	}
+    }
+}
+
+void f_largest_patch_size(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	int max_area = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    int area = fragments[*p].count;
+
+	    if (area > max_area) {
+		max_area = area;
+	    }
+	}
+
+	values[i] = (DCELL) max_area;
+    }
+}
+
+DCELL get_diameter(Patch * frags, int n)
+{
+    int p1, p2;
+    DCELL max = 0.0;
+
+    // for all cells in the first patch
+    for (p1 = 0; p1 < frags[n].count; p1++) {
+	Coords *c1 = frags[n].first_cell + p1;
+
+	// if cell at the border
+	if (c1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = p1 + 1; p2 < frags[n].count; p2++) {
+		Coords *c2 = frags[n].first_cell + p2;
+
+		// if cell at the border
+		if (c2->neighbors < 4) {
+		    DCELL d = dist(c1, c2);
+
+		    if (d > max) {
+			max = d;
+		    }
+		}
+	    }
+	}
+    }
+    return max;
+}
+
+void f_largest_patch_diameter(DCELL * values, Cluster * cluster_list,
+			      int cluster_count, int *adjacency_matrix,
+			      Patch * fragments, int fragcount,
+			      DCELL * distmatrix)
+{
+    int i;
+    int *p;
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	DCELL max_diameter = 0;
+
+	/* for each patch in the cluster */
+	for (p = cluster_list[i].first_patch;
+	     p < cluster_list[i].first_patch + cluster_list[i].count; p++) {
+	    DCELL diameter = get_diameter(fragments, *p);
+
+	    if (diameter > max_diameter) {
+		max_diameter = diameter;
+	    }
+	}
+
+	values[i] = max_diameter;
+    }
+}
+
+/* implements floyd-warshall algorithm for finding shortest pathes */
+void f_graph_diameter_max(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix)
+{
+    int i, j, k;
+
+    /* initialize path matrix */
+    DCELL pathmatrix[fragcount * fragcount * sizeof(DCELL)];
+
+    for (i = 0; i < fragcount; i++) {
+	pathmatrix[i * fragcount + i] = 0.0;
+
+	int j;
+
+	for (j = i + 1; j < fragcount; j++) {
+	    int index = i * fragcount + j;
+	    int index_mirror = j * fragcount + i;
+
+	    if (adjacency_matrix[index]) {
+		pathmatrix[index] = pathmatrix[index_mirror] =
+		    distmatrix[index];
+	    }
+	    else {
+		pathmatrix[index] = pathmatrix[index_mirror] = MAX_DOUBLE;
+	    }
+	}
+    }
+
+    /* for each patch */
+    for (k = 0; k < fragcount; k++) {
+	/* for every other patch */
+	for (i = 0; i < fragcount; i++) {
+	    /* for every third patch */
+	    for (j = 0; j < fragcount; j++) {
+		/* get direct path and detour over p3 */
+		DCELL direct = pathmatrix[i * fragcount + j];
+		DCELL indirect =
+		    pathmatrix[i * fragcount + k] + pathmatrix[k * fragcount +
+							       j];
+
+		/* if detour is shorter */
+		if (indirect < direct) {
+		    pathmatrix[i * fragcount + j] = indirect;
+		}
+	    }
+	}
+    }
+
+    /* for each cluster */
+    for (i = 0; i < cluster_count; i++) {
+	/* search for the maximum distance between two patches in this cluster */
+	DCELL max_dist = 0.0;
+	int *patch;
+
+	for (patch = cluster_list[i].first_patch;
+	     patch < cluster_list[i].first_patch + cluster_list[i].count - 1;
+	     patch++) {
+	    int *other_patch;
+
+	    for (other_patch = patch + 1;
+		 other_patch <
+		 cluster_list[i].first_patch + cluster_list[i].count;
+		 other_patch++) {
+		DCELL dist = pathmatrix[*patch * fragcount + *other_patch];
+
+		if (dist > max_dist) {
+		    max_dist = dist;
+		}
+	    }
+	}
+
+	values[i] = max_dist;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,124 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    Coords *first_cell;
+    int count;
+} Patch;
+
+typedef struct
+{
+    int *first_patch;
+    int count;
+} Cluster;
+
+typedef void (*f_neighborhood) (int *adjacency_matrix, DCELL * distmatrix,
+				int fragcount, DCELL max_dist);
+typedef void (*f_index) (DCELL * values, Cluster * cluster_list,
+			 int clustercount, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+typedef DCELL(*f_statmethod) (DCELL * vals, int count);
+
+
+/* frag.c */
+int writeFragments(Patch * fragments, int *flagbuf, int nrows, int ncols,
+		   int nbr_cnt);
+
+/* func.c */
+int get_dist_matrix(DCELL * distmatrix, Patch * fragments, int fragcount);
+
+void f_nearest_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			int fragcount, DCELL max_dist);
+void f_relative_neighbor(int *adjacency_matrix, DCELL * distmatrix,
+			 int fragcount, DCELL max_dist);
+void f_gabriel(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+	       DCELL max_dist);
+void f_spanning_tree(int *adjacency_matrix, DCELL * distmatrix, int fragcount,
+		     DCELL max_dist);
+
+void f_connectance_index(DCELL * values, Cluster * cluster_list,
+			 int cluster_count, int *adjacency_matrix,
+			 Patch * fragments, int fragcount,
+			 DCELL * distmatrix);
+void f_gyration_radius(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_cohesion_index(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_percent_patches(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_percent_area(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix);
+void f_number_patches(DCELL * values, Cluster * cluster_list,
+		      int cluster_count, int *adjacency_matrix,
+		      Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_number_links(DCELL * values, Cluster * cluster_list, int cluster_count,
+		    int *adjacency_matrix, Patch * fragments, int fragcount,
+		    DCELL * distmatrix);
+void f_mean_patch_size(DCELL * values, Cluster * cluster_list,
+		       int cluster_count, int *adjacency_matrix,
+		       Patch * fragments, int fragcount, DCELL * distmatrix);
+void f_largest_patch_size(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix);
+void f_largest_patch_diameter(DCELL * values, Cluster * cluster_list,
+			      int cluster_count, int *adjacency_matrix,
+			      Patch * fragments, int fragcount,
+			      DCELL * distmatrix);
+void f_graph_diameter_max(DCELL * values, Cluster * cluster_list,
+			  int cluster_count, int *adjacency_matrix,
+			  Patch * fragments, int fragcount,
+			  DCELL * distmatrix);
+
+int find_clusters(Cluster * cluster_list, int *adjacency_matrix,
+		  int fragcount);
+
+DCELL nearest_points(Patch * frags, int n1, int n2, Coords * np1,
+		     Coords * np2);
+
+/* stat_methods.c */
+
+DCELL average(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+
+/* draw.c */
+void draw_line(int *map, int val, int x1, int y1, int x2, int y2, int sx,
+	       int sy, int width);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,502 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.graph.red
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Graph Theory approach for connectivity analysis on patch 
+ *                               level - decreasing distance threshold option
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct neighborhood
+{
+    f_neighborhood method;	/* routine to build adjacency matrix */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct index
+{
+    f_index method;		/* routine to calculate cluster index */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+struct statmethod
+{
+    f_statmethod method;	/* routine to compute statistical value */
+    char *name;			/* method name */
+    char *suffix;		/* abbreviation to be displayed in the output */
+    char *text;			/* menu display - full description */
+};
+
+static struct neighborhood neighborhoods[] = {
+    {f_nearest_neighbor, "nearest_neighbor",
+     "patches are connected with their nearest neighbors"},
+    {f_relative_neighbor, "relative_neighbor",
+     "two patches are connected, if no other patch lies in the central lens between them"},
+    {f_gabriel, "gabriel",
+     "two patches are connected, if no other patch lies in the circle on them"},
+    {f_spanning_tree, "spanning_tree",
+     "two patches are connected, if they are neighbors in the minimum spanning tree"},
+    {0, 0, 0}
+};
+
+static struct index indices[] = {
+    {f_connectance_index, "connectance_index", "connectance index"},
+    {f_gyration_radius, "gyration_radius", "radius of gyration"},
+    {f_cohesion_index, "cohesion_index", "cohesion index"},
+    {f_percent_patches, "percent_patches",
+     "percentage of the patches in the cluster"},
+    {f_percent_area, "percent_area",
+     "percentage of the patch area in the cluster"},
+    {f_number_patches, "number_patches", "number of patches in the cluster"},
+    {f_number_links, "number_links", "number of links in the cluster"},
+    {f_mean_patch_size, "mean_patch_size", "mean patch size in the cluster"},
+    {f_largest_patch_size, "largest_patch_size",
+     "largest patch size in the cluster"},
+    {f_largest_patch_diameter, "largest_patch_diameter",
+     "largest patch diameter in the cluster"},
+    {f_graph_diameter_max, "graph_diameter",
+     "longest minimal path in the cluster"},
+    {0, 0, 0}
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "avg", "average of the values"},
+    {median, "median", "med", "median of the values"},
+    {variance, "variance", "var", "variance of the values"},
+    {std_deviat, "std_deviat", "std", "standard deviation of the values"},
+    {min, "min", "min", "minimum of the values"},
+    {max, "max", "max", "maximum of the values"},
+    {0, 0, 0}
+};
+
+
+int main(int argc, char *argv[])
+{
+    /* result */
+    int exitres = 0;
+
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+    FILE *out_fp;		/* ASCII - output */
+
+    /* parameters */
+    int keyval;
+    int nbr_count;
+    int index[GNAME_MAX];
+    int index_count;
+    int neighborhood;
+    int statmethod;
+    DCELL distance;
+    DCELL step;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    char *p;
+    int row, col, i, j, m;
+    int n;
+    f_neighborhood build_graph;
+    f_index calc_index;
+    f_statmethod calc_stat;
+    int *curpos;
+    CELL *result;
+    DCELL *d_res;
+    CELL *clustermap;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output;
+	struct Option *keyval, *distance, *step;
+	struct Option *neighborhood, *index, *stats;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent;
+    } flag;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Graph Theory - decreasing distance threshold option.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_option();
+    parm.output->key = "output";
+    parm.output->type = TYPE_STRING;
+    parm.output->required = YES;
+    parm.output->gisprompt = "new_file,file,output";
+    parm.output->description = _("Name of the output ASCII file");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.distance = G_define_option();
+    parm.distance->key = "distance";
+    parm.distance->type = TYPE_DOUBLE;
+    parm.distance->required = YES;
+    parm.distance->description = _("Distance at which to begin decreasing");
+
+    parm.step = G_define_option();
+    parm.step->key = "step";
+    parm.step->type = TYPE_DOUBLE;
+    parm.step->required = YES;
+    parm.step->description = _("Step to decrease the distance");
+
+    parm.neighborhood = G_define_option();
+    parm.neighborhood->key = "neighborhood";
+    parm.neighborhood->type = TYPE_STRING;
+    parm.neighborhood->required = YES;
+    p = parm.neighborhood->options = G_malloc(1024);
+    for (n = 0; neighborhoods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, neighborhoods[n].name);
+    }
+    parm.neighborhood->description = _("Neighborhood definition");
+
+    parm.index = G_define_option();
+    parm.index->key = "index";
+    parm.index->type = TYPE_STRING;
+    parm.index->required = YES;
+    parm.index->multiple = YES;
+    p = parm.index->options = G_malloc(1024);
+    for (n = 0; indices[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, indices[n].name);
+    }
+    parm.index->description = _("Cluster index");
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    p = parm.stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, statmethods[n].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the values");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    G_message("rows = %d, cols = %d", nrows, ncols);
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get distance */
+    sscanf(parm.distance->answer, "%lf", &distance);
+
+    /* get step */
+    sscanf(parm.step->answer, "%lf", &step);
+
+    /* get neighborhood definition */
+    for (neighborhood = 0; (p = neighborhoods[neighborhood].name);
+	 neighborhood++) {
+	if ((strcmp(p, parm.neighborhood->answer) == 0))
+	    break;
+    }
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.neighborhood->key,
+		      parm.neighborhood->answer, parm.neighborhood->key);
+	exit(EXIT_FAILURE);
+    }
+
+    /* get the cluster indices */
+    for (index_count = 0; parm.index->answers[index_count]; index_count++) {
+	int idx;
+
+	for (idx = 0; (p = indices[idx].name); idx++) {
+	    if ((strcmp(p, parm.index->answers[index_count]) == 0)) {
+		break;
+	    }
+	}
+
+	if (!p) {
+	    G_fatal_error("<%s=%s> unknown %s", parm.index->key,
+			  parm.index->answers[index_count], parm.index->key);
+	    exit(EXIT_FAILURE);
+	}
+
+	index[index_count] = idx;
+    }
+
+    /* get the statmethod */
+    for (statmethod = 0; (p = statmethods[statmethod].name); statmethod++)
+	if ((strcmp(p, parm.stats->answer) == 0))
+	    break;
+    if (!p) {
+	G_fatal_error("<%s=%s> unknown %s", parm.stats->key,
+		      parm.stats->answer, parm.stats->key);
+    }
+    calc_stat = statmethods[statmethod].method;
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    Coords *cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    Patch *fragments = (Patch *) G_malloc(nrows * ncols * sizeof(Patch));
+
+    fragments[0].first_cell = cells;
+    int *flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+
+    result = G_allocate_c_raster_buf();
+
+    G_message("Loading patches...");
+
+    /* read map */
+    for (row = 0; row < nrows; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /*G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%d", flagbuf[row * ncols + col]);           
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* find fragments */
+    int fragcount =
+	writeFragments(fragments, flagbuf, nrows, ncols, nbr_count);
+
+    /* allocate distance matrix */
+    DCELL *distmatrix =
+	(DCELL *) G_malloc(fragcount * fragcount * sizeof(DCELL));
+    memset(distmatrix, 0, fragcount * fragcount * sizeof(DCELL));
+
+    /* generate the distance matrix */
+    get_dist_matrix(distmatrix, fragments, fragcount);
+
+    /* allocate adjacency matrix */
+    int *adjmatrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+
+    /* allocate clusters */
+    int *patches = (int *)G_malloc(fragcount * sizeof(int));
+    Cluster *clusters = (Cluster *) G_malloc((fragcount) * sizeof(Cluster));
+
+    clusters[0].first_patch = patches;
+
+    /* set build_graph routine */
+    build_graph = neighborhoods[neighborhood].method;
+
+    /*G_message("Distance matrix:");
+       for(row = 0; row < fragcount; row++) {
+       for(col = 0; col < fragcount; col++) {
+       fprintf(stderr, "%0.2f ", distmatrix[row * fragcount + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    int val_rows = (int)(distance / step) + 1;
+
+    /* values = (clustercount, cluster1_index1, cluster2_index1, ...), () */
+    DCELL *values =
+	(DCELL *) G_malloc(val_rows * index_count * fragcount *
+			   sizeof(DCELL));
+
+    int *cluster_counts = (int *)G_malloc(val_rows * sizeof(int));
+
+    /*      calc_index = indices[index].method;
+       calc_index(ref_values, clusters, clustercount, adjmatrix, fragments, fragcount, distmatrix);
+
+       /*fprintf(stderr, "Reference values:");
+       for(i = 0; i < clustercount; i++) {
+       fprintf(stderr, " %0.2f", ref_values[i]);
+       }
+       fprintf(stderr, "\n"); */
+
+    /* perform distance reduction analysis */
+    /* for each patch */
+    G_message("Performing distance reduction...");
+    DCELL temp_d = distance;
+
+    for (i = 0; i < val_rows; i++, temp_d -= step) {
+	/* build graph with current distance */
+	memset(adjmatrix, 0, fragcount * fragcount * sizeof(int));
+	build_graph(adjmatrix, distmatrix, fragcount, temp_d);
+
+	/*fprintf(stderr, "\nAdjacency matrix with deleted patch %d\n", i);
+	   for(p1 = 0; p1 < temp_fragcount; p1++) {
+	   for(p2 = 0; p2 < temp_fragcount; p2++) {
+	   fprintf(stderr, "%d ", temp_adjm[p1 * temp_fragcount + p2]);
+	   }
+	   fprintf(stderr, "\n");
+	   } */
+
+	/* find clusters */
+	cluster_counts[i] = find_clusters(clusters, adjmatrix, fragcount);
+
+	/* calculate and save indices */
+	int idx;
+	DCELL *vals = &(values[i * index_count * fragcount]);
+
+	for (idx = 0; idx < index_count; idx++, vals += fragcount) {
+	    int cur_index = index[idx];
+
+	    calc_index = indices[cur_index].method;
+	    calc_index(vals, clusters, cluster_counts[i], adjmatrix,
+		       fragments, fragcount, distmatrix);
+	}
+
+	G_percent(i + 1, fragcount, 1);
+    }
+
+    /* test output */
+    fprintf(stderr, "Values:");
+    for (row = 0; row < val_rows; row++) {
+	fprintf(stderr, "\n");
+	fprintf(stderr, "Clusters: %d --- ", cluster_counts[row]);
+	for (i = 0; i < index_count * fragcount; i++) {
+	    fprintf(stderr, "%0.2f ",
+		    values[row * index_count * fragcount + i]);
+	}
+    }
+    fprintf(stderr, "\n");
+
+    /* write output */
+    G_message("Writing output...");
+
+    /* ================================== 
+       ============  output  ============ 
+       ================================== */
+
+    /* open ASCII-file or use stdout */
+    if (strcmp(parm.output->answer, "-") != 0) {
+	if (!(out_fp = fopen(parm.output->answer, "w"))) {
+	    G_fatal_error(_("Error creating file <%s>"),
+			  parm.output->answer);
+	}
+    }
+    else {
+	out_fp = stdout;
+    }
+
+    /* write header */
+    fprintf(out_fp, "distance cluster_count");
+    for (i = 0; i < index_count; i++) {
+	fprintf(out_fp, " %s", indices[index[i]].name);
+    }
+    fprintf(out_fp, "\n");
+
+    /* write values */
+    temp_d = distance;
+    for (i = 0; i < val_rows; i++, temp_d -= step) {
+	fprintf(out_fp, "%lf %d", temp_d, cluster_counts[i]);
+
+	int idx;
+	DCELL *vals = &(values[i * index_count * fragcount]);
+
+	for (idx = 0; idx < index_count; idx++, vals += fragcount) {
+	    int cur_index = index[idx];
+
+	    DCELL val = calc_stat(vals, cluster_counts[i]);
+
+	    fprintf(out_fp, " %lf", val);
+	}
+
+	fprintf(out_fp, "\n");
+    }
+
+    /* close output file */
+    if (strcmp(parm.output->answer, "-") != 0) {
+	fclose(out_fp);
+    }
+
+
+    /* =============================
+       =======  free memory  =======
+       ============================= */
+    G_free(cluster_counts);
+    G_free(values);
+    G_free(patches);
+    G_free(clusters);
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+    G_free(result);
+
+    G_free(distmatrix);
+    G_free(adjmatrix);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.graph.red/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.graph.red/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.graph.red/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.graph.red/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.grow/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.grow/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.grow/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.grow
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.grow/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.grow/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.grow/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.grow/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Size and suitability based region growing. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.grow/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.grow/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.grow/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.grow/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,221 @@
+#include "local_proto.h"
+
+int gather_border(Position * res, int neighbors)
+{
+    int count = 0;
+
+    /* traverse all cells */
+    int row, col;
+
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 0) {
+		/* look for a patch neighbor */
+		int x, y;
+
+		switch (neighbors) {
+		case 4:
+		    if (col > 0 && flagbuf[row * ncols + col - 1] == 1 ||
+			col < ncols - 1 && flagbuf[row * ncols + col + 1] == 1
+			|| row > 0 && flagbuf[(row - 1) * ncols + col] == 1 ||
+			row < nrows - 1 &&
+			flagbuf[(row + 1) * ncols + col] == 1) {
+			/* add position to the list */
+			Position pos = { col, row };
+			res[count] = pos;
+			count++;
+		    }
+		    break;
+
+		case 8:
+		    for (x = col - 1; x <= col + 1; x++) {
+			for (y = row - 1; y <= row + 1; y++) {
+			    if (x >= 0 && x < ncols && y >= 0 && y < nrows &&
+				!(x == col && y == row) &&
+				flagbuf[y * ncols + x] == 1) {
+
+				/* add position to the list */
+				Position pos = { col, row };
+				res[count] = pos;
+				count++;
+				break;
+			    }
+			}
+		    }
+		    break;
+		}
+	    }
+	}
+    }
+
+    return count;
+}
+
+int find(Position * list, int count, int row, int col)
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+	if (list[i].x == col && list[i].y == row) {
+	    return i;
+	}
+    }
+
+    return -1;
+}
+
+int add_neighbors(Position * res, int count, int row, int col, int neighbors)
+{
+    /* look for free neighbors and add to list */
+    int x, y;
+
+    switch (neighbors) {
+    case 4:
+	if (col > 0 && flagbuf[row * ncols + col - 1] == 0 &&
+	    find(res, count, row, col - 1) < 0) {
+	    /* add position to the list */
+	    Position pos = { col - 1, row };
+	    res[count] = pos;
+	    count++;
+	}
+	if (col < ncols - 1 && flagbuf[row * ncols + col + 1] == 0 &&
+	    find(res, count, row, col + 1) < 0) {
+	    Position pos = { col + 1, row };
+	    res[count] = pos;
+	    count++;
+	}
+	if (row > 0 && flagbuf[(row - 1) * ncols + col] == 0 &&
+	    find(res, count, row - 1, col) < 0) {
+	    Position pos = { col, row - 1 };
+	    res[count] = pos;
+	    count++;
+	}
+	if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] == 0 &&
+	    find(res, count, row + 1, col) < 0) {
+	    Position pos = { col, row + 1 };
+	    res[count] = pos;
+	    count++;
+	}
+	break;
+
+    case 8:
+	for (x = col - 1; x <= col + 1; x++) {
+	    for (y = row - 1; y <= row + 1; y++) {
+		if (x >= 0 && x < ncols && y >= 0 && y < nrows &&
+		    !(x == col && y == row) && find(res, count, x, y) < 0 &&
+		    flagbuf[y * ncols + x] == 0) {
+
+		    /* add position to the list */
+		    Position pos = { x, y };
+		    res[count] = pos;
+		    count++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return count;
+}
+
+int f_circular(Position * list, int count, int neighbors)
+{
+    if (count == 0) {
+	return 0;
+    }
+
+    /* get random position */
+    int r = (int)((double)rand() / (double)RAND_MAX * (double)count);
+
+    Position *p = list + r;
+
+    flagbuf[p->y * ncols + p->x] = 1;
+
+    /* delete border cell */
+    count--;
+    list[r] = list[count];
+
+    /* if border level is exceeded gather new border */
+    if (count == 0) {
+	/* go to the next level border */
+	count = gather_border(list, neighbors);
+    }
+
+    return count;
+}
+
+int f_random(Position * list, int count, int neighbors)
+{
+    /* get random position */
+    int r = (int)((double)rand() / (double)RAND_MAX * (double)count);
+
+    Position p = list[r];
+
+    flagbuf[p.y * ncols + p.x] = 1;
+
+    /* delete border cell */
+    count--;
+    list[r] = list[count];
+
+    /* add free neighbor cells */
+    count = add_neighbors(list, count, p.y, p.x, neighbors);
+
+    return count;
+}
+
+int f_costbased(Position * list, int count, int neighbors)
+{
+    /* build a cost array */
+    double costbuffer[count];
+    int i;
+    double sum = 0.0;
+
+    for (i = 0; i < count; i++) {
+	Position *p = list + i;
+
+	costbuffer[i] = costmap[p->y * ncols + p->x];
+	double tmp = costbuffer[i];
+
+	costbuffer[i] += sum;
+	sum += tmp;
+
+	//fprintf(stderr, "%0.2f ", costbuffer[i]);
+    }
+    //fprintf(stderr, "\n");
+
+    /* normalize */
+    double inv = 1.0 / sum;
+
+    for (i = 0; i < count; i++) {
+	costbuffer[i] *= inv;
+    }
+
+    /* get random number between 0.0 and 1.0 */
+    double r = (double)rand() / (double)RAND_MAX;
+
+    /* get next position */
+    Position p = list[0];
+
+    for (i = 0; i < count; i++) {
+	if (r < costbuffer[i]) {
+	    p = list[i];
+	    break;
+	}
+    }
+
+    if (i == count) {
+	G_message("i = %d", i);
+	return 0;
+    }
+
+    flagbuf[p.y * ncols + p.x] = 1;
+
+    /* delete border cell */
+    count--;
+    list[i] = list[count];
+
+    /* add free neighbor cells */
+    count = add_neighbors(list, count, p.y, p.x, neighbors);
+
+    return count;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.grow/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.grow/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.grow/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.grow/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,38 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+typedef int (*f_method) (Position *, int, int);
+
+/* func.c */
+int f_circular(Position * list, int count, int neighbors);
+int f_random(Position * list, int count, int neighbors);
+int f_costbased(Position * list, int count, int neighbors);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL int *flagbuf;
+GLOBAL DCELL *costmap;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.grow/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.grow/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.grow/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.grow/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,324 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.grow
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Size and landscape suitability based region growing
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct method
+{
+    f_method method;		/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct method methods[] = {
+    {f_circular, "circular", "random circular growth", "crc"},
+    {f_random, "random", "random growth", "rnd"},
+    {f_costbased, "costbased", "cost-based random growth", "cbr"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset, *costname, *costmapset;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+
+    /* parameters */
+    int keyval;
+    int area;
+    f_method method;
+    int nbr_count;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    DCELL *d_res;
+    int *line;
+
+    char *str;
+    int n, i;
+    int row, col;
+
+    Position *border_list;
+    int border_count;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *output;
+	struct Option *keyval, *area, *method, *seed;
+    } parm;
+
+    struct
+    {
+	struct Flag *adjacent;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Size and suitability based region growing.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = NO;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->description = _("Name of the cost map raster file");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.area = G_define_option();
+    parm.area->key = "area";
+    parm.area->type = TYPE_INTEGER;
+    parm.area->required = YES;
+    parm.area->description = _("Area to grow");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    str = parm.method->options = G_malloc(1024);
+    for (n = 0; methods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, methods[n].name);
+    }
+    parm.method->description = _("Method of growth");
+
+    parm.seed = G_define_option();
+    parm.seed->key = "seed";
+    parm.seed->type = TYPE_INTEGER;
+    parm.seed->required = NO;
+    parm.seed->description = _("Random number generator seed");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+    costname = parm.costmap->answer;
+
+    /* test input file existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* test costmap file existance */
+    if (costname) {
+	if (NULL == (costmapset = G_find_cell2(costname, ""))) {
+	    G_fatal_error("%s: <%s> raster file not found\n",
+			  G_program_name(), costname);
+	    exit(EXIT_FAILURE);
+	}
+    }
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    G_message("rows = %d, cols = %d", nrows, ncols);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get area */
+    sscanf(parm.area->answer, "%d", &area);
+
+    /* get growth method */
+    for (i = 0; (str = methods[i].name) != 0; i++) {
+	if (strcmp(str, parm.method->answer) == 0) {
+	    method = methods[i].method;
+	    break;
+	}
+    }
+
+    /* set random seed */
+    if (parm.seed->answer) {
+	int seed;
+
+	sscanf(parm.seed->answer, "%d", &seed);
+	srand(seed);
+    }
+    else {
+	srand(time(NULL));
+    }
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    flagbuf = (int *)G_malloc(ncols * nrows * sizeof(int));
+    costmap = (DCELL *) G_malloc(ncols * nrows * sizeof(DCELL));
+    line = G_allocate_c_raster_buf();
+    d_res = G_allocate_d_raster_buf();
+
+    G_message("Loading Input file ... ");
+
+    /* load map */
+    /* open input file */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read patch map */
+    memset(flagbuf, 0, ncols * nrows * sizeof(int));
+    for (row = 0; row < nrows; row++) {
+	G_get_c_raster_row(in_fd, line, row);
+	for (col = 0; col < ncols; col++) {
+	    if (line[col] == keyval) {
+		flagbuf[row * ncols + col] = 1;
+	    }
+	}
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /*G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%d ", flagbuf[row * ncols + col]);          
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* load costmap */
+    /* open input file */
+    if (costname) {
+	in_fd = G_open_cell_old(costname, costmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), costname);
+
+	/* read cost map */
+	for (row = 0; row < nrows; row++) {
+	    G_get_d_raster_row(in_fd, &costmap[row * ncols], row);
+
+	    G_percent(row + 1, nrows, 1);
+	}
+
+	/* close cell file */
+	G_close_cell(in_fd);
+    }
+    else {
+	for (row = 0; row < nrows; row++) {
+	    for (col = 0; col < ncols; col++) {
+		costmap[row * ncols + col] = 1.0;
+	    }
+	}
+    }
+
+    /* G_message("costmap");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%0.2f ", costmap[row * ncols + col]);               
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* prepare border list */
+    border_list = (Position *) G_malloc(ncols * nrows * sizeof(Position));
+    border_count = gather_border(border_list, nbr_count);
+
+    /*G_message("border_count = %d", border_count); */
+    
+    for (i = 0; i < area && border_count > 0; i++) {
+	/*G_message("border list step %d:", i);
+	   for(n = 0; n < border_count; n++) {
+	   fprintf(stderr, "(%d,%d)", border_list[n].x, border_list[n].y);
+	   }
+	   fprintf(stderr, "\n"); */
+
+	border_count = method(border_list, border_count, nbr_count);
+    }
+    /*G_message("final border list:");
+       for(i = 0; i < border_count; i++) {
+       fprintf(stderr, "(%d,%d)", border_list[i].x, border_list[i].y);
+       }
+       fprintf(stderr, "\n"); 
+
+       G_message("map");
+       for(row = 0; row < nrows; row++) {
+       for(col = 0; col< ncols; col++) {
+       fprintf(stderr, "%d ", flagbuf[row * ncols + col]);     
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* write output */
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new(newname, DCELL_TYPE);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(d_res, ncols);
+
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		d_res[col] = 1;
+	    }
+	}
+	G_put_d_raster_row(out_fd, d_res);
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    G_free(flagbuf);
+    G_free(costmap);
+    G_free(line);
+    G_free(d_res);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.grow/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass-addons/raster/r.pi/r.pi.import/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.import/description.html	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.import/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,29 +1,60 @@
-<H2>DESCRIPTION</H2>
+<h2>DESCRIPTION</h2>
 
-The <EM>r.pi.import</EM> module imports values and assigns them to corresponding patches using a previously exported raster by <EM>r.pi.export</EM>. The raster must have the 
-same extent, spatial resolution etc. in order to detect the same patches and assign the same patch IDs for all patches.
+Import and generation of patch raster data based on individual patch based raster data.
 
-<P>
+<h2>NOTES</h2>
 
-The program will be run non-interactively if the user specifies program arguments (see OPTIONS) on the command
-line.  Alternately, the user can simply type <B>r.pi.import</B> on the command line, without program
-arguments.  In this case, the user will be prompted for flag settings and parameter values.
+...
 
+<h2>EXAMPLE</h2>
 
-<H2>NOTES</H2>
+An example for the North Carolina sample dataset:
 
-For export and import of patch values after e.g. R calculation <EM>r.pi.export</EM> and <EM>r.pi.import</EM> can be applied using the same raster.
+In order to run <em>r.pi.import</em> we need an exported patch index raster:
+<div class="code"><pre>
+<b> r.pi.index input=</b>landclass96 <b>output=</b>landclass96_forestclass5_area <b>keyval=</b>5 <b>method=</b>area
+</pre></div>
 
+export this resulting map:
+<div class="code"><pre>
+<b>r.pi.export input=</b>landclass96_forestclass5_area <b>output=</b>patch_area_out <b>values=</b>patch_area_values <b>id_raster=</b>forestclass5_ID <b>stats=</b>average,variance,min
+</pre></div>
 
+modify it with R or just import the file again and assign the percentage coverage to each fragment. You need the <em>patch_area_values</em> file and the previously used input file <em>forestclass96</em> raster (important: the same patch coverage is mandatory otherwise patch ID in the text file and raster are not congruent!):
 
-<H2>SEE ALSO</H2>
+<div class="code"><pre>
+<b>r.pi.import input=</b>patch_area_values <b>raster=</b>landclass96 <b>output=</b>imported_values <b>keyval=</b>5 <b>id_col=</b>1 <b>val_col=</b>2
+</pre></div>
 
-<EM><A HREF="r.pi.export.html">r.pi.export</A></EM><br>
+if you want to export the patch values to R and do e.g. a linear regression of two patch values and import them again in GRASS, do:<br>
 
-<H2>AUTHOR</H2>
+apply r.pi.export with two indices (A and B), in R do:
+
+<div class="code"><pre>
+resid.AB <b><- resid(lm(A[,3]~B[,3]))</b> #write residuals of a linear regression
+df.resid.AB <b><- data.frame(A[,1],resid.AB)</b> #merge patch IDs and resid into same data frame
+<b>write.table(</b>df.resid.AB,"resid.for.GRASS"<b>,row.names=F,col.names=F)</b>
+</pre></div>
+
+exit R and run in GRASS:
+<div class="code"><pre>
+<b>r.pi.import input=</b>resid.for.GRASS <b>raster=</b>landclass96 <b>output=</b>resid.AB <b>keyval=</b>5 <b>id_col=</b>1 <b>val_col=</b>2
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
 Programming: Elshad Shirinov<br>
-Scientific concept: Dr. Martin Wegmann <br>
-Department of Remote Sensing <br>Remote Sensing and Biodiversity Unit<br> University of Wuerzburg, Germany
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
 
 <p><i>Last changed: $Date$</i>
 

Modified: grass-addons/raster/r.pi/r.pi.import/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.import/frag.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.import/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -14,9 +14,7 @@
 		 int nbr_cnt)
 {
     int left, right, top, bottom;
-
     int i, j;
-
     int cnt = 0;
 
     switch (nbr_cnt) {
@@ -66,13 +64,9 @@
 		  int ncols, int nbr_cnt)
 {
     int x, y, i;
-
     Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
-
     Position *first = list;
-
     Position *last = list;
-
     Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
 
     /* count neighbors */
@@ -102,17 +96,13 @@
     while (first < last) {
 	/* get position from fifo-list */
 	int r = first->y;
-
 	int c = first->x;
 
 	first++;
 
 	int left = c > 0 ? c - 1 : 0;
-
 	int top = r > 0 ? r - 1 : 0;
-
 	int right = c < ncols - 1 ? c + 1 : ncols - 1;
-
 	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
 
 	/* add neighbors to fifo-list */
@@ -156,7 +146,6 @@
 void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
 {
     int row, col, i;
-
     Coords *p;
 
     fragcount = 0;

Modified: grass-addons/raster/r.pi/r.pi.import/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.import/helpers.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.import/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -68,7 +68,6 @@
 void print_fragments()
 {
     int f;
-
     Coords *p;
 
     for (f = 0; f < fragcount; f++) {

Modified: grass-addons/raster/r.pi/r.pi.import/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.import/local_proto.h	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.import/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,5 +1,10 @@
 #ifndef LOCAL_PROTO_H
 #define LOCAL_PROTO_H
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
 
 #include <string.h>
 #include <stdlib.h>
@@ -53,7 +58,6 @@
 GLOBAL Coords *cells;
 GLOBAL int fragcount;
 GLOBAL int sx, sy;
-GLOBAL int *id_map;
 
 GLOBAL int *adj_matrix;
 

Modified: grass-addons/raster/r.pi/r.pi.import/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.import/main.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.import/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,12 +1,24 @@
-#define MAIN
-#include "local_proto.h"
-
 /*
-   Import of patch values and generating a corresponding raster
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.import
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Import of patch information based on ID patch raster 
+ *                               (Reads a text-file with Patch IDs and values and creates 
+ *                               a raster file with these values for patches)
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
 
-   by Elshad Shirinov.
- */
+#define MAIN
 
+#include "local_proto.h"
+
 int main(int argc, char *argv[])
 {
     /* input */
@@ -17,16 +29,12 @@
 
     /* in and out file pointers */
     int in_fd;
-
     int out_fd;
 
     /* parameters */
     int keyval;
-
     int id_col;
-
     int val_col;
-
     int neighb_count;
 
     /* maps */
@@ -37,38 +45,26 @@
 
     /* helper variables */
     int row, col;
-
     DCELL *d_res;
-
     DCELL *values;
-
     int *result;
-
     int i, n;
-
     int x, y;
-
     Coords *p;
-
-    char output_name[256];
-
+    char output_name[GNAME_MAX];
     char *str;
-
     DCELL val;
 
     RASTER_MAP_TYPE map_type;
-
     struct Cell_head ch, window;
 
     struct GModule *module;
-
     struct
     {
 	struct Option *input, *raster, *output;
 	struct Option *keyval, *id_col, *val_col;
 	struct Option *title;
     } parm;
-
     struct
     {
 	struct Flag *adjacent, *quiet;
@@ -78,8 +74,7 @@
 
     module = G_define_module();
     module->keywords = _("raster");
-    module->description =
-	_("Reads a text-file with Patch IDs and values and creates a raster file with these values for patches.");
+    module->description = _("Import and generation of patch raster data");
 
     parm.input = G_define_option();
     parm.input->key = "input";
@@ -88,26 +83,16 @@
     parm.input->gisprompt = "old_file,file,input";
     parm.input->description = _("Name of the input ASCII-file");
 
-    parm.raster = G_define_option();
+    parm.raster = G_define_standard_option(G_OPT_R_INPUT);
     parm.raster->key = "raster";
-    parm.raster->type = TYPE_STRING;
-    parm.raster->required = YES;
-    parm.raster->gisprompt = "old,cell,raster";
-    parm.raster->description = _("Name of existing raster file");
 
-    parm.output = G_define_option();
-    parm.output->key = "output";
-    parm.output->type = TYPE_STRING;
-    parm.output->required = YES;
-    parm.output->gisprompt = "new,cell,raster";
-    parm.output->description = _("Name of the new raster file");
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
 
     parm.keyval = G_define_option();
     parm.keyval->key = "keyval";
     parm.keyval->type = TYPE_INTEGER;
     parm.keyval->required = YES;
-    parm.keyval->description =
-	_("Category value of the patches in the existing raster file");
+    parm.keyval->description = _("Category value of the patches");
 
     parm.id_col = G_define_option();
     parm.id_col->key = "id_col";
@@ -126,12 +111,12 @@
     parm.title->key_desc = "\"phrase\"";
     parm.title->type = TYPE_STRING;
     parm.title->required = NO;
-    parm.title->description = _("Title of the output raster file");
+    parm.title->description = _("Title for resultant raster map");
 
     flag.adjacent = G_define_flag();
     flag.adjacent->key = 'a';
     flag.adjacent->description =
-	_("Set for 8 cell-neighbors. 4 cell-neighbors are default.");
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
 
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
@@ -140,12 +125,9 @@
     oldname = parm.raster->answer;
 
     /* test raster files existance */
-    if ((oldmapset = G_find_cell2(oldname, "")) == NULL) {
-	G_fatal_error(_("%s: <%s> raster file not found\n"), G_program_name(),
-		      oldname);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
 
     /* get number of cell-neighbors */
     neighb_count = flag.adjacent->answer ? 8 : 4;
@@ -161,12 +143,8 @@
 
     /* check if the new file name is correct */
     newname = parm.output->answer;
-    if (G_legal_filename(newname) < 0) {
-	G_fatal_error(_("%s: <%s> illegal file name\n"), G_program_name(),
-		      newname);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
     newmapset = G_mapset();
 
     /* get size */
@@ -185,12 +163,9 @@
     memset(map, 0, sx * sy * sizeof(int));
 
     /* open map */
-    if ((in_fd = G_open_cell_old(oldname, oldmapset)) < 0) {
-	G_fatal_error(_("can't open cell file <%s> in mapset %s\n"), oldname,
-		      oldmapset);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
 
     /* read map */
     G_message("Reading map file... ");
@@ -214,15 +189,12 @@
     /* parse input */
     parse(values, parm.input->answer, id_col, val_col);
 
-    G_message("Writing output ... ");
+    G_message("Writing output...");
 
     /* open new cellfile  */
     out_fd = G_open_raster_new(newname, DCELL_TYPE);
-    if (out_fd < 0) {
-	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
-		      newname, newmapset);
-	exit(EXIT_FAILURE);
-    }
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
 
     /* write the output file */
     for (row = 0; row < sy; row++) {

Modified: grass-addons/raster/r.pi/r.pi.import/parse.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.import/parse.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.import/parse.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -3,11 +3,8 @@
 void parse_line(DCELL * values, char *buffer, int id_col, int val_col)
 {
     int counter = 1;
-
     char *p = buffer;
-
     int id;
-
     DCELL value;
 
     while (*p != 0) {
@@ -37,10 +34,8 @@
 
 void parse(DCELL * values, char *file_name, int id_col, int val_col)
 {
-    char buffer[256];
-
+    char buffer[GNAME_MAX];
     FILE *fp;
-
     int i;
 
     fp = fopen(file_name, "r");
@@ -53,7 +48,7 @@
     }
 
     /* read lines */
-    while (fgets(buffer, 256, fp)) {
+    while (fgets(buffer, GNAME_MAX, fp)) {
 	parse_line(values, buffer, id_col, val_col);
     }
 

Modified: grass-addons/raster/r.pi/r.pi.index/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.index/description.html	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.index/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,42 +1,134 @@
-<H2>DESCRIPTION</H2>
+<h2>DESCRIPTION</h2>
 
-Available options for the index to be computed for patches within a certain class are: area (area), perimeter (perim), SHAPE (shape), Border-Index (bor), Compactness (comp), Asymmetry (asym), area-perimeter ratio (apr), fractal dimension (fract), distance to euclidean nearest neighbour (ENN)</DD>
+<em>r.fragment</em> is a patch based fragmentation analysis package.
+Computation of basic fragmentation indices can be accomplished. 
 
-<P>
+<p>
+Available options for the index to be computed for patches within
+a certain class are: area (area), perimeter (perim), SHAPE (shape),
+Border-Index (bor), Compactness (comp), Asymmetry (asym),
+area-perimeter ratio (apr), fractal dimension (fract),
+distance to euclidean nearest neighbour (ENN).
 
-The program will be run non-interactively if the user specifies program arguments (see OPTIONS) on the command
-line.  Alternately, the user can simply type <B>r.pi.index</B> on the command line, without program
-arguments.  In this case, the user will be prompted for flag settings and parameter values.
+<h2>NOTES</h2>
 
-
-<H2>NOTES</H2>
-
-The <EM>Nearest Neighbour Index</EM> (ENN) analyse the Euclidean Nearest 
+The <em>Nearest Neighbour Index</em> (ENN) analyse the Euclidean Nearest 
 Neighbour to the first neighbouring patch. The output value is in pixel and can
 be converted to a distance values using g.region resolution information.
-<EM>r.pi.ENN</EM> and <EM>r.pi.FNN</EM> provide the same analysis concerning the
+<em>r.pi.enn</em> and <em>r.fragment.fnn</em> provide the same analysis concerning the
  first nearest neighbour (NN), but are extended to the n-th NN. However due to
-code construction does the <EM>r.pi.index</EM> distance analysis to first ENN perform faster.
+code construction does the <em>r.pi.index</em> distance analysis to first ENN perform faster.
 
 
-<P>
+<em>Methods:</em>
+The <em>method</em> operators determine what algorithm is applied 
+on the patches.
+<em>r.pi.index</em>
+can perform the following operations:
 
-<H2>BUGS</H2>
-Landscapes with more than 10 000 patches might cause a memory
-allocation error depending on your system.
+<p>
 
+<dt><b>Area</b> 
 
-<H2>SEE ALSO</H2>
+<dd>The <em>Area</em> computes the area of each patch.
 
-<EM><A HREF="r.pi.ENN.html">r.pi.ENN</A></EM><br>
-<EM><A HREF="r.pi.FNN.html">r.pi.FNN</A></EM><br>
-<EM><A HREF="r.pi.dist.html">r.pi.dist</A></EM><br>
-<EM><A HREF="r.li.setup.html">r.li.setup</A></EM><br>
+<dt><b>Perimeter</b> 
 
-<H2>AUTHOR</H2>
+<dd>The <em>Perimeter</em> computes the perimeter of each patch.
+
+<dt><b>Area-Perimeter ratio</b> 
+
+<dd>The <em>Area-Perimeter ratio</em> divides the patch perimeter by the area.
+
+<dt><b>SHAPE Index</b> 
+
+<dd>The <em>SHAPE Index</em> divides the patch perimete by the minimum perimeter 
+possible for a maximally compact patch of the corresponding patch area.
+
+<dt><b>Border Index</b> 
+
+<dd>The <em>Border Index</em> ....
+
+<dt><b>Compactness Index</b> 
+
+<dd>The <em>Compactness Index</em> ....
+
+<dt><b>Asymmetry Index</b> 
+
+<dd>The <em>Border Index</em> ....
+
+<dt><b>Fractal Dimension Index</b> 
+
+<dd>The <em>Fractal Dimension Index</em> ....
+
+<dt><b>Nearest Neighbour Index</b> 
+
+<dd>The <em>Nearest Neighbour Index</em> computes the Euclidean distance
+to the first nearest neighbour patch.
+
+
+
+<h2>EXAMPLE</h2>
+
+Examples based on the North Carolina sample dataset are provided below. Indices are calculated for the landscape class 5 (forest).
+
+set region settings to used landcover class map:
+
+<br>
+<div class="code"><pre>
+<b>g.region rast=</b>landclass96
+</pre></div>
+
+
+computation of patch size (patch definition: 4-neighbourhood rule)
+<div class="code"><pre>
+<b> r.pi.index input=</b>landclass96 <b>output=</b>landclass96_forestclass5_area <b>keyval=</b>5 <b>method=</b>area
+# improve colouring of resulting map: 
+<b>r.colors</b> landclass96_forestclass5_area <b>col=</b>bgyr
+</pre></div>
+
+computation of patch size (patch definition: 8-neighbourhood rule)
+<div class="code"><pre>
+<b>r.pi.index input=</b>landclass96 <b>output=</b>landclass96_forestclass5_area <b>keyval=</b>5 <b>method=</b>area <b>-a</b>
+</pre></div>
+
+computation of patch isolation (euclidean distance to 1. nearest neighbour; patch definition: 4-neighbourhood rule)
+<div class="code"><pre>
+<b>r.pi.index input=</b>landclass96 <b>output=</b>landclass96_forestclass5_ENN <b>keyval=</b>5 <b>method=</b>ENN <b>-a</b>
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+
+<h2>BUGS</h2>
+Landscapes with more than 10 000 individual patches might cause a memory
+allocation error depending on your system.
+
+<h2>AUTHORS</h2>
 Programming: Elshad Shirinov<br>
-Scientific concept: Dr. Martin Wegmann <br>
-Department of Remote Sensing <br>Remote Sensing and Biodiversity Unit<br> University of Wuerzburg, Germany
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
 
-<p><i>Last changed: $Date$</i>
-
+<p>
+<i>Last changed: $Date$</i>

Modified: grass-addons/raster/r.pi/r.pi.index/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.index/frag.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.index/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -17,9 +17,7 @@
 int getNeighbors(Position * res, int x, int y, int nx, int ny, int nbr_cnt)
 {
     int left, right, top, bottom;
-
     int i, j;
-
     int cnt = 0;
 
     switch (nbr_cnt) {
@@ -68,13 +66,9 @@
 void writeFrag(int row, int col, int nbr_cnt)
 {
     int x, y, i;
-
     Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
-
     Position *first = list;
-
     Position *last = list;
-
     Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
 
     /* count neighbors */
@@ -104,17 +98,13 @@
     while (first < last) {
 	/* get position from fifo-list */
 	int r = first->y;
-
 	int c = first->x;
 
 	first++;
 
 	int left = c > 0 ? c - 1 : 0;
-
 	int top = r > 0 ? r - 1 : 0;
-
 	int right = c < ncols - 1 ? c + 1 : ncols - 1;
-
 	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
 
 	/* add neighbors to fifo-list */

Modified: grass-addons/raster/r.pi/r.pi.index/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.index/func.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.index/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -26,7 +26,6 @@
 int f_perim(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -50,7 +49,6 @@
 int f_shapeindex(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -60,7 +58,6 @@
 	    G_percent(i, count, 2);
 
 	int border = 0;
-
 	int area = (DCELL) (frags[i + 1] - frags[i]);
 
 	/* for all cells in a patch */
@@ -76,7 +73,6 @@
 int f_borderindex(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -86,11 +82,8 @@
 	    G_percent(i, count, 2);
 
 	int border = 0;
-
 	int maxx, maxy, minx, miny;
-
 	int l = 0;
-
 	int w = 0;
 
 	maxx = minx = frags[i]->x;
@@ -114,7 +107,6 @@
 int f_compactness(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -124,11 +116,8 @@
 	    G_percent(i, count, 2);
 
 	int area = 0;
-
 	int maxx, maxy, minx, miny;
-
 	int l = 0;
-
 	int w = 0;
 
 	maxx = minx = frags[i]->x;
@@ -152,7 +141,6 @@
 int f_asymmetry(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -165,11 +153,8 @@
 	/* formula: a(x) = sum(x_i), b(x) = sum(x_i²), var(x) = (b(x) - a(x)² / n) / n */
 	/* covar(x*y) = (a(x * y) - a(x) * a(y) / n) /n */
 	int ax, ay, axy;
-
 	int bx, by;
-
 	DCELL vx, vy, vxy, vsum, invn;
-
 	int n = 0;
 
 	ax = ay = axy = 0;
@@ -178,9 +163,7 @@
 	//              fprintf(stderr, "\npatch %d: ", i);
 	for (p = frags[i]; p < frags[i + 1]; p++, n++) {
 	    int x = p->x;
-
 	    int y = p->y;
-
 	    int xy = p->x * p->y;
 
 	    ax += x;
@@ -203,7 +186,6 @@
 int f_area_perim_ratio(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -213,7 +195,6 @@
 	    G_percent(i, count, 2);
 
 	int border = 0;
-
 	int area = (DCELL) (frags[i + 1] - frags[i]);
 
 	/* for all cells in a patch */
@@ -229,7 +210,6 @@
 int f_frac_dim(DCELL * vals, Coords ** frags, int count)
 {
     Coords *p;
-
     int i;
 
     /* for all patches */
@@ -239,7 +219,6 @@
 	    G_percent(i, count, 2);
 
 	int border = 0;
-
 	int area = (DCELL) (frags[i + 1] - frags[i]);
 
 	/* for all cells in a patch */
@@ -255,15 +234,10 @@
 DCELL dist(Coords * p1, Coords * p2)
 {
     int x1 = p1->x;
-
     int y1 = p1->y;
-
     int x2 = p2->x;
-
     int y2 = p2->y;
-
     int dx = x2 - x1;
-
     int dy = y2 - y1;
 
     return sqrt(dx * dx + dy * dy);
@@ -272,7 +246,6 @@
 DCELL min_dist(Coords ** frags, int n1, int n2)
 {
     Coords *p1, *p2;
-
     DCELL min = 1000000.0;
 
     // for all cells in the first patch

Modified: grass-addons/raster/r.pi/r.pi.index/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.index/local_proto.h	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.index/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -18,28 +18,19 @@
 extern void writeFrag(int row, int col, int nbr_cnt);
 
 extern int f_area(DCELL * vals, Coords ** frags, int);
-
 extern int f_perim(DCELL * vals, Coords ** frags, int);
-
 extern int f_shapeindex(DCELL *, Coords **, int);
-
 extern int f_borderindex(DCELL *, Coords **, int);
-
 extern int f_compactness(DCELL *, Coords **, int);
-
 extern int f_asymmetry(DCELL *, Coords **, int);
-
 extern int f_area_perim_ratio(DCELL *, Coords **, int);
-
 extern int f_frac_dim(DCELL *, Coords **, int);
-
 extern int f_nearest_dist(DCELL *, Coords **, int);
 
 /* global variables */
 GLOBAL int nrows, ncols;
 GLOBAL Coords **fragments;
 GLOBAL int *flagbuf;
-
 GLOBAL Coords *actpos;
 GLOBAL int verbose;
 

Modified: grass-addons/raster/r.pi/r.pi.index/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.index/main.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.index/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,4 +1,20 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.index
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Fragmentation analysis - basic spatial indices
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 <string.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -8,12 +24,6 @@
 #include <grass/stats.h>
 #include "local_proto.h"
 
-/*
-   Fragmentation analysis - basic indices in r.pi.index
-
-   by Elshad Shirinov.
- */
-
 typedef int (*f_func) (DCELL *, Coords **, int);
 
 struct menu
@@ -41,23 +51,18 @@
 {
     /* input */
     char *newname, *oldname, *newmapset, *oldmapset;
-
     char title[1024];
 
     /* in and out file pointers */
     int in_fd;
-
     int out_fd;
-
     DCELL *result, res[30];
 
     /* map_type and categories */
     RASTER_MAP_TYPE map_type;
-
     struct Categories cats;
 
     int method;
-
     f_func compute_values;
 
     /* neighbors count */
@@ -66,37 +71,26 @@
     char *p;
 
     int row, col, i, j;
-
     int readrow;
-
     int keyval;
-
-    DCELL range = MAX_DOUBLE;
-
     int n;
-
-    int copycolr;
-
     struct Colors colr;
-
+    struct Range range;
+    CELL min, max;
     struct GModule *module;
-
     struct
     {
 	struct Option *input, *output;
 	struct Option *keyval, *method;
 	struct Option *title;
     } parm;
-
     struct
     {
 	struct Flag *adjacent, *quiet;
     } flag;
 
     DCELL *values;
-
     Coords *cells;
-
     int fragcount = 0;
 
     struct Cell_head ch, window;
@@ -105,21 +99,12 @@
 
     module = G_define_module();
     module->keywords = _("raster");
-    module->description =
-	_("Provides basic patch based indices, like area, SHAPE or Nearest Neighbour distance.");
+    module->description = _("Basic patch based indices");
 
-    parm.input = G_define_option();
-    parm.input->key = "input";
-    parm.input->type = TYPE_STRING;
-    parm.input->required = YES;
-    parm.input->gisprompt = "old,cell,raster";
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
     parm.input->description = _("Raster map containing categories");
 
-    parm.output = G_define_option();
-    parm.output->key = "output";
-    parm.output->type = TYPE_STRING;
-    parm.output->required = YES;
-    parm.output->gisprompt = "new,cell,raster";
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
     parm.output->description = _("Output patch-based result as raster map");
 
     parm.keyval = G_define_option();
@@ -147,37 +132,32 @@
     parm.title->key_desc = "\"phrase\"";
     parm.title->type = TYPE_STRING;
     parm.title->required = NO;
-    parm.title->description = _("Title of the output raster file");
+    parm.title->description = _("Title for resultant raster map");
 
     flag.adjacent = G_define_flag();
     flag.adjacent->key = 'a';
     flag.adjacent->description =
-	_("Set for 8 cell-neighbors. 4 cell-neighbors are default.");
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
 
     flag.quiet = G_define_flag();
     flag.quiet->key = 'q';
     flag.quiet->description = _("Run quietly");
 
     if (G_parser(argc, argv))
-	exit(1);
+	    exit(EXIT_FAILURE);
 
     /* get names of input files */
     oldname = parm.input->answer;
 
     /* test input files existance */
-    if (NULL == (oldmapset = G_find_cell2(oldname, ""))) {
-	fprintf(stderr, "%s: <%s> raster file not found\n",
-		G_program_name(), oldname);
-	exit(1);
-    }
+    oldmapset = G_find_cell2(oldname, "");
+	if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
 
     /* check if the new file name is correct */
     newname = parm.output->answer;
-    if (G_legal_filename(newname) < 0) {
-	fprintf(stderr, "%s: <%s> illegal file name\n",
-		G_program_name(), newname);
-	exit(1);
-    }
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
     newmapset = G_mapset();
 
     /* get size */
@@ -185,21 +165,13 @@
     ncols = G_window_cols();
 
     /* open cell files */
-    if ((in_fd = G_open_cell_old(oldname, oldmapset)) < 0) {
-	char msg[200];
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname);
 
-	sprintf(msg, "can't open cell file <%s> in mapset %s\n",
-		oldname, oldmapset);
-	G_fatal_error(msg);
-	exit(-1);
-    }
-
     /* get map type */
-    map_type = DCELL_TYPE;	//G_raster_map_type(oldname, oldmapset);
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
 
-    /* copy color table */
-    copycolr = (G_read_colors(oldname, oldmapset, &colr) > 0);
-
     /* get key value */
     sscanf(parm.keyval->answer, "%d", &keyval);
 
@@ -236,17 +208,11 @@
 
     /* open the new cellfile  */
     out_fd = G_open_raster_new(newname, map_type);
-    if (out_fd < 0) {
-	char msg[200];
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
 
-	sprintf(msg, "can't create new cell file <%s> in mapset %s\n",
-		newname, newmapset);
-	G_fatal_error(msg);
-	exit(1);
-    }
-
     if (verbose = !flag.quiet->answer)
-	fprintf(stderr, "Loading Patches ... ");
+	G_message("Loading patches...");
 
     /* find fragments */
     for (row = 0; row < nrows; row++) {
@@ -274,7 +240,7 @@
 
     /* perform actual function on the patches */
     if (verbose = !flag.quiet->answer)
-	fprintf(stderr, "Performing operation ... ");
+	G_message("Performing operation...");
     values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
     compute_values(values, fragments, fragcount);
     if (verbose)
@@ -282,7 +248,7 @@
 
     /* write the output file */
     if (verbose = !flag.quiet->answer)
-	fprintf(stderr, "Writing output ... ");
+	G_message("Writing output...");
     for (row = 0; row < nrows; row++) {
 	G_set_d_null_value(result, ncols);
 
@@ -313,8 +279,11 @@
     G_init_cats(0, title, &cats);
     G_write_cats(newname, &cats);
 
-    if (copycolr)
-	G_write_colors(newname, newmapset, &colr);
+    G_read_range(newname, newmapset, &range);
+    G_get_range_min_max(&range, &min, &max);
+    G_make_bgyr_colors(&colr, min, max);
+    G_write_colors(newname, newmapset, &colr);
+    G_free_colors(&colr);
 
-    exit(0);
+    exit(EXIT_SUCCESS);
 }

Added: grass-addons/raster/r.pi/r.pi.lm/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.lm/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.lm/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.lm
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.lm/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.lm/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.lm/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.lm/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Linear regression analysis for patches. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.lm/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.lm/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.lm/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.lm/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,104 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int getNeighbors(Position * res, DCELL * map, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, DCELL * map, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && !G_is_d_null_value(&map[y * nx + x - 1])) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && !G_is_d_null_value(&map[(y - 1) * nx + x])) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && !G_is_d_null_value(&map[y * nx + x + 1])) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && !G_is_d_null_value(&map[(y + 1) * nx + x])) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) &&
+		    !G_is_d_null_value(&map[j * nx + i])) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+void clearPatch(DCELL * map, int *flagbuf, int flagval, int row, int col,
+		int nrows, int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *stack = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *top = stack;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* push position on stack */
+    top->x = col;
+    top->y = row;
+    top++;
+
+    while (top > stack) {
+	/* pop position from stack */
+	top--;
+	int r = top->y;
+	int c = top->x;
+
+	/* mark cell on the flag buffer */
+	flagbuf[r * ncols + c] = flagval;
+
+	/* delete cell from map */
+	G_set_d_null_value(&map[r * ncols + c], 1);
+
+	/* get neighbors */
+	int cnt = getNeighbors(nbr_list, map, c, r, ncols, nrows, nbr_cnt);
+
+	/* push neighbors on the stack */
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    top->x = x;
+	    top->y = y;
+	    top++;
+	}
+    }
+
+    G_free(stack);
+    G_free(nbr_list);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.lm/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.lm/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.lm/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.lm/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,43 @@
+#include "local_proto.h"
+
+void linear_regression(DCELL * x, DCELL * y, int count, DCELL * res_offset,
+		       DCELL * res_slope, DCELL * res_residuals,
+		       DCELL * res_correlation)
+{
+    int i;
+    DCELL sum_x = 0;
+    DCELL sum_y = 0;
+    DCELL sum_xy = 0;
+    DCELL sum_xx = 0;
+    DCELL sum_yy = 0;
+
+    if (count <= 0)
+	return;
+
+    for (i = 0; i < count; i++) {
+	DCELL xi = x[i];
+	DCELL yi = y[i];
+
+	sum_x += xi;
+	sum_y += yi;
+	sum_xy += xi * yi;
+	sum_xx += xi * xi;
+	sum_yy += yi * yi;
+    }
+
+    DCELL r_n = 1.0 / (DCELL) count;
+    DCELL var_x = (sum_xx - sum_x * sum_x * r_n) * r_n;
+    DCELL var_y = (sum_yy - sum_y * sum_y * r_n) * r_n;
+    DCELL covar = (sum_xy - sum_x * sum_y * r_n) * r_n;
+    DCELL beta = covar / var_x;
+    DCELL alpha = (sum_y - beta * sum_x) * r_n;
+    DCELL corr = beta * sqrt(var_x) / sqrt(var_y);
+
+    *res_slope = beta;
+    *res_offset = alpha;
+    *res_correlation = corr;
+
+    for (i = 0; i < count; i++) {
+	res_residuals[i] = y[i] - (alpha + beta * x[i]);
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.lm/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.lm/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.lm/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.lm/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,14 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+
+#define MAX_DOUBLE 1000000.0
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.lm/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.lm/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.lm/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.lm/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,258 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.lm
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Linear regression analysis for patches (not pixel based)
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
+
+#include "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *newname, *oldname1, *oldname2, *newmapset, *oldmapset1, *oldmapset2;
+    char fullname[GNAME_MAX];
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+    FILE out_fp;
+
+    /* parameters */
+    int keyval;
+    int nbr_count;
+    int patch_values;
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+
+    /* helpers */
+    DCELL *result;
+    DCELL *map;
+    int row, col;
+    int nrows, ncols;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input1, *input2, *output;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *patch_values;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Linear regression analysis for patches.");
+
+    parm.input1 = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input1->key = "input1";
+
+    parm.input2 = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input2->key = "input2";
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.patch_values = G_define_flag();
+    flag.patch_values->key = 'p';
+    flag.patch_values->description = _("Set to use patch values");
+
+    if (G_parser(argc, argv))
+	    exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname1 = parm.input1->answer;
+    oldname2 = parm.input2->answer;
+
+    /* test input files existance */
+    oldmapset1 = G_find_cell2(oldname1, "");
+	if (oldmapset1 == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname1);
+    oldmapset2 = G_find_cell2(oldname2, "");
+	if (oldmapset2 == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname2);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* get number of cell-neighbors */
+    nbr_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get patch_values flag */
+    patch_values = flag.patch_values->answer;
+
+    /* allocate the cell buffers */
+    map = (DCELL *) G_malloc(nrows * ncols * sizeof(DCELL));
+
+    G_message("Loading patches...");
+
+    /* open first cell file */
+    in_fd = G_open_cell_old(oldname1, oldmapset1);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname1);
+
+    /* read map */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, map + row * ncols, row);
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /*    G_message("Map:");
+       for (row = 0; row < nrows; row++) {
+       for (col = 0; col < ncols; col++) {
+       fprintf(stderr, "%0.1f ", map[row * ncols + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /* open second cell file */
+    in_fd = G_open_cell_old(oldname2, oldmapset2);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname2);
+
+    /* gather pixel or patch values */
+    /* TODO: patch values */
+    result = G_allocate_d_raster_buf();
+    DCELL *x = (DCELL *) malloc(nrows * ncols * sizeof(DCELL));
+    DCELL *y = (DCELL *) malloc(nrows * ncols * sizeof(DCELL));
+    int *flagbuf = (int *)malloc(nrows * ncols * sizeof(int));
+
+    /* initialize flag buffer with -1 */
+    int i;
+
+    for (i = 0; i < nrows * ncols; i++) {
+	flagbuf[i] = -1;
+    }
+    int value_count = 0;
+
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, result, row);
+
+	for (col = 0; col < ncols; col++) {
+	    DCELL val = map[row * ncols + col];
+
+	    if (!G_is_d_null_value(&val)) {
+		x[value_count] = val;
+		y[value_count] = result[col];
+
+		flagbuf[row * ncols + col] = value_count;
+
+		if (patch_values) {
+		    clearPatch(map, flagbuf, value_count, row, col, nrows,
+			       ncols, nbr_count);
+
+		    /*                    int r, c;
+		       G_message("Map:");
+		       for (r = 0; r < nrows; r++) {
+		       for (c = 0; c < ncols; c++) {
+		       fprintf(stderr, "%0.1f ", map[r * ncols + c]);
+		       }
+		       fprintf(stderr, "\n");
+		       } */
+		}
+
+		value_count++;
+	    }
+	}
+    }
+
+    printf("Values:\n");
+    printf("X:");
+    for (i = 0; i < value_count; i++) {
+	printf(" %0.2f", x[i]);
+    }
+    printf("\n");
+    printf("Y:");
+    for (i = 0; i < value_count; i++) {
+	printf(" %0.2f", y[i]);
+    }
+    printf("\n");
+
+    DCELL *residuals = (DCELL *) malloc(value_count * sizeof(DCELL));
+    DCELL offset, slope, correlation;
+
+    /* calculate data */
+    linear_regression(x, y, value_count, &offset, &slope, residuals,
+		      &correlation);
+
+    /* free memory */
+    G_free(x);
+    G_free(y);
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /* write output */
+    G_message("Writing output...");
+
+    G_message("Offset: %lf, Slope: %lf, Correlation: %lf\n", offset, slope,
+	      correlation);
+
+    /* ================================== 
+       ============  output  ============ 
+       ================================== */
+
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    /* write values */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(result, ncols);
+
+	for (col = 0; col < ncols; col++) {
+	    int flagval = flagbuf[row * ncols + col];
+
+	    if (flagval >= 0) {
+		result[col] = residuals[flagval];
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, result);
+
+	G_percent(row + 1, nrows, 1);
+    }
+
+    /* close output file */
+    G_close_cell(out_fd);
+
+    /* =====================
+       ==== free memory ====
+       ===================== */
+    G_free(map);
+    G_free(result);
+    G_free(residuals);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.lm/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/.Makefile.kate-swp
===================================================================
(Binary files differ)


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/.Makefile.kate-swp
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: grass-addons/raster/r.pi/r.pi.neigh/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.neigh
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,34 @@
+<h2>DESCRIPTION</h2>
+
+Neighbourhood analysis - value of patches within a defined range. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.index.html">r.fragment</a>,
+<a href="r.pi.prox.html">r.fragment.dist</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,144 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int getNeighbors(Position * res, int x, int y, int nx, int ny, int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+void writeFrag(int row, int col, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt = getNeighbors(nbr_list, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,103 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL *get_dist_matrix(int count)
+{
+    int i, j;
+    DCELL *distmatrix;
+
+    distmatrix = (DCELL *) G_malloc(count * count * sizeof(DCELL));
+
+    /* fill distance matrix */
+    for (i = 0; i < count; i++) {
+	for (j = i + 1; j < count; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * count + j] = d;
+	    distmatrix[j * count + i] = d;
+	}
+    }
+
+    return distmatrix;
+}
+
+void compute_values(DCELL * vals, int min, int max, f_func stat_method)
+{
+    int i, j;
+    int counter;
+    DCELL *distmatrix = get_dist_matrix(fragcount);
+    DCELL *patch_vals = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+    fprintf(stderr, "fragcount = %d\n\n", fragcount);
+
+    for (i = 0; i < fragcount; i++) {
+	counter = 0;
+	for (j = 0; j < fragcount; j++) {
+	    if (i != j) {
+		DCELL d = distmatrix[i * fragcount + j];
+
+		if (d >= min && d <= max) {
+		    patch_vals[counter] = valsbuf[j];
+		    counter++;
+		}
+	    }
+	}
+
+	/*              fprintf(stderr, "patch_values%d:", i);
+	   for(j = 0; j < counter; j++) {
+	   fprintf(stderr, " %0.2f", patch_vals[j]);
+	   }
+	   fprintf(stderr, "\n"); */
+
+	vals[i] = stat_method(patch_vals, counter);
+	// fprintf(stderr, "vals[%d] = %0.2f\n", i, vals[i]);
+    }
+
+    G_free(distmatrix);
+    G_free(patch_vals);
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define MAX_DOUBLE 1000000.0
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef DCELL(*f_func) (DCELL * values, int count);
+
+/* frag.c */
+void writeFrag(int row, int col, int nbr_cnt);
+
+/* func.c */
+void compute_values(DCELL * vals, int min, int max, f_func stat_method);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL mode(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL Coords **fragments;
+GLOBAL int fragcount;
+GLOBAL int *flagbuf;
+GLOBAL DCELL *valsbuf;
+GLOBAL Coords *actpos;
+GLOBAL int cnt;


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,333 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.neigh
+ * AUTHOR(S):    Elshad Shirinov, Martin Wegmann
+ * PURPOSE:      Neighbourhood analysis - value of patches within a defined range
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct menu
+{
+    f_func *method;		/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct menu menu[] = {
+    {min, "min", "minimum of patch-values within certain range"},
+    {max, "max", "maximum of patch-values within certain range"},
+    {average, "average", "average of patch-values within certain range"},
+    {variance, "var", "variance of patch-values within certain range"},
+    {0, 0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char *vals_name, *vals_mapset;
+    char title[1024];
+    int verbose;
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+    DCELL *result, res[30];
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+    struct Categories cats;
+
+    int method;
+    f_func stat_method;
+
+    char *p;
+
+    /* neighbors count */
+    int neighb_count;
+
+    int row, col, i, j;
+    int readrow;
+    int keyval;
+    int min = 0;
+    int max = MAX_DOUBLE;
+
+    int n;
+    int copycolr;
+    struct Colors colr;
+    struct GModule *module;
+    struct
+    {
+	struct Option *input1, *input2, *output;
+	struct Option *keyval, *method;
+	struct Option *min, *max, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    DCELL *values;
+    Coords *cells;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Neighbourhood analysis - value of patches within a defined range.");
+
+    parm.input1 = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input1->key = "input1";
+    parm.input1->gisprompt = "old,cell,raster,1";
+
+    parm.input2 = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input2->key = "input2";
+    parm.input2->gisprompt = "old,cell,raster,1";	/* 1? */
+    parm.input2->description = _("Raster file with values of patches to use");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    p = parm.method->options = G_malloc(1024);
+    for (n = 0; menu[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, menu[n].name);
+    }
+    parm.method->description = _("Operation to perform on fragments");
+
+    parm.min = G_define_option();
+    parm.min->key = "min";
+    parm.min->type = TYPE_INTEGER;
+    parm.min->required = NO;
+    parm.min->description =
+	_("Minimum range for the operation measured by pixels, default 0");
+
+    parm.max = G_define_option();
+    parm.max->key = "max";
+    parm.max->type = TYPE_INTEGER;
+    parm.max->required = NO;
+    parm.max->description =
+	_("Maximum Range for the operation measured by pixels, default complete map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input1->answer;
+    vals_name = parm.input2->answer;
+
+    /* get mapset */
+    oldmapset = G_find_cell2(oldname, "");
+    vals_mapset = G_find_cell2(vals_name, "");
+
+    /* test input file existance */
+	if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+	if (vals_mapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), vals_name);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;
+
+    /* copy color table */
+    copycolr = (G_read_colors(oldname, oldmapset, &colr) > 0);
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get the method */
+    for (method = 0; (p = menu[method].name); method++)
+	if ((strcmp(p, parm.method->answer) == 0))
+	    break;
+    if (!p) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.method->key, parm.method->answer, parm.method->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* establish the newvalue routine */
+    stat_method = menu[method].method;
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    actpos = cells;
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    fragments[0] = cells;
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    result = G_allocate_d_raster_buf();
+
+    /* get min */
+    if (parm.min->answer)
+	sscanf(parm.min->answer, "%d", &min);
+
+    /* get max */
+    if (parm.max->answer)
+	sscanf(parm.max->answer, "%d", &max);
+
+    /* get title */
+    if (parm.title->answer)
+	strcpy(title, parm.title->answer);
+    else
+	sprintf(title, "Fragmentation of file: %s", oldname);
+
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    if (verbose = !flag.quiet->answer)
+	fprintf(stderr, "Percent complete ... ");
+
+    /* create flag buffer */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+    }
+
+    /* close cell file */
+    G_close_cell(in_fd);
+
+    /* find fragments */
+    fragcount = 0;
+    for (row = 0; row < nrows; row++) {
+	/* display progress */
+	if (verbose)
+	    G_percent(row, nrows, 2);
+
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+		writeFrag(row, col, neighb_count);
+		fragments[fragcount] = actpos;
+	    }
+	}
+    }
+
+    if (verbose)
+	G_percent(1, 1, 2);
+
+    /* open patch-values file */
+    in_fd = G_open_cell_old(vals_name, vals_mapset);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), vals_name);
+
+    if (verbose = !flag.quiet->answer)
+	G_message("Read patch-values...");
+
+    /* read patch-values */
+    valsbuf = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+    for (i = 0; i < fragcount; i++) {
+	col = fragments[i]->x;
+	row = fragments[i]->y;
+
+	if (verbose)
+	    G_percent(i, fragcount, 2);
+
+	G_get_d_raster_row(in_fd, result, row);
+	valsbuf[i] = result[col];
+    }
+
+    /* perform actual function on the patches */
+    values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+    compute_values(values, min, max, stat_method);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(result, ncols);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (actpos = fragments[i]; actpos < fragments[i + 1]; actpos++) {
+		if (actpos->y == row) {
+		    result[actpos->x] = values[i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, result);
+    }
+
+    if (verbose)
+	G_percent(row, nrows, 2);
+
+    G_close_cell(in_fd);
+    G_close_cell(out_fd);
+
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+    G_free(values);
+    G_free(valsbuf);
+
+    G_init_cats(0, title, &cats);
+    G_write_cats(newname, &cats);
+
+    if (copycolr)
+	G_write_colors(newname, newmapset, &colr);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.neigh/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.neigh/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.neigh/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,177 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+void quicksort(DCELL * vals, int begin, int end)
+{
+    int i, j;
+    DCELL pivot, tmp;
+
+    if (end <= begin)
+	return;
+
+    i = begin;
+    j = end - 1;
+    pivot = vals[end];
+
+    while (i <= j) {
+	while (i <= j && vals[i] < pivot)
+	    i++;
+	while (i <= j && vals[j] >= pivot)
+	    j--;
+
+	if (i < j) {
+	    tmp = vals[i];
+	    vals[i] = vals[j];
+	    vals[j] = tmp;
+	    i++;
+	    j--;
+	}
+    }
+
+    tmp = vals[i];
+    vals[i] = vals[end];
+    vals[end] = tmp;
+    i++;
+
+    quicksort(vals, begin, j);
+    quicksort(vals, i, end);
+}
+
+DCELL mode(DCELL * vals, int count)
+{
+    DCELL actval, maxval;
+    int actcnt, maxcnt;
+    int actpos;
+    int i;
+
+    if (count <= 0)
+	return 0;
+
+    quicksort(vals, 0, count - 1);
+
+    fprintf(stderr, "vals = (%0.2f", vals[0]);
+    for (i = 1; i < count; i++)
+	fprintf(stderr, ",%0.2f", vals[i]);
+    fprintf(stderr, ")\n\n");
+
+    maxval = 0;
+    maxcnt = 0;
+    actpos = 0;
+    while (actpos < count) {
+	actcnt = 0;
+	actval = vals[actpos];
+	while (actpos < count && actval == vals[actpos]) {
+	    actcnt++;
+	    actpos++;
+	}
+	if (actcnt > maxcnt) {
+	    maxcnt = actcnt;
+	    maxval = actval;
+	}
+    }
+
+    return maxval;
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL minval = vals[0];
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 1; i < count; i++)
+	if (vals[i] < minval)
+	    minval = vals[i];
+
+    return minval;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL maxval = vals[0];
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 1; i < count; i++)
+	if (vals[i] > maxval)
+	    maxval = vals[i];
+
+    return maxval;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.neigh/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.nlm
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,36 @@
+<h2>DESCRIPTION</h2>
+
+Creates a random generated map with values 0 or 1" "by given landcover and agglomeration value. 
+
+<h2>NOTES</h2>
+
+Related to r.pi.nlm but using fractal landscapes instead of circular growth. Per default the size of the whole region is used for generating a random landscape, this can be constraint by assigning a class in the raster map with acts as mask for the generation of the random landscape (<em>nullval</em>).
+The landcover can be set manually, randomly or be taken from the input class coverage. The agglomeration level (<em>sharpness</em>) can be set manually or randomly. If similar random landscape with differing e.g. percentage coverage should be generated, then the <em>seed</em> can be set using any number and reused for any subsequent analysis.
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+A random landscape is generated using the percentage coverage of class 5. The agglomeration factor is set randomly.<br>
+<div class="code"><pre>
+<b>r.pi.nlm input=</b>landclass96 <b>output=</b>nlm.1 <b>keyval=</b>5 <b>--o</b>
+
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.nlm.html">r.nlm</a>,
+<a href="r.nlm.stats.html">r.nlm.stats</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,258 @@
+#include "local_proto.h"
+
+int GetCell(double *map, int x, int y, int size, double *res)
+{
+    if ((x >= 0) && (x < size) && (y >= 0) && (y < size)) {
+	*res = map[x + y * size];
+	if (G_is_d_null_value(res)) {
+	    double min, max;
+
+	    MinMax(map, &min, &max, size * size);
+	    *res = min;
+	}
+	return 1;
+    }
+    else {
+	*res = 0;
+	return 0;
+    }
+}
+
+void SetCell(double *map, int x, int y, int size, double value)
+{
+    //      fprintf(stderr, "writing value = %f to x = %d y = %d\n", value, x, y);
+    if (!G_is_d_null_value(&map[x + y * size]))
+	map[x + y * size] = value;
+    //      fprintf(stderr, "map[%d,%d] = %f\n", x, y, map[x + y * size]);
+}
+
+double DownSample(double *map, int x, int y, int newcols, int newrows,
+		  int oldsize)
+{
+    int topleftX = oldsize * x / newcols;
+    int topleftY = oldsize * y / newrows;
+    int bottomrightX = oldsize * (x + 1) / newcols;
+    int bottomrightY = oldsize * (y + 1) / newrows;
+
+    int i, j;
+    double cell;
+    int cnt = 0;
+    double sum = 0;
+
+    for (i = topleftX; i < bottomrightX; i++) {
+	for (j = topleftY; j < bottomrightY; j++) {
+	    if (GetCell(map, i, j, oldsize, &cell)) {
+		cnt++;
+		sum += cell;
+	    }
+	}
+    }
+
+    return sum / (double)cnt;
+}
+
+double UpSample(int *map, int x, int y, int oldcols, int oldrows, int newsize)
+{
+    /* bilinear interpolation */
+    double xval = ((double)x + 0.5) / (double)newsize * (double)oldcols;
+    double yval = ((double)y + 0.5) / (double)newsize * (double)oldrows;
+    int oldx = floor(xval);
+    int oldy = floor(yval);
+
+    /*double dummy;
+       double fracx = modf(xval, dummy);
+       double fracy = modf(yval, dummy);
+
+       int i, j;
+
+       for(i = -1; i <= 0; i++) {
+       for(j = -1; j <= 0; j++) {
+       int actx = oldx + i;
+       int acty = oldy + j;
+
+       if(actx >= 0 && actx < oldcols && acty >= 0 && acty < oldrows) {
+
+       }
+       }
+       } */
+
+    double res = 0;
+
+    if (map[oldx + oldy * oldcols] != 0) {
+	G_set_d_null_value(&res, 1);
+    }
+    return res;
+}
+
+void MinMax(double *map, double *min, double *max, int size)
+{
+    int i;
+
+    if (size == 0)
+	return;
+
+    *min = MAX_DOUBLE;
+    *max = MIN_DOUBLE;
+    for (i = 1; i < size; i++) {
+	if (!G_is_d_null_value(&map[i])) {
+	    if (map[i] < *min)
+		*min = map[i];
+	    if (map[i] > *max)
+		*max = map[i];
+	}
+    }
+}
+
+double CutValues(double *map, double mapcover, int size)
+{
+    int values[RESOLUTION - 1];
+    double min, max, span, c;
+    int pixels;
+    int i, j, index;
+    int bottom, top;
+    int topdif, bottomdif;
+
+    // get parameters
+    MinMax(map, &min, &max, size);
+    span = max - min;
+    c = min / span;
+    pixels = Round(size * mapcover);
+
+    // classify heights
+    memset(values, 0, RESOLUTION * sizeof(int));
+    for (i = 0; i < size; i++) {
+	index = floor(RESOLUTION * (map[i] - min) / span);
+	if (index >= RESOLUTION)
+	    index = RESOLUTION - 1;
+	//              index:= RES * map[i] / span - c;
+	values[index]++;
+    }
+
+    // accumulate top to bottom
+    for (i = RESOLUTION - 1; i > 0; i--) {
+	values[i - 1] += values[i];
+    }
+
+    // find matching height
+    bottom = 0;
+    top = RESOLUTION - 1;
+    while (bottom < top) {
+	if (values[bottom] >= pixels)
+	    bottom++;
+	if (values[top] < pixels)
+	    top--;
+    }
+    if (values[bottom] < pixels)
+	bottom--;
+    if (values[top] >= pixels)
+	top++;
+
+    // find the closest to the landcover
+    topdif = abs(values[top] - pixels);
+    bottomdif = abs(values[bottom] - pixels);
+
+    if (topdif < bottomdif) {
+	return span * top / RESOLUTION + min;
+    }
+    else {
+	return span * bottom / RESOLUTION + min;
+    }
+}
+
+void FractalStep(double *map, Point v1, Point v2, Point v3, Point v4,
+		 double d, int size)
+{
+    Point mid;
+    double val1, val2, val3, val4;
+    double mval;
+    double r;
+
+    // get values
+    int cnt = 0;
+
+    if (GetCell(map, v1.x, v1.y, size, &val1))
+	cnt++;
+    if (GetCell(map, v2.x, v2.y, size, &val2))
+	cnt++;
+    if (GetCell(map, v3.x, v3.y, size, &val3))
+	cnt++;
+    if (GetCell(map, v4.x, v4.y, size, &val4))
+	cnt++;
+
+    // calculate midpoints
+    mid.x = (v1.x + v2.x + v3.x + v4.x) / 4;
+    mid.y = (v1.y + v2.y + v3.y + v4.y) / 4;
+
+    // calc mid values
+    r = (Randomf() - 0.5) * 2;
+    mval = (val1 + val2 + val3 + val4) / cnt + r * d;
+
+    // set new values
+    SetCell(map, mid.x, mid.y, size, mval);
+}
+
+void FractalIter(double *map, double d, double dmod, int n, int size)
+{
+    int step;
+    Point v1, v2, v3, v4;
+    int i, x, y, dx;
+    double actd = d;
+    int xdisp;
+
+    // initialize corners
+    SetCell(map, 0, 0, size, 2 * (Randomf() - 0.5));
+    SetCell(map, size - 1, 0, size, 2 * (Randomf() - 0.5));
+    SetCell(map, 0, size - 1, size, 2 * (Randomf() - 0.5));
+    SetCell(map, size - 1, size - 1, size, 2 * (Randomf() - 0.5));
+
+    // calculate starting step width
+    step = size;
+
+    for (i = 0; i < n; i++) {
+	// do diamond step
+	for (x = 0; x < (1 << i); x++) {
+	    for (y = 0; y < (1 << i); y++) {
+		v1.x = x * step;
+		v1.y = y * step;
+		v2.x = (x + 1) * step;
+		v2.y = y * step;
+		v3.x = x * step;
+		v3.y = (y + 1) * step;
+		v4.x = (x + 1) * step;
+		v4.y = (y + 1) * step;
+		FractalStep(map, v1, v2, v3, v4, actd, size);
+	    }
+	}
+
+	// adjust step
+	step >>= 1;
+
+	// do square step
+	xdisp = 1;
+	for (y = 0; y <= (1 << (i + 1)); y++) {
+	    for (x = 0; x <= (1 << i) - xdisp; x++) {
+		dx = 2 * x + xdisp;
+		v1.x = dx * step;
+		v1.y = (y - 1) * step;
+		v2.x = (dx + 1) * step;
+		v2.y = y * step;
+		v3.x = dx * step;
+		v3.y = (y + 1) * step;
+		v4.x = (dx - 1) * step;
+		v4.y = y * step;
+		FractalStep(map, v1, v2, v3, v4, actd, size);
+	    }
+
+	    // switch row offset
+	    if (xdisp == 0) {
+		xdisp = 1;
+	    }
+	    else {
+		xdisp = 0;
+	    }
+	}
+
+	// adjust displacement
+	actd = actd * dmod;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,59 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, " * ", TYPE_NOTHING);
+		break;
+	    case TYPE_NOGO:
+		fprintf(stderr, " X ", TYPE_NOGO);
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d ", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, " %d ", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/list.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/list.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/list.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,142 @@
+#include "local_proto.h"
+
+Point_List *list_array;
+
+void list_init(int count, int rows, int cols)
+{
+    int i;
+
+    /* allocate memory */
+    list_array = (Point_List *) G_malloc(count * sizeof(Point_List));
+
+    for (i = 0; i < count; i++) {
+	/* allocate point lists */
+	list_array[i].list = (Point *) G_malloc(rows * cols * sizeof(Point));
+	list_array[i].count = 0;
+    }
+}
+
+int list_count(int patch)
+{
+    return list_array[patch].count;
+}
+
+Point *list_patch(int patch)
+{
+    return list_array[patch].list;
+}
+
+void list_add(int patch, int x, int y)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    list[cnt].x = x;
+    list[cnt].y = y;
+    list_array[patch].count++;
+}
+
+Point list_get(int patch, int pos)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+    Point res;
+
+    memset(&res, 0, sizeof(Point));
+
+    if (pos >= 0 && pos < cnt) {
+	res.x = list[pos].x;
+	res.y = list[pos].y;
+    }
+
+    return res;
+}
+
+void list_set(int patch, int pos, int x, int y)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt) {
+	list[pos].x = x;
+	list[pos].y = y;
+    }
+}
+
+void list_insert(int patch, int pos, int x, int y)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt) {
+	memmove(list + pos + 1, list + pos, (cnt - pos) * sizeof(Point));
+	list[pos].x = x;
+	list[pos].y = y;
+	list_array[patch].count++;
+    }
+    else {
+	list_add(patch, x, y);
+    }
+}
+
+void list_remove(int patch, int pos)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt) {
+	list_array[patch].count--;
+	cnt--;
+	memmove(list + pos, list + pos + 1, (cnt - pos) * sizeof(Point));
+    }
+}
+
+void list_remove_range(int patch, int pos, int size)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt && size > 0) {
+	if (pos + size < cnt) {
+	    list_array[patch].count -= size;
+	    cnt -= size;
+	    memmove(list + pos, list + pos + size,
+		    (cnt - pos) * sizeof(Point));
+	}
+	else {
+	    list_array[patch].count = pos;
+	}
+    }
+}
+
+int list_indexOf(int patch, int x, int y)
+{
+    int i;
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    for (i = 0; i < cnt; i++) {
+	if (list[i].x == x && list[i].y == y)
+	    return i;
+    }
+
+    return -1;
+}
+
+/* shuffles a list */
+void list_shuffle(int patch)
+{
+    int i, pos;
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+    Point tmp;
+
+    //      fprintf(stderr, "shuffling:\n");
+    for (i = 0; i < cnt - 1; i++) {
+	pos = Random(cnt - i) + i;
+	//              fprintf(stderr, " %d <-> %d ", i, pos);
+	tmp = list[i];
+	list[i] = list[pos];
+	list[pos] = tmp;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/list.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,65 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include <time.h>
+
+#define TYPE_NOTHING 0
+#define TYPE_NOGO -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+} Point;
+
+typedef struct
+{
+    Point *list;
+    int count;
+} Point_List;
+
+/* list_array */
+
+extern Point_List *list_array;
+
+/* list.c */
+void list_init(int count, int rows, int cols);
+int list_count(int patch);
+Point *list_patch(int patch);
+void list_add(int patch, int x, int y);
+Point list_get(int patch, int pos);
+void list_set(int patch, int pos, int x, int y);
+void list_insert(int patch, int pos, int x, int y);
+void list_remove(int patch, int pos);
+void list_remove_range(int patch, int pos, int size);
+int list_indexOf(int patch, int x, int y);
+void list_shuffle(int patch);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_map(double *map, int size);
+
+/* func.c */
+void FractalIter(double *map, double d, double dmod, int n, int size);
+double DownSample(double *map, int x, int y, int newcols, int newrows,
+		  int oldsize);
+double CutValues(double *map, double mapcover, int size);
+double UpSample(int *map, int x, int y, int oldcols, int oldrows,
+		int newsize);
+void MinMax(double *map, double *min, double *max, int size);
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,318 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.nlm.2
+ * AUTHOR(S):    Elshad Shirinov, Martin Wegmann
+ * PURPOSE:      Generation of Neutral Landscapes (fractal landscapes), similar to r.pi.nlm, but fractal landscapes instead of circular growth
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
+
+#include "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* output */
+    char *newname, *newmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+
+    /* parameters */
+    int sx, sy;
+    int keyval, nullval;
+    double landcover;
+    int pixel_count;
+    double sharpness;
+    int rand_seed;
+
+    /* other parameters */
+    int verbose;
+    char *title;
+
+    /* helper variables */
+    RASTER_MAP_TYPE map_type;
+    int *buffer;
+    double *bigbuf;
+    int i, j;
+    int row, col;
+    int cnt;
+    Point *list;
+    CELL *result;
+    int size, n;
+    double edge;
+    struct Cell_head ch, window;
+    double min, max;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output, *size, *nullval;
+	struct Option *keyval, *landcover, *sharpness;
+	struct Option *randseed, *title;
+    } parm;
+    struct
+    {
+	struct Flag *quiet;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Creates a random generated map with values 0 or 1"
+	  "by given landcover and fragment count.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input->key = "input";
+    parm.input->required = NO;
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = NO;
+    parm.keyval->description =
+	_("Value of a category from the input file to measure desired landcover");
+
+    parm.nullval = G_define_option();
+    parm.nullval->key = "nullval";
+    parm.nullval->type = TYPE_INTEGER;
+    parm.nullval->required = NO;
+    parm.nullval->multiple = YES;
+    parm.nullval->description =
+	_("Values marking areas from the input file, which are to be NULL in the resulting map");
+
+    parm.landcover = G_define_option();
+    parm.landcover->key = "landcover";
+    parm.landcover->type = TYPE_DOUBLE;
+    parm.landcover->required = NO;
+    parm.landcover->description = _("Landcover in percent");
+
+    parm.sharpness = G_define_option();
+    parm.sharpness->key = "sharpness";
+    parm.sharpness->type = TYPE_DOUBLE;
+    parm.sharpness->required = NO;
+    parm.sharpness->description =
+	_("Small values produce smooth structures, great values"
+	  " produce sharp, edgy structures - Range [0-1]");
+
+    parm.randseed = G_define_option();
+    parm.randseed->key = "seed";
+    parm.randseed->type = TYPE_INTEGER;
+    parm.randseed->required = NO;
+    parm.randseed->description = _("Seed for random number generator");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    if (oldname && NULL == (oldmapset = G_find_cell2(oldname, "")))
+	    G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* if input specified get keyval */
+    if (oldname) {
+	if (parm.keyval->answer) {
+	    sscanf(parm.keyval->answer, "%d", &keyval);
+	}
+	else if (!parm.landcover->answer) {
+		G_fatal_error("Specify either landcover or an input file with key value for landcover to be acquired!");
+	    }
+    }
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    map_type = CELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    size = 1;
+    n = 0;
+    while (size < sx - 1 || size < sy - 1) {
+	size <<= 1;
+	n++;
+    }
+    size++;
+
+    /* get random seed and init random */
+    if (parm.randseed->answer) {
+	sscanf(parm.randseed->answer, "%d", &rand_seed);
+    }
+    else {
+	rand_seed = time(NULL);
+    }
+    srand(rand_seed);
+
+    /* get landcover from user input */
+    if (parm.landcover->answer) {
+	sscanf(parm.landcover->answer, "%lf", &landcover);
+	landcover /= 100;
+    }
+    else {
+	if (!oldname)
+	   G_fatal_error("Specify either landcover or an input file with key value for landcover to be acquired!");
+	}
+
+    /* get sharpness */
+    if (parm.sharpness->answer) {
+	sscanf(parm.sharpness->answer, "%lf", &sharpness);
+    }
+    else {
+	sharpness = Randomf();
+    }
+
+    /* get verbose */
+    verbose = !flag.quiet->answer;
+
+    /* allocate the cell buffer */
+    buffer = (int *)G_malloc(sx * sy * sizeof(int));
+    bigbuf = (double *)G_malloc(size * size * sizeof(double));
+    result = G_allocate_c_raster_buf();
+
+    /* init buffers */
+    memset(bigbuf, 0, size * size * sizeof(double));
+    memset(buffer, TYPE_NOTHING, sx * sy * sizeof(int));
+
+    /* load values from input file */
+    if (oldname) {
+	pixel_count = 0;
+
+	/* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+	/* init buffer with values from input and get landcover */
+	for (row = 0; row < sy; row++) {
+	    G_get_c_raster_row(in_fd, result, row);
+	    for (col = 0; col < sx; col++) {
+		if (parm.nullval->answers) {
+		    for (i = 0; parm.nullval->answers[i] != NULL; i++) {
+			sscanf(parm.nullval->answers[i], "%d", &nullval);
+			if (result[col] == nullval)
+			    buffer[row * sx + col] = 1;
+		    }
+		}
+
+		/* count pixels for landcover */
+		if (result[col] == keyval)
+		    pixel_count++;
+	    }
+	}
+
+	/* calculate landcover */
+	if (parm.keyval->answer)
+	    landcover = (double)pixel_count / ((double)sx * (double)sy);
+
+	/* resample to bigbuf */
+	for (col = 0; col < size; col++) {
+	    for (row = 0; row < size; row++) {
+		bigbuf[row * size + col] =
+		    UpSample(buffer, col, row, sx, sy, size);
+	    }
+	}
+    }
+
+    /* create fractal */
+    FractalIter(bigbuf, 1, pow(2, -sharpness), n, size);
+
+    /* replace nan values with min value */
+    MinMax(bigbuf, &min, &max, size * size);
+
+    for (i = 0; i < size * size; i++)
+	if (G_is_d_null_value(&bigbuf[i]))
+	    bigbuf[i] = min;
+
+    /* find edge */
+    edge = CutValues(bigbuf, landcover, size * size);
+
+    /* resample map to desired size */
+    for (i = 0; i < sx; i++) {
+	for (j = 0; j < sy; j++) {
+	    double val = DownSample(bigbuf, i, j, sx, sy, size);
+	    double old = buffer[i + j * sx];
+
+	    if (val >= edge && old == 0) {
+		buffer[i + j * sx] = 1;
+	    }
+	    else {
+		buffer[i + j * sx] = 0;
+	    }
+	}
+    }
+
+
+    /* write output file */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    for (j = 0; j < sy; j++) {
+	for (i = 0; i < sx; i++) {
+	    int cell = buffer[i + j * sx];
+
+	    if (cell > 0) {
+		result[i] = 1;
+	    }
+	    else {
+		G_set_c_null_value(result + i, 1);
+	    }
+	}
+	G_put_c_raster_row(out_fd, result);
+    }
+
+    G_close_cell(in_fd);
+    G_close_cell(out_fd);
+
+    /* print report */
+    if (verbose) {
+	fprintf(stderr, "report:\n");
+	fprintf(stderr, "written file: <%s>\n", newname);
+
+	cnt = 0;
+	for (i = 0; i < sx * sy; i++)
+	    if (buffer[i] == 1)
+		cnt++;
+	landcover = (double)cnt / ((double)sx * (double)sy) * 100;
+	fprintf(stderr, "landcover: %0.2lf%%\n", landcover);
+    }
+
+    G_free(buffer);
+    G_free(bigbuf);
+    G_free(result);
+
+    if (verbose)
+	G_percent(100, 100, 2);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.circ/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.circ/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.circ/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.nlm.circ
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.circ/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.circ/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.circ/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.circ/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,83 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.nlm</em> is a random patch generator. It creates a random landscape
+with defined attributes. 
+
+<h2>NOTES</h2>
+
+The user must specify the names of the raster map layers to
+be used for <em>input</em> and <em>output</em>, the
+<em>landcover</em>, the
+<em>size</em>, the
+<em>count</em> used, the <em>keyval</em> 
+of the class of interest of the input raster map.
+
+
+<dt><b>Input</b> 
+
+<dd>The <em>Input</em> is potentially used for Landcover, size and count.
+
+<dt><b>keyval</b> 
+
+<dd>The <em>keyval</em> is used to compute landcover and count if not declared.
+
+<dt><b>landcover</b> 
+
+<dd>The <em>landcover</em> defines the amount of cover, if not declared,
+the landcover of keyval of input is used.
+
+<dt><b>count</b> 
+
+<dd>The <em>count</em> defines the amount of patches in the landscape,
+if not defined, the amount of patches in the input is used, if 0 is inserted,
+random amount of patches are created. Values from 1-n can be defined for
+a fixed number of patches.
+
+<dt><b>size</b> 
+
+<dd>The <em>size</em> defines the size of the artificial landscape. If
+not declared the size of the actual region is taken. 
+
+
+<dt><b>seed</b> 
+
+<dd>The <em>seed</em> defiens the seed of random points. If all settings
+and the seed is fixed, then the patches won't be random anymore, but
+fixed. The user will receive everytime the same landscape.
+
+<dt><b>xxx</b> 
+
+<dd>The <em>xxx</em> ....
+
+<dt><b>xxx</b> 
+
+<dd>The <em>xxx</em> ....
+
+</dl>
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.nlm.fractal.html">r.nlm.fractal</a>,
+<a href="r.nlm.stats.html">r.nlm.stats</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.circ/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.circ/list.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.circ/list.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.circ/list.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,106 @@
+#include "local_proto.h"
+
+Point_List *list_array;
+
+void list_init(int count, int rows, int cols)
+{
+    int i;
+
+    /* allocate memory */
+    list_array = (Point_List *) G_malloc(count * sizeof(Point_List));
+
+    for (i = 0; i < count; i++) {
+	/* allocate point lists */
+	list_array[i].list = (Point *) G_malloc(rows * cols * sizeof(Point));
+	list_array[i].count = 0;
+    }
+}
+
+int list_count(int patch)
+{
+    return list_array[patch].count;
+}
+
+Point *list_patch(int patch)
+{
+    return list_array[patch].list;
+}
+
+void list_add(int patch, int x, int y)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    list[cnt].x = x;
+    list[cnt].y = y;
+    list_array[patch].count++;
+}
+
+Point list_get(int patch, int pos)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+    Point res;
+
+    memset(&res, 0, sizeof(Point));
+
+    if (pos >= 0 && pos < cnt) {
+	res.x = list[pos].x;
+	res.y = list[pos].y;
+    }
+
+    return res;
+}
+
+void list_set(int patch, int pos, int x, int y)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt) {
+	list[pos].x = x;
+	list[pos].y = y;
+    }
+}
+
+void list_insert(int patch, int pos, int x, int y)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt) {
+	memmove(list + pos + 1, list + pos, (cnt - pos) * sizeof(Point));
+	list[pos].x = x;
+	list[pos].y = y;
+	list_array[patch].count++;
+    }
+    else {
+	list_add(patch, x, y);
+    }
+}
+
+void list_remove(int patch, int pos)
+{
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    if (pos >= 0 && pos < cnt) {
+	list_array[patch].count--;
+	cnt--;
+	memmove(list + pos, list + pos + 1, (cnt - pos) * sizeof(Point));
+    }
+}
+
+int list_indexOf(int patch, int x, int y)
+{
+    int i;
+    int cnt = list_array[patch].count;
+    Point *list = list_array[patch].list;
+
+    for (i = 0; i < cnt; i++) {
+	if (list[i].x == x && list[i].y == y)
+	    return i;
+    }
+
+    return -1;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.circ/list.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.circ/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.circ/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.circ/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,41 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include <time.h>
+
+#define TYPE_NOTHING -1
+#define TYPE_NOGO -2
+
+typedef struct
+{
+    int x, y;
+} Point;
+
+typedef struct
+{
+    Point *list;
+    int count;
+} Point_List;
+
+/* list_array */
+
+extern Point_List *list_array;
+
+void list_init(int count, int rows, int cols);
+int list_count(int patch);
+Point *list_patch(int patch);
+void list_add(int patch, int x, int y);
+Point list_get(int patch, int pos);
+void list_set(int patch, int pos, int x, int y);
+void list_insert(int patch, int pos, int x, int y);
+void list_remove(int patch, int pos);
+int list_indexOf(int patch, int x, int y);
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.circ/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.circ/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.circ/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.circ/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,385 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.nlm.circ
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      a simple r.nlm (neutral landscape model) module based on circular growth
+ * 
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
+
+#include "local_proto.h"
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "* ", TYPE_NOTHING);
+		break;
+	    case TYPE_NOGO:
+		fprintf(stderr, "X ", TYPE_NOGO);
+		break;
+	    default:
+		fprintf(stderr, "%d ", buffer[x + y * sx]);
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_list(int patch_count)
+{
+    int i, j;
+    int cnt;
+    Point *list;
+
+    fprintf(stderr, "list_array:\n");
+    for (i = 0; i < patch_count; i++) {
+	cnt = list_count(i);
+	list = list_patch(i);
+
+	fprintf(stderr, "patch %d: ", i);
+	for (j = 0; j < cnt; j++)
+	    fprintf(stderr, "(%d, %d)", list[j].x, list[j].y);
+	fprintf(stderr, "\n");
+    }
+}
+
+/* 
+   plants new cell for the specified patch
+   WARNING:     no tests are performed to determine
+   if position is legal
+ */
+void plant(int *buffer, int sx, int sy, int x, int y, int patch)
+{
+    int right = x + 1 < sx ? x + 1 : sx - 1;
+    int left = x > 0 ? x - 1 : 0;
+    int top = y + 1 < sy ? y + 1 : sy - 1;
+    int bottom = y > 0 ? y - 1 : 0;
+
+    int ix, iy, index, i, cell;
+
+    /* remove cell from border list */
+    list_remove(patch, list_indexOf(patch, x, y));
+
+    for (ix = left; ix <= right; ix++) {
+	for (iy = bottom; iy <= top; iy++) {
+	    /* don't add the cell itself */
+	    if (!(ix == x && iy == y)) {
+		index = ix + iy * sx;
+		cell = buffer[index];
+		switch (cell) {
+		case TYPE_NOTHING:
+		    /* mark cell as owned by patch */
+		    buffer[index] = patch;
+		    /* if not already on list add cell to border list */
+		    index = list_indexOf(patch, ix, iy);
+		    if (index < 0)
+			list_add(patch, ix, iy);
+		    break;
+		case TYPE_NOGO:
+		    /* well basically nothing to do here :) */
+		    break;
+		default:
+		    /* test if cell is owned by other patch */
+		    if (cell != patch) {
+			/* mark cell as "no go" */
+			buffer[index] = TYPE_NOGO;
+			/* remove cell from owners border list */
+			list_remove(cell, list_indexOf(cell, ix, iy));
+		    }
+		    break;
+		}		/* switch */
+	    }			/* if */
+	}			/* for x */
+    }				/* for y */
+}
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+void create_patches(int *buffer, int sx, int sy, int patch_count,
+		    int pixel_count)
+{
+    int pixels = pixel_count;
+    int i, j;
+    int cnt;
+    Point *list;
+
+    /* init list_array for border data */
+    list_init(patch_count, sx, sy);
+
+    /* create seeds for later patches */
+    for (i = 0; i < patch_count; i++) {
+	int x, y;
+
+	if (pixels <= 0)
+	    break;
+
+	/* find appropriate position */
+	do {
+	    x = Random(sx);
+	    y = Random(sy);
+	} while (buffer[x + y * sx] != TYPE_NOTHING);
+	buffer[x + y * sx] = i;
+	plant(buffer, sx, sy, x, y, i);
+	pixels--;
+
+	/*fprintf(stderr, "x = %d, y = %d\n", x, y);
+	   print_buffer(buffer, sx, sy);
+	   print_list(patch_count); */
+    }
+
+    /* now plant new cells at random but always at the border */
+    while (pixels > 0) {
+	int patch, pos, cnt;
+	Point p;
+	int flag;
+
+	/* test if there are some free places */
+	flag = 0;
+	for (patch = 0; patch < patch_count; patch++) {
+	    cnt = list_count(patch);
+	    if (cnt > 0) {
+		flag = 1;
+		break;
+	    }
+	}
+
+	if (!flag)
+	    return;
+
+	/* find patch with free places at the border */
+	do {
+	    patch = Random(patch_count);
+	    cnt = list_count(patch);
+	} while (cnt <= 0);
+
+	/* pick free position */
+	pos = Random(cnt);
+	p = list_get(patch, pos);
+	plant(buffer, sx, sy, p.x, p.y, patch);
+	pixels--;
+
+	/*fprintf(stderr, "x = %d, y = %d\n", p.x, p.y);
+	   print_buffer(buffer, sx, sy);
+	   print_list(patch_count); */
+    }
+
+    /* remove marked cells, which are still on the list */
+    for (i = 0; i < patch_count; i++) {
+	cnt = list_count(i);
+	list = list_patch(i);
+	for (j = 0; j < cnt; j++) {
+	    int x = list[j].x;
+	    int y = list[j].y;
+
+	    buffer[x + y * sx] = TYPE_NOTHING;
+	}
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    /* output */
+    char *newname, *newmapset;
+
+    /* out file pointer */
+    int out_fd;
+
+    /* parameters */
+    int sx, sy;
+    double landcover;
+    int pixel_count;
+    int patch_count;
+    int rand_seed;
+
+    /* other parameters */
+    int verbose;
+    char *title;
+
+    /* helper variables */
+    RASTER_MAP_TYPE map_type;
+    int *buffer;
+    int i, j;
+    int cnt;
+    Point *list;
+    CELL *result;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *output, *size;
+	struct Option *landcover, *count;
+	struct Option *randseed, *title;
+    } parm;
+    struct
+    {
+	struct Flag *quiet;
+    } flag;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Creates a random landscape with defined attributes.");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.size = G_define_option();
+    parm.size->key = "size";
+    parm.size->key_desc = "x,y";
+    parm.size->type = TYPE_INTEGER;
+    parm.size->required = YES;
+    parm.size->description = _("Size of the map");
+
+    parm.landcover = G_define_option();
+    parm.landcover->key = "landcover";
+    parm.landcover->type = TYPE_DOUBLE;
+    parm.landcover->required = YES;
+    parm.landcover->description = _("Landcover in percent");
+
+    parm.count = G_define_option();
+    parm.count->key = "count";
+    parm.count->type = TYPE_INTEGER;
+    parm.count->required = YES;
+    parm.count->description = _("Number of the patches to create");
+
+    parm.randseed = G_define_option();
+    parm.randseed->key = "seed";
+    parm.randseed->type = TYPE_INTEGER;
+    parm.randseed->required = NO;
+    parm.randseed->description = _("Seed for random number generator");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	    exit(EXIT_FAILURE);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    map_type = CELL_TYPE;
+
+    /* get size */
+    sscanf(parm.size->answers[0], "%d", &sx);
+    sscanf(parm.size->answers[1], "%d", &sy);
+
+    /* get landcover */
+    sscanf(parm.landcover->answer, "%lf", &landcover);
+    pixel_count = Round(landcover * sx * sy / 100);
+
+    /* get patchcount */
+    sscanf(parm.count->answer, "%d", &patch_count);
+
+    /* get verbose */
+    verbose = !flag.quiet->answer;
+
+    /* get random seed and init random */
+    if (parm.randseed->answer) {
+	sscanf(parm.randseed->answer, "%d", &rand_seed);
+    }
+    else {
+	rand_seed = time(NULL);
+    }
+    srand(rand_seed);
+
+    /* test output */
+    fprintf(stderr, "This is a test output:\n\n");
+    fprintf(stderr, "output = %s\n", newname);
+    fprintf(stderr, "sx = %d, sy = %d\n", sx, sy);
+    fprintf(stderr, "landcover = %f, pixel_count = %d\n", landcover,
+	    pixel_count);
+    fprintf(stderr, "patch_count = %d\n", patch_count);
+    fprintf(stderr, "rand_seed = %d\n\n", rand_seed);
+
+    /* allocate the cell buffer */
+    buffer = (int *)G_malloc(sx * sy * sizeof(int));
+    memset(buffer, -1, sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+
+    create_patches(buffer, sx, sy, patch_count, pixel_count);
+
+    /* print_buffer(buffer, sx, sy); */
+
+    /* test list */
+    /* list_add(1, 10, 20);
+       list_add(1, 30, 40);
+       list_insert(1, 0, 1, 2);
+       list_remove(1, 1);
+       list_set(1, 1, 3, 4);
+
+       i = list_indexOf(1, 1, 2);
+       fprintf(stderr, "test: %d\n\n", i); 
+
+       fprintf(stderr, "list_array:\n");
+       for(i = 0; i < patch_count; i++) {
+       cnt = list_count(i);
+       list = list_patch(i);
+
+       fprintf(stderr, "patch %d: ", i);
+       for(j = 0; j < cnt; j++)
+       fprintf(stderr, "(%d, %d)", list[j].x, list[j].y);
+       fprintf(stderr, "\n");
+       } */
+
+    /* write output file */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    for (j = 0; j < sy; j++) {
+	for (i = 0; i < sx; i++) {
+	    int cell = buffer[i + j * sx];
+
+	    if (cell >= 0) {
+		result[i] = 1;
+	    }
+	    else {
+		G_set_c_null_value(result + i, 1);
+	    }
+	}
+	G_put_c_raster_row(out_fd, result);
+    }
+    G_close_cell(out_fd);
+
+    if (verbose)
+	G_percent(100, 100, 2);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.circ/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.nlm.stats
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,33 @@
+<h2>DESCRIPTION</h2>
+
+Neutral Landscape Generator - index statistics 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.nlm.html">r.nlm</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/fractal.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/fractal.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/fractal.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,41 @@
+#include "local_proto.h"
+
+void create_map(int *res)
+{
+    double *fractbuf = (double *)G_malloc(size * size * sizeof(double));
+    double min, max;
+    double edge;
+    int i, j;
+
+    /* copy mask from to fractbuf */
+    memmove(fractbuf, bigbuf, size * size * sizeof(double));
+
+    /* create fractal */
+    FractalIter(fractbuf, 1, pow(2, -sharpness), power, size);
+
+    /* replace nan values with min value */
+    MinMax(fractbuf, &min, &max, size * size);
+    for (i = 0; i < size * size; i++)
+	if (G_is_d_null_value(&fractbuf[i]))
+	    fractbuf[i] = min;
+
+    /* find edge */
+    edge = CutValues(fractbuf, landcover, size * size);
+
+    /* resample map to desired size */
+    for (i = 0; i < sx; i++) {
+	for (j = 0; j < sy; j++) {
+	    double val = DownSample(fractbuf, i, j, sx, sy, size);
+	    double old = buffer[i + j * sx];
+
+	    if (val >= edge && old == 0) {
+		res[i + j * sx] = 1;
+	    }
+	    else {
+		res[i + j * sx] = 0;
+	    }
+	}
+    }
+
+    G_free(fractbuf);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/fractal.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,258 @@
+#include "local_proto.h"
+
+int GetCell(double *map, int x, int y, int size, double *res)
+{
+    if ((x >= 0) && (x < size) && (y >= 0) && (y < size)) {
+	*res = map[x + y * size];
+	if (G_is_d_null_value(res)) {
+	    double min, max;
+
+	    MinMax(map, &min, &max, size * size);
+	    *res = min;
+	}
+	return 1;
+    }
+    else {
+	*res = 0;
+	return 0;
+    }
+}
+
+void SetCell(double *map, int x, int y, int size, double value)
+{
+    //      fprintf(stderr, "writing value = %f to x = %d y = %d\n", value, x, y);
+    if (!G_is_d_null_value(&map[x + y * size]))
+	map[x + y * size] = value;
+    //      fprintf(stderr, "map[%d,%d] = %f\n", x, y, map[x + y * size]);
+}
+
+double DownSample(double *map, int x, int y, int newcols, int newrows,
+		  int oldsize)
+{
+    int topleftX = oldsize * x / newcols;
+    int topleftY = oldsize * y / newrows;
+    int bottomrightX = oldsize * (x + 1) / newcols;
+    int bottomrightY = oldsize * (y + 1) / newrows;
+
+    int i, j;
+    double cell;
+    int cnt = 0;
+    double sum = 0;
+
+    for (i = topleftX; i < bottomrightX; i++) {
+	for (j = topleftY; j < bottomrightY; j++) {
+	    if (GetCell(map, i, j, oldsize, &cell)) {
+		cnt++;
+		sum += cell;
+	    }
+	}
+    }
+
+    return sum / (double)cnt;
+}
+
+double UpSample(int *map, int x, int y, int oldcols, int oldrows, int newsize)
+{
+    /* bilinear interpolation */
+    double xval = ((double)x + 0.5) / (double)newsize * (double)oldcols;
+    double yval = ((double)y + 0.5) / (double)newsize * (double)oldrows;
+    int oldx = floor(xval);
+    int oldy = floor(yval);
+
+    /*double dummy;
+       double fracx = modf(xval, dummy);
+       double fracy = modf(yval, dummy);
+
+       int i, j;
+
+       for(i = -1; i <= 0; i++) {
+       for(j = -1; j <= 0; j++) {
+       int actx = oldx + i;
+       int acty = oldy + j;
+
+       if(actx >= 0 && actx < oldcols && acty >= 0 && acty < oldrows) {
+
+       }
+       }
+       } */
+
+    double res = 0;
+
+    if (map[oldx + oldy * oldcols] != 0) {
+	G_set_d_null_value(&res, 1);
+    }
+    return res;
+}
+
+void MinMax(double *map, double *min, double *max, int size)
+{
+    int i;
+
+    if (size == 0)
+	return;
+
+    *min = MAX_DOUBLE;
+    *max = MIN_DOUBLE;
+    for (i = 1; i < size; i++) {
+	if (!G_is_d_null_value(&map[i])) {
+	    if (map[i] < *min)
+		*min = map[i];
+	    if (map[i] > *max)
+		*max = map[i];
+	}
+    }
+}
+
+double CutValues(double *map, double mapcover, int size)
+{
+    int values[RESOLUTION - 1];
+    double min, max, span, c;
+    int pixels;
+    int i, j, index;
+    int bottom, top;
+    int topdif, bottomdif;
+
+    // get parameters
+    MinMax(map, &min, &max, size);
+    span = max - min;
+    c = min / span;
+    pixels = Round(size * mapcover);
+
+    // classify heights
+    memset(values, 0, RESOLUTION * sizeof(int));
+    for (i = 0; i < size; i++) {
+	index = floor(RESOLUTION * (map[i] - min) / span);
+	if (index >= RESOLUTION)
+	    index = RESOLUTION - 1;
+	//              index:= RES * map[i] / span - c;
+	values[index]++;
+    }
+
+    // accumulate top to bottom
+    for (i = RESOLUTION - 1; i > 0; i--) {
+	values[i - 1] += values[i];
+    }
+
+    // find matching height
+    bottom = 0;
+    top = RESOLUTION - 1;
+    while (bottom < top) {
+	if (values[bottom] >= pixels)
+	    bottom++;
+	if (values[top] < pixels)
+	    top--;
+    }
+    if (values[bottom] < pixels)
+	bottom--;
+    if (values[top] >= pixels)
+	top++;
+
+    // find the closest to the landcover
+    topdif = abs(values[top] - pixels);
+    bottomdif = abs(values[bottom] - pixels);
+
+    if (topdif < bottomdif) {
+	return span * top / RESOLUTION + min;
+    }
+    else {
+	return span * bottom / RESOLUTION + min;
+    }
+}
+
+void FractalStep(double *map, Point v1, Point v2, Point v3, Point v4,
+		 double d, int size)
+{
+    Point mid;
+    double val1, val2, val3, val4;
+    double mval;
+    double r;
+
+    // get values
+    int cnt = 0;
+
+    if (GetCell(map, v1.x, v1.y, size, &val1))
+	cnt++;
+    if (GetCell(map, v2.x, v2.y, size, &val2))
+	cnt++;
+    if (GetCell(map, v3.x, v3.y, size, &val3))
+	cnt++;
+    if (GetCell(map, v4.x, v4.y, size, &val4))
+	cnt++;
+
+    // calculate midpoints
+    mid.x = (v1.x + v2.x + v3.x + v4.x) / 4;
+    mid.y = (v1.y + v2.y + v3.y + v4.y) / 4;
+
+    // calc mid values
+    r = (Randomf() - 0.5) * 2;
+    mval = (val1 + val2 + val3 + val4) / cnt + r * d;
+
+    // set new values
+    SetCell(map, mid.x, mid.y, size, mval);
+}
+
+void FractalIter(double *map, double d, double dmod, int n, int size)
+{
+    int step;
+    Point v1, v2, v3, v4;
+    int i, x, y, dx;
+    double actd = d;
+    int xdisp;
+
+    // initialize corners
+    SetCell(map, 0, 0, size, 2 * (Randomf() - 0.5));
+    SetCell(map, size - 1, 0, size, 2 * (Randomf() - 0.5));
+    SetCell(map, 0, size - 1, size, 2 * (Randomf() - 0.5));
+    SetCell(map, size - 1, size - 1, size, 2 * (Randomf() - 0.5));
+
+    // calculate starting step width
+    step = size;
+
+    for (i = 0; i < n; i++) {
+	// do diamond step
+	for (x = 0; x < (1 << i); x++) {
+	    for (y = 0; y < (1 << i); y++) {
+		v1.x = x * step;
+		v1.y = y * step;
+		v2.x = (x + 1) * step;
+		v2.y = y * step;
+		v3.x = x * step;
+		v3.y = (y + 1) * step;
+		v4.x = (x + 1) * step;
+		v4.y = (y + 1) * step;
+		FractalStep(map, v1, v2, v3, v4, actd, size);
+	    }
+	}
+
+	// adjust step
+	step >>= 1;
+
+	// do square step
+	xdisp = 1;
+	for (y = 0; y <= (1 << (i + 1)); y++) {
+	    for (x = 0; x <= (1 << i) - xdisp; x++) {
+		dx = 2 * x + xdisp;
+		v1.x = dx * step;
+		v1.y = (y - 1) * step;
+		v2.x = (dx + 1) * step;
+		v2.y = y * step;
+		v3.x = dx * step;
+		v3.y = (y + 1) * step;
+		v4.x = (dx - 1) * step;
+		v4.y = y * step;
+		FractalStep(map, v1, v2, v3, v4, actd, size);
+	    }
+
+	    // switch row offset
+	    if (xdisp == 0) {
+		xdisp = 1;
+	    }
+	    else {
+		xdisp = 0;
+	    }
+	}
+
+	// adjust displacement
+	actd = actd * dmod;
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,59 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, " * ", TYPE_NOTHING);
+		break;
+	    case TYPE_NOGO:
+		fprintf(stderr, " X ", TYPE_NOGO);
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d ", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, " %d ", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,92 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING 0
+#define TYPE_NOGO -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+} Point;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef int (*f_func) (DCELL *, Coords **, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_map(double *map, int size);
+
+/* func.c */
+void FractalIter(double *map, double d, double dmod, int n, int size);
+double DownSample(double *map, int x, int y, int newcols, int newrows,
+		  int oldsize);
+double CutValues(double *map, double mapcover, int size);
+double UpSample(int *map, int x, int y, int oldcols, int oldrows,
+		int newsize);
+void MinMax(double *map, double *min, double *max, int size);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL mode(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* method.c */
+int f_nearest_dist(DCELL * vals, Coords ** frags, int count);
+int f_area(DCELL * vals, Coords ** frags, int count);
+int f_perim(DCELL * vals, Coords ** frags, int count);
+int f_shapeindex(DCELL * vals, Coords ** frags, int count);
+int f_frac_dim(DCELL * vals, Coords ** frags, int count);
+
+/* fractal.c */
+void create_map(int *res);
+
+/* frag.c */
+/* writes one fragment */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* global parameters */
+GLOBAL int verbose;
+GLOBAL int *buffer;
+GLOBAL double *bigbuf;
+GLOBAL double landcover;
+GLOBAL int sx, sy;
+GLOBAL int power, size;
+GLOBAL double sharpness;
+
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,572 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.nlm.stats
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Generation of Neutral Landscapes and statistical analysis 
+ *                               of fragmentation indices
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct method
+{
+    f_func *method;
+    char *name;
+    char *text;
+};
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct method methodlist[] = {
+    {f_nearest_dist, "distance", "distance to the patch"},
+    {f_area, "area", "area of the patch"},
+    {f_perim, "perimeter", "perimeter of the patch"},
+    {f_shapeindex, "shapeindex", "shapeindex of the patch"},
+    {f_frac_dim, "fractal", "fractal index of the patch"},
+    {0, 0, 0}
+};
+
+static struct statmethod statmethodlist[] = {
+    {average, "average", "average of values"},
+    {mode, "mode", "mode of values"},
+    {median, "median", "median of values"},
+    {variance, "variance", "variance of values"},
+    {min, "min", "minimum of values"},
+    {max, "max", "maximum of values"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* in and out file pointers */
+    int in_fd;			/* raster - input */
+    FILE *out_fp;		/* ASCII - output */
+    FILE *out_rl;		/* ASCII - output for real landscape */
+
+    /* parameters */
+    int n;
+    int keyval, nullval;
+    int pixel_count;
+    int rand_seed;
+    int methods[GNAME_MAX];
+    int statmethods[GNAME_MAX];
+    int neighb_count;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    RASTER_MAP_TYPE map_type;
+    int i, j;
+    int row, col;
+    int cnt;
+    CELL *result;
+    double edge;
+    struct Cell_head ch, window;
+    double min, max;
+    int pos;
+
+    int *real_landscape;
+    DCELL *real_values;
+    DCELL *res_values;
+    int save_fragcount;
+    int *fragcounts;
+
+    int *resmap;
+
+    int method, method_count;
+    int m, sm;
+    int statmethod, statmethod_count;
+    char *actname;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output, *size, *nullval;
+	struct Option *keyval, *landcover, *sharpness;
+	struct Option *n, *method, *statmethod;
+	struct Option *randseed, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Neutral Landscape Generator - index statistics");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+    parm.input->key = "input1";
+    parm.input->required = NO;
+
+    parm.output = G_define_option();
+    parm.output->key = "output";
+    parm.output->type = TYPE_STRING;
+    parm.output->required = YES;
+    parm.output->gisprompt = "new_file,file,output";
+    parm.output->description =
+	_("Name for output ASCII-file (use out=- for stdout)");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = NO;
+    parm.keyval->description =
+	_("Value of a category from the input file to measure desired landcover");
+
+    parm.nullval = G_define_option();
+    parm.nullval->key = "nullval";
+    parm.nullval->type = TYPE_INTEGER;
+    parm.nullval->required = NO;
+    parm.nullval->multiple = YES;
+    parm.nullval->description =
+	_("Values marking areas from the input file, which are to be NULL in the resulting map");
+
+    parm.landcover = G_define_option();
+    parm.landcover->key = "landcover";
+    parm.landcover->type = TYPE_DOUBLE;
+    parm.landcover->required = NO;
+    parm.landcover->description = _("Landcover in percent");
+
+    parm.sharpness = G_define_option();
+    parm.sharpness->key = "sharpness";
+    parm.sharpness->type = TYPE_DOUBLE;
+    parm.sharpness->required = NO;
+    parm.sharpness->description =
+	_("Small values produce smooth structures, great values"
+	  " produce sharp, edgy structures - Range [0-1]");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->description = _("Number of maps to generate");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    actname = parm.method->options = G_malloc(1024);
+    for (n = 0; methodlist[n].name != NULL; n++) {
+	if (n)
+	    strcat(actname, ",");
+	else
+	    *actname = 0;
+	strcat(actname, methodlist[n].name);
+    }
+    parm.method->multiple = YES;
+    parm.method->description = _("Operation to perform on fragments");
+
+    parm.statmethod = G_define_option();
+    parm.statmethod->key = "statmethod";
+    parm.statmethod->type = TYPE_STRING;
+    parm.statmethod->required = YES;
+    actname = parm.statmethod->options = G_malloc(1024);
+    for (n = 0; statmethodlist[n].name != NULL; n++) {
+	if (n)
+	    strcat(actname, ",");
+	else
+	    *actname = 0;
+	strcat(actname, statmethodlist[n].name);
+    }
+    parm.statmethod->multiple = YES;
+    parm.statmethod->description =
+	_("Statistical method to perform on the values");
+
+    parm.randseed = G_define_option();
+    parm.randseed->key = "seed";
+    parm.randseed->type = TYPE_INTEGER;
+    parm.randseed->required = NO;
+    parm.randseed->description = _("Seed for random number generator");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    if (oldname && NULL == (oldmapset = G_find_cell2(oldname, "")))
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* if input specified get keyval */
+    if (oldname) {
+	if (parm.keyval->answer) {
+	    sscanf(parm.keyval->answer, "%d", &keyval);
+	}
+    }
+
+    map_type = CELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    size = 1;
+    power = 0;
+    while (size < sx - 1 || size < sy - 1) {
+	size <<= 1;
+	power++;
+    }
+    size++;
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get random seed and init random */
+    if (parm.randseed->answer) {
+	sscanf(parm.randseed->answer, "%d", &rand_seed);
+    }
+    else {
+	rand_seed = time(NULL);
+    }
+    srand(rand_seed);
+
+    /* get landcover from user input */
+    if (parm.landcover->answer) {
+	sscanf(parm.landcover->answer, "%lf", &landcover);
+	landcover /= 100;
+    }
+    else {
+	landcover = Randomf();
+    }
+
+    /* get sharpness */
+    if (parm.sharpness->answer) {
+	sscanf(parm.sharpness->answer, "%lf", &sharpness);
+    }
+    else {
+	sharpness = Randomf();
+    }
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get verbose */
+    verbose = !flag.quiet->answer;
+
+    /* scan all method answers */
+    for (method_count = 0; parm.method->answers[method_count] != NULL;
+	 method_count++) {
+	/* get actual method */
+	for (method = 0; (actname = methodlist[method].name); method++)
+	    if ((strcmp(actname, parm.method->answers[method_count]) == 0))
+		break;
+	if (!actname) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.method->key, parm.method->answers[method_count],
+		      parm.method->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+	methods[method_count] = method;
+    }
+
+    /* scan all statmethod answers */
+    for (statmethod_count = 0;
+	 parm.statmethod->answers[statmethod_count] != NULL;
+	 statmethod_count++) {
+	/* get the actual statmethod */
+	for (statmethod = 0; (actname = statmethodlist[statmethod].name);
+	     statmethod++)
+	    if ((strcmp(actname, parm.statmethod->answers[statmethod_count])
+		 == 0))
+		break;
+	if (!actname) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.statmethod->key, parm.statmethod->answer,
+		      parm.statmethod->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+	statmethods[statmethod_count] = statmethod;
+    }
+
+    /* allocate cell buffers */
+    buffer = (int *)G_malloc(sx * sy * sizeof(int));
+    bigbuf = (double *)G_malloc(size * size * sizeof(double));
+    resmap = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    /* res_values = (method1(statmethod1(1..n))(statmethod2(1..n))) */
+    res_values =
+	(DCELL *) G_malloc(method_count * statmethod_count * n *
+			   sizeof(DCELL));
+    real_values =
+	(DCELL *) G_malloc(method_count * statmethod_count * sizeof(DCELL));
+    fragcounts = (int *)G_malloc(n * sizeof(int));
+
+    /* init fragments structure */
+    fragments[0] = cells;
+
+
+    /* init buffers */
+    memset(bigbuf, 0, size * size * sizeof(double));
+    memset(buffer, 0, sx * sy * sizeof(int));
+
+    /* load values from input file */
+    if (oldname) {
+	DCELL *res;
+
+	real_landscape = (int *)G_malloc(sx * sy * sizeof(int));
+	memset(real_landscape, 0, sx * sy * sizeof(int));
+
+	pixel_count = 0;
+
+	/* open cell files */
+	in_fd = G_open_cell_old(oldname, oldmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+	/* init buffer with values from input and get landcover */
+	for (row = 0; row < sy; row++) {
+	    G_get_c_raster_row(in_fd, result, row);
+	    for (col = 0; col < sx; col++) {
+		if (parm.nullval->answers) {
+		    for (i = 0; parm.nullval->answers[i] != NULL; i++) {
+			sscanf(parm.nullval->answers[i], "%d", &nullval);
+			if (result[col] == nullval)
+			    buffer[row * sx + col] = 1;
+		    }
+		}
+
+		/* count pixels for landcover */
+		if (result[col] == keyval) {
+		    pixel_count++;
+		    real_landscape[row * sx + col] = 1;
+		}
+	    }
+	}
+
+	/* test output */
+	/*              G_message("real landscape");
+	   for(row = 0; row < sy; row++) {
+	   for(col = 0; col < sx; col++) {
+	   fprintf(stderr, "%d", real_landscape[row * sx + col]);
+	   }
+	   fprintf(stderr, "\n");
+	   } */
+
+	/* calculate landcover */
+	if (parm.keyval->answer)
+	    landcover = (double)pixel_count / ((double)sx * (double)sy);
+
+	/* resample to bigbuf */
+	for (col = 0; col < size; col++) {
+	    for (row = 0; row < size; row++) {
+		bigbuf[row * size + col] =
+		    UpSample(buffer, col, row, sx, sy, size);
+	    }
+	}
+
+	/* apply methods to real landscape */
+
+	writeFragments(real_landscape, sy, sx, neighb_count);
+
+	/* allocate memory for result */
+	res = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	/* calculate requested values */
+	for (m = 0; m < method_count; m++) {
+	    f_func calculate;
+
+	    method = methods[m];
+	    calculate = methodlist[method].method;
+
+	    calculate(res, fragments, fragcount);
+
+	    for (sm = 0; sm < statmethod_count; sm++) {
+		f_statmethod calcstat;
+		DCELL val;
+
+		statmethod = statmethods[sm];
+		calcstat = statmethodlist[statmethod].method;
+
+		val = calcstat(res, fragcount);
+
+		real_values[m * statmethod_count + sm] = val;
+	    }
+	}
+
+	/* save fragment count */
+	save_fragcount = fragcount;
+
+	G_free(res);
+	G_free(real_landscape);
+    }				/* if(oldname) */
+
+    /* generate n fractal maps */
+    for (i = 0; i < n; i++) {
+	DCELL *res;
+
+	G_percent(i, n, 1);
+
+	create_map(resmap);
+
+	writeFragments(resmap, sy, sx, neighb_count);
+
+	/* save fragcount */
+	fragcounts[i] = fragcount;
+
+	/* allocate memory */
+	res = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	/* calculate requested values */
+	for (m = 0; m < method_count; m++) {
+	    int cnt;
+
+	    f_func calculate;
+
+	    method = methods[m];
+	    calculate = methodlist[method].method;
+
+	    calculate(res, fragments, fragcount);
+
+	    for (sm = 0; sm < statmethod_count; sm++) {
+		f_statmethod calcstat;
+		DCELL val;
+
+		statmethod = statmethods[sm];
+		calcstat = statmethodlist[statmethod].method;
+
+		val = calcstat(res, fragcount);
+
+		res_values[m * statmethod_count * n + sm * n + i] = val;
+	    }
+	}
+
+	G_free(res);
+    }
+    G_percent(1, 1, 1);
+
+    /* open ASCII-file or use stdout */
+    if (parm.output->answer && strcmp(parm.output->answer, "-") != 0) {
+	char rlname[GNAME_MAX];
+
+	if (!(out_fp = fopen(parm.output->answer, "w"))) {
+	    G_fatal_error(_("Error creating file <%s>"),
+			  parm.output->answer);
+	}
+
+	if (oldname) {
+	    strcpy(rlname, parm.output->answer);
+	    strcat(rlname, "_RL");
+	    if (!(out_rl = fopen(rlname, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"),
+			      parm.output->answer);
+	    }
+	}
+    }
+    else {
+	out_fp = stdout;
+	out_rl = stdout;
+    }
+
+    /* write method names */
+    for (m = 0; m < method_count; m++) {
+	method = methods[m];
+	for (sm = 0; sm < statmethod_count; sm++) {
+	    statmethod = statmethods[sm];
+	    fprintf(out_fp, "NLM_%s.%s ", methodlist[method].name,
+		    statmethodlist[statmethod].name);
+	}
+    }
+    fprintf(out_fp, "Number ");
+    /* write method names for real landscape */
+    if (oldname) {
+	for (m = 0; m < method_count; m++) {
+	    method = methods[m];
+	    for (sm = 0; sm < statmethod_count; sm++) {
+		statmethod = statmethods[sm];
+		fprintf(out_rl, "RL_%s.%s ", methodlist[method].name,
+			statmethodlist[statmethod].name);
+	    }
+	}
+	fprintf(out_rl, "RL_Number");
+    }
+
+    fprintf(out_fp, "\n");
+    if (oldname && out_fp != out_rl) {
+	fprintf(out_rl, "\n");
+    }
+
+    /* print first data line */
+    for (j = 0, pos = 0; j < method_count * statmethod_count; j++, pos += n) {
+	fprintf(out_fp, "%f ", res_values[pos]);
+    }
+    if (method_count > 0) {
+	fprintf(out_fp, "%d ", fragcounts[0]);
+    }
+    if (oldname) {
+	for (j = 0; j < method_count * statmethod_count; j++) {
+	    fprintf(out_rl, "%f ", real_values[j]);
+	}
+	fprintf(out_rl, "%d", save_fragcount);
+    }
+    fprintf(out_fp, "\n");
+
+    for (i = 1; i < n; i++) {
+	/* print data line */
+	for (j = 0, pos = i; j < method_count * statmethod_count;
+	     j++, pos += n) {
+	    fprintf(out_fp, "%f ", res_values[pos]);
+	}
+	fprintf(out_fp, "%d\n", fragcounts[i]);
+    }
+
+    /* close files */
+    fclose(out_fp);
+    if (oldname) {
+	fclose(out_rl);
+    }
+
+    /* free buffers */
+    G_free(buffer);
+    G_free(bigbuf);
+    G_free(resmap);
+    G_free(result);
+    G_free(fragments);
+    G_free(res_values);
+    G_free(real_values);
+    G_free(fragcounts);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,253 @@
+#include "local_proto.h"
+
+int f_area(DCELL * vals, Coords ** frags, int count)
+{
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	vals[i] = (DCELL) (frags[i + 1] - frags[i]);
+    }
+
+    return 0;
+}
+
+int f_perim(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	int border = 0;
+
+	/* for all cells in a patch */
+	for (p = frags[i]; p < frags[i + 1]; p++) {
+	    border += 4 - p->neighbors;
+	}
+	vals[i] = (DCELL) border;
+    }
+
+    return 0;
+}
+
+int f_shapeindex(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	int border = 0;
+	int area = (DCELL) (frags[i + 1] - frags[i]);
+
+	/* for all cells in a patch */
+	for (p = frags[i]; p < frags[i + 1]; p++) {
+	    border += 4 - p->neighbors;
+	}
+	vals[i] = (DCELL) border / (4 * sqrt((DCELL) area));
+    }
+
+    return 0;
+}
+
+int f_borderindex(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	int border = 0;
+	int maxx, maxy, minx, miny;
+	int l = 0;
+	int w = 0;
+
+	maxx = minx = frags[i]->x;
+	maxy = miny = frags[i]->y;
+	/* for all cells in a patch */
+	for (p = frags[i]; p < frags[i + 1]; p++) {
+	    border += 4 - p->neighbors;
+	    maxx = p->x > maxx ? p->x : maxx;
+	    minx = p->x < minx ? p->x : minx;
+	    maxy = p->y > maxy ? p->y : maxy;
+	    miny = p->y < miny ? p->y : miny;
+	}
+	l = maxx - minx + 1;
+	w = maxy - miny + 1;
+	vals[i] = (DCELL) border / (2 * ((DCELL) l + (DCELL) w));
+    }
+
+    return 0;
+}
+
+int f_compactness(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	int area = 0;
+	int maxx, maxy, minx, miny;
+	int l = 0;
+	int w = 0;
+
+	maxx = minx = frags[i]->x;
+	maxy = miny = frags[i]->y;
+	/* for all cells in a patch */
+	for (p = frags[i]; p < frags[i + 1]; p++) {
+	    area++;
+	    maxx = p->x > maxx ? p->x : maxx;
+	    minx = p->x < minx ? p->x : minx;
+	    maxy = p->y > maxy ? p->y : maxy;
+	    miny = p->y < miny ? p->y : miny;
+	}
+	l = maxx - minx + 1;
+	w = maxy - miny + 1;
+	vals[i] = (DCELL) l *(DCELL) w / (DCELL) area;
+    }
+
+    return 0;
+}
+
+int f_asymmetry(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	/* compute variance for x,y and xy in the patch */
+	/* formula: a(x) = sum(x_i), b(x) = sum(x_i²), var(x) = (b(x) - a(x)² / n) / n */
+	/* covar(x*y) = (a(x * y) - a(x) * a(y) / n) /n */
+	int ax, ay, axy;
+	int bx, by;
+	DCELL vx, vy, vxy, vsum, invn;
+	int n = 0;
+
+	ax = ay = axy = 0;
+	bx = by = 0;
+	/* for all cells in a patch */
+	//              fprintf(stderr, "\npatch %d: ", i);
+	for (p = frags[i]; p < frags[i + 1]; p++, n++) {
+	    int x = p->x;
+	    int y = p->y;
+	    int xy = p->x * p->y;
+
+	    ax += x;
+	    ay += y;
+	    axy += xy;
+	    bx += x * x;
+	    by += y * y;
+	    //                      fprintf(stderr, "x_%d = %d, y_%d = %d; ", n, x, n, y);
+	}
+	invn = 1.0 / (DCELL) n;
+	vx = ((DCELL) bx - (DCELL) ax * (DCELL) ax * invn) * invn;
+	vy = ((DCELL) by - (DCELL) ay * (DCELL) ay * invn) * invn;
+	vxy = ((DCELL) axy - (DCELL) ax * (DCELL) ay * invn) * invn;
+	//              fprintf(stderr, " axy = %d, ax = %d, ay = %d, n = %d", axy, ax, ay, n);
+	vsum = vx + vy;
+	vals[i] = 2 * sqrt(0.25 * vsum * vsum + vxy * vxy - vx * vy) / vsum;
+    }
+}
+
+int f_area_perim_ratio(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	int border = 0;
+	int area = (DCELL) (frags[i + 1] - frags[i]);
+
+	/* for all cells in a patch */
+	for (p = frags[i]; p < frags[i + 1]; p++) {
+	    border += 4 - p->neighbors;
+	}
+	vals[i] = (DCELL) area / (DCELL) border;
+    }
+
+    return 0;
+}
+
+int f_frac_dim(DCELL * vals, Coords ** frags, int count)
+{
+    Coords *p;
+    int i;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	int border = 0;
+	int area = (DCELL) (frags[i + 1] - frags[i]);
+
+	/* for all cells in a patch */
+	for (p = frags[i]; p < frags[i + 1]; p++) {
+	    border += 4 - p->neighbors;
+	}
+	vals[i] = 2 * log(0.25 * (DCELL) border) / log((DCELL) area);
+    }
+
+    return 0;
+}
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+int f_nearest_dist(DCELL * vals, Coords ** frags, int count)
+{
+    int i, j;
+
+    /* for all patches */
+    for (i = 0; i < count; i++) {
+	DCELL min = 1000000.0;
+
+	for (j = 0; j < count; j++) {
+	    if (i != j) {
+		DCELL d = min_dist(frags, i, j);
+
+		if (d < min) {
+		    min = d;
+		}
+	    }
+	}
+	vals[i] = min;
+    }
+
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.nlm.stats/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.nlm.stats/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.nlm.stats/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,177 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+void quicksort(DCELL * vals, int begin, int end)
+{
+    int i, j;
+    DCELL pivot, tmp;
+
+    if (end <= begin)
+	return;
+
+    i = begin;
+    j = end - 1;
+    pivot = vals[end];
+
+    while (i <= j) {
+	while (i <= j && vals[i] < pivot)
+	    i++;
+	while (i <= j && vals[j] >= pivot)
+	    j--;
+
+	if (i < j) {
+	    tmp = vals[i];
+	    vals[i] = vals[j];
+	    vals[j] = tmp;
+	    i++;
+	    j--;
+	}
+    }
+
+    tmp = vals[i];
+    vals[i] = vals[end];
+    vals[end] = tmp;
+    i++;
+
+    quicksort(vals, begin, j);
+    quicksort(vals, i, end);
+}
+
+DCELL mode(DCELL * vals, int count)
+{
+    DCELL actval, maxval;
+    int actcnt, maxcnt;
+    int actpos;
+    int i;
+
+    if (count <= 0)
+	return 0;
+
+    quicksort(vals, 0, count - 1);
+
+    fprintf(stderr, "vals = (%0.2f", vals[0]);
+    for (i = 1; i < count; i++)
+	fprintf(stderr, ",%0.2f", vals[i]);
+    fprintf(stderr, ")\n\n");
+
+    maxval = 0;
+    maxcnt = 0;
+    actpos = 0;
+    while (actpos < count) {
+	actcnt = 0;
+	actval = vals[actpos];
+	while (actpos < count && actval == vals[actpos]) {
+	    actcnt++;
+	    actpos++;
+	}
+	if (actcnt > maxcnt) {
+	    maxcnt = actcnt;
+	    maxval = actval;
+	}
+    }
+
+    return maxval;
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL minval = vals[0];
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 1; i < count; i++)
+	if (vals[i] < minval)
+	    minval = vals[i];
+
+    return minval;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL maxval = vals[0];
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 1; i < count; i++)
+	if (vals[i] > maxval)
+	    maxval = vals[i];
+
+    return maxval;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.nlm.stats/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.odc
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.odc/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/compensation.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/compensation.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/compensation.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,50 @@
+#include "local_proto.h"
+
+DCELL none(DCELL value, int frag)
+{
+    return value;
+}
+
+DCELL odd_area(DCELL value, int frag)
+{
+    DCELL area = fragments[frag + 1] - fragments[frag];
+
+    return value / area;
+}
+
+DCELL area_odd(DCELL value, int frag)
+{
+    DCELL area = fragments[frag + 1] - fragments[frag];
+
+    return area / value;
+}
+
+DCELL odd_perim(DCELL value, int frag)
+{
+    DCELL perim = 0;
+    Coords *fragment;
+
+    for (fragment = fragments[frag]; fragment < fragments[frag + 1];
+	 fragment++) {
+	if (fragment->neighbors < 4) {
+	    perim++;
+	}
+    }
+
+    return value / perim;
+}
+
+DCELL perim_odd(DCELL value, int frag)
+{
+    DCELL perim = 0;
+    Coords *fragment;
+
+    for (fragment = fragments[frag]; fragment < fragments[frag + 1];
+	 fragment++) {
+	if (fragment->neighbors < 4) {
+	    perim++;
+	}
+    }
+
+    return perim / value;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.odc/compensation.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,95 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.pi.odc</em> is part of the patch based fragmentation analysis
+package r.pi.* (Patch Index). It computes omnidirectional connectivity
+analysis between patches.
+
+<h2>NOTES</h2>
+
+Several output raster are generated with the defined <em>output</em> file name and a suffix of the information provided. All files named *.FP.* are providing information concerning the focus patch. All files named *.TP.* are providing informaton about the target patches.<br>
+
+TODO: ???<p>
+
+The user must specify the names of the raster map layers to
+be used for <em>input</em> and <em>output</em>, the <em>keyval</em> the
+<em>ratio</em> (area/odd or odd/area) and <em>stats</em> used (i.e., average).
+<p>
+Within <em>r.pi.odc</em> the following setting have to be set:
+
+<h3>keyval setting:</h3>
+
+The <em>keyval</em> operator determines which category value is taken for the Patch Index analysis.
+
+<h3>Ratio setting:</h3>
+
+The <em>ratio</em> operators determine what measure is applied.
+
+<h3>Neighbourhood level:</h3>
+
+The <em>neighbor_level</em> operator determines which neighbourhood level is used. <em>0</em> produces output for the focus patch itself, <em>1</em> assigns the connectivity information of the first omnidirectional neighbours to the focus patch, hence the connectivity of the surrouding fragments. This value can be increased for analysing the more distant neighbours.
+
+<h3>Output:</h3>
+
+Various output files are autmatically created with the pattern $output.*
+
+The<br>
+
+<em>FP</em> describes attributes of the fokus patch (area and area of the odd)
+
+<em>TP</em> describes attributes of the target patch (all neighbouring patches around the FP) - separated by the statsmethod (average, median, variance, stddev)
+
+<em>ratio</em> describes which ratio is taken for all TPs.
+
+The output raster files are named accordingly:<br>
+
+*.FP.area: size of the patch<br>
+*.FP.odd: size of the isolation area<br>
+*.FP.odd_area: ratio of size of patch and size of isolaton area<br>
+
+*.TP.no: amount of neighbouring patches<br>
+*.TP.area.avg: average size of all neighbouring patches<br>
+*.TP.odd.avg: average size of all isolation areas of neighbouring patches<br>
+*.TP.odd_area.avg: average ratio of isolation area to patch size<br>
+
+*.diagram: (if flag -d active) isolation areas and border are depicted
+
+
+</dl>
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+r.pi.odc input=landclass96 output=odc keyval=5 ratio=odd_area stats=average neighbor_level=0 -d
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.odc/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.odc/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,96 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case NOTHING:
+		fprintf(stderr, ".");
+		break;
+	    case NOGO:
+		fprintf(stderr, "X");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.odc/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,90 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define NOGO -2
+#define NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+} Point;
+
+typedef struct
+{
+    int x, y;
+    int patch;
+} PatchPoint;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+typedef DCELL(*f_compensate) (DCELL, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* voronoi.c */
+void voronoi(DCELL * values, int *map, int sx, int sy, int diag_move);
+void calc_neighbors(DCELL * res, DCELL * focals, f_statmethod * methods,
+		    int stat_count, f_compensate compensate,
+		    int neighbor_level);
+void getNeighborCount(DCELL * res);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+
+/* compensation.c */
+DCELL none(DCELL value, int frag);
+DCELL odd_area(DCELL value, int frag);
+DCELL area_odd(DCELL value, int frag);
+DCELL odd_perim(DCELL value, int frag);
+DCELL perim_odd(DCELL value, int frag);
+
+/* global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+GLOBAL int sx, sy;
+
+GLOBAL int *adj_matrix;
+
+GLOBAL int empty_count;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.odc/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,691 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.odc
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      omnidirectional connectivity analysis based on polygons
+ *                               (related to voronoi for points)
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {0, 0, 0, 0}
+};
+
+struct compensation
+{
+    f_compensate *method;	/* routine to compute compensated value */
+    char *name;			/* method name */
+    char *suffix;		/* output suffix */
+};
+
+static struct compensation compmethods[] = {
+    {none, "none", "none"},
+    {odd_area, "odd_area", "odd_area"},
+    {area_odd, "area_odd", "area_odd"},
+    {odd_perim, "odd_perim", "odd_perim"},
+    {perim_odd, "perim_odd", "perim_odd"},
+    {0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* output */
+    char *newname, *newmapset;
+
+    /* mask */
+    char *maskname, *maskmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+    FILE *out_fp;		/* ASCII - output */
+
+    /* parameters */
+    int keyval;
+    int stats[GNAME_MAX];
+    int stat_count;
+    int ratio;
+    int diag_grow;
+    int compmethod;
+    int neighbor_level;
+
+    /* maps */
+    int *map;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    DCELL *values;
+    DCELL *neighb_values;
+    int neighb_count;
+    int i, n;
+    int x, y;
+    Coords *p;
+    char output_name[GNAME_MAX];
+    char *str;
+    int method;
+    f_statmethod *method_array;
+    DCELL area;
+    f_compensate compensate;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output, *mask;
+	struct Option *keyval, *ratio, *stats;
+	struct Option *neighbor_level, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *diag_grow, *diagram, *matrix;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Omnidirectional connectivity analysis");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.mask = G_define_option();
+    parm.mask->key = "mask";
+    parm.mask->type = TYPE_STRING;
+    parm.mask->required = NO;
+    parm.mask->gisprompt = "old,cell,raster";
+    parm.mask->description =
+	_("Name of a raster file with a mask (0,1 values)");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Category value of the patches");
+
+    parm.ratio = G_define_option();
+    parm.ratio->key = "ratio";
+    parm.ratio->type = TYPE_STRING;
+    parm.ratio->required = YES;
+    str = parm.ratio->options = G_malloc(1024);
+    for (n = 0; compmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, compmethods[n].name);
+    }
+    parm.ratio->description =
+	_("Compensation method to perform on the values");
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    parm.stats->multiple = YES;
+    str = parm.stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[n].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the values");
+
+    parm.neighbor_level = G_define_option();
+    parm.neighbor_level->key = "neighbor_level";
+    parm.neighbor_level->type = TYPE_INTEGER;
+    parm.neighbor_level->required = NO;
+    parm.neighbor_level->description = _("Level of neighbors to analyse");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.diag_grow = G_define_flag();
+    flag.diag_grow->key = 'b';
+    flag.diag_grow->description = _("Allow moving on diagonals");
+
+    flag.diagram = G_define_flag();
+    flag.diagram->key = 'd';
+    flag.diagram->description = _("Graphical output");
+
+    flag.matrix = G_define_flag();
+    flag.matrix->key = 'm';
+    flag.matrix->description = _("Adjacency matrix output");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of mask file */
+    maskname = parm.mask->answer;
+
+    /* test input files existance */
+    if (maskname && (maskmapset = G_find_cell2(maskname, "")) == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), maskname);
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get neighbor level */
+    if (parm.neighbor_level->answer) {
+	sscanf(parm.neighbor_level->answer, "%d", &neighbor_level);
+    }
+    else {
+	neighbor_level = 1;
+    }
+
+    /* get diagonal move flag */
+    diag_grow = flag.diag_grow->answer ? 1 : 0;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    map_type = DCELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    G_message("sx = %d, sy = %d", sx, sy);
+
+    /* scan all statmethod answers */
+    stat_count = 0;
+    while (parm.stats->answers[stat_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (str = statmethods[method].name); method++)
+	    if (strcmp(str, parm.stats->answers[stat_count]) == 0)
+		break;
+	if (!str) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.stats->key, parm.stats->answers[stat_count],
+		      parm.stats->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	stats[stat_count] = method;
+
+	stat_count++;
+    }
+
+    /* scan all statmethod answers */
+    for (compmethod = 0; (str = compmethods[compmethod].name); compmethod++)
+	if (strcmp(str, parm.ratio->answer) == 0)
+	    break;
+    if (!str) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.ratio->key, parm.ratio->answer, parm.ratio->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+    compensate = compmethods[compmethod].method;
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    d_res = G_allocate_d_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row, sy, 1);
+    }
+    G_percent(1, 1, 1);
+
+    /*G_message("Map:");
+       for (row = 0; row < sy; row++) {
+       for (col = 0; col < sx; col++) {
+       fprintf(stderr, "%d", map[row * sx + col]);
+       }    
+       fprintf(stderr, "\n");
+       } */
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* find fragments */
+    writeFragments(map, sy, sx, neighb_count);
+
+    G_message("Found %d patches", fragcount);
+
+    /* apply mask */
+    if (maskname) {
+	/* open mask */
+	in_fd = G_open_cell_old(maskname, maskmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), maskname);
+
+	/* read mask */
+	for (row = 0; row < sy; row++) {
+	    G_get_c_raster_row(in_fd, result, row);
+	    for (col = 0; col < sx; col++) {
+		if (result[col] == 1) {
+		    map[row * sx + col] = NOTHING;
+		}
+		else {
+		    map[row * sx + col] = NOGO;
+		}
+	    }
+
+	}
+
+	/* close mask */
+	G_close_cell(in_fd);
+    }
+    else {
+	for (i = 0; i < sx * sy; i++) {
+	    map[i] = NOTHING;
+	}
+    }
+
+    /* mark patches */
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    x = p->x;
+	    y = p->y;
+	    map[x + y * sx] = i;
+	}
+    }
+
+    /* create voronoi diagram */
+    G_message("Performing calculations:");
+
+    adj_matrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+    values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+    memset(adj_matrix, 0, fragcount * fragcount * sizeof(int));
+
+    voronoi(values, map, sx, sy, diag_grow);
+
+    /* output skipped positions */
+    G_message("Positions skipped: %d", empty_count);
+
+    G_message("Writing output...");
+
+    /*
+       =============================== FOCAL PATCH =========================================
+     */
+    /* open the new cell file  */
+    strcpy(output_name, newname);
+    strcat(output_name, ".FP.area");
+
+    out_fd = G_open_raster_new(output_name, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+    /* write area of focal patch */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    area = fragments[i + 1] - fragments[i];
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] = area;
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* open the new cell file  */
+    strcpy(output_name, newname);
+    strcat(output_name, ".FP.odd");
+
+    out_fd = G_open_raster_new(output_name, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+    /* write ratio of focal patch */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] = values[i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /* open the new cell file  */
+    strcpy(output_name, newname);
+    strcat(output_name, ".ratioFP.");
+    strcat(output_name, compmethods[compmethod].suffix);
+
+    out_fd = G_open_raster_new(output_name, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+    /* write odd of focal patch */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    area = fragments[i + 1] - fragments[i];
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] = compensate(values[i], i);	/* ratio_flag ? values[i] / area : area / values[i]; */
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /*
+       =============================== TARGET PATCHES =========================================
+     */
+    neighb_values =
+	(DCELL *) G_malloc(3 * fragcount * stat_count * sizeof(DCELL));
+    method_array =
+	(f_statmethod *) G_malloc(stat_count * sizeof(f_statmethod));
+    for (i = 0; i < stat_count; i++) {
+	method_array[i] = statmethods[stats[i]].method;
+    }
+
+    calc_neighbors(neighb_values, values, method_array, stat_count,
+		   compensate, neighbor_level);
+
+    /* write areas */
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cell file  */
+	strcpy(output_name, newname);
+	strcat(output_name, ".TP.area.");
+	strcat(output_name, statmethods[stats[method]].suffix);
+
+	out_fd = G_open_raster_new(output_name, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+	/* write areas of target patches with current suffix for statmethod */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = neighb_values[method * fragcount + i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write odds */
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cell file  */
+	strcpy(output_name, newname);
+	strcat(output_name, ".TP.odd.");
+	strcat(output_name, statmethods[stats[method]].suffix);
+
+	out_fd = G_open_raster_new(output_name, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+	/* write odd of target patches with current suffix for statmethod */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    neighb_values[stat_count * fragcount +
+					  method * fragcount + i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write ratios */
+    for (method = 0; method < stat_count; method++) {
+	/* open the new cell file  */
+	strcpy(output_name, newname);
+	strcat(output_name, ".ratioTP.");
+	strcat(output_name, compmethods[compmethod].suffix);
+	strcat(output_name, ".");
+	strcat(output_name, statmethods[stats[method]].suffix);
+
+	out_fd = G_open_raster_new(output_name, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+	/* write ratio of target patches with current suffix for statmethod */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    neighb_values[2 * stat_count * fragcount +
+					  method * fragcount + i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+    /*
+       =============================== DIAGRAM =========================================
+     */
+    if (flag.diagram->answer) {
+	/* open new cell file */
+	strcpy(output_name, newname);
+	strcat(output_name, ".diagram");
+
+	out_fd = G_open_raster_new(output_name, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+	/* write diagram */
+	for (row = 0; row < sy; row++) {
+	    for (col = 0; col < sx; col++) {
+		d_res[col] = map[row * sx + col];
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /*
+       =============================== NUMBER OF NEIGHBORS =========================================
+     */
+    /* open new cell file */
+    strcpy(output_name, newname);
+    strcat(output_name, ".TP.no");
+
+    out_fd = G_open_raster_new(output_name, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+    /* get neighbor count */
+    getNeighborCount(values);
+
+    /* write number of neighbors */
+    for (row = 0; row < sy; row++) {
+	G_set_d_null_value(d_res, sx);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		if (p->y == row) {
+		    d_res[p->x] = values[i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, d_res);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+
+    /*
+       =============================== DIAGRAM =========================================
+     */
+    if (flag.matrix->answer) {
+	/* open new cell file */
+	strcpy(output_name, newname);
+	strcat(output_name, ".id");
+
+	out_fd = G_open_raster_new(output_name, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), output_name);
+
+	/* write ids of patches */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = i;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* output matrix */
+	strcpy(output_name, newname);
+	strcat(output_name, ".matrix");
+
+	/* open ASCII-file */
+	if (!(out_fp = fopen(output_name, "w"))) {
+	    G_fatal_error(_("Error creating file <%s>"), output_name);
+	}
+
+	for (row = 0; row < fragcount; row++) {
+	    for (col = 0; col < fragcount; col++) {
+		fprintf(out_fp, "%d ", adj_matrix[row * fragcount + col]);
+	    }
+
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close ASCII-file */
+	fclose(out_fp);
+    }
+
+    /*
+       =============================== END OUTPUT =========================================
+     */
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(cells);
+    G_free(fragments);
+    G_free(values);
+    G_free(adj_matrix);
+    G_free(neighb_values);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.odc/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,83 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}


Property changes on: grass-addons/raster/r.pi/r.pi.odc/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.odc/voronoi.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.odc/voronoi.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.odc/voronoi.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,414 @@
+#include "local_proto.h"
+
+/*
+   globals
+ */
+DCELL *areas;
+Point *empty_space;
+PatchPoint *new_edge;
+int new_count;
+
+/*
+   allocates memory, initializes the buffers
+ */
+void init_voronoi(int *map, int sx, int sy)
+{
+    int x, y;
+
+    areas = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+    empty_space = (Point *) G_malloc(sx * sy * sizeof(Point));
+    new_edge = (PatchPoint *) G_malloc(sx * sy * sizeof(Point));
+
+    memset(areas, 0, fragcount * sizeof(DCELL));
+    memset(adj_matrix, 0, fragcount * fragcount * sizeof(int));
+
+    /* gather list of empty space */
+    empty_count = 0;
+    for (x = 0; x < sx; x++) {
+	for (y = 0; y < sy; y++) {
+	    if (map[x + y * sx] == NOTHING) {
+		empty_space[empty_count].x = x;
+		empty_space[empty_count].y = y;
+		empty_count++;
+	    }
+	}
+    }
+
+    new_count = 0;
+}
+
+/*
+   deletes point stride from list
+ */
+int delete_stride(int index, int count, Point * list, int size)
+{
+    if (index < 0 || index + count > size)
+	return size;
+
+    memcpy(list + index, list + index + count,
+	   (size - index - count) * sizeof(Point));
+    return size - count;
+}
+
+/*
+   deletes point from list
+ */
+int delete_point(int index, Point * list, int size)
+{
+    if (index < 0 || index > size - 1)
+	return size;
+
+    memcpy(list + index, list + index + 1,
+	   (size - index - 1) * sizeof(Point));
+    return size - 1;
+}
+
+/*
+   adds point to list
+ */
+int add_point(int x, int y, Point * list, int size)
+{
+    list[size].x = x;
+    list[size].y = y;
+
+    return size + 1;
+}
+
+/*
+   gathers neighbors of a pixel
+ */
+int gather_neighbors(int *res, int *map, int x, int y, int sx, int sy,
+		     int diag_grow)
+{
+    int r, l, t, b;
+    int nx, ny;
+    int count;
+    int val;
+
+    /* checklist marks patch neighbors with 1 and not neighbors with 0 */
+    int *checklist = (int *)G_malloc(fragcount * sizeof(int));
+
+    memset(checklist, 0, fragcount * sizeof(int));
+
+    /* iterate through neighbors and gather the not empty ones */
+
+    count = 0;
+    if (diag_grow) {
+	l = x > 0 ? x - 1 : 0;
+	t = y > 0 ? y - 1 : 0;
+	r = x < sx - 1 ? x + 1 : sx - 1;
+	b = y < sy - 1 ? y + 1 : sy - 1;
+
+	for (nx = l; nx <= r; nx++) {
+	    for (ny = t; ny <= b; ny++) {
+		val = map[nx + ny * sx];
+		if (val > NOTHING && checklist[val] == 0) {
+		    checklist[val] = 1;
+		    res[count] = val;
+		    count++;
+		}
+	    }
+	}
+    }
+    else {
+	if (x > 0) {		// left
+	    val = map[x - 1 + y * sx];
+	    if (val > NOTHING && checklist[val] == 0) {
+		checklist[val] = 1;
+		res[count] = val;
+		count++;
+	    }
+	}
+	if (x < sx - 1) {	// right
+	    val = map[x + 1 + y * sx];
+	    if (val > NOTHING && checklist[val] == 0) {
+		checklist[val] = 1;
+		res[count] = val;
+		count++;
+	    }
+	}
+	if (y > 0) {		// up
+	    val = map[x + (y - 1) * sx];
+	    if (val > NOTHING && checklist[val] == 0) {
+		checklist[val] = 1;
+		res[count] = val;
+		count++;
+	    }
+	}
+	if (y < sy - 1) {	// left
+	    val = map[x + (y + 1) * sx];
+	    if (val > NOTHING && checklist[val] == 0) {
+		checklist[val] = 1;
+		res[count] = val;
+		count++;
+	    }
+	}
+    }
+
+    G_free(checklist);
+    return count;
+}
+
+/*
+   grows patches by 1 pixel
+ */
+void grow_step(int *map, int sx, int sy, int diag_grow)
+{
+    int i, j;
+    int *neighbors;
+    int x, y;
+    int patch;
+    int neighb_cnt;
+    DCELL area;
+
+    /* alocate memory */
+    neighbors = (int *)G_malloc(fragcount * sizeof(int));
+
+    /* iterate through empty space */
+    new_count = 0;
+
+    for (i = empty_count - 1; i >= 0; i--) {
+	x = empty_space[i].x;
+	y = empty_space[i].y;
+
+	/* if at least one patch edge adjacent */
+	neighb_cnt =
+	    gather_neighbors(neighbors, map, x, y, sx, sy, diag_grow);
+
+	if (neighb_cnt > 0) {
+	    empty_count = delete_point(i, empty_space, empty_count);
+
+	    /* add new edge point */
+	    new_edge[new_count].x = x;
+	    new_edge[new_count].y = y;
+	    new_edge[new_count].patch = neighb_cnt == 1 ? neighbors[0] : NOGO;
+	    new_count++;
+
+	    /* add voronoi area to patches respectively */
+	    area = 1 / (double)neighb_cnt;
+	    for (j = 0; j < neighb_cnt; j++) {
+		areas[neighbors[j]] += area;
+	    }
+	}
+    }
+
+    /* mark edge points on the map */
+    for (i = 0; i < new_count; i++) {
+	x = new_edge[i].x;
+	y = new_edge[i].y;
+	patch = new_edge[i].patch;
+	map[x + y * sx] = patch;
+
+	if (patch > NOTHING) {
+	    /* test adjacency and mark adjacent patches in the matrix */
+	    neighb_cnt =
+		gather_neighbors(neighbors, map, x, y, sx, sy, diag_grow);
+	    for (j = 0; j < neighb_cnt; j++) {
+		int index1 = patch;
+		int index2 = neighbors[j];
+
+		//                              G_message(_("patches %d and %d are adjacent"), index1, index2);
+
+		if (index1 != index2) {
+		    adj_matrix[index1 + index2 * fragcount] = 1;
+		    adj_matrix[index2 + index1 * fragcount] = 1;
+		}
+	    }
+	}
+    }
+}
+
+/*
+   Expands one patch
+ */
+void expand_patch(int patch)
+{
+    int i, j;
+    int *list = (int *)G_malloc(fragcount * sizeof(int));
+    int *begin = list;
+    int *end = list;
+    int *p;
+    int level = 2;
+    int new_count;
+    int unleveled = fragcount - 1;
+
+    /* initialize list with direct neighbors of the patch */
+    for (i = 0; i < fragcount; i++) {
+	if (adj_matrix[patch * fragcount + i] == 1) {
+	    *end = i;
+	    end++;
+	    unleveled--;
+	}
+    }
+
+    //      while(unleveled > 0) {
+    while (begin < end) {
+	new_count = 0;
+	/* for each patch on the list */
+	for (p = begin; p < end; p++) {
+	    /* push all direct neighbors of higher level on the list */
+	    for (i = 0; i < fragcount; i++) {
+		/* if i-th patch is an unleveled neighbor */
+		if (i != patch && adj_matrix[(*p) * fragcount + i] == 1 &&
+		    adj_matrix[patch * fragcount + i] == 0) {
+		    *(end + new_count) = i;
+		    new_count++;
+		    unleveled--;
+
+		    /* save neighbor in adjacency matrix */
+		    adj_matrix[patch * fragcount + i] = level;
+		}
+	    }
+	}
+
+	begin = end;
+	end += new_count;
+	level++;
+
+	/* test output */
+	/*              for(p = begin; p < end; p++) {
+	   fprintf(stderr, "%d ", *p);
+	   }
+	   fprintf(stderr, "\n\n");
+	   for(i = 0; i < fragcount; i++) {
+	   for(j = 0; j < fragcount; j++) {
+	   fprintf(stderr, "%d", adj_matrix[i * fragcount + j]);
+	   }
+	   fprintf(stderr, "\n");
+	   }
+	   G_message("Unleveled: %d", unleveled); */
+    }
+
+    for (i = 0; i < fragcount - 1; i++) {
+	int j;
+
+	for (j = i + 1; j < fragcount; j++) {
+	    if (adj_matrix[i * fragcount + j] == 0) {
+		//G_message("Patch %d und %d sind nicht verbunden!",  i, j);
+	    }
+	}
+    }
+
+    G_free(list);
+}
+
+/*
+   Expands adjacency matrix by including neighbors of higher grade
+ */
+void expand_matrix()
+{
+    int row;
+
+    for (row = 0; row < fragcount; row++) {
+	expand_patch(row);
+    }
+}
+
+/*
+   constucts a voronoi diagram
+ */
+void voronoi(DCELL * values, int *map, int sx, int sy, int diag_grow)
+{
+    int i, j;
+    int running = 1;
+    int max_empty;
+    int last_empty = 0;
+
+    /* init buffers */
+    init_voronoi(map, sx, sy);
+
+    /* while empty_space not empty ready grow patch buffers by 1 */
+
+    max_empty = empty_count;
+    while (empty_count != last_empty) {
+	last_empty = empty_count;
+	grow_step(map, sx, sy, diag_grow);
+
+	G_percent(max_empty - empty_count, max_empty, 1);
+    }
+
+    /* write result */
+    for (i = 0; i < fragcount; i++) {
+	values[i] = areas[i];
+    }
+
+    expand_matrix();
+
+    G_free(areas);
+    G_free(empty_space);
+    G_free(new_edge);
+
+    return;
+}
+
+/*
+   uses values of neighboring patches and the adjacency matrix
+   to perform a statistical analysis of all neighbors of the focal patch
+
+   res = ( areas( stat1(patch1, patch2, ...), stat2(patch1, patch2, ...), ...  ), odds(), ... )
+ */
+void calc_neighbors(DCELL * res, DCELL * focals, f_statmethod * methods,
+		    int stat_count, f_compensate compensate,
+		    int neighbor_level)
+{
+    int i, j, method;
+    int count;
+    DCELL val;
+    DCELL *areas = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+    DCELL *odds = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+    DCELL *ratios = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+    /* for each patch gather areas and odds of neighbors */
+    for (i = 0; i < fragcount; i++) {
+	count = 0;
+	/* iterate over the corresponding row in the adjacency matrix */
+	for (j = 0; j < fragcount; j++) {
+	    /* if patch i(focal) and patch j(neighbor) are adjacent */
+	    if (adj_matrix[j + i * fragcount] == neighbor_level) {
+		areas[count] = fragments[j + 1] - fragments[j];
+		odds[count] = focals[j];
+		ratios[count] = compensate(odds[count], count);
+		count++;
+	    }
+	}
+
+	/* now we have areas and odds of all neighbors */
+	/* use the statistical methods to combine these */
+	for (method = 0; method < stat_count; method++) {
+	    /* write areas for neighbors of patch i */
+	    val = methods[method] (areas, count);
+	    res[method * fragcount + i] = val;
+
+	    /* write odds for neighbors of patch i */
+	    val = methods[method] (odds, count);
+	    res[stat_count * fragcount + method * fragcount + i] = val;
+
+	    /* write ratios for neighbors of patch i */
+	    val = methods[method] (ratios, count);
+	    res[2 * stat_count * fragcount + method * fragcount + i] = val;
+	}
+    }
+
+    G_free(areas);
+    G_free(odds);
+
+    return;
+}
+
+void getNeighborCount(DCELL * res)
+{
+    int i, j;
+
+    /* for each patch count neighbors */
+    for (i = 0; i < fragcount; i++) {
+	res[i] = 0;
+
+	/* iterate over the corresponding row in the adjacency matrix */
+	for (j = 0; j < fragcount; j++) {
+	    /* if patch i(focal) and patch j(neighbor) are adjacent */
+	    if (adj_matrix[j + i * fragcount] == 1) {
+		res[i]++;
+	    }
+	}
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.odc/voronoi.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.prob.mw
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/analysis.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/analysis.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/analysis.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,103 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int gather_positions(Position * res, int *map, int *mask, int x, int y,
+		     int sizex, int sizey, int patch_only)
+{
+    int i, j;
+    int count = 0;
+
+    for (j = y; j < y + sizey; j++) {
+	for (i = x; i < x + sizex; i++) {
+	    /* test if position should be considered */
+	    if (mask[j * sx + i] &&
+		((!patch_only || (patch_only && map[j * sx + i] > -1)))) {
+		res[count].x = i;
+		res[count].y = j;
+		count++;
+	    }
+	}
+    }
+
+    return count;
+}
+
+int perform_test(Position * positions, int count, int *map, int x, int y)
+{
+    int p1, p2;
+    int x1, x2, y1, y2;
+    int val1, val2;
+
+    /* pick two random position */
+    p1 = Random(count);
+    p2 = Random(count);
+
+    /* get both values */
+    x1 = positions[p1].x;
+    y1 = positions[p1].y;
+    x2 = positions[p2].x;
+    y2 = positions[p2].y;
+    val1 = map[y1 * sx + x1];
+    val2 = map[y2 * sx + x2];
+
+    /* compare values */
+    if (val1 > -1 && val1 == val2) {
+	return 1;
+    }
+    else {
+	return 0;
+    }
+}
+
+void perform_analysis(DCELL * values, int *map, int *mask, int n, int size,
+		      int patch_only)
+{
+    int x, y, nx, ny, sizex, sizey, i;
+    Position *pos_arr;
+    int count;
+    int value;
+    int progress = 0;
+
+    if (size > 0) {
+	pos_arr = (Position *) G_malloc(size * size * sizeof(Position));
+    }
+    else {
+	pos_arr = (Position *) G_malloc(sx * sy * sizeof(Position));
+    }
+
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+    sizex = size > 0 ? size : sx;
+    sizey = size > 0 ? size : sy;
+
+    /* for each window */
+    for (y = 0; y < ny; y++) {
+	for (x = 0; x < nx; x++) {
+	    /* get relevant positions */
+	    count =
+		gather_positions(pos_arr, map, mask, x, y, sizex, sizey,
+				 patch_only);
+
+	    if (count > 0) {
+		/* perform test n times */
+		value = 0;
+		for (i = 0; i < n; i++) {
+		    value += perform_test(pos_arr, count, map, x, y);
+		}
+	    }
+	    else {
+		value = -1;
+	    }
+	    values[y * nx + x] = (DCELL) value / (DCELL) n;
+
+	    progress++;
+	    G_percent(progress, nx * ny, 1);
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/analysis.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,46 @@
+<h2>DESCRIPTION</h2>
+
+Probability analysis of 2 random points being in the same patch. 
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.rectangle.html">r.pi.rectangle</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann <br>
+Department of Remote Sensing <br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,148 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, double distance);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 double distance);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 double distance)
+{
+    int left, right, top, bottom;
+    int i, j;
+    double dist_q = distance * distance;
+    int cnt = 0;
+
+    left = x - distance < 0 ? 0 : Round(x - distance);
+    right = x + distance > nx - 1 ? nx - 1 : Round(x + distance);
+    top = y - distance < 0 ? 0 : Round(y - distance);
+    bottom = y + distance > ny - 1 ? ny - 1 : Round(y + distance);
+
+    for (i = left; i <= right; i++) {
+	for (j = top; j <= bottom; j++) {
+	    if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		int dx = i - x;
+		int dy = j - y;
+		int q_sum = dx * dx + dy * dy;
+
+		if (q_sum <= dist_q) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, double distance)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    int neighb_max_count = Round(4 * distance * distance);
+    Position *nbr_list =
+	(Position *) G_malloc(neighb_max_count * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, distance);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, double distance)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, distance);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,66 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* analysis.c */
+void perform_analysis(DCELL * values, int *map, int *mask, int n, int size, int patch_only);
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, double distance);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* global parameters */
+GLOBAL int sx, sy;
+
+/* global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,356 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.prob.mw
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Probability analysis of 2 randomly set points to be 
+ *              located within the same patch - patch-to-patch distance setting optional
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* output */
+    char *newname, *newmapset;
+
+    /* mask */
+    char *maskname, *maskmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+
+    /* parameters */
+    int stats[GNAME_MAX];
+    f_statmethod *methods;
+    int stat_count;
+    int keyval;
+    int n;
+    int size;
+    double distance;
+    int patch_only;
+
+    /* maps */
+    int *map;
+    int *mask;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    DCELL *values;
+    int i, j;
+    Coords *p;
+    char *str;
+    int method;
+    char outname[GNAME_MAX];
+    int nx, ny;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output, *mask;
+	struct Option *keyval, *n;
+	struct Option *size, *distance;
+    } parm;
+    struct
+    {
+	struct Flag *patch_only;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Probability analysis of 2 random points being in the same patch.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.mask = G_define_option();
+    parm.mask->key = "mask";
+    parm.mask->type = TYPE_STRING;
+    parm.mask->required = NO;
+    parm.mask->gisprompt = "old,cell,raster";
+    parm.mask->description = _("Name of the mask raster file");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Category value of the patches");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->description = _("Number of tests");
+
+    parm.size = G_define_option();
+    parm.size->key = "size";
+    parm.size->type = TYPE_INTEGER;
+    parm.size->required = NO;
+    parm.size->description = _("Size of the output matrix");
+
+    parm.distance = G_define_option();
+    parm.distance->key = "distance";
+    parm.distance->type = TYPE_INTEGER;
+    parm.distance->required = NO;
+    parm.distance->description =
+	_("Maximum distance at which two patches are seen as one");
+
+    flag.patch_only = G_define_flag();
+    flag.patch_only->key = 'p';
+    flag.patch_only->description =
+	_("Patch only flag. When set only places test-points in patches");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    srand(time(NULL));
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of mask */
+    maskname = parm.mask->answer;
+
+    /* test costmap existance */
+    if (maskname && (maskmapset = G_find_cell2(maskname, "")) == NULL)
+	        G_fatal_error(_("Raster map <%s> not found"), maskname);
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get size */
+    if (parm.size->answer) {
+	sscanf(parm.size->answer, "%d", &size);
+    }
+    else {
+	size = 0;
+    }
+
+    /* get distance */
+    if (parm.distance->answer) {
+	sscanf(parm.distance->answer, "%lf", &distance);
+    }
+    else {
+	distance = 1;
+    }
+
+    /* get patch_only */
+    patch_only = flag.patch_only->answer;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    map_type = DCELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* test output */
+    /*      G_message("TEST OUTPUT :");
+       G_message("input = %s", oldname);
+       G_message("output = %s", newname);
+       G_message("mask = %s", maskname);
+       G_message("keyval = %d", keyval);    
+       G_message("n = %d", n);
+       G_message("size = %d", size);
+       G_message("distance = %0.2f", distance);
+       G_message("patch_only = %d", patch_only); */
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    mask = (DCELL *) G_malloc(sx * sy * sizeof(int));
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+
+    result = G_allocate_c_raster_buf();
+    d_res = G_allocate_d_raster_buf();
+
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+    values = (DCELL *) G_malloc(nx * ny * sizeof(Coords));
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row, sy, 2);
+    }
+    G_percent(1, 1, 2);
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if mask specified, read mask */
+    if (maskname) {
+	/* open mask file */
+	in_fd = G_open_cell_old(maskname, maskmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), maskname);
+
+	/* read mask */
+	G_message("Reading mask file:");
+	for (row = 0; row < sy; row++) {
+	    G_get_c_raster_row(in_fd, result, row);
+	    for (col = 0; col < sx; col++) {
+		mask[row * sx + col] = result[col];
+	    }
+
+	    G_percent(row, sy, 2);
+	}
+	G_percent(1, 1, 2);
+
+	/* close mask */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill mask with 1 */
+	for (i = 0; i < sx * sy; i++) {
+	    mask[i] = 1;
+	}
+    }
+
+    /* test output */
+    /*      G_message("costmap:\n");
+       print_d_buffer(costmap, sx, sy); */
+
+    /* find fragments */
+    writeFragments(map, sy, sx, distance);
+
+    /* test output */
+    /*      G_message("fragcount = %d", fragcount);
+       print_fragments(); */
+
+    /* mark each fragment with its number */
+    for (i = 0; i < sx * sy; i++) {
+	map[i] = -1;
+    }
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    map[p->y * sx + p->x] = i;
+	}
+    }
+
+    G_message("Performing analysis:");
+
+    perform_analysis(values, map, mask, n, size, patch_only);
+
+    /* test output */
+    /*G_message("Values: ");
+       for(j = 0; j < ny; j++) {
+       for(i = 0; i < nx; i++) {
+       fprintf(stderr, "%0.2f ", values[j * nx + i]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    if (size > 0) {
+	G_message("Writing output...");
+
+	/* open the new cellfile  */
+	out_fd = G_open_raster_new(newname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    if (row >= size / 2 && row < ny + size / 2) {
+		for (col = 0; col < nx; col++) {
+		    d_res[col + size / 2] =
+			values[(row - size / 2) * nx + col];
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+    }
+    else {
+	fprintf(stdout, "\n\noutput = %lf\n\n", values[0]);
+    }
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(mask);
+    G_free(cells);
+    G_free(fragments);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prob.mw/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prob.mw/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prob.mw/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prob.mw/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prox/.main.c.kate-swp
===================================================================
Added: grass-addons/raster/r.pi/r.pi.prox/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.prox/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prox/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.prox
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.prox/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prox/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.prox/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prox/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,33 @@
+<h2>DESCRIPTION</h2>
+
+Calculates different proximity indices using defined buffer areas.
+
+<h2>NOTES</h2>
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.index.html">r.fragment</a>,
+<a href="r.pi.neigh.html">r.pi.enn</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann<br>
+Department of Remote Sensing<br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.prox/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prox/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prox/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prox/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,143 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+int getNeighbors(Position * res, int x, int y, int nx, int ny, int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+void writeFrag(int row, int col, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col > 0 && flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row > 0 && flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col < ncols - 1 && flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row < nrows - 1 && flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt = getNeighbors(nbr_list, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x > 0 && flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y > 0 && flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x < ncols - 1 && flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y < nrows - 1 && flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prox/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prox/func.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prox/func.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prox/func.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,139 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include <math.h>
+#include "local_proto.h"
+
+DCELL dist(Coords * p1, Coords * p2)
+{
+    int x1 = p1->x;
+    int y1 = p1->y;
+    int x2 = p2->x;
+    int y2 = p2->y;
+    int dx = x2 - x1;
+    int dy = y2 - y1;
+
+    return sqrt(dx * dx + dy * dy);
+}
+
+DCELL min_dist(Coords ** frags, int n1, int n2)
+{
+    Coords *p1, *p2;
+    DCELL min = 1000000.0;
+
+    // for all cells in the first patch
+    for (p1 = frags[n1]; p1 < frags[n1 + 1]; p1++) {
+	// if cell at the border
+	if (p1->neighbors < 4) {
+	    // for all cells in the second patch
+	    for (p2 = frags[n2]; p2 < frags[n2 + 1]; p2++) {
+		// if cell at the border
+		if (p2->neighbors < 4) {
+		    DCELL d = dist(p1, p2);
+
+		    if (d < min) {
+			min = d;
+		    }
+		}
+	    }
+	}
+    }
+    return min;
+}
+
+DCELL *get_dist_matrix(int count)
+{
+    int i, j;
+    DCELL *distmatrix;
+
+    distmatrix = (DCELL *) G_malloc(count * count * sizeof(DCELL));
+
+    /* fill distance matrix */
+    for (i = 0; i < count; i++) {
+	for (j = i + 1; j < count; j++) {
+	    DCELL d = min_dist(fragments, i, j);
+
+	    distmatrix[i * count + j] = d;
+	    distmatrix[j * count + i] = d;
+	}
+    }
+
+    return distmatrix;
+}
+
+int f_proximity(DCELL * vals, Coords ** frags, int count, int min, int max)
+{
+    int i, j;
+    DCELL *distmatrix = get_dist_matrix(count);
+
+    for (i = 0; i < count; i++) {
+	DCELL prox = 0.0;
+
+	for (j = 0; j < count; j++) {
+	    if (i != j) {
+		DCELL area = (DCELL) (frags[j + 1] - frags[j]);
+		DCELL d = distmatrix[i * count + j];
+
+		if (d >= min && d <= max)
+		    prox += area / d;
+	    }
+	}
+	vals[i] = prox;
+    }
+
+    G_free(distmatrix);
+    return 0;
+}
+
+int f_modified_prox(DCELL * vals, Coords ** frags, int count, int min,
+		    int max)
+{
+    int i, j;
+    DCELL *distmatrix = get_dist_matrix(count);
+
+    for (i = 0; i < count; i++) {
+	DCELL prox = 0.0;
+
+	for (j = 0; j < count; j++) {
+	    if (i != j) {
+		DCELL area = (DCELL) (frags[j + 1] - frags[j]);
+		DCELL d = distmatrix[i * count + j];
+
+		if (d >= min && d <= max)
+		    prox += area / d;
+	    }
+	}
+	DCELL area = (DCELL) (frags[i + 1] - frags[i]);
+
+	vals[i] = prox * area;
+    }
+
+    G_free(distmatrix);
+    return 0;
+}
+
+int f_neighborhood(DCELL * vals, Coords ** frags, int count, int min, int max)
+{
+    int i, j;
+    DCELL *distmatrix = get_dist_matrix(count);
+
+    for (i = 0; i < count; i++) {
+	int patchcount = 0;
+
+	for (j = 0; j < count; j++) {
+	    if (i != j) {
+		DCELL d = distmatrix[i * count + j];
+
+		if (d >= min && d <= max)
+		    patchcount++;
+	    }
+	}
+	vals[i] = patchcount;
+    }
+
+    G_free(distmatrix);
+    return 0;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prox/func.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prox/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.prox/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prox/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,29 @@
+#define MAX_DOUBLE 1000000.0
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+/* frag.c */
+void writeFrag(int row, int col, int nbr_cnt);
+
+/* func.c */
+int f_proximity(DCELL *, Coords **, int, int, int);
+int f_modified_prox(DCELL * vals, Coords ** frags, int count, int min,
+		    int max);
+int f_neighborhood(DCELL *, Coords **, int, int, int);
+
+/* global variables */
+GLOBAL int nrows, ncols;
+GLOBAL Coords **fragments;
+GLOBAL int *flagbuf;
+GLOBAL Coords *actpos;
+GLOBAL int cnt;


Property changes on: grass-addons/raster/r.pi/r.pi.prox/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.prox/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.prox/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.prox/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,304 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.prox
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Proximity analysis - values of patches within a defined range
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+#include "local_proto.h"
+
+int recur_test(int, int, int);
+
+typedef int (*f_func) (DCELL *, Coords **, int, int, int);
+
+struct menu
+{
+    f_func *method;		/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+};
+
+static struct menu menu[] = {
+    {f_proximity, "proximity index",
+     "proximity index for every patch within certain range"},
+    {f_modified_prox, "modified proximity index",
+     "modified proximity index for every patch within certain range"},
+    {f_neighborhood, "neighborhood index",
+     "number of patches within certain range"},
+    {0, 0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *newname, *oldname, *newmapset, *oldmapset;
+    char title[1024];
+    int verbose;
+
+    /* in and out file pointers */
+    int in_fd;
+    int out_fd;
+    DCELL *result, res[30];
+
+    /* map_type and categories */
+    RASTER_MAP_TYPE map_type;
+    struct Categories cats;
+
+    int method;
+    f_func compute_values;
+
+    char *p;
+
+    /* neighbors count */
+    int neighb_count;
+
+    int row, col, i, j;
+    int readrow;
+    int keyval;
+    int min = 0;
+    int max = MAX_DOUBLE;
+
+    int n;
+    int copycolr;
+    struct Colors colr;
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *output;
+	struct Option *keyval, *method;
+	struct Option *min, *max, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *quiet;
+    } flag;
+
+    DCELL *values;
+    Coords *cells;
+    int fragcount = 0;
+
+    struct Cell_head ch, window;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Calculates correlation of two raster maps "
+	  "by calculating correlation function of two "
+	  "corresponding rectangular areas for each "
+	  "raster point and writing the result into a new raster map.");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Key value");
+
+    parm.method = G_define_option();
+    parm.method->key = "method";
+    parm.method->type = TYPE_STRING;
+    parm.method->required = YES;
+    p = parm.method->options = G_malloc(1024);
+    for (n = 0; menu[n].name; n++) {
+	if (n)
+	    strcat(p, ",");
+	else
+	    *p = 0;
+	strcat(p, menu[n].name);
+    }
+    parm.method->description = _("Operation to perform on fragments");
+
+    parm.min = G_define_option();
+    parm.min->key = "min";
+    parm.min->type = TYPE_INTEGER;
+    parm.min->required = NO;
+    parm.min->description =
+	_("Minimum range for the operation measured by pixels, default 0");
+
+    parm.max = G_define_option();
+    parm.max->key = "max";
+    parm.max->type = TYPE_INTEGER;
+    parm.max->required = NO;
+    parm.max->description =
+	_("Maximum Range for the operation measured by pixels, default copmlete map");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+
+    flag.quiet = G_define_flag();
+    flag.quiet->key = 'q';
+    flag.quiet->description = _("Run quietly");
+
+    if (G_parser(argc, argv))
+	    exit(EXIT_FAILURE);
+
+    /* get names of input files */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+	if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	    G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* get size */
+    nrows = G_window_rows();
+    ncols = G_window_cols();
+
+    /* open cell files */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+        G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* get map type */
+    map_type = DCELL_TYPE;	/* G_raster_map_type(oldname, oldmapset); */
+
+    /* copy color table */
+    copycolr = (G_read_colors(oldname, oldmapset, &colr) > 0);
+
+    /* get key value */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get the method */
+    for (method = 0; (p = menu[method].name); method++)
+	if ((strcmp(p, parm.method->answer) == 0))
+	    break;
+    if (!p) {
+	G_warning(_("<%s=%s> unknown %s"),
+		  parm.method->key, parm.method->answer, parm.method->key);
+	G_usage();
+	exit(EXIT_FAILURE);
+    }
+
+    /* establish the newvalue routine */
+    compute_values = menu[method].method;
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* allocate the cell buffers */
+    cells = (Coords *) G_malloc(nrows * ncols * sizeof(Coords));
+    actpos = cells;
+    fragments = (Coords **) G_malloc(nrows * ncols * sizeof(Coords *));
+    fragments[0] = cells;
+    flagbuf = (int *)G_malloc(nrows * ncols * sizeof(int));
+    result = G_allocate_d_raster_buf();
+
+    /* get min */
+    if (parm.min->answer)
+	sscanf(parm.min->answer, "%d", &min);
+
+    /* get max */
+    if (parm.max->answer)
+	sscanf(parm.max->answer, "%d", &max);
+
+    /* get title */
+    if (parm.title->answer)
+	strcpy(title, parm.title->answer);
+    else
+	sprintf(title, "Fragmentation of file: %s", oldname);
+
+    /* open the new cellfile  */
+    out_fd = G_open_raster_new(newname, map_type);
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
+
+    if (verbose = !flag.quiet->answer)
+	fprintf(stderr, "Percent complete ... ");
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	G_get_d_raster_row(in_fd, result, row);
+	for (col = 0; col < ncols; col++) {
+	    if (result[col] == keyval)
+		flagbuf[row * ncols + col] = 1;
+	}
+    }
+
+    for (row = 0; row < nrows; row++) {
+	/* display progress */
+	if (verbose)
+	    G_percent(row, nrows, 2);
+
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+		writeFrag(row, col, neighb_count);
+		fragments[fragcount] = actpos;
+	    }
+	}
+    }
+
+    /* perform actual function on the patches */
+    values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+    compute_values(values, fragments, fragcount, min, max);
+
+    /* write the output file */
+    for (row = 0; row < nrows; row++) {
+	G_set_d_null_value(result, ncols);
+
+	for (i = 0; i < fragcount; i++) {
+	    for (actpos = fragments[i]; actpos < fragments[i + 1]; actpos++) {
+		if (actpos->y == row) {
+		    result[actpos->x] = values[i];
+		}
+	    }
+	}
+
+	G_put_d_raster_row(out_fd, result);
+    }
+
+    if (verbose)
+	G_percent(row, nrows, 2);
+
+    G_close_cell(out_fd);
+    G_close_cell(in_fd);
+
+    G_free(cells);
+    G_free(fragments);
+    G_free(flagbuf);
+
+    G_init_cats(0, title, &cats);
+    G_write_cats(newname, &cats);
+
+    if (copycolr)
+	G_write_colors(newname, newmapset, &colr);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.prox/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Modified: grass-addons/raster/r.pi/r.pi.rectangle/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.rectangle/description.html	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.rectangle/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,35 +1,56 @@
-<H2>DESCRIPTION</H2>
+<h2>DESCRIPTION</h2>
 
+<em>r.pi.rectangle</em> converts sampling points (e.g. GPS coordinates)
+of the corner of a sampling site into an area by generating a defined rectangle.
+
+Generates a rectangle based on a corner coordinate. 
 <P>
 This modules aims at generating sampling areas which are only known by the
 coordinate of one corner. The input are single points, while the output are
 areas representing the corresponding area for each of the single
 points/coordinates.
 
-The program will be run non-interactively if the user specifies program
-arguments (see OPTIONS) on the command
-line.  Alternately, the user can simply type <B>r.pi.rectangle</B> on the
-command line, without program arguments.  In this case, the user will be
-prompted for flag settings and parameter values.
+<h2>NOTES</h2>
 
-<H2>NOTES</H2>
+The areas can only be generated horizontally, not diagonal. This can
+be added as wish and might be implemented in the future.
 
-The areas can only be generated horizontally, not diagonal. This can be added
-as wish and might be implemented in the future.
+<h2>EXAMPLE</h2>
 
-<H2>BUGS</H2>
+An example for the North Carolina sample dataset:
 
-<H2>SEE ALSO</H2>
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
 
-<EM><A HREF="r.pi.ENN.html">r.pi.ENN</A></EM><br>
-<EM><A HREF="r.pi.FNN.html">r.pi.FNN</A></EM><br>
-<EM><A HREF="r.pi.dist.html">r.pi.dist</A></EM><br>
-<EM><A HREF="r.li.setup.html">r.li.setup</A></EM><br>
+<h2>SEE ALSO</h2>
 
-<H2>AUTHOR</H2>
+<em>
+<a href="r.pi.corearea.html">r.pi.corearea</a>,
+<a href="r.pi.corrwin.html">r.pi.corrwin</a>,
+<a href="r.pi.csr.mw.html">r.pi.csr.mw</a>,
+<a href="r.pi.export.html">r.pi.export</a>,
+<a href="r.pi.graph.html">r.pi.graph</a>,
+<a href="r.pi.graph.dec.html">r.pi.graph.dec</a>,
+<a href="r.pi.graph.iter.html">r.pi.graph.iter</a>,
+<a href="r.pi.graph.red.html">r.pi.graph.red</a>,
+<a href="r.pi.grow.html">r.pi.grow</a>,
+<a href="r.pi.import.html">r.pi.import</a>,
+<a href="r.pi.index.html">r.pi.index</a>,
+<a href="r.pi.lm.html">r.pi.lm</a>,
+<a href="r.pi.odc.html">r.pi.odc</a>,
+<a href="r.pi.prob.mw.html">r.pi.prob.mw</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
 Programming: Elshad Shirinov<br>
 Scientific concept: Dr. Martin Wegmann <br>
-Department of Remote Sensing <br>Remote Sensing and Biodiversity Unit<br> University of Wuerzburg, Germany
+Department of Remote Sensing <br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
 
-<p><i>Last changed: $Date$</i>
+<p>
+<i>Last changed: $Date$</i>
 

Modified: grass-addons/raster/r.pi/r.pi.rectangle/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.rectangle/main.c	2011-09-27 10:00:15 UTC (rev 48494)
+++ grass-addons/raster/r.pi/r.pi.rectangle/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -1,10 +1,20 @@
-#include "local_proto.h"
-
 /*
-   r.pi.rectangle programming.
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.rectangle
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Delineation of rectangular study areas based on GPS location
+ *                               of the respective corners
+ *
+ * COPYRIGHT:    (C) 2009-2011 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.
+ *
+ *****************************************************************************/
 
-   by Elshad Shirinov.
- */
+#include "local_proto.h"
 
 struct alignment
 {
@@ -32,16 +42,12 @@
 
     /* in and out file pointers */
     int in_fd;
-
     int out_fd;
 
     /* parameters */
     int keyval;
-
     int x, y;
-
     int align;
-
     int sx, sy;
 
     /* maps */
@@ -52,19 +58,13 @@
 
     /* helper variables */
     int row, col;
-
     CELL *result;
-
     char *str;
-
     int n, i;
-
     RASTER_MAP_TYPE map_type;
 
     struct Cell_head ch, window;
-
     struct GModule *module;
-
     struct
     {
 	struct Option *input, *output;
@@ -80,20 +80,11 @@
     module->description =
 	_("Generates a rectangle based on a corner coordinate.");
 
-    parm.input = G_define_option();
-    parm.input->key = "input";
-    parm.input->type = TYPE_STRING;
-    parm.input->required = YES;
-    parm.input->gisprompt = "old,cell,raster";
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
     parm.input->description =
-	_("raster file with single pixels representing sampling points");
+	_("Raster map with single pixels representing sampling points");
 
-    parm.output = G_define_option();
-    parm.output->key = "output";
-    parm.output->type = TYPE_STRING;
-    parm.output->required = YES;
-    parm.output->gisprompt = "new,cell,raster,output";
-    parm.output->description = _("Name for the output raster file");
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
 
     parm.keyval = G_define_option();
     parm.keyval->key = "keyval";
@@ -107,14 +98,14 @@
     parm.x->type = TYPE_INTEGER;
     parm.x->required = YES;
     parm.x->description =
-	_("extent of generated area on the x axis (width) in pixel");
+	_("Extent of generated area on the x axis (width) in pixel");
 
     parm.y = G_define_option();
     parm.y->key = "y";
     parm.y->type = TYPE_INTEGER;
     parm.y->required = YES;
     parm.y->description =
-	_("extent of generated area on the y axis (height) in pixel");
+	_("Extent of generated area on the y axis (height) in pixel");
 
     parm.alignment = G_define_option();
     parm.alignment->key = "alignment";
@@ -129,14 +120,14 @@
 	strcat(str, alignments[n].name);
     }
     parm.alignment->description =
-	_("alignment of the rectangle relative to the input pixel. options: center, top-left, top-right, bottom");
+	_("Alignment of the rectangle relative to the input pixel. options: center, top-left, top-right, bottom");
 
     parm.title = G_define_option();
     parm.title->key = "title";
     parm.title->key_desc = "\"phrase\"";
     parm.title->type = TYPE_STRING;
     parm.title->required = NO;
-    parm.title->description = _("Title of the output raster file");
+    parm.title->description = _("Title for resultant raster map");
 
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
@@ -145,19 +136,14 @@
     oldname = parm.input->answer;
 
     /* test input files existence */
-    if ((oldmapset = G_find_cell2(oldname, "")) == NULL) {
-	G_warning(_("%s: <%s> raster file not found\n"), G_program_name(),
-		  oldname);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    oldmapset = G_find_cell2(oldname, "");
+	if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
 
     /* check if the new file name is correct */
     newname = parm.output->answer;
-    if (G_legal_filename(newname) < 0) {
-	G_warning("%s: <%s> illegal file name\n", G_program_name(), newname);
-	exit(EXIT_FAILURE);
-    }
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
     newmapset = G_mapset();
 
     /* read keyval */
@@ -197,15 +183,12 @@
     G_set_c_null_value(newmap, sx * sy);
 
     /* open map */
-    if ((in_fd = G_open_cell_old(oldname, oldmapset)) < 0) {
-	G_fatal_error(_("can't open cell file <%s> in mapset %s\n"), oldname,
-		      oldmapset);
-	G_usage();
-	exit(EXIT_FAILURE);
-    }
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
 
     /* read map */
-    G_message("Reading map file:\n");
+    G_message("Reading map:");
     for (row = 0; row < sy; row++) {
 	G_get_c_raster_row(in_fd, map + row * sx, row);
 
@@ -225,18 +208,15 @@
     G_close_cell(in_fd);
 
     /* write the output file */
-    G_message("Writing output ... ");
+    G_message("Writing output...");
 
     /* open cell file */
     if ((in_fd = G_open_cell_old(oldname, oldmapset)) < 0) {
     }
     /* open new cell file  */
     out_fd = G_open_raster_new(newname, CELL_TYPE);
-    if (out_fd < 0) {
-	G_fatal_error("Can't create new cell file <%s> in mapset %s", newname,
-		      newmapset);
-	exit(EXIT_FAILURE);
-    }
+    if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), newname);
 
     /* write output */
     for (row = 0; row < sy; row++) {

Added: grass-addons/raster/r.pi/r.pi.searchtime/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.searchtime
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,40 @@
+Individual-based dispersal model for connectivity analysis (time-based) 
+<h2>DESCRIPTION</h2>
+
+This modules aims at generating sampling areas which are only known by the
+coordinate of one corner. The input are single points, while the output are
+areas representing the corresponding area for each of the single
+points/coordinates.
+
+
+<h2>NOTES</h2>
+
+The areas can only be generated horizontally, not diagonal. This can be added
+as wish and might be implemented in the future.
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.searchtime.iter.html">r.pi.searchtime.iter</a>,
+<a href="r.pi.searchtime.mw.html">r.pi.searchtime.mw</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann <br>
+Department of Remote Sensing <br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,109 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    DCELL path;
+    int finished;
+} Individual;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    double weight;
+} WeightedCoords;
+
+typedef struct
+{
+    int x, y;
+} Displacement;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* search.c */
+void perform_search(DCELL * values, int *map, DCELL * costmap,
+		    f_statmethod * stats, int stat_count);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* indices.c */
+DCELL shannon_index(int patch);
+DCELL simpson_index(int patch);
+
+/* global parameters */
+GLOBAL int sx, sy;
+GLOBAL int keyval;
+GLOBAL int n;
+GLOBAL double percent;
+GLOBAL int maxsteps;
+GLOBAL int step_length;
+GLOBAL int out_freq;
+GLOBAL int include_cost;
+GLOBAL int perception_range;
+GLOBAL double step_range;
+GLOBAL double multiplicator;
+
+/* global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+GLOBAL Individual *indi_array;
+GLOBAL int *patch_imi;
+
+GLOBAL char *newname, *newmapset;
+GLOBAL char *iminame, *imimapset;
+
+GLOBAL int *immi_matrix, *mig_matrix;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,907 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.searchtime
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Individual-based dispersal model for connectivity analysis - time-based
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* costmap */
+    char *costname, *costmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+    FILE *out_fp;
+
+    /* parameters */
+    int stats[GNAME_MAX];
+    f_statmethod *methods;
+    int stat_count;
+    DCELL threshold;
+
+    /* maps */
+    int *map;
+    DCELL *costmap;
+
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    DCELL *values;
+    int neighb_count;
+    int i, j;
+    Coords *p;
+    char *str;
+    int method;
+    char outname[GNAME_MAX];
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *output, *out_immi;
+	struct Option *keyval, *step_length, *step_range, *perception,
+	    *multiplicator, *n;
+	struct Option *percent, *stats, *maxsteps, *out_freq, *immi_matrix,
+	    *binary_matrix;
+	struct Option *threshold, *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *cost, *diversity, *indices;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description = _("Individual-based dispersal model for connectivity analysis (time-based)");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = NO;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->description =
+	_("Name of the costmap with values from 0-100");
+    parm.costmap->guisection = "Optional";
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.out_immi = G_define_option();
+    parm.out_immi->key = "out_immi";
+    parm.out_immi->type = TYPE_STRING;
+    parm.out_immi->required = NO;
+    parm.out_immi->gisprompt = "new,cell,raster";
+    parm.out_immi->description =
+	_("Name of the optional raster file for patch immigrants count");
+    parm.out_immi->guisection = "Optional";
+
+    parm.immi_matrix = G_define_option();
+    parm.immi_matrix->key = "immi_matrix";
+    parm.immi_matrix->type = TYPE_STRING;
+    parm.immi_matrix->required = NO;
+    parm.immi_matrix->gisprompt = "new_file,file,output";
+    parm.immi_matrix->description =
+	_("Name for immigrants matrix ASCII-file");
+    parm.immi_matrix->guisection = "Optional";
+
+    parm.binary_matrix = G_define_option();
+    parm.binary_matrix->key = "binary_matrix";
+    parm.binary_matrix->type = TYPE_STRING;
+    parm.binary_matrix->required = NO;
+    parm.binary_matrix->gisprompt = "new_file,file,output";
+    parm.binary_matrix->description =
+	_("Name for binary immigrants matrix ASCII-file");
+    parm.binary_matrix->guisection = "Optional";
+
+    parm.threshold = G_define_option();
+    parm.threshold->key = "threshold";
+    parm.threshold->type = TYPE_DOUBLE;
+    parm.threshold->required = NO;
+    parm.threshold->description =
+	_("Percentage of individuals which must have immigrated"
+	  " successfully to be considered for the binary immigrants matrix");
+    parm.threshold->guisection = "Optional";
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Category value of the patches");
+    parm.keyval->guisection = "Required";
+
+    parm.step_length = G_define_option();
+    parm.step_length->key = "step_length";
+    parm.step_length->type = TYPE_INTEGER;
+    parm.step_length->required = YES;
+    parm.step_length->description =
+	_("Length of a single step measured in pixels");
+    parm.step_length->guisection = "Required";
+
+    parm.step_range = G_define_option();
+    parm.step_range->key = "step_range";
+    parm.step_range->type = TYPE_DOUBLE;
+    parm.step_range->required = NO;
+    parm.step_range->description =
+	_("Range to choose the next step direction from, in degrees"
+	  " [default = 180°]");
+    parm.step_range->guisection = "Optional";
+
+    parm.perception = G_define_option();
+    parm.perception->key = "perception";
+    parm.perception->type = TYPE_INTEGER;
+    parm.perception->required = NO;
+    parm.perception->description = _("Perception range");
+    parm.perception->guisection = "Optional";
+
+    parm.multiplicator = G_define_option();
+    parm.multiplicator->key = "multiplicator";
+    parm.multiplicator->type = TYPE_DOUBLE;
+    parm.multiplicator->required = NO;
+    parm.multiplicator->description = _("Attractivity of patches [1-inf]");
+    parm.multiplicator->guisection = "Optional";
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->description = _("Number of individuals");
+    parm.n->guisection = "Required";
+
+    parm.percent = G_define_option();
+    parm.percent->key = "percent";
+    parm.percent->type = TYPE_DOUBLE;
+    parm.percent->required = YES;
+    parm.percent->description =
+	_("Percentage of individuals which must have arrived successfully"
+	  " to stop the model-run");
+    parm.percent->guisection = "Required";
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    parm.stats->multiple = YES;
+    str = parm.stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[n].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the values");
+    parm.stats->guisection = "Required";
+
+    parm.maxsteps = G_define_option();
+    parm.maxsteps->key = "maxsteps";
+    parm.maxsteps->type = TYPE_INTEGER;
+    parm.maxsteps->required = NO;
+    parm.maxsteps->description = _("Maximum steps for each individual");
+    parm.maxsteps->guisection = "Optional";
+
+    parm.out_freq = G_define_option();
+    parm.out_freq->key = "out_freq";
+    parm.out_freq->type = TYPE_INTEGER;
+    parm.out_freq->required = NO;
+    parm.out_freq->description =
+	_("Output an intermediate state of simulation each [out_freq] steps");
+    parm.out_freq->guisection = "Optional";
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+    parm.title->guisection = "Optional";
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+
+    flag.cost = G_define_flag();
+    flag.cost->key = 'c';
+    flag.cost->description =
+	_("Include cost of the path in the calculation of steps");
+
+    flag.diversity = G_define_flag();
+    flag.diversity->key = 'd';
+    flag.diversity->description = _("Output diversity map");
+
+    flag.indices = G_define_flag();
+    flag.indices->key = 'i';
+    flag.indices->description = _("Output Shannon- and Simpson-index");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    srand(time(NULL));
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of costmap */
+    costname = parm.costmap->answer;
+
+    /* test costmap existance */    if (costname && (costmapset = G_find_cell2(costname, "")) == NULL)
+	    G_fatal_error(_("Raster map <%s> not found"), costname);    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get step_length */
+    sscanf(parm.step_length->answer, "%d", &step_length);
+
+    /* get step_range */
+    if (parm.step_range->answer) {
+	sscanf(parm.step_range->answer, "%lf", &step_range);
+	step_range /= 180.0;
+    }
+    else {
+	step_range = 1.0;
+    }
+
+    /* get perception_range */
+    if (parm.perception->answer) {
+	sscanf(parm.perception->answer, "%d", &perception_range);
+    }
+    else {
+	perception_range = step_length;
+    }
+
+    /* get multiplicator */
+    if (parm.multiplicator->answer) {
+	sscanf(parm.multiplicator->answer, "%lf", &multiplicator);
+    }
+    else {
+	multiplicator = 1.0;
+    }
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get percent */
+    sscanf(parm.percent->answer, "%lf", &percent);
+
+    /* get threshold */
+    if (parm.threshold->answer) {
+	sscanf(parm.threshold->answer, "%lf", &threshold);
+    }
+    else {
+	threshold = 0.0;
+    }
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get include_cost */
+    include_cost = flag.cost->answer;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* check if the immigrants file name is correct */
+    iminame = parm.out_immi->answer;
+    if (iminame && G_legal_filename(iminame) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), iminame);
+    imimapset = G_mapset();
+
+    map_type = DCELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* get maxsteps */
+    if (parm.maxsteps->answer != NULL) {
+	sscanf(parm.maxsteps->answer, "%d", &maxsteps);
+    }
+    else {
+	maxsteps = 10 * sqrt(sx * sx + sy * sy) / step_length;
+    }
+
+    /* get out_freq */
+    if (parm.out_freq->answer != NULL) {
+	sscanf(parm.out_freq->answer, "%d", &out_freq);
+    }
+    else {
+	out_freq = 0;
+    }
+
+    /* scan all statmethod answers */
+    stat_count = 0;
+    while (parm.stats->answers[stat_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (str = statmethods[method].name); method++)
+	    if (strcmp(str, parm.stats->answers[stat_count]) == 0)
+		break;
+	if (!str) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.stats->key, parm.stats->answers[stat_count],
+		      parm.stats->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	stats[stat_count] = method;
+
+	stat_count++;
+    }
+
+    /* test output */
+    /*      fprintf(stderr, "TEST OUTPUT : \n");
+       fprintf(stderr, "input = %s\n", oldname);
+       fprintf(stderr, "output = %s\n", newname);
+       fprintf(stderr, "costmap = %s\n", costname);
+       fprintf(stderr, "keyval = %d\n", keyval);
+       fprintf(stderr, "step_length = %d\n", step_length);
+       fprintf(stderr, "n = %d\n", n);
+       fprintf(stderr, "percent = %0.2f\n", percent);
+       fprintf(stderr, "maxsteps = %d\n", maxsteps); 
+       fprintf(stderr, "Stats: ");
+       for(i = 0; i < stat_count; i++) {
+       fprintf(stderr, statmethods[stats[i]].name);
+       } */
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    costmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    d_res = G_allocate_d_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row, sy, 2);
+    }
+    G_percent(1, 1, 2);
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if costmap specified, read costmap */
+    if (costname != NULL) {
+	/* open costmap */
+	if ((in_fd = G_open_cell_old(costname, costmapset)) < 0) {
+	    G_fatal_error(_("can't open cell file <%s> in mapset %s\n"),
+			  costname, costmapset);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	/* read costmap */
+	G_message("Reading costmap:");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		costmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row, sy, 2);
+	}
+	G_percent(1, 1, 2);
+
+	/* close costmap */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill costmap with 100 */
+	for (i = 0; i < sx * sy; i++) {
+	    costmap[i] = 100;
+	}
+    }
+
+    /* test output */
+    /*      G_message("costmap:\n");
+       print_d_buffer(costmap, sx, sy); */
+
+    /* find fragments */
+    writeFragments(map, sy, sx, neighb_count);
+
+    /* test output */
+    /*      print_fragments(); */
+
+    /* mark each fragment with its number */
+    for (i = 0; i < sx * sy; i++) {
+	map[i] = -1;
+    }
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    map[p->y * sx + p->x] = i;
+	}
+    }
+
+    /* test output */
+    /*      print_buffer(map, sx, sy); */
+    G_message("Performing search runs:");
+
+    /* allocate space for patch immigrants */
+    patch_imi = (int *)G_malloc(fragcount * sizeof(int));
+
+    /* fill methods array */
+    methods = (f_statmethod *) G_malloc(stat_count * sizeof(f_statmethod));
+    for (method = 0; method < stat_count; method++) {
+	methods[method] = statmethods[stats[method]].method;
+    }
+
+    /* perform search */
+    values = (DCELL *) G_malloc(fragcount * stat_count * sizeof(DCELL));
+    perform_search(values, map, costmap, methods, stat_count);
+
+    /* test output */
+    G_message("Results:");
+    for (j = 0; j < stat_count; j++) {
+	G_message("%s: ", statmethods[stats[j]].name);
+	for (i = 0; i < fragcount; i++) {
+	    fprintf(stderr, "frag%d: %0.2f ", i, values[j * fragcount + i]);
+	}
+	fprintf(stderr, "\n");
+    }
+    G_message("");
+
+    G_message("Writing output...");
+    for (method = 0; method < stat_count; method++) {
+
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, statmethods[stats[method]].suffix);
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[method * fragcount + i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(method * sy + row + 1, sy * stat_count, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* open the new cellfile  */
+    if (iminame) {
+	out_fd = G_open_raster_new(iminame, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), iminame);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = patch_imi[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row, sy, 2);
+	}
+
+	G_percent(100, 100, 2);
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write immigrants matrix ASCII file */
+    if (parm.immi_matrix->answer) {
+	if (strcmp(parm.immi_matrix->answer, "-") != 0) {
+	    if (!(out_fp = fopen(parm.immi_matrix->answer, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"),
+			      parm.immi_matrix->answer);
+	    }
+	}
+	else {
+	    out_fp = stdout;
+	}
+
+	/* write data */
+	for (i = 0; i < fragcount; i++) {
+	    for (j = 0; j < fragcount; j++) {
+		fprintf(out_fp, "%d ", immi_matrix[i * fragcount + j]);
+	    }
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close file */
+	if (strcmp(parm.immi_matrix->answer, "-") != 0) {
+	    fclose(out_fp);
+	}
+    }
+
+    /* write binary immigrants matrix ASCII file */
+    if (parm.binary_matrix->answer) {
+	if (strcmp(parm.binary_matrix->answer, "-") != 0) {
+	    if (!(out_fp = fopen(parm.binary_matrix->answer, "w"))) {
+		G_fatal_error(_("Error creating file <%s>"),
+			      parm.binary_matrix->answer);
+	    }
+	}
+	else {
+	    out_fp = stdout;
+	}
+
+	/* write data */
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants from patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += immi_matrix[j * fragcount + i];
+	    }
+
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (immi_matrix[i * fragcount + j] > threshold_count) {
+		    fprintf(out_fp, "1 ");
+		}
+		else {
+		    fprintf(out_fp, "0 ");
+		}
+	    }
+	    fprintf(out_fp, "\n");
+	}
+
+	/* close file */
+	if (strcmp(parm.binary_matrix->answer, "-") != 0) {
+	    fclose(out_fp);
+	}
+    }
+
+    /* write diversity maps */
+    if (flag.diversity->answer) {
+	/* calculate diversity */
+	DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants in patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += immi_matrix[j * fragcount + i];
+	    }
+
+	    /* calculate threshold count */
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    /* count patches with immigrant count exceeding threshold */
+	    DCELL value = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (immi_matrix[j * fragcount + i] > threshold_count) {
+		    value++;
+		}
+	    }
+
+	    values[i] = value;
+	}
+
+	/* antidiversity */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "diversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* antidiversity percentual */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s_percent", newname, "diversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    values[i] / (DCELL) (fragcount - 1) * 100.0;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write antidiversity maps */
+    if (flag.diversity->answer) {
+	/* calculate antidiversity */
+	DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	for (i = 0; i < fragcount; i++) {
+	    /* calculate sum of all imigrants from patch i */
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		sum += immi_matrix[i * fragcount + j];
+	    }
+
+	    /* calculate threshold count */
+	    int threshold_count = (int)(threshold * (double)sum) / 100;
+
+	    /* count all patches with emigrant count exceeding threshold */
+	    DCELL value = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		if (immi_matrix[i * fragcount + j] > threshold_count) {
+		    value++;
+		}
+	    }
+
+	    values[i] = value;
+	}
+
+	/* antidiversity */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "antidiversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* antidiversity percentual */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s_percent", newname, "antidiversity");
+	out_fd = G_open_raster_new(outname, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] =
+			    values[i] / (DCELL) (fragcount - 1) * 100.0;
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* write indices for immigrants */
+    if (flag.indices->answer) {
+	/* SHANNON */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "shannon");
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* calculate indices */
+	DCELL *values = (DCELL *) G_malloc(fragcount * sizeof(DCELL));
+
+	for (i = 0; i < fragcount; i++) {
+	    int N = 0;
+	    DCELL sum = 0.0;
+
+	    for (j = 0; j < fragcount; j++) {
+		int immi = immi_matrix[j * fragcount + i];
+
+		if (immi > 0) {
+		    N += immi;
+		    sum += (DCELL) immi *log((DCELL) immi);
+		}
+	    }
+
+	    values[i] = log((DCELL) N) - sum / (DCELL) N;
+	}
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	/* close output */
+	G_close_cell(out_fd);
+
+	/* SIMPSON */
+	/* open the new cellfile  */
+	sprintf(outname, "%s_%s", newname, "simpson");
+	out_fd = G_open_raster_new(outname, DCELL_TYPE);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	/* calculate indices */
+	for (i = 0; i < fragcount; i++) {
+	    int N = 0;
+	    int sum = 0;
+
+	    for (j = 0; j < fragcount; j++) {
+		int immi = immi_matrix[j * fragcount + i];
+
+		N += immi;
+		sum += immi * (immi - 1);
+	    }
+
+	    values[i] = (DCELL) sum / (DCELL) (N * (N - 1));
+	}
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = values[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row + 1, sy, 1);
+	}
+
+	G_free(values);
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(costmap);
+    G_free(cells);
+    G_free(fragments);
+    G_free(patch_imi);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/search.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/search.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/search.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,552 @@
+#include "local_proto.h"
+
+/* globals */
+
+int global_progress = 0;
+int pickpos_count;
+int perception_count;
+WeightedCoords *pos_arr;
+Displacement *displacements;
+Displacement *perception;
+
+/*
+   output raster with current simulation state
+ */
+void test_output(int *map, int patch, int step, int n)
+{
+    int out_fd;
+    int row, col, i;
+    char outname[GNAME_MAX];
+    DCELL *outmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_patch%d_step%d", newname, patch, step);
+
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write map */
+
+    for (i = 0; i < sx * sy; i++) {
+	outmap[i] = 0;
+    }
+
+    for (i = 0; i < n; i++) {
+	int x, y;
+	Individual *indi = indi_array + i;
+
+	x = indi->x;
+	y = indi->y;
+
+	//              fprintf(stderr, "indi%d: (%d, %d)\n", i, x, y);
+
+	outmap[x + y * sx]++;
+    }
+
+    for (i = 0; i < sx * sy; i++) {
+	if (map[i] != TYPE_NOTHING && outmap[i] == 0) {
+	    outmap[i] = -1;
+	}
+    }
+
+    /*      for(row = 0; row < sy; row++) {
+       for(col = 0; col < sx; col++) {
+       fprintf(stderr, "%0.0f", outmap[row * sx + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* write output */
+    for (row = 0; row < sy; row++) {
+	G_put_d_raster_row(out_fd, outmap + row * sx);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+    G_free(outmap);
+}
+
+/*
+   sorts cells in a fragment, so that border cells come first
+ */
+int sort_frag(Coords * frag, int size)
+{
+    int i, j;
+    Coords temp;
+
+    i = 0;
+    j = size - 1;
+
+    while (i <= j) {
+	while (frag[i].neighbors < 4 && i < size)
+	    i++;
+	while (frag[j].neighbors == 4 && j >= 0)
+	    j--;
+
+	if (i < j) {
+	    temp = frag[i];
+	    frag[i] = frag[j];
+	    frag[j] = temp;
+	}
+    }
+
+    /*      fprintf(stderr, "Sorted fragment: (%d, %d: %d)", frag->x, frag->y, frag->neighbors);
+       for(j = 1; j < size; j++) {
+       fprintf(stderr, " (%d, %d: %d)", frag[j].x, frag[j].y, frag[j].neighbors);
+       }
+       fprintf(stderr, "\n"); */
+
+    return i;
+}
+
+/*
+   picks a random direction pointing outwards a patch
+ */
+double pick_dir(int *map, Coords * frag)
+{
+    double dirs[4];
+    int i;
+    double pick;
+
+    int x = frag->x;
+    int y = frag->y;
+    int count = 0;
+
+    if (x >= sx || map[x + 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.0;
+    if (y <= 0 || map[x + (y + 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.25;
+    if (x <= 0 || map[x - 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.5;
+    if (y >= sy || map[x + (y - 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.75;
+
+    //      G_message("Picks for (%d, %d): %0.2f, %0.2f, %0.2f, %0.2f, cnt=%d", x, y, dirs[0], dirs[1], dirs[2], dirs[3], count);
+
+    pick = count * Randomf();
+
+    for (i = count - 1; i >= 0; i--) {
+	if (pick > i) {
+	    double res = 0.25 * (pick - i) + dirs[i] - 0.125;
+
+	    if (res < 0) {
+		res++;
+	    }
+	    //                      res = res < 0 ? 2 * M_PI + res : res;
+	    //                      G_message("dir = %0.2f", res);
+	    return res;
+	}
+    }
+
+    return -1;			// error
+}
+
+/*
+   initializes all individuals for a fragment
+ */
+void init_individuals(int *map, Coords * frag, int size, int n)
+{
+    int i, border_count, index;
+    Coords *cell;
+
+    border_count = sort_frag(frag, size);
+
+    //      G_message("Initializing");
+
+    for (i = 0; i < n; i++) {
+	//              G_message("border_count = %d", border_count);
+
+	/* pick border cell */
+	index = Random(border_count);
+	cell = frag + index;
+
+	indi_array[i].x = cell->x + 0.5;
+	indi_array[i].y = cell->y + 0.5;
+	indi_array[i].dir = pick_dir(map, cell);	//2 * M_PI * Randomf();
+	indi_array[i].path = 0;
+	indi_array[i].finished = 0;
+
+	//              fprintf(stderr, "indi%d: ", i);
+	//              fprintf(stderr, "x=%0.2f, y=%0.2f, dir=%0.2f, finished=%d\n",
+	//                              indi_array[i].x, indi_array[i].y, indi_array[i].dir, indi_array[i].finished);
+    }
+    //      G_message("End initialization");
+}
+
+/*
+   sets back an individual, when position is illegal
+ */
+void set_back(int *map, int indi, int frag)
+{
+    int index;
+    Coords *cell;
+    int border_count =
+	sort_frag(fragments[frag], fragments[frag + 1] - fragments[frag]);
+
+    /* pick border cell */
+    index = Random(border_count);
+    cell = fragments[frag] + index;
+
+    indi_array[indi].x = cell->x;
+    indi_array[indi].y = cell->y;
+    indi_array[indi].dir = pick_dir(map, cell);
+    indi_array[indi].finished = 0;
+}
+
+/*
+   sets displacement pixels taking advantage of symmetry
+ */
+void set_pixels(Displacement * values, int x, int y, int r)
+{
+    if (y == 0) {
+	values[0].x = x;
+	values[0].y = 0;
+	values[2 * r].x = 0;
+	values[2 * r].y = x;
+	values[4 * r].x = -x;
+	values[4 * r].y = 0;
+	values[6 * r].x = 0;
+	values[6 * r].y = -x;
+    }
+    else if (y == x) {
+	values[r].x = y;
+	values[r].y = y;
+	values[3 * r].x = -y;
+	values[3 * r].y = y;
+	values[5 * r].x = -y;
+	values[5 * r].y = -y;
+	values[7 * r].x = y;
+	values[7 * r].y = -y;
+    }
+    else if (y < x) {
+	values[r - x + y].x = x;
+	values[r - x + y].y = y;
+	values[r + x - y].x = y;
+	values[r + x - y].y = x;
+	values[3 * r - x + y].x = -y;
+	values[3 * r - x + y].y = x;
+	values[3 * r + x - y].x = -x;
+	values[3 * r + x - y].y = y;
+	values[5 * r - x + y].x = -x;
+	values[5 * r - x + y].y = -y;
+	values[5 * r + x - y].x = -y;
+	values[5 * r + x - y].y = -x;
+	values[7 * r - x + y].x = y;
+	values[7 * r - x + y].y = -x;
+	values[7 * r + x - y].x = x;
+	values[7 * r + x - y].y = -y;
+    }
+}
+
+/*
+   calculates displacements for a circle of given radius
+ */
+void calculate_displacement(Displacement * values, int radius)
+{
+    int dx = radius;
+    int dy = 0;
+    float dx_ = (float)dx - 0.5f;
+    float dy_ = (float)dy + 0.5f;
+    float f = 0.5f - (float)radius;
+
+    set_pixels(values, dx, dy, radius);
+
+    while (dx > dy) {
+	if (f < 0) {
+	    f += 2 * dy_ + 1;
+	    dy_++;
+	    dy++;
+	}
+	else {
+	    f += 1 - 2 * dx_;
+	    dx_--;
+	    dx--;
+	}
+
+	set_pixels(values, dx, dy, radius);
+    }
+}
+
+/*
+   fills a weighted array with possible next positions
+ */
+void pick_nextpos(WeightedCoords * result, int indi, int *map,
+		  DCELL * costmap, int frag)
+{
+    int i;
+    double ex_step, ex_pos;
+    Individual *individual = indi_array + indi;
+    int actx = individual->x;
+    int acty = individual->y;
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+    int pos = dir_index - 2 * step_length * step_range;
+
+    if (pos < 0) {
+	pos += 8 * step_length;
+    }
+
+    for (i = 0; i < pickpos_count; i++, pos++) {
+	result[i].x = actx + displacements[pos].x;
+	result[i].y = acty + displacements[pos].y;
+	result[i].dir = (double)pos / (8.0 * (double)step_length);
+	if (result[i].dir >= 1) {
+	    result[i].dir--;
+	}
+
+	/* if out of limits, use weight=1 until better handling */
+	if (actx < 0 || actx >= sx || acty < 0 || acty >= sy) {
+	    result[i].weight = 1;
+	}
+	else {
+	    /* get weight from costmap */
+	    result[i].weight = costmap[(int)acty * sx + (int)actx];
+	}
+    }
+
+    /* apply perception multiplicator */
+    dir_index = Round(individual->dir * 8.0 * (double)perception_range);
+    pos = dir_index - 2 * perception_range;
+    ex_step = (double)perception_range / (double)step_length;
+    ex_pos = (double)pos;
+    for (i = 0; i < pickpos_count; i++) {
+	int patch_flag = 0;
+
+	ex_pos += ex_step;
+	while (pos < ex_pos) {
+	    int x = actx + perception[pos].x;
+	    int y = acty + perception[pos].y;
+
+	    if (x >= 0 && x < sx && y >= 0 && y < sy) {
+		int val = map[x + y * sx];
+
+		patch_flag |= (val > TYPE_NOTHING && val != frag);
+	    }
+	    pos++;
+	}
+
+	if (patch_flag) {
+	    result[i].weight *= multiplicator;
+
+	}
+    }
+
+    return;
+}
+
+/*
+   performs a single step for an individual
+ */
+void indi_step(int indi, int frag, int *map, DCELL * costmap, double step)
+{
+    int i;
+    double sum;
+    Individual *individual = indi_array + indi;
+    double rnd;
+    double newx, newy, newdir;
+    int act_cell;
+
+    /* test output */
+    //      fprintf(stderr, "actpos: x = %0.2f, y = %0.2f\n", individual->x, individual->y);
+
+    /* make a step in the current direction */
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+
+    newx = individual->x + displacements[dir_index].x;
+    newy = individual->y + displacements[dir_index].y;
+
+    /* if new position is out of limits, then set back */
+    if (newx < 0 || newx >= sx || newy < 0 || newy >= sy) {
+	set_back(map, indi, frag);
+
+	return;
+    }
+
+    /* set new position */
+    individual->x = newx;
+    individual->y = newy;
+
+    /* count path of the individuum */
+    if (include_cost) {
+	individual->path += 100 / costmap[(int)newy * sx + (int)newx];
+    }
+    else {
+	individual->path++;
+    }
+
+    /* if new position is another patch, then set finished = true */
+    act_cell = map[(int)newy * sx + (int)newx];
+    if (act_cell > -1 && act_cell != frag) {
+	/* count patch immigrants for this patch */
+	patch_imi[act_cell]++;
+	immi_matrix[frag * fragcount + act_cell]++;
+	individual->finished = 1;
+
+	return;
+    }
+
+    /* write an array with possible next positions */
+    pick_nextpos(pos_arr, indi, map, costmap, frag);
+
+    /* test output */
+    /*      G_message("Nextpos array:\n");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, "(x=%d,y=%d,dir=%0.2f,weight=%0.2f)\n", 
+       pos_arr[i].x, pos_arr[i].y, pos_arr[i].dir, pos_arr[i].weight);
+       } */
+
+    /* if no next position is possible, then set back */
+    sum = 0;
+    for (i = 0; i < pickpos_count; i++) {
+	sum += pos_arr[i].weight;
+    }
+    if (sum == 0) {
+	set_back(map, indi, frag);
+
+	return;
+    }
+
+    /* pick a next position randomly, considering the weights */
+    pos_arr[0].weight = pos_arr[0].weight / sum;
+    for (i = 1; i < pickpos_count; i++) {
+	pos_arr[i].weight = pos_arr[i - 1].weight + pos_arr[i].weight / sum;
+    }
+    rnd = Randomf();
+    for (i = 0; i < pickpos_count; i++) {
+	if (pos_arr[i].weight > rnd)
+	    break;
+    }
+    individual->dir = pos_arr[i].dir;
+
+    /* test output */
+    //      fprintf(stderr, "pick: x = %0.2f, y = %0.2f\n\n", newx, newy);
+
+    return;
+}
+
+/*
+   performs a search run for a single fragment
+ */
+DCELL frag_run(int *map, DCELL * costmap, int frag)
+{
+    int i;
+    DCELL res = 0;
+    int step_cnt = 0;
+    int finished_cnt = 0;
+    int limit = ceil(n * percent / 100);
+
+    //      fprintf(stderr, "\nstarting run:\n");
+    //      fprintf(stderr, "limit = %d\n", limit); 
+
+    init_individuals(map, fragments[frag],
+		     fragments[frag + 1] - fragments[frag], n);
+
+    /* perform a step for each individual */
+    finished_cnt = 0;
+    while (finished_cnt < limit && step_cnt <= maxsteps) {
+	if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	    test_output(map, frag, step_cnt, n);
+	}
+
+	for (i = 0; i < n; i++) {
+	    if (!indi_array[i].finished) {
+		indi_step(i, frag, map, costmap, step_length);
+
+		/* test if new individuum finished */
+		if (indi_array[i].finished) {
+		    finished_cnt++;
+
+		    global_progress++;
+		    G_percent(global_progress, fragcount * limit, 1);
+
+		    if (finished_cnt >= limit)
+			break;
+		}
+	    }
+	}
+
+	step_cnt++;
+    }
+
+    G_percent(frag + 1, fragcount, 1);
+
+    if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	test_output(map, frag, step_cnt, n);
+    }
+
+    //      fprintf(stderr, "stepcnt = %d\n", step_cnt);
+    return (DCELL) step_cnt;
+}
+
+/*
+   performs a search run for each fragment
+ */
+void perform_search(DCELL * values, int *map, DCELL * costmap,
+		    f_statmethod * stats, int stat_count)
+{
+    int fragment, i;
+    int steps;
+    f_statmethod func;
+
+    /* allocate paths array */
+    DCELL *indi_paths = (DCELL *) G_malloc(n * sizeof(DCELL));
+
+    /* allocate individuals array */
+    indi_array = (Individual *) G_malloc(n * sizeof(Individual));
+
+    /* allocate pickpos result array */
+    pickpos_count = 4 * step_length * step_range + 1;
+    pos_arr =
+	(WeightedCoords *) G_malloc(pickpos_count * sizeof(WeightedCoords));
+
+    /* allocate displacement arrays */
+    displacements =
+	(Displacement *) G_malloc(16 * step_length * sizeof(Displacement));
+    perception =
+	(Displacement *) G_malloc(16 * perception_range *
+				  sizeof(Displacement));
+
+    /* calculate displacements */
+    calculate_displacement(displacements, step_length);
+    memcpy(displacements + 8 * step_length, displacements,
+	   8 * step_length * sizeof(Displacement));
+
+    calculate_displacement(perception, perception_range);
+    memcpy(perception + 8 * perception_range, perception,
+	   8 * perception_range * sizeof(Displacement));
+
+    /*      fprintf(stderr, "Displacements:");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, " (%d, %d)", displacements[i].x, displacements[i].y);
+       } */
+
+    memset(patch_imi, 0, fragcount * sizeof(int));
+
+    /* allocate immi_matrix and mig_matrix */
+    immi_matrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+    memset(immi_matrix, 0, fragcount * fragcount * sizeof(int));
+    mig_matrix = (int *)G_malloc(fragcount * fragcount * sizeof(int));
+    memset(mig_matrix, 0, fragcount * fragcount * sizeof(int));
+
+    /* perform a search run for each fragment */
+    for (fragment = 0; fragment < fragcount; fragment++) {
+	steps = frag_run(map, costmap, fragment);
+
+	for (i = 0; i < n; i++) {
+	    indi_paths[i] = indi_array[i].path;
+	}
+
+	for (i = 0; i < stat_count; i++) {
+	    func = stats[i];
+	    values[i * fragcount + fragment] = func(indi_paths, n);
+	}
+    }
+
+    G_free(indi_paths);
+    G_free(indi_array);
+    G_free(pos_arr);
+    G_free(displacements);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/search.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.searchtime.iter
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,39 @@
+Individual-based dispersal model for connectivity analysis (time-based) using iterative removal of patches 
+<h2>DESCRIPTION</h2>
+
+This modules aims at generating sampling areas which are only known by the
+coordinate of one corner. The input are single points, while the output are
+areas representing the corresponding area for each of the single
+points/coordinates.
+
+<h2>NOTES</h2>
+
+The areas can only be generated horizontally, not diagonal. This can be added
+as wish and might be implemented in the future.
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.searchtime.html">r.pi.searchtime</a>,
+<a href="r.pi.searchtime.mw.html">r.pi.searchtime.mw</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann <br>
+Department of Remote Sensing <br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,103 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    DCELL path;
+    int finished;
+} Individual;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    double weight;
+} WeightedCoords;
+
+typedef struct
+{
+    int x, y;
+} Displacement;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* search.c */
+void perform_search(DCELL * values, int *map, DCELL * costmap,
+		    f_statmethod * stats, int stat_count);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* global parameters */
+GLOBAL int sx, sy;
+GLOBAL int keyval;
+GLOBAL int n;
+GLOBAL double percent;
+GLOBAL int maxsteps;
+GLOBAL int step_length;
+GLOBAL int out_freq;
+GLOBAL int include_cost;
+GLOBAL int perception_range;
+GLOBAL double multiplicator;
+
+/* global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+GLOBAL Individual *indi_array;
+GLOBAL int *patch_imi;
+GLOBAL char *deleted_arr;
+
+GLOBAL char *newname, *newmapset;
+GLOBAL char *iminame, *imimapset;
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,638 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.searchtime.iter
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Individual-based dispersal model for connectivity analysis 
+ *                              - time-based - within iterative removal of patches. Based on r.pi.searchtime
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* costmap */
+    char *costname, *costmapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+
+    /* parameters */
+    int stats[GNAME_MAX];
+    f_statmethod *methods;
+    int stat_count;
+
+    int dif_stats[GNAME_MAX];
+    int dif_stat_count;
+
+    /* maps */
+    int *map;
+    DCELL *costmap;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    DCELL *values;
+    DCELL *output_values;
+    DCELL *dummy;
+    int neighb_count;
+    int i, j, k;
+    Coords *p;
+    char *str;
+    int method, difmethod;
+    char outname[GNAME_MAX];
+    int frag, actpos;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *output, *out_immi;
+	struct Option *keyval, *step_length, *perception, *multiplicator, *n;
+	struct Option *percent, *stats, *dif_stats, *maxsteps, *out_freq;
+	struct Option *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *cost;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Individual-based dispersal model for connectivity analysis (time-based) using iterative removal of patches");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = NO;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->description =
+	_("Name of the costmap with values from 0-100");
+    parm.costmap->guisection = _("Optional");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.out_immi = G_define_option();
+    parm.out_immi->key = "out_immi";
+    parm.out_immi->type = TYPE_STRING;
+    parm.out_immi->required = NO;
+    parm.out_immi->gisprompt = "new,cell,raster";
+    parm.out_immi->description =
+	_("Name of the optional raster file for patch immigrants count");
+    parm.out_immi->guisection = _("Optional");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Category value of the patches");
+    parm.keyval->guisection = _("Required");
+
+    parm.step_length = G_define_option();
+    parm.step_length->key = "step_length";
+    parm.step_length->type = TYPE_INTEGER;
+    parm.step_length->required = YES;
+    parm.step_length->description =
+	_("Length of a single step measured in pixels");
+    parm.step_length->guisection = _("Required");
+
+    parm.perception = G_define_option();
+    parm.perception->key = "perception";
+    parm.perception->type = TYPE_INTEGER;
+    parm.perception->required = NO;
+    parm.perception->description = _("Perception range");
+    parm.perception->guisection = _("Optional");
+
+    parm.multiplicator = G_define_option();
+    parm.multiplicator->key = "multiplicator";
+    parm.multiplicator->type = TYPE_DOUBLE;
+    parm.multiplicator->required = NO;
+    parm.multiplicator->description = _("Attractivity of patches [1-inf]");
+    parm.multiplicator->guisection = _("Optional");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->description = _("Number of individuals");
+    parm.n->guisection = _("Required");
+
+    parm.percent = G_define_option();
+    parm.percent->key = "percent";
+    parm.percent->type = TYPE_DOUBLE;
+    parm.percent->required = YES;
+    parm.percent->description =
+	_("Percentage of individuals which must have arrived successfully"
+	  " to stop the model-run");
+    parm.percent->guisection = _("Required");
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    parm.stats->multiple = YES;
+    str = parm.stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[n].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the pathlengths of the individuals");
+    parm.stats->guisection = _("Required");
+
+    parm.dif_stats = G_define_option();
+    parm.dif_stats->key = "dif_stats";
+    parm.dif_stats->type = TYPE_STRING;
+    parm.dif_stats->required = YES;
+    parm.dif_stats->multiple = YES;
+    str = parm.dif_stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[n].name);
+    }
+    parm.dif_stats->description =
+	_("Statistical method to perform on the difference values");
+    parm.dif_stats->guisection = _("Required");
+
+    parm.maxsteps = G_define_option();
+    parm.maxsteps->key = "maxsteps";
+    parm.maxsteps->type = TYPE_INTEGER;
+    parm.maxsteps->required = NO;
+    parm.maxsteps->description = _("Maximum steps for each individual");
+    parm.maxsteps->guisection = _("Optional");
+
+    parm.out_freq = G_define_option();
+    parm.out_freq->key = "out_freq";
+    parm.out_freq->type = TYPE_INTEGER;
+    parm.out_freq->required = NO;
+    parm.out_freq->description =
+	_("Output an intermediate state of simulation each [out_freq] steps");
+    parm.out_freq->guisection = _("Optional");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+    parm.title->guisection = _("Optional");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+    flag.adjacent->guisection = _("Required");
+
+    flag.cost = G_define_flag();
+    flag.cost->key = 'c';
+    flag.cost->description =
+	_("Include cost of the path in the calculation of steps");
+    flag.cost->guisection = _("Required");
+
+    if (G_parser(argc, argv))
+	    exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    srand(time(NULL));
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of costmap */
+    costname = parm.costmap->answer;
+
+    /* test costmap existance */
+    if (costname && (costmapset = G_find_cell2(costname, "")) == NULL)
+	    G_fatal_error(_("Raster map <%s> not found"), costname);
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get step_length */
+    sscanf(parm.step_length->answer, "%d", &step_length);
+
+    /* get perception_range */
+    if (parm.perception->answer) {
+	sscanf(parm.perception->answer, "%d", &perception_range);
+    }
+    else {
+	perception_range = step_length;
+    }
+
+    /* get multiplicator */
+    if (parm.multiplicator->answer) {
+	sscanf(parm.multiplicator->answer, "%lf", &multiplicator);
+    }
+    else {
+	multiplicator = 1.0;
+    }
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get percent */
+    sscanf(parm.percent->answer, "%lf", &percent);
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get include_cost */
+    include_cost = flag.cost->answer;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* check if the immigrants file name is correct */
+    iminame = parm.out_immi->answer;
+    if (iminame && G_legal_filename(iminame) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), iminame);
+    imimapset = G_mapset();
+
+    map_type = DCELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* get maxsteps */
+    if (parm.maxsteps->answer != NULL) {
+	sscanf(parm.maxsteps->answer, "%d", &maxsteps);
+    }
+    else {
+	maxsteps = 10 * sqrt(sx * sx + sy * sy) / step_length;
+    }
+
+    /* get out_freq */
+    if (parm.out_freq->answer != NULL) {
+	sscanf(parm.out_freq->answer, "%d", &out_freq);
+    }
+    else {
+	out_freq = 0;
+    }
+
+    /* scan all statmethod answers */
+    stat_count = 0;
+    while (parm.stats->answers[stat_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (str = statmethods[method].name); method++)
+	    if (strcmp(str, parm.stats->answers[stat_count]) == 0)
+		break;
+	if (!str) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.stats->key, parm.stats->answers[stat_count],
+		      parm.stats->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	stats[stat_count] = method;
+
+	stat_count++;
+    }
+
+    /* scan all dif_stats answers */
+    dif_stat_count = 0;
+    while (parm.dif_stats->answers[dif_stat_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (str = statmethods[method].name) != NULL; method++)
+	    if (strcmp(str, parm.dif_stats->answers[dif_stat_count]) == 0)
+		break;
+	if (!str) {
+	    G_warning("<%s=%s> unknown %s",
+		      parm.dif_stats->key,
+		      parm.dif_stats->answers[stat_count],
+		      parm.dif_stats->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	dif_stats[dif_stat_count] = method;
+
+	dif_stat_count++;
+    }
+
+    /* test output */
+    /*      fprintf(stderr, "TEST OUTPUT : \n");
+       fprintf(stderr, "input = %s\n", oldname);
+       fprintf(stderr, "output = %s\n", newname);
+       fprintf(stderr, "costmap = %s\n", costname);
+       fprintf(stderr, "keyval = %d\n", keyval);
+       fprintf(stderr, "step_length = %d\n", step_length);
+       fprintf(stderr, "n = %d\n", n);
+       fprintf(stderr, "percent = %0.2f\n", percent);
+       fprintf(stderr, "maxsteps = %d\n", maxsteps); 
+       fprintf(stderr, "Difference stats: ");
+       for(i = 0; i < dif_stat_count; i++) {
+       if(i > 0) fprintf(stderr, ",");
+       fprintf(stderr, "%s", statmethods[dif_stats[i]].name);
+       }
+       fprintf(stderr, "\n"); */
+
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    costmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    d_res = G_allocate_d_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row, sy, 2);
+    }
+    G_percent(1, 1, 2);
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if costmap specified, read costmap */
+    if (costname != NULL) {
+	/* open costmap */
+	in_fd = G_open_cell_old(costname, costmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), costname);
+
+	/* read costmap */
+	G_message("Reading costmap:");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		costmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row, sy, 2);
+	}
+	G_percent(1, 1, 2);
+
+	/* close costmap */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill costmap with 100 */
+	for (i = 0; i < sx * sy; i++) {
+	    costmap[i] = 100;
+	}
+    }
+
+    /* test output */
+    /*      G_message("costmap:\n");
+       print_d_buffer(costmap, sx, sy); */
+
+    /* find fragments */
+    writeFragments(map, sy, sx, neighb_count);
+
+    /* test output */
+    /*      print_fragments(); */
+
+    /* mark each fragment with its number */
+    for (i = 0; i < sx * sy; i++) {
+	map[i] = -1;
+    }
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    map[p->y * sx + p->x] = i;
+	}
+    }
+
+    /* test output */
+    /*      print_buffer(map, sx, sy); */
+    G_message("Performing search runs:");
+
+    /* allocate space for patch immigrants */
+    patch_imi = (int *)G_malloc(fragcount * sizeof(int));
+
+    /* allocate memory for deleted patches array */
+    deleted_arr = (char *)G_malloc(fragcount * sizeof(char));
+    memset(deleted_arr, 0, fragcount * sizeof(char));
+
+    /* fill methods array */
+    methods = (f_statmethod *) G_malloc(stat_count * sizeof(f_statmethod));
+    for (method = 0; method < stat_count; method++) {
+	methods[method] = statmethods[stats[method]].method;
+    }
+
+    /* perform search */
+    values =
+	(DCELL *) G_malloc((fragcount + 1) * fragcount * stat_count *
+			   sizeof(DCELL));
+
+    /* first reference run */
+    perform_search(values, map, costmap, methods, stat_count);
+
+    /* then runs with one patch deleted */
+    for (i = 0; i < fragcount; i++) {
+	deleted_arr[i] = 1;
+	perform_search(values + (i + 1) * fragcount * stat_count, map,
+		       costmap, methods, stat_count);
+	deleted_arr[i] = 0;
+
+	/* calculate differences */
+	for (j = 0; j < fragcount * stat_count; j++) {
+	    values[(i + 1) * fragcount * stat_count + j] -= values[j];
+	}
+    }
+    G_percent(1, 1, 1);
+
+    /* test output */
+    /*G_message("Results:");
+       for(k = 0; k <= fragcount; k++) {
+       for(j = 0; j < stat_count; j++) {
+       G_message("%s: ", statmethods[stats[j]].name);
+       for(i = 0; i < fragcount; i++) {
+       fprintf(stderr, "frag%d: %0.2f ", i, values[(k * stat_count + j) * fragcount + i]);
+       }
+       fprintf(stderr, "\n");
+       }
+       }
+       G_message(""); */
+
+    /* allocate output array and dummy for applying statmethod */
+    output_values =
+	(DCELL *) G_malloc(stat_count * dif_stat_count * fragcount *
+			   sizeof(DCELL));
+    dummy = (DCELL *) G_malloc((fragcount - 1) * sizeof(DCELL));
+
+    /* fill output array */
+    /* output_values: difstat1( stat1(patch1, patch2, ...), stat2(), ... ), difstat2(), ... */
+    actpos = stat_count * fragcount;
+    for (frag = 0; frag < fragcount; frag++) {
+	for (method = 0; method < stat_count; method++) {
+	    /* fill dummy ignoring own frag value */
+	    memcpy(dummy, values + actpos, frag * sizeof(DCELL));
+	    memcpy(dummy + frag, values + actpos + frag + 1,
+		   (fragcount - frag - 1) * sizeof(DCELL));
+
+	    for (difmethod = 0; difmethod < dif_stat_count; difmethod++) {
+		f_statmethod func = statmethods[dif_stats[difmethod]].method;
+		DCELL val = func(dummy, fragcount - 1);
+
+		output_values[(difmethod * stat_count + method) * fragcount +
+			      frag] = val;
+	    }
+
+	    actpos += fragcount;
+	}
+    }
+
+    /* test output */
+    /*G_message("output_values:\n");
+       for(k = 0; k < dif_stat_count; k++) {
+       G_message("%s: ", statmethods[dif_stats[k]].name);           
+       for(j = 0; j < stat_count; j++) {
+       G_message("%s: ", statmethods[stats[j]].name);
+       for(i = 0; i < fragcount; i++) {
+       fprintf(stderr, "frag%d: %0.2f ", i, output_values[(k * stat_count + j) * fragcount + i]);
+       }
+       fprintf(stderr, "\n");
+       }
+       }
+       G_message(""); */
+
+    G_message("Writing output...");
+    for (difmethod = 0; difmethod < dif_stat_count; difmethod++) {
+	for (method = 0; method < stat_count; method++) {
+
+	    /* open the new cellfile  */
+	    sprintf(outname, "%s_%s_%s", newname,
+		    statmethods[stats[method]].suffix,
+		    statmethods[dif_stats[difmethod]].suffix);
+	    out_fd = G_open_raster_new(outname, map_type);
+	    if (out_fd < 0)
+		    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	    /* write the output file */
+	    for (row = 0; row < sy; row++) {
+		G_set_d_null_value(d_res, sx);
+
+		for (i = 0; i < fragcount; i++) {
+		    for (p = fragments[i]; p < fragments[i + 1]; p++) {
+			if (p->y == row) {
+			    d_res[p->x] =
+				output_values[(difmethod * stat_count +
+					       method) * fragcount + i];
+			}
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, d_res);
+
+	    }
+
+	    /* close output */
+	    G_close_cell(out_fd);
+	}
+    }
+    G_percent(100, 100, 2);
+
+    /* open the new cellfile  */
+    if (iminame) {
+	out_fd = G_open_raster_new(iminame, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), iminame);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = patch_imi[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row, sy, 2);
+	}
+
+	G_percent(100, 100, 2);
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* free allocated resources */
+    G_free(map);
+    G_free(costmap);
+    G_free(cells);
+    G_free(fragments);
+    G_free(patch_imi);
+    G_free(deleted_arr);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/search.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/search.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/search.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,549 @@
+#include "local_proto.h"
+
+/* globals */
+
+int global_progress = 0;
+int pickpos_count;
+int perception_count;
+WeightedCoords *pos_arr;
+Displacement *displacements;
+Displacement *perception;
+
+/*
+   output raster with current simulation state
+ */
+void test_output(int *map, int patch, int step, int n)
+{
+    int out_fd;
+    int row, col, i;
+    char outname[GNAME_MAX];
+    DCELL *outmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+
+    /* open the new cellfile  */
+    sprintf(outname, "%s_patch%d_step%d", newname, patch, step);
+
+    out_fd = G_open_raster_new(outname, DCELL_TYPE);
+    if (out_fd < 0) {
+	G_fatal_error(_("can't create new cell file <%s> in mapset %s\n"),
+		      outname, newmapset);
+	exit(EXIT_FAILURE);
+    }
+
+    /* write map */
+
+    for (i = 0; i < sx * sy; i++) {
+	outmap[i] = 0;
+    }
+
+    for (i = 0; i < n; i++) {
+	int x, y;
+	Individual *indi = indi_array + i;
+
+	x = indi->x;
+	y = indi->y;
+
+	//              fprintf(stderr, "indi%d: (%d, %d)\n", i, x, y);
+
+	outmap[x + y * sx]++;
+    }
+
+    for (i = 0; i < sx * sy; i++) {
+	if (map[i] != TYPE_NOTHING && outmap[i] == 0) {
+	    outmap[i] = -1;
+	}
+    }
+
+    /*      for(row = 0; row < sy; row++) {
+       for(col = 0; col < sx; col++) {
+       fprintf(stderr, "%0.0f", outmap[row * sx + col]);
+       }
+       fprintf(stderr, "\n");
+       } */
+
+    /* write output */
+    for (row = 0; row < sy; row++) {
+	G_put_d_raster_row(out_fd, outmap + row * sx);
+    }
+
+    /* close output */
+    G_close_cell(out_fd);
+    G_free(outmap);
+}
+
+/*
+   sorts cells in a fragment, so that border cells come first
+ */
+int sort_frag(Coords * frag, int size)
+{
+    int i, j;
+    Coords temp;
+
+    i = 0;
+    j = size - 1;
+
+    while (i <= j) {
+	while (frag[i].neighbors < 4 && i < size)
+	    i++;
+	while (frag[j].neighbors == 4 && j >= 0)
+	    j--;
+
+	if (i < j) {
+	    temp = frag[i];
+	    frag[i] = frag[j];
+	    frag[j] = temp;
+	}
+    }
+
+    /*      fprintf(stderr, "Sorted fragment: (%d, %d: %d)", frag->x, frag->y, frag->neighbors);
+       for(j = 1; j < size; j++) {
+       fprintf(stderr, " (%d, %d: %d)", frag[j].x, frag[j].y, frag[j].neighbors);
+       }
+       fprintf(stderr, "\n"); */
+
+    return i;
+}
+
+/*
+   picks a random direction pointing outwards a patch
+ */
+double pick_dir(int *map, Coords * frag)
+{
+    double dirs[4];
+    int i;
+    double pick;
+
+    int x = frag->x;
+    int y = frag->y;
+    int count = 0;
+
+    if (x >= sx || map[x + 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.0;
+    if (y <= 0 || map[x + (y + 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.25;
+    if (x <= 0 || map[x - 1 + y * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.5;
+    if (y >= sy || map[x + (y - 1) * sx] == TYPE_NOTHING)
+	dirs[count++] = 0.75;
+
+    //      G_message("Picks for (%d, %d): %0.2f, %0.2f, %0.2f, %0.2f, cnt=%d", x, y, dirs[0], dirs[1], dirs[2], dirs[3], count);
+
+    pick = count * Randomf();
+
+    for (i = count - 1; i >= 0; i--) {
+	if (pick > i) {
+	    double res = 0.25 * (pick - i) + dirs[i] - 0.125;
+
+	    if (res < 0) {
+		res++;
+	    }
+	    //                      res = res < 0 ? 2 * M_PI + res : res;
+	    //                      G_message("dir = %0.2f", res);
+	    return res;
+	}
+    }
+
+    return -1;			// error
+}
+
+/*
+   initializes all individuals for a fragment
+ */
+void init_individuals(int *map, Coords * frag, int size, int n)
+{
+    int i, border_count, index;
+    Coords *cell;
+
+    border_count = sort_frag(frag, size);
+
+    //      G_message("Initializing");
+
+    for (i = 0; i < n; i++) {
+	//              G_message("border_count = %d", border_count);
+
+	/* pick border cell */
+	index = Random(border_count);
+	cell = frag + index;
+
+	indi_array[i].x = cell->x + 0.5;
+	indi_array[i].y = cell->y + 0.5;
+	indi_array[i].dir = pick_dir(map, cell);	//2 * M_PI * Randomf();
+	indi_array[i].path = 0;
+	indi_array[i].finished = 0;
+
+	//              fprintf(stderr, "indi%d: ", i);
+	//              fprintf(stderr, "x=%0.2f, y=%0.2f, dir=%0.2f, finished=%d\n",
+	//                              indi_array[i].x, indi_array[i].y, indi_array[i].dir, indi_array[i].finished);
+    }
+    //      G_message("End initialization");
+}
+
+/*
+   sets back an individual, when position is illegal
+ */
+void set_back(int *map, int indi, int frag)
+{
+    int index;
+    Coords *cell;
+    int border_count =
+	sort_frag(fragments[frag], fragments[frag + 1] - fragments[frag]);
+
+    /* pick border cell */
+    index = Random(border_count);
+    cell = fragments[frag] + index;
+
+    indi_array[indi].x = cell->x;
+    indi_array[indi].y = cell->y;
+    indi_array[indi].dir = pick_dir(map, cell);
+    indi_array[indi].finished = 0;
+}
+
+/*
+   sets displacement pixels taking advantage of symmetry
+ */
+void set_pixels(Displacement * values, int x, int y, int r)
+{
+    if (y == 0) {
+	values[0].x = x;
+	values[0].y = 0;
+	values[2 * r].x = 0;
+	values[2 * r].y = x;
+	values[4 * r].x = -x;
+	values[4 * r].y = 0;
+	values[6 * r].x = 0;
+	values[6 * r].y = -x;
+    }
+    else if (y == x) {
+	values[r].x = y;
+	values[r].y = y;
+	values[3 * r].x = -y;
+	values[3 * r].y = y;
+	values[5 * r].x = -y;
+	values[5 * r].y = -y;
+	values[7 * r].x = y;
+	values[7 * r].y = -y;
+    }
+    else if (y < x) {
+	values[r - x + y].x = x;
+	values[r - x + y].y = y;
+	values[r + x - y].x = y;
+	values[r + x - y].y = x;
+	values[3 * r - x + y].x = -y;
+	values[3 * r - x + y].y = x;
+	values[3 * r + x - y].x = -x;
+	values[3 * r + x - y].y = y;
+	values[5 * r - x + y].x = -x;
+	values[5 * r - x + y].y = -y;
+	values[5 * r + x - y].x = -y;
+	values[5 * r + x - y].y = -x;
+	values[7 * r - x + y].x = y;
+	values[7 * r - x + y].y = -x;
+	values[7 * r + x - y].x = x;
+	values[7 * r + x - y].y = -y;
+    }
+}
+
+/*
+   calculates displacements for a circle of given radius
+ */
+void calculate_displacement(Displacement * values, int radius)
+{
+    int dx = radius;
+    int dy = 0;
+    float dx_ = (float)dx - 0.5f;
+    float dy_ = (float)dy + 0.5f;
+    float f = 0.5f - (float)radius;
+
+    set_pixels(values, dx, dy, radius);
+
+    while (dx > dy) {
+	if (f < 0) {
+	    f += 2 * dy_ + 1;
+	    dy_++;
+	    dy++;
+	}
+	else {
+	    f += 1 - 2 * dx_;
+	    dx_--;
+	    dx--;
+	}
+
+	set_pixels(values, dx, dy, radius);
+    }
+}
+
+/*
+   fills a weighted array with possible next positions
+ */
+void pick_nextpos(WeightedCoords * result, int indi, int *map,
+		  DCELL * costmap, int frag)
+{
+    int i;
+    double ex_step, ex_pos;
+    Individual *individual = indi_array + indi;
+    int actx = individual->x;
+    int acty = individual->y;
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+    int pos = dir_index - 2 * step_length;
+
+    if (pos < 0) {
+	pos += 8 * step_length;
+    }
+
+    for (i = 0; i < pickpos_count; i++, pos++) {
+	result[i].x = actx + displacements[pos].x;
+	result[i].y = acty + displacements[pos].y;
+	result[i].dir = (double)pos / (8.0 * (double)step_length);
+	if (result[i].dir >= 1) {
+	    result[i].dir--;
+	}
+
+	/* if out of limits, use weight=1 until better handling */
+	if (actx < 0 || actx >= sx || acty < 0 || acty >= sy) {
+	    result[i].weight = 1;
+	}
+	else {
+	    /* get weight from costmap */
+	    result[i].weight = costmap[(int)acty * sx + (int)actx];
+	}
+    }
+
+    /* apply perception multiplicator */
+    dir_index = Round(individual->dir * 8.0 * (double)perception_range);
+    pos = dir_index - 2 * perception_range;
+    ex_step = (double)perception_range / (double)step_length;
+    ex_pos = (double)pos;
+    for (i = 0; i < pickpos_count; i++) {
+	int patch_flag = 0;
+
+	ex_pos += ex_step;
+	while (pos < ex_pos) {
+	    int x = actx + perception[pos].x;
+	    int y = acty + perception[pos].y;
+
+	    if (x >= 0 && x < sx && y >= 0 && y < sy) {
+		int val = map[x + y * sx];
+
+		patch_flag |= (val > TYPE_NOTHING && val != frag &&
+			       !deleted_arr[val]);
+	    }
+	    pos++;
+	}
+
+	if (patch_flag) {
+	    result[i].weight *= multiplicator;
+
+	}
+    }
+
+    return;
+}
+
+/*
+   performs a single step for an individual
+ */
+void indi_step(int indi, int frag, int *map, DCELL * costmap, double step)
+{
+    int i;
+    double sum;
+    Individual *individual = indi_array + indi;
+    double rnd;
+    double newx, newy, newdir;
+    int act_cell;
+
+    /* test output */
+    //      fprintf(stderr, "actpos: x = %0.2f, y = %0.2f\n", individual->x, individual->y);
+
+    /* write an array with possible next positions */
+    pick_nextpos(pos_arr, indi, map, costmap, frag);
+
+    /* test output */
+    /*      G_message("Nextpos array:\n");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, "(x=%d,y=%d,dir=%0.2f,weight=%0.2f)\n", 
+       pos_arr[i].x, pos_arr[i].y, pos_arr[i].dir, pos_arr[i].weight);
+       } */
+
+    /* if no next position is possible, then set back */
+    sum = 0;
+    for (i = 0; i < pickpos_count; i++) {
+	sum += pos_arr[i].weight;
+    }
+    if (sum == 0) {
+	set_back(map, indi, frag);
+
+	return;
+    }
+
+    /* pick a next position randomly, considering the weights */
+    pos_arr[0].weight = pos_arr[0].weight / sum;
+    for (i = 1; i < pickpos_count; i++) {
+	pos_arr[i].weight = pos_arr[i - 1].weight + pos_arr[i].weight / sum;
+    }
+    rnd = Randomf();
+    for (i = 0; i < pickpos_count; i++) {
+	if (pos_arr[i].weight > rnd)
+	    break;
+    }
+    newx = pos_arr[i].x;
+    newy = pos_arr[i].y;
+    newdir = pos_arr[i].dir;
+
+    /* test output */
+    //      fprintf(stderr, "pick: x = %0.2f, y = %0.2f\n\n", newx, newy);
+
+    /* if new position is out of limits, then set back */
+    if (newx < 0 || newx >= sx || newy < 0 || newy >= sy) {
+	set_back(map, indi, frag);
+
+	return;
+    }
+
+    /* set new position */
+    individual->x = newx;
+    individual->y = newy;
+
+    /* count path of the individuum */
+    if (include_cost) {
+	individual->path += 100 / costmap[(int)newy * sx + (int)newx];
+    }
+    else {
+	individual->path++;
+    }
+    individual->dir = newdir;
+
+    /* if new position is an other patch and patch is not deleted, then set finished = true */
+    act_cell = map[(int)newy * sx + (int)newx];
+    if (act_cell > -1 && act_cell != frag && !deleted_arr[act_cell]) {
+	/* count patch immigrants for this patch */
+	patch_imi[act_cell]++;
+	individual->finished = 1;
+    }
+
+    return;
+}
+
+/*
+   performs a search run for a single fragment
+ */
+DCELL frag_run(int *map, DCELL * costmap, int frag)
+{
+    int i;
+    DCELL res = 0;
+    int step_cnt = 0;
+    int finished_cnt = 0;
+    int limit = ceil(n * percent / 100);
+
+    //      fprintf(stderr, "\nstarting run:\n");
+    //      fprintf(stderr, "limit = %d\n", limit); 
+
+    init_individuals(map, fragments[frag],
+		     fragments[frag + 1] - fragments[frag], n);
+
+    /* perform a step for each individual */
+    finished_cnt = 0;
+    while (finished_cnt < limit && step_cnt <= maxsteps) {
+	if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	    test_output(map, frag, step_cnt, n);
+	}
+
+	for (i = 0; i < n; i++) {
+	    if (!indi_array[i].finished) {
+		indi_step(i, frag, map, costmap, step_length);
+
+		/* test if new individuum finished */
+		if (indi_array[i].finished) {
+		    finished_cnt++;
+
+		    global_progress++;
+		    G_percent(global_progress,
+			      (fragcount + 1) * fragcount * limit, 1);
+
+		    if (finished_cnt >= limit)
+			break;
+		}
+	    }
+	}
+
+	step_cnt++;
+    }
+
+    if (out_freq > 0 && (step_cnt % out_freq == 0)) {
+	test_output(map, frag, step_cnt, n);
+    }
+
+    //      fprintf(stderr, "stepcnt = %d\n", step_cnt);
+    return (DCELL) step_cnt;
+}
+
+/*
+   performs a search run for each fragment
+
+   output in "values": ( stat1(patch1, patch2, patch3, ...), stat2(patch1, patch2, ...) )
+ */
+void perform_search(DCELL * values, int *map, DCELL * costmap,
+		    f_statmethod * stats, int stat_count)
+{
+    int fragment, i;
+    int steps;
+    f_statmethod func;
+
+    /* allocate paths array */
+    DCELL *indi_paths = (DCELL *) G_malloc(n * sizeof(DCELL));
+
+    /* allocate individuals array */
+    indi_array = (Individual *) G_malloc(n * sizeof(Individual));
+
+    /* allocate pickpos result array */
+    pickpos_count = 4 * step_length + 1;
+    pos_arr =
+	(WeightedCoords *) G_malloc(pickpos_count * sizeof(WeightedCoords));
+
+    /* allocate displacement arrays */
+    displacements =
+	(Displacement *) G_malloc(16 * step_length * sizeof(Displacement));
+    perception =
+	(Displacement *) G_malloc(16 * perception_range *
+				  sizeof(Displacement));
+
+    /* calculate displacements */
+    calculate_displacement(displacements, step_length);
+    memcpy(displacements + 8 * step_length, displacements,
+	   8 * step_length * sizeof(Displacement));
+
+    calculate_displacement(perception, perception_range);
+    memcpy(perception + 8 * perception_range, perception,
+	   8 * perception_range * sizeof(Displacement));
+
+    /*      fprintf(stderr, "Displacements:");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, " (%d, %d)", displacements[i].x, displacements[i].y);
+       } */
+
+    /* initialize patch imigrants array */
+    memset(patch_imi, 0, fragcount * sizeof(int));
+
+    /* perform a search run for each fragment */
+    for (fragment = 0; fragment < fragcount; fragment++) {
+	steps = frag_run(map, costmap, fragment);
+
+	for (i = 0; i < n; i++) {
+	    indi_paths[i] = indi_array[i].path;
+	}
+
+	for (i = 0; i < stat_count; i++) {
+	    func = stats[i];
+	    values[i * fragcount + fragment] = func(indi_paths, n);
+	}
+    }
+
+    /*G_message("Values");
+       for(i = 0; i < fragcount * stat_count; i++) {
+       fprintf(stderr, "%0.2f ", values[i]);
+       }
+       G_message(""); */
+
+    G_free(indi_paths);
+    G_free(indi_array);
+    G_free(pos_arr);
+    G_free(displacements);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/search.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.iter/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.iter/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.iter/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.iter/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/Makefile
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/Makefile	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/Makefile	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.pi.searchtime.mw
+
+LIBES = $(STATSLIB) $(GISLIB)
+DEPENDENCIES = $(STATSDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/Makefile
___________________________________________________________________
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/description.html
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/description.html	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/description.html	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,35 @@
+<h2>DESCRIPTION</h2>
+
+Individual-based dispersal model for connectivity analysis (time-based)
+using moving window.
+
+<h2>NOTES</h2>
+
+...
+
+<h2>EXAMPLE</h2>
+
+An example for the North Carolina sample dataset:
+
+<div class="code"><pre>
+g.region -d
+...
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r.pi.searchtime.html">r.pi.searchtime</a>,
+<a href="r.pi.searchtime.iter.html">r.pi.searchtime.iter</a>,
+<a href="r.pi.html">r.pi</a>
+</em>
+
+<h2>AUTHORS</h2>
+Programming: Elshad Shirinov<br>
+Scientific concept: Dr. Martin Wegmann <br>
+Department of Remote Sensing <br>
+Remote Sensing and Biodiversity Unit<br>
+University of Wuerzburg, Germany
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/description.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/frag.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/frag.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/frag.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,168 @@
+#include "local_proto.h"
+
+typedef struct
+{
+    int x, y;
+} Position;
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt);
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt);
+
+int getNeighbors(Position * res, int *flagbuf, int x, int y, int nx, int ny,
+		 int nbr_cnt)
+{
+    int left, right, top, bottom;
+    int i, j;
+    int cnt = 0;
+
+    switch (nbr_cnt) {
+    case 4:			/* von Neumann neighborhood */
+	if (x > 0 && flagbuf[y * nx + x - 1] == 1) {
+	    res[cnt].x = x - 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y > 0 && flagbuf[(y - 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y - 1;
+	    cnt++;
+	}
+	if (x < nx - 1 && flagbuf[y * nx + x + 1] == 1) {
+	    res[cnt].x = x + 1;
+	    res[cnt].y = y;
+	    cnt++;
+	}
+	if (y < ny - 1 && flagbuf[(y + 1) * nx + x] == 1) {
+	    res[cnt].x = x;
+	    res[cnt].y = y + 1;
+	    cnt++;
+	}
+	break;
+    case 8:			/* Moore neighborhood */
+	left = x > 0 ? x - 1 : 0;
+	top = y > 0 ? y - 1 : 0;
+	right = x < nx - 1 ? x + 1 : nx - 1;
+	bottom = y < ny - 1 ? y + 1 : ny - 1;
+	for (i = left; i <= right; i++) {
+	    for (j = top; j <= bottom; j++) {
+		if (!(i == x && j == y) && flagbuf[j * nx + i] == 1) {
+		    res[cnt].x = i;
+		    res[cnt].y = j;
+		    cnt++;
+		}
+	    }
+	}
+	break;
+    }
+
+    return cnt;
+}
+
+Coords *writeFrag(int *flagbuf, Coords * actpos, int row, int col, int nrows,
+		  int ncols, int nbr_cnt)
+{
+    int x, y, i;
+    Position *list = (Position *) G_malloc(nrows * ncols * sizeof(Position));
+    Position *first = list;
+    Position *last = list;
+    Position *nbr_list = (Position *) G_malloc(8 * sizeof(Position));
+
+    /* count neighbors */
+    int neighbors = 0;
+
+    if (col <= 0 || flagbuf[row * ncols + col - 1] != 0)
+	neighbors++;
+    if (row <= 0 || flagbuf[(row - 1) * ncols + col] != 0)
+	neighbors++;
+    if (col >= ncols - 1 || flagbuf[row * ncols + col + 1] != 0)
+	neighbors++;
+    if (row >= nrows - 1 || flagbuf[(row + 1) * ncols + col] != 0)
+	neighbors++;
+
+    /* write first cell */
+    actpos->x = col;
+    actpos->y = row;
+    actpos->neighbors = neighbors;
+    actpos++;
+    flagbuf[row * ncols + col] = -1;
+
+    /* push position on fifo-list */
+    last->x = col;
+    last->y = row;
+    last++;
+
+    while (first < last) {
+	/* get position from fifo-list */
+	int r = first->y;
+	int c = first->x;
+
+	first++;
+
+	int left = c > 0 ? c - 1 : 0;
+	int top = r > 0 ? r - 1 : 0;
+	int right = c < ncols - 1 ? c + 1 : ncols - 1;
+	int bottom = r < nrows - 1 ? r + 1 : nrows - 1;
+
+	/* add neighbors to fifo-list */
+	int cnt =
+	    getNeighbors(nbr_list, flagbuf, c, r, ncols, nrows, nbr_cnt);
+
+	for (i = 0; i < cnt; i++) {
+	    x = nbr_list[i].x;
+	    y = nbr_list[i].y;
+
+	    /* add position to fifo-list */
+	    last->x = x;
+	    last->y = y;
+	    last++;
+
+	    /* count neighbors */
+	    neighbors = 0;
+	    if (x <= 0 || flagbuf[y * ncols + x - 1] != 0)
+		neighbors++;
+	    if (y <= 0 || flagbuf[(y - 1) * ncols + x] != 0)
+		neighbors++;
+	    if (x >= ncols - 1 || flagbuf[y * ncols + x + 1] != 0)
+		neighbors++;
+	    if (y >= nrows - 1 || flagbuf[(y + 1) * ncols + x] != 0)
+		neighbors++;
+
+	    /* set values */
+	    actpos->x = x;
+	    actpos->y = y;
+	    actpos->neighbors = neighbors;
+	    actpos++;
+	    flagbuf[y * ncols + x] = -1;
+	}
+    }
+
+    G_free(list);
+    G_free(nbr_list);
+    return actpos;
+}
+
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt)
+{
+    int row, col, i;
+    Coords *p;
+
+    fragcount = 0;
+    Coords *actpos = fragments[0];
+
+    /* find fragments */
+    for (row = 0; row < nrows; row++) {
+	for (col = 0; col < ncols; col++) {
+	    if (flagbuf[row * ncols + col] == 1) {
+		fragcount++;
+
+		fragments[fragcount] =
+		    writeFrag(flagbuf, fragments[fragcount - 1], row, col,
+			      nrows, ncols, nbr_cnt);
+	    }
+	}
+    }
+
+    return;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/frag.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/helpers.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/helpers.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/helpers.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,93 @@
+#include "local_proto.h"
+
+int Round(double d)
+{
+    return d < 0 ? d - 0.5 : d + 0.5;
+}
+
+int Random(int max)
+{
+    return max <=
+	RAND_MAX ? rand() % max : floor((double)rand() /
+					(double)(RAND_MAX + 1) * max);
+}
+
+double Randomf()
+{
+    return ((double)rand()) / ((double)RAND_MAX);
+}
+
+void print_buffer(int *buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    switch (buffer[x + y * sx]) {
+	    case TYPE_NOTHING:
+		fprintf(stderr, "*");
+		break;
+	    default:
+		if (buffer[x + y * sx] < 0) {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		else {
+		    fprintf(stderr, "%d", buffer[x + y * sx]);
+		}
+		break;
+	    }
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_d_buffer(DCELL * buffer, int sx, int sy)
+{
+    int x, y;
+
+    fprintf(stderr, "buffer:\n");
+    for (y = 0; y < sy; y++) {
+	for (x = 0; x < sx; x++) {
+	    fprintf(stderr, "%0.2f ", buffer[y * sx + x]);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_array(DCELL * buffer, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++) {
+	fprintf(stderr, "%0.2f ", buffer[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+void print_fragments()
+{
+    int f;
+    Coords *p;
+
+    for (f = 0; f < fragcount; f++) {
+	fprintf(stderr, "frag%d: ", f);
+	for (p = fragments[f]; p < fragments[f + 1]; p++) {
+	    fprintf(stderr, "(%d,%d), n=%d ", p->x, p->y, p->neighbors);
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+void print_map(double *map, int size)
+{
+    int x, y;
+
+    fprintf(stderr, "map:\n");
+    for (y = 0; y < size; y++) {
+	for (x = 0; x < size; x++) {
+	    fprintf(stderr, "%0.0f ", map[x + y * size]);
+	}
+	fprintf(stderr, "\n");
+    }
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/helpers.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/local_proto.h
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/local_proto.h	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/local_proto.h	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,99 @@
+#ifndef LOCAL_PROTO_H
+#define LOCAL_PROTO_H
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+#include <time.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+#include <grass/stats.h>
+
+#ifdef MAIN
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+#define TYPE_NOTHING -1
+
+#define RESOLUTION 10000
+
+#define MIN_DOUBLE -1000000
+#define MAX_DOUBLE 1000000
+
+typedef struct
+{
+    int x, y;
+    int neighbors;
+} Coords;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    DCELL path;
+    int finished;
+} Individual;
+
+typedef struct
+{
+    int x, y;
+    double dir;
+    double weight;
+} WeightedCoords;
+
+typedef struct
+{
+    int x, y;
+} Displacement;
+
+typedef DCELL(*f_statmethod) (DCELL *, int);
+
+/* helpers.c */
+int Round(double d);
+int Random(int max);
+double Randomf();
+void print_buffer(int *buffer, int sx, int sy);
+void print_d_buffer(DCELL * buffer, int sx, int sy);
+void print_map(double *map, int size);
+void print_array(DCELL * buffer, int size);
+void print_fragments();
+
+/* frag.c */
+void writeFragments(int *flagbuf, int nrows, int ncols, int nbr_cnt);
+
+/* stat_method.c */
+DCELL average(DCELL * vals, int count);
+DCELL variance(DCELL * vals, int count);
+DCELL std_deviat(DCELL * vals, int count);
+DCELL median(DCELL * vals, int count);
+DCELL min(DCELL * vals, int count);
+DCELL max(DCELL * vals, int count);
+
+/* search.c */
+void perform_search(DCELL * values, int *map, DCELL * costmap, int size,
+		    f_statmethod * stats, int stat_count);
+
+/* global parameters */
+GLOBAL int sx, sy;
+GLOBAL int n;
+GLOBAL double percent;
+GLOBAL int maxsteps;
+GLOBAL int step_length;
+GLOBAL int out_freq;
+GLOBAL int include_cost;
+GLOBAL int perception_range;
+GLOBAL double multiplicator;
+
+/* global variables */
+GLOBAL Coords **fragments;
+GLOBAL Coords *cells;
+GLOBAL int fragcount;
+
+GLOBAL Individual *indi_array;
+GLOBAL int *patch_imi;
+
+
+#endif /* LOCAL_PROTO_H */


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/main.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/main.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/main.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,541 @@
+/*
+ ****************************************************************************
+ *
+ * MODULE:       r.pi.searchtime.mw
+ * AUTHOR(S):    Elshad Shirinov, Dr. Martin Wegmann
+ * PURPOSE:      Individual-based dispersal model for connectivity analysis
+ *                           - time-based - within a moving window. Based on r.pi.searchtime
+ *
+ * COPYRIGHT:    (C) 2009-2011 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 "local_proto.h"
+
+struct statmethod
+{
+    f_statmethod *method;	/* routine to compute new value */
+    char *name;			/* method name */
+    char *text;			/* menu display - full description */
+    char *suffix;		/* output suffix */
+};
+
+static struct statmethod statmethods[] = {
+    {average, "average", "average of values", "avg"},
+    {variance, "variance", "variance of values", "var"},
+    {std_deviat, "standard deviation", "standard deviation of values", "dev"},
+    {median, "median", "median of values", "med"},
+    {min, "min", "minimum of values", "min"},
+    {max, "max", "maximum of values", "max"},
+    {0, 0, 0, 0}
+};
+
+int main(int argc, char *argv[])
+{
+    /* input */
+    char *oldname, *oldmapset;
+
+    /* costmap */
+    char *costname, *costmapset;
+
+    /* output */
+    char *newname, *newmapset;
+    char *iminame, *imimapset;
+
+    /* in and out file pointers */
+    int in_fd, out_fd;
+
+    /* parameters */
+    int size;
+    int stats[GNAME_MAX];
+    f_statmethod *methods;
+    int stat_count;
+    int keyval;
+
+    /* maps */
+    int *map;
+    DCELL *costmap;
+
+    /* other parameters */
+    char *title;
+
+    /* helper variables */
+    int row, col;
+    CELL *result;
+    DCELL *d_res;
+    DCELL *values;
+    int neighb_count;
+    int i, j, k;
+    Coords *p;
+    char *str;
+    int method;
+    char outname[GNAME_MAX];
+    int nx, ny;
+
+    RASTER_MAP_TYPE map_type;
+    struct Cell_head ch, window;
+
+    struct GModule *module;
+    struct
+    {
+	struct Option *input, *costmap, *output, *out_immi;
+	struct Option *keyval, *step_length, *perception, *multiplicator, *n;
+	struct Option *percent, *stats, *maxsteps, *size;
+	struct Option *title;
+    } parm;
+    struct
+    {
+	struct Flag *adjacent, *cost;
+    } flag;
+
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    module->keywords = _("raster");
+    module->description =
+	_("Individual-based dispersal model for connectivity analysis (time-based) using moving window");
+
+    parm.input = G_define_standard_option(G_OPT_R_INPUT);
+
+    parm.costmap = G_define_option();
+    parm.costmap->key = "costmap";
+    parm.costmap->type = TYPE_STRING;
+    parm.costmap->required = NO;
+    parm.costmap->gisprompt = "old,cell,raster";
+    parm.costmap->description =
+	_("Name of the costmap with values from 0-100");
+    parm.costmap->guisection = _("Optional");
+
+    parm.output = G_define_standard_option(G_OPT_R_OUTPUT);
+
+    parm.out_immi = G_define_option();
+    parm.out_immi->key = "out_immi";
+    parm.out_immi->type = TYPE_STRING;
+    parm.out_immi->required = NO;
+    parm.out_immi->gisprompt = "new,cell,raster";
+    parm.out_immi->description =
+	_("Name of the optional raster file for patch immigrants count");
+    parm.out_immi->guisection = _("Optional");
+
+    parm.keyval = G_define_option();
+    parm.keyval->key = "keyval";
+    parm.keyval->type = TYPE_INTEGER;
+    parm.keyval->required = YES;
+    parm.keyval->description = _("Category value of the patches");
+    parm.keyval->guisection = _("Required");
+
+    parm.step_length = G_define_option();
+    parm.step_length->key = "step_length";
+    parm.step_length->type = TYPE_INTEGER;
+    parm.step_length->required = YES;
+    parm.step_length->description =
+	_("Length of a single step measured in pixels");
+    parm.step_length->guisection = _("Required");
+
+    parm.perception = G_define_option();
+    parm.perception->key = "perception";
+    parm.perception->type = TYPE_INTEGER;
+    parm.perception->required = NO;
+    parm.perception->description = _("Perception range");
+    parm.perception->guisection = _("Optional");
+
+    parm.multiplicator = G_define_option();
+    parm.multiplicator->key = "multiplicator";
+    parm.multiplicator->type = TYPE_DOUBLE;
+    parm.multiplicator->required = NO;
+    parm.multiplicator->description = _("Attractivity of patches [1-inf]");
+    parm.multiplicator->guisection = _("Optional");
+
+    parm.n = G_define_option();
+    parm.n->key = "n";
+    parm.n->type = TYPE_INTEGER;
+    parm.n->required = YES;
+    parm.n->description = _("Number of individuals");
+    parm.n->guisection = _("Required");
+
+    parm.percent = G_define_option();
+    parm.percent->key = "percent";
+    parm.percent->type = TYPE_DOUBLE;
+    parm.percent->required = YES;
+    parm.percent->description =
+	_("Percentage of individuals which must have arrived successfully"
+	  " to stop the model-run");
+    parm.percent->guisection = _("Required");
+
+    parm.stats = G_define_option();
+    parm.stats->key = "stats";
+    parm.stats->type = TYPE_STRING;
+    parm.stats->required = YES;
+    parm.stats->multiple = YES;
+    str = parm.stats->options = G_malloc(1024);
+    for (n = 0; statmethods[n].name; n++) {
+	if (n)
+	    strcat(str, ",");
+	else
+	    *str = 0;
+	strcat(str, statmethods[n].name);
+    }
+    parm.stats->description =
+	_("Statistical method to perform on the pathlengths of the individuals");
+    parm.stats->guisection = _("Required");
+
+    parm.maxsteps = G_define_option();
+    parm.maxsteps->key = "maxsteps";
+    parm.maxsteps->type = TYPE_INTEGER;
+    parm.maxsteps->required = NO;
+    parm.maxsteps->description = _("Maximum steps for each individual");
+    parm.maxsteps->guisection = _("Optional");
+
+    parm.size = G_define_option();
+    parm.size->key = "size";
+    parm.size->type = TYPE_INTEGER;
+    parm.size->required = NO;
+    parm.size->description = _("Size of the moving window");
+    parm.size->guisection = _("Optional");
+
+    parm.title = G_define_option();
+    parm.title->key = "title";
+    parm.title->key_desc = "\"phrase\"";
+    parm.title->type = TYPE_STRING;
+    parm.title->required = NO;
+    parm.title->description = _("Title for resultant raster map");
+    parm.title->guisection = _("Optional");
+
+    flag.adjacent = G_define_flag();
+    flag.adjacent->key = 'a';
+    flag.adjacent->description =
+	_("Set for 8 cell-neighbors. 4 cell-neighbors are default");
+    flag.adjacent->guisection = _("Required");
+
+    flag.cost = G_define_flag();
+    flag.cost->key = 'c';
+    flag.cost->description =
+	_("Include cost of the path in the calculation of steps");
+    flag.cost->guisection = _("Required");
+
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    /* initialize random generator */
+    srand(time(NULL));
+
+    /* get name of input file */
+    oldname = parm.input->answer;
+
+    /* test input files existance */
+    oldmapset = G_find_cell2(oldname, "");
+    if (oldmapset == NULL)
+        G_fatal_error(_("Raster map <%s> not found"), oldname);
+
+    /* get name of costmap */
+    costname = parm.costmap->answer;
+
+    /* test costmap existance */
+    if (costname && (costmapset = G_find_cell2(costname, "")) == NULL)
+	    G_fatal_error(_("Raster map <%s> not found"), costname);
+
+    /* get keyval */
+    sscanf(parm.keyval->answer, "%d", &keyval);
+
+    /* get step_length */
+    sscanf(parm.step_length->answer, "%d", &step_length);
+
+    /* get perception_range */
+    if (parm.perception->answer) {
+	sscanf(parm.perception->answer, "%d", &perception_range);
+    }
+    else {
+	perception_range = step_length;
+    }
+
+    /* get multiplicator */
+    if (parm.multiplicator->answer) {
+	sscanf(parm.multiplicator->answer, "%lf", &multiplicator);
+    }
+    else {
+	multiplicator = 1.0;
+    }
+
+    /* get n */
+    sscanf(parm.n->answer, "%d", &n);
+
+    /* get size */
+    if (parm.size->answer) {
+	sscanf(parm.size->answer, "%d", &size);
+    }
+    else {
+	size = 0;
+    }
+
+    /* get percent */
+    sscanf(parm.percent->answer, "%lf", &percent);
+
+    /* get number of cell-neighbors */
+    neighb_count = flag.adjacent->answer ? 8 : 4;
+
+    /* get include_cost */
+    include_cost = flag.cost->answer;
+
+    /* check if the new file name is correct */
+    newname = parm.output->answer;
+    if (G_legal_filename(newname) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), newname);
+    newmapset = G_mapset();
+
+    /* check if the immigrants file name is correct */
+    iminame = parm.out_immi->answer;
+
+    if (iminame && G_legal_filename(iminame) < 0)
+	G_fatal_error(_("<%s> is an illegal file name"), iminame);
+    imimapset = G_mapset();
+
+    map_type = DCELL_TYPE;
+
+    /* get size */
+    sx = G_window_cols();
+    sy = G_window_rows();
+
+    /* get maxsteps */
+    if (parm.maxsteps->answer != NULL) {
+	sscanf(parm.maxsteps->answer, "%d", &maxsteps);
+    }
+    else {
+	maxsteps = 10 * sqrt(sx * sx + sy * sy) / step_length;
+    }
+
+    /* scan all statmethod answers */
+    stat_count = 0;
+    while (parm.stats->answers[stat_count] != NULL) {
+	/* get actual method */
+	for (method = 0; (str = statmethods[method].name); method++)
+	    if (strcmp(str, parm.stats->answers[stat_count]) == 0)
+		break;
+	if (!str) {
+	    G_warning(_("<%s=%s> unknown %s"),
+		      parm.stats->key, parm.stats->answers[stat_count],
+		      parm.stats->key);
+	    G_usage();
+	    exit(EXIT_FAILURE);
+	}
+
+	stats[stat_count] = method;
+
+	stat_count++;
+    }
+
+    /* test output */
+    /*      fprintf(stderr, "TEST OUTPUT : \n");
+       fprintf(stderr, "input = %s\n", oldname);
+       fprintf(stderr, "output = %s\n", newname);
+       fprintf(stderr, "costmap = %s\n", costname);
+       fprintf(stderr, "keyval = %d\n", keyval);
+       fprintf(stderr, "step_length = %d\n", step_length);
+       fprintf(stderr, "n = %d\n", n);
+       fprintf(stderr, "percent = %0.2f\n", percent);
+       fprintf(stderr, "maxsteps = %d\n", maxsteps); 
+       fprintf(stderr, "Difference stats: ");
+       for(i = 0; i < dif_stat_count; i++) {
+       if(i > 0) fprintf(stderr, ",");
+       fprintf(stderr, "%s", statmethods[dif_stats[i]].name);
+       }
+       fprintf(stderr, "\n"); */
+
+
+    /* allocate map buffers */
+    map = (int *)G_malloc(sx * sy * sizeof(int));
+    result = G_allocate_c_raster_buf();
+    costmap = (DCELL *) G_malloc(sx * sy * sizeof(DCELL));
+    d_res = G_allocate_d_raster_buf();
+    cells = (Coords *) G_malloc(sx * sy * sizeof(Coords));
+    fragments = (Coords **) G_malloc(sx * sy * sizeof(Coords *));
+    fragments[0] = cells;
+
+    /* open map */
+    in_fd = G_open_cell_old(oldname, oldmapset);
+    if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), oldname);
+
+    /* read map */
+    G_message("Reading map:");
+    for (row = 0; row < sy; row++) {
+	G_get_c_raster_row(in_fd, result, row);
+	for (col = 0; col < sx; col++) {
+	    if (result[col] == keyval)
+		map[row * sx + col] = 1;
+	}
+
+	G_percent(row, sy, 2);
+    }
+    G_percent(1, 1, 2);
+
+    /* close map */
+    G_close_cell(in_fd);
+
+    /* test output */
+    /*      G_message("map:\n");
+       print_buffer(map, sx, sy); */
+
+    /* if costmap specified, read costmap */
+    if (costname != NULL) {
+	/* open costmap */
+	in_fd = G_open_cell_old(costname, costmapset);
+	if (in_fd < 0)
+	    G_fatal_error(_("Unable to open raster map <%s>"), costname);
+
+	/* read costmap */
+	G_message("Reading costmap:");
+	for (row = 0; row < sy; row++) {
+	    G_get_d_raster_row(in_fd, d_res, row);
+	    for (col = 0; col < sx; col++) {
+		costmap[row * sx + col] = d_res[col];
+	    }
+
+	    G_percent(row, sy, 2);
+	}
+	G_percent(1, 1, 2);
+
+	/* close costmap */
+	G_close_cell(in_fd);
+    }
+    else {
+	/* if no costmap specified, fill costmap with 100 */
+	for (i = 0; i < sx * sy; i++) {
+	    costmap[i] = 100;
+	}
+    }
+
+    /* test output */
+    /*      G_message("costmap:\n");
+       print_d_buffer(costmap, sx, sy); */
+
+    /* find fragments */
+    writeFragments(map, sy, sx, neighb_count);
+
+    /* test output */
+    /*      print_fragments(); */
+
+    /* mark each fragment with its number */
+    for (i = 0; i < sx * sy; i++) {
+	map[i] = -1;
+    }
+    for (i = 0; i < fragcount; i++) {
+	for (p = fragments[i]; p < fragments[i + 1]; p++) {
+	    map[p->y * sx + p->x] = i;
+	}
+    }
+
+    /* test output */
+    /*      print_buffer(map, sx, sy); */
+    G_message("Performing search runs:");
+
+    /* allocate space for patch immigrants */
+    patch_imi = (int *)G_malloc(fragcount * sizeof(int));
+
+    /* fill methods array */
+    methods = (f_statmethod *) G_malloc(stat_count * sizeof(f_statmethod));
+    for (method = 0; method < stat_count; method++) {
+	methods[method] = statmethods[stats[method]].method;
+    }
+
+    /* determine windows number */
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+
+    /* allocate values array */
+    values = (DCELL *) G_malloc(stat_count * nx * ny * sizeof(DCELL));
+
+    /* perform search */
+    perform_search(values, map, costmap, size, methods, stat_count);
+
+    /* free methods array */
+    G_free(methods);
+
+    /*G_message("bump");
+       G_free(cells);
+       G_free(fragments);
+       G_message("bump"); */
+
+    G_message("Writing output...");
+    if (size == 0) {
+	for (method = 0; method < stat_count; method++) {
+	    fprintf(stdout, "statmethod = %s: value = %lf\n",
+		    statmethods[stats[method]].name, values[method]);
+	}
+    }
+    else {
+	for (method = 0; method < stat_count; method++) {
+
+	    /* open the new cellfile  */
+	    sprintf(outname, "%s_%s", newname,
+		    statmethods[stats[method]].suffix);
+	    out_fd = G_open_raster_new(outname, map_type);
+	    if (out_fd < 0)
+		    G_fatal_error(_("Cannot create raster map <%s>"), outname);
+
+	    /* write the output file */
+	    for (row = 0; row < sy; row++) {
+		G_set_d_null_value(d_res, sx);
+
+		if (row >= size / 2 && row < ny + size / 2) {
+		    for (col = 0; col < nx; col++) {
+			d_res[col + size / 2] =
+			    values[(method * ny + row - size / 2) * nx + col];
+		    }
+		}
+
+		G_put_d_raster_row(out_fd, d_res);
+
+		G_percent(row + 1, sy, 1);
+	    }
+
+	    /* close output */
+	    G_close_cell(out_fd);
+	}
+	G_percent(100, 100, 2);
+    }
+
+    /* open the new cellfile  */
+    if (iminame) {
+	out_fd = G_open_raster_new(iminame, map_type);
+	if (out_fd < 0)
+	    G_fatal_error(_("Cannot create raster map <%s>"), iminame);
+
+	/* write the output file */
+	for (row = 0; row < sy; row++) {
+	    G_set_d_null_value(d_res, sx);
+
+	    for (i = 0; i < fragcount; i++) {
+		for (p = fragments[i]; p < fragments[i + 1]; p++) {
+		    if (p->y == row) {
+			d_res[p->x] = patch_imi[i];
+		    }
+		}
+	    }
+
+	    G_put_d_raster_row(out_fd, d_res);
+
+	    G_percent(row, sy, 2);
+	}
+
+	G_percent(100, 100, 2);
+
+	/* close output */
+	G_close_cell(out_fd);
+    }
+
+    /* free allocated resources */
+    G_free(values);
+    G_free(map);
+    G_free(costmap);
+    G_free(cells);
+    G_free(fragments);
+    G_free(patch_imi);
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/search.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/search.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/search.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,427 @@
+#include "local_proto.h"
+
+/* globals */
+
+int global_progress = 0;
+int pickpos_count;
+int perception_count;
+int pos_count;
+WeightedCoords *pos_arr;
+Displacement *displacements;
+Displacement *perception;
+Displacement *positions;
+
+int nx, ny, sizex, sizey;
+
+/*
+   initializes all individuals for a window
+ */
+void init_individuals(int x, int y, int sizex, int sizey, int *map,
+		      DCELL * costmap, int n)
+{
+    int i, j, index;
+    Displacement *cell;
+
+    /* fill positions array with possible starting positions */
+    pos_count = 0;
+    for (j = y; j < sizey + y; j++) {
+	for (i = x; i < sizex + x; i++) {
+	    /* test if position should be considered */
+	    if (costmap[i + j * sx] > 0) {
+		positions[pos_count].x = i;
+		positions[pos_count].y = j;
+		pos_count++;
+	    }
+	}
+    }
+
+    for (i = 0; i < n; i++) {
+	/* pick random cell */
+	index = Random(pos_count);
+	cell = positions + index;
+
+	indi_array[i].x = cell->x + 0.5;
+	indi_array[i].y = cell->y + 0.5;
+	indi_array[i].dir = 2 * M_PI * Randomf();
+	indi_array[i].path = 0;
+	indi_array[i].finished = 0;
+    }
+
+    /* test output */
+    /*G_message("Individuals:");
+       for(i = 0; i < n; i++) {
+       fprintf(stderr, "(%d, %d)dir=%0.2f;", indi_array[i].x, indi_array[i].y, indi_array[i].dir);
+       } */
+}
+
+/*
+   sets back an individual, when position is illegal
+ */
+void set_back(int *map, int indi)
+{
+    int index;
+    Displacement *cell;
+
+    /* pick border cell */
+    index = Random(pos_count);
+    cell = positions + index;
+
+    indi_array[indi].x = cell->x;
+    indi_array[indi].y = cell->y;
+    indi_array[indi].dir = 2 * M_PI * Randomf();
+    indi_array[indi].finished = 0;
+}
+
+/*
+   sets displacement pixels taking advantage of symmetry
+ */
+void set_pixels(Displacement * values, int x, int y, int r)
+{
+    if (y == 0) {
+	values[0].x = x;
+	values[0].y = 0;
+	values[2 * r].x = 0;
+	values[2 * r].y = x;
+	values[4 * r].x = -x;
+	values[4 * r].y = 0;
+	values[6 * r].x = 0;
+	values[6 * r].y = -x;
+    }
+    else if (y == x) {
+	values[r].x = y;
+	values[r].y = y;
+	values[3 * r].x = -y;
+	values[3 * r].y = y;
+	values[5 * r].x = -y;
+	values[5 * r].y = -y;
+	values[7 * r].x = y;
+	values[7 * r].y = -y;
+    }
+    else if (y < x) {
+	values[r - x + y].x = x;
+	values[r - x + y].y = y;
+	values[r + x - y].x = y;
+	values[r + x - y].y = x;
+	values[3 * r - x + y].x = -y;
+	values[3 * r - x + y].y = x;
+	values[3 * r + x - y].x = -x;
+	values[3 * r + x - y].y = y;
+	values[5 * r - x + y].x = -x;
+	values[5 * r - x + y].y = -y;
+	values[5 * r + x - y].x = -y;
+	values[5 * r + x - y].y = -x;
+	values[7 * r - x + y].x = y;
+	values[7 * r - x + y].y = -x;
+	values[7 * r + x - y].x = x;
+	values[7 * r + x - y].y = -y;
+    }
+}
+
+/*
+   calculates displacements for a circle of given radius
+ */
+void calculate_displacement(Displacement * values, int radius)
+{
+    int dx = radius;
+    int dy = 0;
+    float dx_ = (float)dx - 0.5f;
+    float dy_ = (float)dy + 0.5f;
+    float f = 0.5f - (float)radius;
+
+    set_pixels(values, dx, dy, radius);
+
+    while (dx > dy) {
+	if (f < 0) {
+	    f += 2 * dy_ + 1;
+	    dy_++;
+	    dy++;
+	}
+	else {
+	    f += 1 - 2 * dx_;
+	    dx_--;
+	    dx--;
+	}
+
+	set_pixels(values, dx, dy, radius);
+    }
+}
+
+/*
+   fills a weighted array with possible next positions
+ */
+void pick_nextpos(WeightedCoords * result, int indi, int *map,
+		  DCELL * costmap)
+{
+    int i;
+    double ex_step, ex_pos;
+    Individual *individual = indi_array + indi;
+    int actx = individual->x;
+    int acty = individual->y;
+    int dir_index = Round(individual->dir * 8.0 * (double)step_length);
+    int pos = dir_index - 2 * step_length;
+
+    if (pos < 0) {
+	pos += 8 * step_length;
+    }
+
+    for (i = 0; i < pickpos_count; i++, pos++) {
+	result[i].x = actx + displacements[pos].x;
+	result[i].y = acty + displacements[pos].y;
+	result[i].dir = (double)pos / (8.0 * (double)step_length);
+	if (result[i].dir >= 1) {
+	    result[i].dir--;
+	}
+
+	/* if out of limits, use weight=1 until better handling */
+	if (actx < 0 || actx >= sx || acty < 0 || acty >= sy) {
+	    result[i].weight = 1;
+	}
+	else {
+	    /* get weight from costmap */
+	    result[i].weight = costmap[(int)acty * sx + (int)actx];
+	}
+    }
+
+    /* apply perception multiplicator */
+    dir_index = Round(individual->dir * 8.0 * (double)perception_range);
+    pos = dir_index - 2 * perception_range;
+    ex_step = (double)perception_range / (double)step_length;
+    ex_pos = (double)pos;
+    for (i = 0; i < pickpos_count; i++) {
+	int patch_flag = 0;
+
+	ex_pos += ex_step;
+	while (pos < ex_pos) {
+	    int x = actx + perception[pos].x;
+	    int y = acty + perception[pos].y;
+
+	    if (x >= 0 && x < sx && y >= 0 && y < sy) {
+		int val = map[x + y * sx];
+
+		patch_flag |= (val > TYPE_NOTHING);
+	    }
+	    pos++;
+	}
+
+	if (patch_flag) {
+	    result[i].weight *= multiplicator;
+
+	}
+    }
+
+    return;
+}
+
+/*
+   performs a single step for an individual
+ */
+void indi_step(int indi, int *map, DCELL * costmap, double step)
+{
+    int i;
+    double sum;
+    Individual *individual = indi_array + indi;
+    double rnd;
+    double newx, newy, newdir;
+    int act_cell;
+
+    /* if position is a patch, then set finished = true */
+    int x = individual->x;
+    int y = individual->y;
+
+    act_cell = map[y * sx + x];
+    if (act_cell > TYPE_NOTHING) {
+	/* count patch immigrants for this patch */
+	patch_imi[act_cell]++;
+	individual->finished = 1;
+	return;
+    }
+
+    /* test output */
+    //      fprintf(stderr, "actpos: x = %0.2f, y = %0.2f\n", individual->x, individual->y);
+
+    /* write an array with possible next positions */
+    pick_nextpos(pos_arr, indi, map, costmap);
+
+    /* test output */
+    /*      G_message("Nextpos array:\n");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, "(x=%d,y=%d,dir=%0.2f,weight=%0.2f)\n", 
+       pos_arr[i].x, pos_arr[i].y, pos_arr[i].dir, pos_arr[i].weight);
+       } */
+
+    /* if no next position is possible, then set back */
+    sum = 0;
+    for (i = 0; i < pickpos_count; i++) {
+	sum += pos_arr[i].weight;
+    }
+    if (sum == 0) {
+	set_back(map, indi);
+
+	return;
+    }
+
+    /* pick a next position randomly, considering the weights */
+    pos_arr[0].weight = pos_arr[0].weight / sum;
+    for (i = 1; i < pickpos_count; i++) {
+	pos_arr[i].weight = pos_arr[i - 1].weight + pos_arr[i].weight / sum;
+    }
+    rnd = Randomf();
+    for (i = 0; i < pickpos_count; i++) {
+	if (pos_arr[i].weight > rnd)
+	    break;
+    }
+    newx = pos_arr[i].x;
+    newy = pos_arr[i].y;
+    newdir = pos_arr[i].dir;
+
+    /* test output */
+    //      fprintf(stderr, "pick: x = %0.2f, y = %0.2f\n\n", newx, newy);
+
+    /* if new position is out of limits, then set back */
+    if (newx < 0 || newx >= sx || newy < 0 || newy >= sy) {
+	set_back(map, indi);
+
+	return;
+    }
+
+    /* set new position */
+    individual->x = newx;
+    individual->y = newy;
+
+    /* count path of the individuum */
+    if (include_cost) {
+	individual->path += 100 / costmap[(int)newy * sx + (int)newx];
+    }
+    else {
+	individual->path++;
+    }
+    individual->dir = newdir;
+
+    /* if new position is a patch, then set finished = true */
+    /*act_cell = map[(int)newy * sx + (int)newx];
+       if (act_cell > TYPE_NOTHING) {
+       /* count patch immigrants for this patch */
+    /*patch_imi[act_cell]++;
+       individual->finished = 1;
+       } */
+
+    return;
+}
+
+/*
+   performs a search run for a single fragment
+ */
+DCELL window_run(int x, int y, int *map, DCELL * costmap)
+{
+    int i;
+    DCELL res = 0;
+    int step_cnt = 0;
+    int finished_cnt = 0;
+    int limit = ceil(n * percent / 100);
+
+    init_individuals(x, y, sizex, sizey, map, costmap, n);
+
+    /* perform a step for each individual */
+    finished_cnt = 0;
+    while (finished_cnt < limit && step_cnt <= maxsteps) {
+	for (i = 0; i < n; i++) {
+	    if (!indi_array[i].finished) {
+		indi_step(i, map, costmap, step_length);
+
+		/* test if new individual finished */
+		if (indi_array[i].finished) {
+		    finished_cnt++;
+
+		    global_progress++;
+		    G_percent(global_progress, nx * ny * n, 1);
+
+		    if (finished_cnt >= limit)
+			break;
+		}
+	    }
+	}
+
+	step_cnt++;
+    }
+
+    return (DCELL) step_cnt;
+}
+
+/*
+   performs a search run for each fragment
+ */
+void perform_search(DCELL * values, int *map, DCELL * costmap, int size,
+		    f_statmethod * stats, int stat_count)
+{
+    int fragment, i;
+    int steps;
+    f_statmethod func;
+    int x, y;
+
+    /* allocate paths array */
+    DCELL *indi_paths = (DCELL *) G_malloc(n * sizeof(DCELL));
+
+    /* allocate individuals array */
+    indi_array = (Individual *) G_malloc(n * sizeof(Individual));
+
+    /* allocate pickpos result array */
+    pickpos_count = 4 * step_length + 1;
+    pos_arr =
+	(WeightedCoords *) G_malloc(pickpos_count * sizeof(WeightedCoords));
+
+    /* allocate displacement arrays */
+    displacements =
+	(Displacement *) G_malloc(16 * step_length * sizeof(Displacement));
+    perception =
+	(Displacement *) G_malloc(16 * perception_range *
+				  sizeof(Displacement));
+
+    /* calculate displacements */
+    calculate_displacement(displacements, step_length);
+    memcpy(displacements + 8 * step_length, displacements,
+	   8 * step_length * sizeof(Displacement));
+
+    calculate_displacement(perception, perception_range);
+    memcpy(perception + 8 * perception_range, perception,
+	   8 * perception_range * sizeof(Displacement));
+
+    /*      fprintf(stderr, "Displacements:");
+       for(i = 0; i < pickpos_count; i++) {
+       fprintf(stderr, " (%d, %d)", displacements[i].x, displacements[i].y);
+       } */
+
+    memset(patch_imi, 0, fragcount * sizeof(int));
+
+    nx = size > 0 ? sx - size + 1 : 1;
+    ny = size > 0 ? sy - size + 1 : 1;
+    sizex = size > 0 ? size : sx;
+    sizey = size > 0 ? size : sy;
+
+    /* allocate positions array */
+    positions =
+	(Displacement *) G_malloc(sizex * sizey * sizeof(Displacement));
+
+    /* perform a search run for each window */
+    for (x = 0; x < nx; x++) {
+	for (y = 0; y < ny; y++) {
+	    steps = window_run(x, y, map, costmap);
+
+	    for (i = 0; i < n; i++) {
+		indi_paths[i] = indi_array[i].path;
+	    }
+
+	    for (i = 0; i < stat_count; i++) {
+		func = stats[i];
+		values[(i * ny + y) * nx + x] = func(indi_paths, n);
+	    }
+	}
+    }
+
+    G_percent(1, 1, 1);
+
+    G_free(positions);
+    G_free(indi_paths);
+    G_free(indi_array);
+    G_free(pos_arr);
+    G_free(displacements);
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/search.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/raster/r.pi/r.pi.searchtime.mw/stat_method.c
===================================================================
--- grass-addons/raster/r.pi/r.pi.searchtime.mw/stat_method.c	                        (rev 0)
+++ grass-addons/raster/r.pi/r.pi.searchtime.mw/stat_method.c	2011-09-27 11:32:34 UTC (rev 48495)
@@ -0,0 +1,115 @@
+#include "local_proto.h"
+
+DCELL average(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++)
+	res += vals[i];
+
+    return res / count;
+}
+
+DCELL variance(DCELL * vals, int count)
+{
+    int i;
+    DCELL mean;
+    DCELL s = 0;
+    DCELL ss = 0;
+
+    if (count <= 0)
+	return 0;
+
+    for (i = 0; i < count; i++) {
+	DCELL val = vals[i];
+
+	s += val;
+	ss += val * val;
+    }
+
+    mean = s / (DCELL) count;
+    return ss / count - mean * mean;
+}
+
+DCELL std_deviat(DCELL * vals, int count)
+{
+    if (count <= 0)
+	return 0;
+
+    return sqrt(variance(vals, count));
+}
+
+DCELL median(DCELL * vals, int count)
+{
+    int k = (count - 1) / 2;
+    int l = 0;
+    int h = count - 1;
+    DCELL pivot, tmp;
+    int i, j, z;
+
+    if (count <= 0)
+	return 0;
+
+    while (l < h) {
+	pivot = vals[k];
+	i = l;
+	j = h;
+
+	do {
+	    while (vals[i] < pivot)
+		i++;
+	    while (vals[j] > pivot)
+		j--;
+	    if (i <= j) {
+		tmp = vals[i];
+		vals[i] = vals[j];
+		vals[j] = tmp;
+		i++;
+		j--;
+	    }
+	} while (i <= j);
+
+	if (j < k)
+	    l = i;
+	if (i > k)
+	    h = j;
+    }
+
+    return vals[k];
+}
+
+DCELL min(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] < res)
+	    res = vals[i];
+
+    return res;
+}
+
+DCELL max(DCELL * vals, int count)
+{
+    int i;
+    DCELL res = 0;
+
+    if (count <= 0)
+	return 0;
+
+    res = vals[0];
+    for (i = 0; i < count; i++)
+	if (vals[i] > res)
+	    res = vals[i];
+
+    return res;
+}


Property changes on: grass-addons/raster/r.pi/r.pi.searchtime.mw/stat_method.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native



More information about the grass-commit mailing list