[GRASS-SVN] r53686 - in grass/trunk: include/defs lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Nov 5 01:34:48 PST 2012


Author: martinl
Date: 2012-11-05 01:34:48 -0800 (Mon, 05 Nov 2012)
New Revision: 53686

Added:
   grass/trunk/lib/vector/Vlib/local_proto.h
Modified:
   grass/trunk/include/defs/vector.h
   grass/trunk/lib/vector/Vlib/build_nat.c
   grass/trunk/lib/vector/Vlib/build_pg.c
   grass/trunk/lib/vector/Vlib/build_sfa.c
   grass/trunk/lib/vector/Vlib/close_pg.c
   grass/trunk/lib/vector/Vlib/copy.c
   grass/trunk/lib/vector/Vlib/e_intersect.c
   grass/trunk/lib/vector/Vlib/open_pg.c
   grass/trunk/lib/vector/Vlib/pg_local_proto.h
   grass/trunk/lib/vector/Vlib/read_pg.c
   grass/trunk/lib/vector/Vlib/rewind_pg.c
   grass/trunk/lib/vector/Vlib/write.c
   grass/trunk/lib/vector/Vlib/write_nat.c
   grass/trunk/lib/vector/Vlib/write_pg.c
Log:
PG topo support major update 
   V2__write_line_pg() and V2__write_node_pg() implemented
   internal subroutines renamed (use Vect__ prefix)
   move some internal subroutines to local_proto.h


Modified: grass/trunk/include/defs/vector.h
===================================================================
--- grass/trunk/include/defs/vector.h	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/include/defs/vector.h	2012-11-05 09:34:48 UTC (rev 53686)
@@ -541,6 +541,8 @@
                         const struct line_cats *);
 off_t V2_write_line_sfa(struct Map_info *, int, const struct line_pnts *,
                         const struct line_cats *);
+off_t V2_write_line_pg(struct Map_info *, int, const struct line_pnts *,
+                       const struct line_cats *);
 off_t V1_rewrite_line_nat(struct Map_info *, int, int, off_t,
                           const struct line_pnts *, const struct line_cats *);
 off_t V1_rewrite_line_ogr(struct Map_info *, int, int, off_t,
@@ -551,9 +553,6 @@
                           const struct line_pnts *, const struct line_cats *);
 off_t V2_rewrite_line_sfa(struct Map_info *, int, int, off_t,
                           const struct line_pnts *, const struct line_cats *);
-off_t V2_write_area_pg(struct Map_info *, const struct line_pnts *,
-                       const struct line_cats *,
-                       const struct line_pnts **, int);
 
     /* Build topology */
 int Vect_build_nat(struct Map_info *, int);

Modified: grass/trunk/lib/vector/Vlib/build_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_nat.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/build_nat.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -61,7 +61,7 @@
     Cats = Vect_new_cats_struct();
     
     if (plus->built < GV_BUILD_BASE) {
-	register int npoints, c;
+      int npoints, c;
 
 	/* 
 	 *  We shall go through all primitives in coor file and add
@@ -78,7 +78,8 @@
 	    /* register line */
 	    type = Vect_read_next_line(Map, Points, Cats);
 
-	    /* Note: check for dead lines is not needed, because they are skipped by V1_read_next_line_nat() */
+	    /* Note: check for dead lines is not needed, because they
+               are skipped by V1_read_next_line() */
 	    if (type == -1) {
 		G_warning(_("Unable to read vector map"));
 		return 0;

Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/build_pg.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -78,8 +78,8 @@
     }
 
     /* commit transaction block (update mode only) */
-    if (pg_info->inTransaction && execute(pg_info->conn, "COMMIT") == -1)
-	return -1;
+    if (pg_info->inTransaction && Vect__execute_pg(pg_info->conn, "COMMIT") == -1)
+	return 0;
 
     pg_info->inTransaction = FALSE;
 
@@ -135,13 +135,19 @@
         return 0;
     }
     
+    /* read topology from PostGIS ???
     if (plus->built < GV_BUILD_BASE) {
         if (load_plus(Map, FALSE) != 0)
             return 0;
     }
+    */
+
+    /* build GRASS-like topology from PostGIS topological
+       primitives */
+    if (Vect_build_nat(Map, build) != 1)
+        return 0;
     
-    plus->built = build;
-    
+    /* update PostGIS topology based on GRASS-like topology */
     return 1;
 }
 #endif

Modified: grass/trunk/lib/vector/Vlib/build_sfa.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_sfa.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/build_sfa.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -329,7 +329,7 @@
     G_zero(&fparts, sizeof(struct feat_parts));
     
     /* get all features */
-    if (set_initial_query(pg_info, TRUE) != 0)
+    if (Vect__set_initial_query_pg(pg_info, TRUE) != 0)
         return;
     
     /* scan records */
@@ -345,8 +345,8 @@
 	G_progress(iFeature + 1, 1e4);
 
 	/* cache feature (lines) */
-	if (SF_NONE == cache_feature(wkb_data, FALSE, FALSE,
-                                     &(pg_info->cache), &fparts)) {
+	if (SF_NONE == Vect__cache_feature_pg(wkb_data, FALSE, FALSE,
+                                              &(pg_info->cache), &fparts)) {
 	    G_warning(_("Feature %d without geometry skipped"),
 		      iFeature + 1);
 	    continue;

Modified: grass/trunk/lib/vector/Vlib/close_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/close_pg.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/close_pg.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -61,11 +61,11 @@
 
         sprintf(stmt, "CLOSE %s_%s%p",
                 pg_info->schema_name, pg_info->table_name, pg_info->conn);
-        if (execute(pg_info->conn, stmt) == -1) {
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
             G_warning(_("Unable to close cursor"));
             return -1;
         }
-        execute(pg_info->conn, "COMMIT");
+        Vect__execute_pg(pg_info->conn, "COMMIT");
     }
 
     PQfinish(pg_info->conn);

Modified: grass/trunk/lib/vector/Vlib/copy.c
===================================================================
--- grass/trunk/lib/vector/Vlib/copy.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/copy.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -18,6 +18,10 @@
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+#ifdef HAVE_POSTGRES
+#include "pg_local_proto.h"
+#endif
+
 static int copy_lines_1(struct Map_info *, int, struct Map_info *);
 static int copy_lines_2(struct Map_info *, int, int, struct Map_info *);
 static int copy_nodes(const struct Map_info *, struct Map_info *);
@@ -44,7 +48,7 @@
 
    Note: Try to copy on level 2 otherwise level 1 is used.
    
-   \todo Implement V2_write_area_ogr()
+   \todo Implement V2__write_area_ogr()
    
    \param In input vector map
    \param field layer number (-1 for all layers)
@@ -283,13 +287,15 @@
         if (with_z)
             Points->z[0] = z;
         
-        if (-1 == Vect_write_line(Out, GV_POINT, Points, NULL))
-            G_fatal_error(_("Unable to export node %d. Exiting."), node);
+        if (-1 == V2__write_node_pg(Out, Points)) {
+            G_warning(_("Writing node %d failed"), node);
+            return 1;
+        }
     }
 
     Vect_destroy_line_struct(Points);
     
-    return nnodes;
+    return 0;
 }
 
 /*!
@@ -357,9 +363,17 @@
         
         if (ogr)
             Vect_write_line(Out, GV_BOUNDARY, Points, Cats);
-        else
-            V2_write_area_pg(Out, Points, Cats,
-                             (const struct line_pnts **) IPoints, nisles);
+        else {
+#if HAVE_POSTGRES
+            if (-1 == V2__write_area_pg(Out, Points, Cats,
+                                        (const struct line_pnts **) IPoints, nisles)) {
+                G_warning(_("Writing area %d failed"), area);
+                return 1;
+            }
+#else
+            G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+#endif
+        }
     }
     
     /* free allocated space for isles */
@@ -369,7 +383,7 @@
     Vect_destroy_line_struct(Points);
     Vect_destroy_cats_struct(Cats);
 
-    return nareas;
+    return 0;
 }
 
 /*!

Modified: grass/trunk/lib/vector/Vlib/e_intersect.c
===================================================================
--- grass/trunk/lib/vector/Vlib/e_intersect.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/e_intersect.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -15,7 +15,9 @@
 
 #include <stdlib.h>
 #include <math.h>
+
 #include <grass/gis.h>
+
 #include "e_intersect.h"
 
 #define SWAP(a,b) {double t = a; a = b; b = t;}

Added: grass/trunk/lib/vector/Vlib/local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/local_proto.h	                        (rev 0)
+++ grass/trunk/lib/vector/Vlib/local_proto.h	2012-11-05 09:34:48 UTC (rev 53686)
@@ -0,0 +1,9 @@
+#ifndef __LOCAL_PROTO_H__
+#define __LOCAL_PROTO_H__
+
+#include <grass/vector.h>
+
+void V2__add_line_to_topo_nat(struct Map_info *, int ,
+                              const struct line_pnts *, const struct line_cats *);
+
+#endif /* PG_LOCAL_PROTO_H__ */


Property changes on: grass/trunk/lib/vector/Vlib/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/open_pg.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -429,7 +429,7 @@
     /* free and init plus structure */
     dig_init_plus(plus);
     
-    return load_plus(Map, head_only);
+    return Vect__load_plus_pg(Map, head_only);
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
     return -1;
@@ -566,7 +566,7 @@
             pg_info->schema_name, pg_info->table_name);
     G_debug(2, "SQL: %s", stmt);
     
-    if (execute(pg_info->conn, stmt) == -1) {
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
         return -1;
     }
 
@@ -595,7 +595,7 @@
 
     if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
         PQclear(result);
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
@@ -610,8 +610,8 @@
 
     if (!found) {
         sprintf(stmt, "CREATE SCHEMA %s", pg_info->schema_name);
-        if (execute(pg_info->conn, stmt) == -1) {
-            execute(pg_info->conn, "ROLLBACK");
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+            Vect__execute_pg(pg_info->conn, "ROLLBACK");
             return -1;
         }
         G_warning(_("Schema <%s> doesn't exist, created"),
@@ -768,14 +768,14 @@
     strcat(stmt, ")");          /* close CREATE TABLE statement */
 
     /* begin transaction (create table) */
-    if (execute(pg_info->conn, "BEGIN") == -1) {
+    if (Vect__execute_pg(pg_info->conn, "BEGIN") == -1) {
         return -1;
     }
 
     /* create table */
     G_debug(2, "SQL: %s", stmt);
-    if (execute(pg_info->conn, stmt) == -1) {
-        execute(pg_info->conn, "ROLLBACK");
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
@@ -785,8 +785,8 @@
                 pg_info->schema_name, pg_info->table_name,
                 pg_info->fid_column);
         G_debug(2, "SQL: %s", stmt);
-        if (execute(pg_info->conn, stmt) == -1) {
-            execute(pg_info->conn, "ROLLBACK");
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+            Vect__execute_pg(pg_info->conn, "ROLLBACK");
             return -1;
         }
     }
@@ -804,7 +804,7 @@
         break;
     default:
         G_warning(_("Unsupported feature type %d"), pg_info->feature_type);
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
     
@@ -819,7 +819,7 @@
     
     if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
         PQclear(result);
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
     
@@ -834,14 +834,14 @@
                 pg_info->geom_column);
         G_debug(2, "SQL: %s", stmt);
         
-        if (execute(pg_info->conn, stmt) == -1) {
-            execute(pg_info->conn, "ROLLBACK");
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+            Vect__execute_pg(pg_info->conn, "ROLLBACK");
             return -1;
         }
     }
 
     /* close transaction (create table) */
-    if (execute(pg_info->conn, "COMMIT") == -1) {
+    if (Vect__execute_pg(pg_info->conn, "COMMIT") == -1) {
         return -1;
     }
 
@@ -899,7 +899,7 @@
     }
 
     /* begin transaction (create topo schema) */
-    if (execute(pg_info->conn, "BEGIN") == -1) {
+    if (Vect__execute_pg(pg_info->conn, "BEGIN") == -1) {
         return -1;
     }
 
@@ -916,7 +916,7 @@
     result = PQexec(pg_info->conn, stmt);
     if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
         G_warning(_("Execution failed: %s"), PQerrorMessage(pg_info->conn));
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
     
@@ -932,12 +932,12 @@
     result = PQexec(pg_info->conn, stmt);
     if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
         G_warning(_("Execution failed: %s"), PQerrorMessage(pg_info->conn));
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
     /* close transaction (create topo schema) */
-    if (execute(pg_info->conn, "COMMIT") == -1) {
+    if (Vect__execute_pg(pg_info->conn, "COMMIT") == -1) {
         return -1;
     }
 
@@ -1191,8 +1191,8 @@
     PQclear(res);
     
     /* get node coordinates */
-    if (SF_POINT != cache_feature(wkb_data, FALSE, FALSE,
-                                  &(pg_info->cache), NULL))
+    if (SF_POINT != Vect__cache_feature_pg(wkb_data, FALSE, FALSE,
+                                           &(pg_info->cache), NULL))
         G_warning(_("Node %d: unexpected feature type %d"),
                   n, pg_info->cache.sf_type);
     
@@ -1300,7 +1300,7 @@
     }
 
     /* update spatial index */
-    cache_feature(data->wkb_geom, FALSE, FALSE, cache, NULL);
+    Vect__cache_feature_pg(data->wkb_geom, FALSE, FALSE, cache, NULL);
     itype = cache->lines_types[0];
     if ((line->type & GV_POINTS && itype != GV_POINT) ||
         (line->type & GV_LINES  && itype != GV_LINE))
@@ -1427,7 +1427,7 @@
   \return 0 on success
   \return -1 on error
 */
-int load_plus(struct Map_info *Map, int head_only)
+int Vect__load_plus_pg(struct Map_info *Map, int head_only)
 {
     int i, id, ntuples;
     char stmt[DB_SQL_MAX];

Modified: grass/trunk/lib/vector/Vlib/pg_local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/pg_local_proto.h	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/pg_local_proto.h	2012-11-05 09:34:48 UTC (rev 53686)
@@ -51,13 +51,18 @@
 };
 
 /* functions used in *_pg.c files */
-int execute(PGconn *, const char *);
-SF_FeatureType cache_feature(const char *, int, int,
-			     struct Format_info_cache *,
-			     struct feat_parts *);
-int set_initial_query(struct Format_info_pg *, int);
-int load_plus(struct Map_info *, int);
+int Vect__execute_pg(PGconn *, const char *);
+SF_FeatureType Vect__cache_feature_pg(const char *, int, int,
+                                      struct Format_info_cache *,
+                                      struct feat_parts *);
+int Vect__set_initial_query_pg(struct Format_info_pg *, int);
+int Vect__load_plus_pg(struct Map_info *, int);
 
+off_t V2__write_node_pg(struct Map_info *, const struct line_pnts *);
+off_t V2__write_area_pg(struct Map_info *, const struct line_pnts *,
+                        const struct line_cats *,
+                        const struct line_pnts **, int);
+
 #endif /* HAVE_POSTGRES */
 
 #endif /* __PG_LOCAL_PROTO_H__ */

Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/read_pg.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -476,7 +476,7 @@
     if (fid < 1) {
         /* next (read n features) */
         if (!pg_info->res) {
-            if (set_initial_query(pg_info, FALSE) == -1)
+            if (Vect__set_initial_query_pg(pg_info, FALSE) == -1)
                 return -1;
         }
     }
@@ -487,7 +487,7 @@
             return -1;
         }
 
-        if (execute(pg_info->conn, "BEGIN") == -1)
+        if (Vect__execute_pg(pg_info->conn, "BEGIN") == -1)
             return -1;
 
         if (!pg_info->toposchema_name) {
@@ -508,7 +508,7 @@
                 topotable_name = "edge";
             else {
                 G_warning(_("Unsupported feature type %d"), type);
-                execute(pg_info->conn, "ROLLBACK");
+                Vect__execute_pg(pg_info->conn, "ROLLBACK");
                 return -1;
             }
             
@@ -520,7 +520,7 @@
                     topotable_name, topotable_name, fid);
         }
 
-        if (execute(pg_info->conn, stmt) == -1)
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1)
             return -1;
 
         sprintf(stmt, "FETCH ALL in %s_%s%p",
@@ -547,7 +547,7 @@
                 pg_info->schema_name, pg_info->table_name, pg_info->conn);
         pg_info->res = PQexec(pg_info->conn, stmt);
         if (!pg_info->res) {
-            execute(pg_info->conn, "ROLLBACK");
+            Vect__execute_pg(pg_info->conn, "ROLLBACK");
             return -1;
         }
         pg_info->next_line = 0;
@@ -561,12 +561,12 @@
 
             sprintf(stmt, "CLOSE %s_%s%p",
                     pg_info->schema_name, pg_info->table_name, pg_info->conn);
-            if (execute(pg_info->conn, stmt) == -1) {
-                execute(pg_info->conn, "ROLLBACK");
+            if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+                Vect__execute_pg(pg_info->conn, "ROLLBACK");
                 G_warning(_("Unable to close cursor"));
                 return -1;
             }
-            execute(pg_info->conn, "COMMIT");
+            Vect__execute_pg(pg_info->conn, "COMMIT");
         }
         return -2;
     }
@@ -583,9 +583,9 @@
         }
     }
     pg_info->cache.sf_type =
-        cache_feature(data, FALSE,
-                      left_face != 0 || right_face != 0 ? TRUE : FALSE,
-                      &(pg_info->cache), NULL);
+        Vect__cache_feature_pg(data, FALSE,
+                               left_face != 0 || right_face != 0 ? TRUE : FALSE,
+                               &(pg_info->cache), NULL);
     if (fid < 0) {
         pg_info->cache.fid =
             atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1));
@@ -599,12 +599,12 @@
 
         sprintf(stmt, "CLOSE %s_%s%p",
                 pg_info->schema_name, pg_info->table_name, pg_info->conn);
-        if (execute(pg_info->conn, stmt) == -1) {
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
             G_warning(_("Unable to close cursor"));
             return -1;
         }
 
-        if (execute(pg_info->conn, "COMMIT") == -1)
+        if (Vect__execute_pg(pg_info->conn, "COMMIT") == -1)
             return -1;
     }
 
@@ -666,10 +666,10 @@
    \return simple feature type
    \return SF_UNKNOWN on error
  */
-SF_FeatureType cache_feature(const char *data, int skip_polygon,
-                             int force_boundary,
-                             struct Format_info_cache *cache,
-                             struct feat_parts * fparts)
+SF_FeatureType Vect__cache_feature_pg(const char *data, int skip_polygon,
+                                      int force_boundary,
+                                      struct Format_info_cache *cache,
+                                      struct feat_parts * fparts)
 {
     int ret, byte_order, nbytes, is3D;
     unsigned char *wkb_data;
@@ -691,12 +691,12 @@
     if (nbytes < 5) {
         /* G_free(wkb_data); */
         if (nbytes > 0) {
-            G_debug(3, "cache_feature(): invalid geometry");
+            G_debug(3, "Vect__cache_feature_pg(): invalid geometry");
             G_warning(_("Invalid WKB content: %d bytes"), nbytes);
             return SF_UNKNOWN;
         }
         else {
-            G_debug(3, "cache_feature(): no geometry");
+            G_debug(3, "Vect__cache_feature_pg(): no geometry");
             return SF_NONE;
         }
     }
@@ -745,7 +745,7 @@
         ftype = (SF_FeatureType) wkb_data[4];
         is3D = wkb_data[1] & 0x80 || wkb_data[3] & 0x80;
     }
-    G_debug(3, "cache_feature(): sf_type = %d", ftype);
+    G_debug(3, "Vect__cache_feature_pg(): sf_type = %d", ftype);
 
     /* allocate space in lines cache - be minimalistic
 
@@ -1130,11 +1130,11 @@
    \return 0 on success
    \return -1 on error
  */
-int set_initial_query(struct Format_info_pg *pg_info, int fetch_all)
+int Vect__set_initial_query_pg(struct Format_info_pg *pg_info, int fetch_all)
 {
     char stmt[DB_SQL_MAX];
 
-    if (execute(pg_info->conn, "BEGIN") == -1)
+    if (Vect__execute_pg(pg_info->conn, "BEGIN") == -1)
         return -1;
 
     if (!pg_info->toposchema_name) {
@@ -1164,8 +1164,8 @@
     }
     G_debug(2, "SQL: %s", stmt);
     
-    if (execute(pg_info->conn, stmt) == -1) {
-        execute(pg_info->conn, "ROLLBACK");
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
@@ -1177,7 +1177,7 @@
                 pg_info->schema_name, pg_info->table_name, pg_info->conn);
     pg_info->res = PQexec(pg_info->conn, stmt);
     if (!pg_info->res) {
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         G_warning(_("Unable to get features"));
         return -1;
     }
@@ -1197,13 +1197,13 @@
    \return 0 on success
    \return -1 on error
  */
-int execute(PGconn * conn, const char *stmt)
+int Vect__execute_pg(PGconn * conn, const char *stmt)
 {
     PGresult *result;
 
     result = NULL;
 
-    G_debug(3, "execute(): %s", stmt);
+    G_debug(3, "Vect__execute_pg(): %s", stmt);
     result = PQexec(conn, stmt);
     if (!result || PQresultStatus(result) != PGRES_COMMAND_OK) {
         PQclear(result);
@@ -1315,7 +1315,7 @@
     data = (char *)PQgetvalue(res, 0, 0);
     PQclear(res);
     
-    if (GV_POINT != cache_feature(data, FALSE, FALSE, &(pg_info->cache), NULL))
+    if (GV_POINT != Vect__cache_feature_pg(data, FALSE, FALSE, &(pg_info->cache), NULL))
         return -1;
     
     Vect_append_points(line_p, pg_info->cache.lines[0], GV_FORWARD);

Modified: grass/trunk/lib/vector/Vlib/rewind_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/rewind_pg.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/rewind_pg.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -54,11 +54,11 @@
 
         sprintf(stmt, "CLOSE %s_%s%p",
                 pg_info->schema_name, pg_info->table_name, pg_info->conn);
-        if (execute(pg_info->conn, stmt) == -1) {
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
             G_warning(_("Unable to close cursor"));
             return -1;
         }
-        execute(pg_info->conn, "COMMIT");
+        Vect__execute_pg(pg_info->conn, "COMMIT");
     }
 
     return 0;

Modified: grass/trunk/lib/vector/Vlib/write.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/write.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -81,7 +81,7 @@
 #endif
 #ifdef HAVE_POSTGRES
     , {
-	write_dummy, V1_write_line_pg, V2_write_line_sfa}
+	write_dummy, V1_write_line_pg, V2_write_line_pg}
 #else
     , {
 	write_dummy, format_l, format_l}

Modified: grass/trunk/lib/vector/Vlib/write_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_nat.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/write_nat.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -22,6 +22,8 @@
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+#include "local_proto.h"
+
 static off_t V1__rewrite_line_nat(struct Map_info *, off_t, int,
 				  const struct line_pnts *, const struct line_cats *);
 
@@ -133,8 +135,8 @@
     \param points pointer to line_pnts structure (feature's geometry)
     \param cats pointer to line_cats structure (feature's categories)
 */
-static void V2__add_line_to_topo_nat(struct Map_info *Map, int line,
-				     const struct line_pnts *points, const struct line_cats *cats)
+void V2__add_line_to_topo_nat(struct Map_info *Map, int line,
+                              const struct line_pnts *points, const struct line_cats *cats)
 {
     int first, s, n, i;
     int type, node, next_line, area, side, sel_area, new_area[2];
@@ -297,11 +299,13 @@
     }
 
     /* Add category index */
-    for (i = 0; i < cats->n_cats; i++) {
-	dig_cidx_add_cat_sorted(plus, cats->field[i], cats->cat[i], line,
-				type);
+    if (cats) {
+        for (i = 0; i < cats->n_cats; i++) {
+            dig_cidx_add_cat_sorted(plus, cats->field[i], cats->cat[i], line,
+                                    type);
+        }
     }
-
+    
     return;
 }
 

Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c	2012-11-04 21:34:20 UTC (rev 53685)
+++ grass/trunk/lib/vector/Vlib/write_pg.c	2012-11-05 09:34:48 UTC (rev 53686)
@@ -26,6 +26,8 @@
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+#include "local_proto.h"
+
 #ifdef HAVE_POSTGRES
 #include "pg_local_proto.h"
 
@@ -34,7 +36,7 @@
 static off_t write_line_sf(struct Map_info *, int,
                            const struct line_pnts **, int,
                            const struct line_cats *);
-static off_t write_line_tp(struct Map_info *, int,
+static off_t write_line_tp(struct Map_info *, int, int,
                            const struct line_pnts *);
 static char *binary_to_hex(int, const unsigned char *);
 static unsigned char *point_to_wkb(int, const struct line_pnts *, int, int *);
@@ -44,10 +46,11 @@
                                      int, int *);
 static int write_feature(struct Format_info_pg *,
                          int, const struct line_pnts **, int, int,
+                         const struct P_line *,
                          int, const struct field_info *);
 static char *build_insert_stmt(const struct Format_info_pg *, const char *,
                                int, const struct field_info *);
-static char *build_topo_stmt(const struct Format_info_pg *, int,
+static char *build_topo_stmt(struct Format_info_pg *, int,
                              const struct P_line *, const char *);
 static char *build_topogeom_stmt(const struct Format_info_pg *, int, int, int);
 static int execute_topo(PGconn *, const char *);
@@ -75,10 +78,22 @@
                        const struct line_cats *cats)
 {
 #ifdef HAVE_POSTGRES
-    if (!Map->fInfo.pg.toposchema_name)
-        return write_line_sf(Map, type, &points, 1, cats);
-    else
-        return write_line_tp(Map, type, points);
+    struct Format_info_pg *pg_info;
+
+    pg_info = &(Map->fInfo.pg);
+    
+    if (pg_info->feature_type == SF_UNKNOWN) {
+        /* create PostGIS table if doesn't exist */
+        if (V2_open_new_pg(Map, type) < 0)
+            return -1;
+    }
+
+    if (pg_info->toposchema_name) {
+        G_warning(_("PostGIS topology not supported on level 1"));
+        return -1;
+    }
+    
+    return write_line_sf(Map, type, &points, 1, cats);
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
     return -1;
@@ -86,6 +101,36 @@
 }
 
 /*!
+   \brief Writes feature on level 2 (PostGIS interface)
+
+   \param Map pointer to Map_info structure
+   \param type feature type (GV_POINT, GV_LINE, ...)
+   \param points pointer to line_pnts structure (feature geometry) 
+   \param cats pointer to line_cats structure (feature categories)
+
+   \return feature offset into file
+   \return -1 on error
+ */
+off_t V2_write_line_pg(struct Map_info *Map, int type,
+                       const struct line_pnts *points,
+                       const struct line_cats *cats)
+{
+#ifdef HAVE_POSTGRES
+    struct Format_info_pg *pg_info;
+
+    pg_info = &(Map->fInfo.pg);
+    
+    if (!pg_info->toposchema_name) /* pseudo-topology */
+        return V2_write_line_sfa(Map, type, points, cats);
+    else                           /* PostGIS topology */
+        return write_line_tp(Map, type, FALSE, points);
+#else
+    G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+    return -1;
+#endif
+}
+
+/*!
    \brief Rewrites feature at the given offset (level 1) (PostGIS interface)
 
    \param Map pointer to Map_info structure
@@ -157,7 +202,7 @@
     if (!pg_info->inTransaction) {
         /* start transaction */
         pg_info->inTransaction = TRUE;
-        if (execute(pg_info->conn, "BEGIN") == -1)
+        if (Vect__execute_pg(pg_info->conn, "BEGIN") == -1)
             return -1;
     }
 
@@ -165,9 +210,9 @@
             pg_info->table_name, pg_info->fid_column, fid);
     G_debug(2, "SQL: %s", stmt);
 
-    if (execute(pg_info->conn, stmt) == -1) {
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
         G_warning(_("Unable to delete feature"));
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
@@ -179,9 +224,35 @@
 }
 
 /*!
-   \brief Writes area on level 2 (PostGIS interface)
+   \brief Writes node on level 2 (PostGIS Topology interface) - internal use only
 
    \param Map pointer to Map_info structure
+   \param points pointer to line_pnts structure
+   
+   \return 0 on success
+   \return -1 on error
+*/
+off_t V2__write_node_pg(struct Map_info *Map, const struct line_pnts *points)
+{
+#ifdef HAVE_POSTGRES
+    struct Format_info_pg *pg_info;
+
+    pg_info = &(Map->fInfo.pg);
+    
+    if (!pg_info->toposchema_name)
+        return -1; /* PostGIS Topology required */
+    
+    return write_line_tp(Map, GV_POINT, TRUE, points);
+#else
+    G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+    return -1;
+#endif
+}
+
+/*!
+   \brief Writes area on level 2 (PostGIS Simple Features interface) - internal use only
+
+   \param Map pointer to Map_info structure
    \param type feature type (GV_POINT, GV_LINE, ...)
    \param points pointer to line_pnts structure (boundary geometry) 
    \param cats pointer to line_cats structure (feature categories)
@@ -190,11 +261,11 @@
    
    \return feature offset into file
    \return -1 on error
- */
-off_t V2_write_area_pg(struct Map_info *Map, 
-                       const struct line_pnts *bpoints,
-                       const struct line_cats *cats,
-                       const struct line_pnts **ipoints, int nisles)
+*/
+off_t V2__write_area_pg(struct Map_info *Map, 
+                        const struct line_pnts *bpoints,
+                        const struct line_cats *cats,
+                        const struct line_pnts **ipoints, int nisles)
 {
 #ifdef HAVE_POSTGRES
     int i;
@@ -224,6 +295,12 @@
 }
 
 #ifdef HAVE_POSTGRES
+/*!
+  \brief Write vector features as PostGIS simple feature element
+  
+  \return 0 on success
+  \return -1 on error
+*/
 off_t write_line_sf(struct Map_info *Map, int type,
                     const struct line_pnts **points, int nparts,
                     const struct line_cats *cats)
@@ -240,22 +317,22 @@
     pg_info = &(Map->fInfo.pg);
     offset_info = &(pg_info->offset);
 
+    /* check required PG settings */
     if (!pg_info->conn) {
         G_warning(_("No connection defined"));
         return -1;
     }
-
     if (!pg_info->table_name) {
         G_warning(_("PostGIS feature table not defined"));
         return -1;
     }
 
+    /* create PostGIS table if doesn't exist */
     if (pg_info->feature_type == SF_UNKNOWN) {
-        /* create PostGIS table if doesn't exist */
         if (V2_open_new_pg(Map, type) < 0)
             return -1;
     }
-
+    
     Fi = NULL;                  /* no attributes to be written */
     cat = -1;
     if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
@@ -324,8 +401,8 @@
 
     /* write feature's geometry and fid */
     if (-1 == write_feature(pg_info, type, points, nparts,
-                            Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, cat, Fi)) {
-        execute(pg_info->conn, "ROLLBACK");
+                            Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, NULL, cat, Fi)) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
@@ -336,7 +413,6 @@
                                               offset_info->array_alloc *
                                               sizeof(int));
     }
-
     offset = offset_info->array_num;
 
     offset_info->array[offset_info->array_num++] = cat;
@@ -350,25 +426,50 @@
     return offset;
 }
 
-off_t write_line_tp(struct Map_info *Map, int type,
+/*! 
+  \brief Write vector feature in PostGIS topology schema and
+  updates internal topology structures
+
+  \param Map vector map
+  \param type feature type to be written
+  \param points feature geometry
+  \param is_node TRUE for nodes (written as points)
+  
+  \return 0 on success
+  \return -1 on error
+*/
+off_t write_line_tp(struct Map_info *Map, int type, int is_node,
                     const struct line_pnts *points)
 {
     struct Format_info_pg *pg_info;
+    struct Plus_head *plus;
+    struct P_line *Line;
     
     pg_info = &(Map->fInfo.pg);
+    plus = &(Map->plus);
+    
+    /* check type for nodes */
+    if (is_node && type != GV_POINT) {
+        G_warning(_("Invalid type (%d) for nodes"), type);
+        return -1;
+    }
 
+    /* check required PG settings */
     if (!pg_info->conn) {
         G_warning(_("No connection defined"));
         return -1;
     }
-
     if (!pg_info->table_name) {
         G_warning(_("PostGIS feature table not defined"));
         return -1;
     }
-
+    if (!pg_info->toposchema_name) {
+        G_warning(_("PostGIS topology schema not defined"));
+        return -1;
+    }
+    
+    /* create PostGIS table if doesn't exist */
     if (pg_info->feature_type == SF_UNKNOWN) {
-        /* create PostGIS table if doesn't exist */
         if (V2_open_new_pg(Map, type) < 0)
             return -1;
     }
@@ -376,10 +477,32 @@
     G_debug(3, "write_line_pg(): type = %d n_points = %d",
             type, points->n_points);
 
-    /* write feature's geometry and fid */
+    /* update topology before writing feature */
+    Line = NULL;
+    if (is_node) {
+        dig_add_node(plus, points->x[0], points->y[0], points->z[0]);
+    }
+    else {
+        int line;
+        struct bound_box box;
+        
+        dig_line_box(points, &box);
+        line = dig_add_line(plus, type, points, &box, 0); /* offset ? */
+        G_debug(3, "  line added to topo with id = %d", line);
+        if (line == 1)
+            Vect_box_copy(&(plus->box), &box);
+        else
+            Vect_box_extend(&(plus->box), &box);
+        V2__add_line_to_topo_nat(Map, line, points, NULL); /* cats ? */
+
+        Line = plus->Line[line];
+    }
+    
+    /* write feature geometry and fid */
     if (-1 == write_feature(pg_info, type, &points, 1,
-                            Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, -1, NULL)) {
-        execute(pg_info->conn, "ROLLBACK");
+                            Vect_is_3d(Map) ? WITH_Z : WITHOUT_Z, Line,
+                            -1, NULL)) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
@@ -673,8 +796,9 @@
    \retirn 0 on success
  */
 int write_feature(struct Format_info_pg *pg_info, int type,
-                  const struct line_pnts **points, int nparts,
-                  int with_z, int cat, const struct field_info *Fi)
+                  const struct line_pnts **points, int nparts, int with_z,
+                  const struct P_line *Line,
+                  int cat, const struct field_info *Fi)
 {
     int byte_order, nbytes, nsize;
     unsigned int sf_type;
@@ -776,43 +900,38 @@
     if (!pg_info->inTransaction) {
         /* start transaction */
         pg_info->inTransaction = TRUE;
-        if (execute(pg_info->conn, "BEGIN") == -1)
+        if (Vect__execute_pg(pg_info->conn, "BEGIN") == -1)
             return -1;
     }
 
     /* stmt can NULL when writing PostGIS topology with no attributes
      * attached */
-    if (stmt && execute(pg_info->conn, stmt) == -1) {
+    if (stmt && Vect__execute_pg(pg_info->conn, stmt) == -1) {
         /* rollback transaction */
-        execute(pg_info->conn, "ROLLBACK");
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
     }
     G_free(stmt);
     
     /* write feature in PostGIS topology schema if enabled */
     if (pg_info->toposchema_name) {
-        int id, do_update;
-
-        do_update = stmt ? TRUE : FALSE; /* update or insert new record 
-                                            to the feature table */
-        
         /* insert feature into topology schema (node or edge) */
-        stmt = build_topo_stmt(pg_info, type, NULL, text_data);
-        id = execute_topo(pg_info->conn, stmt);
-        if (id == -1) {
+        stmt = build_topo_stmt(pg_info, type, Line, text_data);
+        if (stmt && Vect__execute_pg(pg_info->conn, stmt) == -1) {
             /* rollback transaction */
-            execute(pg_info->conn, "ROLLBACK");
+            Vect__execute_pg(pg_info->conn, "ROLLBACK");
             return -1;
         }
         G_free(stmt);
-
-        /* insert topoelement into feature table) */
+        
+        /* insert topoelement into feature table
         stmt = build_topogeom_stmt(pg_info, id, type, do_update);
-        if (execute(pg_info->conn, stmt) == -1) {
-            execute(pg_info->conn, "ROLLBACK");
+        if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+            Vect__execute_pg(pg_info->conn, "ROLLBACK");
             return -1;
         }
         G_free(stmt);
+        */
     }
 
     G_free(wkb_data);
@@ -981,7 +1100,7 @@
   \return pointer to allocated string buffer with SQL statement
   \return NULL on error
 */
-char *build_topo_stmt(const struct Format_info_pg *pg_info, int type,
+char *build_topo_stmt(struct Format_info_pg *pg_info, int type,
                       const struct P_line *Line, const char *geom_data)
 {
     char *stmt;
@@ -989,7 +1108,7 @@
     stmt = NULL;
     switch(type) {
     case GV_POINT: {
-#if 0
+#if 1
         G_asprintf(&stmt, "INSERT INTO \"%s\".node (geom) VALUES ('%s'::GEOMETRY)",
                    pg_info->toposchema_name, geom_data);
 #else
@@ -999,17 +1118,19 @@
         break;
     }
     case GV_LINE: {
-        struct P_topo_l *topo;
+        if (!Line) {
+            G_warning(_("Topology not available. Unable to insert new edge."));
+            return NULL;
+        }
         
-        topo = (struct P_topo_l *) Line->topo;
-        G_asprintf(&stmt, "INSERT INTO \"%s\".edge_data (geom,"
-                   "start_node,end_node,"
-                   "next_left_edge,abs_next_left_edge,"
-                   "next_right_edge,abs_next_right_edge,"
-                   "left_face,right_face) "
-                   "VALUES ('%s'::GEOMETRY,%d,%d,0,0,0,0,0,0)",
-                   pg_info->toposchema_name, geom_data,
-                   topo->N1, topo->N2);
+        struct P_topo_l *topo = (struct P_topo_l *) Line->topo;
+        
+        G_asprintf(&stmt, "INSERT INTO \"%s\".edge_data (geom, start_node, end_node, "
+                   "next_left_edge, next_right_edge, abs_next_left_edge, abs_next_right_edge, "
+                   "left_face, right_face) "
+                   "VALUES ('%s'::GEOMETRY, %d, %d, %d, %d, %d, %d, %d, %d)",
+                   pg_info->toposchema_name, geom_data, topo->N1, topo->N2, 0, 0, 0, 0, 0, 0);
+
         break;
     }
     case GV_CENTROID: {
@@ -1025,7 +1146,7 @@
         break;
     }
     default:
-        G_warning(_("Unsupported feature type %d"), Line->type);
+        G_warning(_("Unsupported feature type %d"), type);
         break;
     }
     



More information about the grass-commit mailing list