diff --git a/plugins/input/shape/shape_datasource.cpp b/plugins/input/shape/shape_datasource.cpp index cdde8eed9..a8fd2319e 100644 --- a/plugins/input/shape/shape_datasource.cpp +++ b/plugins/input/shape/shape_datasource.cpp @@ -64,6 +64,7 @@ shape_datasource::shape_datasource(parameters const& params) : datasource (params), type_(datasource::Vector), file_length_(0), + shx_file_length_(0), indexed_(false), row_limit_(*params.get("row_limit",0)), desc_(shape_datasource::name(), *params.get("encoding","utf-8")) @@ -104,7 +105,7 @@ shape_datasource::shape_datasource(parameters const& params) init(*shape_ref); for (int i=0;idbf().num_fields();++i) { - field_descriptor const& fd=shape_ref->dbf().descriptor(i); + field_descriptor const& fd = shape_ref->dbf().descriptor(i); std::string fld_name=fd.name_; switch (fd.type_) { @@ -167,36 +168,50 @@ void shape_datasource::init(shape_io& shape) #endif //first read header from *.shp - int file_code=shape.shp().read_xdr_integer(); - if (file_code!=9994) + shape_file::record_type header(100); + shape.shp().read_record(header); + + int file_code = header.read_xdr_integer(); + if (file_code != 9994) { std::ostringstream s; s << "Shape Plugin: wrong file code " << file_code; throw datasource_exception(s.str()); } + header.skip(5 * 4); + file_length_ = header.read_xdr_integer(); + int version = header.read_ndr_integer(); - shape.shp().skip(5*4); - file_length_=shape.shp().read_xdr_integer(); - int version=shape.shp().read_ndr_integer(); - - if (version!=1000) + if (version != 1000) { std::ostringstream s; s << "Shape Plugin: nvalid version number " << version; throw datasource_exception(s.str()); } - shape_type_ = static_cast(shape.shp().read_ndr_integer()); + shape_type_ = static_cast(header.read_ndr_integer()); if (shape_type_ == shape_io::shape_multipatch) throw datasource_exception("Shape Plugin: shapefile multipatch type is not supported"); - shape.shp().read_envelope(extent_); + const double lox = header.read_double(); + const double loy = header.read_double(); + const double hix = header.read_double(); + const double hiy = header.read_double(); + extent_.init(lox, loy, hix, hiy); + + if (shape.shx().is_open()) + { + shape_file::record_type shx_header(100); + shape.shx().read_record(shx_header); + shx_header.skip(6 * 4); + shx_file_length_ = shx_header.read_xdr_integer(); + } #ifdef MAPNIK_LOG - const double zmin = shape.shp().read_double(); - const double zmax = shape.shp().read_double(); - const double mmin = shape.shp().read_double(); - const double mmax = shape.shp().read_double(); + const double zmin = header.read_double(); + const double zmax = header.read_double(); + const double mmin = header.read_double(); + const double mmax = header.read_double(); MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Z min/max=" << zmin << "," << zmax; MAPNIK_LOG_DEBUG(shape) << "shape_datasource: M min/max=" << mmin << "," << mmax; @@ -250,7 +265,7 @@ featureset_ptr shape_datasource::features(query const& q) const shape_name_, q.property_names(), desc_.get_encoding(), - file_length_, + shx_file_length_, row_limit_); } } diff --git a/plugins/input/shape/shape_datasource.hpp b/plugins/input/shape/shape_datasource.hpp index f702036eb..d20033a61 100644 --- a/plugins/input/shape/shape_datasource.hpp +++ b/plugins/input/shape/shape_datasource.hpp @@ -69,6 +69,7 @@ private: std::string shape_name_; shape_io::shapeType shape_type_; long file_length_; + long shx_file_length_; box2d extent_; bool indexed_; const int row_limit_; diff --git a/plugins/input/shape/shape_featureset.cpp b/plugins/input/shape/shape_featureset.cpp index e23fa6a84..4cf9dbf0e 100644 --- a/plugins/input/shape/shape_featureset.cpp +++ b/plugins/input/shape/shape_featureset.cpp @@ -41,19 +41,18 @@ shape_featureset::shape_featureset(filterT const& filter, std::string const& shape_name, std::set const& attribute_names, std::string const& encoding, - long file_length, + long shx_file_length, int row_limit) : filter_(filter), shape_(shape_name, false), query_ext_(), feature_bbox_(), tr_(new transcoder(encoding)), - file_length_(file_length), + shx_file_length_(shx_file_length), row_limit_(row_limit), count_(0), ctx_(std::make_shared()) { - shape_.shp().skip(100); shape_.shx().skip(100); setup_attributes(ctx_, attribute_names, shape_name, shape_, attr_ids_); } @@ -65,7 +64,8 @@ feature_ptr shape_featureset::next() { return feature_ptr(); } - while (!shape_.shx().is_eof()) + + while (shape_.shx().pos() < 2 * shx_file_length_) { int offset = shape_.shx().read_xdr_integer(); int record_length = shape_.shx().read_xdr_integer(); diff --git a/plugins/input/shape/shape_featureset.hpp b/plugins/input/shape/shape_featureset.hpp index a047bae80..dd711a054 100644 --- a/plugins/input/shape/shape_featureset.hpp +++ b/plugins/input/shape/shape_featureset.hpp @@ -50,7 +50,7 @@ public: std::string const& shape_file, std::set const& attribute_names, std::string const& encoding, - long file_length, + long shx_file_length, int row_limit); virtual ~shape_featureset(); feature_ptr next(); @@ -61,7 +61,7 @@ private: box2d query_ext_; mutable box2d feature_bbox_; const std::unique_ptr tr_; - long file_length_; + long shx_file_length_; std::vector attr_ids_; mapnik::value_integer row_limit_; mutable int count_; diff --git a/plugins/input/shape/shape_io.hpp b/plugins/input/shape/shape_io.hpp index e3e1b842c..cc8f2584c 100644 --- a/plugins/input/shape/shape_io.hpp +++ b/plugins/input/shape/shape_io.hpp @@ -85,8 +85,8 @@ public: shape_file shx_; dbf_file dbf_; std::unique_ptr index_; - unsigned reclength_; - unsigned id_; + int reclength_; + int id_; box2d cur_extent_; static const std::string SHP;