[GRASS-SVN] r58246 - in grass/trunk: include/vect lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Nov 17 09:59:58 PST 2013


Author: martinl
Date: 2013-11-17 09:59:57 -0800 (Sun, 17 Nov 2013)
New Revision: 58246

Modified:
   grass/trunk/include/vect/dig_structs.h
   grass/trunk/lib/vector/Vlib/open_pg.c
   grass/trunk/lib/vector/Vlib/read_pg.c
Log:
vlib/pg: fix reading categories from PostGIS Topology (work in progress)


Modified: grass/trunk/include/vect/dig_structs.h
===================================================================
--- grass/trunk/include/vect/dig_structs.h	2013-11-17 17:58:14 UTC (rev 58245)
+++ grass/trunk/include/vect/dig_structs.h	2013-11-17 17:59:57 UTC (rev 58246)
@@ -474,6 +474,10 @@
     */
     int *lines_types;
     /*!
+      \brief List of line cats (used only for PostGIS Topology access)
+    */
+    int *lines_cats;
+    /*!
       \brief Number of allocated lines in cache
     */
     int lines_alloc;

Modified: grass/trunk/lib/vector/Vlib/open_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open_pg.c	2013-11-17 17:58:14 UTC (rev 58245)
+++ grass/trunk/lib/vector/Vlib/open_pg.c	2013-11-17 17:59:57 UTC (rev 58246)
@@ -1231,7 +1231,7 @@
                 pg_info->toposchema_name);
     else
         sprintf(stmt, "SELECT node.node_id,geom,lines,angles FROM \"%s\".node AS node "
-                "join \"%s\".%s AS node_grass ON node.node_id = node_grass.node_id "
+                "JOIN \"%s\".%s AS node_grass ON node.node_id = node_grass.node_id "
                 "ORDER BY node_id", pg_info->toposchema_name, pg_info->toposchema_name,
                 TOPO_TABLE_NODE);
     G_debug(2, "SQL: %s", stmt);

Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c	2013-11-17 17:58:14 UTC (rev 58245)
+++ grass/trunk/lib/vector/Vlib/read_pg.c	2013-11-17 17:59:57 UTC (rev 58246)
@@ -116,8 +116,12 @@
     struct P_line *Line;
     struct bound_box lbox, mbox;
 
+    struct Format_info_pg *pg_info;
+    
     G_debug(3, "V2_read_next_line_pg()");
 
+    pg_info = &(Map->fInfo.pg);
+    
     if (Map->constraint.region_flag)
         Vect_get_constraint_box(Map, &mbox);
 
@@ -142,8 +146,9 @@
             }
         }
 
-        if (Line->type == GV_CENTROID) {
-            G_debug(4, "Centroid");
+        if (!pg_info->toposchema_name &&
+            Line->type == GV_CENTROID) {
+            G_debug(4, "Determine centroid for simple features");
 
             if (line_p != NULL) {
                 int i, found;
@@ -263,7 +268,7 @@
         get_feature(pg_info, fid, -1);
 
         if (pg_info->cache.sf_type == SF_NONE) {
-            G_warning(_("Feature %d without geometry skipped"), fid);
+            G_warning(_("Feature %ld without geometry skipped"), fid);
             return -1;
         }
 
@@ -338,15 +343,8 @@
     if (!line_p && !line_c)
         return Line->type;
 
-    if (line_c) {
-        Vect_reset_cats(line_c);
-        Vect_cat_set(line_c, 1, (int) Line->offset);
-    }
-
-    if (!line_p)
-        return Line->type;
-    
-    Vect_reset_line(line_p);
+    if (line_p)
+        Vect_reset_line(line_p);
     if (Line->type == GV_CENTROID && !pg_info->toposchema_name) {
         /* simple features access: get centroid from sidx */
         return get_centroid(Map, line, line_p);
@@ -368,9 +366,22 @@
     }
     if (0 > (int)pg_info->cache.sf_type) /* -1 || - 2 */
         return -1;
+
+    if (line_c) {
+        int cat;
+
+        Vect_reset_cats(line_c);
+        if (!pg_info->toposchema_name) /* simple features access */
+            cat = (int) Line->offset;
+        else                           /* PostGIS Topology (cats are cached) */
+            cat = pg_info->cache.lines_cats[0];
+        if (cat != -1)
+            Vect_cat_set(line_c, 1, cat);
+    }
+
+    if (line_p)
+        Vect_append_points(line_p, pg_info->cache.lines[0], GV_FORWARD);
     
-    Vect_append_points(line_p, pg_info->cache.lines[0], GV_FORWARD);
-    
     return Line->type;
 #else
     G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
@@ -422,7 +433,7 @@
             sf_type = get_feature(pg_info, -1, -1);
             
             if (sf_type == SF_NONE) {
-                G_warning(_("Feature %d without geometry skipped"), pg_info->cache.fid);
+                G_warning(_("Feature %ld without geometry skipped"), pg_info->cache.fid);
                 return -1;
             }
 
@@ -467,8 +478,15 @@
         if (line_p)
             Vect_append_points(line_p, iline, GV_FORWARD);
 
-        if (line_c)
-            Vect_cat_set(line_c, 1, (int)pg_info->cache.fid);
+        if (line_c) {
+            int cat;
+            if (!pg_info->toposchema_name) /* simple features access */
+                cat = (int)pg_info->cache.fid;
+            else                           /* PostGIS Topology (cats are cached) */
+                cat = pg_info->cache.lines_cats[pg_info->cache.lines_next];
+            if (cat != -1)
+                Vect_cat_set(line_c, 1, cat);
+        }
 
         pg_info->cache.lines_next++;
 
@@ -597,10 +615,19 @@
                                                     FALSE, force_type,
                                                     &(pg_info->cache), NULL);
     
+    /* cache also categories (only for PostGIS Topology) */
+    if (pg_info->toposchema_name) {
+        if (!PQgetisnull(pg_info->res, pg_info->next_line, 3))
+            pg_info->cache.lines_cats[pg_info->cache.lines_next] =
+                atoi(PQgetvalue(pg_info->res, pg_info->next_line, 3)); 
+        else
+            pg_info->cache.lines_cats[pg_info->cache.lines_next] = -1; /* no cat */
+    }
+
     /* set feature id */
     if (fid < 0) {
         pg_info->cache.fid =
-            atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1));
+            atoi(PQgetvalue(pg_info->res, pg_info->next_line, 1)); 
         pg_info->next_line++;
     }
     else {
@@ -1154,26 +1181,31 @@
         /* TODO: optimize SQL statement (for points/centroids) */
         sprintf(stmt,
                 "DECLARE %s CURSOR FOR "
-                "SELECT geom,fid,type FROM ("
-                "SELECT node_id AS fid,geom, %d AS type FROM \"%s\".node WHERE "
-                "containing_face IS NULL AND 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 "
-                "node_id AS fid,geom, %d AS type FROM \"%s\".node WHERE "
-                "containing_face IS NOT NULL AND 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 edge_id AS fid, geom, %d AS type FROM \"%s\".edge WHERE "
-                "left_face = 0 AND right_face = 0 UNION ALL SELECT edge_id AS fid, geom, %d AS type FROM "
-                "\"%s\".edge WHERE left_face != 0 OR right_face != 0 ) AS foo ORDER BY type,fid",
-                pg_info->cursor_name, GV_POINT,
-                pg_info->toposchema_name, pg_info->toposchema_name, pg_info->toposchema_name,
-                GV_CENTROID, pg_info->toposchema_name, pg_info->toposchema_name, pg_info->toposchema_name,
-                GV_LINE, pg_info->toposchema_name, GV_BOUNDARY, pg_info->toposchema_name);
+                "SELECT geom,id,type,fid FROM ("
+                "SELECT tt.node_id AS id,tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".node AS tt "
+                "LEFT JOIN \"%s\" AS ft ON (%s).type = 1 AND (%s).id = node_id "
+                "WHERE containing_face IS NULL AND 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 tt.node_id AS id,tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".node AS tt "
+                "LEFT JOIN \"%s\" AS ft ON (%s).type = 3 AND (%s).id = containing_face "
+                "WHERE containing_face IS NOT NULL AND 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 tt.edge_id AS id, tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".edge AS tt "
+                "LEFT JOIN \"%s\" AS ft ON (%s).type = 2 AND (%s).id = edge_id "
+                "WHERE left_face = 0 AND right_face = 0 UNION ALL "
+                "SELECT tt.edge_id AS id, tt.geom, %d AS type, ft.fid AS fid FROM \"%s\".edge AS tt "
+                "LEFT JOIN \"%s\" AS ft ON (%s).type = 2 AND (%s).id = edge_id "
+                "WHERE left_face != 0 OR right_face != 0 ) AS foo ORDER BY type,id",
+                pg_info->cursor_name, 
+                GV_POINT, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column,
+                pg_info->toposchema_name, pg_info->toposchema_name,
+                GV_CENTROID, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column,
+                pg_info->toposchema_name, pg_info->toposchema_name,
+                GV_LINE, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column,
+                GV_BOUNDARY, pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column, pg_info->topogeom_column);
     }
-    
     if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
         Vect__execute_pg(pg_info->conn, "ROLLBACK");
         return -1;
@@ -1333,13 +1365,19 @@
         
         if (type & GV_POINTS) {
             sprintf(stmt,
-                    "SELECT geom,containing_face FROM \"%s\".node WHERE node_id = %d",
-                    pg_info->toposchema_name, fid);
+                    "SELECT tt.geom,tt.containing_face,ft.fid FROM \"%s\".node AS tt "
+                    "LEFT JOIN \"%s\" AS ft ON (%s).type = 1 and (%s).id = edge_id "
+                    "WHERE node_id = %d",
+                    pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column,
+                    pg_info->topogeom_column, fid);
         }
         else {
             sprintf(stmt,
-                    "SELECT geom,left_face,right_face FROM \"%s\".edge WHERE edge_id = %d",
-                    pg_info->toposchema_name, fid);
+                    "SELECT tt.geom,tt.left_face,tt.right_face,ft.fid FROM \"%s\".edge AS tt "
+                    "LEFT JOIN \"%s\" AS ft ON (%s).type = 2 and (%s).id = edge_id "
+                    "WHERE edge_id = %d",
+                    pg_info->toposchema_name, pg_info->table_name, pg_info->topogeom_column,
+                    pg_info->topogeom_column, fid);
         }
     }
     G_debug(3, "SQL: %s", stmt);
@@ -1440,16 +1478,20 @@
                                                   sizeof(struct line_pnts *));
     cache->lines_types = (int *)G_realloc(cache->lines_types,
                                           cache->lines_alloc * sizeof(int));
+    cache->lines_cats = (int *)G_realloc(cache->lines_cats,
+                                         cache->lines_alloc * sizeof(int));
 
     if (cache->lines_alloc > 1) {
         for (i = cache->lines_alloc - num; i < cache->lines_alloc; i++) {
             cache->lines[i] = Vect_new_line_struct();
             cache->lines_types[i] = -1;
+            cache->lines_cats[i] = -1;
         }
     }
     else {
         cache->lines[0] = Vect_new_line_struct();
         cache->lines_types[0] = -1;
+        cache->lines_cats[0] = -1;
     }
 }
 



More information about the grass-commit mailing list