[GRASS-SVN] r52776 - grass/trunk/lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Aug 20 07:07:12 PDT 2012


Author: mmetz
Date: 2012-08-20 07:07:12 -0700 (Mon, 20 Aug 2012)
New Revision: 52776

Modified:
   grass/trunk/lib/vector/Vlib/build.c
   grass/trunk/lib/vector/Vlib/cats.c
   grass/trunk/lib/vector/Vlib/field.c
   grass/trunk/lib/vector/Vlib/map.c
   grass/trunk/lib/vector/Vlib/read.c
   grass/trunk/lib/vector/Vlib/remove_areas.c
Log:
Vlib fix for multiple cats in the same layer

Modified: grass/trunk/lib/vector/Vlib/build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build.c	2012-08-20 14:06:32 UTC (rev 52775)
+++ grass/trunk/lib/vector/Vlib/build.c	2012-08-20 14:07:12 UTC (rev 52776)
@@ -745,16 +745,17 @@
 */
 void Vect__build_downgrade(struct Map_info *Map, int build)
 {
-    int line;
+    int line, area;
     struct Plus_head *plus;
     struct P_line *Line;
+    struct P_area *Area;
     
     plus = &(Map->plus);
     
     /* lower level request - release old sources (this also
        initializes structures and numbers of elements) */
     if (plus->built >= GV_BUILD_CENTROIDS && build < GV_BUILD_CENTROIDS) {
-        /* reset info about areas stored for centroids */
+        /* reset info about centroids stored for areas */
         for (line = 1; line <= plus->n_lines; line++) {
             Line = plus->Line[line];
             if (Line && Line->type == GV_CENTROID) {
@@ -762,10 +763,13 @@
                 topo->area = 0;
             }
         }
-        dig_free_plus_areas(plus);
-        dig_spidx_free_areas(plus);
-        dig_free_plus_isles(plus);
-        dig_spidx_free_isles(plus);
+        /* reset info about areas stored for centroids */
+        for (area = 1; area <= plus->n_areas; area++) {
+            Area = plus->Area[area];
+	    if (Area)
+		Area->centroid = 0;
+        }
+	/* keep areas and isles */
     }
     
     if (plus->built >= GV_BUILD_AREAS && build < GV_BUILD_AREAS) {

Modified: grass/trunk/lib/vector/Vlib/cats.c
===================================================================
--- grass/trunk/lib/vector/Vlib/cats.c	2012-08-20 14:06:32 UTC (rev 52775)
+++ grass/trunk/lib/vector/Vlib/cats.c	2012-08-20 14:07:12 UTC (rev 52776)
@@ -275,6 +275,7 @@
 	    }
 	    Cats->n_cats--;
 	    found = 1;
+	    n--;		/* check again this position */
 	}
     }
 

Modified: grass/trunk/lib/vector/Vlib/field.c
===================================================================
--- grass/trunk/lib/vector/Vlib/field.c	2012-08-20 14:06:32 UTC (rev 52775)
+++ grass/trunk/lib/vector/Vlib/field.c	2012-08-20 14:07:12 UTC (rev 52776)
@@ -232,27 +232,37 @@
   \brief Add new DB connection to dblinks structure
   
   \param[in,out] p pointer to existing dblinks structure
-  \param number layer number (1 for OGR)
-  \param name   layer name (layer for OGR) - if not given use table name
-  \param table  table name (layer for OGR)
-  \param key    key name
-  \param db     database name (datasource for OGR)
-  \param driver driver name (dbf, postgresql, ogr, ...)
+  \param number  layer number (1 for OGR)
+  \param lname   layer name (layer for OGR) - if not given use table name
+  \param table   table name (layer for OGR)
+  \param key     key name
+  \param db      database name (datasource for OGR)
+  \param driver  driver name (dbf, postgresql, ogr, ...)
   
   \return 0 on success
   \return -1 error
  */
-int Vect_add_dblink(struct dblinks *p, int number, const char *name,
+int Vect_add_dblink(struct dblinks *p, int number, const char *lname,
 		    const char *table, const char *key, const char *db,
 		    const char *driver)
 {
     int ret;
+    char *name = NULL;
 
     G_debug(3, "Field number <%d>, name <%s>", number, name);
-    if (!name) {
-	/* if name is not given, use table name */
-	name = table;
+    if (lname) {
+	name = G_store(lname);
     }
+    else if (table) {
+	/* if layer name is not given, use table name */
+	name = G_store(table);
+    }
+    if (name) {
+	/* replace all spaces with underscore, otherwise dbln can't be read */
+	G_strip(name);
+	G_strchg(name, ' ', '_');
+    }
+
     ret = Vect_check_dblink(p, number, name);
     if (ret == 1) {
 	G_warning(_("Layer number %d or name <%s> already exists"), number,
@@ -269,11 +279,8 @@
 
     p->field[p->n_fields].number = number;
 
-    if (name != NULL) {
-	p->field[p->n_fields].name = G_store(name);
-	/* replace all spaces with underscore, otherwise dbln can't be read */
-	G_strchg(p->field[p->n_fields].name, ' ', '_');
-    }
+    if (name != NULL)
+	p->field[p->n_fields].name = name;
     else
 	p->field[p->n_fields].name = NULL;
 
@@ -307,17 +314,18 @@
   
   \param Map pointer to Map_info structure
   \param field layer number
-  \param field_name layer name
+  \param name layer name
   \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE 
 
   \return pointer to allocated field_info structure
  */
 struct field_info *Vect_default_field_info(struct Map_info *Map,
-					   int field, const char *field_name, int type)
+					   int field, const char *name, int type)
 {
     struct field_info *fi;
     char buf[GNAME_MAX], buf2[GNAME_MAX];
     const char *schema;
+    char *field_name = NULL;
     dbConnection connection;
 
     G_debug(1, "Vect_default_field_info(): map = %s field = %d", Map->name,
@@ -361,6 +369,11 @@
 	sprintf(buf, "%s", Map->name);
     }
     else {
+	if (name) {
+	    field_name = G_store(name);
+	    G_strip(field_name);
+	    G_strchg(field_name, ' ', '_');
+	}
 	if (field_name != NULL && strlen(field_name) > 0)
 	    sprintf(buf, "%s_%s", Map->name, field_name);
 	else
@@ -376,8 +389,10 @@
     }
 
     /* Field name */
-    if (field_name)
+    if (field_name) {
 	fi->name = G_store(field_name);
+	G_free(field_name);
+    }
     else
 	fi->name = G_store(buf);
 

Modified: grass/trunk/lib/vector/Vlib/map.c
===================================================================
--- grass/trunk/lib/vector/Vlib/map.c	2012-08-20 14:06:32 UTC (rev 52775)
+++ grass/trunk/lib/vector/Vlib/map.c	2012-08-20 14:07:12 UTC (rev 52776)
@@ -39,7 +39,7 @@
  */
 static int copy_file(const char *src, const char *dst)
 {
-    char buf[1024];
+    char buf[4096];
     int fd, fd2;
     FILE *f2;
     int len, len2;
@@ -55,7 +55,7 @@
 
     fd2 = fileno(f2);
 
-    while ((len = read(fd, buf, 1024)) > 0) {
+    while ((len = read(fd, buf, sizeof(buf))) > 0) {
         while (len && (len2 = write(fd2, buf, len)) >= 0)
             len -= len2;
     }

Modified: grass/trunk/lib/vector/Vlib/read.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read.c	2012-08-20 14:06:32 UTC (rev 52775)
+++ grass/trunk/lib/vector/Vlib/read.c	2012-08-20 14:07:12 UTC (rev 52776)
@@ -138,11 +138,11 @@
 /*!
    \brief Read vector feature
 
-   This function implements random access. Note that constraits are
-   ignored!
+   This function implements random access. Note that constraints are
+   ignored! Needs at least GV_BUILD_BASE topology.
 
    G_fatal_error() is called on failure.
-   
+
    \param Map pointer to vector map
    \param[out] line_p feature geometry
    (pointer to line_pnts struct)

Modified: grass/trunk/lib/vector/Vlib/remove_areas.c
===================================================================
--- grass/trunk/lib/vector/Vlib/remove_areas.c	2012-08-20 14:06:32 UTC (rev 52775)
+++ grass/trunk/lib/vector/Vlib/remove_areas.c	2012-08-20 14:07:12 UTC (rev 52776)
@@ -31,7 +31,7 @@
    \return number of removed areas 
  */
 int
-Vect_remove_small_areas(struct Map_info *Map, double thresh,
+Vect_remove_small_areas_org(struct Map_info *Map, double thresh,
 			struct Map_info *Err, double *removed_area)
 {
     int area, nareas;
@@ -101,7 +101,7 @@
 	}
 	G_debug(3, "num neighbours = %d", AList->n_values);
 
-	/* Go through the list of neghours and find that with the longest boundary */
+	/* Go through the list of neighours and find that with the longest boundary */
 	dissolve_neighbour = 0;
 	length = -1.0;
 	for (i = 0; i < AList->n_values; i++) {
@@ -178,3 +178,129 @@
 
     return (nremoved);
 }
+
+int
+Vect_remove_small_areas(struct Map_info *Map, double thresh,
+			struct Map_info *Err, double *removed_area)
+{
+    int area, nareas;
+    int nremoved = 0;
+    struct ilist *List;
+    struct ilist *AList;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    double size_removed = 0.0;
+    int left, right, dissolve_neighbour;
+
+    List = Vect_new_list();
+    AList = Vect_new_list();
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    nareas = Vect_get_num_areas(Map);
+    for (area = 1; area <= Vect_get_num_areas(Map); area++) {
+	int i, centroid, remove_boundary;
+	double length, size;
+
+	if (area <= nareas)
+	    G_percent(area, nareas, 1);
+	G_debug(3, "area = %d", area);
+	if (!Vect_area_alive(Map, area))
+	    continue;
+
+	size = Vect_get_area_area(Map, area);
+	if (size > thresh)
+	    continue;
+	size_removed += size;
+
+	/* The area is smaller than the limit -> remove */
+
+	/* Remove centroid */
+	centroid = Vect_get_area_centroid(Map, area);
+	if (centroid > 0) {
+	    if (Err) {
+		Vect_read_line(Map, Points, Cats, centroid);
+		Vect_write_line(Err, GV_CENTROID, Points, Cats);
+	    }
+	    Vect_delete_line(Map, centroid);
+	}
+
+	/* Find the adjacent area with which the longest boundary is shared */
+
+	Vect_get_area_boundaries(Map, area, List);
+
+	/* Go through the list of boundaries and find the longest boundary */
+	remove_boundary = 0;
+	length = -1.0;
+	for (i = 0; i < List->n_values; i++) {
+	    int line;
+	    double l = 0.0;
+
+	    line = List->value[i];
+	    G_debug(4, "   line = %d", line);
+
+	    Vect_read_line(Map, Points, NULL, abs(line));
+	    l = Vect_line_length(Points);
+
+	    if (l > length) {
+		length = l;
+		remove_boundary = line;
+	    }
+	}
+
+	G_debug(3, "remove_boundary = %d", remove_boundary);
+
+	Vect_get_line_areas(Map, abs(remove_boundary), &left, &right);
+	if (remove_boundary > 0)
+	    dissolve_neighbour = left;
+	else
+	    dissolve_neighbour = right;
+
+	G_debug(3, "dissolve_neighbour = %d", dissolve_neighbour);
+
+	/* Make list of boundaries to be removed */
+	Vect_reset_list(AList);
+	for (i = 0; i < List->n_values; i++) {
+	    int line, neighbour;
+
+	    line = List->value[i];
+	    Vect_get_line_areas(Map, abs(line), &left, &right);
+	    if (line > 0)
+		neighbour = left;
+	    else
+		neighbour = right;
+
+	    G_debug(3, "   neighbour = %d", neighbour);
+
+	    if (neighbour == dissolve_neighbour) {
+		Vect_list_append(AList, abs(line));
+	    }
+	}
+
+	/* Remove boundaries */
+	for (i = 0; i < AList->n_values; i++) {
+	    int line;
+
+	    line = AList->value[i];
+
+	    if (Err) {
+		Vect_read_line(Map, Points, Cats, line);
+		Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
+	    }
+	    Vect_delete_line(Map, line);
+	}
+
+	nremoved++;
+    }
+
+    if (removed_area)
+	*removed_area = size_removed;
+
+    G_verbose_message(_("%d areas of total size %g removed"), nremoved,
+		size_removed);
+
+    Vect_build_partial(Map, GV_BUILD_BASE);
+    Vect_merge_lines(Map, GV_BOUNDARY, NULL, NULL);
+
+    return (nremoved);
+}



More information about the grass-commit mailing list