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

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Apr 3 02:40:20 PDT 2013


Author: martinl
Date: 2013-04-03 02:40:20 -0700 (Wed, 03 Apr 2013)
New Revision: 55602

Modified:
   grass/trunk/lib/vector/Vlib/copy.c
   grass/trunk/lib/vector/Vlib/local_proto.h
   grass/trunk/lib/vector/Vlib/pg_local_proto.h
   grass/trunk/lib/vector/Vlib/write_ogr.c
   grass/trunk/lib/vector/Vlib/write_pg.c
   grass/trunk/lib/vector/Vlib/write_sfa.c
Log:
vlib: implement V2__write_area_ogr() + V2__write_area_sfa()
      update V2__write_area_pg()
      fix off_t formatting issues


Modified: grass/trunk/lib/vector/Vlib/copy.c
===================================================================
--- grass/trunk/lib/vector/Vlib/copy.c	2013-04-03 08:14:23 UTC (rev 55601)
+++ grass/trunk/lib/vector/Vlib/copy.c	2013-04-03 09:40:20 UTC (rev 55602)
@@ -18,6 +18,8 @@
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+#include "local_proto.h"
+
 /*!
   \brief Copy topological elements
 
@@ -60,8 +62,6 @@
 
    Note: Try to copy on level 2 otherwise level 1 is used.
    
-   \todo Implement V2__write_area_ogr()
-   
    \param In input vector map
    \param field layer number (-1 for all layers)
    \param[out] Out output vector map
@@ -317,6 +317,9 @@
             G_warning(_("Writing node %d failed"), node);
             return 1;
         }
+#else
+        G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+        return 1;
 #endif
     }
 
@@ -376,19 +379,20 @@
 */
 int copy_areas(const struct Map_info *In, int field, struct Map_info *Out)
 {
-    int i, area, nareas, cat, isle, nisles, nisles_alloc;
+    int i, area, nareas, cat, isle, nisles, nparts_alloc;
     int ogr;
-    struct line_pnts *Points, **IPoints;
+    struct line_pnts **Points;
     struct line_cats *Cats;
     
     ogr = Vect_maptype(Out) == (GV_FORMAT_OGR || GV_FORMAT_OGR_DIRECT);
     
-    IPoints = NULL;
-    nisles_alloc = 0;
-    Points  = Vect_new_line_struct();
-    Cats    = Vect_new_cats_struct();
+    /* allocate points & cats */
+    Points    = (struct line_pnts **) G_malloc(sizeof(struct line_pnts *));
+    Points[0] = Vect_new_line_struct();
+    nparts_alloc = 1;
+    Cats      = Vect_new_cats_struct();
 
-    /* copy areas/polygons */
+    /* copy areas */
     nareas = Vect_get_num_areas(In);
     G_message(_("Exporting areas..."));
     for (area = 1; area <= nareas; area++) {
@@ -406,49 +410,40 @@
             continue;
         }
         
-        /* get outer ring (area) geometry */
-        Vect_get_area_points(In, area, Points);
+        /* get outer ring (area) */
+        Vect_get_area_points(In, area, Points[0]);
 
+        /* get category */
         Vect_reset_cats(Cats);
         Vect_cat_set(Cats, field, cat);
         
-        /* get inner rings (isles) geometry */
+        /* get inner rings (isles) */
         nisles = Vect_get_area_num_isles(In, area);
-        if (nisles > nisles_alloc) {
+        if (nisles + 1 > nparts_alloc) {
             /* reallocate space for isles */
-            IPoints = (struct line_pnts **) G_realloc(IPoints,
-                                                      nisles *
-                                                      sizeof(struct line_pnts *));
-            for (i = nisles_alloc; i < nisles; i++)
-                IPoints[i] = Vect_new_line_struct();
-            nisles_alloc = nisles;
+            Points = (struct line_pnts **) G_realloc(Points,
+                                                     (nisles + 1) *
+                                                     sizeof(struct line_pnts *));
+            for (i = nparts_alloc; i < nisles + 1; i++)
+                Points[i] = Vect_new_line_struct();
+            nparts_alloc = nisles + 1;
         }
         G_debug(3, "\tcat=%d, nisles=%d", cat, nisles);
         for (i = 0; i < nisles; i++) {
             isle = Vect_get_area_isle(In, area, i);
-            Vect_get_isle_points(In, isle, IPoints[i]);
+            Vect_get_isle_points(In, isle, Points[i + 1]);
         }
         
-        if (ogr)
-            Vect_write_line(Out, GV_BOUNDARY, Points, Cats);
-        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
+        if (0 > V2__write_area_sfa(Out, (const struct line_pnts **) Points,
+                                   nisles + 1, Cats)) {
+            G_warning(_("Writing area %d failed"), area);
+            return -1;
         }
     }
     
     /* free allocated space for isles */
-    for (i = 0; i < nisles_alloc; i++)
-        Vect_destroy_line_struct(IPoints[i]);
-
-    Vect_destroy_line_struct(Points);
+    for (i = 0; i < nparts_alloc; i++)
+        Vect_destroy_line_struct(Points[i]);
     Vect_destroy_cats_struct(Cats);
 
     return 0;

Modified: grass/trunk/lib/vector/Vlib/local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/local_proto.h	2013-04-03 08:14:23 UTC (rev 55601)
+++ grass/trunk/lib/vector/Vlib/local_proto.h	2013-04-03 09:40:20 UTC (rev 55602)
@@ -22,4 +22,14 @@
 int V2__delete_line_from_topo_nat(struct Map_info *, int, int,
                                   const struct line_pnts *, const struct line_cats *);
 
+/* write_sfa.c */
+off_t V2__write_area_sfa(struct Map_info *, const struct line_pnts **, int,
+                         const struct line_cats *);
+
+/* write_ogr.c */
+#ifdef HAVE_OGR
+off_t V2__write_area_ogr(struct Map_info *, const struct line_pnts **, int,
+                         const struct line_cats *);
+#endif /* HAVE_OGR */
+
 #endif /* PG_LOCAL_PROTO_H__ */

Modified: grass/trunk/lib/vector/Vlib/pg_local_proto.h
===================================================================
--- grass/trunk/lib/vector/Vlib/pg_local_proto.h	2013-04-03 08:14:23 UTC (rev 55601)
+++ grass/trunk/lib/vector/Vlib/pg_local_proto.h	2013-04-03 09:40:20 UTC (rev 55602)
@@ -63,9 +63,8 @@
 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);
+off_t V2__write_area_pg(struct Map_info *, const struct line_pnts **, int,
+                        const struct line_cats *);
 
 int Vect__insert_face_pg(struct Map_info *, int);
 

Modified: grass/trunk/lib/vector/Vlib/write_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_ogr.c	2013-04-03 08:14:23 UTC (rev 55601)
+++ grass/trunk/lib/vector/Vlib/write_ogr.c	2013-04-03 09:40:20 UTC (rev 55602)
@@ -9,7 +9,7 @@
 
    \todo How to deal with OGRNullFID
    
-   (C) 2009-2011, 2012 by Martin Landa, and the GRASS Development Team
+   (C) 2009-2013 by Martin Landa, and 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.
@@ -24,9 +24,11 @@
 #ifdef HAVE_OGR
 #include <ogr_api.h>
 
-static int sqltype_to_ogrtype(int);
+static off_t write_feature(struct Map_info *, int, const struct line_pnts **, int,
+                           const struct line_cats *);
 static int write_attributes(dbDriver *, int, const struct field_info *,
 			    OGRLayerH, OGRFeatureH);
+static int sqltype_to_ogrtype(int);
 #endif
 
 /*!
@@ -58,9 +60,130 @@
 			const struct line_cats *cats)
 {
 #ifdef HAVE_OGR
+    return write_feature(Map, type, &points, 1, cats);
+#else
+    G_fatal_error(_("GRASS is not compiled with OGR support"));
+    return -1;
+#endif
+}
+
+/*!
+  \brief Rewrites feature at the given offset on level 1 (OGR interface)
+  
+  This function simply calls V1_delete_line_ogr() and V1_write_line_ogr().
+  
+  \param Map pointer to Map_info structure
+  \param offset feature offset
+  \param type feature type (see V1_write_line_ogr() for supported types)
+  \param points pointer to line_pnts structure (feature geometry)
+  \param cats pointer to line_cats structure (feature categories)
+  
+  \return feature offset (rewriten feature)
+  \return -1 on error
+*/
+off_t V1_rewrite_line_ogr(struct Map_info *Map,
+			  int line, int type, off_t offset,
+			  const struct line_pnts *points, const struct line_cats *cats)
+{
+    G_debug(3, "V1_rewrite_line_ogr(): line=%d type=%d offset=%"PRI_OFF_T,
+	    line, type, offset);
+#ifdef HAVE_OGR
+    if (type != V1_read_line_ogr(Map, NULL, NULL, offset)) {
+	G_warning(_("Unable to rewrite feature (incompatible feature types)"));
+	return -1;
+    }
+
+    /* delete old */
+    V1_delete_line_ogr(Map, offset);
+
+    return V1_write_line_ogr(Map, type, points, cats);
+#else
+    G_fatal_error(_("GRASS is not compiled with OGR support"));
+    return -1;
+#endif
+}
+
+/*!
+  \brief Deletes feature at the given offset on level 1 (OGR interface)
+  
+  \param Map pointer Map_info structure
+  \param offset offset of feature to be deleted
+  
+  \return  0 on success
+  \return -1 on error
+*/
+int V1_delete_line_ogr(struct Map_info *Map, off_t offset)
+{
+#ifdef HAVE_OGR
+    struct Format_info_ogr *ogr_info;
+    
+    G_debug(3, "V1_delete_line_ogr(), offset = %lu", (unsigned long) offset);
+
+    ogr_info = &(Map->fInfo.ogr);
+    
+    if (!ogr_info->layer) {
+	G_warning(_("OGR layer not defined"));
+	return -1;
+    }
+    
+    if (offset >= ogr_info->offset.array_num) {
+	G_warning(_("Invalid offset (%d)"), offset);
+	return -1;
+    }
+    
+    if (OGR_L_DeleteFeature(ogr_info->layer,
+			    ogr_info->offset.array[offset]) != OGRERR_NONE)
+	G_warning(_("Unable to delete feature"));
+	return -1;
+    
+    return 0;
+#else
+    G_fatal_error(_("GRASS is not compiled with OGR support"));
+    return -1;
+#endif
+}
+
+#ifdef HAVE_OGR
+/*!
+   \brief Writes area on topological level (OGR Simple Features
+   interface, internal use only)
+
+   \param Map pointer to Map_info structure
+   \param points feature geometry (exterior + interior rings)
+   \param nparts number of parts including exterior ring
+   \param cats feature categories
+   
+   \return feature offset
+   \return -1 on error
+*/
+off_t V2__write_area_ogr(struct Map_info *Map,
+                         const struct line_pnts **points, int nparts,
+                         const struct line_cats *cats)
+{
+    return write_feature(Map, GV_BOUNDARY, points, nparts, cats);
+}
+
+/*!
+  \brief Write OGR feature
+
+   \param Map pointer to Map_info structure
+   \param type feature type (GV_POINT, GV_LINE, ...)
+   \param bpoints feature geometry
+   \param cats feature categories
+   \param ipoints isle geometry for polygons on NULL
+   \param nisles number of isles
+   
+   \return feature offset into file
+   \return -1 on error
+*/
+off_t write_feature(struct Map_info *Map, int type,
+                    const struct line_pnts **p_points, int nparts,
+                    const struct line_cats *cats)
+{
     int i, cat, ret;
 
     struct field_info *Fi;
+    const struct line_pnts *points;
     struct Format_info_ogr *ogr_info;
     struct Format_info_offset *offset_info;
     
@@ -74,6 +197,11 @@
     ogr_info = &(Map->fInfo.ogr);
     offset_info = &(ogr_info->offset);
     
+    if (nparts < 1)
+        return -1;
+    
+    points = p_points[0]; /* feature geometry */
+    
     if (!ogr_info->layer) {
 	/* create OGR layer if doesn't exist */
 	if (V2_open_new_ogr(Map, type) < 0)
@@ -137,43 +265,48 @@
     G_debug(3, "V1_write_line_ogr(): type = %d", type);
 
     if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
-	/* create exterior ring */
-	OGRGeometryH Ogr_ring;
-	int npoints;
+	int iring, npoints;
 	
-	npoints = points->n_points - 1;
-	Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
-	if (points->x[0] != points->x[npoints] ||
-	    points->y[0] != points->y[npoints] ||
-	    points->z[0] != points->z[npoints]) {
-	    G_warning(_("Boundary is not closed. Skipping."));
-	    return -1;
-	}
+        /* add rings (first is exterior ring) */
+        for (iring = 0; iring < nparts; iring++) {
+            OGRGeometryH Ogr_ring;
+            
+            points = p_points[iring];
+            npoints = points->n_points - 1;
+            Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
+            if (points->x[0] != points->x[npoints] ||
+                points->y[0] != points->y[npoints] ||
+                points->z[0] != points->z[npoints]) {
+                G_warning(_("Boundary is not closed. Feature skipped."));
+                return -1;
+            }
 	
-	/* add points */
-	for (i = 0; i < points->n_points; i++) {
-	    OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
-			   points->z[i]);
-	}
-	OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
+            /* add points */
+            for (i = 0; i < npoints; i++) {
+                OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
+                               points->z[i]);
+            }
+            G_debug(4, "   ring(%d): n_points = %d", iring, npoints);
+            OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
+        }
     }
     else {
 	for (i = 0; i < points->n_points; i++) {
 	    OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i],
 			   points->z[i]);
 	}
+        G_debug(4, "   n_points = %d", points->n_points);
     }
     
-    G_debug(4, "   n_points = %d", points->n_points);
-
     /* create feature & set geometry */
     Ogr_feature = OGR_F_Create(Ogr_featuredefn);
     OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
 
     /* write attributes */
     if (cat > -1 && ogr_info->dbdriver) {
-	write_attributes(ogr_info->dbdriver,
-			 cat, Fi, ogr_info->layer, Ogr_feature);
+	if (0 > write_attributes(ogr_info->dbdriver,
+                                 cat, Fi, ogr_info->layer, Ogr_feature))
+            G_warning(_("Unable to writes feature attributes"));
 	G_free(Fi);
     }
     /* write feature into layer */
@@ -202,93 +335,24 @@
     if (ret != OGRERR_NONE)
 	return -1;
     
-    G_debug(3, "V1_write_line_ogr(): -> offset = %lu offset_num = %d cat = %d",
+    G_debug(3, "write_feature(): -> offset = %lu offset_num = %d cat = %d",
 	    (unsigned long) offset, offset_info->array_num, cat);
 
     return offset;
-#else
-    G_fatal_error(_("GRASS is not compiled with OGR support"));
-    return -1;
-#endif
 }
 
 /*!
-  \brief Rewrites feature at the given offset on level 1 (OGR interface)
-  
-  This function simply calls V1_delete_line_ogr() and V1_write_line_ogr().
-  
-  \param Map pointer to Map_info structure
-  \param offset feature offset
-  \param type feature type (see V1_write_line_ogr() for supported types)
-  \param points pointer to line_pnts structure (feature geometry)
-  \param cats pointer to line_cats structure (feature categories)
-  
-  \return feature offset (rewriten feature)
-  \return -1 on error
-*/
-off_t V1_rewrite_line_ogr(struct Map_info *Map,
-			  int line, int type, off_t offset,
-			  const struct line_pnts *points, const struct line_cats *cats)
-{
-    G_debug(3, "V1_rewrite_line_ogr(): line=%d type=%d offset=%lu",
-	    line, type, offset);
-#ifdef HAVE_OGR
-    if (type != V1_read_line_ogr(Map, NULL, NULL, offset)) {
-	G_warning(_("Unable to rewrite feature (incompatible feature types)"));
-	return -1;
-    }
+  \brief Writes attributes
 
-    /* delete old */
-    V1_delete_line_ogr(Map, offset);
+  \param driver pointer to dbDriver
+  \param Fi pointer to field_info struct
+  \param[in,out] Ogr_layer OGR layer
+  \param[in,out] Ogr_feature OGR feature to modify
 
-    return V1_write_line_ogr(Map, type, points, cats);
-#else
-    G_fatal_error(_("GRASS is not compiled with OGR support"));
-    return -1;
-#endif
-}
-
-/*!
-  \brief Deletes feature at the given offset on level 1 (OGR interface)
-  
-  \param Map pointer Map_info structure
-  \param offset offset of feature to be deleted
-  
-  \return  0 on success
+  \return 1 on success
+  \return 0 no attributes
   \return -1 on error
 */
-int V1_delete_line_ogr(struct Map_info *Map, off_t offset)
-{
-#ifdef HAVE_OGR
-    struct Format_info_ogr *ogr_info;
-    
-    G_debug(3, "V1_delete_line_ogr(), offset = %lu", (unsigned long) offset);
-
-    ogr_info = &(Map->fInfo.ogr);
-    
-    if (!ogr_info->layer) {
-	G_warning(_("OGR layer not defined"));
-	return -1;
-    }
-    
-    if (offset >= ogr_info->offset.array_num) {
-	G_warning(_("Invalid offset (%d)"), offset);
-	return -1;
-    }
-    
-    if (OGR_L_DeleteFeature(ogr_info->layer,
-			    ogr_info->offset.array[offset]) != OGRERR_NONE)
-	G_warning(_("Unable to delete feature"));
-	return -1;
-    
-    return 0;
-#else
-    G_fatal_error(_("GRASS is not compiled with OGR support"));
-    return -1;
-#endif
-}
-
-#ifdef HAVE_OGR
 int write_attributes(dbDriver *driver, int cat, const struct field_info *Fi,
 		     OGRLayerH Ogr_layer, OGRFeatureH Ogr_feature)
 {
@@ -321,13 +385,15 @@
 
     /* select data */
     if (db_open_select_cursor(driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
-	G_fatal_error(_("Unable to select attributes for category %d"),
-		      cat);
+        G_warning(_("Unable to select attributes for category %d"),
+                  cat);
+        return -1;
     }
     
     if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
-	G_fatal_error(_("Unable to fetch data from table <%s>"),
-		      Fi->table);
+	G_warning(_("Unable to fetch data from table <%s>"),
+                  Fi->table);
+        return -1;
     }
     
     if (!more) {

Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c	2013-04-03 08:14:23 UTC (rev 55601)
+++ grass/trunk/lib/vector/Vlib/write_pg.c	2013-04-03 09:40:20 UTC (rev 55602)
@@ -168,7 +168,7 @@
                          const struct line_pnts * points,
                          const struct line_cats * cats)
 {
-    G_debug(3, "V1_rewrite_line_pg(): line=%d type=%d offset=%lu",
+    G_debug(3, "V1_rewrite_line_pg(): line=%d type=%d offset=%"PRI_OFF_T,
             line, type, offset);
 #ifdef HAVE_POSTGRES
     if (type != V1_read_line_pg(Map, NULL, NULL, offset)) {
@@ -206,7 +206,7 @@
 off_t V2_rewrite_line_pg(struct Map_info *Map, int line, int type, off_t old_offset,
 			  const struct line_pnts *points, const struct line_cats *cats)
 {
-    G_debug(3, "V2_rewrite_line_pg(): line=%d type=%d offset=%lu",
+    G_debug(3, "V2_rewrite_line_pg(): line=%d type=%d offset=%"PRI_OFF_T,
             line, type, old_offset);
 #ifdef HAVE_POSTGRES
     const char *schema_name, *table_name, *keycolumn;
@@ -378,8 +378,8 @@
             /* first remove references to this edge */
             /* (1) left next edge */
             sprintf(stmt, "UPDATE \"%s\".\"%s\" SET abs_next_left_edge = edge_id, "
-                    "next_left_edge = -edge_id WHERE abs_next_left_edge = %ld",
-                    pg_info->toposchema_name, table_name, Line->offset);
+                    "next_left_edge = -edge_id WHERE abs_next_left_edge = %d",
+                    pg_info->toposchema_name, table_name, (int)Line->offset);
             if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
                 Vect__execute_pg(pg_info->conn, "ROLLBACK");
                 return -1;
@@ -387,8 +387,8 @@
 
             /* (2) right next edge */
             sprintf(stmt, "UPDATE \"%s\".\"%s\" SET abs_next_right_edge = edge_id, "
-                    "next_right_edge = edge_id WHERE abs_next_right_edge = %ld",
-                    pg_info->toposchema_name, table_name, Line->offset);
+                    "next_right_edge = edge_id WHERE abs_next_right_edge = %d",
+                    pg_info->toposchema_name, table_name, (int)Line->offset);
             if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
                 Vect__execute_pg(pg_info->conn, "ROLLBACK");
                 return -1;
@@ -405,8 +405,8 @@
             return -1;
 
         /* delete record from topology table */
-        sprintf(stmt, "DELETE FROM \"%s\".\"%s\" WHERE %s_id = %ld",
-                pg_info->toposchema_name, table_name, keycolumn, Line->offset);
+        sprintf(stmt, "DELETE FROM \"%s\".\"%s\" WHERE %s_id = %d",
+                pg_info->toposchema_name, table_name, keycolumn, (int)Line->offset);
         if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
             G_warning(_("Unable to delete feature (%s) %d"), keycolumn,
                       line);
@@ -450,6 +450,7 @@
 #endif
 }
 
+#ifdef HAVE_POSTGRES
 /*!
    \brief Writes node on topological level (PostGIS Topology interface, internal use only)
 
@@ -461,7 +462,6 @@
 */
 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);
@@ -470,63 +470,38 @@
         return -1; /* PostGIS Topology required */
     
     return write_line_tp(Map, GV_POINT, TRUE, points, NULL);
-#else
-    G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
-    return -1;
-#endif
 }
 
 /*!
-   \brief Writes area on topological level (PostGIS Simple Features interface, internal use only)
+   \brief Writes area on topological level (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)
-   \param ipoints pointer to line_pnts structure (isles geometry) 
-   \param nisles number of isles
+   \param points feature geometry (exterior + interior rings)
+   \param nparts number of parts including exterior ring
+   \param cats feature categories
    
-   \return feature offset into file
+   \return feature offset
    \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)
+                        const struct line_pnts **points, int nparts,
+                        const struct line_cats *cats)
 {
-#ifdef HAVE_POSTGRES
-    int i;
-    off_t ret;
-    const struct line_pnts **points;
-
-    if (nisles > 0) {
-        points = (const struct line_pnts **) G_calloc(nisles + 1, sizeof(struct line_pnts *));
-        points[0] = bpoints;
-        for (i = 0; i < nisles; i++)
-            points[i + 1] = ipoints[i];
-    }
-    else {
-        points = &bpoints;
-    }
-    
-    ret = write_line_sf(Map, GV_BOUNDARY, points, nisles + 1, cats);
-
-    if (nisles > 0)
-        G_free(points);
-
-    return ret;
-#else
-    G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
-    return -1;
-#endif
+    return write_line_sf(Map, GV_BOUNDARY, points, nparts, cats);
 }
 
-#ifdef HAVE_POSTGRES
 /*!
   \brief Write vector features as PostGIS simple feature element
   
-  \return 0 on success
-  \return -1 on error
+   \param Map pointer to Map_info structure
+   \param type feature type (GV_POINT, GV_LINE, ...)
+   \param points feature geometry (exterior + interior rings for polygonsx)
+   \param nparts number of parts
+   \param cats feature categories
+
+   \return feature offset
+   \return -1 on error
 */
 off_t write_line_sf(struct Map_info *Map, int type,
                     const struct line_pnts **points, int nparts,
@@ -544,6 +519,9 @@
     pg_info = &(Map->fInfo.pg);
     offset_info = &(pg_info->offset);
 
+    if (nparts < 1)
+        return -1;
+    
     /* check required PG settings */
     if (!pg_info->conn) {
         G_warning(_("No connection defined"));
@@ -1472,8 +1450,8 @@
         nle = -Line->offset;
         nre = Line->offset;
         
-        G_debug(3, "new edge: id=%lu next_left_edge=%d next_right_edge=%d",
-                Line->offset, nle, nre);
+        G_debug(3, "new edge: id=%d next_left_edge=%d next_right_edge=%d",
+                (int)Line->offset, nle, nre);
         
         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, "
@@ -1579,15 +1557,15 @@
     
     if (next_line < 0) {
         sprintf(stmt, "UPDATE \"%s\".edge_data SET next_left_edge = %d, "
-                "abs_next_left_edge = %d WHERE edge_id = %lu AND abs_next_left_edge = %lu",
-                pg_info->toposchema_name, edge, abs(edge), Line_next->offset,  Line_next->offset);
-        G_debug(3, "update edge=%lu next_left_edge=%d (?)", Line_next->offset, edge);
+                "abs_next_left_edge = %d WHERE edge_id = %d AND abs_next_left_edge = %d",
+                pg_info->toposchema_name, edge, abs(edge), (int)Line_next->offset, (int)Line_next->offset);
+        G_debug(3, "update edge=%d next_left_edge=%d (?)", (int)Line_next->offset, edge);
     }
     else {
         sprintf(stmt, "UPDATE \"%s\".edge_data SET next_right_edge = %d, "
-                "abs_next_right_edge = %d WHERE edge_id = %lu AND abs_next_right_edge = %lu",
-                pg_info->toposchema_name, edge, abs(edge), Line_next->offset, Line_next->offset);
-        G_debug(3, "update edge=%lu next_right_edge=%d (?)", Line_next->offset, edge);
+                "abs_next_right_edge = %d WHERE edge_id = %d AND abs_next_right_edge = %d",
+                pg_info->toposchema_name, edge, abs(edge), (int)Line_next->offset, (int)Line_next->offset);
+        G_debug(3, "update edge=%d next_right_edge=%d (?)", (int)Line_next->offset, edge);
     }
     
     if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
@@ -1606,15 +1584,15 @@
         
         if (next_line < 0) {
             sprintf(stmt, "UPDATE \"%s\".edge_data SET next_left_edge = %d, "
-                    "abs_next_left_edge = %d WHERE edge_id = %lu",
-                    pg_info->toposchema_name, edge, abs(edge), Line_next->offset);
-            G_debug(3, "update edge=%lu next_left_edge=%d", Line_next->offset, edge);
+                    "abs_next_left_edge = %d WHERE edge_id = %d",
+                    pg_info->toposchema_name, edge, abs(edge), (int)Line_next->offset);
+            G_debug(3, "update edge=%d next_left_edge=%d", (int)Line_next->offset, edge);
         }
         else {
             sprintf(stmt, "UPDATE \"%s\".edge_data SET next_right_edge = %d, "
-                    "abs_next_right_edge = %d WHERE edge_id = %lu",
-                    pg_info->toposchema_name, edge, abs(edge), Line_next->offset);
-            G_debug(3, "update edge=%lu next_right_edge=%d", Line_next->offset, edge);
+                    "abs_next_right_edge = %d WHERE edge_id = %d",
+                    pg_info->toposchema_name, edge, abs(edge), (int)Line_next->offset);
+            G_debug(3, "update edge=%d next_right_edge=%d", (int)Line_next->offset, edge);
         }
      
         if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
@@ -1807,25 +1785,25 @@
         sprintf(stmt, "UPDATE \"%s\".edge_data SET "
                 "next_left_edge = %d, abs_next_left_edge = %d, "
                 "next_right_edge = %d, abs_next_right_edge = %d "
-                "WHERE edge_id = %lu", pg_info->toposchema_name,
-                nle, abs(nle), nre, abs(nre), Line->offset);
+                "WHERE edge_id = %d", pg_info->toposchema_name,
+                nle, abs(nle), nre, abs(nre), (int)Line->offset);
     }
     else if (nle != 0) {
         /* update next left edge only */
         sprintf(stmt, "UPDATE \"%s\".edge_data SET "
                 "next_left_edge = %d, abs_next_left_edge = %d "
-                "WHERE edge_id = %lu", pg_info->toposchema_name,
-                nle, abs(nle), Line->offset);
+                "WHERE edge_id = %d", pg_info->toposchema_name,
+                nle, abs(nle), (int)Line->offset);
     }
     else {
         /* update next right edge only */
         sprintf(stmt, "UPDATE \"%s\".edge_data SET "
                 "next_right_edge = %d, abs_next_right_edge = %d "
-                "WHERE edge_id = %lu", pg_info->toposchema_name,
-                nre, abs(nre), Line->offset);
+                "WHERE edge_id = %d", pg_info->toposchema_name,
+                nre, abs(nre), (int)Line->offset);
     }
-    G_debug(3, "update edge=%lu next_left_edge=%d next_right_edge=%d",
-            Line->offset, nle, nre);
+    G_debug(3, "update edge=%d next_left_edge=%d next_right_edge=%d",
+            (int)Line->offset, nle, nre);
     
     if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
         /* rollback transaction */
@@ -1898,10 +1876,10 @@
             
             sprintf(stmt, "UPDATE \"%s\".edge_data SET "
                     "left_face = %d, right_face = %d "
-                    "WHERE edge_id = %lu", pg_info->toposchema_name,
+                    "WHERE edge_id = %d", pg_info->toposchema_name,
                     topo_i->left > 0 ? topo_i->left : 0,
                     topo_i->right > 0 ? topo_i->right : 0,
-                    Line_i->offset);
+                    (int) Line_i->offset);
             G_debug(2, "SQL: %s", stmt);
             
             if(Vect__execute_pg(pg_info->conn, stmt) == -1) {
@@ -1914,8 +1892,8 @@
         if (Area->centroid > 0) {
             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[s], Line_i->offset);
+                    "WHERE node_id = %d", pg_info->toposchema_name,
+                    face[s], (int)Line_i->offset);
             G_debug(2, "SQL: %s", stmt);
             
             if(Vect__execute_pg(pg_info->conn, stmt) == -1) {

Modified: grass/trunk/lib/vector/Vlib/write_sfa.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_sfa.c	2013-04-03 08:14:23 UTC (rev 55601)
+++ grass/trunk/lib/vector/Vlib/write_sfa.c	2013-04-03 09:40:20 UTC (rev 55602)
@@ -24,9 +24,15 @@
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+#include "local_proto.h"
+
+#ifdef HAVE_POSTGRES
+#include "pg_local_proto.h"
+#endif
+
 #if defined HAVE_OGR || defined HAVE_POSTGRES
-void V2__add_line_to_topo_sfa(struct Map_info *, int, const struct line_pnts *,
-			      const struct line_cats *);
+static void V2__add_line_to_topo_sfa(struct Map_info *, int, const struct line_pnts *,
+                                     const struct line_cats *);
 #endif
 
 /*!
@@ -142,7 +148,7 @@
 off_t V2_rewrite_line_sfa(struct Map_info *Map, int line, int type, off_t offset,
 			  const struct line_pnts *points, const struct line_cats *cats)
 {
-    G_debug(3, "V2_rewrite_line_sfa(): line=%d type=%d offset=%lu",
+    G_debug(3, "V2_rewrite_line_sfa(): line=%d type=%d offset=%"PRI_OFF_T,
 	    line, type, offset);
 
     if (line < 1 || line > Map->plus.n_lines) {
@@ -262,6 +268,44 @@
 #endif
 }
 
+/*!
+   \brief Writes area on topological level (Simple Features interface,
+   internal use only)
+
+   \param Map pointer to Map_info structure
+   \param points feature geometry (exterior + interior rings)
+   \param nparts number of parts including exterior ring
+   \param cats feature categories
+   
+   \return feature offset
+   \return -1 on error
+*/
+off_t V2__write_area_sfa(struct Map_info *Map, 
+                         const struct line_pnts **points, int nparts,
+                         const struct line_cats *cats)
+{
+    if (Map->format == GV_FORMAT_OGR) {
+#ifdef HAVE_OGR
+        return V2__write_area_ogr(Map, points, nparts, cats);
+#else
+        G_fatal_error(_("GRASS is not compiled with OGR support"));
+        return -1;
+#endif
+    }
+    else if (Map->format == GV_FORMAT_POSTGIS) {
+#ifdef HAVE_POSTGRES
+        return V2__write_area_pg(Map, points, nparts, cats);
+#else
+        G_fatal_error(_("GRASS is not compiled with PostgreSQL support"));
+        return -1;
+#endif
+    }
+    else {
+        G_warning(_("Unsupported vector map format (%d)"), Map->format);
+    }
+    return -1;
+}
+
 #if defined HAVE_OGR || defined HAVE_POSTGRES
 /*!
   \brief Add feature to topo file (internal use only)



More information about the grass-commit mailing list