+ upgrade postgis.input to work with feature_impl

This commit is contained in:
Artem Pavlenko 2012-01-16 13:19:31 -05:00
parent b380462ce4
commit 89b4ffc848
3 changed files with 42 additions and 36 deletions

View file

@ -487,7 +487,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
s_error << geometry_table_ << "'.";
throw mapnik::datasource_exception(s_error.str());
}
std::ostringstream s;
s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom";
@ -497,10 +497,13 @@ featureset_ptr postgis_datasource::features(const query& q) const
std::set<std::string> const& props=q.property_names();
std::set<std::string>::const_iterator pos=props.begin();
std::set<std::string>::const_iterator end=props.end();
while (pos != end)
mapnik::context_ptr ctx = boost::make_shared<mapnik::context>();
for ( ;pos != end;++pos)
{
mapnik::sql_utils::quote_attr(s,*pos);
++pos;
ctx->push(*pos);
}
std::string table_with_bbox = populate_tokens(table_,scale_denom,box);
@ -515,7 +518,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
unsigned num_attr = props.size();
if (!key_field_.empty())
++num_attr;
return boost::make_shared<postgis_featureset>(rs,desc_.get_encoding(), !key_field_.empty(),num_attr);
return boost::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty());
}
else
{
@ -563,13 +566,16 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
if (!key_field_.empty())
mapnik::sql_utils::quote_attr(s,key_field_);
mapnik::context_ptr ctx = boost::make_shared<mapnik::context>();
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
unsigned size=0;
while (itr != end)
for ( ; itr != end; ++itr)
{
mapnik::sql_utils::quote_attr(s,itr->get_name());
++itr;
ctx->push(itr->get_name());
++size;
}
@ -583,7 +589,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
}
boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
return boost::make_shared<postgis_featureset>(rs,desc_.get_encoding(), !key_field_.empty(),size);
return boost::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty());
}
}
return featureset_ptr();

View file

@ -46,13 +46,14 @@ using mapnik::geometry_type;
using mapnik::byte;
using mapnik::geometry_utils;
using mapnik::feature_factory;
using mapnik::context_ptr;
postgis_featureset::postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
context_ptr const& ctx,
std::string const& encoding,
bool key_field=false,
unsigned num_attrs=0)
bool key_field)
: rs_(rs),
num_attrs_(num_attrs),
ctx_(ctx),
tr_(new transcoder(encoding)),
totalGeomSize_(0),
feature_id_(1),
@ -86,15 +87,15 @@ feature_ptr postgis_featureset::next()
{
val = int4net(buf);
}
feature = feature_factory::create(val);
feature = feature_factory::create(ctx_, val);
// TODO - extend feature class to know
// that its id is also an attribute to avoid
// this duplication
boost::put(*feature,name,val);
feature->put(name,val);
++pos;
} else {
// fallback to auto-incrementing id
feature = feature_factory::create(feature_id_);
feature = feature_factory::create(ctx_,feature_id_);
++feature_id_;
}
@ -104,59 +105,59 @@ feature_ptr postgis_featureset::next()
geometry_utils::from_wkb(feature->paths(), data, size);
totalGeomSize_+=size;
for ( ;pos<num_attrs_+1;++pos)
int num_attrs = ctx_->size() + 1;
for ( ; pos < num_attrs; ++pos)
{
std::string name = rs_->getFieldName(pos);
if (rs_->isNull(pos))
{
boost::put(*feature,name,mapnik::value_null());
feature->put(name,mapnik::value_null());
}
else
{
const char* buf = rs_->getValue(pos);
int oid = rs_->getTypeOID(pos);
if (oid==16) //bool
{
boost::put(*feature,name,buf[0] != 0);
feature->put(name,(buf[0] != 0));
}
else if (oid==23) //int4
{
int val = int4net(buf);
boost::put(*feature,name,val);
feature->put(name,val);
}
else if (oid==21) //int2
{
int val = int2net(buf);
boost::put(*feature,name,val);
feature->put(name,val);
}
else if (oid==20) //int8/BigInt
{
int val = int8net(buf);
boost::put(*feature,name,val);
feature->put(name,val);
}
else if (oid == 700) // float4
{
float val;
float4net(val,buf);
boost::put(*feature,name,val);
feature->put(name,val);
}
else if (oid == 701) // float8
{
double val;
float8net(val,buf);
boost::put(*feature,name,val);
feature->put(name,val);
}
else if (oid==25 || oid==1043) // text or varchar
{
UnicodeString ustr = tr_->transcode(buf);
boost::put(*feature,name,ustr);
feature->put(name,tr_->transcode(buf));
}
else if (oid==1042)
{
UnicodeString ustr = tr_->transcode(trim_copy(std::string(buf)).c_str()); // bpchar
boost::put(*feature,name,ustr);
// bpchar
feature->put(name,tr_->transcode(trim_copy(std::string(buf)).c_str()));
}
else if (oid == 1700) // numeric
{
@ -164,7 +165,7 @@ feature_ptr postgis_featureset::next()
try
{
double val = boost::lexical_cast<double>(str);
boost::put(*feature,name,val);
feature->put(name,val);
}
catch (boost::bad_lexical_cast & ex)
{

View file

@ -37,28 +37,27 @@ using mapnik::Featureset;
using mapnik::box2d;
using mapnik::feature_ptr;
using mapnik::transcoder;
using mapnik::context_ptr;
class IResultSet;
class postgis_featureset : public mapnik::Featureset
class postgis_featureset : public mapnik::Featureset,
private boost::noncopyable
{
private:
boost::shared_ptr<IResultSet> rs_;
unsigned num_attrs_;
context_ptr ctx_;
boost::scoped_ptr<mapnik::transcoder> tr_;
int totalGeomSize_;
int feature_id_;
bool key_field_;
public:
postgis_featureset(boost::shared_ptr<IResultSet> const& rs,
context_ptr const& ctx,
std::string const& encoding,
bool key_field,
unsigned num_attrs);
mapnik::feature_ptr next();
bool key_field = false);
feature_ptr next();
~postgis_featureset();
private:
postgis_featureset(const postgis_featureset&);
const postgis_featureset& operator=(const postgis_featureset&);
};
#endif // POSTGIS_FEATURESET_HPP