[GRASS-SVN] r55855 - in grass/trunk: lib/vector/Vlib vector/v.out.postgis

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Apr 17 08:48:59 PDT 2013


Author: martinl
Date: 2013-04-17 08:48:58 -0700 (Wed, 17 Apr 2013)
New Revision: 55855

Modified:
   grass/trunk/lib/vector/Vlib/build_pg.c
   grass/trunk/lib/vector/Vlib/copy.c
   grass/trunk/lib/vector/Vlib/write_pg.c
   grass/trunk/vector/v.out.postgis/main.c
Log:
vlib(pg): various fixes related to v.out.postgis (export also attributes)


Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c	2013-04-17 14:48:46 UTC (rev 55854)
+++ grass/trunk/lib/vector/Vlib/build_pg.c	2013-04-17 15:48:58 UTC (rev 55855)
@@ -58,6 +58,11 @@
     G_debug(1, "Vect_build_pg(): db='%s' table='%s', build=%d",
             pg_info->db_name, pg_info->table_name, build);
 
+    /* commit transaction block (update mode only) */
+    if (pg_info->inTransaction && Vect__execute_pg(pg_info->conn, "COMMIT") == -1)
+        return 0;
+    pg_info->inTransaction = FALSE;
+    
     if (build == plus->built)
         return 1;            /* do nothing */
 
@@ -81,11 +86,6 @@
         return 0;
     }
 
-    /* commit transaction block (update mode only) */
-    if (pg_info->inTransaction && Vect__execute_pg(pg_info->conn, "COMMIT") == -1)
-        return 0;
-    pg_info->inTransaction = FALSE;
-    
     if (build > GV_BUILD_NONE) {
         G_message(_("Using external data format '%s' (feature type '%s')"),
                   Vect_get_finfo_format_info(Map),

Modified: grass/trunk/lib/vector/Vlib/copy.c
===================================================================
--- grass/trunk/lib/vector/Vlib/copy.c	2013-04-17 14:48:46 UTC (rev 55854)
+++ grass/trunk/lib/vector/Vlib/copy.c	2013-04-17 15:48:58 UTC (rev 55855)
@@ -96,7 +96,11 @@
             G_fatal_error(_("Unsupported feature type %d"), type);
             
         /* create feature table with given feature type */
-        Vect_write_line(Out, type, NULL, NULL);
+        if (0 > Vect_write_line(Out, type, NULL, NULL)) {
+            G_warning(_("Unable to create PostGIS layer <%s>"),
+                      Vect_get_finfo_layer_name(Out));
+            return 1;
+        }
     }
   
     /* Note: sometimes is important to copy on level 2 (pseudotopo
@@ -112,7 +116,7 @@
         
         /* copy features */
         ret += copy_lines_2(In, field, topo, Out);
-        
+
         if (topo == TOPO_NONE) {
             /* copy areas - external formats and simple features access only */
             ret += copy_areas(In, field, Out);
@@ -389,7 +393,7 @@
   \brief Copy areas as polygons (OGR/PostGIS simple features access only)
 
   \param In input vector map
-  \param field layer number (> 0)
+  \param field layer number (-1 for all layers)
   \param Out output vector map
   
   \return 0 on success
@@ -414,16 +418,24 @@
         G_debug(3, "area = %d", area);
         G_percent(area, nareas, 3);
 
-        /* get area category */
-        cat = Vect_get_area_cat(In, area, field);
-        if (cat < 0) {
-            /* no category - check if area forms an isle */
-	    /* this check does not make sense because the area
-	     * is also not exported if it is part of an isle
-	     * inside another area: the isle gets exported
-	     * as an inner ring */
+        /* get category */
+        Vect_reset_cats(Cats);
+        if (field > 0) {
+            cat = Vect_get_area_cat(In, area, field);
+            if (cat == -1)
+                continue; /* skip area without category in given layer */
+            
+            Vect_cat_set(Cats, field, cat);
+        }
+
+        /* skip isles */
+        if (Vect_get_area_centroid(In, area) == 0) {
+            /* no centroid - check if area forms an isle */
+	    /* this check does not make sense because the area is also
+	     * not exported if it is part of an isle inside another
+	     * area: the isle gets exported as an inner ring */
             if (!is_isle(In, area))
-                G_warning(_("No category defined for area %d. "
+                G_warning(_("No centroid defined for area %d. "
                             "Area not exported."),
                           area);
             continue;
@@ -432,10 +444,6 @@
         /* get outer ring (area) */
         Vect_get_area_points(In, area, Points[0]);
 
-        /* get category */
-        Vect_reset_cats(Cats);
-        Vect_cat_set(Cats, field, cat);
-        
         /* get inner rings (isles) */
         nisles = Vect_get_area_num_isles(In, area);
         if (nisles + 1 > nparts_alloc) {

Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c	2013-04-17 14:48:46 UTC (rev 55854)
+++ grass/trunk/lib/vector/Vlib/write_pg.c	2013-04-17 15:48:58 UTC (rev 55855)
@@ -548,27 +548,24 @@
     }
 
     /* prepare CREATE TABLE statement */
-    sprintf(stmt, "CREATE TABLE \"%s\".\"%s\" (%s SERIAL",
-            pg_info->schema_name, pg_info->table_name, pg_info->fid_column);
+    sprintf(stmt, "CREATE TABLE \"%s\".\"%s\" (%s SERIAL%s, %s INTEGER",
+            pg_info->schema_name, pg_info->table_name, pg_info->fid_column,
+            primary_key ? " PRIMARY KEY" : "", GV_KEY_COLUMN);
     
-    /* add primary key ? */
-    if (primary_key)
-        strcat(stmt, " PRIMARY KEY");
-    
     if (Fi) {
         /* append attributes */
         int col, ncols, sqltype, length;
         char stmt_col[DB_SQL_MAX];
         const char *colname;
 
-        dbString dbstmt;
+        dbString dbtable_name;
         dbHandle handle;
         dbDriver *driver;
         dbCursor cursor;
         dbTable *table;
         dbColumn *column;
 
-        db_init_string(&dbstmt);
+        db_init_string(&dbtable_name);
         db_init_handle(&handle);
 
         pg_info->dbdriver = driver = db_start_driver(Fi->driver);
@@ -586,20 +583,14 @@
         }
 
         /* describe table */
-        db_set_string(&dbstmt, "select * from ");
-        db_append_string(&dbstmt, Fi->table);
-        db_append_string(&dbstmt, " where 0 = 1");
-
-        if (db_open_select_cursor(driver, &dbstmt,
-                                  &cursor, DB_SEQUENTIAL) != DB_OK) {
-            G_warning(_("Unable to open select cursor: '%s'"),
-                      db_get_string(&dbstmt));
+        db_set_string(&dbtable_name, Fi->table);
+        if (db_describe_table(driver, &dbtable_name, &table) != DB_OK) {
+            G_warning(_("Unable to desribe table <%s>"),
+                      Fi->table);
             db_close_database_shutdown_driver(driver);
             pg_info->dbdriver = NULL;
             return -1;
         }
-
-        table = db_get_cursor_table(&cursor);
         ncols = db_get_table_number_of_columns(table);
 
         G_debug(3,
@@ -615,9 +606,10 @@
             G_debug(3, "\tcolumn = %d name = %s type = %d length = %d",
                     col, colname, sqltype, length);
 
-            if (strcmp(pg_info->fid_column, colname) == 0) {
+            if (strcmp(pg_info->fid_column, colname) == 0 ||
+                strcmp(GV_KEY_COLUMN, colname) == 0) {
                 /* skip fid column if exists */
-                G_debug(3, "\t%s skipped", pg_info->fid_column);
+                G_debug(3, "\t%s skipped", colname);
                 continue;
             }
 
@@ -631,7 +623,7 @@
             }
         }
 
-        db_free_string(&dbstmt);
+        db_free_string(&dbtable_name);
     }
     strcat(stmt, ")");          /* close CREATE TABLE statement */
 
@@ -641,7 +633,6 @@
     }
 
     /* create table */
-    G_debug(2, "SQL: %s", stmt);
     if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
         Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
@@ -680,7 +671,20 @@
         return -1;
     }
     
-    /* create index ? */
+    /* create indeces
+        - GV_KEY_COLUMN
+        - geometry column
+    */
+    sprintf(stmt,
+            "CREATE INDEX %s_%s_idx ON \"%s\".\"%s\" (%s)",
+            pg_info->table_name, GV_KEY_COLUMN,
+            pg_info->schema_name, pg_info->table_name,
+            GV_KEY_COLUMN);
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
+        return -1;
+    }
+
     if (spatial_index) {
         G_verbose_message(_("Building spatial index on <%s>..."),
                           pg_info->geom_column);
@@ -689,7 +693,6 @@
                 pg_info->table_name, pg_info->geom_column,
                 pg_info->schema_name, pg_info->table_name,
                 pg_info->geom_column);
-        G_debug(2, "SQL: %s", stmt);
         
         if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
             Vect__execute_pg(pg_info->conn, "ROLLBACK");
@@ -1028,20 +1031,25 @@
             return -1;
     }
     
-    Fi = NULL; /* no attributes to be written */
+    /* get category & check for attributes */
+    Fi = NULL; 
     cat = -1;
-    if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
-        /* check for attributes */
-        Fi = Vect_get_dblink(Map, 0);
-        if (Fi) {
-            if (!Vect_cat_get(cats, Fi->number, &cat))
-                G_warning(_("No category defined for layer %d"), Fi->number);
-            if (cats->n_cats > 1) {
-                G_warning(_("Feature has more categories, using "
-                            "category %d (from layer %d)"),
-                          cat, cats->field[0]);
-            }
+    if (cats->n_cats > 0) {
+        int field;
+        
+        field = cats->field[0]; /* we assume only one layer defined */
+        if (Vect_get_num_dblinks(Map) > 0) {
+            /* check for attributes */
+            Fi = Vect_get_field(Map, field);
         }
+        
+        if (!Vect_cat_get(cats, field, &cat))
+            G_warning(_("No category defined for layer %d"), field);
+        if (cats->n_cats > 1) {
+            G_warning(_("Feature has more categories, using "
+                        "category %d (from layer %d)"),
+                      cat, field);
+        }
     }
 
     sf_type = pg_info->feature_type;
@@ -1129,7 +1137,7 @@
   \param points feature geometry
   \param is_node TRUE for nodes (written as points)
   
-  \return 0 feature offset
+  \return feature id (build level >= GV_BUILD_BASE otherwise 0)
   \return -1 on error
 */
 off_t write_line_tp(struct Map_info *Map, int type, int is_node,
@@ -1170,6 +1178,9 @@
         if (create_pg_layer(Map, type) < 0)
             return -1;
     }
+
+    if (!points)
+        return 0;
     
     G_debug(3, "write_line_pg(): type = %d n_points = %d",
             type, points->n_points);
@@ -1198,7 +1209,8 @@
     line = 0;
     if (plus->built >= GV_BUILD_BASE) {
         if (is_node) {
-            dig_add_node(plus, points->x[0], points->y[0], points->z[0]);
+            /* nodes are given with negative id */
+            line = -1 * dig_add_node(plus, points->x[0], points->y[0], points->z[0]);
         }
         else {
             off_t offset;
@@ -1218,7 +1230,7 @@
     
     /* write new feature to PostGIS
        - feature table for simple features
-       - feature table and topo schema for topological access 
+       - feature table and topo schema for topological access
     */
     if (-1 == write_feature(Map, line, type, &points, 1, cat, Fi)) {
         Vect__execute_pg(pg_info->conn, "ROLLBACK");
@@ -1226,12 +1238,10 @@
     }
 
     /* update PostGIS-line topo */
-    if (plus->built >= GV_BUILD_BASE && (type & GV_LINES))
-        update_topo_edge(Map, line);
     if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY)
-        update_topo_face(Map, line);
+        update_topo_face(Map, line); /* TODO: avoid extra statements */
     
-    return line;
+    return !is_node ? line : 0;
 }
 
 /*!
@@ -1675,7 +1685,6 @@
        simple feature geometry + attributes
     */
     stmt = build_insert_stmt(pg_info, geom_data, topo_id, cat, Fi);
-    G_debug(2, "SQL: %s", stmt);
 
     /* stmt can NULL when writing PostGIS topology with no attributes
      * attached */
@@ -1870,10 +1879,21 @@
         /* no attributes */
         if (!pg_info->toposchema_name) {
             /* no attributes (simple features access) */
-            G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
-                       "('%s'::GEOMETRY)",
-                       pg_info->schema_name, pg_info->table_name,
-                       pg_info->geom_column, geom_data);
+            if (cat > 0) {
+                /* cetegory defined */
+                G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s,%s) VALUES "
+                           "(%d, '%s'::GEOMETRY)",
+                           pg_info->schema_name, pg_info->table_name,
+                           GV_KEY_COLUMN, pg_info->geom_column,
+                           cat, geom_data);
+            }
+            else {
+                /* no category */
+                G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s) VALUES "
+                           "('%s'::GEOMETRY)",
+                           pg_info->schema_name, pg_info->table_name,
+                           pg_info->geom_column, geom_data);
+            }
         }
         else {
             if (cat > 0) {
@@ -1881,7 +1901,7 @@
                 G_asprintf(&stmt, "INSERT INTO \"%s\".\"%s\" (%s,%s) VALUES "
                            "(%d, '(%d, 1, %d, %d)'::topology.TopoGeometry)",
                            pg_info->schema_name, pg_info->table_name,
-                           pg_info->fid_column, pg_info->topogeom_column, cat,
+                           GV_KEY_COLUMN, pg_info->topogeom_column, cat,
                            pg_info->toposchema_id, topo_id, topogeom_type); 
             }
 	}
@@ -1920,7 +1940,7 @@
         if (id > 0) { /* -> feature */
             topo_id = id;
             if (topo_id > Map->plus.n_lines) {
-                G_warning(_("Invalid line %d (%d)"), topo_id, Map->plus.n_lines);
+                G_warning(_("Invalid feature %d (max: %d)"), topo_id, Map->plus.n_lines);
                 return -1;
             }
             Line = Map->plus.Line[topo_id];
@@ -1974,20 +1994,42 @@
                     pg_info->toposchema_name);
             topo_id = Vect__execute_get_value_pg(pg_info->conn, stmt_id);
         }
+ 
+        nle = -topo_id; /* assuming isolated lines */
+        nre = topo_id;
         
         if (Line) {
+            int i, n, next_edge;
             struct P_topo_l *topo = (struct P_topo_l *) Line->topo;
         
             topo_id = (int)Line->offset;
+            /* start & end node */
             n1 = topo->N1;
             n2 = topo->N2;
+            
+            /* next left & right edge */
+            for (i = 0; i < 2; i++) {
+                n = Vect_get_node_n_lines(Map, i == 0 ? n1 : n2);
+                if (n < 2) /* no connection */
+                    continue;
+                
+                next_edge = update_next_edge(Map, n,
+                                             i == 0 ? topo_id : -topo_id);
+                if (next_edge != 0) {
+                    if (i == 0)
+                        nre = next_edge; /* update next right edge for start node */
+                    else
+                        nle = next_edge; /* update next left edge for end node */
+                }
+                else {
+                    G_warning(_("Unable to determine next left/right edge for edge %d"), topo_id);
+                }
+            }
         }
         else {
             G_warning(_("Unable to insert new edge. Topology not available."));
             return -1;
         }
-        nle = -topo_id; /* assuming isolated lines */
-        nre = topo_id;
         
         G_debug(3, "new edge: id=%d next_left_edge=%d next_right_edge=%d",
                 topo_id, nle, nre);
@@ -2465,7 +2507,7 @@
   \return -1 on error
 */
 int add_line_to_topo_pg(struct Map_info *Map, off_t offset, int type,
-                          const struct line_pnts *points)
+                        const struct line_pnts *points)
 {
     int line, n_nodes;
     

Modified: grass/trunk/vector/v.out.postgis/main.c
===================================================================
--- grass/trunk/vector/v.out.postgis/main.c	2013-04-17 14:48:46 UTC (rev 55854)
+++ grass/trunk/vector/v.out.postgis/main.c	2013-04-17 15:48:58 UTC (rev 55855)
@@ -138,12 +138,11 @@
     /* copy vector features & create PostGIS table*/
     if (Vect_copy_map_lines_field(&In, field, &Out) != 0)
         G_fatal_error(_("Copying features failed"));
-    
-    if (flags.topo->answer) 
-        Vect_build_partial(&Out, GV_BUILD_NONE); /* build from scratch */
-    
+
+    /* close input map */
     Vect_close(&In);
     
+    /* build topology for output map */
     if (Vect_build(&Out) != 1)
         G_fatal_error(_("Building %s topology failed"),
                       flags.topo->answer ? "PostGIS" : "pseudo");
@@ -151,6 +150,7 @@
     G_done_msg(_("Feature table <%s> created in database <%s>."),
                Vect_get_finfo_layer_name(&Out), Vect_get_finfo_dsn_name(&Out));
     
+    /* close output map */
     Vect_close(&Out);
 
     /* remove PG file */



More information about the grass-commit mailing list