From eebc8cc73eb18903b07e3b3e0757c11925962124 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Sun, 11 Nov 2012 21:35:50 -0800 Subject: [PATCH] add image/grid clear methods to make it easier to quickly re-use previously allocated objects for rendering - closes #1571 --- bindings/python/mapnik_grid.cpp | 1 + bindings/python/mapnik_image.cpp | 1 + include/mapnik/graphics.hpp | 5 ++ include/mapnik/grid/grid.hpp | 2 + src/grid/grid.cpp | 12 +++++ tests/python_tests/buffer_clear_test.py | 63 +++++++++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 tests/python_tests/buffer_clear_test.py diff --git a/bindings/python/mapnik_grid.cpp b/bindings/python/mapnik_grid.cpp index 4bff835c8..6f51c085b 100644 --- a/bindings/python/mapnik_grid.cpp +++ b/bindings/python/mapnik_grid.cpp @@ -66,6 +66,7 @@ void export_grid() .def("height",&mapnik::grid::height) .def("view",&mapnik::grid::get_view) .def("get_pixel",&get_pixel) + .def("clear",&mapnik::grid::clear) .def("encode",encode, ( boost::python::arg("encoding")="utf", boost::python::arg("features")=true,boost::python::arg("resolution")=4 ), "Encode the grid as as optimized json\n" diff --git a/bindings/python/mapnik_image.cpp b/bindings/python/mapnik_image.cpp index ca370eb8a..58ae16ba8 100644 --- a/bindings/python/mapnik_image.cpp +++ b/bindings/python/mapnik_image.cpp @@ -235,6 +235,7 @@ void export_image() .def("demultiply",&image_32::demultiply) .def("set_pixel",&set_pixel) .def("get_pixel",&get_pixel) + .def("clear",&image_32::clear) //TODO(haoyu) The method name 'tostring' might be confusing since they actually return bytes in Python 3 .def("tostring",&tostring1) diff --git a/include/mapnik/graphics.hpp b/include/mapnik/graphics.hpp index a3d04b984..659f4fbca 100644 --- a/include/mapnik/graphics.hpp +++ b/include/mapnik/graphics.hpp @@ -72,6 +72,11 @@ public: return painted_; } + inline void clear() + { + std::memset(data_.getData(),0,sizeof(mapnik::image_data_32::pixel_type)*data_.width()*data_.height()); + } + boost::optional const& get_background() const; void set_background(const color& c); diff --git a/include/mapnik/grid/grid.hpp b/include/mapnik/grid/grid.hpp index 7cd9d0bbc..b8dcf3e42 100644 --- a/include/mapnik/grid/grid.hpp +++ b/include/mapnik/grid/grid.hpp @@ -82,6 +82,8 @@ public: ~hit_grid() {} + void clear(); + inline void painted(bool painted) { painted_ = painted; diff --git a/src/grid/grid.cpp b/src/grid/grid.cpp index 9d870379a..883901656 100644 --- a/src/grid/grid.cpp +++ b/src/grid/grid.cpp @@ -65,6 +65,18 @@ hit_grid::hit_grid(hit_grid const& rhs) data_.set(base_mask); } +template +void hit_grid::clear() +{ + painted_ = false; + f_keys_.clear(); + features_.clear(); + names_.clear(); + f_keys_[base_mask] = ""; + data_.set(base_mask); + ctx_ = boost::make_shared(); +} + template void hit_grid::add_feature(mapnik::feature_impl & feature) { diff --git a/tests/python_tests/buffer_clear_test.py b/tests/python_tests/buffer_clear_test.py new file mode 100644 index 000000000..b508d6628 --- /dev/null +++ b/tests/python_tests/buffer_clear_test.py @@ -0,0 +1,63 @@ +import sys +import os, mapnik +from timeit import Timer, time +from nose.tools import * +from utilities import execution_path + +def setup(): + # All of the paths used are relative, if we run the tests + # from another directory we need to chdir() + os.chdir(execution_path('.')) + +def test_clearing_image_data(): + im = mapnik.Image(256,256) + # make sure it equals itself + bytes = im.tostring() + eq_(im.tostring(),bytes) + # set background, then clear + im.background = mapnik.Color('green') + eq_(im.tostring()!=bytes,True) + # clear image, should now equal original + im.clear() + eq_(im.tostring(),bytes) + +def make_map(): + ds = mapnik.MemoryDatasource() + context = mapnik.Context() + context.push('Name') + pixel_key = 1 + f = mapnik.Feature(context,pixel_key) + f['Name'] = str(pixel_key) + f.add_geometries_from_wkt('POLYGON ((0 0, 0 256, 256 256, 256 0, 0 0))') + ds.add_feature(f) + s = mapnik.Style() + r = mapnik.Rule() + symb = mapnik.PolygonSymbolizer() + r.symbols.append(symb) + s.rules.append(r) + lyr = mapnik.Layer('Places') + lyr.datasource = ds + lyr.styles.append('places_labels') + width,height = 256,256 + m = mapnik.Map(width,height) + m.append_style('places_labels',s) + m.layers.append(lyr) + m.zoom_all() + return m + +def test_clearing_grid_data(): + g = mapnik.Grid(256,256) + utf = g.encode() + # make sure it equals itself + eq_(g.encode(),utf) + m = make_map() + mapnik.render_layer(m,g,layer=0,fields=['__id__','Name']) + eq_(g.encode()!=utf,True) + # clear grid, should now match original + g.clear() + eq_(g.encode(),utf) + + +if __name__ == "__main__": + setup() + [eval(run)() for run in dir() if 'test_' in run] \ No newline at end of file