diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index 3d0e7d158..1a4229eb2 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -196,20 +196,41 @@ void render_to_file1(const mapnik::Map& map, const std::string& filename, const std::string& format) { - mapnik::Image32 image(map.getWidth(),map.getHeight()); - render(map,image,0,0); - mapnik::save_to_file(image,filename,format); + if (format == "pdf" | format == "svg" | format =="ps" | format == "ARGB32" | format == "RGB24") + { +#if defined(HAVE_CAIRO) + mapnik::save_to_cairo_file(map,filename,format); +#else + throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); +#endif + } + else + { + mapnik::Image32 image(map.getWidth(),map.getHeight()); + render(map,image,0,0); + mapnik::save_to_file(image,filename,format); + } } -void render_to_file2(const mapnik::Map& map, - const std::string& filename) +void render_to_file2(const mapnik::Map& map,const std::string& filename) { - mapnik::Image32 image(map.getWidth(),map.getHeight()); - render(map,image,0,0); - mapnik::save_to_file(image,filename); + std::string format = mapnik::guess_type(filename); + if (format == "pdf" | format == "svg" | format =="ps") + { +#if defined(HAVE_CAIRO) + mapnik::save_to_cairo_file(map,filename,format); +#else + throw mapnik::ImageWriterException("Cairo backend not available, cannot write to format: " + format); +#endif + } + else + { + mapnik::Image32 image(map.getWidth(),map.getHeight()); + render(map,image,0,0); + mapnik::save_to_file(image,filename); + } } - double scale_denominator(mapnik::Map const &map, bool geographic) { return mapnik::scale_denominator(map, geographic); diff --git a/include/mapnik/image_util.hpp b/include/mapnik/image_util.hpp index 202eb3ce6..a1b3c69fe 100644 --- a/include/mapnik/image_util.hpp +++ b/include/mapnik/image_util.hpp @@ -27,6 +27,7 @@ // mapnik #include +#include #include // boost @@ -53,6 +54,10 @@ namespace mapnik { } }; + MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map, + std::string const& filename, + std::string const& type); + template MAPNIK_DECL void save_to_file(T const& image, std::string const& filename, @@ -91,12 +96,30 @@ namespace mapnik { return boost::algorithm::iends_with(filename,std::string(".tif")) || boost::algorithm::iends_with(filename,std::string(".tiff")); } - + + inline bool is_pdf (std::string const& filename) + { + return boost::algorithm::iends_with(filename,std::string(".pdf")); + } + + inline bool is_svg (std::string const& filename) + { + return boost::algorithm::iends_with(filename,std::string(".svg")); + } + + inline bool is_ps (std::string const& filename) + { + return boost::algorithm::iends_with(filename,std::string(".ps")); + } + inline std::string type_from_filename(std::string const& filename) { if (is_png(filename)) return "png"; if (is_jpeg(filename)) return "jpeg"; if (is_tiff(filename)) return "tiff"; + if (is_pdf(filename)) return "pdf"; + if (is_svg(filename)) return "svg"; + if (is_ps(filename)) return "ps"; return "unknown"; } diff --git a/src/image_util.cpp b/src/image_util.cpp index c9c2f26c3..cd9968888 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -35,6 +35,10 @@ extern "C" #include #include +#ifdef HAVE_CAIRO +#include +#endif + // stl #include #include @@ -103,8 +107,10 @@ namespace mapnik } } else throw ImageWriterException("unknown file type: " + type); - } + } + else throw ImageWriterException("Could not write file to " + filename ); } + template void save_to_file(T const& image,std::string const& filename) @@ -112,12 +118,66 @@ namespace mapnik std::string type = type_from_filename(filename); save_to_file(image,filename,type); } - + + +#if defined(HAVE_CAIRO) + // TODO - move to separate cairo_io.hpp + void save_to_cairo_file(mapnik::Map const& map, std::string const& filename) + { + std::string type = type_from_filename(filename); + save_to_cairo_file(map,filename,type); + } + + void save_to_cairo_file(mapnik::Map const& map, + std::string const& filename, + std::string const& type) + { + std::ofstream file (filename.c_str(), std::ios::out|std::ios::trunc|std::ios::binary); + if (file) + { + Cairo::RefPtr surface; + unsigned width = map.getWidth(); + unsigned height = map.getHeight(); + if (type == "pdf") + surface = Cairo::PdfSurface::create(filename,width,height); + else if (type == "svg") + surface = Cairo::SvgSurface::create(filename,width,height); + else if (type == "ps") + surface = Cairo::PsSurface::create(filename,width,height); + else if (type == "ARGB32") + surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32,width,height); + else if (type == "RGB24") + surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24,width,height); + else + throw ImageWriterException("unknown file type: " + type); + Cairo::RefPtr context = Cairo::Context::create(surface); + + // TODO - expose as user option + /* + if (type == "ARGB32" | type == "RGB24") + { + context->set_antialias(Cairo::ANTIALIAS_NONE); + } + */ + + + mapnik::cairo_renderer ren(map, context); + ren.apply(); + + if (type == "ARGB32" | type == "RGB24") + { + surface->write_to_png(filename); + } + surface->finish(); + } + } + +#endif template void save_to_file(ImageData32 const&, std::string const&, std::string const&); - + template void save_to_file(ImageData32 const&, std::string const&);