diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index da28f952e..b1701767c 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -90,10 +90,39 @@ class _Projection(Projection,_injector): return forward_(obj,self) def inverse(self,obj): return inverse_(obj,self) - + +def get_types(num): + if num == 1: + return int + elif num == 2: + return float + elif num == 3: + return float + elif num == 4: + return str + elif num == 5: + return Geometry2d + elif num == 6: + return object + class _Datasource(Datasource,_injector): def describe(self): return Describe(self) + def field_types(self): + return map(get_types,self._field_types()) + def all_features(self): + query = Query(self.envelope(),1.0) + for fld in self.fields(): + query.add_property_name(fld) + return self.features(query).features + +class _Feature(Feature,_injector): + @property + def attributes(self): + attr = {} + for prop in self.properties: + attr[prop[0]] = prop[1] + return attr #class _Filter(Filter,_injector): # """Mapnik Filter expression. diff --git a/bindings/python/mapnik_datasource.cpp b/bindings/python/mapnik_datasource.cpp index c2f0da959..45b08cf03 100644 --- a/bindings/python/mapnik_datasource.cpp +++ b/bindings/python/mapnik_datasource.cpp @@ -25,6 +25,8 @@ #include // stl #include +#include + // mapnik #include #include @@ -35,6 +37,8 @@ using mapnik::datasource; using mapnik::point_datasource; +using mapnik::layer_descriptor; +using mapnik::attribute_descriptor; struct ds_pickle_suite : boost::python::pickle_suite { @@ -92,7 +96,52 @@ namespace } return ss.str(); } -} + + std::string encoding(boost::shared_ptr const& ds) + { + layer_descriptor ld = ds->get_descriptor(); + return ld.get_encoding(); + } + + std::string name(boost::shared_ptr const& ds) + { + layer_descriptor ld = ds->get_descriptor(); + return ld.get_name(); + } + + boost::python::list fields(boost::shared_ptr const& ds) + { + boost::python::list flds; + if (ds) + { + layer_descriptor ld = ds->get_descriptor(); + std::vector const& desc_ar = ld.get_descriptors(); + std::vector::const_iterator it = desc_ar.begin(); + std::vector::const_iterator end = desc_ar.end(); + for (; it != end; ++it) + { + flds.append(it->get_name()); + } + } + return flds; + } + boost::python::list field_types(boost::shared_ptr const& ds) + { + boost::python::list fld_types; + if (ds) + { + layer_descriptor ld = ds->get_descriptor(); + std::vector const& desc_ar = ld.get_descriptors(); + std::vector::const_iterator it = desc_ar.begin(); + std::vector::const_iterator end = desc_ar.end(); + for (; it != end; ++it) + { + unsigned type = it->get_type(); + fld_types.append(type); + } + } + return fld_types; + }} void export_datasource() { @@ -104,6 +153,10 @@ void export_datasource() .def("envelope",&datasource::envelope) .def("descriptor",&datasource::get_descriptor) //todo .def("features",&datasource::features) + .def("fields",&fields) + .def("_field_types",&field_types) + .def("encoding",&encoding) //todo expose as property + .def("name",&name) .def("features_at_point",&datasource::features_at_point) .def("params",&datasource::params,return_value_policy(), "The configuration parameters of the data source. " diff --git a/bindings/python/mapnik_feature.cpp b/bindings/python/mapnik_feature.cpp index b2b9e577f..3fc24cfa4 100644 --- a/bindings/python/mapnik_feature.cpp +++ b/bindings/python/mapnik_feature.cpp @@ -221,6 +221,7 @@ void export_feature() // .def("add_geometry", // TODO define more mapnik::Feature methods .def("num_geometries",&Feature::num_geometries) .def("get_geometry", make_function(get_geom1,return_value_policy())) + .def("envelope", &Feature::envelope) ; class_ >("Properties") diff --git a/bindings/python/mapnik_featureset.cpp b/bindings/python/mapnik_featureset.cpp index 979892238..0ded88b3c 100644 --- a/bindings/python/mapnik_featureset.cpp +++ b/bindings/python/mapnik_featureset.cpp @@ -29,18 +29,21 @@ namespace { using namespace boost::python; - inline object pass_through(object const& o) { return o; } - - inline mapnik::feature_ptr next(mapnik::featureset_ptr const& itr) - { - if (!itr) - { - PyErr_SetString(PyExc_StopIteration, "No more features."); - boost::python::throw_error_already_set(); - } - return itr->next(); - } + list features(mapnik::featureset_ptr const& itr) + { + list l; + while (true) + { + mapnik::feature_ptr fp = itr->next(); + if (!fp) + { + break; + } + l.append(fp); + } + return l; + } } void export_featureset() @@ -51,8 +54,6 @@ void export_featureset() class_, boost::noncopyable>("Featureset",no_init) - .def("next",next) - .def("__iter__",pass_through) + .add_property("features",features) ; } - diff --git a/bindings/python/mapnik_map.cpp b/bindings/python/mapnik_map.cpp index 88c06c4fe..204248be2 100644 --- a/bindings/python/mapnik_map.cpp +++ b/bindings/python/mapnik_map.cpp @@ -267,11 +267,11 @@ void export_map() "otherwise will return None.\n" "\n" "Usage:\n" - ">>> feat = m.query_map_point(0,200,200)\n" - ">>> feat\n" - ">>> \n" - ">>> feat.next()\n" - ">>> \n" + ">>> featureset = m.query_map_point(0,200,200)\n" + ">>> featureset\n" + "\n" + ">>> featureset.features\n" + ">>> []\n" ) .def("query_point",&Map::query_point, @@ -282,11 +282,11 @@ void export_map() "otherwise will return None.\n" "\n" "Usage:\n" - ">>> feat = m.query_point(0,-122,48)\n" - ">>> feat\n" - ">>> \n" - ">>> feat.next()\n" - ">>> \n" + ">>> featureset = m.query_point(0,-122,48)\n" + ">>> featureset\n" + "\n" + ">>> featureset.features\n" + ">>> []\n" ) .def("remove_all",&Map::remove_all, diff --git a/include/mapnik/feature.hpp b/include/mapnik/feature.hpp index 518b6f90a..17a4683a0 100644 --- a/include/mapnik/feature.hpp +++ b/include/mapnik/feature.hpp @@ -94,7 +94,26 @@ namespace mapnik { { return geom_cont_[index]; } - + + Envelope envelope() const + { + Envelope result; + for (unsigned i=0;i box = geom.envelope(); + result.init(box.minx(),box.miny(),box.maxx(),box.maxy()); + } + else + { + result.expand_to_include(geom.envelope()); + } + } + return result; + } + const raster_type& get_raster() const { return raster_; diff --git a/tests/python_tests/object_test.py b/tests/python_tests/object_test.py index 09fbeca87..b445431d3 100644 --- a/tests/python_tests/object_test.py +++ b/tests/python_tests/object_test.py @@ -130,7 +130,7 @@ def test_shapefile_init(): # Shapefile properties def test_shapefile_properties(): s = mapnik.Shapefile(file='../../demo/data/boundaries') - f = s.features_at_point(s.envelope().center()).next() + f = s.features_at_point(s.envelope().center()).features[0] eq_(f.properties['CGNS_FID'], u'6f733341ba2011d892e2080020a0f4c9') eq_(f.properties['COUNTRY'], u'CAN')