[GRASS-SVN] r52565 - in grass/trunk/vector: . v.out.postgis

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Aug 6 09:41:58 PDT 2012


Author: martinl
Date: 2012-08-06 09:41:58 -0700 (Mon, 06 Aug 2012)
New Revision: 52565

Added:
   grass/trunk/vector/v.out.postgis/
   grass/trunk/vector/v.out.postgis/Makefile
   grass/trunk/vector/v.out.postgis/export.c
   grass/trunk/vector/v.out.postgis/export_topo.c
   grass/trunk/vector/v.out.postgis/local_proto.h
   grass/trunk/vector/v.out.postgis/main.c
   grass/trunk/vector/v.out.postgis/options.c
   grass/trunk/vector/v.out.postgis/v.out.postgis.html
Log:
v.out.postgis: new module to export GRASS vector data into PostGIS
               initial support for PostGIS topology
               very initial prototype (work in progress), disabled by default



Property changes on: grass/trunk/vector/v.out.postgis
___________________________________________________________________
Added: svn:ignore
   + OBJ.*


Added: grass/trunk/vector/v.out.postgis/Makefile
===================================================================
--- grass/trunk/vector/v.out.postgis/Makefile	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/Makefile	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,14 @@
+MODULE_TOPDIR = ../..
+
+PGM=v.out.postgis
+
+LIBES = $(GPROJLIB) $(VECTORLIB) $(DBMILIB) $(GISLIB) 
+DEPENDENCIES = $(GPROJDEP) $(VECTORDEP) $(DBMIDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC) $(PROJINC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+ifneq ($(USE_POSTGRES),)
+default: cmd
+endif


Property changes on: grass/trunk/vector/v.out.postgis/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass/trunk/vector/v.out.postgis/export.c
===================================================================
--- grass/trunk/vector/v.out.postgis/export.c	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/export.c	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,105 @@
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+int export_lines(struct Map_info *In, int field, struct Map_info *Out)
+{
+    int type, nlines;
+
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    Points  = Vect_new_line_struct();
+    Cats    = Vect_new_cats_struct();
+
+    nlines = 0;
+    while(TRUE) {
+        type = Vect_read_next_line(In, Points, Cats);
+        if (type == -2)
+            break; /* eof */
+        
+        G_debug(3, "Export line %d", ++nlines);
+
+        if (-1 == Vect_write_line(Out, type, Points, Cats))
+            G_fatal_error(_("Unable to export feature %d. Exiting."), nlines);
+        
+        G_progress(nlines, 1e3);
+    }
+    G_progress(1, 1);
+
+    if (nlines < 1)
+        G_warning(_("Nothing exported"));
+    
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+    
+    return nlines;
+}
+
+int export_areas(struct Map_info *In, int field, struct Map_info *Out)
+{
+    int cat, i, isle;
+    int area, nareas, nisles, nisles_alloc;
+
+    struct line_pnts *Points, **IPoints;
+    struct line_cats *Cats;
+
+    Points = Vect_new_line_struct();
+    Cats   = Vect_new_cats_struct();
+    
+    IPoints = NULL;
+    nisles_alloc = 0;
+    
+    nareas = Vect_get_num_areas(In);
+    for(area = 1; area <= nareas; area++) {
+        Vect_reset_cats(Cats);
+        
+        G_percent(area, nareas, 3);
+        G_debug(3, "Export area %d", area);
+
+        /* get outer ring geometry */
+        Vect_get_area_points(In, area, Points);
+        
+        /* get category */
+        cat = Vect_get_area_cat(In, area, field);
+        if (cat < 0) {
+            G_warning(_("No centroid found for area %d. "
+                        "Area not exported."),
+                      area);
+            continue;
+        }
+        G_debug(3, " -> cat %d", cat);
+        Vect_cat_set(Cats, field, cat);
+
+        nisles = Vect_get_area_num_isles(In, area);
+        if (nisles > nisles_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;
+        }
+        G_debug(3, " -> nisles=%d", nisles);
+        
+        /* get isles geometry */
+        for (i = 0; i < nisles; i++) {
+            isle = Vect_get_area_isle(In, area, i);
+            Vect_get_isle_points(In, isle, IPoints[i]);
+        }
+
+        V2_write_area_pg(Out, Points, Cats,
+                         (const struct line_pnts **) IPoints, nisles);
+
+        /* TODO */
+    }
+    
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+    for (i = 0; i < nisles_alloc; i++)
+        Vect_destroy_line_struct(IPoints[i]);
+    
+    return nareas;
+}


Property changes on: grass/trunk/vector/v.out.postgis/export.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass/trunk/vector/v.out.postgis/export_topo.c
===================================================================
--- grass/trunk/vector/v.out.postgis/export_topo.c	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/export_topo.c	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,73 @@
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+static int export_nodes(struct Map_info *, struct Map_info *);
+
+int export_topo(struct Map_info *In, int field, struct Map_info *Out)
+{
+    int nfeat;
+
+    nfeat = 0;
+
+    /* export GRASS nodes -> PostGIS nodes */
+    nfeat += export_nodes(In, Out);
+    
+    /*
+      export GRASS points -> PostGIS nodes
+      export GRASS lines/boundaries -> PostGIS edges
+     
+      skip centroids
+    */
+    G_message(_("Exporting points/lines/boundaries..."));
+    nfeat += export_lines(In, field, Out);
+    
+    /* export GRASS areas as PostGIS faces */
+
+    /* export GRASS isles as PostGIS faces */
+
+    /* export GRASS centroids as nodes (in faces) */
+    
+    return nfeat;
+}
+
+int export_nodes(struct Map_info *In, struct Map_info *Out)
+{
+    int node, nnodes, with_z;
+    double x, y, z;
+    
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    
+    nnodes = Vect_get_num_nodes(In);
+    if (nnodes < 1)
+        return 0;
+    
+    with_z = Vect_is_3d(In);
+
+    Points = Vect_new_line_struct();
+    Cats    = Vect_new_cats_struct();
+
+    G_message(_("Exporting nodes..."));
+    Vect_append_point(Points, 0., 0., 0.);
+    for (node = 1; node <= nnodes; node++) {
+        G_debug(3, "Exporting GRASS node %d", node);
+        
+        G_percent(node, nnodes, 5);
+        Vect_get_node_coor(In, node, &x, &y, &z);
+        Points->x[0] = x;
+        Points->y[0] = y;
+        if (with_z)
+            Points->z[0] = z;
+
+        if (-1 == Vect_write_line(Out, GV_POINT, Points, Cats))
+            G_fatal_error(_("Unable to export node %d. Exiting."), node);
+    }
+        
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return nnodes;
+}
+


Property changes on: grass/trunk/vector/v.out.postgis/export_topo.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass/trunk/vector/v.out.postgis/local_proto.h
===================================================================
--- grass/trunk/vector/v.out.postgis/local_proto.h	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/local_proto.h	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,25 @@
+#ifndef __LOCAL_PROTO_V_OUT_POSTGIS__
+#define __LOCAL_PROTO_V_OUT_POSTGIS__
+
+#include <grass/vector.h>
+
+struct params {
+    struct Option *input, *layer, *dsn, *olayer;
+};
+
+struct flags {
+    struct Flag *table, *topo;
+};
+
+/* export.c */
+int export_lines(struct Map_info *, int, struct Map_info *);
+int export_areas(struct Map_info *, int, struct Map_info *);
+
+/* export_topo.c */
+int export_topo(struct Map_info *, int, struct Map_info *);
+
+/* options.c */
+void define_options(struct params *, struct flags *);
+char *create_pgfile(const char *, int);
+
+#endif /* __LOCAL_PROTO_V_OUT_POSTGIS__ */


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

Added: grass/trunk/vector/v.out.postgis/main.c
===================================================================
--- grass/trunk/vector/v.out.postgis/main.c	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/main.c	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,112 @@
+/***************************************************************
+ *
+ * MODULE:       v.out.postgis
+ *
+ * AUTHOR(S):    Martin Landa <landa.martin gmail.com>
+ *
+ * PURPOSE:      Converts GRASS vector map layer to PostGIS
+ *
+ * COPYRIGHT:    (C) 2012 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.
+ *
+ **************************************************************/
+
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+    struct GModule *module;
+    struct params params;
+    struct flags flags;
+    
+    int ret, field, do_areas;
+    struct Map_info In, Out;
+    
+    G_gisinit(argv[0]);
+
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("export"));
+    G_add_keyword(_("PostGIS"));
+
+    module->description =
+        _("Converts a vector map layer to PostGIS.");
+    module->overwrite = TRUE;
+    
+    define_options(&params, &flags);
+    
+    if (G_parser(argc, argv))
+        exit(EXIT_FAILURE);
+
+    /* if olayer not given, use input as the name */
+    if (!params.olayer->answer)
+        params.olayer->answer = G_store(params.input->answer);
+    
+    /* open input for reading */
+    ret = Vect_open_old2(&In, params.input->answer, "", params.layer->answer);
+    if (ret == -1)
+        G_fatal_error(_("Unable to open vector map <%s>"),
+                      params.input->answer);
+    if (ret < 2) 
+        G_warning(_("Unable to open vector map <%s> on topological level"),
+                  params.input->answer);
+    
+    /* create output for writing */
+    create_pgfile(params.dsn->answer, flags.topo->answer ? TRUE : FALSE);
+    
+    if (-1 == Vect_open_new(&Out, params.olayer->answer, Vect_is_3d(&In)))
+        G_fatal_error(_("Unable to create PostGIS layer <%s>"),
+                      params.olayer->answer);
+    
+    /* define attributes */
+    field = Vect_get_field_number(&In, params.layer->answer);
+    if (!flags.table->answer)
+        Vect_copy_map_dblinks(&In, &Out, TRUE);
+
+    ret = 0;
+    if (flags.topo->answer) {
+        /* PostGIS topology export */
+        G_message(_("Exporting features (topology)..."));
+        ret = export_topo(&In, field, &Out);
+    }
+    else {
+        /* simple features export */
+        int do_areas;
+
+        do_areas = FALSE;
+        if (Vect_level(&In) >= 2) {
+            if (Vect_get_num_areas(&In) > 0)
+                do_areas = TRUE;
+        }
+        else {
+            G_warning(_("Unable to process areas"));
+        }
+        
+        if (!do_areas) {
+            G_message(_("Exporting features..."));
+            ret = export_lines(&In, field, &Out);
+        }
+        else {
+            G_message(_("Exporting areas..."));
+            ret = export_areas(&In, field, &Out);
+        }
+    }
+    
+    if (ret > 0)
+        G_message(_("%d features exported"), ret);
+
+    Vect_build(&Out);
+    
+    Vect_close(&In);
+    Vect_close(&Out);
+    
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass/trunk/vector/v.out.postgis/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass/trunk/vector/v.out.postgis/options.c
===================================================================
--- grass/trunk/vector/v.out.postgis/options.c	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/options.c	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,100 @@
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+static void file_handler(void *);
+
+void define_options(struct params *params, struct flags *flags)
+{
+    params->input = G_define_standard_option(G_OPT_V_INPUT);
+    params->input->description = NULL;
+    
+    params->layer = G_define_standard_option(G_OPT_V_FIELD);
+    params->layer->description = NULL;
+    
+    params->dsn = G_define_option();
+    params->dsn->key = "dsn";
+    params->dsn->type = TYPE_STRING;
+    params->dsn->required = YES;
+    params->dsn->label = _("PostGIS output datasource name");
+    params->dsn->description =
+        _("Starts with 'PG' prefix, eg. 'PG:dbname=grass'");
+    
+    params->olayer = G_define_option();
+    params->olayer->key = "olayer";
+    params->olayer->type = TYPE_STRING;
+    params->olayer->required = NO;
+    params->olayer->label =
+        _("Name for output PostGIS layer");
+    params->olayer->description = 
+        _("If not specified, input name is used");
+
+    flags->table = G_define_flag();
+    flags->table->key = 't';
+    flags->table->description =
+        _("Don't export attribute table");
+
+    flags->topo = G_define_flag();
+    flags->topo->key = 'l';
+    flags->topo->description =
+        _("Export PostGIS topology instead of simple features");
+}
+
+char *create_pgfile(const char *dsn, int topo)
+{
+    char *filename, *conninfo;
+    FILE *fp;
+    
+    struct Key_Value *key_val;
+    
+    filename = NULL;
+    G_asprintf(&filename, "PG_%d", (int) getpid());
+    G_debug(1, "PG file: %s", filename);
+    
+    fp = G_fopen_new("", filename);
+    if (!fp)
+        G_fatal_error(_("Unable to create <%s> file"), filename);
+    setenv("GRASS_VECTOR_PGFILE", filename, TRUE);
+    G_add_error_handler(file_handler, filename);
+
+    key_val = G_create_key_value();
+    
+   /* be friendly, ignored 'PG:' prefix for GRASS-PostGIS data driver */
+    if (G_strncasecmp(dsn, "PG:", 3) == 0) {
+        int i, length;
+        
+        length = strlen(dsn);
+        conninfo = (char *) G_malloc(length - 3);
+        for (i = 3; i < length; i++)
+            conninfo[i-3] = dsn[i];
+        conninfo[length-3] = '\0';
+    }
+    else {
+        conninfo = G_store(dsn);
+    }
+    
+    G_set_key_value("conninfo", conninfo, key_val);
+    if (topo)
+        G_set_key_value("topology", "on", key_val);
+
+    if (G_fwrite_key_value(fp, key_val) < 0)
+        G_fatal_error(_("Error writing <%s> file"), filename);
+
+    fclose(fp);
+
+    G_free(conninfo);
+    
+    return filename;
+}
+
+void file_handler(void *p) {
+    const char *filename = (const char *) p;
+    
+    G_remove("", filename);
+    unsetenv("GRASS_VECTOR_PGFILE");
+}


Property changes on: grass/trunk/vector/v.out.postgis/options.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass/trunk/vector/v.out.postgis/v.out.postgis.html
===================================================================
--- grass/trunk/vector/v.out.postgis/v.out.postgis.html	                        (rev 0)
+++ grass/trunk/vector/v.out.postgis/v.out.postgis.html	2012-08-06 16:41:58 UTC (rev 52565)
@@ -0,0 +1,67 @@
+<h2>DESCRIPTION</h2>
+
+<em>v.out.postgis</em> exports existing GRASS vector map layer into
+PostGIS feature table.
+
+<h2>NOTES</h2>
+
+Currently only 2D vector features are supported.
+
+<p>
+By default <em>v.out.postgis</em> exports vector data as <em>simple
+features</em>, ie. boundaries and centroids (forming topological
+areas) become polygons, isles become holes. Geometry of simple feature
+elements is stored in PostGIS feature table.
+
+<p>
+<em>v.out.postgis</em> also allows to export vector features as
+<em>topological elements</em>
+in <a href="http://postgis.refractions.net/docs/Topology.html">PostGIS
+Topology</a>. PostGIS Topology extension uses three tables to store
+different topological primitives which forms topological objects like
+areas or isles in GRASS terminology. <em>Nodes</em> (0-dimensional
+elements) are stored in "node" table, <em>edges</em>
+(1-dimensional elements) in "edge" table and <em>faces</em>
+(2-dimensional elements) in "face" table.
+
+<ul>
+  <li>GRASS nodes are stored in <i>node</i> table</li>
+  <li>GRASS points are stored in <i>node</i> table as regular nodes</li>
+  <li>GRASS centroids are stored in <i>node</i> table as regular nodes
+  (<tt>containing_face</tt> refers to related area)</li>
+  <li>GRASS lines are stored in <i>edge</i> table</li>
+  <li>GRASS boundaries are stored in <i>edge</i> table</li>
+  <li>GRASS areas are stored in <i>face</i> table</li>
+</ul>
+
+Tables <i>node</i>, <i>edge</i> and <i>face</i> are stored in given topological schema. By default <em>v.out.postgis</em> defines it's name as <tt>topo_<name of input vector map></tt>.
+
+<h2>EXAMPLES</h2>
+
+<em>To be added</em>
+
+<h2>TODO</h2>
+
+<ul>
+  <li>Multi-feature export</li>
+</ul>
+
+<h2>REFERENCES</h2>
+
+<ul>
+  <li><a href="http://postgis.refractions.net/docs/Topology.html">PostGIS Topology</a> manual</li>
+</ul>
+
+<h2>SEE ALSO</h2>
+
+<em>
+  <a href="v.out.ogr.html">v.out.ogr</a>,
+  <a href="v.external.out.html">v.external.out</a>
+</em>
+
+<h2>AUTHORS</h2>
+
+Martin Landa, Czech Technical University in Prague, Czech Republic
+
+<p>
+<i>Last changed: $Date$</i>


Property changes on: grass/trunk/vector/v.out.postgis/v.out.postgis.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native



More information about the grass-commit mailing list