shape.input - add support for reading offset/record_length from *.shx in shape_featureset (no *.index) - ref #3126

This commit is contained in:
artemp 2015-10-14 16:44:43 +01:00
parent b15dba95cd
commit a73e8537d8
3 changed files with 26 additions and 12 deletions

View file

@ -22,7 +22,7 @@
// stl
#include <iostream>
#include <cassert>
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/feature_factory.hpp>
@ -54,7 +54,8 @@ shape_featureset<filterT>::shape_featureset(filterT const& filter,
ctx_(std::make_shared<mapnik::context_type>())
{
shape_.shp().skip(100);
setup_attributes(ctx_, attribute_names, shape_name, shape_,attr_ids_);
shape_.shx().skip(100);
setup_attributes(ctx_, attribute_names, shape_name, shape_, attr_ids_);
}
template <typename filterT>
@ -64,12 +65,13 @@ feature_ptr shape_featureset<filterT>::next()
{
return feature_ptr();
}
while (shape_.shp().pos() < std::streampos(file_length_ * 2))
while (!shape_.shx().is_eof())
{
shape_.move_to(shape_.shp().pos());
shape_file::record_type record(shape_.reclength_ * 2);
int offset = shape_.shx().read_xdr_integer();
int record_length = shape_.shx().read_xdr_integer();
shape_.move_to(2*offset);
assert(record_length == shape_.reclength_);
shape_file::record_type record(record_length * 2);
shape_.shp().read_record(record);
int type = record.read_ndr_integer();
@ -136,13 +138,11 @@ feature_ptr shape_featureset<filterT>::next()
if (attr_ids_.size())
{
shape_.dbf().move_to(shape_.id_);
std::vector<int>::const_iterator itr = attr_ids_.begin();
std::vector<int>::const_iterator end = attr_ids_.end();
try
{
for (; itr != end; ++itr)
for (auto id : attr_ids_)
{
shape_.dbf().add_attribute(*itr, *tr_, *feature); //TODO optimize!!!
shape_.dbf().add_attribute(id, *tr_, *feature); //TODO optimize!!!
}
}
catch (...)

View file

@ -31,18 +31,20 @@
using mapnik::datasource_exception;
const std::string shape_io::SHP = ".shp";
const std::string shape_io::SHX = ".shx";
const std::string shape_io::DBF = ".dbf";
const std::string shape_io::INDEX = ".index";
shape_io::shape_io(std::string const& shape_name, bool open_index)
: type_(shape_null),
shp_(shape_name + SHP),
shx_(shape_name + SHX),
dbf_(shape_name + DBF),
reclength_(0),
id_(0)
{
bool ok = (shp_.is_open() && dbf_.is_open());
if (! ok)
if (!ok)
{
throw datasource_exception("Shape Plugin: cannot read shape file '" + shape_name + "'");
}
@ -58,6 +60,10 @@ shape_io::shape_io(std::string const& shape_name, bool open_index)
MAPNIK_LOG_WARN(shape) << "shape_io: Could not open index=" << shape_name << INDEX;
}
}
if (!index_ && !shx_.is_open())
{
throw datasource_exception("Shape Plugin: cannot read shape index file '" + shape_name + ".shx'");
}
}
shape_io::~shape_io() {}
@ -74,6 +80,11 @@ shape_file& shape_io::shp()
return shp_;
}
shape_file& shape_io::shx()
{
return shx_;
}
dbf_file& shape_io::dbf()
{
return dbf_;

View file

@ -61,6 +61,7 @@ public:
~shape_io();
shape_file& shp();
shape_file& shx();
dbf_file& dbf();
inline boost::optional<shape_file&> index()
@ -81,6 +82,7 @@ public:
shapeType type_;
shape_file shp_;
shape_file shx_;
dbf_file dbf_;
std::unique_ptr<shape_file> index_;
unsigned reclength_;
@ -88,6 +90,7 @@ public:
box2d<double> cur_extent_;
static const std::string SHP;
static const std::string SHX;
static const std::string DBF;
static const std::string INDEX;
};