- modified coding style in shape plugin

This commit is contained in:
kunitoki 2011-10-22 15:27:28 +02:00
parent c0273234b6
commit 2a4fe24ea9
7 changed files with 656 additions and 595 deletions

View file

@ -3,7 +3,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -21,15 +21,15 @@
*
*****************************************************************************/
// stl
#include <iostream>
// mapnik
#include <mapnik/feature_factory.hpp>
// boost
#include <boost/algorithm/string.hpp>
// stl
#include <iostream>
#include "shape_featureset.hpp"
using mapnik::geometry_type;
@ -42,22 +42,23 @@ shape_featureset<filterT>::shape_featureset(const filterT& filter,
std::string const& encoding,
long file_length,
int row_limit)
: filter_(filter),
//shape_type_(shape_io::shape_null),
shape_(shape_name, false),
query_ext_(),
tr_(new transcoder(encoding)),
file_length_(file_length),
count_(0),
row_limit_(row_limit)
: filter_(filter),
//shape_type_(shape_io::shape_null),
shape_(shape_name, false),
query_ext_(),
tr_(new transcoder(encoding)),
file_length_(file_length),
count_(0),
row_limit_(row_limit)
{
shape_.shp().skip(100);
//attributes
typename std::set<std::string>::const_iterator pos=attribute_names.begin();
while (pos!=attribute_names.end())
typename std::set<std::string>::const_iterator pos = attribute_names.begin();
while (pos != attribute_names.end())
{
bool found_name = false;
for (int i=0;i<shape_.dbf().num_fields();++i)
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{
if (shape_.dbf().descriptor(i).name_ == *pos)
{
@ -66,82 +67,89 @@ shape_featureset<filterT>::shape_featureset(const filterT& filter,
break;
}
}
if (!found_name)
if (! found_name)
{
std::ostringstream s;
s << "no attribute '" << *pos << "' in '"
<< shape_name << "'. Valid attributes are: ";
std::vector<std::string> list;
for (int i=0;i<shape_.dbf().num_fields();++i)
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{
list.push_back(shape_.dbf().descriptor(i).name_);
}
s << boost::algorithm::join(list, ",") << ".";
throw mapnik::datasource_exception( "Shape Plugin: " + s.str() );
throw mapnik::datasource_exception("Shape Plugin: " + s.str());
}
++pos;
}
}
template <typename filterT>
feature_ptr shape_featureset<filterT>::next()
{
if (row_limit_ && count_ > row_limit_)
{
return feature_ptr();
}
std::streampos pos = shape_.shp().pos();
std::streampos pos=shape_.shp().pos();
// skip null shapes
while (pos > 0 && pos < std::streampos(file_length_ * 2))
{
shape_.move_to(pos);
if (shape_.type() == shape_io::shape_null)
if (shape_.type() == shape_io::shape_null)
{
pos += std::streampos(12);
}
else break;
else
{
break;
}
}
if (pos < std::streampos(file_length_ * 2))
{
int type=shape_.type();
int type = shape_.type();
feature_ptr feature(feature_factory::create(shape_.id_));
if (type == shape_io::shape_point)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointm)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().skip(8); //m
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
// skip m
shape_.shp().skip(8);
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointz)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
// skip z
shape_.shp().skip(8);
//skip m if exists
if ( shape_.reclength_ == 8 + 36)
// skip m if exists
if (shape_.reclength_ == 8 + 36)
{
shape_.shp().skip(8);
}
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
++count_;
}
@ -153,11 +161,19 @@ feature_ptr shape_featureset<filterT>::next()
std::streampos pos = shape_.shp().pos();
if (shape_.type() == shape_io::shape_null)
{
pos += std::streampos(12);
pos += std::streampos(12);
// TODO handle the shapes
std::cerr << "NULL SHAPE len=" << shape_.reclength_ << std::endl;
}
else if (filter_.pass(shape_.current_extent())) break;
else pos += std::streampos(2 * shape_.reclength_ - 36);
}
else if (filter_.pass(shape_.current_extent()))
{
break;
}
else
{
pos += std::streampos(2 * shape_.reclength_ - 36);
}
if (pos > 0 && pos < std::streampos(file_length_ * 2))
{
shape_.move_to(pos);
@ -176,97 +192,104 @@ feature_ptr shape_featureset<filterT>::next()
case shape_io::shape_multipoint:
{
int num_points = shape_.shp().read_ndr_integer();
for (int i=0; i< num_points;++i)
for (int i = 0; i < num_points; ++i)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
}
++count_;
break;
}
case shape_io::shape_multipointm:
{
int num_points = shape_.shp().read_ndr_integer();
for (int i=0; i< num_points;++i)
for (int i = 0; i < num_points; ++i)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
}
// skip m
shape_.shp().skip(2*8 + 8*num_points);
// skip m
shape_.shp().skip(2 * 8 + 8 * num_points);
++count_;
break;
}
case shape_io::shape_multipointz:
{
unsigned num_points = shape_.shp().read_ndr_integer();
for (unsigned i=0; i< num_points;++i)
int num_points = shape_.shp().read_ndr_integer();
for (int i = 0; i < num_points; ++i)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
}
// skip z
shape_.shp().skip(2*8 + 8*num_points);
shape_.shp().skip(2 * 8 + 8 * num_points);
// check if we have measure data
if ( shape_.reclength_ == num_points * 16 + 36)
if (shape_.reclength_ == (unsigned)(num_points * 16 + 36))
{
// skip m
shape_.shp().skip(2*8 + 8*num_points);
shape_.shp().skip(2 * 8 + 8 * num_points);
}
++count_;
break;
}
case shape_io::shape_polyline:
{
geometry_type * line = shape_.read_polyline();
geometry_type* line = shape_.read_polyline();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinem:
{
geometry_type * line = shape_.read_polylinem();
geometry_type* line = shape_.read_polylinem();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinez:
{
geometry_type * line = shape_.read_polylinez();
geometry_type* line = shape_.read_polylinez();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polygon:
{
geometry_type * poly = shape_.read_polygon();
geometry_type* poly = shape_.read_polygon();
feature->add_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonm:
{
geometry_type * poly = shape_.read_polygonm();
geometry_type* poly = shape_.read_polygonm();
feature->add_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonz:
{
geometry_type * poly = shape_.read_polygonz();
geometry_type* poly = shape_.read_polygonz();
feature->add_geometry(poly);
++count_;
break;
@ -278,13 +301,13 @@ 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();
std::vector<int>::const_iterator itr = attr_ids_.begin();
std::vector<int>::const_iterator end = attr_ids_.end();
try
{
for (;itr!=end;++itr)
for (; itr != end; ++itr)
{
shape_.dbf().add_attribute(*itr,*tr_,*feature);//TODO optimize!!!
shape_.dbf().add_attribute(*itr, *tr_, *feature); //TODO optimize!!!
}
}
catch (...)
@ -292,6 +315,7 @@ feature_ptr shape_featureset<filterT>::next()
std::clog << "Shape Plugin: error processing attributes " << std::endl;
}
}
return feature;
}
else
@ -308,5 +332,3 @@ shape_featureset<filterT>::~shape_featureset() {}
template class shape_featureset<mapnik::filter_in_box>;
template class shape_featureset<mapnik::filter_at_point>;

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,7 +20,8 @@
*
*****************************************************************************/
//$Id: shape_index_featureset.cc 36 2005-04-05 14:32:18Z pavlenko $
// stl
#include <fstream>
// mapnik
#include <mapnik/feature_factory.hpp>
@ -29,9 +30,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
// stl
#include <fstream>
#include "shape_index_featureset.hpp"
using mapnik::feature_factory;
@ -44,26 +42,27 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
std::string const& encoding,
std::string const& shape_name,
int row_limit)
: filter_(filter),
//shape_type_(0),
shape_(shape),
tr_(new transcoder(encoding)),
count_(0),
row_limit_(row_limit)
: filter_(filter),
//shape_type_(0),
shape_(shape),
tr_(new transcoder(encoding)),
count_(0),
row_limit_(row_limit)
{
shape_.shp().skip(100);
boost::shared_ptr<shape_file> index = shape_.index();
if (index)
{
#ifdef SHAPE_MEMORY_MAPPED_FILE
//shp_index<filterT,stream<mapped_file_source> >::query(filter,index->file(),ids_);
shp_index<filterT,boost::interprocess::ibufferstream>::query(filter,index->file(),ids_);
//shp_index<filterT,stream<mapped_file_source> >::query(filter, index->file(), ids_);
shp_index<filterT,boost::interprocess::ibufferstream>::query(filter, index->file(), ids_);
#else
shp_index<filterT,std::ifstream>::query(filter,index->file(),ids_);
shp_index<filterT,std::ifstream>::query(filter, index->file(), ids_);
#endif
}
std::sort(ids_.begin(),ids_.end());
std::sort(ids_.begin(), ids_.end());
#ifdef MAPNIK_DEBUG
std::clog << "Shape Plugin: query size=" << ids_.size() << std::endl;
@ -72,11 +71,11 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
itr_ = ids_.begin();
// deal with attributes
std::set<std::string>::const_iterator pos=attribute_names.begin();
while (pos!=attribute_names.end())
std::set<std::string>::const_iterator pos = attribute_names.begin();
while (pos != attribute_names.end())
{
bool found_name = false;
for (int i=0;i<shape_.dbf().num_fields();++i)
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{
if (shape_.dbf().descriptor(i).name_ == *pos)
{
@ -85,21 +84,23 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
break;
}
}
if (!found_name)
if (! found_name)
{
std::ostringstream s;
s << "no attribute '" << *pos << "' in '" << shape_name << "'. Valid attributes are: ";
s << "no attribute '" << *pos << "' in '"
<< shape_name << "'. Valid attributes are: ";
std::vector<std::string> list;
for (int i=0;i<shape_.dbf().num_fields();++i)
for (int i = 0; i < shape_.dbf().num_fields(); ++i)
{
list.push_back(shape_.dbf().descriptor(i).name_);
}
s << boost::algorithm::join(list, ",") << ".";
throw mapnik::datasource_exception( "Shape Plugin: " + s.str() );
throw mapnik::datasource_exception("Shape Plugin: " + s.str());
}
++pos;
}
}
@ -108,59 +109,61 @@ template <typename filterT>
feature_ptr shape_index_featureset<filterT>::next()
{
if (row_limit_ && count_ > row_limit_)
return feature_ptr();
if (itr_!=ids_.end())
{
int pos=*itr_++;
return feature_ptr();
}
if (itr_ != ids_.end())
{
int pos = *itr_++;
shape_.move_to(pos);
int type=shape_.type();
int type = shape_.type();
feature_ptr feature(feature_factory::create(shape_.id_));
if (type == shape_io::shape_point)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointm)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().skip(8);// skip m
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
// skip m
shape_.shp().skip(8);
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointz)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
// skip z
shape_.shp().skip(8);
//skip m if exists
if ( shape_.reclength_ == 8 + 36)
// skip m if exists
if (shape_.reclength_ == 8 + 36)
{
shape_.shp().skip(8);
}
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
++count_;
}
else
{
while(!filter_.pass(shape_.current_extent()) &&
itr_!=ids_.end())
while(! filter_.pass(shape_.current_extent()) &&
itr_ != ids_.end())
{
if (shape_.type() != shape_io::shape_null)
{
pos=*itr_++;
pos = *itr_++;
shape_.move_to(pos);
}
else
@ -176,56 +179,62 @@ feature_ptr shape_index_featureset<filterT>::next()
case shape_io::shape_multipointz:
{
int num_points = shape_.shp().read_ndr_integer();
for (int i=0; i< num_points;++i)
for (int i = 0; i < num_points; ++i)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_type * point = new geometry_type(mapnik::Point);
point->move_to(x,y);
double x = shape_.shp().read_double();
double y = shape_.shp().read_double();
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(x, y);
feature->add_geometry(point);
}
// ignore m and z for now
++count_;
break;
}
case shape_io::shape_polyline:
{
geometry_type * line = shape_.read_polyline();
geometry_type* line = shape_.read_polyline();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinem:
{
geometry_type * line = shape_.read_polylinem();
geometry_type* line = shape_.read_polylinem();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinez:
{
geometry_type * line = shape_.read_polylinez();
geometry_type* line = shape_.read_polylinez();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polygon:
{
geometry_type * poly = shape_.read_polygon();
geometry_type* poly = shape_.read_polygon();
feature->add_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonm:
{
geometry_type * poly = shape_.read_polygonm();
geometry_type* poly = shape_.read_polygonm();
feature->add_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonz:
{
geometry_type * poly = shape_.read_polygonz();
geometry_type* poly = shape_.read_polygonz();
feature->add_geometry(poly);
++count_;
break;
@ -237,18 +246,18 @@ feature_ptr shape_index_featureset<filterT>::next()
if (attr_ids_.size())
{
shape_.dbf().move_to(shape_.id_);
std::set<int>::const_iterator itr=attr_ids_.begin();
std::set<int>::const_iterator end=attr_ids_.end();
std::set<int>::const_iterator itr = attr_ids_.begin();
std::set<int>::const_iterator end = attr_ids_.end();
try
{
for ( ; itr!=end; ++itr)
for (; itr!=end; ++itr)
{
shape_.dbf().add_attribute(*itr,*tr_,*feature);
shape_.dbf().add_attribute(*itr, *tr_, *feature);
}
}
catch (...)
{
std::clog << "Shape Plugin: error processing attributes" << std::endl;
std::cerr << "Shape Plugin: error processing attributes" << std::endl;
}
}
return feature;
@ -269,4 +278,3 @@ shape_index_featureset<filterT>::~shape_index_featureset() {}
template class shape_index_featureset<mapnik::filter_in_box>;
template class shape_index_featureset<mapnik::filter_at_point>;

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -23,13 +23,18 @@
#ifndef SHAPE_INDEX_FEATURESET_HPP
#define SHAPE_INDEX_FEATURESET_HPP
// stl
#include <set>
#include <vector>
// mapnik
#include <mapnik/geom_util.hpp>
// boost
#include <boost/scoped_ptr.hpp>
#include "shape_datasource.hpp"
#include "shape_io.hpp"
#include <set>
#include <vector>
using mapnik::Featureset;
using mapnik::box2d;
@ -38,32 +43,31 @@ using mapnik::feature_ptr;
template <typename filterT>
class shape_index_featureset : public Featureset
{
filterT filter_;
//int shape_type_;
shape_io & shape_;
boost::scoped_ptr<transcoder> tr_;
std::vector<int> ids_;
std::vector<int>::iterator itr_;
std::set<int> attr_ids_;
mutable box2d<double> feature_ext_;
mutable int total_geom_size;
mutable int count_;
const int row_limit_;
public:
shape_index_featureset(const filterT& filter,
shape_io& shape,
const std::set<std::string>& attribute_names,
std::string const& encoding,
std::string const& shape_name,
int row_limit);
virtual ~shape_index_featureset();
feature_ptr next();
public:
shape_index_featureset(const filterT& filter,
shape_io& shape,
const std::set<std::string>& attribute_names,
std::string const& encoding,
std::string const& shape_name,
int row_limit);
virtual ~shape_index_featureset();
feature_ptr next();
private:
//no copying
shape_index_featureset(const shape_index_featureset&);
shape_index_featureset& operator=(const shape_index_featureset&);
private:
filterT filter_;
//int shape_type_;
shape_io & shape_;
boost::scoped_ptr<transcoder> tr_;
std::vector<int> ids_;
std::vector<int>::iterator itr_;
std::set<int> attr_ids_;
mutable box2d<double> feature_ext_;
mutable int total_geom_size;
mutable int count_;
const int row_limit_;
//no copying
shape_index_featureset(const shape_index_featureset&);
shape_index_featureset& operator=(const shape_index_featureset&);
};
#endif //SHAPE_INDEX_FEATURESET_HPP
#endif // SHAPE_INDEX_FEATURESET_HPP

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,10 +20,9 @@
*
*****************************************************************************/
//$Id: shape_io.cc 26 2005-03-29 19:18:59Z pavlenko $
#include "shape_io.hpp"
// mapnik
#include <mapnik/datasource.hpp>
// boost
@ -38,22 +37,22 @@ const std::string shape_io::DBF = ".dbf";
const std::string shape_io::INDEX = ".index";
shape_io::shape_io(const std::string& shape_name, bool open_index)
: type_(shape_null),
shp_(shape_name + SHP),
dbf_(shape_name + DBF),
reclength_(0),
id_(0)
: type_(shape_null),
shp_(shape_name + SHP),
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 + "'");
}
if (open_index)
{
try
{
index_= boost::make_shared<shape_file>(shape_name + INDEX);
}
catch (...)
@ -67,370 +66,398 @@ shape_io::shape_io(const std::string& shape_name, bool open_index)
shape_io::~shape_io() {}
void shape_io::move_to (int pos)
void shape_io::move_to(int pos)
{
shp_.seek(pos);
id_ = shp_.read_xdr_integer();
reclength_ = shp_.read_xdr_integer();
type_ = shp_.read_ndr_integer();
shp_.seek(pos);
id_ = shp_.read_xdr_integer();
reclength_ = shp_.read_xdr_integer();
type_ = shp_.read_ndr_integer();
if (type_!= shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
{
shp_.read_envelope(cur_extent_);
}
if (type_ != shape_null && type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
{
shp_.read_envelope(cur_extent_);
}
}
int shape_io::type() const
{
return type_;
return type_;
}
const box2d<double>& shape_io::current_extent() const
{
return cur_extent_;
return cur_extent_;
}
shape_file& shape_io::shp()
{
return shp_;
return shp_;
}
/*shape_file& shape_io::shx()
#if 0
shape_file& shape_io::shx()
{
return shx_;
}*/
return shx_;
}
#endif
dbf_file& shape_io::dbf()
{
return dbf_;
return dbf_;
}
geometry_type * shape_io::read_polyline()
geometry_type* shape_io::read_polyline()
{
shape_file::record_type record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_type * line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
line->set_capacity(num_points + 1);
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
geometry_type* line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
line->set_capacity(num_points + 1);
record.skip(4);
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int i = 1; i < num_points; ++i)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
int start, end;
for (int k = 0; k < num_parts; ++k)
{
start = parts[k];
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
return line;
for (int j = start + 1; j < end; ++j)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
}
return line;
}
geometry_type * shape_io::read_polylinem()
geometry_type* shape_io::read_polylinem()
{
shape_file::record_type record(reclength_*2-36);
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
geometry_type* line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int i = 1; i < num_points; ++i)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
int start, end;
for (int k = 0; k < num_parts; ++k)
{
start = parts[k];
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int j = start + 1; j < end; ++j)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_type* shape_io::read_polylinez()
{
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_type * line = new geometry_type(mapnik::LineString);
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
geometry_type* line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int i = 1; i < num_points; ++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
for (int i = 0; i < num_parts; ++i)
{
parts[i]=record.read_ndr_integer();
parts[i] = record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
int start, end;
for (int k = 0; k < num_parts; ++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_type * shape_io::read_polylinez()
{
shape_file::record_type record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_type * line = new geometry_type(mapnik::LineString);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
start = parts[k];
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
double x = record.read_double();
double y = record.read_double();
line->move_to(x, y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
// {
// double z=record.read_double();
// }
for (int j = start + 1; j < end; ++j)
{
x = record.read_double();
y = record.read_double();
line->line_to(x, y);
}
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
// {
// double z=record.read_double();
// }
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_type * shape_io::read_polygon()
geometry_type* shape_io::read_polygon()
{
shape_file::record_type record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type * poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type* poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
for (int k = 0; k < num_parts; k++)
{
int start = parts[k];
int end;
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x = record.read_double();
double y = record.read_double();
poly->move_to(x, y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
return poly;
for (int j=start+1;j<end;j++)
{
x = record.read_double();
y = record.read_double();
poly->line_to(x, y);
}
}
return poly;
}
geometry_type * shape_io::read_polygonm()
geometry_type* shape_io::read_polygonm()
{
shape_file::record_type record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type * poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type* poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int k = 0; k < num_parts; k++)
{
int start = parts[k];
int end;
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x = record.read_double();
double y = record.read_double();
poly->move_to(x, y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
for (int j = start + 1; j < end; j++)
{
x = record.read_double();
y = record.read_double();
poly->line_to(x, y);
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
}
geometry_type * shape_io::read_polygonz()
geometry_type* shape_io::read_polygonz()
{
shape_file::record_type record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type * poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
shape_file::record_type record(reclength_ * 2 - 36);
shp_.read_record(record);
int num_parts = record.read_ndr_integer();
int num_points = record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_type* poly = new geometry_type(mapnik::Polygon);
poly->set_capacity(num_points + num_parts);
for (int i = 0; i < num_parts; ++i)
{
parts[i] = record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int k = 0; k < num_parts; k++)
{
int start = parts[k];
int end;
if (k == num_parts - 1)
{
end = num_points;
}
else
{
end = parts[k + 1];
}
double x = record.read_double();
double y = record.read_double();
poly->move_to(x, y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double z=record.read_double();
//}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
for (int j = start + 1; j < end; j++)
{
x = record.read_double();
y = record.read_double();
poly->line_to(x, y);
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double z=record.read_double();
//}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
}

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -23,29 +23,16 @@
#ifndef SHAPE_IO_HPP
#define SHAPE_IO_HPP
// mapnik
#include "dbfile.hpp"
#include "shapefile.hpp"
#include "shp_index.hpp"
// boost
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include "dbfile.hpp"
#include "shapefile.hpp"
#include "shp_index.hpp"
struct shape_io : boost::noncopyable
{
static const std::string SHP;
//static const std::string SHX;
static const std::string DBF;
static const std::string INDEX;
unsigned type_;
shape_file shp_;
//shape_file shx_;
dbf_file dbf_;
boost::shared_ptr<shape_file> index_;
unsigned reclength_;
unsigned id_;
box2d<double> cur_extent_;
public:
enum shapeType
{
@ -67,6 +54,7 @@ public:
shape_io(const std::string& shape_name, bool open_index=true);
~shape_io();
shape_file& shp();
//shape_file& shx();
dbf_file& dbf();
@ -84,12 +72,26 @@ public:
void move_to(int id);
int type() const;
const box2d<double>& current_extent() const;
mapnik::geometry_type * read_polyline();
mapnik::geometry_type * read_polylinem();
mapnik::geometry_type * read_polylinez();
mapnik::geometry_type * read_polygon();
mapnik::geometry_type * read_polygonm();
mapnik::geometry_type * read_polygonz();
mapnik::geometry_type* read_polyline();
mapnik::geometry_type* read_polylinem();
mapnik::geometry_type* read_polylinez();
mapnik::geometry_type* read_polygon();
mapnik::geometry_type* read_polygonm();
mapnik::geometry_type* read_polygonz();
unsigned type_;
shape_file shp_;
//shape_file shx_;
dbf_file dbf_;
boost::shared_ptr<shape_file> index_;
unsigned reclength_;
unsigned id_;
box2d<double> cur_extent_;
static const std::string SHP;
//static const std::string SHX;
static const std::string DBF;
static const std::string INDEX;
};
#endif //SHAPE_IO_HPP

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -20,11 +20,13 @@
*
*****************************************************************************/
//$Id: shapefile.hpp 33 2005-04-04 13:01:03Z pavlenko $
#ifndef SHAPEFILE_HPP
#define SHAPEFILE_HPP
// stl
#include <cstring>
#include <fstream>
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/box2d.hpp>
@ -35,10 +37,6 @@
#include <boost/cstdint.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
// stl
#include <cstring>
#include <fstream>
using mapnik::box2d;
using mapnik::read_int32_ndr;
using mapnik::read_int32_xdr;
@ -63,7 +61,7 @@ struct RecordTag
struct MappedRecordTag
{
typedef const char* data_type;
static data_type alloc(unsigned) { return 0;}
static data_type alloc(unsigned) { return 0; }
static void dealloc(data_type ) {}
};
@ -73,12 +71,18 @@ struct shape_record
typename Tag::data_type data;
size_t size;
mutable size_t pos;
explicit shape_record(size_t size)
:
data(Tag::alloc(size)),
: data(Tag::alloc(size)),
size(size),
pos(0) {}
pos(0)
{}
~shape_record()
{
Tag::dealloc(data);
}
void set_data(typename Tag::data_type data_)
{
data = data_;
@ -91,42 +95,37 @@ struct shape_record
void skip(unsigned n)
{
pos+=n;
pos += n;
}
int read_ndr_integer()
{
boost::int32_t val;
read_int32_ndr(&data[pos],val);
pos+=4;
read_int32_ndr(&data[pos], val);
pos += 4;
return val;
}
int read_xdr_integer()
{
boost::int32_t val;
read_int32_xdr(&data[pos],val);
pos+=4;
read_int32_xdr(&data[pos], val);
pos += 4;
return val;
}
double read_double()
{
double val;
read_double_ndr(&data[pos],val);
pos+=8;
read_double_ndr(&data[pos], val);
pos += 8;
return val;
}
long remains()
{
return (size-pos);
}
~shape_record()
{
Tag::dealloc(data);
}
return (size - pos);
}
};
using namespace boost::interprocess;
@ -144,10 +143,10 @@ public:
#endif
file_source_type file_;
shape_file() {}
shape_file(std::string const& file_name)
:
shape_file(std::string const& file_name) :
#ifdef SHAPE_MEMORY_MAPPED_FILE
file_()
#else
@ -155,18 +154,19 @@ public:
#endif
{
#ifdef SHAPE_MEMORY_MAPPED_FILE
boost::optional<mapnik::mapped_region_ptr> memory = mapnik::mapped_memory_cache::find(file_name.c_str(),true);
boost::optional<mapnik::mapped_region_ptr> memory =
mapnik::mapped_memory_cache::find(file_name.c_str(),true);
if (memory)
{
file_.buffer(static_cast<char*>((*memory)->get_address()),(*memory)->get_size());
file_.buffer(static_cast<char*>((*memory)->get_address()), (*memory)->get_size());
}
#endif
}
~shape_file() {}
inline file_source_type & file()
inline file_source_type& file()
{
return file_;
}
@ -184,9 +184,9 @@ public:
{
#ifdef SHAPE_MEMORY_MAPPED_FILE
rec.set_data(file_.buffer().first + file_.tellg());
file_.seekg(rec.size,std::ios::cur);
file_.seekg(rec.size, std::ios::cur);
#else
file_.read(rec.get_data(),rec.size);
file_.read(rec.get_data(), rec.size);
#endif
}
@ -195,16 +195,16 @@ public:
char b[4];
file_.read(b, 4);
boost::int32_t val;
read_int32_xdr(b,val);
read_int32_xdr(b, val);
return val;
}
inline int read_ndr_integer()
{
char b[4];
file_.read(b,4);
file_.read(b, 4);
boost::int32_t val;
read_int32_ndr(b,val);
read_int32_ndr(b, val);
return val;
}
@ -212,11 +212,11 @@ public:
{
double val;
#ifndef MAPNIK_BIG_ENDIAN
file_.read(reinterpret_cast<char*>(&val),8);
file_.read(reinterpret_cast<char*>(&val), 8);
#else
char b[8];
file_.read(b,8);
read_double_ndr(b,val);
file_.read(b, 8);
read_double_ndr(b, val);
#endif
return val;
}
@ -224,22 +224,22 @@ public:
inline void read_envelope(box2d<double>& envelope)
{
#ifndef MAPNIK_BIG_ENDIAN
file_.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
file_.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
#else
char data[4*8];
file_.read(data,4*8);
double minx,miny,maxx,maxy;
read_double_ndr(data + 0*8,minx);
read_double_ndr(data + 1*8,miny);
read_double_ndr(data + 2*8,maxx);
read_double_ndr(data + 3*8,maxy);
envelope.init(minx,miny,maxx,maxy);
char data[4 * 8];
file_.read(data,4 * 8);
double minx, miny, maxx, maxy;
read_double_ndr(data + 0 * 8, minx);
read_double_ndr(data + 1 * 8, miny);
read_double_ndr(data + 2 * 8, maxx);
read_double_ndr(data + 3 * 8, maxy);
envelope.init(minx, miny, maxx, maxy);
#endif
}
inline void skip(std::streampos bytes)
{
file_.seekg(bytes,std::ios::cur);
file_.seekg(bytes, std::ios::cur);
}
inline void rewind()
@ -249,7 +249,7 @@ public:
inline void seek(std::streampos pos)
{
file_.seekg(pos,std::ios::beg);
file_.seekg(pos, std::ios::beg);
}
inline std::streampos pos()
@ -263,4 +263,4 @@ public:
}
};
#endif //SHAPEFILE_HPP
#endif // SHAPEFILE_HPP

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2006 Artem Pavlenko
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -23,9 +23,10 @@
#ifndef SHP_INDEX_HH
#define SHP_INDEX_HH
// st
// stl
#include <fstream>
#include <vector>
// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/query.hpp>
@ -43,63 +44,60 @@ private:
~shp_index();
shp_index(const shp_index&);
shp_index& operator=(const shp_index&);
static int read_ndr_integer(IStream & in);
static void read_envelope(IStream & in,box2d<double> &envelope);
static void query_node(const filterT& filter,IStream & in,std::vector<int>& pos);
static int read_ndr_integer(IStream& in);
static void read_envelope(IStream& in, box2d<double>& envelope);
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)
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);
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)
void shp_index<filterT, IStream>::query_node(const filterT& filter, IStream& file, std::vector<int>& ids)
{
int offset=read_ndr_integer(file);
int offset = read_ndr_integer(file);
box2d<double> node_ext;
read_envelope(file,node_ext);
read_envelope(file, node_ext);
int num_shapes=read_ndr_integer(file);
int num_shapes = read_ndr_integer(file);
if (!filter.pass(node_ext))
if (! filter.pass(node_ext))
{
file.seekg(offset+num_shapes*4+4,std::ios::cur);
file.seekg(offset + num_shapes * 4 + 4, std::ios::cur);
return;
}
for (int i=0;i<num_shapes;++i)
for (int i = 0; i < num_shapes; ++i)
{
int id=read_ndr_integer(file);
int id = read_ndr_integer(file);
ids.push_back(id);
}
int children=read_ndr_integer(file);
int children = read_ndr_integer(file);
for (int j=0;j<children;++j)
for (int j = 0; j < children; ++j)
{
query_node(filter,file,ids);
query_node(filter, file, ids);
}
}
template <typename filterT,typename IStream>
int shp_index<filterT,IStream>::read_ndr_integer(IStream & file)
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;
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,box2d<double>& envelope)
template <typename filterT, typename IStream>
void shp_index<filterT, IStream>::read_envelope(IStream& file, box2d<double>& envelope)
{
file.read(reinterpret_cast<char*>(&envelope),sizeof(envelope));
file.read(reinterpret_cast<char*>(&envelope), sizeof(envelope));
}
#endif //SHP_INDEX_HH
#endif // SHP_INDEX_HH