Store text attributes as USC-2 encoded std::wstring

This commit is contained in:
Artem Pavlenko 2007-02-14 19:54:39 +00:00
parent bf2859cee2
commit 2d256166b4
17 changed files with 511 additions and 426 deletions

View file

@ -29,23 +29,24 @@
void export_feature()
{
using namespace boost::python;
using mapnik::Feature;
class_<Feature,boost::shared_ptr<Feature>,
boost::noncopyable>("Feature",no_init)
.def("id",&Feature::id)
.def("__str__",&Feature::to_string)
using namespace boost::python;
using mapnik::Feature;
class_<Feature,boost::shared_ptr<Feature>,
boost::noncopyable>("Feature",no_init)
.def("id",&Feature::id)
.def("__str__",&Feature::to_string)
//.def(map_indexing_suite<mapnik::Feature>())
.add_property("properties",
make_function(&Feature::props,return_value_policy<reference_existing_object>()))
;
.add_property("properties",
make_function(&Feature::props,return_value_policy<reference_existing_object>()))
;
class_<std::map<std::string, mapnik::value> >("Properties")
class_<std::map<std::string, mapnik::value> >("Properties")
.def(map_indexing_suite<std::map<std::string, mapnik::value
> >())
;
class_<mapnik::value>("Value")
.def("__str__",&mapnik::value::to_string)
;
class_<mapnik::value>("Value")
.def("__str__",&mapnik::value::to_string)
.def("unicode",&mapnik::value::to_unicode)
;
}

View file

@ -35,7 +35,6 @@
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/placement_finder.hpp>
#include <mapnik/map.hpp>
#include <mapnik/unicode.hpp>
namespace mapnik {
template <typename T>
@ -78,7 +77,6 @@ namespace mapnik {
face_manager<freetype_engine> font_manager_;
placement_finder finder_;
label_collision_detector2 point_detector_; //Note: May want to merge this with placement_finder
boost::shared_ptr<transcoder> tr_;
};
}

View file

@ -51,7 +51,7 @@ namespace mapnik {
literal(double val)
: expression<FeatureT>(),
value_(val) {}
literal(std::string const& val)
literal(std::wstring const& val)
: expression<FeatureT>(),
value_(val) {}
literal(literal const& other)
@ -62,14 +62,17 @@ namespace mapnik {
{
return value_;
}
void accept(filter_visitor<FeatureT>& v)
{
v.visit(*this);
}
expression<FeatureT>* clone() const
{
return new literal(*this);
}
std::string to_string() const
{
return value_.to_expression_string();

View file

@ -88,9 +88,9 @@ namespace mapnik
template <typename Iter>
void operator() (Iter start,Iter end) const
{
string str(start,end);
char quote='\\';
string::size_type idx;
std::wstring str(start,end);
std::wstring quote = L"\\";
std::wstring::size_type idx;
idx = str.find(quote);
while (idx != string::npos)
{

View file

@ -145,6 +145,19 @@ namespace mapnik {
return out;
}
inline std::string latin1_to_unicode2(std::string const& text)
{
std::string out;
std::string::const_iterator itr=text.begin();
std::string::const_iterator end=text.end();
while ( itr != end)
{
out.push_back(0x00);
out.push_back(*itr++);
}
return out;
}
class transcoder : private boost::noncopyable
{
public:
@ -153,7 +166,7 @@ namespace mapnik {
desc_ = iconv_open("UCS-2",encoding.c_str());
}
std::wstring transcode(std::string const& input)
std::wstring transcode(std::string const& input) const
{
std::string buf(input.size() * 2,0);
size_t inleft = input.size();

View file

@ -32,9 +32,12 @@
// boost
#include <boost/variant.hpp>
// mapnik
#include <mapnik/unicode.hpp>
namespace mapnik {
typedef boost::variant<int,double,std::string> value_base;
typedef boost::variant<int,double,std::wstring> value_base;
namespace impl {
struct equals
@ -51,7 +54,7 @@ namespace mapnik {
{
return lhs == rhs;
}
bool operator() (int lhs, double rhs) const
{
return lhs == rhs;
@ -62,8 +65,8 @@ namespace mapnik {
return lhs == rhs;
}
bool operator() (std::string const& lhs,
std::string const& rhs) const
bool operator() (std::wstring const& lhs,
std::wstring const& rhs) const
{
return lhs == rhs;
}
@ -94,7 +97,7 @@ namespace mapnik {
return lhs > rhs;
}
bool operator() (std::string const& lhs, std::string const& rhs) const
bool operator() (std::wstring const& lhs, std::wstring const& rhs) const
{
return lhs > rhs;
}
@ -125,7 +128,7 @@ namespace mapnik {
return lhs >= rhs;
}
bool operator() (std::string const& lhs, std::string const& rhs ) const
bool operator() (std::wstring const& lhs, std::wstring const& rhs ) const
{
return lhs >= rhs;
}
@ -156,8 +159,8 @@ namespace mapnik {
return lhs < rhs;
}
bool operator()( std::string const& lhs,
std::string const& rhs ) const
bool operator()( std::wstring const& lhs,
std::wstring const& rhs ) const
{
return lhs < rhs;
}
@ -189,8 +192,8 @@ namespace mapnik {
}
template <typename T>
bool operator()( std::string const& lhs,
std::string const& rhs ) const
bool operator()( std::wstring const& lhs,
std::wstring const& rhs ) const
{
return lhs <= rhs;
}
@ -211,8 +214,8 @@ namespace mapnik {
return lhs + rhs ;
}
value_type operator() (std::string const& lhs ,
std::string const& rhs ) const
value_type operator() (std::wstring const& lhs ,
std::wstring const& rhs ) const
{
return lhs + rhs;
}
@ -243,8 +246,8 @@ namespace mapnik {
return lhs - rhs ;
}
value_type operator() (std::string const& lhs,
std::string const& ) const
value_type operator() (std::wstring const& lhs,
std::wstring const& ) const
{
return lhs;
}
@ -275,8 +278,8 @@ namespace mapnik {
return lhs * rhs;
}
value_type operator() (std::string const& lhs,
std::string const& ) const
value_type operator() (std::wstring const& lhs,
std::wstring const& ) const
{
return lhs;
}
@ -308,8 +311,8 @@ namespace mapnik {
return lhs / rhs;
}
value_type operator() (std::string const& lhs,
std::string const&) const
value_type operator() (std::wstring const& lhs,
std::wstring const&) const
{
return lhs;
}
@ -336,9 +339,26 @@ namespace mapnik {
return ss.str();
}
// specializations
std::string const& operator() (std::string const& val) const
std::string operator() (std::wstring const& val) const
{
return val;
std::stringstream ss;
std::wstring::const_iterator pos = val.begin();
ss << std::hex ;
for (;pos!=val.end();++pos)
{
wchar_t c = *pos;
if (c < 0x7f)
{
ss << char(c);
}
else
{
ss << "\\x";
ss << ((c >> 8) & 0xff);
ss << (c & 0xff);
}
}
return ss.str();
}
std::string operator() (double val) const
@ -348,14 +368,46 @@ namespace mapnik {
return ss.str();
}
};
struct to_unicode : public boost::static_visitor<std::wstring>
{
template <typename T>
std::wstring operator() (T val) const
{
return L"TODO";
}
// specializations
std::wstring const& operator() (std::wstring const& val) const
{
return val;
}
};
struct to_expression_string : public boost::static_visitor<std::string>
{
std::string operator() (std::string const& val) const
std::string operator() (std::wstring const& val) const
{
return "'" + val + "'";
std::stringstream ss;
std::wstring::const_iterator pos = val.begin();
ss << std::hex ;
for (;pos!=val.end();++pos)
{
wchar_t c = *pos;
if (c < 0x7f)
{
ss << char(c);
}
else
{
ss << "\\x";
ss << ((c >> 8) & 0xff);
ss << (c & 0xff);
}
}
return ss.str();
}
template <typename T>
std::string operator() (T val) const
{
@ -417,6 +469,7 @@ namespace mapnik {
{
return boost::apply_visitor(impl::less_or_equal(),base_,other.base_);
}
value_base const& base() const
{
return base_;
@ -431,8 +484,13 @@ namespace mapnik {
{
return boost::apply_visitor(impl::to_string(),base_);
}
std::wstring to_unicode() const
{
return boost::apply_visitor(impl::to_unicode(),base_);
}
};
inline const value operator+(value const& p1,value const& p2)
{
@ -462,7 +520,7 @@ namespace mapnik {
operator << (std::basic_ostream<charT,traits>& out,
value const& v)
{
out << v.base();
out << v.to_string();
return out;
}
}

View file

@ -88,9 +88,8 @@ postgis_datasource::postgis_datasource(parameters const& params)
{
PoolGuard<shared_ptr<Connection>,
shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
//std::cout << "encoding = " << conn->client_encoding()<< "\n";
//desc_.set_encoding(conn->client_encoding());
desc_.set_encoding(conn->client_encoding());
std::string table_name=table_from_sql(table_);
std::ostringstream s;
@ -215,7 +214,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
std::clog << s.str() << "\n";
#endif
shared_ptr<ResultSet> rs=conn->executeQuery(s.str(),1);
return featureset_ptr(new postgis_featureset(rs,props.size()));
return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),props.size()));
}
}
return featureset_ptr();
@ -254,7 +253,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
std::clog << s.str() << "\n";
#endif
shared_ptr<ResultSet> rs=conn->executeQuery(s.str(),1);
return featureset_ptr(new postgis_featureset(rs, size));
return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),size));
}
}
return featureset_ptr();

View file

@ -30,58 +30,62 @@
#include <mapnik/envelope.hpp>
#include <mapnik/feature.hpp>
#include "connection_manager.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/scoped_ptr.hpp>
#include <set>
using namespace mapnik;
#include "connection_manager.hpp"
using namespace mapnik;
class mapnik::transcoder;
class postgis_datasource : public datasource
{
static const std::string GEOMETRY_COLUMNS;
static const std::string SPATIAL_REF_SYS;
const std::string uri_;
const std::string username_;
const std::string password_;
const std::string table_;
std::string geometryColumn_;
int type_;
int srid_;
mutable bool extent_initialized_;
mutable mapnik::Envelope<double> extent_;
layer_descriptor desc_;
ConnectionCreator<Connection> creator_;
static const std::string name_;
public:
static std::string name();
int type() const;
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt) const;
mapnik::Envelope<double> envelope() const;
layer_descriptor get_descriptor() const;
postgis_datasource(const parameters &params);
~postgis_datasource();
private:
static std::string table_from_sql(const std::string& sql);
postgis_datasource(const postgis_datasource&);
postgis_datasource& operator=(const postgis_datasource&);
static const std::string GEOMETRY_COLUMNS;
static const std::string SPATIAL_REF_SYS;
const std::string uri_;
const std::string username_;
const std::string password_;
const std::string table_;
std::string geometryColumn_;
int type_;
int srid_;
mutable bool extent_initialized_;
mutable mapnik::Envelope<double> extent_;
layer_descriptor desc_;
ConnectionCreator<Connection> creator_;
static const std::string name_;
public:
static std::string name();
int type() const;
featureset_ptr features(const query& q) const;
featureset_ptr features_at_point(coord2d const& pt) const;
mapnik::Envelope<double> envelope() const;
layer_descriptor get_descriptor() const;
postgis_datasource(const parameters &params);
~postgis_datasource();
private:
static std::string table_from_sql(const std::string& sql);
postgis_datasource(const postgis_datasource&);
postgis_datasource& operator=(const postgis_datasource&);
};
class postgis_featureset : public Featureset
{
private:
boost::shared_ptr<ResultSet> rs_;
unsigned num_attrs_;
mutable int totalGeomSize_;
mutable int count_;
public:
postgis_featureset(const boost::shared_ptr<ResultSet>& rs,unsigned num_attrs);
feature_ptr next();
~postgis_featureset();
private:
postgis_featureset(const postgis_featureset&);
const postgis_featureset& operator=(const postgis_featureset&);
private:
boost::shared_ptr<ResultSet> rs_;
unsigned num_attrs_;
boost::scoped_ptr<mapnik::transcoder> tr_;
mutable int totalGeomSize_;
mutable int count_;
public:
postgis_featureset(boost::shared_ptr<ResultSet> const& rs,
std::string const& encoding,
unsigned num_attrs);
feature_ptr next();
~postgis_featureset();
private:
postgis_featureset(const postgis_featureset&);
const postgis_featureset& operator=(const postgis_featureset&);
};
#endif //POSTGIS_HPP

View file

@ -25,6 +25,7 @@
#include <boost/algorithm/string.hpp>
#include <mapnik/global.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include "postgis.hpp"
using boost::lexical_cast;
@ -33,10 +34,12 @@ using boost::trim;
using std::string;
postgis_featureset::postgis_featureset(boost::shared_ptr<ResultSet> const& rs,
std::string const& encoding,
unsigned num_attrs=0)
: rs_(rs),
num_attrs_(num_attrs),
totalGeomSize_(0),
tr_(new transcoder(encoding)),
count_(0) {}
feature_ptr postgis_featureset::next()
@ -85,7 +88,8 @@ feature_ptr postgis_featureset::next()
{
std::string str(buf);
trim(str);
boost::put(*feature,name,str);
std::wstring wstr = tr_->transcode(str);
boost::put(*feature,name,wstr);
}
else
{

View file

@ -26,210 +26,212 @@
#include <boost/lexical_cast.hpp>
// mapnik
#include <mapnik/utils.hpp>
#include <mapnik/unicode.hpp>
#include "dbffile.hpp"
dbf_file::dbf_file()
: num_records_(0),
num_fields_(0),
record_length_(0),
record_(0) {}
dbf_file::dbf_file(const char* file_name)
:num_records_(0),
: num_records_(0),
num_fields_(0),
record_length_(0),
record_(0)
record_(0) {}
dbf_file::dbf_file(const char* file_name)
:num_records_(0),
num_fields_(0),
record_length_(0),
record_(0)
{
file_.open(file_name);
if (file_.is_open())
{
read_header();
}
file_.open(file_name);
if (file_.is_open())
{
read_header();
}
}
dbf_file::~dbf_file()
{
::operator delete(record_);
file_.close();
::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;
file_.open(file_name.c_str(),std::ios::in|std::ios::binary);
if (file_.is_open())
read_header();
return file_?true:false;
}
bool dbf_file::is_open()
{
return file_.is_open();
return file_.is_open();
}
void dbf_file::close()
{
if (file_ && file_.is_open())
file_.close();
if (file_ && file_.is_open())
file_.close();
}
int dbf_file::num_records() const
{
return num_records_;
return num_records_;
}
int dbf_file::num_fields() const
{
return num_fields_;
return num_fields_;
}
void dbf_file::move_to(int index)
{
if (index>0 && index<=num_records_)
{
long pos=(num_fields_<<5)+34+(index-1)*(record_length_+1);
file_.seekg(pos,std::ios::beg);
file_.read(record_,record_length_);
}
if (index>0 && index<=num_records_)
{
long pos=(num_fields_<<5)+34+(index-1)*(record_length_+1);
file_.seekg(pos,std::ios::beg);
file_.read(record_,record_length_);
}
}
std::string dbf_file::string_value(int col) const
{
if (col>=0 && col<num_fields_)
{
return std::string(record_+fields_[col].offset_,fields_[col].length_);
}
return "";
if (col>=0 && col<num_fields_)
{
return std::string(record_+fields_[col].offset_,fields_[col].length_);
}
return "";
}
const field_descriptor& dbf_file::descriptor(int col) const
{
assert(col>=0 && col<num_fields_);
return fields_[col];
assert(col>=0 && col<num_fields_);
return fields_[col];
}
void dbf_file::add_attribute(int col,Feature const& f) const throw()
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature const& f) const throw()
{
if (col>=0 && col<num_fields_)
{
std::string name=fields_[col].name_;
std::string str=boost::trim_copy(std::string(record_+fields_[col].offset_,fields_[col].length_));
switch (fields_[col].type_)
{
case 'C':
case 'D'://todo handle date?
case 'M':
case 'L':
f[name] = str;
if (col>=0 && col<num_fields_)
{
std::string name=fields_[col].name_;
std::string str=boost::trim_copy(std::string(record_+fields_[col].offset_,fields_[col].length_));
switch (fields_[col].type_)
{
case 'C':
case 'D'://todo handle date?
case 'M':
case 'L':
{
f[name] = tr.transcode(str);
break;
case 'N':
case 'F':
}
case 'N':
case 'F':
{
if (str[0]=='*')
{
if (str[0]=='*')
{
boost::put(f,name,0);
break;
}
if ( fields_[col].dec_>0 )
{
try
{
double d = boost::lexical_cast<double>(str);
boost::put(f,name,d);
}
catch (boost::bad_lexical_cast &)
{
boost::put(f,name,0.0);
}
}
else
{
try
{
int i = boost::lexical_cast<int>(str);
boost::put(f,name,i);
}
catch (boost::bad_lexical_cast &)
{
boost::put(f,name,0);
}
}
break;
boost::put(f,name,0);
break;
}
}
}
if ( fields_[col].dec_>0 )
{
try
{
double d = boost::lexical_cast<double>(str);
boost::put(f,name,d);
}
catch (boost::bad_lexical_cast &)
{
boost::put(f,name,0.0);
}
}
else
{
try
{
int i = boost::lexical_cast<int>(str);
boost::put(f,name,i);
}
catch (boost::bad_lexical_cast &)
{
boost::put(f,name,0);
}
}
break;
}
}
}
}
void dbf_file::read_header()
{
char c=file_.get();
if (c=='\3' || c=='\131')
{
skip(3);
num_records_=read_int();
assert(num_records_>=0);
num_fields_=read_short();
assert(num_fields_>0);
num_fields_=(num_fields_-33)/32;
skip(22);
int offset=0;
char name[11];
memset(&name,0,11);
fields_.reserve(num_fields_);
for (int i=0;i<num_fields_;++i)
{
field_descriptor desc;
desc.index_=i;
file_.read(name,10);
desc.name_=boost::trim_left_copy(std::string(name));
skip(1);
desc.type_=file_.get();
skip(4);
desc.length_=file_.get();
desc.dec_=file_.get();
skip(14);
desc.offset_=offset;
offset+=desc.length_;
fields_.push_back(desc);
}
record_length_=offset;
if (record_length_>0)
{
record_=static_cast<char*>(::operator new (sizeof(char)*record_length_));
}
}
char c=file_.get();
if (c=='\3' || c=='\131')
{
skip(3);
num_records_=read_int();
assert(num_records_>=0);
num_fields_=read_short();
assert(num_fields_>0);
num_fields_=(num_fields_-33)/32;
skip(22);
int offset=0;
char name[11];
memset(&name,0,11);
fields_.reserve(num_fields_);
for (int i=0;i<num_fields_;++i)
{
field_descriptor desc;
desc.index_=i;
file_.read(name,10);
desc.name_=boost::trim_left_copy(std::string(name));
skip(1);
desc.type_=file_.get();
skip(4);
desc.length_=file_.get();
desc.dec_=file_.get();
skip(14);
desc.offset_=offset;
offset+=desc.length_;
fields_.push_back(desc);
}
record_length_=offset;
if (record_length_>0)
{
record_=static_cast<char*>(::operator new (sizeof(char)*record_length_));
}
}
}
int dbf_file::read_short()
{
char b[2];
file_.read(b,2);
return (b[0] & 0xff) | (b[1] & 0xff) << 8;
char b[2];
file_.read(b,2);
return (b[0] & 0xff) | (b[1] & 0xff) << 8;
}
int dbf_file::read_int()
{
char b[4];
file_.read(b,4);
return (b[0] & 0xff) | (b[1] & 0xff) << 8 |
(b[2] & 0xff) << 16 | (b[3] & 0xff) <<24;
char b[4];
file_.read(b,4);
return (b[0] & 0xff) | (b[1] & 0xff) << 8 |
(b[2] & 0xff) << 16 | (b[3] & 0xff) <<24;
}
void dbf_file::skip(int bytes)
{
file_.seekg(bytes,std::ios::cur);
file_.seekg(bytes,std::ios::cur);
}

View file

@ -32,6 +32,7 @@
using namespace mapnik;
class mapnik::transcoder;
struct field_descriptor
{
int index_;
@ -65,7 +66,7 @@ public:
field_descriptor const& descriptor(int col) const;
void move_to(int index);
std::string string_value(int col) const;
void add_attribute(int col,Feature const& f) const throw();
void add_attribute(int col, transcoder const& tr, Feature const& f) const throw();
private:
dbf_file(const dbf_file&);
dbf_file& operator=(const dbf_file&);

View file

@ -34,13 +34,13 @@
DATASOURCE_PLUGIN(shape_datasource)
shape_datasource::shape_datasource(const parameters &params)
: datasource (params) ,
shape_name_(params.get("file")),
type_(datasource::Vector),
file_length_(0),
indexed_(false),
desc_(params.get("name"),"latin1")
shape_datasource::shape_datasource(const parameters &params)
: datasource (params) ,
shape_name_(params.get("file")),
type_(datasource::Vector),
file_length_(0),
indexed_(false),
desc_(params.get("name"),"latin1")
{
try
{

View file

@ -28,162 +28,165 @@ shape_featureset<filterT>::shape_featureset(const filterT& filter,
const std::string& shape_file,
const std::set<std::string>& attribute_names,
long file_length )
: filter_(filter),
shape_type_(shape_io::shape_null),
shape_(shape_file),
query_ext_(),
file_length_(file_length),
count_(0)
: filter_(filter),
shape_type_(shape_io::shape_null),
shape_(shape_file),
query_ext_(),
tr_(new transcoder("latin1")),
file_length_(file_length),
count_(0)
{
shape_.shp().skip(100);
//attributes
typename std::set<std::string>::const_iterator pos=attribute_names.begin();
while (pos!=attribute_names.end())
{
for (int i=0;i<shape_.dbf().num_fields();++i)
{
if (shape_.dbf().descriptor(i).name_ == *pos)
{
attr_ids_.push_back(i);
break;
}
}
++pos;
}
shape_.shp().skip(100);
//attributes
typename std::set<std::string>::const_iterator pos=attribute_names.begin();
while (pos!=attribute_names.end())
{
for (int i=0;i<shape_.dbf().num_fields();++i)
{
if (shape_.dbf().descriptor(i).name_ == *pos)
{
attr_ids_.push_back(i);
break;
}
}
++pos;
}
}
template <typename filterT>
feature_ptr shape_featureset<filterT>::next()
{
std::streampos pos=shape_.shp().pos();
std::streampos pos=shape_.shp().pos();
if (pos < std::streampos(file_length_ * 2))
{
shape_.move_to(pos);
int type=shape_.type();
feature_ptr feature(new Feature(shape_.id_));
if (type == shape_io::shape_point)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_ptr point(new point_impl(-1));
point->move_to(x,y);
feature->set_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointm)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().read_double();//m
geometry_ptr point(new point_impl(-1));
point->move_to(x,y);
feature->set_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointz)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().read_double();//z
shape_.shp().read_double();//m
geometry_ptr point(new point_impl(-1));
point->move_to(x,y);
feature->set_geometry(point);
++count_;
}
else
{
while (!filter_.pass(shape_.current_extent()))
{
unsigned reclen=shape_.reclength_;
if (!shape_.shp().is_eof())
{
long pos = shape_.shp().pos();
shape_.move_to(pos + 2 * reclen - 36);
}
else
{
return feature_ptr();
}
}
switch (type)
if (pos < std::streampos(file_length_ * 2))
{
shape_.move_to(pos);
int type=shape_.type();
feature_ptr feature(new Feature(shape_.id_));
if (type == shape_io::shape_point)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
geometry_ptr point(new point_impl(-1));
point->move_to(x,y);
feature->set_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointm)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().read_double();//m
geometry_ptr point(new point_impl(-1));
point->move_to(x,y);
feature->set_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointz)
{
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().read_double();//z
shape_.shp().read_double();//m
geometry_ptr point(new point_impl(-1));
point->move_to(x,y);
feature->set_geometry(point);
++count_;
}
else
{
while (!filter_.pass(shape_.current_extent()))
{
unsigned reclen=shape_.reclength_;
if (!shape_.shp().is_eof())
{
long pos = shape_.shp().pos();
shape_.move_to(pos + 2 * reclen - 36);
}
else
{
return feature_ptr();
}
}
switch (type)
{
case shape_io::shape_polyline:
{
geometry_ptr line = shape_.read_polyline();
feature->set_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinem:
{
geometry_ptr line = shape_.read_polylinem();
feature->set_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinez:
{
geometry_ptr line = shape_.read_polylinez();
feature->set_geometry(line);
++count_;
break;
}
case shape_io::shape_polygon:
{
geometry_ptr poly = shape_.read_polygon();
feature->set_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonm:
{
geometry_ptr poly = shape_.read_polygonm();
feature->set_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonz:
{
geometry_ptr poly = shape_.read_polygonz();
feature->set_geometry(poly);
++count_;
break;
}
}
}
if (attr_ids_.size())
{
shape_.dbf().move_to(shape_.id_);
typename std::vector<int>::const_iterator pos=attr_ids_.begin();
while (pos!=attr_ids_.end())
{
try
{
shape_.dbf().add_attribute(*pos,*feature);//TODO optimize!!!
}
catch (...)
{
std::clog << "error processing attributes " << std::endl;
}
++pos;
geometry_ptr line = shape_.read_polyline();
feature->set_geometry(line);
++count_;
break;
}
}
return feature;
}
else
{
case shape_io::shape_polylinem:
{
geometry_ptr line = shape_.read_polylinem();
feature->set_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinez:
{
geometry_ptr line = shape_.read_polylinez();
feature->set_geometry(line);
++count_;
break;
}
case shape_io::shape_polygon:
{
geometry_ptr poly = shape_.read_polygon();
feature->set_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonm:
{
geometry_ptr poly = shape_.read_polygonm();
feature->set_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonz:
{
geometry_ptr poly = shape_.read_polygonz();
feature->set_geometry(poly);
++count_;
break;
}
}
}
if (attr_ids_.size())
{
shape_.dbf().move_to(shape_.id_);
std::vector<int>::const_iterator pos=attr_ids_.begin();
std::vector<int>::const_iterator end=attr_ids_.end();
while (pos!=end)
{
try
{
shape_.dbf().add_attribute(*pos,*tr_,*feature);//TODO optimize!!!
}
catch (...)
{
std::clog << "error processing attributes " << std::endl;
}
++pos;
}
}
return feature;
}
else
{
#ifdef MAPNIK_DEBUG
std::clog<<" total shapes read="<<count_<<"\n";
std::clog<<" total shapes read="<<count_<<"\n";
#endif
return feature_ptr();
}
return feature_ptr();
}
}
@ -193,3 +196,4 @@ shape_featureset<filterT>::~shape_featureset() {}
template class shape_featureset<filter_in_box>;
template class shape_featureset<filter_at_point>;

View file

@ -23,6 +23,7 @@
#ifndef SHAPE_FS_HH
#define SHAPE_FS_HH
#include <boost/scoped_ptr.hpp>
#include <mapnik/geom_util.hpp>
#include "shape.hpp"
@ -31,23 +32,25 @@ using namespace mapnik;
template <typename filterT>
class shape_featureset : public Featureset
{
filterT filter_;
int shape_type_;
shape_io shape_;
Envelope<double> query_ext_;
long file_length_;
std::vector<int> attr_ids_;
mutable Envelope<double> feature_ext_;
mutable int total_geom_size;
mutable int count_;
public:
shape_featureset(const filterT& filter, const std::string& shape_file,
const std::set<std::string>& attribute_names,long file_length);
virtual ~shape_featureset();
feature_ptr next();
private:
shape_featureset(const shape_featureset&);
const shape_featureset& operator=(const shape_featureset&);
filterT filter_;
int shape_type_;
shape_io shape_;
Envelope<double> query_ext_;
boost::scoped_ptr<transcoder> tr_;
long file_length_;
std::vector<int> attr_ids_;
mutable Envelope<double> feature_ext_;
mutable int total_geom_size;
mutable int count_;
public:
shape_featureset(const filterT& filter, const std::string& shape_file,
const std::set<std::string>& attribute_names,long file_length);
virtual ~shape_featureset();
feature_ptr next();
private:
shape_featureset(const shape_featureset&);
const shape_featureset& operator=(const shape_featureset&);
};
#endif //SHAPE_FS_HH
#endif //SHAPE_FS_HH

View file

@ -32,6 +32,7 @@ shape_index_featureset<filterT>::shape_index_featureset(const filterT& filter,
: filter_(filter),
shape_type_(0),
shape_(shape_file),
tr_(new transcoder("latin1")),
count_(0)
{
@ -171,7 +172,7 @@ feature_ptr shape_index_featureset<filterT>::next()
{
try
{
shape_.dbf().add_attribute(*pos,*feature);
shape_.dbf().add_attribute(*pos,*tr_,*feature);
}
catch (...)
{

View file

@ -25,31 +25,32 @@
#include <set>
#include <vector>
#include <boost/scoped_ptr.hpp>
#include "shape_featureset.hpp"
template <typename filterT>
class shape_index_featureset : public Featureset
{
filterT filter_;
int shape_type_;
shape_io shape_;
std::set<int> ids_;
std::set<int>::iterator itr_;
std::vector<int> attr_ids_;
mutable Envelope<double> feature_ext_;
mutable int total_geom_size;
mutable int count_;
filterT filter_;
int shape_type_;
shape_io shape_;
boost::scoped_ptr<transcoder> tr_;
std::set<int> ids_;
std::set<int>::iterator itr_;
std::vector<int> attr_ids_;
mutable Envelope<double> feature_ext_;
mutable int total_geom_size;
mutable int count_;
public:
shape_index_featureset(const filterT& filter,const std::string& shape_file,
const std::set<std::string>& attribute_names);
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&);
public:
shape_index_featureset(const filterT& filter,const std::string& shape_file,
const std::set<std::string>& attribute_names);
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&);
};
#endif //SHAPE_INDEX_FEATURESET_HPP

View file

@ -95,10 +95,9 @@ namespace mapnik
pixmap_(pixmap),
t_(m.getWidth(),m.getHeight(),m.getCurrentExtent(),offset_x,offset_y),
finder_(Envelope<double>(0 ,0, m.getWidth(), m.getHeight()), 64),
point_detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64)),
tr_(new transcoder("utf-8"))
point_detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64))
{
Color const& bg=m.getBackground();
Color const& bg = m.getBackground();
pixmap_.setBackground(bg);
#ifdef MAPNIK_DEBUG
std::clog << "scale=" << m.scale() << "\n";
@ -129,14 +128,8 @@ namespace mapnik
std::clog << "start layer processing : " << lay.name() << "\n";
std::clog << "datasource = " << lay.datasource().get() << "\n";
#endif
datasource_ptr ds = lay.datasource();
if (ds)
{
layer_descriptor desc = ds->get_descriptor();
tr_ = boost::shared_ptr<transcoder>(new transcoder(desc.get_encoding()));
}
}
template <typename T>
void agg_renderer<T>::end_layer_processing(Layer const&)
{
@ -342,12 +335,12 @@ namespace mapnik
if (geom && geom->num_points() > 0)
{
//std::wstring text = to_unicode(feature[sym.get_name()].to_string());
std::string str = feature[sym.get_name()].to_string();
std::wstring text = feature[sym.get_name()].to_unicode();
boost::shared_ptr<ImageData32> const& data = sym.get_data();
if (str.length() > 0 && data)
if (text.length() > 0 && data)
{
std::wstring text = tr_->transcode(str);
//std::wstring text = tr_->transcode(str);
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
{
@ -503,10 +496,10 @@ namespace mapnik
if (geom && geom->num_points() > 0)
{
std::string str = feature[sym.get_name()].to_string();
if ( str.length() > 0 )
std::wstring text = feature[sym.get_name()].to_unicode();
if ( text.length() > 0 )
{
std::wstring text = tr_->transcode(str);
//std::wstring text = tr_->transcode(str);
Color const& fill = sym.get_fill();
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)