support for inline topojson (in memory string) - closes #2058
This commit is contained in:
parent
9f9f981731
commit
914b4c2e8b
3 changed files with 58 additions and 16 deletions
|
@ -146,33 +146,55 @@ topojson_datasource::topojson_datasource(parameters const& params)
|
|||
type_(datasource::Vector),
|
||||
desc_(topojson_datasource::name(),
|
||||
*params.get<std::string>("encoding","utf-8")),
|
||||
file_(*params.get<std::string>("file","")),
|
||||
filename_(),
|
||||
inline_string_(),
|
||||
extent_(),
|
||||
tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
|
||||
tree_(16,1)
|
||||
{
|
||||
if (file_.empty()) throw mapnik::datasource_exception("TopoJSON Plugin: missing <file> parameter");
|
||||
|
||||
boost::optional<std::string> base = params.get<std::string>("base");
|
||||
if (base)
|
||||
boost::optional<std::string> inline_string = params.get<std::string>("inline");
|
||||
if (inline_string)
|
||||
{
|
||||
file_ = *base + "/" + file_;
|
||||
inline_string_ = *inline_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::optional<std::string> file = params.get<std::string>("file");
|
||||
if (!file) throw mapnik::datasource_exception("TopoJSON Plugin: missing <file> parameter");
|
||||
|
||||
using base_iterator_type = std::istreambuf_iterator<char>;
|
||||
|
||||
boost::optional<std::string> base = params.get<std::string>("base");
|
||||
if (base)
|
||||
filename_ = *base + "/" + *file;
|
||||
else
|
||||
filename_ = *file;
|
||||
}
|
||||
if (!inline_string_.empty())
|
||||
{
|
||||
std::istringstream in(inline_string_);
|
||||
parse_topojson(in);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (_WINDOWS)
|
||||
std::ifstream is(mapnik::utf8_to_utf16(file_),std::ios_base::in | std::ios_base::binary);
|
||||
std::ifstream in(mapnik::utf8_to_utf16(filename_),std::ios_base::in | std::ios_base::binary);
|
||||
#else
|
||||
std::ifstream is(file_.c_str(),std::ios_base::in | std::ios_base::binary);
|
||||
std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
|
||||
#endif
|
||||
if (!is.is_open())
|
||||
{
|
||||
throw mapnik::datasource_exception("TopoJSON Plugin: could not open: '" + file_ + "'");
|
||||
if (!in.is_open())
|
||||
{
|
||||
throw mapnik::datasource_exception("TopoJSON Plugin: could not open: '" + filename_ + "'");
|
||||
}
|
||||
parse_topojson(in);
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void topojson_datasource::parse_topojson(T & stream)
|
||||
{
|
||||
using base_iterator_type = std::istreambuf_iterator<char>;
|
||||
boost::spirit::multi_pass<base_iterator_type> begin =
|
||||
boost::spirit::make_default_multi_pass(base_iterator_type(is));
|
||||
boost::spirit::make_default_multi_pass(base_iterator_type(stream));
|
||||
|
||||
boost::spirit::multi_pass<base_iterator_type> end =
|
||||
boost::spirit::make_default_multi_pass(base_iterator_type());
|
||||
|
@ -182,7 +204,7 @@ topojson_datasource::topojson_datasource(parameters const& params)
|
|||
bool result = boost::spirit::qi::phrase_parse(begin, end, g, space, topo_);
|
||||
if (!result)
|
||||
{
|
||||
throw mapnik::datasource_exception("topojson_datasource: Failed parse TopoJSON file '" + file_ + "'");
|
||||
throw mapnik::datasource_exception("topojson_datasource: Failed parse TopoJSON file '" + filename_ + "'");
|
||||
}
|
||||
|
||||
std::size_t count = 0;
|
||||
|
|
|
@ -65,11 +65,14 @@ public:
|
|||
mapnik::box2d<double> envelope() const;
|
||||
mapnik::layer_descriptor get_descriptor() const;
|
||||
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||
template <typename T>
|
||||
void parse_topojson(T & stream);
|
||||
private:
|
||||
mapnik::datasource::datasource_t type_;
|
||||
std::map<std::string, mapnik::parameters> statistics_;
|
||||
mapnik::layer_descriptor desc_;
|
||||
std::string file_;
|
||||
std::string filename_;
|
||||
std::string inline_string_;
|
||||
mapnik::box2d<double> extent_;
|
||||
std::shared_ptr<mapnik::transcoder> tr_;
|
||||
mapnik::topojson::topology topo_;
|
||||
|
|
|
@ -54,6 +54,23 @@ if 'topojson' in mapnik.DatasourceCache.plugin_names():
|
|||
eq_(f['NOM_FR'], u'Qu\xe9bec')
|
||||
eq_(f['NOM_FR'], u'Québec')
|
||||
|
||||
def test_geojson_from_in_memory_string():
|
||||
ds = mapnik.Datasource(type='topojson',inline=open('../data/json/escaped.topojson','r').read())
|
||||
f = ds.all_features()[0]
|
||||
eq_(len(ds.fields()),7)
|
||||
|
||||
desc = ds.describe()
|
||||
eq_(desc['geometry_type'],mapnik.DataGeometryType.Point)
|
||||
|
||||
eq_(f['name'], u'Test')
|
||||
eq_(f['int'], 1)
|
||||
eq_(f['description'], u'Test: \u005C')
|
||||
eq_(f['spaces'], u'this has spaces')
|
||||
eq_(f['double'], 1.1)
|
||||
eq_(f['boolean'], True)
|
||||
eq_(f['NOM_FR'], u'Qu\xe9bec')
|
||||
eq_(f['NOM_FR'], u'Québec')
|
||||
|
||||
# @raises(RuntimeError)
|
||||
def test_that_nonexistant_query_field_throws(**kwargs):
|
||||
ds = mapnik.Datasource(type='topojson',file='../data/json/escaped.topojson')
|
||||
|
|
Loading…
Reference in a new issue