[GRASS-SVN] r71873 - grass/trunk/vector/v.out.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Nov 29 13:20:50 PST 2017
Author: mmetz
Date: 2017-11-29 13:20:50 -0800 (Wed, 29 Nov 2017)
New Revision: 71873
Modified:
grass/trunk/vector/v.out.ogr/export_areas.c
grass/trunk/vector/v.out.ogr/local_proto.h
grass/trunk/vector/v.out.ogr/main.c
Log:
v.out.ogr: adjust polygon ring orientation to match OGC specs except for known exceptions
Modified: grass/trunk/vector/v.out.ogr/export_areas.c
===================================================================
--- grass/trunk/vector/v.out.ogr/export_areas.c 2017-11-29 20:53:00 UTC (rev 71872)
+++ grass/trunk/vector/v.out.ogr/export_areas.c 2017-11-29 21:20:50 UTC (rev 71873)
@@ -6,20 +6,43 @@
OGRFeatureDefnH, OGRLayerH,
struct field_info *, dbDriver *, int, int *,
const char **, int, int,
- int *, 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 *);
+ int *, int *, int);
+static OGRGeometryH create_polygon(struct Map_info *, int, struct line_pnts *, int);
+/* maybe useful */
+void reverse_points(struct line_pnts *Points)
+{
+ int i, j, nhalf;
+ double tmp;
+
+ nhalf = Points->n_points / 2;
+
+ for (i = 0, j = Points->n_points - 1; i < nhalf; i++, j--) {
+ tmp = Points->x[i];
+ Points->x[i] = Points->x[j];
+ Points->x[j] = tmp;
+
+ tmp = Points->y[i];
+ Points->y[i] = Points->y[j];
+ Points->y[j] = tmp;
+
+ tmp = Points->z[i];
+ Points->z[i] = Points->z[j];
+ Points->z[j] = tmp;
+ }
+}
+
/* 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)
+ int *noatt, int *fout, int outer_ring_ccw)
{
if (multi)
/* export as multi-polygons */
@@ -27,21 +50,21 @@
Ogr_featuredefn, Ogr_layer,
Fi, driver, ncol, colctype,
colname, doatt, nocat,
- noatt, fout);
+ noatt, fout, outer_ring_ccw);
/* export as polygons */
return export_areas_single(In, field, donocat,
Ogr_featuredefn, Ogr_layer,
Fi, driver, ncol, colctype,
colname, doatt, nocat,
- noatt, fout);
+ noatt, fout, outer_ring_ccw);
}
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 *n_noatt, int *n_nocat, int outer_ring_ccw)
{
int i;
int cat, area, n_areas;
@@ -76,7 +99,7 @@
}
/* create polygon from area */
- Ogr_geometry = create_polygon(In, area, Points);
+ Ogr_geometry = create_polygon(In, area, Points, outer_ring_ccw);
/* add feature */
Ogr_feature = OGR_F_Create(Ogr_featuredefn);
@@ -116,7 +139,7 @@
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 *n_noatt, int *n_nocat, int outer_ring_ccw)
{
int i, n_exported, area;
int cat, ncats_field, line, type, findex, ipart;
@@ -183,7 +206,7 @@
continue;
/* create polygon from area */
- Ogr_geometry_part = create_polygon(In, area, Points);
+ Ogr_geometry_part = create_polygon(In, area, Points, outer_ring_ccw);
/* add part */
OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);
@@ -230,7 +253,7 @@
}
/* create polygon from area */
- Ogr_geometry_part = create_polygon(In, area, Points);
+ Ogr_geometry_part = create_polygon(In, area, Points, outer_ring_ccw);
/* add part */
OGR_G_AddGeometryDirectly(Ogr_geometry, Ogr_geometry_part);
@@ -268,7 +291,7 @@
}
OGRGeometryH create_polygon(struct Map_info *In, int area,
- struct line_pnts *Points)
+ struct line_pnts *Points, int outer_ring_ccw)
{
int j, k;
OGRGeometryH Ogr_geometry, ring;
@@ -279,29 +302,58 @@
ring = OGR_G_CreateGeometry(wkbLinearRing);
/* Area */
- for (j = 0; j < Points->n_points; j++) {
- if (Vect_is_3d(In))
- OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
- Points->z[j]);
- else
- OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]);
+ if (Vect_is_3d(In)) {
+ if (outer_ring_ccw) {
+ for (j = Points->n_points - 1; j >= 0 ; j--)
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+ else {
+ for (j = 0; j < Points->n_points; j++)
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
}
-
+ else {
+ if (outer_ring_ccw) {
+ for (j = Points->n_points - 1; j >= 0 ; j--)
+ OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]);
+ }
+ else {
+ for (j = 0; j < Points->n_points; j++)
+ OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[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++) {
- if(Vect_is_3d(In))
- OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
- Points->z[j]);
- else
- OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]);
- }
+ if (Vect_is_3d(In)) {
+ if (outer_ring_ccw) {
+ for (j = Points->n_points - 1; j >= 0 ; j--)
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+ else {
+ for (j = 0; j < Points->n_points; j++)
+ OGR_G_AddPoint(ring, Points->x[j], Points->y[j],
+ Points->z[j]);
+ }
+ }
+ else {
+ if (outer_ring_ccw) {
+ for (j = Points->n_points - 1; j >= 0 ; j--)
+ OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]);
+ }
+ else {
+ for (j = 0; j < Points->n_points; j++)
+ OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]);
+ }
+ }
OGR_G_AddGeometryDirectly(Ogr_geometry, ring);
}
Modified: grass/trunk/vector/v.out.ogr/local_proto.h
===================================================================
--- grass/trunk/vector/v.out.ogr/local_proto.h 2017-11-29 20:53:00 UTC (rev 71872)
+++ grass/trunk/vector/v.out.ogr/local_proto.h 2017-11-29 21:20:50 UTC (rev 71873)
@@ -73,4 +73,4 @@
OGRFeatureDefnH, OGRLayerH,
struct field_info *, dbDriver *, int, int *,
const char **, int, int,
- int *, int *);
+ int *, int *, int);
Modified: grass/trunk/vector/v.out.ogr/main.c
===================================================================
--- grass/trunk/vector/v.out.ogr/main.c 2017-11-29 20:53:00 UTC (rev 71872)
+++ grass/trunk/vector/v.out.ogr/main.c 2017-11-29 21:20:50 UTC (rev 71873)
@@ -74,6 +74,7 @@
char **papszDSCO = NULL, **papszLCO = NULL;
int num_types;
char *dsn;
+ int outer_ring_ccw;
G_gisinit(argv[0]);
@@ -262,7 +263,6 @@
if (cellhd.proj != PROJECTION_XY) {
const char *epsg;
- Ogr_projection = NULL;
/* try EPSG code first */
epsg = G_database_epsg_code();
if (!epsg) {
@@ -772,6 +772,19 @@
if (OGR_L_TestCapability(Ogr_layer, OLCTransactions))
OGR_L_StartTransaction(Ogr_layer);
+
+ /* export polygons oriented according to OGC simple features standard 1.2.1
+ * outer rings are oriented counter-clockwise (CCW)
+ * inner rings are oriented clockwise (CW) */
+ outer_ring_ccw = 1;
+ /* some formats expect outer rings to be CW and inner rings to be CCW:
+ * ESRI Shapefile, PGeo, FileGDB, OpenFileGDB (all ESRI) */
+ if (strcmp(options.format->answer, "ESRI Shapefile") == 0 ||
+ strcmp(options.format->answer, "PGeo") == 0 ||
+ strcmp(options.format->answer, "FileGDB") == 0 ||
+ strcmp(options.format->answer, "OpenFileGDB") == 0) {
+ outer_ring_ccw = 0;
+ }
/* Lines (run always to count features of different type) */
if (otype & (GV_POINTS | GV_LINES | GV_KERNEL | GV_FACE)) {
@@ -799,7 +812,7 @@
Ogr_featuredefn, Ogr_layer,
Fi, Driver, ncol, colctype,
colname, doatt, flags.nocat->answer ? TRUE : FALSE,
- &n_noatt, &n_nocat);
+ &n_noatt, &n_nocat, outer_ring_ccw);
}
/*
More information about the grass-commit
mailing list