Browse Source

v.out.postgis: fix type parameter issues (see https://trac.osgeo.org/grass/ticket/2460)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@70505 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa 8 years ago
parent
commit
e562f0b09a
3 changed files with 71 additions and 17 deletions
  1. 35 9
      lib/vector/Vlib/copy.c
  2. 14 6
      lib/vector/Vlib/write_pg.c
  3. 22 2
      vector/v.out.postgis/main.c

+ 35 - 9
lib/vector/Vlib/copy.c

@@ -122,7 +122,10 @@ int Vect_copy_map_lines_field(struct Map_info *In, int field,
         /* copy features */
         ret += copy_lines_2(In, field, topo, Out);
 
-        if (topo == TOPO_NONE) {
+        if (topo == TOPO_NONE &&
+            /* check output feature type, centroids can be exported as
+             * points; boundaries as linestrings */
+            strcmp(Vect_get_finfo_geometry_type(Out), "polygon") == 0) {
             /* copy areas - external formats and simple features access only */
             ret += Vect__copy_areas(In, field, Out);
         }
@@ -210,6 +213,8 @@ int copy_lines_2(struct Map_info *In, int field, int topo, struct Map_info *Out)
     struct line_pnts *Points, *CPoints, *NPoints;
     struct line_cats *Cats, *CCats;
 
+    const char *ftype = NULL;
+    
     Points  = Vect_new_line_struct();
     CPoints = Vect_new_line_struct();
     NPoints = Vect_new_line_struct();
@@ -221,8 +226,6 @@ int copy_lines_2(struct Map_info *In, int field, int topo, struct Map_info *Out)
     ret = 0;
     nlines = Vect_get_num_lines(In);
     if (topo == TOPO_NONE) {
-        const char *ftype;
-
         ftype = Vect_get_finfo_geometry_type(Out);
         G_debug(2, "feature type: %s", ftype ? ftype : "?");
         if (!ftype)
@@ -249,12 +252,35 @@ int copy_lines_2(struct Map_info *In, int field, int topo, struct Map_info *Out)
         }
         if (type == 0)
             continue;       /* dead line */
-        
-        if (topo == TOPO_NONE && (type == GV_CENTROID || type == GV_BOUNDARY)) {
-            /* OGR/PostGIS layers (simple features): centroids are
-               stored in topo polygon defined by areas (topo required)
-            */
-            continue;
+        if (In->constraint.type_flag) {
+            /* skip feature by type */
+            if (!(type & In->constraint.type))
+                continue;
+        }
+
+        if (topo == TOPO_NONE) {
+            /* OGR/PostGIS layers (simple features) */
+            int skip = FALSE;
+            
+            if (type == GV_BOUNDARY)
+                /* boundaries are written as linestrings when output
+                 * feature type is defined as 'linestring', otherwise
+                 * they are skipped */
+                if (ftype && strcmp(ftype, "linestring") != 0)
+                    skip = TRUE;
+
+            /* centroids are stored in topo polygon defined by areas
+               (topo required) */
+            if (type == GV_CENTROID) {
+                /* centroids are written as points when output feature
+                 * type is defined as 'point', otherwise they are
+                 * skipped */
+                if (ftype && strcmp(ftype, "point") != 0)
+                    skip = TRUE;
+            }
+
+            if (skip)
+                continue;
         }
 
         /* don't skips boundaries if field != -1 */

+ 14 - 6
lib/vector/Vlib/write_pg.c

@@ -1085,12 +1085,13 @@ int create_pg_layer(struct Map_info *Map, int type)
     
     switch (type) {
     case GV_POINT:
+    case GV_CENTROID:
         pg_info->feature_type = SF_POINT;
         break;
     case GV_LINE:
+    case GV_BOUNDARY:
         pg_info->feature_type = SF_LINESTRING;
         break;
-    case GV_BOUNDARY:
     case GV_AREA:
         pg_info->feature_type = SF_POLYGON;
         break;
@@ -1259,11 +1260,17 @@ off_t write_line_sf(struct Map_info *Map, int type,
             return 0;
         }
     }
-    else if (type & GV_BOUNDARY || type & GV_CENTROID) {
-        if (sf_type != SF_POLYGON) {
-            G_warning(_("Boundary/centroid skipped (output feature type: %s)"),
+    else if (type & GV_CENTROID) {
+        if (sf_type != SF_POLYGON && sf_type != SF_POINT) {
+            G_warning(_("Centroid skipped (output feature type: %s)"),
+                      Vect_get_finfo_geometry_type(Map));
+            return 0;
+        }
+    }
+    else if (type & GV_BOUNDARY) {
+        if (sf_type != SF_POLYGON && sf_type != SF_LINESTRING) {
+            G_warning(_("Boundary skipped (output feature type: %s)"),
                       Vect_get_finfo_geometry_type(Map));
-            G_warning(_("Feature is not a polygon. Skipping."));
             return 0;
         }
     }
@@ -1772,7 +1779,8 @@ char *line_to_wkb(struct Format_info_pg *pg_info,
     wkb_data = NULL;
     if (type & GV_POINTS) /* point or centroid */
         wkb_data = point_to_wkb(byte_order, points[0], with_z, &nbytes);
-    else if (type == GV_LINE)
+    else if (type == GV_LINE ||
+             (type == GV_BOUNDARY && pg_info->feature_type == SF_LINESTRING))
         wkb_data = linestring_to_wkb(byte_order, points[0], with_z, &nbytes);
     else if (type & (GV_BOUNDARY | GV_FACE | GV_AREA)) {
         if (!pg_info->toposchema_name || type == GV_AREA) {

+ 22 - 2
vector/v.out.postgis/main.c

@@ -142,11 +142,27 @@ int main(int argc, char *argv[])
         Vect_copy_map_dblinks(&In, &Out, TRUE);
 
     /* check output type */
-    if (otype > 0) { /* type is not 'auto' */
+    if (otype < 1 && Vect_level(&In) > 1) {
+        /* type 'auto' -> try to guess output feature type on level 2 */
+        if (Vect_get_num_areas(&In) > 0)
+            otype = GV_AREA;
+        else if (Vect_get_num_primitives(&In, GV_LINE) > 0)
+            otype = GV_LINE;
+        else if (Vect_get_num_primitives(&In, GV_POINT) > 0)
+            otype = GV_POINT;
+    }
+    if (otype > 0) {
+        if (otype & (GV_FACE | GV_KERNEL))
+            G_fatal_error(_("Feature type '%s' not supported"),
+                          params.type->answer);
+        
+        /* set up output feature type if possible */
         if (Vect_write_line(&Out, otype, NULL, NULL) < 0)
             G_fatal_error(_("Feature type %d is not supported"), otype);
-    }
 
+        Vect_set_constraint_type(&In, otype);
+    }
+    
     /* copy vector features & create PostGIS table */
     if (Vect_copy_map_lines_field(&In, field, &Out) != 0)
         G_fatal_error(_("Copying features failed"));
@@ -209,9 +225,13 @@ void output_handler(void *p)
     G_debug(1, "output_handler(): schema = %s; olayer = %s", pg_info->schema_name, pg_info->table_name);
     sprintf(stmt, "SELECT DropGeometryTable('%s', '%s')", pg_info->schema_name, pg_info->table_name);
     result = PQexec(pg_info->conn, stmt);
+    /*
+      be quiet - table may do not exists
+
     if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
         G_warning(_("Unable to drop table <%s.%s>"), pg_info->schema_name, pg_info->table_name);
     }
+    */
     PQclear(result);
 
     if (pg_info->toposchema_name) {