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

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jun 5 05:44:18 PDT 2012


Author: martinl
Date: 2012-06-05 05:44:17 -0700 (Tue, 05 Jun 2012)
New Revision: 51975

Modified:
   grass/trunk/include/defs/vector.h
   grass/trunk/lib/vector/Vlib/box.c
   grass/trunk/lib/vector/Vlib/build.c
   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.c
   grass/trunk/lib/vector/Vlib/open.c
   grass/trunk/lib/vector/Vlib/open_pg.c
   grass/trunk/lib/vector/Vlib/pg_local_proto.h
   grass/trunk/lib/vector/Vlib/read.c
   grass/trunk/lib/vector/Vlib/read_pg.c
   grass/trunk/lib/vector/diglib/spindex.c
   grass/trunk/lib/vector/diglib/spindex_rw.c
Log:
vlib: improve PostGIS topology support
      read topology tables instead of feature table
      introduce level 3 (PostGIS topology access)


Modified: grass/trunk/include/defs/vector.h
===================================================================
--- grass/trunk/include/defs/vector.h	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/include/defs/vector.h	2012-06-05 12:44:17 UTC (rev 51975)
@@ -517,6 +517,8 @@
                           struct line_cats *);
 int V2_read_next_line_pg(struct Map_info *, struct line_pnts *,
                          struct line_cats *);
+int V3_read_next_line_pg(struct Map_info *, struct line_pnts *,
+                         struct line_cats *);
 int V1_delete_line_nat(struct Map_info *, off_t);
 int V1_delete_line_ogr(struct Map_info *, off_t);
 int V1_delete_line_pg(struct Map_info *, off_t);
@@ -547,6 +549,7 @@
 
     /* Build topology */
 int Vect_build_nat(struct Map_info *, int);
+void Vect__build_downgrade(struct Map_info *, int);
 int Vect__build_sfa(struct Map_info *, int);
 int Vect_build_ogr(struct Map_info *, int);
 int Vect_build_pg(struct Map_info *, int);

Modified: grass/trunk/lib/vector/Vlib/box.c
===================================================================
--- grass/trunk/lib/vector/Vlib/box.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/box.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -302,23 +302,16 @@
     Area = Plus->Area[area];
 
     if (Area == NULL) {		/* dead */
-	Box->N = 0;
-	Box->S = 0;
-	Box->E = 0;
-	Box->W = 0;
-	Box->T = 0;
-	Box->B = 0;
-
+        G_zero(Box, sizeof(struct bound_box));
 	return 0;
     }
     else {
-
 	Line = Plus->Line[abs(Area->lines[0])];
 	topo = (struct P_topo_b *)Line->topo;
 	Node = Plus->Node[topo->N1];
 
 	if (list == NULL) {
-	    list = Vect_new_boxlist(1);
+	    list = Vect_new_boxlist(TRUE);
 	}
 	Vect_reset_boxlist(list);
 	
@@ -332,7 +325,7 @@
 	dig_boxlist_add(list, area, bbox);
 	
 	if (dig_find_area_box(Plus, list) == 0)
-	    G_fatal_error(_("Could not find area box"));
+	    G_fatal_error(_("Unable to get bounding box for area %d"), area);
 
 	Box->N = list->box[0].N;
 	Box->S = list->box[0].S;

Modified: grass/trunk/lib/vector/Vlib/build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/build.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -655,10 +655,69 @@
  */
 int Vect_get_built(const struct Map_info *Map)
 {
-    return (Map->plus.built);
+    return Map->plus.built;
 }
 
 /*!
+  \brief Downgrade build level (for internal use only)
+
+  See Vect_build_nat(), Vect__build_sfa(), and Vect_build_pg() for
+  implementation issues.
+
+  \param Map pointer to Map_info
+*/
+void Vect__build_downgrade(struct Map_info *Map, int build)
+{
+    int line;
+    struct Plus_head *plus;
+    struct P_line *Line;
+    
+    plus = &(Map->plus);
+    
+    /* lower level request - release old sources (this also
+       initializes structures and numbers of elements) */
+    if (plus->built >= GV_BUILD_CENTROIDS && build < GV_BUILD_CENTROIDS) {
+        /* reset info about areas stored for centroids */
+        for (line = 1; line <= plus->n_lines; line++) {
+            Line = plus->Line[line];
+            if (Line && Line->type == GV_CENTROID) {
+                struct P_topo_c *topo = (struct P_topo_c *)Line->topo;
+                topo->area = 0;
+            }
+        }
+        dig_free_plus_areas(plus);
+        dig_spidx_free_areas(plus);
+        dig_free_plus_isles(plus);
+        dig_spidx_free_isles(plus);
+    }
+    
+    if (plus->built >= GV_BUILD_AREAS && build < GV_BUILD_AREAS) {
+        /* reset info about areas stored for lines */
+        for (line = 1; line <= plus->n_lines; line++) {
+            Line = plus->Line[line];
+            if (Line && Line->type == GV_BOUNDARY) {
+                struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
+                topo->left = 0;
+                topo->right = 0;
+            }
+        }
+        dig_free_plus_areas(plus);
+        dig_spidx_free_areas(plus);
+        dig_free_plus_isles(plus);
+        dig_spidx_free_isles(plus);
+    }
+    
+    if (plus->built >= GV_BUILD_BASE && build < GV_BUILD_BASE) {
+        dig_free_plus_nodes(plus);
+        dig_spidx_free_nodes(plus);
+        dig_free_plus_lines(plus);
+        dig_spidx_free_lines(plus);
+    }
+
+    plus->built = build;
+}
+
+/*!
    \brief Build partial topology for vector map.
 
    Should only be used in special cases of vector processing.
@@ -701,14 +760,14 @@
 
     G_debug(3, "Vect_build(): build = %d", build);
 
-    /* If topology is already build (map on level2), set level to 1 so
-     * that lines will be read by V1_read_ (all lines) */
+    /* If topology is already build (map on > level 2), set level to 1
+     * so that lines will be read by V1_read_ (all lines) */
     Map->level = 1; /* may be not needed, because V1_read is used
 		       directly by Vect_build_ */
     if (Map->format != GV_FORMAT_OGR_DIRECT)
 	Map->support_updated = TRUE;
 
-    if (Map->plus.Spidx_built == FALSE)
+    if (!Map->plus.Spidx_built)
 	Vect_open_sidx(Map, 2);
 
     plus = &(Map->plus);
@@ -734,11 +793,12 @@
 	G_verbose_message(_("Topology was built"));
     }
 
-    Map->level = LEVEL_2;
+    if (Map->level == 1)
+        Map->level = LEVEL_2;
     plus->mode = GV_MODE_WRITE;
 
     if (build == GV_BUILD_ALL) {
-	plus->cidx_up_to_date = 1;	/* category index was build */
+	plus->cidx_up_to_date = TRUE;	/* category index was build */
 	dig_cidx_sort(plus);
     }
 
@@ -1040,8 +1100,8 @@
 	G_fatal_error(_("Unable to build spatial index from topology, "
 			"vector map is not opened at topology level 2"));
     }
-    if (!(Map->plus.Spidx_built)) {
-	return (Vect_build_sidx_from_topo(Map));
+    if (!Map->plus.Spidx_built) {
+	return Vect_build_sidx_from_topo(Map);
     }
     return 0;
 }
@@ -1082,8 +1142,8 @@
 
     plus = &(Map->plus);
 
-    if (plus->Spidx_built == FALSE) {
-	G_warning("Spatial index not available, can not be saved");
+    if (!plus->Spidx_built) {
+	G_warning(_("Spatial index not available, can not be saved"));
 	return 0;
     }
 

Modified: grass/trunk/lib/vector/Vlib/build_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_nat.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/build_nat.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -50,55 +50,13 @@
 	return 1;		/* Do nothing */
 
     /* Check if upgrade or downgrade */
-    if (build < plus->built) {	/* lower level request */
-
-	/* release old sources (this also initializes structures and numbers of elements) */
-	if (plus->built >= GV_BUILD_CENTROIDS && build < GV_BUILD_CENTROIDS) {
-	    /* reset info about areas stored for centroids */
-	    int nlines = Vect_get_num_lines(Map);
-
-	    for (line = 1; line <= nlines; line++) {
-		Line = plus->Line[line];
-		if (Line && Line->type == GV_CENTROID) {
-		    struct P_topo_c *topo = (struct P_topo_c *)Line->topo;
-		    topo->area = 0;
-		}
-	    }
-	    dig_free_plus_areas(plus);
-	    dig_spidx_free_areas(plus);
-	    dig_free_plus_isles(plus);
-	    dig_spidx_free_isles(plus);
-	}
-
-
-	if (plus->built >= GV_BUILD_AREAS && build < GV_BUILD_AREAS) {
-	    /* reset info about areas stored for lines */
-	    int nlines = Vect_get_num_lines(Map);
-
-	    for (line = 1; line <= nlines; line++) {
-		Line = plus->Line[line];
-		if (Line && Line->type == GV_BOUNDARY) {
-		    struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
-		    topo->left = 0;
-		    topo->right = 0;
-		}
-	    }
-	    dig_free_plus_areas(plus);
-	    dig_spidx_free_areas(plus);
-	    dig_free_plus_isles(plus);
-	    dig_spidx_free_isles(plus);
-	}
-	if (plus->built >= GV_BUILD_BASE && build < GV_BUILD_BASE) {
-	    dig_free_plus_nodes(plus);
-	    dig_spidx_free_nodes(plus);
-	    dig_free_plus_lines(plus);
-	    dig_spidx_free_lines(plus);
-	}
-
-	plus->built = build;
-	return 1;
+    if (build < plus->built) {
+        /* -> downgrade */
+	Vect__build_downgrade(Map, build);
+        return 1;
     }
 
+    /* -> upgrade */
     Points = Vect_new_line_struct();
     Cats = Vect_new_cats_struct();
     
@@ -106,9 +64,9 @@
 	register int npoints, c;
 
 	/* 
-	 *  We shall go through all primitives in coor file and 
-	 *  add new node for each end point to nodes structure
-	 *  if the node with the same coordinates doesn't exist yet.
+	 *  We shall go through all primitives in coor file and add
+	 *  new node for each end point to nodes structure if the node
+	 *  with the same coordinates doesn't exist yet.
 	 */
 
 	/* register lines, create nodes */

Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/build_pg.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -85,12 +85,21 @@
 
     pg_info->inTransaction = FALSE;
 
-    if (build > GV_BUILD_NONE)
+    if (build > GV_BUILD_NONE) {
 	G_message(_("Using external data format '%s' (feature type '%s')"),
 		  Vect_get_finfo_format_info(Map),
-		  Vect_get_finfo_geometry_type(Map));
+		  Vect_get_finfo_geometry_type(Map)); 
+        if (!pg_info->toposchema_name)
+            G_message(_("Building pseudo-topology over simple features..."));
+        else
+            G_message(_("Building topology from PostGIS topology schema <%s>..."),
+                      pg_info->toposchema_name);
+    }
 
-    return Vect__build_sfa(Map, build);
+    if (!pg_info->toposchema_name)
+        return Vect__build_sfa(Map, build);
+    
+    return build_topo(Map, build);
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
     return 0;
@@ -98,9 +107,46 @@
 }
 
 #ifdef HAVE_POSTGRES
+/*!
+  \brief Build based on PostGIS topology
+
+  Currently only GV_BUILD_ALL is supported
+
+  \param Map pointer to Map_info struct
+  \param build build level
+
+  \return 1 on success
+  \return 0 on error
+*/
 int build_topo(struct Map_info *Map, int build)
 {
-    G_fatal_error(_("Not implemented"));
+    struct Format_info_pg *pg_info;
+    struct Plus_head *plus;
+    
+    pg_info = &(Map->fInfo.pg);
+    plus = &(Map->plus);
+    
+    /* check if upgrade or downgrade */
+    if (build < plus->built) { 
+        /* -> downgrade */
+        Vect__build_downgrade(Map, build);
+        return 1;
+    }
+    
+    if (build != GV_BUILD_ALL) {
+        G_warning(_("Only %s is supported for PostGIS topology"),
+                  "GV_BUILD_ALL");
+        return 0;
+    }
+    
+    if (plus->built < GV_BUILD_BASE) {
+        if (load_plus(pg_info, plus, FALSE) != 0)
+            return 0;
+    }
+    
+    plus->built = build;
+    Map->level = 3;
+    
     return 1;
 }
 #endif

Modified: grass/trunk/lib/vector/Vlib/build_sfa.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_sfa.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/build_sfa.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -315,7 +315,6 @@
 void build_pg(struct Map_info *Map, int build)
 {
     int iFeature, ipart, fid, nrecords, npoints;
-    char stmt[DB_SQL_MAX];
     char *wkb_data;
     
     struct Format_info_pg *pg_info;
@@ -329,20 +328,10 @@
     init_parts(&parts);
     G_zero(&fparts, sizeof(struct feat_parts));
     
-    /* get records */
-    sprintf(stmt, "SELECT %s,%s FROM %s.%s",
-	    pg_info->fid_column,
-	    pg_info->geom_column, pg_info->schema_name, pg_info->table_name);
-    G_debug(2, "SQL: %s", stmt);
-    pg_info->res = PQexec(pg_info->conn, stmt);
-    if (!pg_info->res || PQresultStatus(pg_info->res) != PGRES_TUPLES_OK) {
-	PQclear(pg_info->res);
-	pg_info->res = NULL;
-	G_warning(_("Unable to get features:\n%s"),
-		  PQerrorMessage(pg_info->conn));
-	return; /* reading failed */
-    }
-
+    /* get all features */
+    if (set_initial_query(pg_info, TRUE) != 0)
+        return;
+    
     /* scan records */
     npoints = 0;
     nrecords = PQntuples(pg_info->res);
@@ -350,8 +339,8 @@
     G_message(_("Registering primitives..."));
     for (iFeature = 0; iFeature < nrecords; iFeature++) {
 	/* get feature id */
-	fid  = atoi(PQgetvalue(pg_info->res, iFeature, 0));
-	wkb_data = PQgetvalue(pg_info->res, iFeature, 1);
+	fid  = atoi(PQgetvalue(pg_info->res, iFeature, 1));
+	wkb_data = PQgetvalue(pg_info->res, iFeature, 0);
 	
 	G_progress(iFeature + 1, 1e4);
 
@@ -699,70 +688,35 @@
     plus = &(Map->plus);
     
     /* check if upgrade or downgrade */
-    if (build < plus->built) { 
-	/* lower level request, currently only GV_BUILD_NONE */
-	if (plus->built >= GV_BUILD_CENTROIDS && build < GV_BUILD_CENTROIDS) {
-	    /* reset info about areas stored for centroids */
-	    for (line = 1; line <= plus->n_lines; line++) {
-		Line = plus->Line[line];
-		if (Line && Line->type == GV_CENTROID) {
-		    struct P_topo_c *topo = (struct P_topo_c *)Line->topo;
-		    topo->area = 0;
-		}
-	    }
-	    dig_free_plus_areas(plus);
-	    dig_spidx_free_areas(plus);
-	    dig_free_plus_isles(plus);
-	    dig_spidx_free_isles(plus);
-	}
-	
-	if (plus->built >= GV_BUILD_AREAS && build < GV_BUILD_AREAS) {
-	    /* reset info about areas stored for lines */
-	    for (line = 1; line <= plus->n_lines; line++) {
-		Line = plus->Line[line];
-		if (Line && Line->type == GV_BOUNDARY) {
-		    struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
-		    topo->left = 0;
-		    topo->right = 0;
-		}
-	    }
-	    dig_free_plus_areas(plus);
-	    dig_spidx_free_areas(plus);
-	    dig_free_plus_isles(plus);
-	    dig_spidx_free_isles(plus);
-	}
-
-	if (plus->built >= GV_BUILD_BASE && build < GV_BUILD_BASE) {
-	    dig_free_plus_nodes(plus);
-	    dig_spidx_free_nodes(plus);
-	    dig_free_plus_lines(plus);
-	    dig_spidx_free_lines(plus);
-	}
+    if (build < plus->built) {
+        /* -> downgrade */
+        Vect__build_downgrade(Map, build);
+        return 1;
     }
-    else {
-	if (plus->built < GV_BUILD_BASE) {
-	    if (Map->format == GV_FORMAT_OGR ||
-		Map->format == GV_FORMAT_OGR_DIRECT) {
+    
+    /* -> upgrade */
+    if (plus->built < GV_BUILD_BASE) {
+        if (Map->format == GV_FORMAT_OGR ||
+            Map->format == GV_FORMAT_OGR_DIRECT) {
 #ifdef HAVE_OGR
-		build_ogr(Map, build);
+            build_ogr(Map, build);
 #else
-		G_fatal_error(_("GRASS is not compiled with OGR support"));
+            G_fatal_error(_("GRASS is not compiled with OGR support"));
 #endif
-	    }
- 	    else if (Map->format == GV_FORMAT_POSTGIS) {
+        }
+        else if (Map->format == GV_FORMAT_POSTGIS) {
 #ifdef HAVE_POSTGRES
-		build_pg(Map, build);
+            build_pg(Map, build);
 #else
-		G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+            G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
 #endif
-	    }
-	    else {
-		G_fatal_error(_("%s: Native format unsupported"),
-			      "Vect__build_sfa()");
-	    }
-	}
+        }
+        else {
+            G_fatal_error(_("%s: Native format unsupported"),
+                          "Vect__build_sfa()");
+        }
     }
-
+    
     plus->built = build;
     
     return 1;

Modified: grass/trunk/lib/vector/Vlib/close.c
===================================================================
--- grass/trunk/lib/vector/Vlib/close.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/close.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -75,15 +75,15 @@
     G_debug(1, "Vect_close(): name = %s, mapset = %s, format = %d, level = %d",
 	    Map->name, Map->mapset, Map->format, Map->level);
 
-    /* Store support files for vector maps in the current mapsset if
-       in write mode on level 2 */
+    /* store support files for vector maps in the current mapset if in
+       write mode on level 2 */
     if (strcmp(Map->mapset, G_mapset()) == 0 &&
 	Map->support_updated &&
 	Map->plus.built == GV_BUILD_ALL) {
 	char buf[GPATH_MAX];
 	char file_path[GPATH_MAX];
 
-	/* Delete old support files if available */
+	/* delete old support files if available */
 	sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
 
 	G_file_name(file_path, buf, GV_TOPO_ELEMENT, G_mapset());
@@ -110,8 +110,8 @@
 	Map->plus.coor_mtime = CInfo.mtime;
 
 	/* write out topo file */
-	Vect_save_topo(Map);
-
+        Vect_save_topo(Map);
+        
 	/* write out sidx file */
 	Map->plus.Spidx_new = TRUE;
 	Vect_save_sidx(Map);
@@ -122,7 +122,7 @@
 	/* write out fidx file */
 	if (Map->format == GV_FORMAT_OGR)
 	    V2_close_ogr(Map);
-	else if (Map->format == GV_FORMAT_POSTGIS)
+	else if (Map->format == GV_FORMAT_POSTGIS && Map->level == 2)
 	    V2_close_pg(Map);
     }
     else {
@@ -135,7 +135,7 @@
 	    fclose(Map->plus.spidx_fp.file);
     }
 
-    if (Map->level == 2 && Map->plus.release_support) {
+    if (Map->level > 1 && Map->plus.release_support) {
 	G_debug(1, "free topology");
 	dig_free_plus(&(Map->plus));
 
@@ -153,7 +153,7 @@
 	    fclose(Map->hist_fp);
     }
 
-    /* Close level 1 files / data sources if not head_only */
+    /* close level 1 files / data sources if not head_only */
     if (!Map->head_only) {
 	if (((*Close_array[Map->format][1]) (Map)) != 0) {
 	    G_warning(_("Unable to close vector <%s>"),

Modified: grass/trunk/lib/vector/Vlib/open.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/open.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -26,9 +26,20 @@
 #include <grass/glocale.h>
 
 /*
-  \brief Number of levels - without and with topology
+  \brief Number of levels
+
+  Native format:
+   - 1 without topology
+   - 2 with topology
+  OGR-links:
+   - 1 without topology
+   - 2 with pseudo-topology (simple features access)
+  PG-links:
+   - 1 without topology
+   - 2 with pseudo-topology (simple features access)
+   - 3 with topology (PostGIS Topology access)
 */
-#define MAX_OPEN_LEVEL 2
+#define MAX_OPEN_LEVEL 3
 
 static int open_old_dummy()
 {
@@ -231,7 +242,7 @@
     G_debug(1, "Map name: %s", Map->name);
     G_debug(1, "Map mapset: %s", Map->mapset);
 
-    /* Read vector format information */
+    /* read vector format information */
     if (ogr_mapset) {
         format = GV_FORMAT_OGR_DIRECT;
     }
@@ -273,19 +284,19 @@
     G_debug(1, "Level request = %d", level_request);
 
     /* There are only 2 possible open levels, 1 and 2. Try first to
-     * open 'support' files (topo,sidx,cidx), these files are the same
-     * for all formats.  If it is not possible and requested level is
-     * 2, return error, otherwise call Open_old_array[format][1], to
-     * open remaining files/sources (level 1)
-     */
+       open 'support' files (topo, sidx, cidx), these files are the same
+       for all formats.  If it is not possible and requested level is
+       2, return error, otherwise call Open_old_array[format][1], to
+       open remaining files/sources (level 1)
+    */
 
-    /* Try to open support files if level was not requested or
+    /* try to open support files if level was not requested or
      * requested level is 2 (format independent) */
-    if (level_request == 0 || level_request == 2) {
+    if (level_request == 0 || level_request > 1) {
         level = 2;              /* we expect success */
+        
         /* open topo */
         ret = -1;
-        
         if (Map->format == GV_FORMAT_POSTGIS)
             /* try to read full-topology for PostGIS links */
             ret = Vect_open_topo_pg(Map, head_only);
@@ -513,7 +524,8 @@
         if (access(file_path, F_OK) == 0)       /* cidx file exists? */
             unlink(file_path);
 
-        if (format == GV_FORMAT_OGR || format == GV_FORMAT_POSTGIS) {
+        if (format == GV_FORMAT_OGR ||
+            (format == GV_FORMAT_POSTGIS && level == 2)) {
             G_file_name(file_path, buf, GV_FIDX_ELEMENT, G_mapset());
             if (access(file_path, F_OK) == 0)   /* fidx file exists? */
                 unlink(file_path);
@@ -1063,12 +1075,9 @@
     ret = dig_load_plus(Plus, &fp, head_only);
 
     fclose(fp.file);
-    /* dig_file_free ( &fp); */
-
-    if (ret == 0)
-        return -1;
-
-    return 0;
+    /* dig_file_free(&fp); */
+    
+    return ret == 0 ? -1 : 0;
 }
 
 /*!
@@ -1082,7 +1091,7 @@
 */
 int Vect_open_sidx(struct Map_info *Map, int mode)
 {
-    char buf[500], file_path[2000];
+    char buf[GPATH_MAX], file_path[GPATH_MAX];
     int err;
     struct Coor_info CInfo;
     struct Plus_head *Plus;
@@ -1090,15 +1099,15 @@
     G_debug(1, "Vect_open_sidx(): name = %s mapset= %s mode = %s", Map->name,
             Map->mapset, mode == 0 ? "old" : (mode == 1 ? "update" : "new"));
 
-    if (Map->plus.Spidx_built == TRUE) {
-        G_warning("Spatial index already opened");
+    Plus = &(Map->plus);
+
+    if (Plus->Spidx_built) {
+        G_debug(1, "Spatial index already opened");
         return 0;
     }
 
-    Plus = &(Map->plus);
+    dig_file_init(&(Plus->spidx_fp));
 
-    dig_file_init(&(Map->plus.spidx_fp));
-
     if (mode < 2) {
         sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
         G_file_name(file_path, buf, GV_SIDX_ELEMENT, Map->mapset);
@@ -1106,10 +1115,10 @@
         if (access(file_path, F_OK) != 0)       /* does not exist */
             return 1;
 
-        Map->plus.spidx_fp.file =
+        Plus->spidx_fp.file =
             G_fopen_old(buf, GV_SIDX_ELEMENT, Map->mapset);
 
-        if (Map->plus.spidx_fp.file == NULL) {  /* sidx file is not available */
+        if (Plus->spidx_fp.file == NULL) {  /* sidx file is not available */
             G_debug(1, "Cannot open spatial index file for vector '%s@%s'.",
                     Map->name, Map->mapset);
             return -1;
@@ -1120,11 +1129,11 @@
         Vect_coor_info(Map, &CInfo);
 
         /* initialize spatial index */
-        Map->plus.Spidx_new = FALSE;
+        Plus->Spidx_new = FALSE;
 
         /* load head */
-        if (dig_Rd_spidx_head(&(Map->plus.spidx_fp), Plus) == -1) {
-            fclose(Map->plus.spidx_fp.file);
+        if (dig_Rd_spidx_head(&(Plus->spidx_fp), Plus) == -1) {
+            fclose(Plus->spidx_fp.file);
             return -1;
         }
 
@@ -1147,36 +1156,36 @@
         if (err) {
             G_warning(_("Please rebuild topology for vector map <%s@%s>"),
                       Map->name, Map->mapset);
-            fclose(Map->plus.spidx_fp.file);
+            fclose(Plus->spidx_fp.file);
             return -1;
         }
     }
 
     if (mode) {
         /* open new spatial index */
-        Map->plus.Spidx_new = TRUE;
+        Plus->Spidx_new = TRUE;
         
         /* file based or memory based */
         if (getenv("GRASS_VECTOR_LOWMEM")) {
             /* free old indices */
             dig_spidx_free(Plus);
             /* initialize file based indices */
-            Map->plus.Spidx_file = 1;
+            Plus->Spidx_file = 1;
             dig_spidx_init(Plus);
         }
         G_debug(1, "%s based spatial index",
-                   Map->plus.Spidx_file == 0 ? "Memory" : "File");
+                   Plus->Spidx_file == 0 ? "Memory" : "File");
 
         if (mode == 1) {
             /* load spatial index for update */
-            if (dig_Rd_spidx(&(Map->plus.spidx_fp), Plus) == -1) {
-                fclose(Map->plus.spidx_fp.file);
+            if (dig_Rd_spidx(&(Plus->spidx_fp), Plus) == -1) {
+                fclose(Plus->spidx_fp.file);
                 return -1;
             }
         }
     }
 
-    Map->plus.Spidx_built = TRUE;
+    Plus->Spidx_built = TRUE;
 
     return 0;
 }

Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/open_pg.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -23,7 +23,7 @@
 #ifdef HAVE_POSTGRES
 #include "pg_local_proto.h"
 
-static struct edge_data {
+struct edge_data {
     int id;
     int start_node;
     int end_node;
@@ -37,17 +37,17 @@
 static int check_schema(const struct Format_info_pg *);
 static int create_table(struct Format_info_pg *, const struct field_info *);
 static void connect_db(struct Format_info_pg *);
+static int check_topo(struct Format_info_pg *, struct Plus_head *);
 static int parse_bbox(const char *, struct bound_box *, int);
 static int num_of_records(const struct Format_info_pg *, const char *);
 static int read_p_node(struct Plus_head *, int, int, struct Format_info_pg *);
-static int read_p_line(struct Plus_head *, int, const struct edge_data *, struct Format_info_pg *);
+static int read_p_line(struct Plus_head *, int, const struct edge_data *);
 static int read_p_area(struct Plus_head *, int, int, struct Format_info_pg *);
-static int load_plus_head(struct Format_info_pg *, PGresult *, struct Plus_head *);
-static int load_plus(struct Format_info_pg *, PGresult *, struct Plus_head *);
+static int load_plus_head(struct Format_info_pg *, struct Plus_head *);
 #endif
 
 /*!
-   \brief Open existing PostGIS feature table (level 1 - without topology)
+   \brief Open vector map - PostGIS feature table (level 1 - without topology)
 
    \todo Check database instead of geometry_columns
 
@@ -127,8 +127,12 @@
     if (!found) {
         G_warning(_("Feature table <%s> not found in 'geometry_columns'"),
                   pg_info->table_name);
+        return -1;
     }
 
+    /* check for topo schema */
+    check_topo(pg_info, &(Map->plus));
+    
     return 0;
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -137,7 +141,7 @@
 }
 
 /*!
-   \brief Open existing PostGIS layer (level 2 - feature index)
+   \brief Open vector map - PostGIS feature table (level 2 - feature index)
 
    \param[in,out] Map pointer to Map_info structure
 
@@ -387,51 +391,20 @@
 int Vect_open_topo_pg(struct Map_info *Map, int head_only)
 {
 #ifdef HAVE_POSTGRES
-    char stmt[DB_SQL_MAX];
-
     struct Plus_head *plus;
     struct Format_info_pg *pg_info;
     
-    PGresult *res;
-
     plus = &(Map->plus);
     pg_info = &(Map->fInfo.pg);
     
-    /* connect database */
-    if (!pg_info->conn)
-        connect_db(pg_info);
+    /* check for topo schema */
+    if (check_topo(pg_info, plus) != 0)
+        return 1;
     
-    /* check if topology layer/schema exists */
-    sprintf(stmt,
-            "SELECT t.name,t.hasz,l.feature_column FROM topology.layer "
-            "AS l JOIN topology.topology AS t ON l.topology_id = t.id "
-            "WHERE schema_name = '%s' AND table_name = '%s'",
-            pg_info->schema_name, pg_info->table_name);
-    G_debug(2, "SQL: %s", stmt);
-    
-    res = PQexec(pg_info->conn, stmt);
-    if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
-        PQntuples(res) != 1) {
-        G_debug(1, "Topology layers for '%s.%s' not found (%s)",
-                pg_info->schema_name, pg_info->table_name,
-                PQerrorMessage(pg_info->conn));
-        if (res)
-            PQclear(res);
-        return 1;
-    }
-
-    pg_info->toposchema_name = G_store(PQgetvalue(res, 0, 0));
-    pg_info->topogeom_column = G_store(PQgetvalue(res, 0, 2));
-
     /* free and init plus structure */
     dig_init_plus(plus);
-    if (load_plus_head(pg_info, res, plus) != 0)
-        return -1;
     
-    if (head_only)
-        return 0;
-    
-    return load_plus(pg_info, res, plus);
+    return load_plus(pg_info, plus, head_only);
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
     return -1;
@@ -439,6 +412,14 @@
 }
 
 #ifdef HAVE_POSTGRES
+/*!
+  \brief Get key column for feature table
+
+  \param pg_info pointer to Format_info_pg
+   
+  \return string buffer with key column name
+  \return NULL on missing key column
+*/
 char *get_key_column(struct Format_info_pg *pg_info)
 {
     char *key_column;
@@ -478,10 +459,17 @@
     return key_column;
 }
 
+/*!
+  \brief Get simple feature type from string
+
+  \param type string
+
+  \return SF type
+*/
 SF_FeatureType ftype_from_string(const char *type)
 {
     SF_FeatureType sf_type;
-
+    
     if (G_strcasecmp(type, "POINT") == 0)
         return SF_POINT;
     else if (G_strcasecmp(type, "LINESTRING") == 0)
@@ -496,14 +484,22 @@
         return SF_MULTIPOLYGON;
     else if (G_strcasecmp(type, "GEOMETRYCOLLECTION") == 0)
         return SF_GEOMETRYCOLLECTION;
-
-    return SF_UNKNOWN;
-
+    else
+        return SF_UNKNOWN;
+    
     G_debug(3, "ftype_from_string(): type='%s' -> %d", type, sf_type);
-
+    
     return sf_type;
 }
 
+/*!
+  \brief Drop feature table
+
+  \param pg_info pointer to Format_info_pg
+
+  \return -1 on error
+  \return 0 on success
+*/
 int drop_table(struct Format_info_pg *pg_info)
 {
     char stmt[DB_SQL_MAX];
@@ -518,6 +514,14 @@
     return 0;
 }
 
+/*!
+  \brief Creates new schema for feature table if not exists
+
+  \param pg_info pointer to Format_info_pg
+
+  \return -1 on error
+  \return 0 on success
+*/
 int check_schema(const struct Format_info_pg *pg_info)
 {
     int i, found, nschema;
@@ -558,6 +562,15 @@
     return 0;
 }
 
+/*!
+  \brief Create new feature table
+
+  \param pg_info pointer to Format_info_pg
+  \param Fi pointer to field_info
+
+  \return -1 on error
+  \return 0 on success
+*/
 int create_table(struct Format_info_pg *pg_info, const struct field_info *Fi)
 {
     int spatial_index, primary_key;
@@ -760,6 +773,11 @@
     return 0;
 }
 
+/*!
+  \brief Establish PG connection (pg_info->conninfo)
+
+  \param pg_info pointer to Format_info_pg
+*/
 void connect_db(struct Format_info_pg *pg_info)
 {
     pg_info->conn = PQconnectdb(pg_info->conninfo);
@@ -771,6 +789,60 @@
 }
 
 /*!
+  \brief Check for topology schema (pg_info->toposchema_name)
+
+  \param pg_info pointer to Format_info_pg
+
+  \return 0 schema exists
+  \return 1 schema doesn't exists
+ */
+int check_topo(struct Format_info_pg *pg_info, struct Plus_head *plus)
+{
+    char stmt[DB_SQL_MAX];
+    
+    PGresult *res;
+    
+    /* connect database */
+    if (!pg_info->conn)
+        connect_db(pg_info);
+    
+    if (pg_info->toposchema_name)
+        return 0;
+    
+    /* check if topology layer/schema exists */
+    sprintf(stmt,
+            "SELECT t.name,t.hasz,l.feature_column FROM topology.layer "
+            "AS l JOIN topology.topology AS t ON l.topology_id = t.id "
+            "WHERE schema_name = '%s' AND table_name = '%s'",
+            pg_info->schema_name, pg_info->table_name);
+    G_debug(2, "SQL: %s", stmt);
+    
+    res = PQexec(pg_info->conn, stmt);
+    if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
+        PQntuples(res) != 1) {
+        G_debug(1, "Topology layers for '%s.%s' not found (%s)",
+                pg_info->schema_name, pg_info->table_name,
+                PQerrorMessage(pg_info->conn));
+        if (res)
+            PQclear(res);
+        return 1;
+    }
+
+    pg_info->toposchema_name = G_store(PQgetvalue(res, 0, 0));
+    pg_info->topogeom_column = G_store(PQgetvalue(res, 0, 2));
+
+    G_debug(1, "PostGIS topology detected: schema = %s column = %s",
+            pg_info->toposchema_name, pg_info->topogeom_column);
+    
+    /* check for 3D */
+    if (strcmp(PQgetvalue(res, 0, 1), "t") == 0)
+        plus->with_z = WITH_Z;
+    PQclear(res);
+    
+    return 0;
+}
+
+/*!
   \brief Parse BBOX string
   
   \param value string buffer
@@ -986,8 +1058,7 @@
   \return -1 on failure
 */
 int read_p_line(struct Plus_head *plus, int n,
-                const struct edge_data *data,
-                struct Format_info_pg *pg_info)
+                const struct edge_data *data)
 {
     int tp;
     struct P_line *line;
@@ -1120,24 +1191,21 @@
 }
 
 /*!
-  \brief Read topo header info only
+  \brief Read topo (from PostGIS topology schema) header info only
 
   \param[in,out] plus pointer to Plus_head struct
 
   \return 0 on success
   \return -1 on error
 */
-int load_plus_head(struct Format_info_pg *pg_info, PGresult *res, struct Plus_head *plus)
+int load_plus_head(struct Format_info_pg *pg_info, struct Plus_head *plus)
 {
     char stmt[DB_SQL_MAX];
     
+    PGresult *res;
+    
     plus->off_t_size = -1;
     
-    /* check for 3D */
-    if (strcmp(PQgetvalue(res, 0, 1), "t") == 0)
-        plus->with_z = WITH_Z;
-    PQclear(res);
-    
     /* get map bounding box */
     sprintf(stmt,
             "SELECT ST_3DExtent(%s) FROM \"%s\".\"%s\"",
@@ -1213,7 +1281,6 @@
             "SELECT COUNT(*) FROM \"%s\".face WHERE mbr IS NOT NULL",
             pg_info->toposchema_name);
     plus->n_clines = num_of_records(pg_info, stmt);
-    plus->n_lines += plus->n_plines; /* register isolated nodes as points */
     G_debug(3, "Vect_open_topo_pg(): n_clines=%d", plus->n_clines);
     /* TODO: nflines | n_klines */
 
@@ -1225,19 +1292,30 @@
 }
 
 /*!
-  \brief Read topo info
+  \brief Read topo info (from PostGIS topology schema)
 
+  \param pg_info pointer to Format_info_pg
   \param[in,out] plus pointer to Plus_head struct
-
+  \param head_only TRUE to read only header info
+  
   \return 0 on success
   \return -1 on error
 */
-int load_plus(struct Format_info_pg *pg_info, PGresult *res, struct Plus_head *plus)
+int load_plus(struct Format_info_pg *pg_info, struct Plus_head *plus,
+              int head_only)
 {
     int i, id, ntuples;
     char stmt[DB_SQL_MAX];
     struct edge_data line_data;
     
+    PGresult *res;
+  
+    if (load_plus_head(pg_info, plus) != 0)
+        return -1;
+
+    if (head_only)
+        return 0;
+    
     /* read nodes (GRASS Topo)
        note: standalone nodes are ignored
     */
@@ -1258,6 +1336,7 @@
         return -1;
     }
 
+    G_debug(3, "load_plus(): n_nodes = %d", plus->n_nodes);
     dig_alloc_nodes(plus, plus->n_nodes);
     for (i = 1; i <= plus->n_nodes; i++) {
         id = atoi(PQgetvalue(res, i - 1, 0));
@@ -1267,8 +1346,9 @@
 
     /* read lines (GRASS Topo)
        - standalone nodes -> points
-       - edges -> lines/bouindaries
+       - edges -> lines/boundaries
     */
+    G_debug(3, "load_plus(): n_lines = %d", plus->n_lines);
     dig_alloc_lines(plus, plus->n_lines); 
     
     /* read PostGIS Topo standalone nodes */
@@ -1282,7 +1362,7 @@
     G_debug(2, "SQL: %s", stmt);
     res = PQexec(pg_info->conn, stmt);
     if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ||
-        PQntuples(res) > plus->n_lines) {
+        PQntuples(res) > plus->n_plines) {
         G_warning(_("Unable to read lines"));
         if (res)
             PQclear(res);
@@ -1294,7 +1374,7 @@
     for (i = 0; i < ntuples; i++) {
         /* process standalone nodes (PostGIS Topo) */
         line_data.id = atoi(PQgetvalue(res, i, 0));
-        read_p_line(plus, i + 1, &line_data, pg_info);
+        read_p_line(plus, i + 1, &line_data);
     }
     PQclear(res);
     
@@ -1321,7 +1401,7 @@
         line_data.end_node   = atoi(PQgetvalue(res, i, 2));
         line_data.left_face  = atoi(PQgetvalue(res, i, 3));
         line_data.right_face = atoi(PQgetvalue(res, i, 4));
-        read_p_line(plus, plus->n_plines + i + 1, &line_data, pg_info);
+        read_p_line(plus, plus->n_plines + i + 1, &line_data);
     }
     PQclear(res);
     
@@ -1339,14 +1419,14 @@
         return -1;
     }
     
+    G_debug(3, "load_plus(): n_areas = %d", plus->n_areas);
     dig_alloc_areas(plus, plus->n_areas);
     G_zero(&line_data, sizeof(struct edge_data));
     for (i = 1; i <= plus->n_areas; i++) {
         line_data.id = line_data.left_face = atoi(PQgetvalue(res, i - 1, 0));
         read_p_area(plus, i, line_data.id, pg_info);
         /* add centroids */
-        read_p_line(plus, plus->n_lines - plus->n_clines + i,
-                    &line_data, pg_info);
+        read_p_line(plus, plus->n_lines - plus->n_clines + i, &line_data);
     }
     PQclear(res);
     

Modified: grass/trunk/lib/vector/Vlib/pg_local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/pg_local_proto.h	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/pg_local_proto.h	2012-06-05 12:44:17 UTC (rev 51975)
@@ -52,6 +52,8 @@
 SF_FeatureType cache_feature(const char *, int,
 			     struct Format_info_cache *,
 			     struct feat_parts *);
+int set_initial_query(struct Format_info_pg *, int);
+int load_plus(struct Format_info_pg *, struct Plus_head *, int);
 
 #endif /* HAVE_POSTGRES */
 

Modified: grass/trunk/lib/vector/Vlib/read.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/read.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -50,7 +50,7 @@
 #endif
 #ifdef HAVE_POSTGRES
     , {
-	read_dummy, V1_read_next_line_pg, V2_read_next_line_pg, V2_read_next_line_pg}
+	read_dummy, V1_read_next_line_pg, V2_read_next_line_pg, V3_read_next_line_pg}
 #else
     , {
 	read_dummy, format, format, format}

Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/Vlib/read_pg.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -44,7 +44,6 @@
                                         struct Format_info_cache *,
                                         struct feat_parts *);
 static int error_corrupted_data(const char *);
-static int set_initial_query();
 static void reallocate_cache(struct Format_info_cache *, int);
 static void add_fpart(struct feat_parts *, SF_FeatureType, int, int);
 static int read_centroid_pg(struct Format_info_pg *, int, struct line_pnts *);
@@ -86,7 +85,8 @@
 }
 
 /*!
-   \brief Read next feature from PostGIS layer on topological level.
+   \brief Read next feature from PostGIS layer on topological level
+   (simple feature access).
 
    This function implements sequential access.
 
@@ -201,6 +201,28 @@
 }
 
 /*!
+   \brief Read next feature from PostGIS layer on topological level
+   (PostGIS topology access).
+
+   This function implements sequential access.
+
+   \param Map pointer to Map_info structure
+   \param[out] line_p container used to store line points within
+   (pointer to line_pnts struct)
+   \param[out] line_c container used to store line categories within
+   (pointer to line_cats struct)
+
+   \return feature type
+   \return -2 no more features (EOF)
+   \return -1 on failure
+ */
+int V3_read_next_line_pg(struct Map_info *Map, struct line_pnts *line_p,
+                         struct line_cats *line_c)
+{
+    return V2_read_next_line_pg(Map, line_p, line_c);
+}
+
+/*!
    \brief Read feature from PostGIS layer at given offset (level 1 without topology)
 
    This function implements random access on level 1.
@@ -300,7 +322,7 @@
         return -1;
     }
     
-    G_debug(4, "V3_read_line_pg() line = %d type = %d offset = %llu",
+    G_debug(4, "V3_read_line_pg() line = %d type = %d offset = %lu",
             line, Line->type, Line->offset);
     
     if (!line_p && !line_c)
@@ -348,9 +370,6 @@
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
     return -1;
 #endif
-
-
-
 }
 
 #ifdef HAVE_POSTGRES
@@ -478,7 +497,7 @@
     if (fid < 1) {
         /* next (read n features) */
         if (!pg_info->res) {
-            if (set_initial_query(pg_info) == -1)
+            if (set_initial_query(pg_info, FALSE) == -1)
                 return -1;
         }
     }
@@ -1102,30 +1121,53 @@
    \return 0 on success
    \return -1 on error
  */
-int set_initial_query(struct Format_info_pg *pg_info)
+int set_initial_query(struct Format_info_pg *pg_info, int fetch_all)
 {
     char stmt[DB_SQL_MAX];
 
     if (execute(pg_info->conn, "BEGIN") == -1)
         return -1;
 
-    sprintf(stmt,
-            "DECLARE %s_%s%p CURSOR FOR SELECT %s,%s FROM \"%s\".\"%s\"",
-            pg_info->schema_name, pg_info->table_name, pg_info->conn,
-            pg_info->geom_column, pg_info->fid_column, pg_info->schema_name,
-            pg_info->table_name);
+    if (!pg_info->toposchema_name) {
+        /* simple feature access */
+        sprintf(stmt,
+                "DECLARE %s_%s%p CURSOR FOR SELECT %s,%s FROM \"%s\".\"%s\"",
+                pg_info->schema_name, pg_info->table_name, pg_info->conn,
+                pg_info->geom_column, pg_info->fid_column, pg_info->schema_name,
+                pg_info->table_name);
+    }
+    else {
+        /* topology access */
+        sprintf(stmt,
+                "DECLARE %s_%s%p CURSOR FOR "
+                "SELECT geom,row_number() OVER "
+                "(ORDER BY ST_GeometryType(geom) DESC) AS fid FROM ("
+                "SELECT geom FROM \"%s\".node WHERE node_id NOT IN "
+                "(SELECT node FROM (SELECT start_node AS node FROM \"%s\".edge "
+                "GROUP BY start_node UNION ALL SELECT end_node AS node FROM "
+                "\"%s\".edge GROUP BY end_node) AS foo) "
+                "UNION ALL SELECT geom FROM \"%s\".edge) AS foo",
+                pg_info->schema_name, pg_info->table_name, pg_info->conn,
+                pg_info->toposchema_name, pg_info->toposchema_name,
+                pg_info->toposchema_name, pg_info->toposchema_name); 
+    }
     G_debug(2, "SQL: %s", stmt);
-
+    
     if (execute(pg_info->conn, stmt) == -1) {
         execute(pg_info->conn, "ROLLBACK");
         return -1;
     }
 
-    sprintf(stmt, "FETCH %d in %s_%s%p", CURSOR_PAGE,
-            pg_info->schema_name, pg_info->table_name, pg_info->conn);
+    if (fetch_all)
+        sprintf(stmt, "FETCH ALL in %s_%s%p",
+                pg_info->schema_name, pg_info->table_name, pg_info->conn);
+    else
+        sprintf(stmt, "FETCH %d in %s_%s%p", CURSOR_PAGE,
+                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");
+        G_warning(_("Unable to get features"));
         return -1;
     }
     pg_info->next_line = 0;

Modified: grass/trunk/lib/vector/diglib/spindex.c
===================================================================
--- grass/trunk/lib/vector/diglib/spindex.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/diglib/spindex.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -821,7 +821,7 @@
 }
 
 /*!
-   \brief Find box for area
+   \brief Find bounding box for given area
 
    \param Plus pointer to Plus_head structure
    \param[in,out] list list with area id and search box (in)/area box (out)
@@ -844,7 +844,7 @@
     G_debug(3, "dig_find_line_box()");
 
     if (list->n_values < 1)
-	G_fatal_error(_("No line id given"));
+	G_fatal_error(_("Unable to get area bounding box. No feature id given."));
 
     rect.boundary[0] = list->box[0].W;
     rect.boundary[1] = list->box[0].S;
@@ -858,7 +858,7 @@
     else
 	ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, list, Plus);
 
-    return (ret);
+    return ret;
 }
 
 /*! 

Modified: grass/trunk/lib/vector/diglib/spindex_rw.c
===================================================================
--- grass/trunk/lib/vector/diglib/spindex_rw.c	2012-06-04 21:15:02 UTC (rev 51974)
+++ grass/trunk/lib/vector/diglib/spindex_rw.c	2012-06-05 12:44:17 UTC (rev 51975)
@@ -93,7 +93,7 @@
 	else if (ptr->off_t_size == 8)
 	    length = 117;
 	else
-	    G_fatal_error("topo must be written before sidx");
+            G_fatal_error(_("Topology file must be written before spatial index file"));
     }
     else if (ptr->spidx_port.off_t_size == 8) {
 	if (ptr->off_t_size == 4)
@@ -101,7 +101,7 @@
 	else if (ptr->off_t_size == 8)
 	    length = 145;
 	else
-	    G_fatal_error("topo must be written before sidx");
+            G_fatal_error(_("Topology file must be written before spatial index file"));
     }
 
     /* bytes 7 - 10 : header size */
@@ -1335,8 +1335,6 @@
     assert(t);
 
     if (!stack_init) {
-	struct Rect_Real *r;
-
 	for (i = 0; i < MAXLEVEL; i++) {
 	    for (j = 0; j < MAXCARD; j++) {
 		s[i].sn.branch[j].rect.boundary = G_malloc(6 * sizeof(RectReal));



More information about the grass-commit mailing list