Ver código fonte

simple features API: initial support for Polygon added

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@39377 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa 15 anos atrás
pai
commit
decec7fdd2

+ 1 - 0
include/vect/dig_defines.h

@@ -233,5 +233,6 @@ typedef enum overlay_operator OVERLAY_OPERATOR;
 #define SF_LINE	      0x02
 #define SF_LINESTRING 0x04
 #define SF_LINEARRING 0x08
+#define SF_POLYGON    0x10
 
 #define HEADSTR	50

+ 43 - 2
lib/vector/Vlib/ascii.c

@@ -348,7 +348,7 @@ int Vect_write_ascii(FILE *ascii,
 		db_close_database(driver);
 		db_shutdown_driver(driver);
 	    }
-	    return n_lines;
+	    break;
 	}
 
 	if (format == GV_ASCII_FORMAT_POINT && !(type & GV_POINTS))
@@ -559,6 +559,8 @@ int Vect_write_ascii(FILE *ascii,
 	    }
 	}
 	else if (format == GV_ASCII_FORMAT_WKT) {
+	    if (type & (GV_BOUNDARY | GV_CENTROID | GV_FACE | GV_KERNEL))
+		continue;
 	    /* Well-Known Text */
 	    Vect_sfa_write_line_wkt(Points, type, Vect_is_3d(Map), dp, ascii);
 	}
@@ -568,7 +570,46 @@ int Vect_write_ascii(FILE *ascii,
 	n_lines++;
     }
 
-    /* not reached */
+    if (format == GV_ASCII_FORMAT_WKT) {
+	/* process areas - topology required */
+	int i, area, nareas, isle, nisles;
+	if (Vect_level(Map) < 2) {
+	    G_warning(_("Topology not available, unable to process areas"));
+	    nareas = 0;
+	}
+	else {
+	    nareas = Vect_get_num_areas(Map);
+	}
+	for (area = 1; area <= nareas; area++) {
+	    if (!Vect_area_alive(Map, area)) /* skip dead areas */
+		continue;
+	    if (Vect_get_area_cat(Map, area, field) < 0)
+		continue;
+	    /* get boundary -> linearring */
+	    if (Vect_get_area_points(Map, area, Points) < 0) {
+		G_warning(_("Unable to get boundary of area id %d"), area);
+		continue;
+	    }
+	    fprintf(ascii, "POLYGON(");
+	    /* write outter ring */
+	    Vect_sfa_write_line_wkt(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
+	    /* get isles (holes) -> inner rings */
+	    nisles = Vect_get_area_num_isles(Map, area);
+	    for (i = 0; i < nisles; i++) {
+		/* get isle boundary -> linearring */
+		isle = Vect_get_area_isle(Map, area, i);
+		if (Vect_get_isle_points(Map, isle, Points) < 0) {
+		    G_warning(_("Unable to get boundary of isle id %d (area id %d)"), isle, area);
+		    continue;
+		}
+		fprintf(ascii, ", ");
+		/* write inner ring */
+		Vect_sfa_write_line_wkt(Points, GV_BOUNDARY, 0, dp, ascii); /* boundary is always 2D */
+	    }
+	    fprintf(ascii, ")\n");
+	}
+    }
+
     return n_lines;
 }
 

+ 24 - 2
lib/vector/Vlib/simple_features.c

@@ -74,7 +74,7 @@ int Vect_sfa_check_line_type(const struct line_pnts *Points, int type, int sftyp
 */
 void Vect_sfa_write_line_wkt(const struct line_pnts *Points, int type, int with_z, int precision, FILE *file)
 {
-    int sftype;
+    int i, sftype;
     
     sftype = Vect_sfa_get_line_type(Points, type, with_z);
     
@@ -86,7 +86,6 @@ void Vect_sfa_write_line_wkt(const struct line_pnts *Points, int type, int with_
 	break;
     }
     case SF_LINESTRING: case SF_LINE: case SF_LINEARRING: {
-	int i;
 	if (sftype == SF_LINESTRING)
 	    fprintf(file, "LINESTRING(");
 	else if (sftype ==  SF_LINE)
@@ -101,6 +100,17 @@ void Vect_sfa_write_line_wkt(const struct line_pnts *Points, int type, int with_
 	fprintf(file, ")\n");
 	break;
     }
+    case SF_POLYGON: {
+	/* write only outter/inner ring */
+	fprintf(file, "(");
+	for (i = 0; i < Points->n_points; i++) {
+	    print_point(Points, i, with_z, precision, file);
+	    if (i < Points->n_points - 1)
+		fprintf(file, ", ");
+	}
+	fprintf(file, ")");
+	break;
+    }
     default: {
 	G_warning(_("Unknown Simple Features type (%d)"), sftype);
 	break;
@@ -136,6 +146,15 @@ int check_sftype(const struct line_pnts *points, int type, int sftype, int with_
 	}
     }
 
+    if (type == GV_BOUNDARY) {
+	int num = Vect_get_num_line_points(points);
+	if (sftype == SF_POLYGON &&
+	    points->x[0] == points->x[num-1] &&
+	    points->y[0] == points->y[num-1]) {
+	    return 1;
+	}
+    }
+
     return 0;
 }
 
@@ -153,6 +172,9 @@ int get_sftype(const struct line_pnts *points, int type, int with_z)
     if (check_sftype(points, type, SF_LINESTRING, with_z))
 	return SF_LINESTRING;
 
+    if (check_sftype(points, type, SF_POLYGON, with_z))
+	return SF_POLYGON;
+
     return -1;
 }
 

+ 11 - 3
vector/v.out.ascii/main.c

@@ -66,10 +66,18 @@ int main(int argc, char *argv[])
 	G_fatal_error(_("'output' must be given for old version"));
     }
 
-    Vect_set_open_level(1);	/* only need level I */
-    if (Vect_open_old(&Map, input, "") < 0)
-	G_fatal_error(_("Unable to open vector map <%s>"),
+    if (format != GV_ASCII_FORMAT_WKT) {
+	Vect_set_open_level(1);	/* topology not needed */
+	if (Vect_open_old(&Map, input, "") < 0)
+	    G_fatal_error(_("Unable to open vector map <%s>"),
+			  input);
+    }
+    else {
+	if (Vect_open_old(&Map, input, "") < 2) /* topology required for polygons */
+	    G_warning(_("Unable to open vector map <%s> at topology level. "
+			"Only points, lines can be processed."),
 		      input);
+    }
     
     if (strcmp(output, "-") != 0) {
 	if (ver == 4) {