[GRASS-SVN] r66102 - in grass-addons/grass7/raster: . r.mcda.promethee
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Sep 4 14:43:40 PDT 2015
Author: gianluca
Date: 2015-09-04 14:43:40 -0700 (Fri, 04 Sep 2015)
New Revision: 66102
Added:
grass-addons/grass7/raster/r.mcda.promethee/
grass-addons/grass7/raster/r.mcda.promethee/Makefile
grass-addons/grass7/raster/r.mcda.promethee/local_proto.h
grass-addons/grass7/raster/r.mcda.promethee/main.c
grass-addons/grass7/raster/r.mcda.promethee/promethee.c
grass-addons/grass7/raster/r.mcda.promethee/r.mcda.promethee.html
Log:
firsth implementation of mcda promethee module
Added: grass-addons/grass7/raster/r.mcda.promethee/Makefile
===================================================================
--- grass-addons/grass7/raster/r.mcda.promethee/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.mcda.promethee/Makefile 2015-09-04 21:43:40 UTC (rev 66102)
@@ -0,0 +1,9 @@
+MODULE_TOPDIR = ../..
+PGM = r.mcda.promethee
+
+LIBES = $(RASTERLIB) $(GISLIB) $(MATHLIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: grass-addons/grass7/raster/r.mcda.promethee/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.mcda.promethee/local_proto.h (rev 0)
+++ grass-addons/grass7/raster/r.mcda.promethee/local_proto.h 2015-09-04 21:43:40 UTC (rev 66102)
@@ -0,0 +1,24 @@
+#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 ncriteria, struct Option *weight,
+ double *weight_vect);
+
+void build_flow_matrix(int nrows, int ncols, int ncriteria,
+ double *weight_vect, double ***decision_vol,
+ double ***positive_flow_vol, double ***negative_flow_vol);
+
Added: grass-addons/grass7/raster/r.mcda.promethee/main.c
===================================================================
--- grass-addons/grass7/raster/r.mcda.promethee/main.c (rev 0)
+++ grass-addons/grass7/raster/r.mcda.promethee/main.c 2015-09-04 21:43:40 UTC (rev 66102)
@@ -0,0 +1,260 @@
+/****************************************************************************
+ *
+ * MODULE: r.mcda.promethee
+ * AUTHORS: Gianluca Massei (g_massa at libero.it) - Antonio Boggia (boggia at unipg.it)
+ *
+ * PURPOSE: Make a multicriteria decision analysis based on PROMETHEE algorithm,
+ * with concordance and discordance indexes maps
+ *
+ * COPYRIGHT: (C) GRASS Development Team (2015)
+ *
+ * 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_positive_flow, *result_negative_flow, *result_netflow; /* outputs raster name */
+ /*char *mapset; mapset name */
+ unsigned char *outrast_positive_flow, *outrast_negative_flow, *outrast_netflow; /* output buffer */
+ int i,j, ncriteria=0; /* index and files number*/
+ int nrows, ncols;
+ int row1, col1;
+ int outfd_positive_flow, outfd_negative_flow, outfd_netflow; /* output file descriptor */
+ /*RASTER_MAP_TYPE data_type; type of the map (CELL/DCELL/...) */
+ double *weight_vect, ***decision_vol, ***positive_flow_vol, ***negative_flow_vol;/* vector and matrix */
+
+
+ struct History history; /* holds meta-data (title, comments,..) */
+
+ struct GModule *module; /* GRASS module for parsing arguments */
+
+ struct Option *criteria, *weight, *positiveflow, *negativeflow, *netflow; /* 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 PROMETHEE 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,..,wn)");
+
+ positiveflow = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory */
+ positiveflow->key = "positiveflow";
+ positiveflow->type = TYPE_STRING;
+ positiveflow->required = YES;
+ positiveflow->gisprompt = "new,cell,raster";
+ positiveflow->answer ="positiveflow";
+ positiveflow->description = "positive flow output map";
+
+ negativeflow = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory */
+ negativeflow->key = "negativeflow";
+ negativeflow->type = TYPE_STRING;
+ negativeflow->required = YES;
+ negativeflow->gisprompt = "new,cell,raster";
+ negativeflow->answer ="negativeflow";
+ negativeflow->description = "negative flow output map";
+
+ netflow = G_define_option(); /* Allocates memory for the Option structure and returns a pointer to this memory */
+ netflow->key = "netflow";
+ netflow->type = TYPE_STRING;
+ netflow->required = YES;
+ netflow->gisprompt = "new,cell,raster";
+ netflow->answer ="netflow";
+ netflow->description = "net flow 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(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 = (char *) G_find_raster2(p->name,""); /* 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) /* Rast_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_positive_flow=positiveflow->answer; /* store output name in variables*/
+ result_negative_flow=negativeflow->answer;
+ result_netflow=netflow->answer;
+
+
+ if (G_legal_filename(result_positive_flow) < 0) /* check for legal database file names */
+ G_fatal_error(_("<%s> is an illegal file name"), result_positive_flow);
+
+ if (G_legal_filename(result_negative_flow) < 0) /* check for legal database file names */
+ G_fatal_error(_("<%s> is an illegal file name"), result_negative_flow);
+
+ if (G_legal_filename(result_netflow) < 0) /* check for legal database file names */
+ G_fatal_error(_("<%s> is an illegal file name"), result_netflow);
+
+ /*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*));
+ positive_flow_vol=G_malloc(nrows * sizeof(double*));
+ negative_flow_vol=G_malloc(nrows * sizeof(double*));
+
+ for (i=0; i<nrows; ++i)
+ {
+ decision_vol[i]=G_malloc(ncols * sizeof(double*));
+ positive_flow_vol[i]=G_malloc(nrows * sizeof(double*));
+ negative_flow_vol[i]=G_malloc(nrows * sizeof(double*));
+ for (j=0; j<ncols; ++j)
+ {
+ decision_vol[i][j]=G_malloc((ncriteria+2) * sizeof(double)); /****NOTE: it's storage ****/
+ positive_flow_vol[i][j]=G_malloc((ncriteria+2) * sizeof(double));
+ negative_flow_vol[i][j]=G_malloc((ncriteria+2) * sizeof(double));
+ }
+ }
+
+ /* Allocate output buffer, use DCELL_TYPE */
+ outrast_positive_flow = Rast_allocate_buf(DCELL_TYPE); /* Allocate memory for a raster map of type DCELL_TYPE. */
+ outrast_negative_flow = Rast_allocate_buf(DCELL_TYPE);
+
+ /* controlling, if we can write the raster */
+ outrast_positive_flow = Rast_open_new(result_positive_flow, DCELL_TYPE);
+ outrast_negative_flow = Rast_open_new(result_negative_flow, DCELL_TYPE);
+ outrast_netflow = Rast_open_new(result_netflow, 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);
+ G_message("row: %d",row1);
+
+ }
+ }
+ }
+
+
+ build_flow_matrix(nrows,ncols,ncriteria,weight_vect,decision_vol,positive_flow_vol, negative_flow_vol); /*scan all DCELL, make a pairwise comparatione, buil positive flow matrix*/
+
+
+ for (row1 = 0; row1 < nrows; row1++)
+ {
+ for (col1 = 0; col1 < ncols; col1++)
+ {
+ ((DCELL *) outrast_positive_flow)[col1] = (DCELL)positive_flow_vol[row1][col1][ncriteria];/*write positive flow map*/
+ ((DCELL *) outrast_negative_flow)[col1] = (DCELL)negative_flow_vol[row1][col1][ncriteria];/*write negative flow map*/
+ }
+ Rast_put_row(outfd_positive_flow, outrast_positive_flow, DCELL_TYPE);
+ Rast_put_row(outfd_negative_flow, outrast_negative_flow, DCELL_TYPE);
+ }
+
+
+ G_message("End: %s",G_date());
+
+ /* memory cleanup */
+ for (i = 0; i<ncriteria; i++)
+ G_free(attributes[i].inrast);
+
+ G_free(outrast_positive_flow);
+ G_free(outrast_negative_flow);
+ G_free(decision_vol);
+ G_free(positive_flow_vol);
+ G_free(negative_flow_vol);
+
+
+
+ /* closing raster maps */
+ for (i = 0; i<ncriteria; i++)
+ Rast_close(attributes[i].infd);
+
+ Rast_close(outfd_positive_flow);
+ Rast_close(outfd_negative_flow);
+
+ /* add command line incantation to history concordance file */
+ Rast_short_history(result_positive_flow, "raster", &history);
+ Rast_command_history(&history);
+ Rast_write_history(result_positive_flow, &history);
+
+ /* add command line incantation to history discordance file */
+ Rast_short_history(result_negative_flow, "raster", &history);
+ Rast_command_history(&history);
+ Rast_write_history(result_negative_flow, &history);
+
+ exit(EXIT_SUCCESS);
+}
+
Added: grass-addons/grass7/raster/r.mcda.promethee/promethee.c
===================================================================
--- grass-addons/grass7/raster/r.mcda.promethee/promethee.c (rev 0)
+++ grass-addons/grass7/raster/r.mcda.promethee/promethee.c 2015-09-04 21:43:40 UTC (rev 66102)
@@ -0,0 +1,102 @@
+#include "local_proto.h"
+
+/*
+ * global function declaration
+ */
+
+void build_weight_vect(int ncriteria, struct Option *weight,
+ double *weight_vect);
+
+void build_flow_matrix(int nrows, int ncols, int ncriteria,
+ double *weight_vect, double ***decision_vol,
+ double ***positive_flow_vol, double ***negative_flow_vol);
+
+
+/*
+ * function definitions
+ */
+
+void build_weight_vect(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_flow_matrix(int nrows, int ncols, int ncriteria,
+ double *weight_vect, double ***decision_vol,
+ double ***positive_flow_vol, double ***negative_flow_vol)
+{
+ int row1, col1, row2, col2;
+ int i;
+ double threshold;
+
+/* make pairwise comparation and build positive flow matrix */
+ for (i = 0; i < ncriteria; i++)
+ {
+ G_percent(i, (nrows*ncriteria), 2);
+ for (row1 = 0; row1 < nrows; row1++)
+ {
+ for (col1 = 0; col1 < ncols; col1++)
+ {
+ for (row2 = 0; row2 < nrows; row2++)
+ {
+ for (col2 = 0; col2 < ncols; col2++)
+ {
+ threshold = (decision_vol[row1][col1][i] - decision_vol[row2][col2][i]);
+ if (threshold>0)
+ {
+ positive_flow_vol[row1][col1][i]=threshold*weight_vect[i];
+ negative_flow_vol[row1][col1][i]=0;
+ }
+ else
+ {
+ positive_flow_vol[row1][col1][i]=0;
+ negative_flow_vol[row1][col1][i]=threshold*weight_vect[i];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*storage preference value in decision_vol */
+ for (row1 = 0; row1 < nrows; row1++)
+ {
+ G_percent(row1, nrows, 2);
+ for (col1 = 0; col1 < ncols; col1++)
+ {
+ for ( i=0; i<ncriteria;i++)
+ {
+ /*fill matrix with performance for each DCELL */
+ positive_flow_vol[row1][col1][ncriteria] = positive_flow_vol[row1][col1][ncriteria]+positive_flow_vol[row1][col1][i];
+ negative_flow_vol[row1][col1][ncriteria] = negative_flow_vol[row1][col1][ncriteria]+negative_flow_vol[row1][col1][i];
+ }
+ }
+ }
+}
Added: grass-addons/grass7/raster/r.mcda.promethee/r.mcda.promethee.html
===================================================================
--- grass-addons/grass7/raster/r.mcda.promethee/r.mcda.promethee.html (rev 0)
+++ grass-addons/grass7/raster/r.mcda.promethee/r.mcda.promethee.html 2015-09-04 21:43:40 UTC (rev 66102)
@@ -0,0 +1,47 @@
+<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>CITE AS</h2>
+<p>Massei, G., Rocchi, L., Paolotti, L., Greco, S., & Boggia,
+Decision Support Systems for environmental management:
+A case study on wastewater from agriculture, Journal of Environmental Management,
+Volume 146, 15 December 2014, Pages 491-504, ISSN 0301-4797</p>
+
+
+
+<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 (2015)</P>
+
+<h2>SEE ALSO</h2>
+<em>r.mcda.fuzzy, r.mcda.regime, r.mcda.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>
More information about the grass-commit
mailing list