[GRASS-SVN] r71532 - grass/trunk/vector/v.in.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Oct 6 07:47:29 PDT 2017
Author: mmetz
Date: 2017-10-06 07:47:29 -0700 (Fri, 06 Oct 2017)
New Revision: 71532
Modified:
grass/trunk/vector/v.in.ogr/main.c
Log:
v.in.ogr: fix spatial filter, use GDAL 2.2 API
Modified: grass/trunk/vector/v.in.ogr/main.c
===================================================================
--- grass/trunk/vector/v.in.ogr/main.c 2017-10-05 16:56:44 UTC (rev 71531)
+++ grass/trunk/vector/v.in.ogr/main.c 2017-10-06 14:47:29 UTC (rev 71532)
@@ -52,7 +52,11 @@
struct OGR_iterator
{
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetH *Ogr_ds;
+#else
OGRDataSourceH *Ogr_ds;
+#endif
char *dsn;
int nlayers;
int has_nonempty_layers;
@@ -61,13 +65,21 @@
OGRFeatureDefnH Ogr_featuredefn;
int requested_layer;
int curr_layer;
+ int done;
};
-void OGR_iterator_init(struct OGR_iterator *OGR_iter, OGRDataSourceH *Ogr_ds,
+void OGR_iterator_init(struct OGR_iterator *OGR_iter,
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetH *Ogr_ds,
+#else
+ OGRDataSourceH *Ogr_ds,
+#endif
char *dsn, int nlayers,
int ogr_interleaved_reading);
+
void OGR_iterator_reset(struct OGR_iterator *OGR_iter);
-OGRFeatureH ogr_getnextfeature(struct OGR_iterator *, int);
+OGRFeatureH ogr_getnextfeature(struct OGR_iterator *, int, char *,
+ OGRGeometryH , const char *);
int main(int argc, char *argv[])
{
@@ -111,19 +123,25 @@
int key_idx = -2; /* -1 for fid column */
/* OGR */
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetH Ogr_ds;
+#else
OGRDataSourceH Ogr_ds;
+#endif
const char *ogr_driver_name;
- int osm_interleaved_reading;
+ int ogr_interleaved_reading;
OGRLayerH Ogr_layer;
OGRFieldDefnH Ogr_field;
char *Ogr_fieldname;
OGRFieldType Ogr_ftype;
OGRFeatureH Ogr_feature;
OGRFeatureDefnH Ogr_featuredefn;
- OGRGeometryH Ogr_geometry, Ogr_oRing, poSpatialFilter;
+ OGRGeometryH Ogr_geometry, Ogr_oRing, *poSpatialFilter;
OGRSpatialReferenceH Ogr_projection;
OGREnvelope oExt;
- int have_ogr_extent = 0;
+ double *xminl, *yminl, *xmaxl, *ymaxl;
+ int *have_ogr_extent;
+ const char *attr_filter;
struct OGR_iterator OGR_iter;
int OFTIntegerListlength;
@@ -146,9 +164,11 @@
int ncentr, n_overlaps;
struct bound_box box;
- xmin = ymin = xmax = ymax = 0.0;
+ xmin = ymin = 1.0;
+ xmax = ymax = 0.0;
loc_proj_info = loc_proj_units = NULL;
- Ogr_ds = Ogr_oRing = poSpatialFilter = NULL;
+ Ogr_ds = NULL;
+ Ogr_oRing = poSpatialFilter = NULL;
OFTIntegerListlength = 255; /* hack due to limitation in OGR */
area_size = 0.0;
use_tmp_vect = FALSE;
@@ -350,8 +370,14 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
+#if GDAL_VERSION_NUM >= 2000000
+ GDALAllRegister();
+#else
OGRRegisterAll();
+#endif
+ G_debug(1, "GDAL version %d", GDAL_VERSION_NUM);
+
/* list supported formats */
if (flag.formats->answer) {
int iDriver;
@@ -449,37 +475,62 @@
/* open OGR DSN */
Ogr_ds = NULL;
- if (strlen(dsn) > 0)
+ if (strlen(dsn) > 0) {
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_ds = GDALOpenEx(dsn, GDAL_OF_VECTOR, NULL, NULL, NULL);
+#else
Ogr_ds = OGROpen(dsn, FALSE, NULL);
+#endif
+ }
if (Ogr_ds == NULL)
G_fatal_error(_("Unable to open data source <%s>"), dsn);
/* driver name */
+#if GDAL_VERSION_NUM >= 2020000
+ ogr_driver_name = GDALGetDriverShortName(GDALGetDatasetDriver(Ogr_ds));
+ G_verbose_message(_("Using OGR driver '%s': %s"), ogr_driver_name,
+ GDALGetDriverLongName(GDALGetDatasetDriver(Ogr_ds)));
+#else
ogr_driver_name = OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds));
G_verbose_message(_("Using OGR driver '%s'"), ogr_driver_name);
+#endif
/* OSM interleaved reading */
- osm_interleaved_reading = 0;
+ ogr_interleaved_reading = 0;
if (strcmp(ogr_driver_name, "OSM") == 0) {
+ /* re-open OGR DSN */
+#if GDAL_VERSION_NUM < 2020000
CPLSetConfigOption("OGR_INTERLEAVED_READING", "YES");
- /* re-open OGR DSN */
OGR_DS_Destroy(Ogr_ds);
Ogr_ds = OGROpen(dsn, FALSE, NULL);
- osm_interleaved_reading = 1;
+#endif
+ ogr_interleaved_reading = 1;
}
- if (osm_interleaved_reading)
- G_verbose_message(_("Using OSM interleaved reading"));
+ if (strcmp(ogr_driver_name, "GMLAS") == 0)
+ ogr_interleaved_reading = 1;
+ if (ogr_interleaved_reading)
+ G_verbose_message(_("Using interleaved reading mode"));
+#if GDAL_VERSION_NUM >= 2020000
+ navailable_layers = GDALDatasetGetLayerCount(Ogr_ds);
+#else
navailable_layers = OGR_DS_GetLayerCount(Ogr_ds);
+#endif
OGR_iterator_init(&OGR_iter, &Ogr_ds, dsn, navailable_layers,
- osm_interleaved_reading);
+ ogr_interleaved_reading);
if (param.geom->answer) {
#if GDAL_VERSION_NUM >= 1110000
+#if GDAL_VERSION_NUM >= 2020000
+ if (!GDALDatasetTestCapability(Ogr_ds, ODsCCreateGeomFieldAfterCreateLayer)) {
+ G_warning(_("Option <%s> will be ignored. OGR doesn't support it for selected format (%s)."),
+ param.geom->key, ogr_driver_name);
+#else
if (!OGR_DS_TestCapability(Ogr_ds, ODsCCreateGeomFieldAfterCreateLayer)) {
G_warning(_("Option <%s> will be ignored. OGR doesn't support it for selected format (%s)."),
- param.geom->key, OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)));
+ param.geom->key, ogr_driver_name);
+#endif
param.geom->answer = NULL;
}
#else
@@ -497,16 +548,19 @@
}
/* make a list of available layers */
- navailable_layers = OGR_DS_GetLayerCount(Ogr_ds);
available_layer_names =
(char **)G_malloc(navailable_layers * sizeof(char *));
- if (flag.list->answer)
+ if (flag.list->answer) {
G_message(_("Data source <%s> (format '%s') contains %d layers:"),
- dsn,
- OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)), navailable_layers);
+ dsn, ogr_driver_name, navailable_layers);
+ }
for (i = 0; i < navailable_layers; i++) {
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, i);
+#else
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
+#endif
Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
available_layer_names[i] =
@@ -517,7 +571,11 @@
}
if (flag.list->answer) {
fflush(stdout);
+#if GDAL_VERSION_NUM >= 2020000
+ GDALClose(Ogr_ds);
+#else
OGR_DS_Destroy(Ogr_ds);
+#endif
exit(EXIT_SUCCESS);
}
@@ -574,7 +632,11 @@
}
/* Get first imported layer to use for projection check */
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, layers[0]);
+#else
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[0]);
+#endif
/* projection check must come before extents check */
/* Fetch input map projection in GRASS form. */
@@ -600,28 +662,39 @@
#endif
/* fetch boundaries */
+ have_ogr_extent = (int *)G_malloc(nlayers * sizeof(int));
+ xminl = (double *)G_malloc(nlayers * sizeof(double));
+ xmaxl = (double *)G_malloc(nlayers * sizeof(double));
+ yminl = (double *)G_malloc(nlayers * sizeof(double));
+ ymaxl = (double *)G_malloc(nlayers * sizeof(double));
for (layer = 0; layer < nlayers; layer++) {
+
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, layers[layer]);
+#else
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[layer]);
+#endif
+ have_ogr_extent[layer] = 0;
if ((OGR_L_GetExtent(Ogr_layer, &oExt, 1)) == OGRERR_NONE) {
- if (!have_ogr_extent) {
- ymax = oExt.MaxY;
- ymin = oExt.MinY;
- xmin = oExt.MinX;
- xmax = oExt.MaxX;
- }
- else {
- ymax = MAX(ymax, oExt.MaxY);
- ymin = MIN(ymin, oExt.MinY);
- xmin = MIN(xmin, oExt.MinX);
- xmax = MAX(xmax, oExt.MaxX);
- }
+ xminl[layer] = oExt.MinX;
+ xmaxl[layer] = oExt.MaxX;
+ yminl[layer] = oExt.MinY;
+ ymaxl[layer] = oExt.MaxY;
/* use OGR extents if possible, needed to skip corrupted data
* in OGR dsn/layer */
- have_ogr_extent = 1;
+ have_ogr_extent[layer] = 1;
}
+ /* OGR_L_GetExtent():
+ * Note that some implementations of this method may alter
+ * the read cursor of the layer. */
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetResetReading(Ogr_ds);
+#else
+ OGR_L_ResetReading(Ogr_layer);
+#endif
}
-
+
G_get_window(&cellhd);
cellhd.north = 1.;
cellhd.south = 0.;
@@ -663,7 +736,11 @@
/* If the i flag is set, clean up and exit here */
if (flag.no_import->answer) {
+#if GDAL_VERSION_NUM >= 2020000
+ GDALClose(Ogr_ds);
+#else
OGR_DS_Destroy(Ogr_ds);
+#endif
exit(EXIT_SUCCESS);
}
}
@@ -793,36 +870,12 @@
G_fatal_error(_("Select either the current region flag or the spatial option, not both"));
if (!param.outloc->answer && flag.region->answer) {
G_get_window(&cur_wind);
- if (have_ogr_extent) {
- /* check for any overlap */
- if (cur_wind.west > xmax || cur_wind.east < xmin ||
- cur_wind.south > ymax || cur_wind.north < ymin) {
- G_warning(_("The current region does not overlap with OGR input. Nothing to import."));
- OGR_DS_Destroy(Ogr_ds);
- exit(EXIT_SUCCESS);
- }
- if (xmin < cur_wind.west)
- xmin = cur_wind.west;
- if (xmax > cur_wind.east)
- xmax = cur_wind.east;
- if (ymin < cur_wind.south)
- ymin = cur_wind.south;
- if (ymax > cur_wind.north)
- ymax = cur_wind.north;
- }
- else {
- xmin = cur_wind.west;
- xmax = cur_wind.east;
- ymin = cur_wind.south;
- ymax = cur_wind.north;
- }
+ xmin = cur_wind.west;
+ xmax = cur_wind.east;
+ ymin = cur_wind.south;
+ ymax = cur_wind.north;
}
if (param.spat->answer) {
- double spatxmin = xmin,
- spatxmax = xmax,
- spatymin = ymin,
- spatymax = ymax;
-
/* See as reference: gdal/ogr/ogr_capi_test.c */
/* cut out a piece of the map */
@@ -830,13 +883,13 @@
i = 0;
while (param.spat->answers[i]) {
if (i == 0)
- spatxmin = atof(param.spat->answers[i]);
+ xmin = atof(param.spat->answers[i]);
if (i == 1)
- spatymin = atof(param.spat->answers[i]);
+ ymin = atof(param.spat->answers[i]);
if (i == 2)
- spatxmax = atof(param.spat->answers[i]);
+ xmax = atof(param.spat->answers[i]);
if (i == 3)
- spatymax = atof(param.spat->answers[i]);
+ ymax = atof(param.spat->answers[i]);
i++;
}
if (i != 4)
@@ -845,63 +898,108 @@
G_fatal_error(_("xmin is larger than xmax in 'spatial' parameters"));
if (ymin > ymax)
G_fatal_error(_("ymin is larger than ymax in 'spatial' parameters"));
-
- if (have_ogr_extent) {
- /* check for any overlap */
- if (spatxmin > xmax || spatxmax < xmin ||
- spatymin > ymax || spatymax < ymin) {
- G_warning(_("The 'spatial' parameters do not overlap with OGR input. Nothing to import."));
- OGR_DS_Destroy(Ogr_ds);
- exit(EXIT_SUCCESS);
- }
- if (xmin < spatxmin)
- xmin = spatxmin;
- if (ymin < spatymin)
- ymin = spatymin;
- if (xmax > spatxmax)
- xmax = spatxmax;
- if (ymax > spatymax)
- ymax = spatymax;
- }
- else {
- xmin = spatxmin;
- ymin = spatymin;
- xmax = spatxmax;
- ymax = spatymax;
- }
}
if ((!param.outloc->answer && flag.region->answer) ||
- param.spat->answer || have_ogr_extent) {
+ param.spat->answer) {
G_debug(2, "cut out with boundaries: xmin:%f ymin:%f xmax:%f ymax:%f",
xmin, ymin, xmax, ymax);
+ }
- /* in theory this could be an irregular polygon */
- poSpatialFilter = OGR_G_CreateGeometry(wkbPolygon);
- Ogr_oRing = OGR_G_CreateGeometry(wkbLinearRing);
- OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0);
- OGR_G_AddPoint(Ogr_oRing, xmin, ymax, 0.0);
- OGR_G_AddPoint(Ogr_oRing, xmax, ymax, 0.0);
- OGR_G_AddPoint(Ogr_oRing, xmax, ymin, 0.0);
- OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0);
- OGR_G_AddGeometryDirectly(poSpatialFilter, Ogr_oRing);
+ /* spatial filter, set by ogr_getnextfeature */
+ poSpatialFilter = G_malloc(nlayers * sizeof(OGRGeometryH));
+ for (layer = 0; layer < nlayers; layer++) {
+ int have_filter = 0;
- for (layer = 0; layer < nlayers; layer++) {
- Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[layer]);
- OGR_L_SetSpatialFilter(Ogr_layer, poSpatialFilter);
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, layers[layer]);
+#else
+ Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[layer]);
+#endif
+
+ if (have_ogr_extent[layer]) {
+ if (xmin <= xmax && ymin <= ymax) {
+ /* check for any overlap */
+ if (xminl[layer] > xmax || xmaxl[layer] < xmin ||
+ yminl[layer] > ymax || ymaxl[layer] < ymin) {
+ G_warning(_("The spatial filter does not overlap with OGR layer <%s>. Nothing to import."),
+ layer_names[layer]);
+
+ xminl[layer] = xmin;
+ xmaxl[layer] = xmax;
+ yminl[layer] = ymin;
+ ymaxl[layer] = ymax;
+ }
+ else {
+ /* shrink with user options */
+ xminl[layer] = MAX(xminl[layer], xmin);
+ xmaxl[layer] = MIN(xmaxl[layer], xmax);
+ yminl[layer] = MAX(yminl[layer], ymin);
+ ymaxl[layer] = MIN(ymaxl[layer], ymax);
+ }
+ }
+ have_filter = 1;
}
- }
+ else if (xmin <= xmax && ymin <= ymax) {
+ xminl[layer] = xmin;
+ xmaxl[layer] = xmax;
+ yminl[layer] = ymin;
+ ymaxl[layer] = ymax;
- if (param.where->answer) {
- /* select by attribute */
- for (layer = 0; layer < nlayers; layer++) {
- Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[layer]);
- OGR_L_SetAttributeFilter(Ogr_layer, param.where->answer);
+ have_filter = 1;
}
+
+ if (have_filter) {
+ /* some invalid features can be filtered out by using
+ * the layer's extents as spatial filter
+ * hopefully these filtered features are all invalid */
+ /* TODO/BUG:
+ * for OSM, a spatial filter applied on the 'points' layer
+ * will also affect other layers */
+
+ /* in theory this could be an irregular polygon */
+ G_debug(2, "spatial filter for layer <%s>: xmin:%f ymin:%f xmax:%f ymax:%f",
+ layer_names[layer],
+ xminl[layer], yminl[layer],
+ xmaxl[layer], ymaxl[layer]);
+
+ poSpatialFilter[layer] = OGR_G_CreateGeometry(wkbPolygon);
+ Ogr_oRing = OGR_G_CreateGeometry(wkbLinearRing);
+ OGR_G_AddPoint_2D(Ogr_oRing, xminl[layer], yminl[layer]);
+ OGR_G_AddPoint_2D(Ogr_oRing, xminl[layer], ymaxl[layer]);
+ OGR_G_AddPoint_2D(Ogr_oRing, xmaxl[layer], ymaxl[layer]);
+ OGR_G_AddPoint_2D(Ogr_oRing, xmaxl[layer], yminl[layer]);
+ OGR_G_AddPoint_2D(Ogr_oRing, xminl[layer], yminl[layer]);
+ OGR_G_AddGeometryDirectly(poSpatialFilter[layer], Ogr_oRing);
+ }
+ else
+ poSpatialFilter[layer] = NULL;
}
+ /* update xmin, xmax, ymin, ymax if possible */
+ for (layer = 0; layer < nlayers; layer++) {
+ if (have_ogr_extent[layer]) {
+ if (xmin > xmax) {
+ xmin = xminl[layer];
+ xmax = xmaxl[layer];
+ ymin = yminl[layer];
+ ymax = ymaxl[layer];
+ }
+ else {
+ /* expand */
+ xmin = MIN(xminl[layer], xmin);
+ xmax = MAX(xmaxl[layer], xmax);
+ ymin = MIN(yminl[layer], ymin);
+ ymax = MAX(ymaxl[layer], ymax);
+ }
+ }
+ }
+ /* attribute filter, set by ogr_getnextfeature */
+ attr_filter = param.where->answer;
+
/* suppress boundary splitting ? */
- if (flag.no_clean->answer || !have_ogr_extent) {
+ if (flag.no_clean->answer || xmin >= xmax || ymin >= ymax) {
split_distance = -1.;
+ area_size = -1;
}
else {
split_distance = 0.;
@@ -922,7 +1020,11 @@
layer_id = layers[layer];
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, layer_id);
+#else
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
+#endif
Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
igeom = -1;
#if GDAL_VERSION_NUM >= 1110000
@@ -942,12 +1044,12 @@
n_features[layer_id] = ogr_feature_count;
/* count polygons and isles */
- if (!osm_interleaved_reading) {
- OGR_L_ResetReading(Ogr_layer);
- }
G_message(_("Check if OGR layer <%s> contains polygons..."),
layer_names[layer]);
- while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id)) != NULL) {
+ while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id,
+ layer_names[layer],
+ poSpatialFilter[layer],
+ attr_filter)) != NULL) {
if (ogr_feature_count > 0)
G_percent(feature_count++, n_features[layer], 1); /* show something happens */
@@ -994,7 +1096,7 @@
G_message("Importing %lld features", n_import_features);
G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries);
- if (have_ogr_extent && n_polygon_boundaries > 50) {
+ if (area_size > 0 && n_polygon_boundaries > 50) {
split_distance =
area_size / log(n_polygon_boundaries);
/* divisor is the handle: increase divisor to decrease split_distance */
@@ -1048,7 +1150,11 @@
for (layer = 0; layer < nlayers; layer++) {
layer_id = layers[layer];
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, layer_id);
+#else
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
+#endif
Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
igeom = -1;
@@ -1269,7 +1375,10 @@
G_important_message(_("Importing %lld features (OGR layer <%s>)..."),
n_features[layer], layer_names[layer]);
- while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id)) != NULL) {
+ while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id,
+ layer_names[layer],
+ poSpatialFilter[layer],
+ attr_filter)) != NULL) {
G_percent(feature_count++, n_features[layer], 1); /* show something happens */
/* Geometry */
@@ -1554,7 +1663,11 @@
G_message("%s", separator);
G_message(_("Finding centroids for OGR layer <%s>..."), layer_names[layer]);
layer_id = layers[layer];
+#if GDAL_VERSION_NUM >= 2020000
+ Ogr_layer = GDALDatasetGetLayer(Ogr_ds, layer_id);
+#else
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
+#endif
Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
igeom = -1;
@@ -1563,10 +1676,11 @@
igeom = OGR_FD_GetGeomFieldIndex(Ogr_featuredefn, param.geom->answer);
#endif
- OGR_L_ResetReading(Ogr_layer);
-
cat = 0; /* field = layer + 1 */
- while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id)) != NULL) {
+ while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id,
+ layer_names[layer],
+ poSpatialFilter[layer],
+ attr_filter)) != NULL) {
G_percent(cat, n_features[layer], 2);
/* Category */
@@ -1687,7 +1801,11 @@
G_message("%s", separator);
}
+#if GDAL_VERSION_NUM >= 2020000
+ GDALClose(Ogr_ds);
+#else
OGR_DS_Destroy(Ogr_ds);
+#endif
if (use_tmp_vect) {
/* Copy temporary vector to output vector */
@@ -1863,7 +1981,12 @@
exit(EXIT_SUCCESS);
}
-void OGR_iterator_init(struct OGR_iterator *OGR_iter, OGRDataSourceH *Ogr_ds,
+void OGR_iterator_init(struct OGR_iterator *OGR_iter,
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetH *Ogr_ds,
+#else
+ OGRDataSourceH *Ogr_ds,
+#endif
char *dsn, int nlayers,
int ogr_interleaved_reading)
{
@@ -1875,90 +1998,149 @@
OGR_iter->curr_layer = -1;
OGR_iter->Ogr_layer = NULL;
OGR_iter->has_nonempty_layers = 0;
+ OGR_iter->done = 0;
+
+ if (OGR_iter->ogr_interleaved_reading) {
+#if GDAL_VERSION_NUM >= 2020000
+ G_verbose_message(_("Using GDAL 2.2+ style interleaved reading for GDAL version %d"),
+ GDAL_VERSION_NUM);
+#else
+ G_verbose_message(_("Using GDAL 1.x style interleaved reading for GDAL version %d"),
+ GDAL_VERSION_NUM);
+#endif
+ }
}
void OGR_iterator_reset(struct OGR_iterator *OGR_iter)
{
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetResetReading(*(OGR_iter->Ogr_ds));
+#endif
OGR_iter->requested_layer = -1;
OGR_iter->curr_layer = -1;
OGR_iter->Ogr_layer = NULL;
OGR_iter->has_nonempty_layers = 0;
+ OGR_iter->done = 0;
}
-OGRFeatureH ogr_getnextfeature(struct OGR_iterator *OGR_iter, int layer)
+OGRFeatureH ogr_getnextfeature(struct OGR_iterator *OGR_iter,
+ int layer, char *layer_name,
+ OGRGeometryH poSpatialFilter,
+ const char *attr_filter)
{
if (OGR_iter->requested_layer != layer) {
+ int i;
+
+ /* clear filters */
+ for (i = 0; i < OGR_iter->nlayers; i++) {
+#if GDAL_VERSION_NUM >= 2020000
+ OGR_iter->Ogr_layer = GDALDatasetGetLayer(*(OGR_iter->Ogr_ds), i);
+#else
+ OGR_iter->Ogr_layer = OGR_DS_GetLayer(*(OGR_iter->Ogr_ds), i);
+#endif
+ OGR_L_SetSpatialFilter(OGR_iter->Ogr_layer, NULL);
+ OGR_L_SetAttributeFilter(OGR_iter->Ogr_layer, NULL);
+ }
+
/* reset OGR reading */
if (!OGR_iter->ogr_interleaved_reading) {
OGR_iter->curr_layer = layer;
+#if GDAL_VERSION_NUM >= 2020000
+ OGR_iter->Ogr_layer = GDALDatasetGetLayer(*(OGR_iter->Ogr_ds), OGR_iter->curr_layer);
+#else
OGR_iter->Ogr_layer = OGR_DS_GetLayer(*(OGR_iter->Ogr_ds), OGR_iter->curr_layer);
+#endif
OGR_iter->Ogr_featuredefn = OGR_L_GetLayerDefn(OGR_iter->Ogr_layer);
OGR_L_ResetReading(OGR_iter->Ogr_layer);
+ OGR_L_SetSpatialFilter(OGR_iter->Ogr_layer, poSpatialFilter);
+ OGR_L_SetAttributeFilter(OGR_iter->Ogr_layer, attr_filter);
}
else {
+#if GDAL_VERSION_NUM >= 2020000
+ GDALDatasetResetReading(*(OGR_iter->Ogr_ds));
+ OGR_iter->curr_layer = 0;
+ OGR_iter->Ogr_layer = GDALDatasetGetLayer(*(OGR_iter->Ogr_ds), layer);
+ OGR_iter->Ogr_featuredefn = OGR_L_GetLayerDefn(OGR_iter->Ogr_layer);
+ OGR_L_SetSpatialFilter(OGR_iter->Ogr_layer, poSpatialFilter);
+ OGR_L_SetAttributeFilter(OGR_iter->Ogr_layer, attr_filter);
+#else
/* need to re-open OGR DSN in order to start reading from the beginning
* NOTE: any constraints are lost */
OGR_DS_Destroy(*(OGR_iter->Ogr_ds));
*(OGR_iter->Ogr_ds) = OGROpen(OGR_iter->dsn, FALSE, NULL);
if (*(OGR_iter->Ogr_ds) == NULL)
G_fatal_error(_("Unable to re-open data source <%s>"), OGR_iter->dsn);
+ OGR_iter->Ogr_layer = OGR_DS_GetLayer(*(OGR_iter->Ogr_ds), layer);
+ OGR_L_SetSpatialFilter(OGR_iter->Ogr_layer, poSpatialFilter);
+ OGR_L_SetAttributeFilter(OGR_iter->Ogr_layer, attr_filter);
OGR_iter->curr_layer = 0;
OGR_iter->Ogr_layer = OGR_DS_GetLayer(*(OGR_iter->Ogr_ds), OGR_iter->curr_layer);
OGR_iter->Ogr_featuredefn = OGR_L_GetLayerDefn(OGR_iter->Ogr_layer);
OGR_iter->has_nonempty_layers = 0;
+#endif
}
OGR_iter->requested_layer = layer;
+ OGR_iter->done = 0;
}
- if (OGR_iter->Ogr_layer == NULL)
+ if (OGR_iter->done == 1)
return NULL;
if (!OGR_iter->ogr_interleaved_reading) {
OGRFeatureH Ogr_feature;
Ogr_feature = OGR_L_GetNextFeature(OGR_iter->Ogr_layer);
- if (Ogr_feature == NULL)
+ if (Ogr_feature == NULL) {
OGR_iter->Ogr_layer = NULL;
+ OGR_iter->done = 1;
+ }
return Ogr_feature;
}
else {
- OGRFeatureH Ogr_feature;
+ OGRFeatureH Ogr_feature = NULL;
/* fetch next feature */
+#if GDAL_VERSION_NUM >= 2020000
while (1) {
- while (OGR_iter->curr_layer != layer) {
- while ((Ogr_feature = OGR_L_GetNextFeature(OGR_iter->Ogr_layer)) != NULL) {
- OGR_iter->has_nonempty_layers = 1;
- OGR_F_Destroy(Ogr_feature);
- }
- OGR_iter->curr_layer++;
- if (OGR_iter->curr_layer == OGR_iter->nlayers) {
- if (!OGR_iter->has_nonempty_layers) {
- OGR_iter->Ogr_layer = NULL;
+ OGR_iter->Ogr_layer = NULL;
+ Ogr_feature = GDALDatasetGetNextFeature(*(OGR_iter->Ogr_ds),
+ &(OGR_iter->Ogr_layer),
+ NULL, NULL, NULL);
- return NULL;
- }
- else {
- OGR_iter->curr_layer = 0;
- OGR_iter->has_nonempty_layers = 0;
- }
+ if (Ogr_feature == NULL) {
+ OGR_iter->Ogr_layer = NULL;
+ OGR_iter->done = 1;
+
+ return Ogr_feature;
+ }
+ if (OGR_iter->Ogr_layer != NULL) {
+ const char *ln = OGR_L_GetName(OGR_iter->Ogr_layer);
+
+ if (ln && *ln && strcmp(ln, layer_name) == 0) {
+
+ return Ogr_feature;
}
- G_debug(3, "advancing to layer %d ...", OGR_iter->curr_layer);
- OGR_iter->Ogr_layer = OGR_DS_GetLayer(*(OGR_iter->Ogr_ds), OGR_iter->curr_layer);
- OGR_iter->Ogr_featuredefn = OGR_L_GetLayerDefn(OGR_iter->Ogr_layer);
}
+ OGR_F_Destroy(Ogr_feature);
+ OGR_iter->Ogr_layer = NULL;
+ }
+#else
+ while (1) {
Ogr_feature = OGR_L_GetNextFeature(OGR_iter->Ogr_layer);
if (Ogr_feature != NULL) {
OGR_iter->has_nonempty_layers = 1;
-
- return Ogr_feature;
+ if (OGR_iter->curr_layer != layer)
+ OGR_F_Destroy(Ogr_feature);
+ else
+ return Ogr_feature;
}
else {
OGR_iter->curr_layer++;
if (OGR_iter->curr_layer == OGR_iter->nlayers) {
if (!OGR_iter->has_nonempty_layers) {
OGR_iter->Ogr_layer = NULL;
+ OGR_iter->done = 1;
return NULL;
}
@@ -1972,6 +2154,7 @@
OGR_iter->Ogr_featuredefn = OGR_L_GetLayerDefn(OGR_iter->Ogr_layer);
}
}
+#endif
}
return NULL;
More information about the grass-commit
mailing list