[GRASS-SVN] r65811 - grass-addons/grass7/raster/r.mcda.electre

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Aug 2 14:54:19 PDT 2015


Author: gianluca
Date: 2015-08-02 14:54:18 -0700 (Sun, 02 Aug 2015)
New Revision: 65811

Added:
   grass-addons/grass7/raster/r.mcda.electre/dominance.c
   grass-addons/grass7/raster/r.mcda.electre/local_proto.h
   grass-addons/grass7/raster/r.mcda.electre/main.c
   grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.html
Removed:
   grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.py
Modified:
   grass-addons/grass7/raster/r.mcda.electre/Makefile
Log:
Porting r.mcda.electre to grass7 with C language

Modified: grass-addons/grass7/raster/r.mcda.electre/Makefile
===================================================================
--- grass-addons/grass7/raster/r.mcda.electre/Makefile	2015-08-02 18:36:42 UTC (rev 65810)
+++ grass-addons/grass7/raster/r.mcda.electre/Makefile	2015-08-02 21:54:18 UTC (rev 65811)
@@ -1,7 +1,9 @@
-MODULE_TOPDIR = ../..
-
+MODULE_TOPDIR = ../../..
 PGM = r.mcda.electre
 
-include $(MODULE_TOPDIR)/include/Make/Script.make
+LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP)
 
-default: script
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd

Added: grass-addons/grass7/raster/r.mcda.electre/dominance.c
===================================================================
--- grass-addons/grass7/raster/r.mcda.electre/dominance.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.mcda.electre/dominance.c	2015-08-02 21:54:18 UTC (rev 65811)
@@ -0,0 +1,116 @@
+#include "local_proto.h"
+
+/*
+ * global function declaration
+ */
+
+void build_weight_vect(int nrows, int ncols, int ncriteria,
+                       struct Option *weight, double *weight_vect);
+
+void build_dominance_matrix(int nrows, int ncols, int ncriteria,
+                            double *weight_vect, double ***decision_vol);
+
+
+/*
+ * function definitions
+ */
+
+void build_weight_vect(int nrows, int ncols, int ncriteria,
+                       struct Option *weight, double *weight_vect)
+{
+
+    int i, nweight = 0;
+    double weight_sum = 0;
+
+    while (weight->answers[nweight] != NULL)
+    {
+        nweight++;
+    }
+
+
+    if (nweight != ncriteria)
+        G_fatal_error(_("criteria number  and weight number are different"));
+
+
+    for (i = 0; i < nweight; i++)
+    {
+        weight_vect[i] = (atof(weight->answers[i]));	/*transfer  weight value  in double  array */
+        weight_sum = weight_sum + weight_vect[i];	/*calculate sum weight */
+    }
+
+    for (i = 0; i < nweight; i++)
+    {
+        weight_vect[i] = weight_vect[i] / weight_sum;	/*normalize vector weight */
+
+    }
+
+}
+
+
+void build_dominance_matrix(int nrows, int ncols, int ncriteria,
+                            double *weight_vect, double ***decision_vol)
+{
+    int row1, col1, row2, col2;
+    int i, j, k, cont;
+	double *row_sum_conc;
+	double *col_sum_conc;
+	double *row_sum_disc;
+	double *col_sum_disc;
+
+	row_sum_conc=G_malloc(ncriteria * nrows * ncols * sizeof(double*));
+	col_sum_conc=G_malloc(ncriteria * nrows * ncols * sizeof(double*));
+	row_sum_disc=G_malloc(ncriteria * nrows * ncols * sizeof(double*));
+	col_sum_disc=G_malloc(ncriteria * nrows * ncols * sizeof(double*));
+
+    k = 0;			/* make pairwise comparation and build concordance/discordance matrix */
+    for (row1 = 0; row1 < nrows; row1++)
+    {
+        G_percent(row1, nrows, 2);
+        for (col1 = 0; col1 < ncols; col1++)
+        {
+            j = 0;
+            for (row2 = 0; row2 < nrows; row2++)
+            {
+                for (col2 = 0; col2 < ncols; col2++)
+                {
+                    double conc = 0, disc = 0;
+                    for (i = 0; i < ncriteria; i++)
+                    {
+                        double d;
+						d = decision_vol[row1][col1][i] - decision_vol[row2][col2][i];
+                        if (d >= 0 )
+                            conc += weight_vect[i];
+                        if (d < disc)	/*WARNING: if(d>conc) */
+                            /**/ disc = -d;
+                    }
+                    row_sum_conc[k] += conc;
+                    col_sum_conc[j] += conc;
+                    row_sum_disc[k] += disc;
+                    col_sum_disc[j] += disc;
+		    
+
+                    j++;	/* increase rows index up to nrows*ncols */
+                }
+            }
+            k++;		/* increase columns index up to nrows*ncols */;
+        }
+    }
+
+    /*calculate concordance and discordance index and storage in decision_vol */
+    cont = 0;			/*variabile progressiva per riga/colonna della concordance_map */
+    for (row1 = 0; row1 < nrows; row1++)
+    {
+        G_percent(row1, nrows, 2);
+        for (col1 = 0; col1 < ncols; col1++)
+        {
+
+            /*fill matrix with concordance index for each DCELL */
+            decision_vol[row1][col1][ncriteria] =
+                row_sum_conc[cont] - col_sum_conc[cont];
+            /*fill matrix with discordance index for each DCELL */
+            decision_vol[row1][col1][ncriteria + 1] =
+                row_sum_disc[cont] - col_sum_disc[cont];
+            cont++;
+        }
+    }
+}

Added: grass-addons/grass7/raster/r.mcda.electre/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.mcda.electre/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/raster/r.mcda.electre/local_proto.h	2015-08-02 21:54:18 UTC (rev 65811)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+#include <grass/config.h>
+
+
+struct input
+{
+    char *name, *mapset;	/* input raster name  and mapset name */
+    int infd;
+    void *inrast;		/* input buffer */
+};
+
+void build_weight_vect(int nrows, int ncols, int ncriteria,
+                       struct Option *weight, double *weight_vect);
+
+void build_dominance_matrix(int nrows, int ncols, int ncriteria,
+                            double *weight_vect, double ***decision_vol);
+

Added: grass-addons/grass7/raster/r.mcda.electre/main.c
===================================================================
--- grass-addons/grass7/raster/r.mcda.electre/main.c	                        (rev 0)
+++ grass-addons/grass7/raster/r.mcda.electre/main.c	2015-08-02 21:54:18 UTC (rev 65811)
@@ -0,0 +1,237 @@
+/****************************************************************************
+ *
+ * MODULE:	 r.mcda.electre
+ * AUTHORS:	 Gianluca Massei (g_massa at libero.it) - Antonio Boggia (boggia at unipg.it)
+ *
+ * PURPOSE:      Make a multicriterio decision  analysis based on ELECTRE algorthm
+ *
+ * COPYRIGHT:    (C) GRASS Development Team (2008)
+ *
+ *		        This program is free software under the GNU General Public
+ *   	    	License (>=v2). Read the file COPYING that comes with GRASS
+ *   	    	for details.
+ *
+ *****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+/*
+ * main function
+ */
+int main(int argc, char *argv[])
+{
+    struct Cell_head cellhd;	/* it stores region information,  and header information of rasters */
+    char *result_concordance, *result_discordance;		/* outputs raster name */
+    char *mapset;		/* mapset name */
+    unsigned char *outrast_concordance, *outrast_discordance;	/* output buffer */
+    char *message;
+    int i,j, ncriteria=0;	/* index and  files number*/
+    int nrows, ncols;
+    int row1, row2, col1, col2;
+    int outfd_concordance, outfd_discordance;		/* output file descriptor */
+	RASTER_MAP_TYPE data_type;	/* type of the map (CELL/DCELL/...) */
+    double *weight_vect, ***decision_vol;/* vector and matrix */
+
+
+    struct History history;	/* holds meta-data (title, comments,..) */
+
+    struct GModule *module;	/* GRASS module for parsing arguments */
+
+    struct Option *criteria, *weight, *discordance, *concordance;	/* options */
+
+    struct input *attributes; /*storage  alla input criteria GRID files and output concordance and discordance GRID files*/
+
+
+    /* initialize GIS environment */
+    G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("raster,MCDA"));
+    module->description = _("Multicirtieria decision analysis based on ELECTRE method");
+
+    /* Define the different options as defined in gis.h */
+    criteria  = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory*/
+    criteria->key        = "criteria";
+    criteria->type       = TYPE_STRING;
+    criteria->required   = YES;
+    criteria->multiple   = YES;
+    criteria->gisprompt  = "old,cell,raster" ;
+    criteria->description = "Input geographics criteria in information system";
+
+    weight = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory*/
+    weight->key        = "weight";
+    weight->type       = TYPE_DOUBLE;
+    weight->required   = YES;
+    weight->multiple   = YES;
+    weight->description = _("Criteria weight(s) (w1,w2,..)");
+
+    concordance = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory */
+    concordance->key = "concordance";
+    concordance->type = TYPE_STRING;
+    concordance->required = YES;
+    concordance->gisprompt = "new,cell,raster";
+    concordance->answer ="concordance";
+    concordance->description = "concordance output map";
+
+    discordance = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory */
+    discordance->key = "discordance";
+    discordance->type = TYPE_STRING;
+    discordance->required = YES;
+    discordance->gisprompt = "new,cell,raster";
+    discordance->answer ="discordance";
+    discordance->description = "discordance output map";
+
+    /* options and flags parser */
+    if (G_parser(argc, argv))
+        exit(EXIT_FAILURE);
+
+
+    G_message("Start: %s",G_date()); /*write calculation start time*/
+
+    /* number of file (=criteria) */
+    while (criteria->answers[ncriteria]!=NULL)
+    {
+        ncriteria++;
+    }
+
+    /* process the input maps:  stores options and flags to variables */
+    /* CRITERIA grid */
+    attributes = G_malloc(ncriteria * sizeof(struct input)); /*attributes is input struct defined in top file and store alla criteria files*/
+    weight_vect=G_malloc(ncriteria * sizeof(double)); /*allocate memory fron vector weight*/
+
+
+
+    build_weight_vect(nrows,ncols,ncriteria,weight,weight_vect); /*calcolate weight vector*/
+
+
+
+    for (i = 0; i < ncriteria; i++)
+    {
+        struct input *p = &attributes[i];
+        p->name = criteria->answers[i];
+        p->mapset = G_find_raster2(p->name,""); /* G_find_cell: Looks for the raster map "name" in the database. */
+        if (p->mapset==NULL) /* returns NULL if the map was not found in any mapset,   mapset name otherwise */
+            G_fatal_error(_("Raster file <%s> not found"), p->name);
+
+
+ /* determine the inputmap type (CELL/FCELL/DCELL) */
+ /*   	data_type = Rast_map_type(p->name, p->mapset);*/
+
+        if ((p->infd =  Rast_open_old(p->name, p->mapset))<0) /* G_open_cell_old - returns file destriptor (>0) */
+            G_fatal_error(_("Unable to open input map <%s> in mapset <%s>"),p->name, p->mapset);
+
+        Rast_get_cellhd(p->name,p->mapset,&cellhd);/* controlling, if we can open input raster */
+		G_debug(3, "number of rows %d", cellhd.rows);
+
+        p->inrast = Rast_allocate_buf(DCELL_TYPE); /* Allocate an array of DCELL based on the number of columns in the current region. Return DCELL   */
+    }
+
+    result_concordance=concordance->answer; /* store outputn name in variables*/
+    result_discordance=discordance->answer;
+
+
+    if (G_legal_filename(result_concordance) < 0) /* check for legal database file names */
+        G_fatal_error(_("<%s> is an illegal file name"), result_concordance);
+
+    if (G_legal_filename(result_discordance) < 0) /* check for legal database file names */
+        G_fatal_error(_("<%s> is an illegal file name"), result_discordance);
+
+    /*values = G_malloc(ncriteria * sizeof(DCELL));*/
+
+    nrows = Rast_window_rows();
+    ncols = Rast_window_cols();
+
+    /*memory allocation for-three dimensional matrix*/
+    decision_vol=G_malloc(nrows * sizeof(double*));
+    for (i=0; i<nrows; ++i)
+    {
+        decision_vol[i]=G_malloc(ncols * sizeof(double*));
+        for (j=0; j<ncols; ++j)
+        {
+            decision_vol[i][j]=G_malloc((ncriteria+2) * sizeof(double)); /****NOTE: it's storage enven concordance and discordance index map****/
+        }
+    }
+
+    /* Allocate output buffer, use  DCELL_TYPE */
+    outrast_concordance = Rast_allocate_buf(DCELL_TYPE); /* Allocate memory for a raster map of type DCELL_TYPE. */
+    outrast_discordance = Rast_allocate_buf(DCELL_TYPE);
+
+    /* controlling, if we can write the raster */
+    outfd_concordance = Rast_open_new(result_concordance, DCELL_TYPE);
+	outfd_discordance = Rast_open_new(result_discordance, DCELL_TYPE);
+
+
+    /*build a three dimensional matrix for storage all critera maps*/
+    for (i=0;i<ncriteria;i++)
+    {
+        for (row1 = 0; row1 < nrows;row1++)
+        {
+            Rast_get_row(attributes[i].infd, attributes[i].inrast, row1,DCELL_TYPE);/* Reads appropriate information into the buffer buf associated with the requested row*/
+            /*G_fatal_error(_("Unable to read raster map <%s> row %d"), criteria->answers[i], row);*/
+            for (col1 = 0; col1 < ncols; col1++)
+            {
+                /* viene letto il valore di cella e lo si attribuisce ad una variabile di tipo DCELL e poi ad un array*/
+                DCELL v1 = ((DCELL *)attributes[i].inrast)[col1];
+                decision_vol[row1][col1][i]=(double)(v1);
+
+            }
+        }
+    }
+
+
+    build_dominance_matrix(nrows,ncols,ncriteria,weight_vect,decision_vol); /*scan all DCELL, make a pairwise comparatione, buil concordance and discordance matrix and relative index*/
+
+
+    for (row1 = 0; row1 < nrows; row1++)
+    {
+        for (col1 = 0; col1 < ncols; col1++)
+        {
+            ((DCELL *) outrast_concordance)[col1] = (DCELL)decision_vol[row1][col1][ncriteria];/*write concordance map*/
+            ((DCELL *) outrast_discordance)[col1] = (DCELL)decision_vol[row1][col1][ncriteria+1];/*write discordance map*/
+        }
+        Rast_put_row(outfd_concordance, outrast_concordance,  DCELL_TYPE);
+        Rast_put_row(outfd_discordance, outrast_discordance,  DCELL_TYPE);
+    }
+
+
+    G_message("End: %s",G_date());
+
+    /* memory cleanup */
+    for (i = 0; i<ncriteria; i++)
+        G_free(attributes[i].inrast);
+
+    G_free(outrast_concordance);
+    G_free(outrast_discordance);
+    G_free(decision_vol);
+
+
+
+    /* closing raster maps */
+    for (i = 0; i<ncriteria; i++)
+        Rast_close(attributes[i].infd);
+
+    Rast_close(outfd_concordance);
+    Rast_close(outfd_discordance);
+
+    /* add command line incantation to history concordance file */
+    Rast_short_history(result_concordance, "raster", &history);
+    Rast_command_history(&history);
+    Rast_write_history(result_concordance, &history);
+
+    /* add command line incantation to history discordance file */
+    Rast_short_history(result_discordance, "raster", &history);
+    Rast_command_history(&history);
+    Rast_write_history(result_discordance, &history);
+
+    exit(EXIT_SUCCESS);
+}
+

Added: grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.html
===================================================================
--- grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.html	                        (rev 0)
+++ grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.html	2015-08-02 21:54:18 UTC (rev 65811)
@@ -0,0 +1,40 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.mcda.electre</em> is the implementation of the ELECTRE multicriteria
+algorithm in GRASS GIS environment. It is one of the available tools in the
+r.mcda suite. It requires as an input the list of raster representing the
+criteria to be assessed in the multicriteria evaluation and the vector of
+weights to be assigned. Every single cell of the GRASS region is considered
+as one of the possible alternatives to evaluate and it is described with
+the value assumed for the same cell by the raster used as criteria. There
+are two output files. One represents the spatial distribution of the
+concordance index, the other one of the discordance index. The optimal
+solution is the one presenting the maximum concordance value and the minimum
+discordance value at the same time.
+
+
+<h2>NOTES</h2>
+The module does not standardize the raster-criteria. Therefore, they must
+be prepared before by using, for example, r.mapcalc. The weights vector
+is always normalized so that the sum of the weights is 1.
+
+
+<h2>REFERENCE</h2>
+<p>Roy, B. (1971) Problem and methods with multiple objective functions
+ Mathematical programming 1, 239-266.</P>
+<p>Roy, B. (1990): The outranking approach and the foundations of Electre
+ methods , Document du LAMSADE, Paris.</P>
+<p>Janssen R. (1994) - Multiobjective decision support for environmental
+ management, Kluwer Academic Publishers.</P>
+<p>GRASS Development Team (2008)</P>
+
+<h2>SEE ALSO</h2>
+<em>r.mcda.fuzzy, r.mcda.electre, r.roughet, r.mapcalc</em>
+
+<h2>AUTHORS</h2>
+Antonio Boggia - Gianluca Massei<br>
+Department of Economics and Appraisal - University of Perugia - Italy 
+
+
+<p>
+<i>Last changed: $Date: 2012-12-04 19:08:17 +0100 (mar, 04 dic 2012) $</i>

Deleted: grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.py
===================================================================
--- grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.py	2015-08-02 18:36:42 UTC (rev 65810)
+++ grass-addons/grass7/raster/r.mcda.electre/r.mcda.electre.py	2015-08-02 21:54:18 UTC (rev 65811)
@@ -1,116 +0,0 @@
-#!/usr/bin/env python
-############################################################################
-#
-# MODULE:	   r.mcda.electre
-# AUTHOR:	   Gianluca Massei - Antonio Boggia
-# PURPOSE:	   Elaborate several criteria maps and gets concordance and 
-#				discordance maps indices as a base for electre analysis	 
-# COPYRIGHT:  c) 2010 Gianluca Massei, Antonio Boggia  and the GRASS 
-#					   Development Team. This program is free software under the 
-#					   GNU General PublicLicense (>=v2). Read the file COPYING 
-#					   that comes with GRASS for details.
-#
-#############################################################################
-#%module
-#% description: Gets concordance and discordance maps indices for MCDA analysis
-#% keyword: raster
-#% keyword: criteria maps
-#% keyword: MCDA
-#%end
-#%option G_OPT_R_INPUTS
-#% key: criteria
-#% multiple: yes
-#% gisprompt: old,cell,raster
-#% key_desc: name
-#% description: Name of criteria raster maps 
-#% required: yes
-#%end
-#%option
-#% key: weights
-#% type: double
-#% description: weights (w1,w2,...,wn)
-#% multiple: yes
-#% required: yes
-#%end
-#%option G_OPT_R_OUTPUT
-#% key: concordancemap
-#% type: string
-#% gisprompt: new_file,cell,output
-#% description: output concordance raster map
-#% answer:concordance
-#% required: yes
-#%end
-#%option G_OPT_R_OUTPUT
-#% key: discordancemap
-#% type: string
-#% gisprompt: new_file,cell,output
-#% description: output discordance raster map
-#% answer:discordance
-#% required: yes
-#%end
-
-
-import sys
-
-import grass.script as gscript
-from grass.pygrass import raster
-
-
-def preprocessing(attributes,weights):
-	matrix=[]
-	for attribute in attributes:
-		c=[]
-		criteria = raster.RasterRowIO(str(attribute))
-		#criteria.is_open()
-		criteria.open('r')
-		for row in criteria: 
-			c.append(row)
-		matrix.append(c)
-		criteria.close()
-	print len(matrix),weights
-	print dir(criteria)
-
-def concordance(attributes,weights,concordanceMap):
-	i=0
-	listMaps=[]
-	for attrRow,weight in zip(attributes,weights):
-		for attrCol in attributes:
-			concordanceMap="conc_%s" % str(i)
-			formula="%s=if(%s>%s,%s,0)" % (concordanceMap,attrRow.split('@')[0],attrCol.split('@')[0],weight)
-			gscript.mapcalc(formula,overwrite = True)
-			listMaps.append(concordanceMap)
-			i=i+1
-	endMap="%s=%s" % (concordanceMap,("+".join(listMaps)))
-	gscript.mapcalc(endMap,overwrite = True)
-	gscript.run_command("g.remove", type='raster',flags='f', name=",".join(listMaps))
-	return 0
-
-
-def discordance(attributes,discordanceMap):
-	i=0
-	listMaps=[]
-	for attrRow in attributes:
-		for attrCol in attributes:
-			discordanceMap="conc_%s" % str(i)
-			formula="%s=if(%s>%s,%s-%s,0)" % (discordanceMap,attrRow.split('@')[0],attrCol.split('@')[0],attrRow.split('@')[0],attrCol.split('@')[0])
-			gscript.mapcalc(formula,overwrite = True)
-			listMaps.append(discordanceMap)
-			i=i+1
-	endMap="%s=max(%s)" % (discordanceMap,("+".join(listMaps)))
-	gscript.mapcalc(endMap,overwrite = True)
-	gscript.run_command("g.remove", type='raster',flags='f', name=",".join(listMaps))
-	return 0
-
-def main():
-	options, flags = gscript.parser()
-	attributes = options['criteria'].split(',')
-	weights = options['weights'].split(',')
-	concordanceMap= options['concordancemap']
-	discordanceMap= options['discordancemap']
-	concordance(attributes,weights,concordanceMap) 
-	discordance(attributes,discordanceMap)
-	return 0
-
-
-if __name__ == "__main__":
-    sys.exit(main())



More information about the grass-commit mailing list