[GRASS-SVN] r71194 - grass/trunk/vector/v.net.alloc

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jun 20 02:51:11 PDT 2017


Author: mmetz
Date: 2017-06-20 02:51:11 -0700 (Tue, 20 Jun 2017)
New Revision: 71194

Modified:
   grass/trunk/vector/v.net.alloc/Makefile
   grass/trunk/vector/v.net.alloc/main.c
   grass/trunk/vector/v.net.alloc/v.net.alloc.html
Log:
v.net.alloc: add flag for unique and original categories (#517)

Modified: grass/trunk/vector/v.net.alloc/Makefile
===================================================================
--- grass/trunk/vector/v.net.alloc/Makefile	2017-06-20 09:50:49 UTC (rev 71193)
+++ grass/trunk/vector/v.net.alloc/Makefile	2017-06-20 09:51:11 UTC (rev 71194)
@@ -3,8 +3,8 @@
 
 PGM = v.net.alloc
 
-LIBES = $(VECTORLIB) $(GISLIB) $(GRAPHLIB)
-DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+LIBES = $(VECTORLIB) $(DBMILIB) $(GISLIB) $(GRAPHLIB)
+DEPENDENCIES = $(VECTORDEP) $(DBMIDEP) $(GISDEP)
 EXTRA_INC = $(VECT_INC)
 EXTRA_CFLAGS = $(VECT_CFLAGS)
 

Modified: grass/trunk/vector/v.net.alloc/main.c
===================================================================
--- grass/trunk/vector/v.net.alloc/main.c	2017-06-20 09:50:49 UTC (rev 71193)
+++ grass/trunk/vector/v.net.alloc/main.c	2017-06-20 09:51:11 UTC (rev 71194)
@@ -37,18 +37,25 @@
     struct Option *map, *output, *method_opt;
     struct Option *afield_opt, *nfield_opt, *afcol, *abcol, *ncol, *type_opt,
 	*term_opt, *tfield_opt, *tucfield_opt;
-    struct Flag *geo_f, *turntable_f;
+    struct Flag *geo_f, *turntable_f, *ucat_f;
     struct GModule *module;
     struct Map_info Map, Out;
     struct cat_list *catlist;
     CENTER *Centers = NULL;
     int acenters = 0, ncenters = 0;
     NODE *Nodes;
-    struct line_cats *Cats;
+    struct line_cats *Cats, *ICats, *OCats;
     struct line_pnts *Points, *SPoints;
     int graph_version;
     int from_centers;
 
+    /* Attribute table */
+    int unique_cats, ucat, ocat, n;
+    char buf[2000];
+    dbString sql;
+    dbDriver *driver;
+    struct field_info *Fi;
+
     /* initialize GIS environment */
     G_gisinit(argv[0]);		/* reads grass env, stores program name to G_program_name() */
 
@@ -150,12 +157,20 @@
     geo_f->description =
 	_("Use geodesic calculation for longitude-latitude locations");
 
+    ucat_f = G_define_flag();
+    ucat_f->key = 'u';
+    ucat_f->label =
+	_("Create unique categories and attribute table");
+    ucat_f->description =
+	_("Default: same category like nearest center");
+
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
     Vect_check_input_output_name(map->answer, output->answer, G_FATAL_EXIT);
 
     Cats = Vect_new_cats_struct();
+    OCats = Vect_new_cats_struct();
     Points = Vect_new_line_struct();
     SPoints = Vect_new_line_struct();
 
@@ -164,6 +179,8 @@
     catlist = Vect_new_cat_list();
     Vect_str_to_cat_list(term_opt->answer, catlist);
 
+    unique_cats = ucat_f->answer;
+
     if (geo_f->answer)
 	geo = 1;
     else
@@ -274,13 +291,63 @@
 
     Vect_hist_command(&Out);
 
+    Fi = NULL;
+    driver = NULL;
+    if (unique_cats) {
+	/* create attribute table:
+	 * cat: new category
+	 * ocat: original category in afield
+	 * centre: nearest centre
+	 */
+	Fi = Vect_default_field_info(&Out, 1, NULL, GV_MTABLE);
+	Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database,
+			    Fi->driver);
+
+	driver = db_start_driver_open_database(Fi->driver, Fi->database);
+	if (driver == NULL)
+	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+			  Fi->database, Fi->driver);
+	db_set_error_handler_driver(driver);
+
+	sprintf(buf,
+		"create table %s ( %s integer, ocat integer, center integer )",
+		Fi->table, GV_KEY_COLUMN);
+
+	db_init_string(&sql);
+	db_set_string(&sql, buf);
+	G_debug(2, "%s", db_get_string(&sql));
+
+	if (db_execute_immediate(driver, &sql) != DB_OK) {
+	    G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql));
+	}
+
+	if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK)
+	    G_warning(_("Cannot create index"));
+
+	if (db_grant_on_table
+	    (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK)
+	    G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table);
+
+	db_begin_transaction(driver);
+    }
+
     nlines = Vect_get_num_lines(&Map);
+    ucat = 1;
     for (line = 1; line <= nlines; line++) {
-	ltype = Vect_read_line(&Map, Points, NULL, line);
+	ltype = Vect_read_line(&Map, Points, ICats, line);
 	if (!(ltype & type)) {
 	    continue;
 	}
 
+	if (unique_cats) {
+	    Vect_reset_cats(OCats);
+	    for (n = 0; n < ICats->n_cats; n++) {
+		if (ICats->field[n] == afield) {
+		    Vect_cat_set(OCats, 2, ICats->cat[n]);
+		}
+	    }
+	}
+
 	if (turntable_f->answer) {
 	    center1 = Nodes[line * 2].center;
 	    center2 = Nodes[line * 2 + 1].center;
@@ -331,7 +398,30 @@
 		    cat = Centers[center1].cat;	/* line reachable */
 		else
 		    cat = Centers[center2].cat;
-		Vect_cat_set(Cats, 1, cat);
+
+		if (unique_cats) {
+		    Vect_cat_set(Cats, 1, ucat);
+		    for (n = 0; n < OCats->n_cats; n++) {
+			Vect_cat_set(Cats, 2, OCats->cat[n]);
+		    }
+		    ocat = -1;
+		    Vect_cat_get(ICats, afield, &ocat);
+
+		    sprintf(buf,
+			    "insert into %s values ( %d, %d, %d')",
+			    Fi->table, ucat, ocat, cat);
+		    db_set_string(&sql, buf);
+		    G_debug(3, "%s", db_get_string(&sql));
+
+		    if (db_execute_immediate(driver, &sql) != DB_OK) {
+			G_fatal_error(_("Cannot insert new record: %s"),
+				      db_get_string(&sql));
+		    }
+		    ucat++;
+		}
+		else
+		    Vect_cat_set(Cats, 1, cat);
+
 		Vect_write_line(&Out, ltype, Points, Cats);
 	    }
 	    else {		/* each node in different area */
@@ -340,7 +430,30 @@
 		    G_debug(3,
 			    "    -> arc is not reachable from 1. node -> alloc to 2. node");
 		    cat = Centers[center2].cat;
-		    Vect_cat_set(Cats, 1, cat);
+
+		    if (unique_cats) {
+			Vect_cat_set(Cats, 1, ucat);
+			for (n = 0; n < OCats->n_cats; n++) {
+			    Vect_cat_set(Cats, 2, OCats->cat[n]);
+			}
+			ocat = -1;
+			Vect_cat_get(ICats, afield, &ocat);
+
+			sprintf(buf,
+				"insert into %s values ( %d, %d, %d')",
+				Fi->table, ucat, ocat, cat);
+			db_set_string(&sql, buf);
+			G_debug(3, "%s", db_get_string(&sql));
+
+			if (db_execute_immediate(driver, &sql) != DB_OK) {
+			    G_fatal_error(_("Cannot insert new record: %s"),
+					  db_get_string(&sql));
+			}
+			ucat++;
+		    }
+		    else
+			Vect_cat_set(Cats, 1, cat);
+
 		    Vect_write_line(&Out, ltype, Points, Cats);
 		    continue;
 		}
@@ -348,7 +461,30 @@
 		    G_debug(3,
 			    "    -> arc is not reachable from 2. node -> alloc to 1. node");
 		    cat = Centers[center1].cat;
-		    Vect_cat_set(Cats, 1, cat);
+
+		    if (unique_cats) {
+			Vect_cat_set(Cats, 1, ucat);
+			for (n = 0; n < OCats->n_cats; n++) {
+			    Vect_cat_set(Cats, 2, OCats->cat[n]);
+			}
+			ocat = -1;
+			Vect_cat_get(ICats, afield, &ocat);
+
+			sprintf(buf,
+				"insert into %s values ( %d, %d, %d')",
+				Fi->table, ucat, ocat, cat);
+			db_set_string(&sql, buf);
+			G_debug(3, "%s", db_get_string(&sql));
+
+			if (db_execute_immediate(driver, &sql) != DB_OK) {
+			    G_fatal_error(_("Cannot insert new record: %s"),
+					  db_get_string(&sql));
+			}
+			ucat++;
+		    }
+		    else
+			Vect_cat_set(Cats, 1, cat);
+
 		    Vect_write_line(&Out, ltype, Points, Cats);
 		    continue;
 		}
@@ -362,12 +498,59 @@
 		 * Note this check also possibility of (e1cost + e2cost) = 0 */
 		if (s1cost + e1cost <= s2cost) {	/* whole arc reachable from node1 */
 		    cat = Centers[center1].cat;
-		    Vect_cat_set(Cats, 1, cat);
+
+		    Vect_reset_cats(Cats);
+		    if (unique_cats) {
+			Vect_cat_set(Cats, 1, ucat);
+			for (n = 0; n < OCats->n_cats; n++) {
+			    Vect_cat_set(Cats, 2, OCats->cat[n]);
+			}
+			ocat = -1;
+			Vect_cat_get(ICats, afield, &ocat);
+
+			sprintf(buf,
+				"insert into %s values ( %d, %d, %d')",
+				Fi->table, ucat, ocat, cat);
+			db_set_string(&sql, buf);
+			G_debug(3, "%s", db_get_string(&sql));
+
+			if (db_execute_immediate(driver, &sql) != DB_OK) {
+			    G_fatal_error(_("Cannot insert new record: %s"),
+					  db_get_string(&sql));
+			}
+			ucat++;
+		    }
+		    else
+			Vect_cat_set(Cats, 1, cat);
+
 		    Vect_write_line(&Out, ltype, Points, Cats);
 		}
 		else if (s2cost + e2cost <= s1cost) {	/* whole arc reachable from node2 */
 		    cat = Centers[center2].cat;
-		    Vect_cat_set(Cats, 1, cat);
+
+		    if (unique_cats) {
+			Vect_cat_set(Cats, 1, ucat);
+			for (n = 0; n < OCats->n_cats; n++) {
+			    Vect_cat_set(Cats, 2, OCats->cat[n]);
+			}
+			ocat = -1;
+			Vect_cat_get(ICats, afield, &ocat);
+
+			sprintf(buf,
+				"insert into %s values ( %d, %d, %d')",
+				Fi->table, ucat, ocat, cat);
+			db_set_string(&sql, buf);
+			G_debug(3, "%s", db_get_string(&sql));
+
+			if (db_execute_immediate(driver, &sql) != DB_OK) {
+			    G_fatal_error(_("Cannot insert new record: %s"),
+					  db_get_string(&sql));
+			}
+			ucat++;
+		    }
+		    else
+			Vect_cat_set(Cats, 1, cat);
+
 		    Vect_write_line(&Out, ltype, Points, Cats);
 		}
 		else {		/* split */
@@ -395,7 +578,30 @@
 		    }
 		    else {
 			cat = Centers[center1].cat;
-			Vect_cat_set(Cats, 1, cat);
+
+			if (unique_cats) {
+			    Vect_cat_set(Cats, 1, ucat);
+			    for (n = 0; n < OCats->n_cats; n++) {
+				Vect_cat_set(Cats, 2, OCats->cat[n]);
+			    }
+			    ocat = -1;
+			    Vect_cat_get(ICats, afield, &ocat);
+
+			    sprintf(buf,
+				    "insert into %s values ( %d, %d, %d')",
+				    Fi->table, ucat, ocat, cat);
+			    db_set_string(&sql, buf);
+			    G_debug(3, "%s", db_get_string(&sql));
+
+			    if (db_execute_immediate(driver, &sql) != DB_OK) {
+				G_fatal_error(_("Cannot insert new record: %s"),
+					      db_get_string(&sql));
+			    }
+			    ucat++;
+			}
+			else
+			    Vect_cat_set(Cats, 1, cat);
+
 			Vect_write_line(&Out, ltype, SPoints, Cats);
 		    }
 
@@ -408,7 +614,30 @@
 		    else {
 			Vect_reset_cats(Cats);
 			cat = Centers[center2].cat;
-			Vect_cat_set(Cats, 1, cat);
+
+			if (unique_cats) {
+			    Vect_cat_set(Cats, 1, ucat);
+			    for (n = 0; n < OCats->n_cats; n++) {
+				Vect_cat_set(Cats, 2, OCats->cat[n]);
+			    }
+			    ocat = -1;
+			    Vect_cat_get(ICats, afield, &ocat);
+
+			    sprintf(buf,
+				    "insert into %s values ( %d, %d, %d')",
+				    Fi->table, ucat, ocat, cat);
+			    db_set_string(&sql, buf);
+			    G_debug(3, "%s", db_get_string(&sql));
+
+			    if (db_execute_immediate(driver, &sql) != DB_OK) {
+				G_fatal_error(_("Cannot insert new record: %s"),
+					      db_get_string(&sql));
+			    }
+			    ucat++;
+			}
+			else
+			    Vect_cat_set(Cats, 1, cat);
+
 			Vect_write_line(&Out, ltype, SPoints, Cats);
 		    }
 		}
@@ -417,10 +646,37 @@
 	else {
 	    /* arc is not reachable */
 	    G_debug(3, "  -> arc is not reachable");
+	    if (unique_cats) {
+		Vect_cat_set(Cats, 1, ucat);
+		for (n = 0; n < OCats->n_cats; n++) {
+		    Vect_cat_set(Cats, 2, OCats->cat[n]);
+		}
+		ocat = -1;
+		Vect_cat_get(ICats, afield, &ocat);
+
+		sprintf(buf,
+			"insert into %s values ( %d, %d, %d)",
+			Fi->table, ucat, ocat, -1);
+		db_set_string(&sql, buf);
+		G_debug(3, "%s", db_get_string(&sql));
+
+		if (db_execute_immediate(driver, &sql) != DB_OK) {
+		    G_fatal_error(_("Cannot insert new record: %s"),
+				  db_get_string(&sql));
+		}
+		ucat++;
+	    }
 	    Vect_write_line(&Out, ltype, Points, Cats);
 	}
     }
 
+    if (unique_cats) {
+	db_commit_transaction(driver);
+	db_close_database_shutdown_driver(driver);
+
+	Vect_copy_table(&Map, &Out, afield, 2, NULL, GV_MTABLE);
+    }
+
     Vect_build(&Out);
 
     /* Free, ... */

Modified: grass/trunk/vector/v.net.alloc/v.net.alloc.html
===================================================================
--- grass/trunk/vector/v.net.alloc/v.net.alloc.html	2017-06-20 09:50:49 UTC (rev 71193)
+++ grass/trunk/vector/v.net.alloc/v.net.alloc.html	2017-06-20 09:51:11 UTC (rev 71194)
@@ -23,6 +23,15 @@
 nearest center or costs to the nearest center with option 
 <b>method</b>. See example below.
 <p>
+By default, the category value of the nearest center is used as 
+category value for output lines. With the <b>-u</b> flag, output lines 
+become unique categories and an attribute table is created with the 
+fields <em>cat, ocat, center</em>. The <em>ocat</em> field holds the 
+original line category in <b>arc_layer</b> and the <em>center</em> 
+field holds the center category in <b>node_layer</b>. Additionally, 
+original line categories are copied from the input <b>arc_layer</b> to 
+layer 2 in the output, together with any attribute table.
+<p>
 Application of flag <b>-t</b> enables a turntable support. 
 This flag requires additional parameters <b>turn_layer</b> and <b>turn_cat_layer</b> 
 that are otherwise ignored.



More information about the grass-commit mailing list