implement inline (in-memory string) support for GeoJSON plugin - refs #2058
This commit is contained in:
parent
ba1127ea57
commit
7f0029eb0b
3 changed files with 59 additions and 17 deletions
|
@ -101,33 +101,55 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
|||
type_(datasource::Vector),
|
||||
desc_(geojson_datasource::name(),
|
||||
*params.get<std::string>("encoding","utf-8")),
|
||||
file_(*params.get<std::string>("file","")),
|
||||
filename_(),
|
||||
inline_string_(),
|
||||
extent_(),
|
||||
features_(),
|
||||
tree_(16,1)
|
||||
{
|
||||
if (file_.empty()) throw mapnik::datasource_exception("GeoJSON 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("GeoJSON 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_geojson(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("GeoJSON Plugin: could not open: '" + file_ + "'");
|
||||
if (!in.is_open())
|
||||
{
|
||||
throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + filename_ + "'");
|
||||
}
|
||||
parse_geojson(in);
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void geojson_datasource::parse_geojson(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());
|
||||
|
@ -139,7 +161,8 @@ geojson_datasource::geojson_datasource(parameters const& params)
|
|||
bool result = boost::spirit::qi::phrase_parse(begin, end, fc_grammar, space, features_);
|
||||
if (!result)
|
||||
{
|
||||
throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + file_ + "'");
|
||||
if (!inline_string_.empty()) throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file from in-memory string");
|
||||
else throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + filename_ + "'");
|
||||
}
|
||||
|
||||
std::size_t count=0;
|
||||
|
|
|
@ -65,15 +65,18 @@ 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_geojson(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::vector<mapnik::feature_ptr> features_;
|
||||
spatial_index_type tree_;
|
||||
};
|
||||
|
||||
|
||||
#endif // FILE_DATASOURCE_HPP
|
||||
#endif // GEOJSON_DATASOURCE_HPP
|
||||
|
|
|
@ -51,6 +51,22 @@ if 'geojson' 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='geojson',inline='{"type":"LineString","coordinates":[[0,0],[10,10]]}')
|
||||
f = ds.all_features()[0]
|
||||
|
||||
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='geojson',file='../data/json/escaped.geojson')
|
||||
|
|
Loading…
Reference in a new issue