[GRASS-SVN] r71464 - grass/trunk/vector/v.in.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Sep 4 11:15:16 PDT 2017
Author: mmetz
Date: 2017-09-04 11:15:15 -0700 (Mon, 04 Sep 2017)
New Revision: 71464
Modified:
grass/trunk/vector/v.in.ogr/main.c
Log:
v.in.ogr: use interleaved reading for OSM
Modified: grass/trunk/vector/v.in.ogr/main.c
===================================================================
--- grass/trunk/vector/v.in.ogr/main.c 2017-09-03 02:14:01 UTC (rev 71463)
+++ grass/trunk/vector/v.in.ogr/main.c 2017-09-04 18:15:15 UTC (rev 71464)
@@ -29,6 +29,7 @@
#include <grass/glocale.h>
#include <gdal_version.h> /* needed for OFTDate */
#include "ogr_api.h"
+#include "cpl_conv.h"
#include "global.h"
#ifndef MAX
@@ -48,6 +49,25 @@
char *get_datasource_name(const char *, int);
+struct OGR_iterator
+{
+ OGRDataSourceH *Ogr_ds;
+ char *dsn;
+ int nlayers;
+ int has_nonempty_layers;
+ int ogr_interleaved_reading;
+ OGRLayerH Ogr_layer;
+ OGRFeatureDefnH Ogr_featuredefn;
+ int requested_layer;
+ int curr_layer;
+};
+
+void OGR_iterator_init(struct OGR_iterator *OGR_iter, OGRDataSourceH *Ogr_ds,
+ char *dsn, int nlayers,
+ int ogr_interleaved_reading);
+void OGR_iterator_reset(struct OGR_iterator *OGR_iter);
+OGRFeatureH ogr_getnextfeature(struct OGR_iterator *, int);
+
int main(int argc, char *argv[])
{
struct GModule *module;
@@ -92,6 +112,7 @@
/* OGR */
OGRDataSourceH Ogr_ds;
const char *ogr_driver_name;
+ int osm_interleaved_reading;
OGRLayerH Ogr_layer;
OGRFieldDefnH Ogr_field;
char *Ogr_fieldname;
@@ -102,6 +123,7 @@
OGRSpatialReferenceH Ogr_projection;
OGREnvelope oExt;
int have_ogr_extent = 0;
+ struct OGR_iterator OGR_iter;
int OFTIntegerListlength;
@@ -115,7 +137,8 @@
char **available_layer_names; /* names of layers to be imported */
int navailable_layers;
int layer_id;
- unsigned int n_features, feature_count;
+ unsigned int feature_count;
+ GIntBig *n_features, n_import_features;
int overwrite;
double area_size;
int use_tmp_vect;
@@ -408,14 +431,27 @@
if (Ogr_ds == NULL)
G_fatal_error(_("Unable to open data source <%s>"), dsn);
+ /* driver name */
ogr_driver_name = OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds));
+ G_verbose_message(_("Using OGR driver '%s'"), ogr_driver_name);
+
+ /* OSM interleaved reading */
+ osm_interleaved_reading = 0;
if (strcmp(ogr_driver_name, "OSM") == 0) {
+
+ CPLSetConfigOption("OGR_INTERLEAVED_READING", "YES");
+ /* re-open OGR DSN */
OGR_DS_Destroy(Ogr_ds);
- G_warning(_("OpenStreetMap import can result in missing features. "
- "Please use ogr2ogr first to convert to a different format."));
- G_fatal_error(_("OSM import cancelled."));
+ Ogr_ds = OGROpen(dsn, FALSE, NULL);
+ osm_interleaved_reading = 1;
}
+ if (osm_interleaved_reading)
+ G_verbose_message(_("Using OSM interleaved reading"));
+ navailable_layers = OGR_DS_GetLayerCount(Ogr_ds);
+ OGR_iterator_init(&OGR_iter, &Ogr_ds, dsn, navailable_layers,
+ osm_interleaved_reading);
+
if (param.geom->answer) {
#if GDAL_VERSION_NUM >= 1110000
if (!OGR_DS_TestCapability(Ogr_ds, ODsCCreateGeomFieldAfterCreateLayer)) {
@@ -492,6 +528,10 @@
for (i = 0; i < nlayers; i++)
layers[i] = i;
}
+ n_features = (GIntBig *)G_malloc(nlayers * sizeof(GIntBig));
+ for (i = 0; i < nlayers; i++) {
+ n_features[i] = 0;
+ }
if (param.out->answer) {
output = G_store(param.out->answer);
@@ -850,7 +890,10 @@
/* check if input id 3D and if we need a tmp vector */
/* estimate distance for boundary splitting --> */
+ OGR_iterator_reset(&OGR_iter);
for (layer = 0; layer < nlayers; layer++) {
+ GIntBig ogr_feature_count;
+
layer_id = layers[layer];
Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
@@ -864,19 +907,30 @@
param.geom->answer, OGR_L_GetName(Ogr_layer));
}
#endif
- n_features = feature_count = 0;
+ feature_count = 0;
- n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
- OGR_L_ResetReading(Ogr_layer);
+ ogr_feature_count = 0;
+ if (n_features[layer_id] == 0)
+ ogr_feature_count = OGR_L_GetFeatureCount(Ogr_layer, 1);
+ if (ogr_feature_count > 0)
+ 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_L_GetNextFeature(Ogr_layer)) != NULL) {
- G_percent(feature_count++, n_features, 1); /* show something happens */
+ while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id)) != NULL) {
+ if (ogr_feature_count > 0)
+ G_percent(feature_count++, n_features[layer], 1); /* show something happens */
+ if (ogr_feature_count <= 0)
+ n_features[layer]++;
+
/* Geometry */
#if GDAL_VERSION_NUM >= 1110000
+ Ogr_featuredefn = OGR_iter.Ogr_featuredefn;
for (i = 0; i < OGR_FD_GetGeomFieldCount(Ogr_featuredefn); i++) {
if (igeom > -1 && i != igeom)
continue; /* use only geometry defined via param.geom */
@@ -899,6 +953,11 @@
G_percent(1, 1, 1);
}
+ n_import_features = 0;
+ for (i = 0; i < nlayers; i++)
+ n_import_features += n_features[i];
+ G_message("Importing %lld features", n_import_features);
+
G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries);
if (n_polygon_boundaries > 50) {
split_distance =
@@ -946,10 +1005,11 @@
ncentr = n_overlaps = n_polygons = 0;
/* Points and lines are written immediately with categories. Boundaries of polygons are
- * written to the vector then cleaned and centroids are calculated for all areas in cleaan vector.
+ * written to the vector then cleaned and centroids are calculated for all areas in clean vector.
* Then second pass through finds all centroids in each polygon feature and adds its category
* to the centroid. The result is that one centroids may have 0, 1 ore more categories
* of one ore more (more input layers) fields. */
+ OGR_iterator_reset(&OGR_iter);
for (layer = 0; layer < nlayers; layer++) {
layer_id = layers[layer];
@@ -1171,16 +1231,15 @@
nogeom = 0;
feature_count = 0;
- n_features = OGR_L_GetFeatureCount(Ogr_layer, TRUE);
- G_important_message(_("Importing %d features (OGR layer <%s>)..."),
- n_features, layer_names[layer]);
-
- OGR_L_ResetReading(Ogr_layer);
- while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
- G_percent(feature_count++, n_features, 1); /* show something happens */
+ 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) {
+ G_percent(feature_count++, n_features[layer], 1); /* show something happens */
+
/* Geometry */
#if GDAL_VERSION_NUM >= 1110000
+ Ogr_featuredefn = OGR_iter.Ogr_featuredefn;
for (i = 0; i < OGR_FD_GetGeomFieldCount(Ogr_featuredefn); i++) {
if (igeom > -1 && i != igeom)
continue; /* use only geometry defined via param.geom */
@@ -1313,7 +1372,6 @@
nogeom == 1 ? "feature" : "features");
}
-
separator = "-----------------------------------------------------";
G_message("%s", separator);
@@ -1444,6 +1502,7 @@
}
/* Go through all layers and find centroids for each polygon */
+ OGR_iterator_reset(&OGR_iter);
for (layer = 0; layer < nlayers; layer++) {
G_message("%s", separator);
G_message(_("Finding centroids for OGR layer <%s>..."), layer_names[layer]);
@@ -1456,13 +1515,12 @@
if (param.geom->answer)
igeom = OGR_FD_GetGeomFieldIndex(Ogr_featuredefn, param.geom->answer);
#endif
-
- n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
+
OGR_L_ResetReading(Ogr_layer);
cat = 0; /* field = layer + 1 */
- while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
- G_percent(cat, n_features, 2);
+ while ((Ogr_feature = ogr_getnextfeature(&OGR_iter, layer_id)) != NULL) {
+ G_percent(cat, n_features[layer], 2);
/* Category */
if (key_idx > -1)
@@ -1472,6 +1530,7 @@
/* Geometry */
#if GDAL_VERSION_NUM >= 1110000
+ Ogr_featuredefn = OGR_iter.Ogr_featuredefn;
for (i = 0; i < OGR_FD_GetGeomFieldCount(Ogr_featuredefn); i++) {
if (igeom > -1 && i != igeom)
continue; /* use only geometry defined via param.geom */
@@ -1747,3 +1806,117 @@
exit(EXIT_SUCCESS);
}
+
+void OGR_iterator_init(struct OGR_iterator *OGR_iter, OGRDataSourceH *Ogr_ds,
+ char *dsn, int nlayers,
+ int ogr_interleaved_reading)
+{
+ OGR_iter->Ogr_ds = Ogr_ds;
+ OGR_iter->dsn = dsn;
+ OGR_iter->nlayers = nlayers;
+ OGR_iter->ogr_interleaved_reading = ogr_interleaved_reading;
+ OGR_iter->requested_layer = -1;
+ OGR_iter->curr_layer = -1;
+ OGR_iter->Ogr_layer = NULL;
+ OGR_iter->has_nonempty_layers = 0;
+}
+
+void OGR_iterator_reset(struct OGR_iterator *OGR_iter)
+{
+ OGR_iter->requested_layer = -1;
+ OGR_iter->curr_layer = -1;
+ OGR_iter->Ogr_layer = NULL;
+ OGR_iter->has_nonempty_layers = 0;
+}
+
+OGRFeatureH ogr_getnextfeature(struct OGR_iterator *OGR_iter, int layer)
+{
+ if (OGR_iter->requested_layer != layer) {
+ /* reset OGR reading */
+ if (!OGR_iter->ogr_interleaved_reading) {
+ OGR_iter->curr_layer = 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_L_ResetReading(OGR_iter->Ogr_layer);
+ }
+ 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->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;
+ }
+ OGR_iter->requested_layer = layer;
+ }
+
+ if (OGR_iter->Ogr_layer == NULL)
+ return NULL;
+
+ if (!OGR_iter->ogr_interleaved_reading) {
+ OGRFeatureH Ogr_feature;
+
+ Ogr_feature = OGR_L_GetNextFeature(OGR_iter->Ogr_layer);
+ if (Ogr_feature == NULL)
+ OGR_iter->Ogr_layer = NULL;
+
+ return Ogr_feature;
+ }
+ else {
+ OGRFeatureH Ogr_feature;
+
+ /* fetch next feature */
+ 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;
+
+ return NULL;
+ }
+ else {
+ OGR_iter->curr_layer = 0;
+ OGR_iter->has_nonempty_layers = 0;
+ }
+ }
+ 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_feature = OGR_L_GetNextFeature(OGR_iter->Ogr_layer);
+ if (Ogr_feature != NULL) {
+ OGR_iter->has_nonempty_layers = 1;
+
+ 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;
+
+ return NULL;
+ }
+ else {
+ OGR_iter->curr_layer = 0;
+ OGR_iter->has_nonempty_layers = 0;
+ }
+ }
+ 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);
+ }
+ }
+ }
+
+ return NULL;
+}
More information about the grass-commit
mailing list