[GRASS-SVN] r58447 - grass/trunk/vector/v.out.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Dec 11 15:22:40 PST 2013
Author: martinl
Date: 2013-12-11 15:22:40 -0800 (Wed, 11 Dec 2013)
New Revision: 58447
Added:
grass/trunk/vector/v.out.ogr/export_areas.c
grass/trunk/vector/v.out.ogr/export_lines.c
Modified:
grass/trunk/vector/v.out.ogr/args.c
grass/trunk/vector/v.out.ogr/attrb.c
grass/trunk/vector/v.out.ogr/create.c
grass/trunk/vector/v.out.ogr/local_proto.h
grass/trunk/vector/v.out.ogr/main.c
grass/trunk/vector/v.out.ogr/v.out.ogr.html
Log:
v.out.ogr: implement multi-feature support
Modified: grass/trunk/vector/v.out.ogr/args.c
===================================================================
--- grass/trunk/vector/v.out.ogr/args.c 2013-12-11 20:21:50 UTC (rev 58446)
+++ grass/trunk/vector/v.out.ogr/args.c 2013-12-11 23:22:40 UTC (rev 58447)
@@ -6,39 +6,30 @@
struct Options *options, struct Flags *flags)
{
options->input = G_define_standard_option(G_OPT_V_INPUT);
+ options->input->label = _("Name of input vector map to export");
+
+ options->field = G_define_standard_option(G_OPT_V_FIELD);
+ options->field->guisection = _("Selection");
options->type = G_define_standard_option(G_OPT_V3_TYPE);
options->type->options =
"point,line,boundary,centroid,area,face,kernel,auto";
options->type->answer = "auto";
-
options->type->label = _("Feature type(s)");
options->type->description =
_("Combination of types is not supported "
"by all output formats. Default is to use first type found in input vector map.");
options->type->guisection = _("Selection");
- options->field = G_define_standard_option(G_OPT_V_FIELD);
- options->field->guisection = _("Selection");
-
options->dsn = G_define_option();
options->dsn->key = "dsn";
options->dsn->type = TYPE_STRING;
options->dsn->required = YES;
- options->dsn->label = _("OGR output datasource name");
+ options->dsn->label = _("Name of output OGR datasource");
options->dsn->description =
- _("For example: ESRI Shapefile: filename or directory for storage");
+ _("For example: ESRI Shapefile: filename or directory for storage\n"
+ "\tPostGIS database: connection string");
- options->layer = G_define_option();
- options->layer->key = "olayer";
- options->layer->type = TYPE_STRING;
- options->layer->required = NO;
- options->layer->label =
- _("OGR layer name. If not specified, input name is used.");
- options->layer->description =
- _("For example: ESRI Shapefile: shapefile name");
- options->layer->guisection = _("Creation");
-
options->format = G_define_option();
options->format->key = "format";
options->format->type = TYPE_STRING;
@@ -48,6 +39,28 @@
options->format->options = OGR_list_write_drivers();
options->format->description = _("Data format to write");
+ options->layer = G_define_option();
+ options->layer->key = "olayer";
+ options->layer->type = TYPE_STRING;
+ options->layer->required = NO;
+ options->layer->label =
+ _("Name for output OGR layer. If not specified, input name is used");
+ options->layer->description =
+ _("For example: ESRI Shapefile: shapefile name\n"
+ "\tPostGIS database: table name");
+ options->layer->guisection = _("Creation");
+
+ options->otype = G_define_standard_option(G_OPT_V_TYPE);
+ options->otype->key = "otype";
+ options->otype->options = "line,boundary";
+ options->otype->answer = "";
+ options->otype->description = _("Optionally change default output type");
+ G_asprintf((char **) &options->otype->descriptions,
+ "line;%s;boundary;%s",
+ _("export area boundaries as linestrings"),
+ _("export lines as polygons"));
+ options->otype->guisection = _("Creation");
+
options->dsco = G_define_option();
options->dsco->key = "dsco";
options->dsco->type = TYPE_STRING;
@@ -70,7 +83,7 @@
flags->update = G_define_flag();
flags->update->key = 'u';
- flags->update->description = _("Open an existing datasource for update");
+ flags->update->description = _("Open an existing OGR datasource for update");
flags->append = G_define_flag();
flags->append->key = 'a';
@@ -107,10 +120,16 @@
flags->poly->description = _("Export lines as polygons");
flags->poly->guisection = _("Creation");
+ flags->multi = G_define_flag();
+ flags->multi->key = 'm';
+ flags->multi->description =
+ _("Export vector data as multi-features");
+ flags->multi->guisection = _("Creation");
+
flags->new = G_define_flag();
flags->new->key = 'n';
flags->new->description =
- _("Create a new empty OGR layer in defined OGR datasource "
+ _("Create a new empty layer in defined OGR datasource "
"and exit. Nothing is read from input.");
flags->new->guisection = _("Creation");
Modified: grass/trunk/vector/v.out.ogr/attrb.c
===================================================================
--- grass/trunk/vector/v.out.ogr/attrb.c 2013-12-11 20:21:50 UTC (rev 58446)
+++ grass/trunk/vector/v.out.ogr/attrb.c 2013-12-11 23:22:40 UTC (rev 58447)
@@ -2,9 +2,9 @@
#include "local_proto.h"
-int mk_att(int cat, struct field_info *Fi, dbDriver *Driver, int ncol,
+int mk_att(int cat, struct field_info *Fi, dbDriver *driver, int ncol,
int *colctype, const char **colname, int doatt, int nocat,
- OGRFeatureH Ogr_feature, int *noatt, int *fout)
+ OGRFeatureH Ogr_feature, int *noatt)
{
int j, ogrfieldnum;
int more;
@@ -44,8 +44,7 @@
sprintf(buf, "SELECT * FROM %s WHERE %s = %d", Fi->table, Fi->key, cat);
G_debug(2, "SQL: %s", buf);
db_set_string(&dbstring, buf);
- if (db_open_select_cursor
- (Driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
+ if (db_open_select_cursor (driver, &dbstring, &cursor, DB_SEQUENTIAL) != DB_OK) {
G_fatal_error(_("Cannot select attributes for cat = %d"),
cat);
}
@@ -143,7 +142,6 @@
/* G_warning ("Line without cat of layer %d", field); */
nocat++;
}
- (*fout)++;
/*
db_free_string(&dbstring);
Modified: grass/trunk/vector/v.out.ogr/create.c
===================================================================
--- grass/trunk/vector/v.out.ogr/create.c 2013-12-11 20:21:50 UTC (rev 58446)
+++ grass/trunk/vector/v.out.ogr/create.c 2013-12-11 23:22:40 UTC (rev 58447)
@@ -36,3 +36,38 @@
G_fatal_error(_("Creation of OGR layer <%s> failed"), layer);
}
}
+
+OGRwkbGeometryType get_multi_wkbtype(OGRwkbGeometryType wkbtype)
+{
+ OGRwkbGeometryType multiwkbtype;
+
+ switch (wkbtype) {
+ case wkbPoint:
+ multiwkbtype = wkbMultiPoint;
+ break;
+ case wkbLineString:
+ multiwkbtype = wkbMultiLineString;
+ break;
+ case wkbPolygon:
+ multiwkbtype = wkbMultiPolygon;
+ break;
+ default:
+ multiwkbtype = wkbGeometryCollection;
+ break;
+ }
+
+ return multiwkbtype;
+}
+
+OGRwkbGeometryType get_wkbtype(int type, int otype)
+{
+ if (type == GV_POINT || type == GV_KERNEL ||
+ (type == GV_CENTROID && otype & GV_CENTROID))
+ return wkbPoint;
+ else if (type & GV_LINES)
+ return wkbLineString;
+ else if (type == GV_FACE)
+ return wkbPolygon25D;
+
+ return wkbGeometryCollection;
+}
Added: grass/trunk/vector/v.out.ogr/export_areas.c
===================================================================
--- grass/trunk/vector/v.out.ogr/export_areas.c (rev 0)
+++ grass/trunk/vector/v.out.ogr/export_areas.c 2013-12-11 23:22:40 UTC (rev 58447)
@@ -0,0 +1,307 @@
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+static int export_areas_single(struct Map_info *, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
+static int export_areas_multi(struct Map_info *, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
+static OGRGeometryH create_polygon(struct Map_info *, int, struct line_pnts *);
+
+/* export areas as single/multi-polygons */
+int export_areas(struct Map_info *In, int field, int multi, int donocat,
+ OGRFeatureDefnH Ogr_featuredefn,OGRLayerH Ogr_layer,
+ struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
+ const char **colname, int doatt, int nocat,
+ int *noatt, int *fout)
+{
+ if (multi)
+ /* export as multi-polygons */
+ return export_areas_multi(In, field, donocat,
+ Ogr_featuredefn, Ogr_layer,
+ Fi, driver, ncol, colctype,
+ colname, doatt, nocat,
+ noatt, fout);
+
+ /* export as polygons */
+ return export_areas_single(In, field, donocat,
+ Ogr_featuredefn, Ogr_layer,
+ Fi, driver, ncol, colctype,
+ colname, doatt, nocat,
+ noatt, fout);
+}
+
+int export_areas_single(struct Map_info *In, int field, int donocat,
+ OGRFeatureDefnH Ogr_featuredefn,OGRLayerH Ogr_layer,
+ struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
+ const char **colname, int doatt, int nocat,
+ int *n_noatt, int *n_nocat)
+{
+ int i, j;
+ int centroid, cat, area, n_areas;
+ int n_exported;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+
+ OGRGeometryH Ogr_geometry;
+ OGRFeatureH Ogr_feature;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+
+ n_exported = 0;
+
+ n_areas = Vect_get_num_areas(In);
+ for (i = 1; i <= n_areas; i++) {
+ G_percent(i, n_areas, 5);
+
+ /* get centroid's category */
+ centroid = Vect_get_area_centroid(In, i);
+ cat = -1;
+ if (centroid > 0) {
+ Vect_read_line(In, NULL, Cats, centroid);
+ Vect_cat_get(Cats, field, &cat);
+ }
+ G_debug(3, "area = %d centroid = %d ncats = %d", i, centroid,
+ Cats->n_cats);
+ if (cat < 0 && !donocat) {
+ (*n_nocat)++;
+ continue; /* skip areas without category, do not export
+ * not labeled */
+ }
+
+ /* find correspoding area */
+ area = Vect_get_centroid_area(In, centroid);
+ if (area == 0)
+ continue;
+
+ /* create polygon from area */
+ Ogr_geometry = create_polygon(In, area, Points);
+
+ /* add feature */
+ Ogr_feature = OGR_F_Create(Ogr_featuredefn);
+ OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
+
+ /* output one feature for each category */
+ for (j = -1; j < Cats->n_cats; j++) {
+ if (j == -1) {
+ if (cat >= 0)
+ continue; /* cat(s) exists */
+ }
+ else {
+ if (Cats->field[j] == field)
+ cat = Cats->cat[j];
+ else
+ continue;
+ }
+
+ mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
+ Ogr_feature, n_noatt);
+ OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
+
+ n_exported++;
+ }
+ OGR_G_DestroyGeometry(Ogr_geometry);
+ OGR_F_Destroy(Ogr_feature);
+ }
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+
+ return n_exported;
+}
+
+int export_areas_multi(struct Map_info *In, int field, int donocat,
+ OGRFeatureDefnH Ogr_featuredefn,OGRLayerH Ogr_layer,
+ struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
+ const char **colname, int doatt, int nocat,
+ int *n_noatt, int *n_nocat)
+{
+ int i, n_exported, area;
+ int cat, lcat, ncats_field, line, type, findex, ipart;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ struct ilist *cat_list, *line_list;
+
+ OGRGeometryH Ogr_geometry, Ogr_geometry_part;
+ OGRFeatureH Ogr_feature;
+ OGRwkbGeometryType wkbtype, wkbtype_part;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ cat_list = Vect_new_list();
+ line_list = Vect_new_list();
+
+ n_exported = 0;
+
+ /* check if category index is available for given field */
+ findex = Vect_cidx_get_field_index(In, field);
+ if (findex == -1)
+ G_fatal_error(_("Unable to export multi-features. No category index for layer %d."),
+ field);
+
+ /* determine type */
+ wkbtype_part = wkbPolygon;
+ wkbtype = get_multi_wkbtype(wkbtype_part);
+
+ ncats_field = Vect_cidx_get_unique_cats_by_index(In, findex, cat_list);
+ G_debug(1, "n_cats = %d for layer %d", ncats_field, field);
+
+ for (i = 0; i < cat_list->n_values; i++) {
+ cat = cat_list->value[i];
+ /* find all centroids with given category */
+ Vect_cidx_find_all(In, field, GV_CENTROID, cat, line_list);
+
+ /* create multi-feature */
+ Ogr_geometry = OGR_G_CreateGeometry(wkbtype);
+
+ /* build simple features geometry, go through all parts */
+ for (ipart = 0; ipart < line_list->n_values; ipart++) {
+ line = line_list->value[ipart];
+ G_debug(3, "cat=%d, line=%d -> part=%d", cat, line, ipart);
+
+ /* get centroid's category */
+ Vect_read_line(In, NULL, Cats, line);
+ /* check for category consistency */
+ Vect_cat_get(Cats, field, &lcat);
+ if (lcat > 0 && lcat != cat)
+ G_fatal_error(_("Unable to create multi-feature. "
+ "Invalid category %d (should be %d)"),
+ lcat, cat);
+
+ /* find correspoding area */
+ area = Vect_get_centroid_area(In, line);
+ if (area == 0)
+ continue;
+
+ /* create polygon from area */
+ Ogr_geometry_part = create_polygon(In, area, Points);
+
+ /* add part */
+ OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);
+ }
+
+ if (!OGR_G_IsEmpty(Ogr_geometry)) {
+ /* write multi-feature */
+ Ogr_feature = OGR_F_Create(Ogr_featuredefn);
+ OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
+
+ mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
+ Ogr_feature, n_noatt);
+ OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
+
+ OGR_F_Destroy(Ogr_feature);
+
+ n_exported++;
+ }
+ else {
+ /* skip empty features */
+ G_debug(3, "multi-feature is empty -> skipped");
+ }
+
+ OGR_G_DestroyGeometry(Ogr_geometry);
+ }
+
+ /* check lines without category, if -c flag is given write them as
+ * one multi-feature */
+ Ogr_geometry = OGR_G_CreateGeometry(wkbtype);
+
+ Vect_rewind(In);
+ Vect_set_constraint_type(In, GV_CENTROID);
+ while(TRUE) {
+ type = Vect_read_next_line(In, NULL, Cats);
+ if (type < 0)
+ break;
+
+ /* get centroid's category */
+ Vect_cat_get(Cats, field, &cat);
+ if (cat > 0)
+ continue; /* skip features with category */
+ if (cat < 0 && !donocat) {
+ (*n_nocat)++;
+ continue; /* skip lines without category, do not export
+ * not labeled */
+ }
+
+ /* find correspoding area */
+ area = Vect_get_centroid_area(In, line);
+ if (area == 0)
+ continue;
+
+ /* create polygon from area */
+ Ogr_geometry_part = create_polygon(In, area, Points);
+
+ /* add part */
+ OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);
+ }
+
+ if (!OGR_G_IsEmpty(Ogr_geometry)) {
+ /* write multi-feature */
+ Ogr_feature = OGR_F_Create(Ogr_featuredefn);
+ OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
+
+ mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
+ Ogr_feature, n_noatt);
+ OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
+
+ OGR_F_Destroy(Ogr_feature);
+
+ n_exported++;
+ }
+ else {
+ /* skip empty features */
+ G_debug(3, "multi-feature is empty -> skipped");
+ }
+
+ OGR_G_DestroyGeometry(Ogr_geometry);
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+ Vect_destroy_list(cat_list);
+ Vect_destroy_list(line_list);
+
+ return n_exported;
+}
+
+OGRGeometryH create_polygon(struct Map_info *In, int area,
+ struct line_pnts *Points)
+{
+ int j, k;
+ OGRGeometryH Ogr_geometry, ring;
+
+ Vect_get_area_points(In, area, Points);
+
+ Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
+ ring = OGR_G_CreateGeometry(wkbLinearRing);
+
+ /* Area */
+ for (j = 0; j < Points->n_points; j++) {
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+
+ OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
+
+ /* Isles */
+ for (k = 0; k < Vect_get_area_num_isles(In, area); k++) {
+ Vect_get_isle_points(In, Vect_get_area_isle(In, area, k),
+ Points);
+
+ ring = OGR_G_CreateGeometry(wkbLinearRing);
+ for (j = 0; j < Points->n_points; j++) {
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+ OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
+ }
+
+ return Ogr_geometry;
+}
Added: grass/trunk/vector/v.out.ogr/export_lines.c
===================================================================
--- grass/trunk/vector/v.out.ogr/export_lines.c (rev 0)
+++ grass/trunk/vector/v.out.ogr/export_lines.c 2013-12-11 23:22:40 UTC (rev 58447)
@@ -0,0 +1,335 @@
+#include <grass/glocale.h>
+
+#include "local_proto.h"
+
+static int export_lines_single(struct Map_info *, int, int, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
+static int export_lines_multi(struct Map_info *, int, int, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
+
+static void line_to_polygon(OGRGeometryH, const struct line_pnts *);
+
+static void add_part(OGRGeometryH, OGRwkbGeometryType,
+ int, struct line_pnts *);
+
+/* export primitives as single/multi-features */
+int export_lines(struct Map_info *In, int field, int otype, int multi, int donocat, int force_poly,
+ OGRFeatureDefnH Ogr_featuredefn, OGRLayerH Ogr_layer,
+ struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
+ const char **colname, int doatt, int nocat,
+ int *n_noatt, int *n_nocat)
+{
+ if (multi)
+ /* export as multi-features */
+ return export_lines_multi(In, field, otype, donocat, force_poly,
+ Ogr_featuredefn, Ogr_layer,
+ Fi, driver, ncol, colctype,
+ colname, doatt, nocat,
+ n_noatt, n_nocat);
+
+ /* export as single features */
+ return export_lines_single(In, field, otype, donocat, force_poly,
+ Ogr_featuredefn, Ogr_layer,
+ Fi, driver, ncol, colctype,
+ colname, doatt, nocat,
+ n_noatt, n_nocat);
+}
+
+/* export line as single feature */
+int export_lines_single(struct Map_info *In, int field, int otype, int donocat, int force_poly,
+ OGRFeatureDefnH Ogr_featuredefn, OGRLayerH Ogr_layer,
+ struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
+ const char **colname, int doatt, int nocat,
+ int *n_noatt, int *n_nocat)
+{
+ int i, j, n_exported, n_lines;
+ int cat, type;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+
+ OGRGeometryH Ogr_geometry;
+ OGRFeatureH Ogr_feature;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+
+ n_exported = 0;
+ n_lines = Vect_get_num_lines(In);
+ for (i = 1; i <= n_lines; i++) {
+
+ G_percent(i, n_lines, 5);
+
+ /* read line */
+ type = Vect_read_line(In, Points, Cats, i);
+ G_debug(2, "line = %d type = %d", i, type);
+ if (!(otype & type)) {
+ /* skip lines with different type */
+ G_debug(2, "type %d not specified -> skipping", type);
+ continue;
+ }
+
+ /* get line category */
+ Vect_cat_get(Cats, field, &cat);
+ if (cat < 0 && !donocat) {
+ (*n_nocat)++;
+ continue; /* skip lines without category, do not export
+ * not labeled */
+ }
+
+ /* build simple features geometry */
+ if ((type == GV_LINE && force_poly) || type == GV_FACE) {
+ /* lines to polygons
+ faces to 2.5D polygons */
+ Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
+ line_to_polygon(Ogr_geometry, Points);
+ }
+ else {
+ Ogr_geometry = OGR_G_CreateGeometry(get_wkbtype(type, otype));
+ if (OGR_G_GetGeometryType(Ogr_geometry) == wkbPoint) {
+ /* GV_POINTS -> wkbPoint */
+ OGR_G_AddPoint(Ogr_geometry, Points->x[0], Points->y[0],
+ Points->z[0]);
+ }
+ else { /* GV_LINES -> wkbLinestring */
+ for (j = 0; j < Points->n_points; j++) {
+ OGR_G_AddPoint(Ogr_geometry, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+ }
+ }
+
+ /* create feature & set geometry */
+ Ogr_feature = OGR_F_Create(Ogr_featuredefn);
+ OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
+
+ /* output one feature for each category, export also features
+ * without category (cat = -1) */
+ for (j = -1; j < Cats->n_cats; j++) {
+ if (j == -1) {
+ if (cat >= 0)
+ continue; /* cat(s) exists */
+ }
+ else {
+ if (Cats->field[j] == field)
+ cat = Cats->cat[j];
+ else
+ continue;
+ }
+
+ mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
+ Ogr_feature, n_noatt);
+ OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
+ }
+ OGR_G_DestroyGeometry(Ogr_geometry);
+ OGR_F_Destroy(Ogr_feature);
+
+ n_exported++;
+ }
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+
+ return n_exported;
+}
+
+/* export line as multi-feature */
+int export_lines_multi(struct Map_info *In, int field, int otype, int donocat, int force_poly,
+ OGRFeatureDefnH Ogr_featuredefn, OGRLayerH Ogr_layer,
+ struct field_info *Fi, dbDriver *driver, int ncol, int *colctype,
+ const char **colname, int doatt, int nocat,
+ int *n_noatt, int *n_nocat)
+{
+ int i, n_exported;
+ int cat, lcat, ncats_field, line, type, findex, ipart;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ struct ilist *cat_list, *line_list;
+
+ OGRGeometryH Ogr_geometry;
+ OGRFeatureH Ogr_feature;
+ OGRwkbGeometryType wkbtype, wkbtype_part;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ cat_list = Vect_new_list();
+ line_list = Vect_new_list();
+
+ n_exported = 0;
+
+ /* check if category index is available for given field */
+ findex = Vect_cidx_get_field_index(In, field);
+ if (findex == -1)
+ G_fatal_error(_("Unable to export multi-features. No category index for layer %d."),
+ field);
+
+ /* determine type */
+ type = -1; /* unknown -> GeometryCollection */
+ if (Vect_cidx_get_num_types_by_index(In, findex) == 1)
+ Vect_cidx_get_type_count_by_index(In, findex, 0, &type, NULL);
+ if (force_poly)
+ wkbtype_part = wkbPolygon;
+ else
+ wkbtype_part = get_wkbtype(type, otype);
+ wkbtype = get_multi_wkbtype(wkbtype_part);
+
+ ncats_field = Vect_cidx_get_unique_cats_by_index(In, findex, cat_list);
+ G_debug(1, "n_cats = %d for layer %d", ncats_field, field);
+
+ for (i = 0; i < cat_list->n_values; i++) {
+ cat = cat_list->value[i];
+ Vect_cidx_find_all(In, field, otype, cat, line_list);
+
+ /* create multi-feature */
+ Ogr_geometry = OGR_G_CreateGeometry(wkbtype);
+
+ /* build simple features geometry, go through all parts */
+ for (ipart = 0; ipart < line_list->n_values; ipart++) {
+ line = line_list->value[ipart];
+ G_debug(3, "cat=%d, line=%d -> part=%d", cat, line, ipart);
+
+ /* read line */
+ type = Vect_read_line(In, Points, Cats, line);
+
+ /* check for category consistency */
+ Vect_cat_get(Cats, field, &lcat);
+ if (lcat > 0 && lcat != cat)
+ G_fatal_error(_("Unable to create multi-feature. "
+ "Invalid category %d (should be %d)"),
+ lcat, cat);
+
+ /* add part */
+ add_part(Ogr_geometry, wkbtype_part,
+ type == GV_LINE && force_poly, Points);
+ }
+
+ if (!OGR_G_IsEmpty(Ogr_geometry)) {
+ /* write multi-feature */
+ Ogr_feature = OGR_F_Create(Ogr_featuredefn);
+ OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
+
+ mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
+ Ogr_feature, n_noatt);
+ OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
+
+ OGR_F_Destroy(Ogr_feature);
+
+ n_exported++;
+ }
+ else {
+ /* skip empty features */
+ G_debug(3, "multi-feature is empty -> skipped");
+ }
+
+ OGR_G_DestroyGeometry(Ogr_geometry);
+ }
+
+ /* check lines without category, if -c flag is given write them as
+ * one multi-feature */
+ Ogr_geometry = OGR_G_CreateGeometry(wkbtype);
+
+ Vect_rewind(In);
+ while(TRUE) {
+ type = Vect_read_next_line(In, Points, Cats);
+ if (type < 0)
+ break;
+
+ Vect_cat_get(Cats, field, &cat);
+ if (cat > 0)
+ continue; /* skip features with category */
+ if (cat < 0 && !donocat) {
+ (*n_nocat)++;
+ continue; /* skip lines without category, do not export
+ * not labeled */
+ }
+
+ /* add part */
+ add_part(Ogr_geometry, wkbtype_part,
+ type == GV_LINE && force_poly, Points);
+ }
+
+ if (!OGR_G_IsEmpty(Ogr_geometry)) {
+ /* write multi-feature */
+ Ogr_feature = OGR_F_Create(Ogr_featuredefn);
+ OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
+
+ mk_att(cat, Fi, driver, ncol, colctype, colname, doatt, nocat,
+ Ogr_feature, n_noatt);
+ OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
+
+ OGR_F_Destroy(Ogr_feature);
+
+ n_exported++;
+ }
+ else {
+ /* skip empty features */
+ G_debug(3, "multi-feature is empty -> skipped");
+ }
+
+ OGR_G_DestroyGeometry(Ogr_geometry);
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+ Vect_destroy_list(cat_list);
+ Vect_destroy_list(line_list);
+
+ return n_exported;
+}
+
+/* build polygon for closed line */
+void line_to_polygon(OGRGeometryH Ogr_geometry, const struct line_pnts *Points)
+{
+ int j;
+ OGRGeometryH ring;
+
+ ring = OGR_G_CreateGeometry(wkbLinearRing);
+
+ /* create a ring */
+ for (j = 0; j < Points->n_points; j++) {
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+
+ /* close ring */
+ if (Points->x[Points->n_points - 1] != Points->x[0] ||
+ Points->y[Points->n_points - 1] != Points->y[0] ||
+ Points->z[Points->n_points - 1] != Points->z[0]) {
+ OGR_G_AddPoint(ring, Points->x[0], Points->y[0],
+ Points->z[0]);
+ }
+
+ OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
+}
+
+void add_part(OGRGeometryH Ogr_geometry, OGRwkbGeometryType wkbtype_part,
+ int force_poly, struct line_pnts *Points)
+{
+ int j;
+ OGRGeometryH Ogr_geometry_part;
+
+ Ogr_geometry_part = OGR_G_CreateGeometry(wkbtype_part);
+ if (force_poly) {
+ line_to_polygon(Ogr_geometry_part, Points);
+ }
+ else {
+ if (OGR_G_GetGeometryType(Ogr_geometry_part) == wkbPoint) {
+ /* GV_POINTS -> wkbPoint */
+ OGR_G_AddPoint(Ogr_geometry_part, Points->x[0], Points->y[0],
+ Points->z[0]);
+ }
+ else { /* GV_LINES -> wkbLinestring */
+ for (j = 0; j < Points->n_points; j++) {
+ OGR_G_AddPoint(Ogr_geometry_part, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+ }
+ }
+ OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);
+}
Modified: grass/trunk/vector/v.out.ogr/local_proto.h
===================================================================
--- grass/trunk/vector/v.out.ogr/local_proto.h 2013-12-11 20:21:50 UTC (rev 58446)
+++ grass/trunk/vector/v.out.ogr/local_proto.h 2013-12-11 23:22:40 UTC (rev 58447)
@@ -12,11 +12,11 @@
struct Options {
struct Option *input, *dsn, *layer, *type, *format,
- *field, *dsco, *lco;
+ *field, *dsco, *lco, *otype;
};
struct Flags {
- struct Flag *cat, *esristyle, *poly, *update, *nocat, *new, *append, *force2d;
+ struct Flag *cat, *esristyle, *poly, *update, *nocat, *new, *append, *force2d, *multi;
};
/* args.c */
@@ -24,9 +24,9 @@
struct Options*, struct Flags *);
/* attributes.c */
-int mk_att(int cat, struct field_info *Fi, dbDriver *Driver,
- int ncol, int *colctype, const char **colname, int doatt, int nocat,
- OGRFeatureH Ogr_feature, int *, int *);
+int mk_att(int, struct field_info *, dbDriver *,
+ int, int *, const char **, int, int,
+ OGRFeatureH, int *);
/* list.c */
char *OGR_list_write_drivers();
@@ -34,3 +34,26 @@
/* create.c */
void create_ogr_layer(const char *, const char *, const char *,
unsigned int, char **, char **);
+OGRwkbGeometryType get_multi_wkbtype(OGRwkbGeometryType);
+OGRwkbGeometryType get_wkbtype(int, int);
+
+/* export_lines.c */
+int export_lines(struct Map_info *, int, int, int, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
+
+/* export_lines_3d.c */
+int export_lines_3d(struct Map_info *, int, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
+
+/* export_areas.c */
+int export_areas(struct Map_info *, int, int, int,
+ OGRFeatureDefnH, OGRLayerH,
+ struct field_info *, dbDriver *, int, int *,
+ const char **, int, int,
+ int *, int *);
Modified: grass/trunk/vector/v.out.ogr/main.c
===================================================================
--- grass/trunk/vector/v.out.ogr/main.c 2013-12-11 20:21:50 UTC (rev 58446)
+++ grass/trunk/vector/v.out.ogr/main.c 2013-12-11 23:22:40 UTC (rev 58447)
@@ -5,11 +5,11 @@
*
* AUTHOR(S): Radim Blazek
* Some extensions: Markus Neteler, Benjamin Ducke
- * Update for GRASS 7 by Martin Landa <landa.martin gmail.com> (create new OGR layer)
+ * Multi-features support by Martin Landa <landa.martin gmail.com>
*
* PURPOSE: Converts GRASS vector to one of supported OGR vector formats.
*
- * COPYRIGHT: (C) 2001-2009, 2011 by the GRASS Development Team
+ * COPYRIGHT: (C) 2001-2013 by the GRASS Development Team
*
* This program is free software under the GNU General
* Public License (>=v2). Read the file COPYING that
@@ -29,10 +29,11 @@
int main(int argc, char *argv[])
{
- int i, j, k, centroid, otype, donocat;
+ int i, otype, ftype, donocat;
int num_to_export;
int field;
int overwrite, found;
+
struct GModule *module;
struct Options options;
struct Flags flags;
@@ -45,9 +46,6 @@
/* Vector */
struct Map_info In;
- struct line_pnts *Points;
- struct line_cats *Cats;
- int type, cat;
/* Attributes */
int doatt = 0, ncol = 0, colsqltype, colwidth, keycol = -1;
@@ -59,8 +57,8 @@
dbString dbstring;
dbColumn *Column;
- int fout, fskip; /* features written/ skip */
- int nocat, noatt, nocatskip; /* number of features without cats/atts written/skip */
+ int n_feat; /* number of written features */
+ int n_nocat, n_noatt, n_nocatskip; /* number of features without cats/atts written/skip */
/* OGR */
int drn;
@@ -69,10 +67,8 @@
OGRSFDriverH Ogr_driver;
OGRLayerH Ogr_layer;
OGRFieldDefnH Ogr_field;
- OGRFeatureH Ogr_feature;
OGRFeatureDefnH Ogr_featuredefn;
- OGRGeometryH Ogr_geometry;
- OGRwkbGeometryType wkbtype = wkbUnknown; /* ?? */
+ OGRwkbGeometryType wkbtype = wkbUnknown;
OGRSpatialReferenceH Ogr_projection;
char **papszDSCO = NULL, **papszLCO = NULL;
int num_types;
@@ -85,8 +81,9 @@
G_add_keyword(_("export"));
G_add_keyword("OGR");
- module->description =
- _("Converts a vector map to any of the supported OGR vector formats.");
+ module->label =
+ _("Exports a vector map layer to any of the supported OGR vector formats.");
+ module->description = _("By default a vector map layer is exported to Esri Shapefile format.");
module->overwrite = TRUE;
/* parse & read options */
@@ -187,6 +184,7 @@
/* check output feature type */
otype = Vect_option_to_types(options.type);
+ ftype = Vect_option_to_types(options.otype);
if (!options.layer->answer) {
char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
@@ -197,20 +195,37 @@
options.layer->answer = G_store(options.input->answer);
}
- if (otype & GV_POINTS)
- wkbtype = wkbPoint;
- else if (otype & GV_LINES)
- wkbtype = wkbLineString;
- else if (otype & GV_AREA)
- wkbtype = wkbPolygon;
- else if (otype & GV_FACE)
- wkbtype = wkbPolygon25D;
- else if (otype & GV_VOLUME)
- wkbtype = wkbPolygon25D;
+ if (flags.poly->answer) {
+ if (!flags.multi->answer)
+ wkbtype = wkbPolygon;
+ else
+ wkbtype = wkbMultiPolygon;
+ }
+ else if (otype & GV_POINTS) {
+ if (!flags.multi->answer)
+ wkbtype = wkbPoint;
+ else
+ wkbtype = wkbMultiPoint;
+ }
+ else if (otype & GV_LINES || ftype == GV_LINE) {
+ if (!flags.multi->answer)
+ wkbtype = wkbLineString;
+ else
+ wkbtype = wkbMultiLineString;
+ }
+ else if (otype & GV_AREA) {
+ if (!flags.multi->answer)
+ wkbtype = wkbPolygon;
+ else
+ wkbtype = wkbMultiPolygon;
+ }
+ else if (otype & (GV_FACE | GV_VOLUME)) {
+ if (!flags.multi->answer)
+ wkbtype = wkbPolygon25D;
+ else
+ wkbtype = wkbMultiPolygon25D;
+ }
- if (flags.poly->answer)
- wkbtype = wkbPolygon;
-
if (((GV_POINTS & otype) && (GV_LINES & otype)) ||
((GV_POINTS & otype) && (GV_AREA & otype)) ||
((GV_POINTS & otype) && (GV_FACE & otype)) ||
@@ -225,7 +240,6 @@
((GV_KERNEL & otype) && (GV_AREA & otype)) ||
((GV_KERNEL & otype) && (GV_FACE & otype)) ||
((GV_KERNEL & otype) && (GV_VOLUME & otype))
-
) {
G_warning(_("The combination of types is not supported"
" by all formats."));
@@ -266,9 +280,6 @@
else
donocat = 0;
- Points = Vect_new_line_struct();
- Cats = Vect_new_cats_struct();
-
if ((GV_AREA & otype) && Vect_get_num_islands(&In) > 0 &&
flags.cat->answer)
G_warning(_("The map contains islands. With the -c flag, "
@@ -515,7 +526,7 @@
else {
G_warning(_("Vector map <%s> is 3D. "
"Use format specific layer creation options (parameter 'lco') "
- "to export in 3D rather than 2D (default)."),
+ "to export <in 3D rather than 2D (default)."),
options.input->answer);
}
}
@@ -647,291 +658,43 @@
Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
- fout = fskip = nocat = noatt = nocatskip = 0;
+ n_feat = n_nocat = n_noatt = n_nocatskip = 0;
if (OGR_L_TestCapability(Ogr_layer, OLCTransactions))
OGR_L_StartTransaction(Ogr_layer);
/* Lines (run always to count features of different type) */
- if ((otype & GV_POINTS) || (otype & GV_LINES)) {
+ if (otype & (GV_POINTS | GV_LINES | GV_KERNEL | GV_FACE)) {
G_message(_("Exporting %d features..."), Vect_get_num_primitives(&In, otype));
- for (i = 1; i <= Vect_get_num_lines(&In); i++) {
- G_percent(i, Vect_get_num_lines(&In), 1);
-
- type = Vect_read_line(&In, Points, Cats, i);
- G_debug(2, "line = %d type = %d", i, type);
- if (!(otype & type)) {
- G_debug(2, "type %d not specified -> skipping", type);
- fskip++;
- continue;
- }
-
- Vect_cat_get(Cats, field, &cat);
- if (cat < 0 && !donocat) { /* Do not export not labeled */
- nocatskip++;
- continue;
- }
-
- /* Geometry */
- if (type == GV_LINE && flags.poly->answer) {
- OGRGeometryH ring;
-
- ring = OGR_G_CreateGeometry(wkbLinearRing);
- Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
-
- /* Area */
- for (j = 0; j < Points->n_points; j++) {
- OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
- Points->z[j]);
- }
- if (Points->x[Points->n_points - 1] != Points->x[0] ||
- Points->y[Points->n_points - 1] != Points->y[0] ||
- Points->z[Points->n_points - 1] != Points->z[0]) {
- OGR_G_AddPoint(ring, Points->x[0], Points->y[0],
- Points->z[0]);
- }
-
- OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
- }
- else if ((type == GV_POINT) ||
- ((type == GV_CENTROID) && (otype & GV_CENTROID))) {
- Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
- OGR_G_AddPoint(Ogr_geometry, Points->x[0], Points->y[0],
- Points->z[0]);
- }
- else { /* GV_LINE or GV_BOUNDARY */
- Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
- for (j = 0; j < Points->n_points; j++) {
- OGR_G_AddPoint(Ogr_geometry, Points->x[j], Points->y[j],
- Points->z[j]);
- }
- }
- Ogr_feature = OGR_F_Create(Ogr_featuredefn);
-
- OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
-
- /* Output one feature for each category */
- for (j = -1; j < Cats->n_cats; j++) {
- if (j == -1) {
- if (cat >= 0)
- continue; /* cat(s) exists */
- }
- else {
- if (Cats->field[j] == field)
- cat = Cats->cat[j];
- else
- continue;
- }
-
- mk_att(cat, Fi, Driver, ncol, colctype, colname, doatt, flags.nocat->answer,
- Ogr_feature, &noatt, &fout);
- OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
- }
- OGR_G_DestroyGeometry(Ogr_geometry);
- OGR_F_Destroy(Ogr_feature);
- }
+ n_feat += export_lines(&In, field, otype, flags.multi->answer ? TRUE : FALSE,
+ donocat, flags.poly->answer ? TRUE : FALSE,
+ Ogr_featuredefn, Ogr_layer,
+ Fi, Driver, ncol, colctype,
+ colname, doatt, flags.nocat->answer ? TRUE : FALSE,
+ &n_noatt, &n_nocatskip);
}
/* Areas (run always to count features of different type) */
- if (Vect_get_num_areas(&In) > 0 && otype & GV_AREA) {
- G_message(_("Exporting %i areas (may take some time)..."),
+ if (Vect_get_num_areas(&In) > 0 && (otype & GV_AREA)) {
+ G_message(_("Exporting %d areas (may take some time)..."),
Vect_get_num_areas(&In));
- for (i = 1; i <= Vect_get_num_areas(&In); i++) {
- OGRGeometryH ring;
- G_percent(i, Vect_get_num_areas(&In), 1);
-
- centroid = Vect_get_area_centroid(&In, i);
- cat = -1;
- if (centroid > 0) {
- Vect_read_line(&In, NULL, Cats, centroid);
- Vect_cat_get(Cats, field, &cat);
- }
- G_debug(3, "area = %d centroid = %d ncats = %d", i, centroid,
- Cats->n_cats);
- if (cat < 0 && !donocat) { /* Do not export not labeled */
- nocatskip++;
- continue;
- }
-
- Vect_get_area_points(&In, i, Points);
-
- /* Geometry */
- Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
-
- ring = OGR_G_CreateGeometry(wkbLinearRing);
-
- /* Area */
- for (j = 0; j < Points->n_points; j++) {
- OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
- Points->z[j]);
- }
-
- OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
-
- /* Isles */
- for (k = 0; k < Vect_get_area_num_isles(&In, i); k++) {
- Vect_get_isle_points(&In, Vect_get_area_isle(&In, i, k),
- Points);
-
- ring = OGR_G_CreateGeometry(wkbLinearRing);
- for (j = 0; j < Points->n_points; j++) {
- OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
- Points->z[j]);
- }
- OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
- }
-
- Ogr_feature = OGR_F_Create(Ogr_featuredefn);
- OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
-
- /* Output one feature for each category */
- for (j = -1; j < Cats->n_cats; j++) {
- if (j == -1) {
- if (cat >= 0)
- continue; /* cat(s) exists */
- }
- else {
- if (Cats->field[j] == field)
- cat = Cats->cat[j];
- else
- continue;
- }
-
- mk_att(cat, Fi, Driver, ncol, colctype, colname, doatt, flags.nocat->answer,
- Ogr_feature, &noatt, &fout);
- OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
- }
- OGR_G_DestroyGeometry(Ogr_geometry);
- OGR_F_Destroy(Ogr_feature);
- }
+ n_feat += export_areas(&In, field, flags.multi->answer ? TRUE : FALSE, donocat,
+ Ogr_featuredefn, Ogr_layer,
+ Fi, Driver, ncol, colctype,
+ colname, doatt, flags.nocat->answer ? TRUE : FALSE,
+ &n_noatt, &n_nocatskip);
}
- /* Faces (run always to count features of different type) - Faces are similar to lines */
- if (Vect_get_num_primitives(&In, GV_FACE) > 0 && otype & GV_FACE) {
- G_message(_("Exporting %i faces..."), Vect_get_num_faces(&In));
- for (i = 1; i <= Vect_get_num_faces(&In); i++) {
- OGRGeometryH ring;
-
- G_percent(i, Vect_get_num_faces(&In), 1);
-
- type = Vect_read_line(&In, Points, Cats, i);
- G_debug(3, "line type = %d", type);
-
- cat = -1;
- Vect_cat_get(Cats, field, &cat);
-
- G_debug(3, "face = %d ncats = %d", i, Cats->n_cats);
- if (cat < 0 && !donocat) { /* Do not export not labeled */
- nocatskip++;
- continue;
- }
-
- if (type & GV_FACE) {
-
- Ogr_feature = OGR_F_Create(Ogr_featuredefn);
-
- /* Geometry */
- Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
- ring = OGR_G_CreateGeometry(wkbLinearRing);
-
- /* Face */
- for (j = 0; j < Points->n_points; j++) {
- OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
- Points->z[j]);
- }
-
- OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
-
- OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
-
- /* Output one feature for each category */
- for (j = -1; j < Cats->n_cats; j++) {
- if (j == -1) {
- if (cat >= 0)
- continue; /* cat(s) exists */
- }
- else {
- if (Cats->field[j] == field)
- cat = Cats->cat[j];
- else
- continue;
- }
-
- mk_att(cat, Fi, Driver, ncol, colctype, colname, doatt, flags.nocat->answer,
- Ogr_feature, &noatt, &fout);
- OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
- }
-
- OGR_G_DestroyGeometry(Ogr_geometry);
- OGR_F_Destroy(Ogr_feature);
- } /* if type & GV_FACE */
- } /* for */
- }
-
- /* Kernels */
- if (Vect_get_num_primitives(&In, GV_KERNEL) > 0 && otype & GV_KERNEL) {
- G_message(_("Exporting %i kernels..."), Vect_get_num_kernels(&In));
- for (i = 1; i <= Vect_get_num_lines(&In); i++) {
-
- G_percent(i, Vect_get_num_lines(&In), 1);
-
- type = Vect_read_line(&In, Points, Cats, i);
- G_debug(2, "line = %d type = %d", i, type);
- if (!(otype & type)) {
- G_debug(2, "type %d not specified -> skipping", type);
- fskip++;
- continue;
- }
-
- Vect_cat_get(Cats, field, &cat);
- if (cat < 0 && !donocat) { /* Do not export not labeled */
- nocatskip++;
- continue;
- }
-
- /* Geometry */
- if (type == GV_KERNEL) {
- Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
- OGR_G_AddPoint(Ogr_geometry, Points->x[0], Points->y[0],
- Points->z[0]);
-
- Ogr_feature = OGR_F_Create(Ogr_featuredefn);
-
- OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);
-
- /* Output one feature for each category */
- for (j = -1; j < Cats->n_cats; j++) {
- if (j == -1) {
- if (cat >= 0)
- continue; /* cat(s) exists */
- }
- else {
- if (Cats->field[j] == field)
- cat = Cats->cat[j];
- else
- continue;
- }
-
- mk_att(cat, Fi, Driver, ncol, colctype, colname, doatt, flags.nocat->answer,
- Ogr_feature, &noatt, &fout);
- OGR_L_CreateFeature(Ogr_layer, Ogr_feature);
- }
- OGR_G_DestroyGeometry(Ogr_geometry);
- OGR_F_Destroy(Ogr_feature);
- }
- }
- }
-
/*
- TODO: Volumes. Do not export kernels here, that's already done.
- We do need to worry about holes, though.
- NOTE: We can probably just merge this with faces export function.
- Except for GRASS, which output format would know the difference?
+ TODO: Volumes. Do not export kernels here, that's already done.
+ We do need to worry about holes, though. NOTE: We can probably
+ just merge this with faces export function. Except for GRASS,
+ which output format would know the difference?
*/
- if ((otype & GV_VOLUME)) {
- G_message(_("Exporting %i volumes..."), Vect_get_num_volumes(&In));
+ if (Vect_get_num_volumes(&In) > 0 && (otype & GV_VOLUME)) {
+ G_message(_("Exporting %d volumes..."), Vect_get_num_volumes(&In));
G_warning(_("Export of volumes not implemented yet. Skipping."));
}
@@ -948,26 +711,27 @@
}
/* Summary */
- if (nocat > 0)
- G_warning(_("%d features without category were written"), nocat);
- if (noatt > 0)
- G_warning(_("%d features without attributes were written"), noatt);
- if (nocatskip > 0)
+ if (n_nocat > 0)
+ G_important_message(_("%d features without category were written"), n_nocat);
+ if (n_noatt > 0)
+ G_important_message(_("%d features without attributes were written"), n_noatt);
+
+ if (n_nocatskip > 0)
G_warning(_("%d features without category were skipped. "
"Features without category are written only when -%c flag is given."),
- nocatskip, flags.cat->key);
+ n_nocatskip, flags.cat->key);
- /* Enable this? May be confusing that for area type are not reported
- * all boundaries/centroids.
- * OTOH why should be reported? */
+ /* Enable this? May be confusing that for area type are not
+ * reported all boundaries/centroids. OTOH why should be
+ * reported? */
/*
if (((otype & GV_POINTS) || (otype & GV_LINES)) && fskip > 0)
G_warning ("%d features of different type skip", fskip);
*/
- if (fout < 1)
+ if (n_feat < 1)
G_warning(_("Output layer is empty, no features written"));
- G_done_msg(_("%d features (%s type) written to <%s> (%s format)."), fout,
+ G_done_msg(_("%d features (%s type) written to <%s> (%s format)."), n_feat,
OGRGeometryTypeToName(wkbtype),
options.layer->answer, options.format->answer);
Modified: grass/trunk/vector/v.out.ogr/v.out.ogr.html
===================================================================
--- grass/trunk/vector/v.out.ogr/v.out.ogr.html 2013-12-11 20:21:50 UTC (rev 58446)
+++ grass/trunk/vector/v.out.ogr/v.out.ogr.html 2013-12-11 23:22:40 UTC (rev 58447)
@@ -1,67 +1,109 @@
<h2>DESCRIPTION</h2>
-<em>v.out.ogr</em> converts GRASS vector data to
-<a href="http://www.gdal.org/ogr/">OGR</a> format.
-OGR (Simple Features Library) is part of the
+<em>v.out.ogr</em> converts GRASS vector map layer to any of the
+supported <a href="http://www.gdal.org/ogr/">OGR</a> vector formats
+(like a Esri Shapefile, SpatiaLite or GML).
+
+<p>
+OGR (Simple Features Library) is part of the
<a href="http://www.gdal.org">GDAL</a> library, so you need to
-install gdal to use <em>v.out.ogr</em>.
+install this library to use <em>v.out.ogr</em>.
-<h3>Supported OGR Vector Formats</h3>
+<p>
+The OGR library supports many various formats including:
-<a href="http://www.gdal.org/ogr/drv_shapefile.html">ESRI Shapefile</a><br>
-<a href="http://www.gdal.org/ogr/drv_csv.html">CSV</a><br>
-<a href="http://www.gdal.org/ogr/drv_gml.html">GML</a><br>
-<a href="http://www.gdal.org/ogr/drv_kml.html">KML</a><br>
-<a href="http://www.gdal.org/ogr/drv_mitab.html">Mapinfo File</a><br>
-<a href="http://www.gdal.org/ogr/drv_pg.html">PostgreSQL/PostGIS</a><br>
-<a href="http://www.gdal.org/ogr/drv_tiger.html">TIGER</a>
+<ul>
+ <li><a href="http://www.gdal.org/ogr/drv_shapefile.html">ESRI Shapefile</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_pg.html">PostGIS</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_sqlite.html">SpatiaLite</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_csv.html">CSV</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_gml.html">GML</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_kml.html">KML</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_mitab.html">Mapinfo File</a></li>
+ <li><a href="http://www.gdal.org/ogr/drv_tiger.html">TIGER</a></li>
+ <li>... and many others</li>
+</ul>
<p>
-For further available drivers go
+For further available other supported formats go
<a href="http://www.gdal.org/ogr/ogr_formats.html">here</a>.
<h2>NOTES</h2>
-By default, islands will appear as holes inside surrounding areas.
-To export areas with holes into, e.g., a Shapefile, and make the
-holes appear as filled areas, the flag <em>-c</em> has to be used.
-<p>The "-z" flag can be used to automatically export a 3D map to a 3D Shapefile, instead
-of setting the correct <em>lco=</em> option manually.
+By default, islands will appear as holes inside surrounding areas. To
+export polygons with holes into, e.g., a Esri Shapefile, and make the
+holes appear as filled areas, the flag <b>-c</b> has to be used.
+<p>
+<em>v.out.ogr</em> exports 3D vector data as 2.5D simple features if
+possible (not supported by all formats). For exporting 3D vector data
+as 2D simple features, use <b>-2</b> flag.
+
+<p>
+By default, <em>v.out.ogr</em> converts GRASS vector data to single
+simple features. If GRASS features has more categories defined in
+given <b>layer</b>, then the features is exported several times. GRASS
+features without category are skipped by default. To export features
+also without category, the <b>-c</b> flag must be given.
+
+<p>
+When <b>-m</b> flag is given, <em>v.out.ogr</em> export GRASS vector
+data as multi-features based on their category(ies). Multi-feature is
+formed by GRASS features with the same category. When <b>-c</b> flag
+is given, the module also export GRASS features without category as
+one multi-feature. Note that multi-features are not supported by all
+formats.
+
<h2>EXAMPLES</h2>
-<h3>Export to Shapefile</h3>
+<h3>Export to Esri Shapefile</h3>
Export lines from GRASS vector map to Shapefile format:
+
<div class="code"><pre>
v.out.ogr input=lines type=line dsn=lines.shp
</pre></div>
-<p>Export areas from GRASS vector map to Shapefile format, converting
-islands (holes) to filled areas (generates /tmp/testogr.shp and related files):
+
+<p>
+Export areas from GRASS vector map to Shapefile format, converting
+islands (holes) to filled polygons:
+
<div class="code"><pre>
v.out.ogr -c input=areas_islands type=area dsn=areas_islands.shp
</pre></div>
-<p>Export 3D lines from GRASS vector map to Shapefile format:
+
+<p>
+Export 3D lines from GRASS vector map to Shapefile format:
+
<div class="code"><pre>
v.out.ogr input=lines_3d type=line dsn=lines_3d.shp lco="SHPT=ARCZ"
</pre></div>
-<p>Export 3D points (e.g., Lidar points) from GRASS vector map to Shapefile format
+
+<p>
+Export 3D points (e.g., Lidar points) from GRASS vector map to Shapefile format
+
<div class="code"><pre>
v.out.ogr points_3d type=point dsn=points_3d.shp lco="SHPT=POINTZ"
</pre></div>
-<p>Export 3D faces from GRASS vector map to Shapefile format:
+
+<p>
+Export 3D faces from GRASS vector map to Shapefile format:
<div class="code"><pre>
v.out.ogr input=objects_3d type=face dsn=faces_3d.shp lco="SHPT=POLYGONZ"
</pre></div>
-<p>Export 3D faces from GRASS vector map to Shapefile format, automatic 3D setting:
+
+<p>
+Export 3D faces from GRASS vector map to Shapefile format, automatic 3D setting:
+
<div class="code"><pre>
-v.out.ogr input=objects_3d type=face dsn=faces_3d.shp -z"
+v.out.ogr input=objects_3d type=face dsn=faces_3d.shp"
</pre></div>
<h3>Export to GML</h3>
Export lines from GRASS vector map to GML format
- (generates /tmp/testogr.gml file with layer 'testogr'):
+ (generates '/tmp/testogr.gml' file with layer 'testogr'):
+
<div class="code"><pre>
v.out.ogr input=multi type=line dsn=/tmp/testogr.gml olayer=testogr format=GML
</pre></div>
@@ -69,24 +111,29 @@
<h3>Export to PostgreSQL/PostGIS</h3>
Export areas from GRASS vector map directly to PostGIS:
+
<div class="code"><pre>
-v.out.ogr input=polygons type=area \
- dsn="PG:host=localhost dbname=postgis user=postgres" \
- olayer=polymap format=PostgreSQL
+v.out.ogr input=polygons type=area dsn="PG:host=localhost dbname=postgis user=postgres" olayer=polymap format=PostgreSQL
</pre></div>
+<i>Note:</i> For exporting GRASS vector data to PostGIS database
+should be used <em><a href="v.out.postgis.html">v.out.postgis</a></em>
+module. This module supports beside simple features also topological
+format PostGIS Topology.
+
<h3>Export to KML (Google Earth)</h3>
-<b>Example 1 (Latitude-Longitude location):</b><br>
+<p>
Export faces (3D vectors) from GRASS vector map to KML format for Google Earth:
+
<div class="code"><pre>
-v.out.ogr input=buildings_3d dsn=buildings_3d.kml olayer=buildings_3d \
- format=KML type=face
+v.out.ogr input=buildings_3d dsn=buildings_3d.kml olayer=buildings_3d format=KML type=face
</pre></div>
-<p><b>Example 2 (Latitude-Longitude location):</b><br>
+<p>
Generate and export GRASS vector "asteroid" map (faces, 3D vectors) to
- KML format for Google Earth:
+KML format for Google Earth:
+
<div class="code"><pre>
# near Raleigh (NC, USA)
g.region n=35.73952587 s=35.73279182 w=-78.68263928 e=-78.67499517
@@ -102,32 +149,35 @@
v.hull input=random3d output="random3d_hull"
# export to KML 3D
-v.out.ogr input=random3d_hull dsn=random3d_hull.kml format=KML \
- type=face dsco="AltitudeMode=absolute"
+v.out.ogr input=random3d_hull dsn=random3d_hull.kml format=KML type=face dsco="AltitudeMode=absolute"
# now open KML file 'random3d_hull.kml' in Google Earth or NASA WorldWind or ...
</pre></div>
-
<h2>REFERENCES</h2>
-<a href="http://www.gdal.org/ogr/">OGR vector library</a>
-<br>
-<a href="http://www.gdal.org/ogr/ogr__api_8h.html">OGR vector library C API</a>
-documentation
+<ul>
+<li><a href="http://www.gdal.org/ogr/">OGR vector library</a></li>
+<li><a href="http://www.gdal.org/ogr/ogr__api_8h.html">OGR vector library C API</a>
+ documentation</li>
+</ul>
-
<h2>SEE ALSO</h2>
<em>
+<a href="v.out.postgis.html">v.out.postgis</a>,
<a href="db.out.ogr.html">db.out.ogr</a>,
<a href="v.external.html">v.external</a>,
+<a href="v.external.out.html">v.external.out</a>,
<a href="v.in.ogr.html">v.in.ogr</a>
</em>
<h2>AUTHORS</h2>
Radim Blazek, ITC-Irst, Trento, Italy<br>
-Some contributions: Markus Neteler, Martin Landa
-<p><i>Last changed: $Date$</i>
+Some contributions: Markus Neteler<br>
+Multi-feature support by Martin Landa, Czech Technical University in Prague, 2013
+<p>
+<i>Last changed: $Date$</i>
+
More information about the grass-commit
mailing list