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)
This commit is contained in:
parent
c7f136db91
commit
930b2cc7b6
3 changed files with 106 additions and 62 deletions
|
@ -89,12 +89,21 @@ ogr_datasource::ogr_datasource(parameters const& params)
|
|||
|
||||
// initialize layer
|
||||
|
||||
boost::optional<std::string> layer = params.get<std::string>("layer");
|
||||
boost::optional<unsigned> layer_idx = params.get<unsigned>("layer_by_index");
|
||||
boost::optional<std::string> layer_by_name = params.get<std::string>("layer");
|
||||
boost::optional<unsigned> layer_by_index = params.get<unsigned>("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 <layer> parameter, available layers are: ");
|
||||
std::ostringstream s;
|
||||
s << "missing <layer> or <layer_by_index> 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 <layer> 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 ();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<double> extent = ogr.envelope();
|
||||
quadtree<int> 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<double> extent = ogr.envelope();
|
||||
quadtree<int> 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<double> item_ext = fp->envelope();
|
||||
|
||||
tree.insert (count, item_ext);
|
||||
if (verbose) {
|
||||
std::clog << "record number " << (count + 1) << " box=" << item_ext << std::endl;
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
box2d<double> 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="<<tree.count()<<std::endl;
|
||||
file.exceptions(std::ios::failbit | std::ios::badbit);
|
||||
tree.write(file);
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
// catch problem at the datasource creation
|
||||
catch (const mapnik::datasource_exception & ex )
|
||||
{
|
||||
std::clog << ex.what() << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::clog << " number shapes=" << count << std::endl;
|
||||
|
||||
std::fstream file((ogrlayername+".index").c_str(),
|
||||
std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
if (!file) {
|
||||
std::clog << "cannot open index file for writing file \""
|
||||
<< (ogrlayername+".index") << "\"" << std::endl;
|
||||
} else {
|
||||
tree.trim();
|
||||
std::clog<<" number nodes="<<tree.count()<<std::endl;
|
||||
file.exceptions(std::ios::failbit | std::ios::badbit);
|
||||
tree.write(file);
|
||||
file.flush();
|
||||
file.close();
|
||||
catch (...)
|
||||
{
|
||||
std::clog << "unknown exception..." << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::clog << "done!" << std::endl;
|
||||
|
|
Loading…
Add table
Reference in a new issue