use memory mapped files for reading shape files

This commit is contained in:
Artem Pavlenko 2008-02-04 11:12:32 +00:00
parent 57cb2edef1
commit a8859645b3
14 changed files with 307 additions and 331 deletions

View file

@ -162,6 +162,7 @@ BOOST_LIBSHEADERS = [
# ['system', 'boost/system/system_error.hpp', True], # uncomment this on Darwin + boost_1_35 # ['system', 'boost/system/system_error.hpp', True], # uncomment this on Darwin + boost_1_35
['filesystem', 'boost/filesystem/operations.hpp', True], ['filesystem', 'boost/filesystem/operations.hpp', True],
['regex', 'boost/regex.hpp', True], ['regex', 'boost/regex.hpp', True],
['iostreams','boost/iostreams/device/mapped_file.hpp',True],
['program_options', 'boost/program_options.hpp', False] ['program_options', 'boost/program_options.hpp', False]
] ]

View file

@ -33,11 +33,17 @@ shape_src = Split(
shapefile.cpp shapefile.cpp
shape_index_featureset.cpp shape_index_featureset.cpp
shape_io.cpp shape_io.cpp
shp_index.cpp
""" """
) )
thread_suffix = '-mt'
libraries = [] if env['PLATFORM'] == 'FreeBSD':
thread_suffix = ''
if env['THREADING'] == 'multi':
libraries = ['boost_iostreams%s%s' % (env['BOOST_APPEND'],thread_suffix) ]
else:
libraries = ['boost_iostreams%s' % (env['BOOST_APPEND']) ]
if env['PLATFORM'] == 'Darwin': if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik') libraries.append('mapnik')
libraries.append('iconv') libraries.append('iconv')

View file

@ -35,13 +35,13 @@ dbf_file::dbf_file()
record_length_(0), record_length_(0),
record_(0) {} record_(0) {}
dbf_file::dbf_file(const char* file_name) dbf_file::dbf_file(std::string const& file_name)
:num_records_(0), :num_records_(0),
num_fields_(0), num_fields_(0),
record_length_(0), record_length_(0),
file_(file_name),
record_(0) record_(0)
{ {
file_.open(file_name);
if (file_.is_open()) if (file_.is_open())
{ {
read_header(); read_header();
@ -52,16 +52,6 @@ dbf_file::dbf_file(const char* file_name)
dbf_file::~dbf_file() dbf_file::~dbf_file()
{ {
::operator delete(record_); ::operator delete(record_);
file_.close();
}
bool dbf_file::open(const std::string& file_name)
{
file_.open(file_name.c_str(),std::ios::in|std::ios::binary);
if (file_.is_open())
read_header();
return file_?true:false;
} }

View file

@ -23,12 +23,16 @@
#ifndef DBFFILE_HPP #ifndef DBFFILE_HPP
#define DBFFILE_HPP #define DBFFILE_HPP
#include <mapnik/feature.hpp>
// boost
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
// stl
#include <vector> #include <vector>
#include <string> #include <string>
#include <fstream>
#include <cassert> #include <cassert>
#include <mapnik/feature.hpp>
using mapnik::transcoder; using mapnik::transcoder;
using mapnik::Feature; using mapnik::Feature;
@ -44,37 +48,36 @@ struct field_descriptor
int offset_; int offset_;
}; };
using namespace boost::iostreams;
class dbf_file class dbf_file
{ {
private: private:
int num_records_;
int num_records_; int num_fields_;
int num_fields_; int record_length_;
int record_length_; std::vector<field_descriptor> fields_;
std::vector<field_descriptor> fields_; stream<mapped_file_source> file_;
std::ifstream file_; char* record_;
char* record_;
public: public:
dbf_file(); dbf_file();
dbf_file(const char* file_name); dbf_file(const std::string& file_name);
dbf_file(const std::string& file_name); ~dbf_file();
~dbf_file(); bool is_open();
bool open(const std::string& file_name); void close();
bool is_open(); int num_records() const;
void close(); int num_fields() const;
int num_records() const; field_descriptor const& descriptor(int col) const;
int num_fields() const; void move_to(int index);
field_descriptor const& descriptor(int col) const; std::string string_value(int col) const;
void move_to(int index); void add_attribute(int col, transcoder const& tr, Feature const& f) const throw();
std::string string_value(int col) const; private:
void add_attribute(int col, transcoder const& tr, Feature const& f) const throw(); dbf_file(const dbf_file&);
private: dbf_file& operator=(const dbf_file&);
dbf_file(const dbf_file&); void read_header();
dbf_file& operator=(const dbf_file&); int read_short();
void read_header(); int read_int();
int read_short(); void skip(int bytes);
int read_int();
void skip(int bytes);
}; };
#endif //DBFFILE_HPP #endif //DBFFILE_HPP

View file

@ -23,8 +23,15 @@
//$Id: shape_index_featureset.cc 36 2005-04-05 14:32:18Z pavlenko $ //$Id: shape_index_featureset.cc 36 2005-04-05 14:32:18Z pavlenko $
#include <mapnik/feature_factory.hpp> #include <mapnik/feature_factory.hpp>
// boost
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include "shape_index_featureset.hpp" #include "shape_index_featureset.hpp"
using namespace boost::iostreams;
template <typename filterT> template <typename filterT>
shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter, shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
const std::string& shape_file, const std::string& shape_file,
@ -38,17 +45,17 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
{ {
shape_.shp().skip(100); shape_.shp().skip(100);
std::string indexname(shape_file + ".index"); stream<mapped_file_source> file(shape_file + ".index");
std::ifstream file(indexname.c_str(),std::ios::in|std::ios::binary);
if (file) if (file)
{ {
shp_index<filterT>::query(filter,file,ids_); shp_index<filterT,stream<mapped_file_source> >::query(filter,file,ids_);
file.close(); file.close();
} }
std::sort(ids_.begin(),ids_.end());
#ifdef MAPNIK_DEBUG
//#ifdef MAPNIK_DEBUG
std::clog<< "query size=" << ids_.size() << "\n"; std::clog<< "query size=" << ids_.size() << "\n";
#endif //#endif
itr_ = ids_.begin(); itr_ = ids_.begin();
@ -60,7 +67,7 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
{ {
if (shape_.dbf().descriptor(i).name_ == *pos) if (shape_.dbf().descriptor(i).name_ == *pos)
{ {
attr_ids_.push_back(i); attr_ids_.insert(i);
break; break;
} }
} }
@ -170,7 +177,7 @@ feature_ptr shape_index_featureset<filterT>::next()
if (attr_ids_.size()) if (attr_ids_.size())
{ {
shape_.dbf().move_to(shape_.id_); shape_.dbf().move_to(shape_.id_);
std::vector<int>::const_iterator pos=attr_ids_.begin(); std::set<int>::const_iterator pos=attr_ids_.begin();
while (pos!=attr_ids_.end()) while (pos!=attr_ids_.end())
{ {
try try

View file

@ -35,9 +35,9 @@ class shape_index_featureset : public Featureset
int shape_type_; int shape_type_;
shape_io shape_; shape_io shape_;
boost::scoped_ptr<transcoder> tr_; boost::scoped_ptr<transcoder> tr_;
std::set<int> ids_; std::vector<int> ids_;
std::set<int>::iterator itr_; std::vector<int>::iterator itr_;
std::vector<int> attr_ids_; std::set<int> attr_ids_;
mutable Envelope<double> feature_ext_; mutable Envelope<double> feature_ext_;
mutable int total_geom_size; mutable int total_geom_size;
mutable int count_; mutable int count_;

View file

@ -32,11 +32,12 @@ const std::string shape_io::DBF = ".dbf";
shape_io::shape_io(const std::string& shape_name) shape_io::shape_io(const std::string& shape_name)
: type_(shape_null), : type_(shape_null),
shp_(shape_name + SHP),
dbf_(shape_name + DBF),
reclength_(0), reclength_(0),
id_(0) id_(0)
{ {
bool ok = (shp_.open(shape_name + SHP) && bool ok = (shp_.is_open() && dbf_.is_open());
dbf_.open(shape_name + DBF));
if (!ok) if (!ok)
{ {
throw datasource_exception("cannot read shape file"); throw datasource_exception("cannot read shape file");
@ -49,7 +50,6 @@ shape_io::~shape_io()
dbf_.close(); dbf_.close();
} }
void shape_io::move_to (int pos) void shape_io::move_to (int pos)
{ {
shp_.seek(pos); shp_.seek(pos);
@ -57,6 +57,12 @@ void shape_io::move_to (int pos)
reclength_ = shp_.read_xdr_integer(); reclength_ = shp_.read_xdr_integer();
type_ = shp_.read_ndr_integer(); type_ = shp_.read_ndr_integer();
if (shp_.is_eof()) {
id_ = 0;
reclength_ = 0;
type_ = shape_null;
}
if (type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz) if (type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
{ {
shp_.read_envelope(cur_extent_); shp_.read_envelope(cur_extent_);

View file

@ -31,36 +31,36 @@ using mapnik::geometry2d;
struct shape_io struct shape_io
{ {
static const std::string SHP; static const std::string SHP;
static const std::string SHX; static const std::string SHX;
static const std::string DBF; static const std::string DBF;
unsigned type_;
shape_file shp_;
shape_file shx_;
dbf_file dbf_;
unsigned reclength_;
unsigned id_;
Envelope<double> cur_extent_;
shape_file shp_; public:
shape_file shx_; enum shapeType
dbf_file dbf_; {
unsigned type_; shape_null = 0,
unsigned reclength_; shape_point = 1,
unsigned id_; shape_polyline = 3,
Envelope<double> cur_extent_; shape_polygon = 5,
shape_multipoint = 8,
public: shape_pointz = 11,
enum shapeType shape_polylinez = 13,
{ shape_polygonz = 15,
shape_null = 0, shape_multipointz = 18,
shape_point = 1, shape_pointm = 21,
shape_polyline = 3, shape_polylinem = 23,
shape_polygon = 5, shape_polygonm = 25,
shape_multipoint = 8, shape_multipointm = 28,
shape_pointz = 11, shape_multipatch = 31
shape_polylinez = 13, };
shape_polygonz = 15,
shape_multipointz = 18,
shape_pointm = 21,
shape_polylinem = 23,
shape_polygonm = 25,
shape_multipointm = 28,
shape_multipatch = 31
};
shape_io(const std::string& shape_name); shape_io(const std::string& shape_name);
~shape_io(); ~shape_io();

View file

@ -25,25 +25,9 @@
shape_file::shape_file() {} shape_file::shape_file() {}
shape_file::shape_file(const std::string& file_name) shape_file::shape_file(const std::string& file_name)
{ : file_(file_name) {}
//file_.rdbuf()->pubsetbuf(buff_,buffer_size);
file_.open(file_name.c_str(),std::ios::in|std::ios::binary);
}
shape_file::~shape_file()
{
if (file_ && file_.is_open())
file_.close();
}
bool shape_file::open(const std::string& file_name)
{
//file_.rdbuf()->pubsetbuf(buff_,buffer_size);
file_.open(file_name.c_str(),std::ios::in | std::ios::binary);
return file_?true:false;
}
shape_file::~shape_file() {}
bool shape_file::is_open() bool shape_file::is_open()
{ {

View file

@ -20,64 +20,66 @@
* *
*****************************************************************************/ *****************************************************************************/
//$Id: shapefile.hh 33 2005-04-04 13:01:03Z pavlenko $ //$Id: shapefile.hpp 33 2005-04-04 13:01:03Z pavlenko $
#ifndef SHAPEFILE_HPP #ifndef SHAPEFILE_HPP
#define SHAPEFILE_HPP #define SHAPEFILE_HPP
#include <fstream>
#include <mapnik/envelope.hpp> #include <mapnik/envelope.hpp>
// boost
#include <boost/utility.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
using mapnik::Envelope; using mapnik::Envelope;
struct shape_record struct shape_record
{ {
char* data; const char* data;
size_t size; size_t size;
size_t pos; mutable size_t pos;
explicit shape_record(size_t size) explicit shape_record(size_t size)
: data(static_cast<char*>(::operator new(sizeof(char)*size))), : size(size),
size(size), pos(0) {}
pos(0) {}
void set_data(const char * data_)
char* rawdata() {
{ data = data_;
return &data[0]; }
}
void skip(unsigned n)
void skip(unsigned n) {
{ pos+=n;
pos+=n; }
}
int read_ndr_integer()
int read_ndr_integer() {
{ int val=(data[pos] & 0xff) |
int val=(data[pos] & 0xff) |
(data[pos+1] & 0xff) << 8 | (data[pos+1] & 0xff) << 8 |
(data[pos+2] & 0xff) << 16 | (data[pos+2] & 0xff) << 16 |
(data[pos+3] & 0xff) << 24; (data[pos+3] & 0xff) << 24;
pos+=4; pos+=4;
return val; return val;
} }
int read_xdr_integer() int read_xdr_integer()
{ {
int val=(data[pos] & 0xff) << 24 | int val=(data[pos] & 0xff) << 24 |
(data[pos+1] & 0xff) << 16 | (data[pos+1] & 0xff) << 16 |
(data[pos+2] & 0xff) << 8 | (data[pos+2] & 0xff) << 8 |
(data[pos+3] & 0xff); (data[pos+3] & 0xff);
pos+=4; pos+=4;
return val; return val;
} }
double read_double() double read_double()
{ {
double val; double val;
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
std::memcpy(&val,&data[pos],8); std::memcpy(&val,&data[pos],8);
#else #else
long long bits = ((long long)data[pos] & 0xff) | long long bits = ((long long)data[pos] & 0xff) |
((long long)data[pos+1] & 0xff) << 8 | ((long long)data[pos+1] & 0xff) << 8 |
((long long)data[pos+2] & 0xff) << 16 | ((long long)data[pos+2] & 0xff) << 16 |
((long long)data[pos+3] & 0xff) << 24 | ((long long)data[pos+3] & 0xff) << 24 |
@ -85,64 +87,62 @@ struct shape_record
((long long)data[pos+5] & 0xff) << 40 | ((long long)data[pos+5] & 0xff) << 40 |
((long long)data[pos+6] & 0xff) << 48 | ((long long)data[pos+6] & 0xff) << 48 |
((long long)data[pos+7] & 0xff) << 56 ; ((long long)data[pos+7] & 0xff) << 56 ;
std::memcpy(&val,&bits,8); std::memcpy(&val,&bits,8);
#endif #endif
pos+=8; pos+=8;
return val; return val;
} }
long remains() long remains()
{ {
return (size-pos); return (size-pos);
} }
~shape_record() ~shape_record() {}
{
::operator delete(data);
}
}; };
class shape_file using namespace boost::iostreams;
class shape_file : boost::noncopyable
{ {
std::ifstream file_; stream<mapped_file_source> file_;
//static const int buffer_size = 16; public:
//char buff_[buffer_size]; shape_file();
public: shape_file(const std::string& file_name);
shape_file(); ~shape_file();
shape_file(const std::string& file_name); bool is_open();
~shape_file(); void close();
bool open(const std::string& file_name);
bool is_open(); inline void read_record(shape_record& rec)
void close(); {
rec.set_data(file_->data() + file_.tellg());
inline void read_record(shape_record& rec) file_.seekg(rec.size,std::ios::cur);
{ }
file_.read(rec.rawdata(),rec.size);
} inline int read_xdr_integer()
{
inline int read_xdr_integer() char b[4];
{ file_.read(b, 4);
char b[4]; return b[3] & 0xffu | (b[2] & 0xffu) << 8 |
file_.read(b, 4);
return b[3] & 0xffu | (b[2] & 0xffu) << 8 |
(b[1] & 0xffu) << 16 | (b[0] & 0xffu) << 24; (b[1] & 0xffu) << 16 | (b[0] & 0xffu) << 24;
} }
inline int read_ndr_integer() inline int read_ndr_integer()
{ {
char b[4]; char b[4];
file_.read(b,4); file_.read(b,4);
return b[0]&0xffu | (b[1]&0xffu) << 8 | return b[0]&0xffu | (b[1]&0xffu) << 8 |
(b[2]&0xffu) << 16 | (b[3]&0xffu) << 24; (b[2]&0xffu) << 16 | (b[3]&0xffu) << 24;
} }
inline double read_double() inline double read_double()
{ {
double val; double val;
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
file_.read(reinterpret_cast<char*>(&val),8); file_.read(reinterpret_cast<char*>(&val),8);
#else #else
char b[8]; char b[8];
file_.read(b,8); file_.read(b,8);
long long bits = ((long long)b[0] & 0xff) | long long bits = ((long long)b[0] & 0xff) |
((long long)b[1] & 0xff) << 8 | ((long long)b[1] & 0xff) << 8 |
((long long)b[2] & 0xff) << 16 | ((long long)b[2] & 0xff) << 16 |
((long long)b[3] & 0xff) << 24 | ((long long)b[3] & 0xff) << 24 |
@ -150,52 +150,48 @@ public:
((long long)b[5] & 0xff) << 40 | ((long long)b[5] & 0xff) << 40 |
((long long)b[6] & 0xff) << 48 | ((long long)b[6] & 0xff) << 48 |
((long long)b[7] & 0xff) << 56 ; ((long long)b[7] & 0xff) << 56 ;
memcpy(&val,&bits,8); memcpy(&val,&bits,8);
#endif #endif
return val; return val;
} }
inline void read_envelope(Envelope<double>& envelope) inline void read_envelope(Envelope<double>& envelope)
{ {
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
file_.read(reinterpret_cast<char*>(&envelope),sizeof(envelope)); file_.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
#else #else
double minx=read_double(); double minx=read_double();
double miny=read_double(); double miny=read_double();
double maxx=read_double(); double maxx=read_double();
double maxy=read_double(); double maxy=read_double();
envelope.init(minx,miny,maxx,maxy); envelope.init(minx,miny,maxx,maxy);
#endif #endif
} }
inline void skip(std::streampos bytes) inline void skip(std::streampos bytes)
{ {
file_.seekg(bytes,std::ios::cur); file_.seekg(bytes,std::ios::cur);
} }
inline void rewind() inline void rewind()
{ {
seek(100); seek(100);
} }
inline void seek(std::streampos pos) inline void seek(std::streampos pos)
{ {
file_.seekg(pos,std::ios::beg); file_.seekg(pos,std::ios::beg);
} }
inline std::streampos pos() inline std::streampos pos()
{ {
return file_.tellg(); return file_.tellg();
} }
inline bool is_eof() inline bool is_eof()
{ {
return file_.eof(); return file_.eof();
} }
private:
shape_file(const shape_file&);
shape_file& operator=(const shape_file&);
}; };
#endif //SHAPEFILE_HPP #endif //SHAPEFILE_HPP

View file

@ -1,80 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#include <mapnik/geom_util.hpp>
#include "shp_index.hpp"
template <typename filterT>
void shp_index<filterT>::query(const filterT& filter,std::ifstream& file,std::set<int>& pos)
{
file.seekg(16,std::ios::beg);
query_node(filter,file,pos);
}
template <typename filterT>
void shp_index<filterT>::query_node(const filterT& filter,std::ifstream& file,std::set<int>& ids)
{
int offset=read_ndr_integer(file);
Envelope<double> node_ext;
read_envelope(file,node_ext);
int num_shapes=read_ndr_integer(file);
if (!filter.pass(node_ext))
{
file.seekg(offset+num_shapes*4+4,std::ios::cur);
return;
}
for (int i=0;i<num_shapes;++i)
{
int id=read_ndr_integer(file);
ids.insert(id);
}
int children=read_ndr_integer(file);
for (int j=0;j<children;++j)
{
query_node(filter,file,ids);
}
}
template <typename filterT>
int shp_index<filterT>::read_ndr_integer(std::ifstream& file)
{
char b[4];
file.read(b,4);
return (b[0]&0xff) | (b[1]&0xff)<<8 | (b[2]&0xff)<<16 | (b[3]&0xff)<<24;
}
template <typename filterT>
void shp_index<filterT>::read_envelope(std::ifstream& file,Envelope<double>& envelope)
{
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
}
template class shp_index<mapnik::filter_in_box>;
template class shp_index<mapnik::filter_at_point>;

View file

@ -25,7 +25,7 @@
// st // st
#include <fstream> #include <fstream>
#include <set> #include <vector>
// mapnik // mapnik
#include <mapnik/envelope.hpp> #include <mapnik/envelope.hpp>
#include <mapnik/query.hpp> #include <mapnik/query.hpp>
@ -33,19 +33,73 @@
using mapnik::Envelope; using mapnik::Envelope;
using mapnik::query; using mapnik::query;
template <typename filterT> template <typename filterT, typename IStream = std::ifstream>
class shp_index class shp_index
{ {
public: public:
static void query(const filterT& filter,std::ifstream& file,std::set<int>& pos); static void query(const filterT& filter, IStream& file,std::vector<int>& pos);
private: private:
shp_index(); shp_index();
~shp_index(); ~shp_index();
shp_index(const shp_index&); shp_index(const shp_index&);
shp_index& operator=(const shp_index&); shp_index& operator=(const shp_index&);
static int read_ndr_integer(std::ifstream& in); static int read_ndr_integer(IStream & in);
static void read_envelope(std::ifstream& in,Envelope<double> &envelope); static void read_envelope(IStream & in,Envelope<double> &envelope);
static void query_node(const filterT& filter,std::ifstream& file,std::set<int>& pos); static void query_node(const filterT& filter,IStream & in,std::vector<int>& pos);
}; };
template <typename filterT,typename IStream>
void shp_index<filterT, IStream>::query(const filterT& filter,IStream & file,std::vector<int>& pos)
{
file.seekg(16,std::ios::beg);
query_node(filter,file,pos);
}
template <typename filterT, typename IStream>
void shp_index<filterT,IStream>::query_node(const filterT& filter,IStream & file,std::vector<int>& ids)
{
int offset=read_ndr_integer(file);
Envelope<double> node_ext;
read_envelope(file,node_ext);
int num_shapes=read_ndr_integer(file);
if (!filter.pass(node_ext))
{
file.seekg(offset+num_shapes*4+4,std::ios::cur);
return;
}
for (int i=0;i<num_shapes;++i)
{
int id=read_ndr_integer(file);
ids.push_back(id);
}
int children=read_ndr_integer(file);
for (int j=0;j<children;++j)
{
query_node(filter,file,ids);
}
}
template <typename filterT,typename IStream>
int shp_index<filterT,IStream>::read_ndr_integer(IStream & file)
{
char b[4];
file.read(b,4);
return (b[0]&0xff) | (b[1]&0xff)<<8 | (b[2]&0xff)<<16 | (b[3]&0xff)<<24;
}
template <typename filterT,typename IStream>
void shp_index<filterT,IStream>::read_envelope(IStream & file,Envelope<double>& envelope)
{
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
}
#endif //SHP_INDEX_HH #endif //SHP_INDEX_HH

View file

@ -42,9 +42,13 @@ source = Split(
headers = ['#plugins/input/shape'] + env['CPPPATH'] headers = ['#plugins/input/shape'] + env['CPPPATH']
boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND'] boost_program_options = 'boost_program_options%s' % env['BOOST_APPEND']
boost_iostreams = 'boost_iostreams%s' % env['BOOST_APPEND']
if env['THREADING'] == 'multi': if env['THREADING'] == 'multi':
boost_program_options = '%s%s' % (boost_program_options,thread_suffix) boost_program_options = '%s%s' % (boost_program_options,thread_suffix)
shapeindex = env.Program('shapeindex', source, CPPPATH=headers, LIBS=boost_program_options) boost_iostreams = '%s%s' % (boost_iostreams,thread_suffix)
libraries = [boost_program_options,boost_iostreams]
shapeindex = env.Program('shapeindex', source, CPPPATH=headers, LIBS=libraries)
env.Install(install_prefix + '/bin', shapeindex) env.Install(install_prefix + '/bin', shapeindex)
env.Alias('install', install_prefix + '/bin') env.Alias('install', install_prefix + '/bin')

View file

@ -31,7 +31,8 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include "quadtree.hpp" #include "quadtree.hpp"
#include "shape.hpp" #include "shapefile.hpp"
#include "shape_io.hpp"
const int MAXDEPTH = 64; const int MAXDEPTH = 64;
const int DEFAULT_DEPTH = 8; const int DEFAULT_DEPTH = 8;
@ -45,6 +46,7 @@ int main (int argc,char** argv)
namespace po = boost::program_options; namespace po = boost::program_options;
using std::string; using std::string;
using std::vector; using std::vector;
using std::clog;
bool verbose=false; bool verbose=false;
unsigned int depth=DEFAULT_DEPTH; unsigned int depth=DEFAULT_DEPTH;
@ -112,14 +114,17 @@ int main (int argc,char** argv)
while (itr != shape_files.end()) while (itr != shape_files.end())
{ {
std::clog<<"processing "<<*itr << std::endl; std::clog<<"processing "<<*itr << std::endl;
shape_file shp; //shape_file shp;
std::string shapename(*itr++); std::string shapename(*itr++);
if (!shp.open(shapename+".shp")) { shape_file shp(shapename+".shp");
if (!shp.is_open()) {
std::clog<<"error : cannot open "<< (shapename+".shp") <<"\n"; std::clog<<"error : cannot open "<< (shapename+".shp") <<"\n";
continue; continue;
} }
shp.read_xdr_integer(); //file_code == 9994 int code = shp.read_xdr_integer(); //file_code == 9994
std::clog << code << "\n";
shp.skip(5*4); shp.skip(5*4);
int file_length=shp.read_xdr_integer(); int file_length=shp.read_xdr_integer();