[GRASS-SVN] r58636 - in grass-addons/grass7/vector: . v.area.stats

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jan 7 08:18:18 PST 2014


Author: zarch
Date: 2014-01-07 08:18:18 -0800 (Tue, 07 Jan 2014)
New Revision: 58636

Added:
   grass-addons/grass7/vector/v.area.stats/
   grass-addons/grass7/vector/v.area.stats/Makefile
   grass-addons/grass7/vector/v.area.stats/areas.c
   grass-addons/grass7/vector/v.area.stats/export.c
   grass-addons/grass7/vector/v.area.stats/global.h
   grass-addons/grass7/vector/v.area.stats/main.c
   grass-addons/grass7/vector/v.area.stats/parse.c
   grass-addons/grass7/vector/v.area.stats/v.area.stats.html
Log:
Add a module to extract shape statistics for areas

Added: grass-addons/grass7/vector/v.area.stats/Makefile
===================================================================
--- grass-addons/grass7/vector/v.area.stats/Makefile	                        (rev 0)
+++ grass-addons/grass7/vector/v.area.stats/Makefile	2014-01-07 16:18:18 UTC (rev 58636)
@@ -0,0 +1,14 @@
+
+MODULE_TOPDIR = ../..
+
+PGM=v.area.stats
+
+LIBES = $(VECTORLIB) $(DBMILIB) $(GISLIB) $(MATHLIB)
+DEPENDENCIES = $(VECTORDEP) $(DBMIDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+ 
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd	
+

Added: grass-addons/grass7/vector/v.area.stats/areas.c
===================================================================
--- grass-addons/grass7/vector/v.area.stats/areas.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.area.stats/areas.c	2014-01-07 16:18:18 UTC (rev 58636)
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <grass/glocale.h>
+
+#include "global.h"
+
+int init_vals(struct value val)
+{
+	val.area_id = 0;
+	val.cat = 0;
+	val.nisles = 0;
+	val.x_extent = 0;
+	val.y_extent = 0;
+	val.iperimeter = 0;
+	val.iarea = 0;
+	val.icompact = 0;
+	val.ifd = 0;
+	val.perimeter = 0;
+	val.area = 0;
+	val.boundarea = 0;
+	val.aratio = 0;
+	val.compact = 0;
+	val.fd = 0;
+	return 0;
+}
+
+
+/* This function now does one of 3 things:
+ * 1) It reads the areas of the areas.
+ * 2) It reads the perimeter lengths of the areas. If projection is LL, the geodesic distance is used.
+ * 3) It calculates the compactness using this formula:
+ *    compactness = perimeter / (2 * sqrt(M_PI * area))
+ * 4) It calculates the fractal dimension of the bounding curve:
+ *    D_L  = 2 * log(perimeter) / log(area)
+ *    (See B.B. Mandelbrot, The Fractal Geometry of Nature. 1982.)
+ */
+int read_areas(struct Map_info *Map, int nareas)
+{
+	int isle, aid, ax;
+	struct line_pnts *Ppoints;
+	struct bound_box Bbox;
+	double iarea, iperimeter;
+
+	Ppoints = Vect_new_line_struct();
+	nareas = Vect_get_num_areas(Map);
+
+	G_message(_("Reading areas..."));
+
+	/* Cycle through all areas */
+	for (aid = 1; aid <= nareas; aid++) {
+		init_vals(Values[aid]);
+
+		if (Vect_area_alive(Map, aid) > 0){
+			Vect_reset_line(Ppoints);
+			
+			Values[aid].area_id = aid;
+			Values[aid].cat = Vect_get_area_cat(Map, aid, options.field);;
+			Vect_get_area_points(Map, aid, Ppoints);
+			Values[aid].perimeter = Vect_line_geodesic_length(Ppoints);
+			Values[aid].boundarea = G_area_of_polygon(Ppoints->x, Ppoints->y, Ppoints->n_points);
+			Vect_line_box(Ppoints, &Bbox);
+			Values[aid].x_extent = Bbox.E - Bbox.W;
+			Values[aid].y_extent = Bbox.N - Bbox.S;
+			Values[aid].nisles = Vect_get_area_num_isles(Map, aid);
+
+			if (Values[aid].nisles) {
+			    for (isle = 0; isle < Values[aid].nisles; isle++) {
+					Vect_reset_line(Ppoints);
+					ax = Vect_get_area_isle(Map, aid, isle);
+					if (Vect_get_isle_points(Map, ax, Ppoints) == -1){
+					    G_fatal_error(_("Not able to read the isle <%d> of the area <%d>.\n"),
+							  isle, aid);
+					}
+
+					iarea = G_area_of_polygon(Ppoints->x, Ppoints->y, 
+								      Ppoints->n_points);
+					iperimeter = Vect_line_geodesic_length(Ppoints);
+					Values[aid].icompact += iperimeter / (2.0 * sqrt(M_PI * iarea));
+					Values[aid].ifd += 2.0 * log(iperimeter) / log(iarea);
+					Values[aid].iarea += iarea;
+					Values[aid].iperimeter += iperimeter;
+					/* May be we can add also the mean and the std? */
+			    }
+			}
+			Values[aid].area = Values[aid].boundarea - Values[aid].iarea;
+			Values[aid].aratio = Values[aid].iarea / Values[aid].boundarea;
+			Values[aid].compact = Values[aid].perimeter / (2.0 * sqrt(M_PI * Values[aid].boundarea));
+			Values[aid].fd = 2.0 * log(Values[aid].perimeter) / log(Values[aid].boundarea);
+		}
+		G_percent(aid, nareas, 2);
+	}
+	return 0;
+}

Added: grass-addons/grass7/vector/v.area.stats/export.c
===================================================================
--- grass-addons/grass7/vector/v.area.stats/export.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.area.stats/export.c	2014-01-07 16:18:18 UTC (rev 58636)
@@ -0,0 +1,109 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+
+char *join(const char* sep, char** string_list, int llen, char *buf)
+{
+	int i;
+
+	strcpy(buf, string_list[0]);
+	strcat(buf, sep);
+	for (i = 1; i < llen; i++) {
+		strcat(buf, string_list[i]);
+		if (i < llen - 1)
+			strcat(buf, sep);
+	}
+	strcat(buf, "\n");
+	/* G_debug(4, "buf: %s", buf); */
+
+	return buf;
+}
+
+
+int get_str_length(char** string_list, int llen, int seplen)
+{
+	int i;
+	int slen = llen * seplen + 1;
+	
+	G_debug(3, "Compute the length of the final string");
+	for (i = 0; i < llen; i++) {
+		slen += strlen(string_list[i]);
+	}
+	return slen;
+}
+
+
+
+int get_vals(char **str_vals, struct value val)
+{
+	G_debug(3, "Copy the values from the struct"
+			" for area <%d> to a list of strings.", val.area_id);
+	sprintf(str_vals[AREA_ID], "%d", val.area_id);
+	sprintf(str_vals[CAT], "%d", val.cat);
+	sprintf(str_vals[NISLES], "%d", val.nisles);
+	sprintf(str_vals[X_EXTENT], "%f", val.x_extent);
+	sprintf(str_vals[Y_EXTENT], "%f", val.y_extent);
+	sprintf(str_vals[IPERIMETER], "%f", val.iperimeter);
+	sprintf(str_vals[IAREA], "%f", val.iarea);
+	sprintf(str_vals[ICOMPACT], "%f", val.icompact);
+	sprintf(str_vals[IFD], "%f", val.ifd);
+	sprintf(str_vals[PERIMETER], "%f", val.perimeter);
+	sprintf(str_vals[AREA], "%f", val.area);
+	sprintf(str_vals[BOUNDAREA], "%f", val.boundarea);
+	sprintf(str_vals[ARATIO], "%f", val.aratio);
+	sprintf(str_vals[COMPACT], "%f", val.compact);
+	sprintf(str_vals[FD], "%f", val.fd);
+	return 0;
+}
+
+int export2csv(int length)
+{
+	int i, idx, buflen;
+	int len = LENVALS + 1;
+	FILE *fp;
+	
+	G_debug(2, "Allocate memory to copy and write the results");
+	char **str_vals = (char **) calloc(len, sizeof(char *));
+	for (i = 0; i <= len; i++){
+		str_vals[i] = (char *) G_calloc(STRLEN, sizeof(char));
+	}
+	
+	G_debug(2, "Allocate memory for row buffer");
+	get_vals(str_vals, Values[0]);
+	buflen = get_str_length(str_vals, LENVALS, strlen(options.separator));
+	buflen += 128;  /* for safety reasons */
+	char *buf = (char *) G_calloc(buflen, sizeof(char));
+	
+	G_debug(2, "Open the file to write the results.");
+	if (options.out != NULL && strcmp(options.out, "-") != 0) {
+		fp = freopen(options.out, "w", stdout);
+		if (fp == NULL) {
+			G_fatal_error(_("Unable to open file <%s> for writing"), 
+						  options.out);
+		}
+    }
+
+    G_debug(2, "Start copying the results.");
+	for (idx = 1; idx <= length; idx++) {
+		if (Values[idx].area_id){
+			get_vals(str_vals, Values[idx]);
+			buf = join(options.separator, str_vals, LENVALS, buf);
+			/* G_debug(3, "buf:%s\n", buf); */
+			printf(buf);
+		}
+	}
+
+	/* fclose(fp); */
+	
+	/* free string list */
+	G_free((void *) str_vals);
+	G_free((void *) buf);
+
+    return 0;
+}
+

Added: grass-addons/grass7/vector/v.area.stats/global.h
===================================================================
--- grass-addons/grass7/vector/v.area.stats/global.h	                        (rev 0)
+++ grass-addons/grass7/vector/v.area.stats/global.h	2014-01-07 16:18:18 UTC (rev 58636)
@@ -0,0 +1,63 @@
+#include <grass/gis.h>
+#include <grass/vector.h>
+
+#define LENVALS 15
+#define STRLEN 32
+
+#define AREA_ID 0
+#define CAT 1
+#define NISLES 2
+#define X_EXTENT 3
+#define Y_EXTENT 4
+#define IPERIMETER 5
+#define IAREA 6
+#define ICOMPACT 7
+#define IFD 8
+#define PERIMETER 9
+#define AREA 10
+#define BOUNDAREA 11
+#define ARATIO 12
+#define COMPACT 13
+#define FD 14
+
+struct value
+{
+	int area_id;			/* area_id */
+	int cat;				/* category */
+	int nisles;				/* number of isles */
+	double x_extent;		/* x extent */
+	double y_extent;		/* y extent */
+	double iperimeter;		/* sum of isles perimeters */
+	double iarea;			/* sum of isles area */
+	double icompact;		/* sum of isles compact */
+	double ifd;				/* sum of isles fd */
+	double perimeter;		/* area perimeter */
+	double area;			/* area area */
+	double boundarea;		/* area of the boundary of the area */
+	double aratio;			/* ratio between the the area of the external boundary and the area of the isles */
+	double compact;			/* compact of the area */
+	double fd;				/* fd of the area */
+};
+
+extern struct value *Values;
+
+struct options
+{
+	char *name;
+	int field;
+	const char *out;;
+	char *separator;
+};
+
+extern struct options options;
+
+
+/* areas.c */
+int read_areas(struct Map_info *, int);
+
+/* parse.c */
+int parse_command_line(int, char *[]);
+
+/* export.c */
+char *join(const char*, char **, int, char *);
+int export2csv(int);

Added: grass-addons/grass7/vector/v.area.stats/main.c
===================================================================
--- grass-addons/grass7/vector/v.area.stats/main.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.area.stats/main.c	2014-01-07 16:18:18 UTC (rev 58636)
@@ -0,0 +1,67 @@
+
+/****************************************************************************
+ *
+ * MODULE:       v.to.db
+ * AUTHOR(S):    Pietro Zambelli <peter.zamb gmail com> (from v.to.db)
+ * PURPOSE:      load values from vector to database
+ * COPYRIGHT:    (C) 2000-2010 by the GRASS Development Team
+ *
+ *               This program is free software under the GNU General Public
+ *               License (>=v2). Read the file COPYING that comes with GRASS
+ *               for details.
+ *
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+struct value *Values;
+struct options options;
+
+int main(int argc, char *argv[])
+{
+	int nareas;
+	struct Map_info Map;
+	struct GModule *module;
+	struct field_info *Fi;
+
+	G_gisinit(argv[0]);
+
+	module = G_define_module();
+	G_add_keyword(_("vector"));
+	G_add_keyword(_("attribute table"));
+	G_add_keyword(_("database"));
+	module->description = _("Populates attribute values from vector features.");
+	module->overwrite = 1;
+
+	parse_command_line(argc, argv);
+
+	G_begin_distance_calculations();
+	G_begin_polygon_area_calculations();
+
+	/* open map */
+	Vect_set_open_level(2);
+	Vect_open_old(&Map, options.name, "");
+
+	Fi = Vect_get_field(&Map, options.field);
+
+	if (Fi == NULL) {
+		G_fatal_error(_("Database connection not defined for layer %d. "
+				"Use v.db.connect first."), options.field);
+	}
+
+	/* allocate array for values */
+	nareas = Vect_get_num_areas(&Map);
+	Values = (struct value *) G_calloc(nareas + 1, sizeof(struct value));
+
+	read_areas(&Map, nareas);
+	export2csv(nareas);
+
+	Vect_close(&Map);
+
+	/* free list */
+	G_free(Values);
+
+	exit(EXIT_SUCCESS);
+}

Added: grass-addons/grass7/vector/v.area.stats/parse.c
===================================================================
--- grass-addons/grass7/vector/v.area.stats/parse.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.area.stats/parse.c	2014-01-07 16:18:18 UTC (rev 58636)
@@ -0,0 +1,73 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+int parse_units();
+int parse_option();
+int match();
+
+int parse_command_line(int argc, char *argv[])
+{
+	struct
+	{
+		struct Option *vect;
+		struct Option *field;
+		struct Option *output;
+		struct Option *separator;
+	} parms;
+
+	struct
+	{
+		struct Flag *shell_style;
+		struct Flag *extended;
+		struct Flag *table;
+	} flags;
+
+
+	parms.vect = G_define_standard_option(G_OPT_V_MAP);
+
+	parms.field = G_define_standard_option(G_OPT_V_FIELD);
+	parms.field->label = _("Layer number or name (write to)");
+
+	parms.output = G_define_standard_option(G_OPT_F_OUTPUT);
+    parms.output->required = NO;
+    parms.output->description = _("Name for output file (if omitted or \"-\" output to stdout)");
+    parms.output->guisection = _("Output settings");
+
+	parms.separator = G_define_standard_option(G_OPT_F_SEP);
+	parms.separator->guisection = _("Formatting");
+
+	flags.shell_style = G_define_flag();
+	flags.shell_style->key = 'g';
+	flags.shell_style->description = _("Print the stats in shell script style");
+	flags.shell_style->guisection = _("Formatting");
+
+	flags.extended = G_define_flag();
+	flags.extended->key = 'e';
+	flags.extended->description = _("Calculate extended statistics");
+	flags.extended->guisection = _("Extended");
+
+	flags.table = G_define_flag();
+	flags.table->key = 't';
+	flags.table->description = _("Table output format instead of standard output format");
+	flags.table->guisection = _("Formatting");
+
+	if (G_parser(argc, argv))
+		exit(EXIT_FAILURE);
+
+	/* check for required options */
+	if (!parms.vect->answer)
+		G_fatal_error(_("Required parameter <%s> not set:\n\t(%s)"),
+		              parms.vect->key, parms.vect->description);
+
+	options.name = parms.vect->answer;
+	options.field = atoi(parms.field->answer);
+	
+	options.out = parms.output->answer;
+	options.separator = ";"; /* G_option_to_separator(parms.separator); */
+	printf("The separator is: <%s>", options.separator);
+
+	return 0;
+}

Added: grass-addons/grass7/vector/v.area.stats/v.area.stats.html
===================================================================


More information about the grass-commit mailing list