[GRASS-SVN] r54085 - grass/trunk/lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Nov 28 01:01:37 PST 2012


Author: martinl
Date: 2012-11-28 01:01:36 -0800 (Wed, 28 Nov 2012)
New Revision: 54085

Modified:
   grass/trunk/lib/vector/Vlib/build_nat.c
   grass/trunk/lib/vector/Vlib/local_proto.h
   grass/trunk/lib/vector/Vlib/write_nat.c
   grass/trunk/lib/vector/Vlib/write_pg.c
Log:
vlib/PostGIS Topo: implement deleting faces (work in progress)


Modified: grass/trunk/lib/vector/Vlib/build_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_nat.c	2012-11-28 08:28:26 UTC (rev 54084)
+++ grass/trunk/lib/vector/Vlib/build_nat.c	2012-11-28 09:01:36 UTC (rev 54085)
@@ -3,12 +3,10 @@
 
    \brief Vector library - Building topology for native format
 
-   (C) 2001-2009, 2011 by the GRASS Development Team
+   (C) 2001-2012 by the GRASS Development Team
 
-   This program is free software under the 
-   GNU General Public License (>=v2). 
-   Read the file COPYING that comes with GRASS
-   for details.
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
 
    \author Original author CERL, probably Dave Gerdes or Mike Higgins.
    \author Update to GRASS 5.7 Radim Blazek and David D. Gray.

Modified: grass/trunk/lib/vector/Vlib/local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/local_proto.h	2012-11-28 08:28:26 UTC (rev 54084)
+++ grass/trunk/lib/vector/Vlib/local_proto.h	2012-11-28 09:01:36 UTC (rev 54085)
@@ -4,6 +4,7 @@
 #include <grass/vector.h>
 
 void V2__add_line_to_topo_nat(struct Map_info *, int ,
-                              const struct line_pnts *, const struct line_cats *);
+                              const struct line_pnts *, const struct line_cats *,
+                              int (*external_routine) (const struct Map_info *, int));
 
 #endif /* PG_LOCAL_PROTO_H__ */

Modified: grass/trunk/lib/vector/Vlib/write_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_nat.c	2012-11-28 08:28:26 UTC (rev 54084)
+++ grass/trunk/lib/vector/Vlib/write_nat.c	2012-11-28 09:01:36 UTC (rev 54085)
@@ -5,7 +5,7 @@
 
    Higher level functions for reading/writing/manipulating vectors.
 
-   (C) 2001-2010, 2012 by the GRASS Development Team
+   (C) 2001-2012 by the GRASS Development Team
 
    This program is free software under the GNU General Public License
    (>=v2). Read the file COPYING that comes with GRASS for details.
@@ -136,7 +136,8 @@
     \param cats pointer to line_cats structure (feature's categories)
 */
 void V2__add_line_to_topo_nat(struct Map_info *Map, int line,
-                              const struct line_pnts *points, const struct line_cats *cats)
+                              const struct line_pnts *points, const struct line_cats *cats,
+                              int (*external_routine) (const struct Map_info *, int))
 {
     int first, s, n, i;
     int type, node, next_line, area, side, sel_area, new_area[2];
@@ -212,9 +213,13 @@
 			    V2__delete_area_cats_from_cidx_nat(Map, area);
 			}
 			dig_del_area(plus, area);
+                        if (external_routine) /* call external subroutine if defined */
+                            external_routine(Map, area);
 		    }
 		    else if (area < 0) {	/* is isle */
 			dig_del_isle(plus, -area);
+                        if (external_routine)  /* call external subroutine if defined */
+                            external_routine(Map, area);
 		    }
 		}
 	    }
@@ -374,7 +379,7 @@
 	    Vect_box_extend(&(plus->box), &box);
     }
 
-    V2__add_line_to_topo_nat(Map, line, points, cats);
+    V2__add_line_to_topo_nat(Map, line, points, cats, NULL);
 
     G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
 	    plus->uplist.n_upnodes);
@@ -496,7 +501,7 @@
 	    Vect_box_extend(&(plus->box), &box);
     }
 
-    V2__add_line_to_topo_nat(Map, line, points, cats);
+    V2__add_line_to_topo_nat(Map, line, points, cats, NULL);
 
     G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
 	    plus->uplist.n_upnodes);
@@ -966,8 +971,7 @@
 	Vect_box_extend(&(plus->box), &box);
     }
     
-    V2__add_line_to_topo_nat(Map,
-		     line, points, cats);
+    V2__add_line_to_topo_nat(Map, line, points, cats, NULL);
 
     G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
 	    plus->uplist.n_upnodes);

Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c	2012-11-28 08:28:26 UTC (rev 54084)
+++ grass/trunk/lib/vector/Vlib/write_pg.c	2012-11-28 09:01:36 UTC (rev 54085)
@@ -58,6 +58,7 @@
 static int insert_topo_element(struct Map_info *, int, int, const char *);
 static int update_next_edge(struct Map_info*, int, int);
 static int insert_face(struct Map_info *, int);
+static int delete_face(const struct Map_info *, int);
 static int update_topo_edge(struct Map_info *, int);
 static int update_topo_face(struct Map_info *, int);
 #endif
@@ -970,7 +971,8 @@
         
         /* update GRASS-like topo */
         if (line > 0) /* skip nodes */
-            V2__add_line_to_topo_nat(Map, line, points[0], NULL); /* TODO: cats */
+            V2__add_line_to_topo_nat(Map, line, points[0], NULL, /* TODO: cats */
+                                     delete_face);
         
         /* update PostGIS-line topo */
         if (type & GV_LINES)
@@ -1394,7 +1396,68 @@
     return area;
 }
 
+/*!
+  \brief Delete existing face
 
+  \todo Set foreign keys as DEFERRABLE INITIALLY DEFERRED and use SET
+  CONSTRAINTS ALL DEFERRED
+  
+  \param Map pointer to Map_info struct
+  \param area area id to delete
+
+  \return 0 on success
+  \return -1 on error
+*/
+int delete_face(const struct Map_info *Map, int area)
+{
+    char stmt[DB_SQL_MAX];
+
+    const struct Format_info_pg *pg_info;
+
+    pg_info = &(Map->fInfo.pg);
+    
+    /* update centroids first */
+    sprintf(stmt, "UPDATE \"%s\".node SET containing_face = 0 "
+            "WHERE containing_face = %d",
+            pg_info->toposchema_name, area);
+    G_debug(3, "SQL: %s", stmt);
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
+        return -1;
+    }
+
+    /* update also edges (left face) */
+    sprintf(stmt, "UPDATE \"%s\".edge_data SET left_face = 0 "
+            "WHERE left_face = %d",
+            pg_info->toposchema_name, area);
+    G_debug(3, "SQL: %s", stmt);
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
+        return -1;
+    }
+
+    /* update also edges (left face) */
+    sprintf(stmt, "UPDATE \"%s\".edge_data SET right_face = 0 "
+            "WHERE right_face = %d",
+            pg_info->toposchema_name, area);
+    G_debug(3, "SQL: %s", stmt);
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
+        return -1;
+    }
+
+    /* delete face */
+    sprintf(stmt, "DELETE FROM \"%s\".face WHERE face_id = %d",
+            pg_info->toposchema_name, area);
+    G_debug(3, "delete face id=%d", area);
+    if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
+        Vect__execute_pg(pg_info->conn, "ROLLBACK");
+        return -1;
+    }
+
+    return 0;
+}
+
 /*!
   \brief Update lines (next left and right edges)
   
@@ -1511,13 +1574,13 @@
 */  
 int update_topo_face(struct Map_info *Map, int line)
 {
-    int i, s, area, face;
+    int i, s, area, face[2];
     char stmt[DB_SQL_MAX];
     
     struct Format_info_pg *pg_info;
-    struct P_line *Line;
+    struct P_line *Line, *Line_i;
     struct P_area *Area;
-    struct P_topo_b *topo;
+    struct P_topo_b *topo, *topo_i;
     
     pg_info = &(Map->fInfo.pg);
     
@@ -1533,39 +1596,51 @@
     
     topo = (struct P_topo_b *)Line->topo;
     
+    /* for both side on the current boundary (line) */
+    /* create new faces */
     for (s = 0; s < 2; s++) { /* for each side */
         area = s == 0 ? topo->left : topo->right;
         if (area <= 0) /* no area - skip */
             continue;
+
+        face[s] = insert_face(Map, area);
+        if (face[s] < 1) {
+            G_warning(_("Unable to create new face"));
+            return -1;
+        }
+    }
+    
+    /* update edges forming faces */
+    for (s = 0; s < 2; s++) { /* for each side */
+        area = s == 0 ? topo->left : topo->right;
+        if (area <= 0) /* no area - skip */
+          continue;
+        
         Area = Map->plus.Area[area];
-        
-        face = insert_face(Map, area); /* TODO: update */
-        
-        for (i = 0; i < Area->n_lines; i++) { /* update all boundaries */
-            Line = Map->plus.Line[abs(Area->lines[i])];
-            topo = (struct P_topo_b *)Line->topo;
+        for (i = 0; i < Area->n_lines; i++) {
+            Line_i = Map->plus.Line[abs(Area->lines[i])];
+            topo_i = (struct P_topo_b *)Line_i->topo;
             
             sprintf(stmt, "UPDATE \"%s\".edge_data SET "
                     "left_face = %d, right_face = %d "
                     "WHERE edge_id = %lu", pg_info->toposchema_name,
-                    topo->left > 0 ? topo->left : 0,
-                    topo->right > 0 ? topo->right : 0,
-                    Line->offset);
+                    topo_i->left > 0 ? topo_i->left : 0,
+                    topo_i->right > 0 ? topo_i->right : 0,
+                    Line_i->offset);
             G_debug(2, "SQL: %s", stmt);
             
             if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
-                /* rollback transaction */
                 Vect__execute_pg(pg_info->conn, "ROLLBACK");
                 return -1;
             }
         }
         
-        /* update also centroids */
+        /* update also centroids (stored as nodes) */
         if (Area->centroid > 0) {
-            Line = Map->plus.Line[Area->centroid];
+            Line_i = Map->plus.Line[Area->centroid];
             sprintf(stmt, "UPDATE \"%s\".node SET containing_face = %d "
                     "WHERE node_id = %lu", pg_info->toposchema_name,
-                    face, Line->offset);
+                    face[s], Line_i->offset);
             G_debug(2, "SQL: %s", stmt);
             
             if(Vect__execute_pg(pg_info->conn, stmt) == -1) {



More information about the grass-commit mailing list