void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature const& f) const throw() { using namespace boost::spirit; if (col>=0 && col<num_fields_) { std::string name=fields_[col].name_; switch (fields_[col].type_) { case 'C': case 'D'://todo handle date? case 'M': case 'L': { // FIXME - avoid constructing std::string on stack std::string str(record_+fields_[col].offset_,fields_[col].length_); boost::trim(str); f[name] = tr.transcode(str.c_str()); break; } case 'N': case 'F': { if (record_[fields_[col].offset_] == '*') { boost::put(f,name,0); break; } if ( fields_[col].dec_>0 ) { double val = 0.0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; qi::phrase_parse(itr,end,double_,ascii::space,val); boost::put(f,name,val); } else { int val = 0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; qi::phrase_parse(itr,end,int_,ascii::space,val); boost::put(f,name,val); } break; } } } }
#include <mapnik/symbolizer.hpp> #include <mapnik/text/placements/dummy.hpp> #include <mapnik/text/formatting/text.hpp> TEST_CASE("fontset") { SECTION("error") { try { // create a renderable map with a fontset and a text symbolizer // and do not register any fonts, to ensure the error thrown is reasonable mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>(); ctx->push("name"); mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1)); mapnik::transcoder tr("utf-8"); mapnik::value_unicode_string ustr = tr.transcode("hello world!"); feature->put("name",ustr); mapnik::geometry::point<double> pt(128,128); feature->set_geometry(std::move(pt)); mapnik::parameters params; params["type"]="memory"; auto ds = std::make_shared<mapnik::memory_datasource>(params); ds->push(feature); mapnik::Map m(256,256); mapnik::font_set fontset("fontset"); // NOTE: this is a valid font, but will fail because none are registered fontset.add_face_name("DejaVu Sans Book"); m.insert_fontset("fontset", fontset); mapnik::layer lyr("layer");
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, Feature & f) const throw() { using namespace boost::spirit; if (col>=0 && col<num_fields_) { std::string const& name=fields_[col].name_; switch (fields_[col].type_) { case 'C': case 'D': { // FIXME - avoid constructing std::string on stack std::string str(record_+fields_[col].offset_,fields_[col].length_); boost::trim(str); f.put(name,tr.transcode(str.c_str())); break; } case 'L': { char ch = record_[fields_[col].offset_]; if ( ch == '1' || ch == 't' || ch == 'T' || ch == 'y' || ch == 'Y') { f.put(name,true); } else { // NOTE: null logical fields use '?' f.put(name,false); } break; } case 'N': { if (record_[fields_[col].offset_] == '*') { f.put(name,mapnik::value_null()); break; } if ( fields_[col].dec_>0 ) { double val = 0.0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; if (qi::phrase_parse(itr,end,double_,ascii::space,val)) f.put(name,val); } else { mapnik::value_integer val = 0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; if (qi::phrase_parse(itr,end,int_,ascii::space,val)) f.put(name,val); } break; } } } }
return evaluate(*feature, *expr); } std::string parse_and_dump(std::string const& str) { auto expr = mapnik::parse_expression(str); return mapnik::to_expression_string(*expr); } } // namespace TEST_CASE("expressions") { using namespace std::placeholders; using properties_type = std::vector<std::pair<std::string, mapnik::value> > ; mapnik::transcoder tr("utf8"); properties_type prop = {{ "foo" , tr.transcode("bar") }, { "name" , tr.transcode("Québec")}, { "grass" , tr.transcode("grow")}, { "wind" , tr.transcode("blow")}, { "sky" , tr.transcode("is blue")}, { "double", mapnik::value_double(1.23456)}, { "int" , mapnik::value_integer(123)}, { "bool" , mapnik::value_bool(true)}, { "null" , mapnik::value_null()}}; auto feature = make_test_feature(1, "POINT(100 200)", prop); auto eval = std::bind(evaluate_string, feature, _1); auto approx = Approx::custom().epsilon(1e-6);
void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feature_impl & f) const throw() { using namespace boost::spirit; if (col>=0 && col<num_fields_) { std::string const& name=fields_[col].name_; // NOTE: ensure types handled here are matched in shape_datasource.cpp switch (fields_[col].type_) { case 'C': case 'D': { // FIXME - avoid constructing std::string on stack std::string str(record_+fields_[col].offset_,fields_[col].length_); mapnik::util::trim(str); f.put(name,tr.transcode(str.c_str())); break; } case 'L': { char ch = record_[fields_[col].offset_]; if ( ch == '1' || ch == 't' || ch == 'T' || ch == 'y' || ch == 'Y') { f.put(name,true); } else { // NOTE: null logical fields use '?' f.put(name,false); } break; } case 'N': // numeric case 'O': // double case 'F': // float { if (record_[fields_[col].offset_] == '*') { // NOTE: we intentionally do not store null here // since it is equivalent to the attribute not existing break; } if ( fields_[col].dec_>0 ) { double val = 0.0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; ascii::space_type space; static qi::double_type double_; if (qi::phrase_parse(itr,end,double_,space,val)) { f.put(name,val); } } else { mapnik::value_integer val = 0; const char *itr = record_+fields_[col].offset_; const char *end = itr + fields_[col].length_; ascii::space_type space; static qi::int_parser<mapnik::value_integer,10,1,-1> numeric_parser; if (qi::phrase_parse(itr, end, numeric_parser, space, val)) { f.put(name,val); } } break; } } } }