[GRASS-SVN] r43534 - grass/branches/develbranch_6/vector/v.in.ogr

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Sep 20 04:04:56 EDT 2010


Author: mmetz
Date: 2010-09-20 08:04:55 +0000 (Mon, 20 Sep 2010)
New Revision: 43534

Modified:
   grass/branches/develbranch_6/vector/v.in.ogr/geom.c
   grass/branches/develbranch_6/vector/v.in.ogr/global.h
Log:
speed up vector polygon import, backport from trunk

Modified: grass/branches/develbranch_6/vector/v.in.ogr/geom.c
===================================================================
--- grass/branches/develbranch_6/vector/v.in.ogr/geom.c	2010-09-20 08:03:41 UTC (rev 43533)
+++ grass/branches/develbranch_6/vector/v.in.ogr/geom.c	2010-09-20 08:04:55 UTC (rev 43534)
@@ -25,6 +25,8 @@
 #include "ogr_api.h"
 #include "global.h"
 
+int split_line(struct Map_info *Map, int otype, struct line_pnts *Points,
+	       struct line_cats *Cats);
 
 /* Add categories to centroids inside polygon */
 int
@@ -166,6 +168,35 @@
     return 0;
 }
 
+/* count polygons and isles */
+int poly_count(OGRGeometryH hGeom)
+{
+    int i, nr, ret;
+    OGRwkbGeometryType eType;
+    OGRGeometryH hRing;
+    eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));
+
+    if (eType == wkbPolygon) {
+	G_debug(3, "Polygon");
+	nr = OGR_G_GetGeometryCount(hGeom);
+	n_polygon_boundaries += nr;
+
+    }
+    else if (eType == wkbGeometryCollection || eType == wkbMultiPolygon) {
+	G_debug(3, "GeometryCollection or MultiPolygon");
+	nr = OGR_G_GetGeometryCount(hGeom);
+	for (i = 0; i < nr; i++) {
+	    hRing = OGR_G_GetGeometryRef(hGeom, i);
+
+	    ret = poly_count(hRing);
+	    if (ret == -1) {
+		G_warning(_("Cannot read part of geometry"));
+	    }
+	}
+    }
+    return 0;
+}
+
 /* Write geometry to output map */
 int
 geom(OGRGeometryH hGeom, struct Map_info *Map, int field, int cat,
@@ -223,7 +254,11 @@
 	    otype = GV_BOUNDARY;
 	else
 	    otype = GV_LINE;
-	Vect_write_line(Map, otype, Points, Cats);
+
+	if (split_distance > 0 && otype == GV_BOUNDARY)
+	    split_line(Map, otype, Points, Cats);
+	else
+	    Vect_write_line(Map, otype, Points, Cats);
     }
 
     else if (eType == wkbPolygon) {
@@ -256,7 +291,7 @@
 
 	size = G_area_of_polygon(Points->x, Points->y, Points->n_points);
 	if (size < min_area) {
-	    G_warning(_("Area size [%.1e], area not imported"), size);
+	    G_debug(2, "Area size [%.1e], area not imported", size);
 	    return 0;
 	}
 
@@ -264,8 +299,12 @@
 	    otype = GV_LINE;
 	else
 	    otype = GV_BOUNDARY;
-	Vect_write_line(Map, otype, Points, BCats);
 
+	if (split_distance > 0 && otype == GV_BOUNDARY)
+	    split_line(Map, otype, Points, Cats);
+	else
+	    Vect_write_line(Map, otype, Points, Cats);
+
 	/* Isles */
 	IPoints =
 	    (struct line_pnts **)G_malloc((nr - 1) *
@@ -298,7 +337,7 @@
 				      IPoints[valid_isles]->y,
 				      IPoints[valid_isles]->n_points);
 		if (size < min_area) {
-		    G_warning(_("Island size [%.1e], island not imported"),
+		    G_debug(2, "Island size [%.1e], island not imported",
 			      size);
 		}
 		else {
@@ -306,7 +345,11 @@
 			otype = GV_LINE;
 		    else
 			otype = GV_BOUNDARY;
-		    Vect_write_line(Map, otype, IPoints[valid_isles], BCats);
+		    if (split_distance > 0 && otype == GV_BOUNDARY)
+			split_line(Map, otype, IPoints[valid_isles], BCats);
+		    else
+			Vect_write_line(Map, otype, IPoints[valid_isles],
+					BCats);
 		}
 		valid_isles++;
 	    }
@@ -383,3 +426,52 @@
 
     return 0;
 }
+
+int split_line(struct Map_info *Map, int otype, struct line_pnts *Points,
+	       struct line_cats *Cats)
+{
+    int i;
+    double dist = 0., seg_dist, dx, dy;
+    struct line_pnts *OutPoints;
+
+    /* don't write zero length boundaries */
+    Vect_line_prune(Points);
+    if (Points->n_points < 2)
+	return 0;
+
+    /* can't split boundaries with only 2 vertices */
+    if (Points->n_points == 2) {
+	Vect_write_line(Map, otype, Points, Cats);
+	return 0;
+    }
+
+    OutPoints = Vect_new_line_struct();
+    Vect_append_point(OutPoints, Points->x[0], Points->y[0], Points->z[0]);
+    Vect_append_point(OutPoints, Points->x[1], Points->y[1], Points->z[1]);
+    dx = Points->x[1] - Points->x[0];
+    dy = Points->y[1] - Points->y[0];
+    dist = sqrt(dx * dx + dy * dy);
+
+    /* trying to keep line length smaller than split_distance
+     * alternative, less code: write line as soon as split_distance is exceeded */
+    for (i = 2; i < Points->n_points; i++) {
+	dx = Points->x[i] - Points->x[i - 1];
+	dy = Points->y[i] - Points->y[i - 1];
+	seg_dist = sqrt(dx * dx + dy * dy);
+	dist += seg_dist;
+	if (dist > split_distance) {
+	    Vect_write_line(Map, otype, OutPoints, Cats);
+	    Vect_reset_line(OutPoints);
+	    dist = seg_dist;
+	    Vect_append_point(OutPoints, Points->x[i - 1], Points->y[i - 1],
+			      Points->z[i - 1]);
+	}
+	Vect_append_point(OutPoints, Points->x[i], Points->y[i],
+			  Points->z[i]);
+    }
+    Vect_write_line(Map, otype, OutPoints, Cats);
+
+    Vect_destroy_line_struct(OutPoints);
+
+    return 0;
+}

Modified: grass/branches/develbranch_6/vector/v.in.ogr/global.h
===================================================================
--- grass/branches/develbranch_6/vector/v.in.ogr/global.h	2010-09-20 08:03:41 UTC (rev 43533)
+++ grass/branches/develbranch_6/vector/v.in.ogr/global.h	2010-09-20 08:04:55 UTC (rev 43534)
@@ -26,11 +26,14 @@
 
 #ifdef MAIN
 int n_polygons = 0;
+int n_polygon_boundaries;
+double split_distance;
 #else
 extern int n_polygons;
+extern int n_polygon_boundaries;
+extern double split_distance;
 #endif
 
-
 /* centroid structure */
 typedef struct
 {



More information about the grass-commit mailing list