finish exposing mapnik.Feature.from_geojson
This commit is contained in:
parent
13343eb5be
commit
78b4980352
16 changed files with 54 additions and 18 deletions
|
@ -8,6 +8,8 @@ For a complete change history, see the git log.
|
||||||
|
|
||||||
## Future
|
## Future
|
||||||
|
|
||||||
|
- Added the ability to create a mapnik Feature from a geojson feature with `mapnik.Feature.from_geojson` in python.
|
||||||
|
|
||||||
- Added to python bindings: `has_tiff`, `has_png`, `has_webp`, `has_proj4`, `has_svg_renderer`, and `has_grid_renderer`
|
- Added to python bindings: `has_tiff`, `has_png`, `has_webp`, `has_proj4`, `has_svg_renderer`, and `has_grid_renderer`
|
||||||
|
|
||||||
- Made it possible to disable compilation of `grid_renderer` with `./configure GRID_RENDERER=False` (#1962)
|
- Made it possible to disable compilation of `grid_renderer` with `./configure GRID_RENDERER=False` (#1962)
|
||||||
|
|
|
@ -30,12 +30,15 @@
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/feature_factory.hpp>
|
||||||
#include <mapnik/feature_kv_iterator.hpp>
|
#include <mapnik/feature_kv_iterator.hpp>
|
||||||
#include <mapnik/datasource.hpp>
|
#include <mapnik/datasource.hpp>
|
||||||
#include <mapnik/wkb.hpp>
|
#include <mapnik/wkb.hpp>
|
||||||
#include <mapnik/wkt/wkt_factory.hpp>
|
#include <mapnik/wkt/wkt_factory.hpp>
|
||||||
|
#include <mapnik/json/feature_parser.hpp>
|
||||||
#include <mapnik/json/geojson_generator.hpp>
|
#include <mapnik/json/geojson_generator.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
|
@ -49,7 +52,7 @@ using mapnik::context_type;
|
||||||
using mapnik::context_ptr;
|
using mapnik::context_ptr;
|
||||||
using mapnik::feature_kv_iterator;
|
using mapnik::feature_kv_iterator;
|
||||||
|
|
||||||
mapnik::geometry_type const& (mapnik::feature_impl::*get_geometry_by_const_ref)(unsigned) const = &mapnik::feature_impl::get_geometry;
|
mapnik::geometry_type const& (mapnik::feature_impl::*get_geometry_by_const_ref)(std::size_t) const = &mapnik::feature_impl::get_geometry;
|
||||||
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::feature_impl::*get_paths_by_const_ref)() const = &mapnik::feature_impl::paths;
|
boost::ptr_vector<mapnik::geometry_type> const& (mapnik::feature_impl::*get_paths_by_const_ref)() const = &mapnik::feature_impl::paths;
|
||||||
|
|
||||||
void feature_add_geometries_from_wkb(mapnik::feature_impl &feature, std::string wkb)
|
void feature_add_geometries_from_wkb(mapnik::feature_impl &feature, std::string wkb)
|
||||||
|
@ -64,6 +67,18 @@ void feature_add_geometries_from_wkt(mapnik::feature_impl &feature, std::string
|
||||||
if (!result) throw std::runtime_error("Failed to parse WKT");
|
if (!result) throw std::runtime_error("Failed to parse WKT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapnik::feature_ptr from_geojson_impl(std::string const& json, mapnik::context_ptr const& ctx)
|
||||||
|
{
|
||||||
|
mapnik::transcoder tr("utf8");
|
||||||
|
mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx,1));
|
||||||
|
mapnik::json::feature_parser<std::string::const_iterator> parser(tr);
|
||||||
|
if (!parser.parse(json.begin(), json.end(), *feature))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to parse geojson feature");
|
||||||
|
}
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
|
||||||
std::string feature_to_geojson(mapnik::feature_impl const& feature)
|
std::string feature_to_geojson(mapnik::feature_impl const& feature)
|
||||||
{
|
{
|
||||||
std::string json;
|
std::string json;
|
||||||
|
@ -232,5 +247,7 @@ void export_feature()
|
||||||
.def("__len__", &mapnik::feature_impl::size)
|
.def("__len__", &mapnik::feature_impl::size)
|
||||||
.def("context",&mapnik::feature_impl::context)
|
.def("context",&mapnik::feature_impl::context)
|
||||||
.def("to_geojson",&feature_to_geojson)
|
.def("to_geojson",&feature_to_geojson)
|
||||||
|
.def("from_geojson",from_geojson_impl)
|
||||||
|
.staticmethod("from_geojson")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,17 +211,17 @@ public:
|
||||||
geom_cont_.push_back(geom);
|
geom_cont_.push_back(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned num_geometries() const
|
std::size_t num_geometries() const
|
||||||
{
|
{
|
||||||
return geom_cont_.size();
|
return geom_cont_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
geometry_type const& get_geometry(unsigned index) const
|
geometry_type const& get_geometry(std::size_t index) const
|
||||||
{
|
{
|
||||||
return geom_cont_[index];
|
return geom_cont_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
geometry_type& get_geometry(unsigned index)
|
geometry_type& get_geometry(std::size_t index)
|
||||||
{
|
{
|
||||||
return geom_cont_[index];
|
return geom_cont_[index];
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned i=0; i<(*pos_)->num_geometries();++i)
|
for (std::size_t i=0; i<(*pos_)->num_geometries();++i)
|
||||||
{
|
{
|
||||||
geometry_type & geom = (*pos_)->get_geometry(i);
|
geometry_type & geom = (*pos_)->get_geometry(i);
|
||||||
if (bbox_.intersects(geom.envelope()))
|
if (bbox_.intersects(geom.envelope()))
|
||||||
|
|
|
@ -86,7 +86,7 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
|
||||||
height = result.to_double() * scale_factor_;
|
height = result.to_double() * scale_factor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i=0;i<feature.num_geometries();++i)
|
for (std::size_t i=0;i<feature.num_geometries();++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature.get_geometry(i);
|
geometry_type const& geom = feature.get_geometry(i);
|
||||||
if (geom.size() > 2)
|
if (geom.size() > 2)
|
||||||
|
|
|
@ -63,7 +63,7 @@ void agg_renderer<T>::process(debug_symbolizer const& sym,
|
||||||
}
|
}
|
||||||
else if (mode == DEBUG_SYM_MODE_VERTEX)
|
else if (mode == DEBUG_SYM_MODE_VERTEX)
|
||||||
{
|
{
|
||||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
for (std::size_t i=0; i<feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature.get_geometry(i);
|
geometry_type const& geom = feature.get_geometry(i);
|
||||||
double x;
|
double x;
|
||||||
|
|
|
@ -74,7 +74,7 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
|
||||||
agg::trans_affine recenter_tr = recenter * tr;
|
agg::trans_affine recenter_tr = recenter * tr;
|
||||||
box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(scale_factor_);
|
box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(scale_factor_);
|
||||||
|
|
||||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
for (std::size_t i=0; i<feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature.get_geometry(i);
|
geometry_type const& geom = feature.get_geometry(i);
|
||||||
double x;
|
double x;
|
||||||
|
|
|
@ -201,6 +201,7 @@ source = Split(
|
||||||
json/geometry_grammar.cpp
|
json/geometry_grammar.cpp
|
||||||
json/geometry_parser.cpp
|
json/geometry_parser.cpp
|
||||||
json/feature_grammar.cpp
|
json/feature_grammar.cpp
|
||||||
|
json/feature_parser.cpp
|
||||||
json/feature_collection_parser.cpp
|
json/feature_collection_parser.cpp
|
||||||
json/geojson_generator.cpp
|
json/geojson_generator.cpp
|
||||||
processed_text.cpp
|
processed_text.cpp
|
||||||
|
|
|
@ -354,7 +354,7 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
|
||||||
height = result.to_double() * scale_factor_;
|
height = result.to_double() * scale_factor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
for (std::size_t i = 0; i < feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature.get_geometry(i);
|
geometry_type const& geom = feature.get_geometry(i);
|
||||||
|
|
||||||
|
@ -673,7 +673,7 @@ void cairo_renderer_base::process(point_symbolizer const& sym,
|
||||||
agg::trans_affine recenter_tr = recenter * tr;
|
agg::trans_affine recenter_tr = recenter * tr;
|
||||||
box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(scale_factor_);
|
box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(scale_factor_);
|
||||||
|
|
||||||
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
for (std::size_t i = 0; i < feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature.get_geometry(i);
|
geometry_type const& geom = feature.get_geometry(i);
|
||||||
double x;
|
double x;
|
||||||
|
@ -760,7 +760,7 @@ void cairo_renderer_base::process(line_pattern_symbolizer const& sym,
|
||||||
pattern.set_filter(CAIRO_FILTER_BILINEAR);
|
pattern.set_filter(CAIRO_FILTER_BILINEAR);
|
||||||
context_.set_line_width(height * scale_factor_);
|
context_.set_line_width(height * scale_factor_);
|
||||||
|
|
||||||
for (unsigned i = 0; i < feature.num_geometries(); ++i)
|
for (std::size_t i = 0; i < feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type & geom = feature.get_geometry(i);
|
geometry_type & geom = feature.get_geometry(i);
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ void grid_renderer<T>::process(building_symbolizer const& sym,
|
||||||
height = result.to_double() * scale_factor_;
|
height = result.to_double() * scale_factor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i=0;i<feature.num_geometries();++i)
|
for (std::size_t i=0;i<feature.num_geometries();++i)
|
||||||
{
|
{
|
||||||
geometry_type & geom = feature.get_geometry(i);
|
geometry_type & geom = feature.get_geometry(i);
|
||||||
if (geom.size() > 2)
|
if (geom.size() > 2)
|
||||||
|
|
|
@ -62,7 +62,7 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
|
||||||
// TODO - actually handle image dimensions
|
// TODO - actually handle image dimensions
|
||||||
int stroke_width = 2;
|
int stroke_width = 2;
|
||||||
|
|
||||||
for (unsigned i=0;i<feature.num_geometries();++i)
|
for (std::size_t i=0;i<feature.num_geometries();++i)
|
||||||
{
|
{
|
||||||
geometry_type & geom = feature.get_geometry(i);
|
geometry_type & geom = feature.get_geometry(i);
|
||||||
if (geom.size() > 1)
|
if (geom.size() > 1)
|
||||||
|
|
|
@ -76,7 +76,7 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
|
||||||
agg::trans_affine recenter_tr = recenter * tr;
|
agg::trans_affine recenter_tr = recenter * tr;
|
||||||
box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(scale_factor_) ;
|
box2d<double> label_ext = bbox * recenter_tr * agg::trans_affine_scaling(scale_factor_) ;
|
||||||
|
|
||||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
for (std::size_t i=0; i<feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature.get_geometry(i);
|
geometry_type const& geom = feature.get_geometry(i);
|
||||||
double x;
|
double x;
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct accumulate_extent
|
||||||
|
|
||||||
void operator() (feature_ptr feat)
|
void operator() (feature_ptr feat)
|
||||||
{
|
{
|
||||||
for (unsigned i=0;i<feat->num_geometries();++i)
|
for (std::size_t i=0;i<feat->num_geometries();++i)
|
||||||
{
|
{
|
||||||
geometry_type & geom = feat->get_geometry(i);
|
geometry_type & geom = feat->get_geometry(i);
|
||||||
if ( first_ )
|
if ( first_ )
|
||||||
|
|
|
@ -71,7 +71,7 @@ bool svg_renderer<OutputIterator>::process(rule::symbolizers const& syms,
|
||||||
if (process_path)
|
if (process_path)
|
||||||
{
|
{
|
||||||
// generate path output for each geometry of the current feature.
|
// generate path output for each geometry of the current feature.
|
||||||
for(unsigned i=0; i<feature.num_geometries(); ++i)
|
for(std::size_t i=0; i<feature.num_geometries(); ++i)
|
||||||
{
|
{
|
||||||
geometry_type & geom = feature.get_geometry(i);
|
geometry_type & geom = feature.get_geometry(i);
|
||||||
if(geom.size() > 0)
|
if(geom.size() > 0)
|
||||||
|
|
|
@ -211,8 +211,8 @@ template <typename FaceManagerT, typename DetectorT>
|
||||||
void text_symbolizer_helper<FaceManagerT, DetectorT>::initialize_geometries()
|
void text_symbolizer_helper<FaceManagerT, DetectorT>::initialize_geometries()
|
||||||
{
|
{
|
||||||
bool largest_box_only = false;
|
bool largest_box_only = false;
|
||||||
unsigned num_geom = feature_.num_geometries();
|
std::size_t num_geom = feature_.num_geometries();
|
||||||
for (unsigned i=0; i<num_geom; ++i)
|
for (std::size_t i=0; i<num_geom; ++i)
|
||||||
{
|
{
|
||||||
geometry_type const& geom = feature_.get_geometry(i);
|
geometry_type const& geom = feature_.get_geometry(i);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,11 @@ from utilities import execution_path, run_all
|
||||||
import mapnik
|
import mapnik
|
||||||
from binascii import unhexlify
|
from binascii import unhexlify
|
||||||
|
|
||||||
|
try:
|
||||||
|
import json
|
||||||
|
except ImportError:
|
||||||
|
import simplejson as json
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
# All of the paths used are relative, if we run the tests
|
# All of the paths used are relative, if we run the tests
|
||||||
# from another directory we need to chdir()
|
# from another directory we need to chdir()
|
||||||
|
@ -222,6 +227,17 @@ def test_wkt_collection_flattening():
|
||||||
# except RuntimeError, e:
|
# except RuntimeError, e:
|
||||||
# raise RuntimeError('%s %s' % (e, wkt))
|
# raise RuntimeError('%s %s' % (e, wkt))
|
||||||
|
|
||||||
|
def test_creating_feature_from_geojson():
|
||||||
|
json_feat = {
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {"type": "Point", "coordinates": [-122,48]},
|
||||||
|
"properties": {"name": "value"}
|
||||||
|
}
|
||||||
|
ctx = mapnik.Context()
|
||||||
|
feat = mapnik.Feature.from_geojson(json.dumps(json_feat),ctx)
|
||||||
|
eq_(feat.id(),1)
|
||||||
|
eq_(feat['name'],u'value')
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup()
|
setup()
|
||||||
run_all(eval(x) for x in dir() if x.startswith("test_"))
|
run_all(eval(x) for x in dir() if x.startswith("test_"))
|
||||||
|
|
Loading…
Reference in a new issue