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),
|
type_(datasource::Vector),
|
||||||
desc_(topojson_datasource::name(),
|
desc_(topojson_datasource::name(),
|
||||||
*params.get<std::string>("encoding","utf-8")),
|
*params.get<std::string>("encoding","utf-8")),
|
||||||
file_(*params.get<std::string>("file","")),
|
filename_(),
|
||||||
|
inline_string_(),
|
||||||
extent_(),
|
extent_(),
|
||||||
tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
|
tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
|
||||||
tree_(16,1)
|
tree_(16,1)
|
||||||
{
|
{
|
||||||
if (file_.empty()) throw mapnik::datasource_exception("TopoJSON Plugin: missing <file> parameter");
|
boost::optional<std::string> inline_string = params.get<std::string>("inline");
|
||||||
|
if (inline_string)
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
|
||||||
boost::optional<std::string> base = params.get<std::string>("base");
|
boost::optional<std::string> base = params.get<std::string>("base");
|
||||||
if (base)
|
if (base)
|
||||||
{
|
filename_ = *base + "/" + *file;
|
||||||
file_ = *base + "/" + file_;
|
else
|
||||||
|
filename_ = *file;
|
||||||
}
|
}
|
||||||
|
if (!inline_string_.empty())
|
||||||
using base_iterator_type = std::istreambuf_iterator<char>;
|
{
|
||||||
|
std::istringstream in(inline_string_);
|
||||||
|
parse_topojson(in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined (_WINDOWS)
|
#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
|
#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
|
#endif
|
||||||
if (!is.is_open())
|
if (!in.is_open())
|
||||||
{
|
{
|
||||||
throw mapnik::datasource_exception("TopoJSON Plugin: could not open: '" + file_ + "'");
|
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::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::multi_pass<base_iterator_type> end =
|
||||||
boost::spirit::make_default_multi_pass(base_iterator_type());
|
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_);
|
bool result = boost::spirit::qi::phrase_parse(begin, end, g, space, topo_);
|
||||||
if (!result)
|
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;
|
std::size_t count = 0;
|
||||||
|
|
|
@ -65,11 +65,14 @@ public:
|
||||||
mapnik::box2d<double> envelope() const;
|
mapnik::box2d<double> envelope() const;
|
||||||
mapnik::layer_descriptor get_descriptor() const;
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
|
template <typename T>
|
||||||
|
void parse_topojson(T & stream);
|
||||||
private:
|
private:
|
||||||
mapnik::datasource::datasource_t type_;
|
mapnik::datasource::datasource_t type_;
|
||||||
std::map<std::string, mapnik::parameters> statistics_;
|
std::map<std::string, mapnik::parameters> statistics_;
|
||||||
mapnik::layer_descriptor desc_;
|
mapnik::layer_descriptor desc_;
|
||||||
std::string file_;
|
std::string filename_;
|
||||||
|
std::string inline_string_;
|
||||||
mapnik::box2d<double> extent_;
|
mapnik::box2d<double> extent_;
|
||||||
std::shared_ptr<mapnik::transcoder> tr_;
|
std::shared_ptr<mapnik::transcoder> tr_;
|
||||||
mapnik::topojson::topology topo_;
|
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\xe9bec')
|
||||||
eq_(f['NOM_FR'], u'Québec')
|
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)
|
# @raises(RuntimeError)
|
||||||
def test_that_nonexistant_query_field_throws(**kwargs):
|
def test_that_nonexistant_query_field_throws(**kwargs):
|
||||||
ds = mapnik.Datasource(type='topojson',file='../data/json/escaped.topojson')
|
ds = mapnik.Datasource(type='topojson',file='../data/json/escaped.topojson')
|
||||||
|
|
Loading…
Reference in a new issue