From 930b2cc7b62cbb7e2499466f32d96d20fc8e3046 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 20 Aug 2010 21:20:55 +0000 Subject: [PATCH] better handling and error reporting around ogr layer names and indexes, renamed ogr plugins index file to 'ogrindex' to avoid collision with shape plugins index (when using common shapefile between each as the indexes appear incompatible) --- plugins/input/ogr/ogr_datasource.cpp | 58 +++++++++----- plugins/input/shape/shape.cpp | 2 +- utils/ogrindex/ogrindex.cpp | 108 ++++++++++++++++----------- 3 files changed, 106 insertions(+), 62 deletions(-) diff --git a/plugins/input/ogr/ogr_datasource.cpp b/plugins/input/ogr/ogr_datasource.cpp index 4967e5c7c..48eaf8369 100644 --- a/plugins/input/ogr/ogr_datasource.cpp +++ b/plugins/input/ogr/ogr_datasource.cpp @@ -89,12 +89,21 @@ ogr_datasource::ogr_datasource(parameters const& params) // initialize layer - boost::optional layer = params.get("layer"); - boost::optional layer_idx = params.get("layer_by_index"); + boost::optional layer_by_name = params.get("layer"); + boost::optional layer_by_index = params.get("layer_by_index"); - if (layer_idx && !layer) + if (layer_by_name && layer_by_index) + throw datasource_exception("OGR Plugin: you can only select an ogr layer by name ('layer' parameter) or by number ('layer_by_index' parameter), do not supply both parameters" ); + + + if (layer_by_name) + { + layerName_ = *layer_by_name; + layer_ = dataset_->GetLayerByName (layerName_.c_str()); + } + else if (layer_by_index) { - OGRLayer *ogr_layer = dataset_->GetLayer(*layer_idx); + OGRLayer *ogr_layer = dataset_->GetLayer(*layer_by_index); if (ogr_layer) { OGRFeatureDefn* def = ogr_layer->GetLayerDefn(); @@ -104,30 +113,35 @@ ogr_datasource::ogr_datasource(parameters const& params) } } } - - if (!layer) + else { - std::string s ("missing parameter, available layers are: "); + std::ostringstream s; + s << "missing or parameter, available layers are: "; unsigned num_layers = dataset_->GetLayerCount(); + bool found = false; for (unsigned i = 0; i < num_layers; ++i ) { OGRLayer *ogr_layer = dataset_->GetLayer(i); OGRFeatureDefn* def = ogr_layer->GetLayerDefn(); if (def != 0) { - s += " '"; - s += def->GetName(); - s += "' "; - } else { - s += "No layers found!"; + found = true; + s << " " << i << ":"; + s << def->GetName(); } } - throw datasource_exception(s); + if (!found) { + s << "None (no layers were found in dataset)"; + } + throw datasource_exception(s.str()); } - else + + if (!layer_) { - layerName_ = *layer; - layer_ = dataset_->GetLayerByName (layerName_.c_str()); - if (! layer_) throw datasource_exception("cannot find in dataset"); + std::string s("OGR Plugin: "); + if (layer_by_name) s += "cannot find layer by name '" + *layer_by_name; + else if (layer_by_index) s += "cannot find layer by index number '" + *layer_by_index; + s += "' in dataset '" + dataset_name_ + "'"; + throw datasource_exception(s); } // initialize envelope @@ -136,15 +150,23 @@ ogr_datasource::ogr_datasource(parameters const& params) extent_.init (envelope.MinX, envelope.MinY, envelope.MaxX, envelope.MaxY); // scan for index file + // TODO - layer names don't match dataset name, so this will break for + // any layer types of ogr than shapefiles, etc + // fix here and in ogrindex size_t breakpoint = dataset_name_.find_last_of ("."); if (breakpoint == std::string::npos) breakpoint = dataset_name_.length(); - index_name_ = dataset_name_.substr(0, breakpoint) + ".index"; + index_name_ = dataset_name_.substr(0, breakpoint) + ".ogrindex"; std::ifstream index_file (index_name_.c_str(), std::ios::in | std::ios::binary); if (index_file) { indexed_=true; index_file.close(); } + // enable this warning once the ogrindex tool is a bit more stable/mature + //else + /*{ + std::clog << "### Notice: no ogrindex file found for " + dataset_name_ + ", use the 'ogrindex' program to build an index for faster rendering\n"; + }*/ // deal with attributes descriptions OGRFeatureDefn* def = layer_->GetLayerDefn (); diff --git a/plugins/input/shape/shape.cpp b/plugins/input/shape/shape.cpp index 6e32055a2..9405e66e0 100644 --- a/plugins/input/shape/shape.cpp +++ b/plugins/input/shape/shape.cpp @@ -177,7 +177,7 @@ void shape_datasource::init(shape_io& shape) } else { - std::clog << "### Notice: no index found for " + shape_name_ + ".shp, use the 'shapeindex' program to build an index for faster rendering\n"; + std::clog << "### Notice: no .index file found for " + shape_name_ + ".shp, use the 'shapeindex' program to build an index for faster rendering\n"; } #ifdef MAPNIK_DEBUG diff --git a/utils/ogrindex/ogrindex.cpp b/utils/ogrindex/ogrindex.cpp index 4b78369ac..4cbbc052f 100644 --- a/utils/ogrindex/ogrindex.cpp +++ b/utils/ogrindex/ogrindex.cpp @@ -43,6 +43,8 @@ #include "ogr_featureset.cpp" #include "ogr_index_featureset.cpp" +using mapnik::datasource_exception; + const int MAXDEPTH = 64; const int DEFAULT_DEPTH = 8; const double MINRATIO=0.5; @@ -129,67 +131,87 @@ int main (int argc,char** argv) continue; } - unsigned breakpoint = ogrname.find_last_of ("."); + // TODO - layer names don't match dataset name, so this will break for + // any layer types of ogr than shapefiles, etc + size_t breakpoint = ogrname.find_last_of ("."); if (breakpoint == string::npos) breakpoint = ogrname.length(); std::string ogrlayername (ogrname.substr(0, breakpoint)); - if (boost::filesystem::exists (ogrlayername + ".index")) + if (boost::filesystem::exists (ogrlayername + ".ogrindex")) { - std::clog << "error : " << ogrlayername << ".index file already exists for " << ogrname << std::endl; + std::clog << "error : " << ogrlayername << ".ogrindex file already exists for " << ogrname << std::endl; continue; } mapnik::parameters params; params["type"] = "ogr"; params["file"] = ogrname; - params["layer"] = ogrlayername; + //unsigned first = 0; + params["layer_by_index"] = 0;//ogrlayername; - ogr_datasource ogr (params); - - box2d extent = ogr.envelope(); - quadtree tree (extent, depth, ratio); - int count=0; - - std::clog << "file:" << ogrname << std::endl; - std::clog << "layer:" << ogrlayername << std::endl; - std::clog << "extent:" << extent << std::endl; - - mapnik::query q (extent, 1.0); - mapnik::featureset_ptr itr = ogr.features (q); - - while (true) + try { - mapnik::feature_ptr fp = itr->next(); - if (!fp) + ogr_datasource ogr (params); + + + box2d extent = ogr.envelope(); + quadtree tree (extent, depth, ratio); + int count=0; + + std::clog << "file:" << ogrname << std::endl; + std::clog << "layer:" << ogrlayername << std::endl; + std::clog << "extent:" << extent << std::endl; + + mapnik::query q (extent, 1.0); + mapnik::featureset_ptr itr = ogr.features (q); + + while (true) { - break; + mapnik::feature_ptr fp = itr->next(); + if (!fp) + { + break; + } + + box2d item_ext = fp->envelope(); + + tree.insert (count, item_ext); + if (verbose) { + std::clog << "record number " << (count + 1) << " box=" << item_ext << std::endl; + } + + ++count; } - - box2d item_ext = fp->envelope(); - - tree.insert (count, item_ext); - if (verbose) { - std::clog << "record number " << (count + 1) << " box=" << item_ext << std::endl; + + std::clog << " number shapes=" << count << std::endl; + + std::fstream file((ogrlayername+".ogrindex").c_str(), + std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary); + if (!file) { + std::clog << "cannot open ogrindex file for writing file \"" + << (ogrlayername+".ogrindex") << "\"" << std::endl; + } else { + tree.trim(); + std::clog<<" number nodes="<