diff --git a/bindings/python/mapnik_map.cpp b/bindings/python/mapnik_map.cpp index 3bc1ca983..ae94c3d57 100644 --- a/bindings/python/mapnik_map.cpp +++ b/bindings/python/mapnik_map.cpp @@ -150,16 +150,17 @@ bool has_metawriter(mapnik::Map const& m) // returns empty shared_ptr when the metawriter isn't found, or is // of the wrong type. empty pointers make it back to Python as a None. -mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map & m, std::string const& name) { - mapnik::metawriter_ptr metawriter = m.find_metawriter(name); - mapnik::metawriter_inmem_ptr inmem; - if (metawriter) { - inmem = boost::dynamic_pointer_cast(metawriter); - } +//mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map & m, std::string const& name) { +// mapnik::metawriter_ptr metawriter = m.find_metawriter(name); +/// mapnik::metawriter_inmem_ptr inmem; - return inmem; -} +// if (metawriter) { +// inmem = boost::dynamic_pointer_cast(metawriter); +// } +// +// return inmem; +//} // TODO - we likely should allow indexing by negative number from python // for now, protect against negative values and kindly throw @@ -482,13 +483,14 @@ void export_map() "\n" "Use a path like \"[z]/[x]/[y].json\" to create filenames.\n" ) - .def("find_inmem_metawriter", find_inmem_metawriter, - (arg("name")), - "Gets an inmem metawriter, or None if no such metawriter " - "exists.\n" - "Use this after the map has been rendered to retrieve information " - "about the hit areas rendered on the map.\n" - ) + +// .def("find_inmem_metawriter", find_inmem_metawriter, + // (arg("name")), + // "Gets an inmem metawriter, or None if no such metawriter " + // "exists.\n" + // "Use this after the map has been rendered to retrieve information " + // "about the hit areas rendered on the map.\n" + // ) .def("__deepcopy__",&map_deepcopy) .add_property("parameters",make_function(params_nonconst,return_value_policy()),"TODO") diff --git a/demo/viewer/mainwindow.cpp b/demo/viewer/mainwindow.cpp index 6ceaf0656..9a8557aa6 100644 --- a/demo/viewer/mainwindow.cpp +++ b/demo/viewer/mainwindow.cpp @@ -39,6 +39,12 @@ #include #include #include +#include +#ifdef HAVE_CAIRO +// cairo +#include +#include +#endif #endif // qt @@ -49,6 +55,8 @@ #include "layerdelegate.hpp" #include "about_dialog.hpp" + + MainWindow::MainWindow() : filename_(), default_extent_(-20037508.3428,-20037508.3428,20037508.3428,20037508.3428) @@ -256,6 +264,56 @@ void MainWindow::export_as() } } +void MainWindow::export_as_pdf() +{ + QAction *action = qobject_cast(sender()); + QString initialPath = QDir::currentPath() + "/mapnik-cairo.pdf"; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export As PDF"), + initialPath, + tr("%1 Files (*.%2);;All Files (*)") + .arg(QString("PDF")) + .arg(QString("pdf"))); + if (!fileName.isEmpty()) + { + std::cout << "FILE NAME:" << fileName.toStdString() << std::endl; +#ifdef HAVE_CAIRO + boost::shared_ptr map_ptr = mapWidget_->getMap(); + if (map_ptr) + { + Cairo::RefPtr surface; + surface = Cairo::PdfSurface::create(fileName.toStdString().c_str(), map_ptr->width(),map_ptr->height()); + mapnik::cairo_renderer pdf_render(*map_ptr, surface); + pdf_render.apply(); + } +#endif + } +} + +void MainWindow::export_as_meta() +{ + QAction *action = qobject_cast(sender()); + QString initialPath = QDir::currentPath() + "/mapnik-meta.json"; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export As Meta JSON"), + initialPath, + tr("%1 Files (*.%2);;All Files (*)") + .arg(QString("META")) + .arg(QString("json"))); + if (!fileName.isEmpty()) + { + std::cout << "FILE NAME:" << fileName.toStdString() << std::endl; +#ifdef HAVE_CAIRO + boost::shared_ptr map_ptr = mapWidget_->getMap(); + if (map_ptr) + { + mapnik::metawriter_renderer ren(*map_ptr); + ren.apply(); + } +#endif + } +} + void MainWindow::print() { @@ -328,6 +386,14 @@ void MainWindow::createActions() exportAsActs.append(action); } + // export PDF + exportPdfAction = new QAction(QString("PDF (cairo)"), this); + connect(exportPdfAction, SIGNAL(triggered()), this, SLOT(export_as_pdf())); + + // export META Json + exportMetaAction = new QAction(QString("META (json)"), this); + connect(exportMetaAction, SIGNAL(triggered()), this, SLOT(export_as_meta())); + printAct = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this); printAct->setShortcut(tr("Ctrl+E")); connect(printAct, SIGNAL(triggered()), this, SLOT(print())); @@ -349,6 +415,8 @@ void MainWindow::createMenus() fileMenu = new QMenu(tr("&File"),this); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); + fileMenu->addAction(exportPdfAction); + fileMenu->addAction(exportMetaAction); fileMenu->addMenu(exportMenu); fileMenu->addAction(printAct); fileMenu->addSeparator(); diff --git a/demo/viewer/mainwindow.hpp b/demo/viewer/mainwindow.hpp index e96fb78f2..d04a1e291 100644 --- a/demo/viewer/mainwindow.hpp +++ b/demo/viewer/mainwindow.hpp @@ -54,6 +54,8 @@ public slots: void pan(); void info(); void export_as(); + void export_as_pdf(); + void export_as_meta(); void open(QString const& path = QString()); void reload(); void save(); @@ -88,6 +90,8 @@ private: QAction *infoAct; QAction *openAct; QAction *saveAct; + QAction *exportPdfAction; + QAction *exportMetaAction; QAction *printAct; QAction *exitAct; QAction *aboutAct; diff --git a/include/mapnik/map.hpp b/include/mapnik/map.hpp index bfbf87edd..2dd184185 100644 --- a/include/mapnik/map.hpp +++ b/include/mapnik/map.hpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include // boost @@ -72,7 +72,7 @@ private: boost::optional background_; boost::optional background_image_; std::map styles_; - std::map metawriters_; + std::map metawriters_; std::map fontsets_; std::vector layers_; aspect_fix_mode aspectFixMode_; @@ -87,7 +87,7 @@ public: typedef std::map::iterator style_iterator; typedef std::map::const_iterator const_fontset_iterator; typedef std::map::iterator fontset_iterator; - typedef std::map::const_iterator const_metawriter_iterator; + typedef std::map::const_iterator const_metawriter_iterator; /*! \brief Default constructor. * @@ -173,7 +173,7 @@ public: * @return true If success. * @return false If no success. */ - bool insert_metawriter(std::string const& name, metawriter_ptr const& writer); + bool insert_metawriter(std::string const& name, metawriter const& writer); /*! \brief Remove a metawriter from the map. * @param name The name of the writer. @@ -184,12 +184,12 @@ public: * @param name The name of the writer. * @return The writer if found. If not found return 0. */ - metawriter_ptr find_metawriter(std::string const& name) const; + metawriter find_metawriter(std::string const& name) const; /*! \brief Get all metawriters. * @return Const reference to metawriters. */ - std::map const& metawriters() const; + std::map const& metawriters() const; /*! \brief Get first iterator in metawriters. * @return Constant metawriter iterator. diff --git a/include/mapnik/metawriter.hpp b/include/mapnik/metawriter.hpp index 693a9059a..b6ea47360 100644 --- a/include/mapnik/metawriter.hpp +++ b/include/mapnik/metawriter.hpp @@ -27,13 +27,12 @@ #include #include #include - // boost #include #include #include #include - +#include // stl #include #include @@ -79,7 +78,7 @@ private: }; -/** All properties to be output by a metawriter. */ +// All properties to be output by a metawriter. class metawriter_properties : public std::set { public: @@ -90,76 +89,23 @@ public: std::string to_string() const; }; -/** Abstract baseclass for all metawriter classes. */ -class metawriter +// Abstract baseclass for all metawriter classes. +class metawriter_base { -public: - typedef coord_transform path_type; - metawriter(metawriter_properties dflt_properties) : +public: + explicit metawriter_base(metawriter_properties dflt_properties) : dflt_properties_(dflt_properties), width_(0), height_(0) {} - virtual ~metawriter() {} - /** Output a rectangular area. - * \param box Area (in pixel coordinates) - * \param feature The feature being processed - * \param prj_trans Projection transformation - * \param t Coordinate transformation - * \param properties List of properties to output - */ - virtual void add_box(box2d const& box, Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties)=0; - virtual void add_text(boost::ptr_vector &placements, - box2d const& extents, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties)=0; - virtual void add_polygon(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties)=0; - virtual void add_line(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties)=0; - - /** Start processing. - * Write file header, init database connection, ... - * - * \param properties metawriter_property_map object with userdefined values. - * Useful for setting filename etc. - */ - virtual void start(metawriter_property_map const& properties) - { - boost::ignore_unused_variable_warning(properties); - } - - /** Stop processing. - * Write file footer, close database connection, ... - */ - virtual void stop() {} - /** Set output size (pixels). - * All features that are completely outside this size are discarded. - */ - void set_size(int width, int height) { width_ = width; height_ = height; } - /** Set Map object's srs. */ - virtual void set_map_srs(projection const& proj) { /* Not required when working with image coordinates. */ } - /** Return the list of default properties. */ + + void set_size(int width, int height) { width_ = width; height_ = height; } metawriter_properties const& get_default_properties() const { return dflt_properties_;} protected: metawriter_properties dflt_properties_; - /** Output width (pixels). */ int width_; - /** Output height (pixels). */ int height_; }; -/** Shared pointer to metawriter object. */ -typedef boost::shared_ptr metawriter_ptr; -/** Metawriter object + properties. */ -typedef std::pair metawriter_with_properties; - } #endif // MAPNIK_METAWRITER_HPP diff --git a/include/mapnik/metawriter_factory.hpp b/include/mapnik/metawriter_factory.hpp index 1af7ff5d7..7acc4924d 100644 --- a/include/mapnik/metawriter_factory.hpp +++ b/include/mapnik/metawriter_factory.hpp @@ -25,28 +25,198 @@ // mapnik #include - +#include +#include // boost #include namespace mapnik { + + class xml_node; +struct is_valid : boost::static_visitor +{ + template + bool operator() (T const& writer_ptr) const + { + return (writer_ptr.get()!=0) ? true : false; + } +}; + +struct add_box_ : boost::static_visitor<> +{ + add_box_(box2d const& box, Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) + : box_(box), + feature_(feature), + t_(t), + properties_(properties) + {} + + template + void operator() (T const& writer_ptr) const + { + return writer_ptr->add_box(box_,feature_,t_, properties_); + } + + box2d const& box_; + Feature const& feature_; + CoordTransform const& t_; + metawriter_properties const& properties_; +}; + + +template +struct add_line_ : boost::static_visitor<> +{ + typedef T path_type; + + add_line_(path_type & path, Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) + : path_(path), + feature_(feature), + t_(t), + properties_(properties) + {} + + template + void operator() (U const& writer_ptr) const + { + return writer_ptr->add_line(path_,feature_,t_, properties_); + } + + path_type & path_; + Feature const& feature_; + CoordTransform const& t_; + metawriter_properties const& properties_; +}; + + +struct start_ : boost::static_visitor<> +{ + start_(metawriter_property_map const& properties) + : properties_(properties) {} + + template + void operator() (U const& writer_ptr) const + { + std::cout << typeid(*writer_ptr).name() << std::endl; + return writer_ptr->start(properties_); + } + metawriter_property_map const& properties_; +}; + +struct set_size_ : boost::static_visitor<> +{ + set_size_(unsigned w, unsigned h) + : w_(w), h_(h) {} + + template + void operator() (U const& writer_ptr) const + { + return writer_ptr->set_size(w_,h_); + } + + unsigned w_; + unsigned h_; +}; + + +struct set_map_srs_ : boost::static_visitor<> +{ + set_map_srs_(projection const& proj) + : proj_(proj) {} + + template + void operator() (U const& writer_ptr) const + { + return writer_ptr->set_map_srs(proj_); + } + + projection const& proj_; +}; + +struct stop_ : boost::static_visitor<> +{ + template + void operator() (U const& writer_ptr) const + { + return writer_ptr->stop(); + } +}; + + +typedef boost::variant metawriter; + +inline bool check_metawriter(metawriter const& m) +{ + return boost::apply_visitor(is_valid(), m); +} + + +inline void add_box(metawriter const& m, + box2d const& box, Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) +{ + add_box_ v(box,feature,t,properties); + boost::apply_visitor(v, m); +} + +template +void add_line(metawriter const& m, + T & path, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) +{ + add_line_ v(path,feature,t,properties); + boost::apply_visitor(v, m); +} + +inline void start(metawriter const& m, metawriter_property_map const& properties ) +{ + start_ v(properties); + boost::apply_visitor(v, m); +} + +inline void stop(metawriter const& m) +{ + boost::apply_visitor(stop_(), m); +} + +inline void set_size(metawriter const& m, unsigned w, unsigned h) +{ + set_size_ v(w,h); + boost::apply_visitor(v, m); +} + +inline void set_map_srs(metawriter const& m, projection const& proj) +{ + set_map_srs_ v(proj); + boost::apply_visitor(v, m); +} + +typedef std::pair metawriter_with_properties; + /** * Creates a metawriter with the properties specified in the property * tree argument. Currently, this is hard-coded to the JSON and inmem * metawriters, but should provide an easy point to make them a * proper factory method if this is wanted in the future. */ -metawriter_ptr metawriter_create(xml_node const& pt); +metawriter metawriter_create(xml_node const& pt); /** * Writes properties into the given property tree representing the * metawriter argument, and which can be used to reconstruct it. */ void metawriter_save( - const metawriter_ptr &m, - boost::property_tree::ptree &pt, + metawriter const& m, + boost::property_tree::ptree & pt, bool explicit_defaults); } diff --git a/include/mapnik/metawriter_inmem.hpp b/include/mapnik/metawriter_inmem.hpp index ee57f2a6b..54b952732 100644 --- a/include/mapnik/metawriter_inmem.hpp +++ b/include/mapnik/metawriter_inmem.hpp @@ -32,6 +32,8 @@ // stl #include +#include +#include namespace mapnik { @@ -50,37 +52,76 @@ namespace mapnik { * very common in the rendered image will increase memory usage, especially if * many attributes are also kept. */ + + +namespace { + +using mapnik::value; +using mapnik::Feature; +using mapnik::metawriter_properties; + +// intersect a set of properties with those in the feature descriptor +std::map intersect_properties(Feature const& feature, metawriter_properties const& properties) +{ + + std::map nprops; + BOOST_FOREACH(std::string p, properties) + { + if (feature.has_key(p)) + nprops.insert(std::make_pair(p,feature.get(p))); + } + + return nprops; +}} // end anonymous namespace + class MAPNIK_DECL metawriter_inmem - : public metawriter, private boost::noncopyable { + : public metawriter_base, private boost::noncopyable +{ public: - /** - * Construct an in-memory writer which keeps properties specified by the - * dflt_properties argument. For example: if dflt_properties contains "name", - * then the name attribute of rendered features referencing this metawriter - * will be kept in memory. - */ metawriter_inmem(metawriter_properties dflt_properties); ~metawriter_inmem(); - virtual void add_box(box2d const& box, Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - virtual void add_text(boost::ptr_vector &placements, - box2d const& extents, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - virtual void add_polygon(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - virtual void add_line(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - - virtual void start(metawriter_property_map const& properties); - + void add_box(box2d const& box, Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties); + void add_text(boost::ptr_vector &placements, + box2d const& extents, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties); + + template + void add_polygon(T & path, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties); + + template + void add_line(T & path, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) + { + box2d box; + unsigned cmd; + double x = 0.0, y = 0.0; + + path.rewind(0); + while ((cmd = path.vertex(&x, &y)) != SEG_END) { + box.expand_to_include(x, y); + } + + if ((box.width() >= 0.0) && (box.height() >= 0.0)) { + meta_instance inst; + inst.properties = intersect_properties(feature, properties); + inst.box = box; + instances_.push_back(inst); + } + } + + void start(metawriter_property_map const& properties); + void stop() {}; + void set_map_srs(projection const& proj) {} /** * An instance of a rendered feature. The box represents the image * coordinates of a bounding box around the feature. The properties @@ -105,7 +146,8 @@ private: std::list instances_; - void add_vertices(path_type & path, + template + void add_vertices(T & path, Feature const& feature, CoordTransform const& t, metawriter_properties const& properties); diff --git a/include/mapnik/metawriter_json.hpp b/include/mapnik/metawriter_json.hpp index 693824921..35a80cd6d 100644 --- a/include/mapnik/metawriter_json.hpp +++ b/include/mapnik/metawriter_json.hpp @@ -35,44 +35,69 @@ namespace mapnik { - -/** Write JSON data to a stream object. */ -class metawriter_json_stream : public metawriter, private boost::noncopyable +class metawriter_json_stream : public metawriter_base, + private boost::noncopyable { public: - metawriter_json_stream(metawriter_properties dflt_properties); + explicit metawriter_json_stream(metawriter_properties dflt_properties); ~metawriter_json_stream(); - virtual void add_box(box2d const& box, Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - virtual void add_text(boost::ptr_vector &placements, - box2d const& extents, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - virtual void add_polygon(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); - virtual void add_line(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties); + void add_box(box2d const& box, Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties); + void add_text(boost::ptr_vector &placements, + box2d const& extents, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties); + template + void add_polygon(T & path, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties); + + template + void add_line(T & path, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) + { + write_feature_header("MultiLineString"); - virtual void start(metawriter_property_map const& properties); - virtual void stop(); - /** Set output stream. This function has to be called before the first output is made. */ - void set_stream(std::ostream *f) { f_ = f; } - /** Get output stream. */ - std::ostream *get_stream() const { return f_; } - /** Only write header/footer to file with one or more features. */ - void set_output_empty(bool output_empty) { output_empty_ = output_empty; } - /** See set_output_empty(). */ + *f_ << " ["; + double x, y, last_x=0.0, last_y=0.0; + unsigned cmd, last_cmd = SEG_END; + path.rewind(0); + + int polygon_count = 0; + while ((cmd = path.vertex(&x, &y)) != SEG_END) { + if (cmd == SEG_LINETO) { + if (last_cmd == SEG_MOVETO) { + //Start new polygon/line + if (polygon_count++) *f_ << "], "; + *f_ << "["; + write_point(t, last_x, last_y, true); + } + *f_ << ","; + write_point(t, x, y, true); + } + last_x = x; + last_y = y; + last_cmd = cmd; + } + *f_ << "]]"; + + write_properties(feature, properties); + } + + void start(metawriter_property_map const& properties); + void stop(); + void set_stream(std::ostream *f) { f_ = f; } + std::ostream *get_stream() const { return f_; } + void set_output_empty(bool output_empty) { output_empty_ = output_empty; } bool get_output_empty() { return output_empty_; } void set_pixel_coordinates(bool on) { pixel_coordinates_ = on; } bool get_pixel_coordinates() { return pixel_coordinates_; } - virtual void set_map_srs(projection const& proj); - + void set_map_srs(projection const& proj); protected: enum { HEADER_NOT_WRITTEN = -1, @@ -87,10 +112,10 @@ protected: proj_transform *trans_; projection output_srs_; bool pixel_coordinates_; - - virtual void write_header(); - - inline void write_feature_header(std::string type) { + + void write_header(); + inline void write_feature_header(std::string type) + { if (count_ == STOPPED) { MAPNIK_LOG_WARN(metawrite_json) << "Metawriter: instance not started before using it."; @@ -116,43 +141,38 @@ protected: *f_ << ","; } } + + template + void write_line_polygon(T & path, CoordTransform const& t, bool polygon); + - void write_line_polygon(path_type & path, CoordTransform const& t, bool polygon); - + + private: std::ostream *f_; }; -/** Shared pointer to metawriter_json_stream object. */ -typedef boost::shared_ptr metawriter_json_stream_ptr; +//typedef boost::shared_ptr metawriter_json_stream_ptr; -/** JSON writer. */ +// JSON writer. class metawriter_json : public metawriter_json_stream { public: metawriter_json(metawriter_properties dflt_properties, path_expression_ptr fn); - - virtual void start(metawriter_property_map const& properties); - virtual void stop(); - /** Set filename template. - * - * This template is processed with values from Map's metawriter properties to - * create the actual filename during start() call. - */ + void start(metawriter_property_map const& properties); + void stop(); void set_filename(path_expression_ptr fn); - /** Get filename template. */ path_expression_ptr get_filename() const; - + private: path_expression_ptr fn_; std::fstream f_; std::string filename_; protected: - virtual void write_header(); + void write_header(); }; -/** Shared pointer to metawriter_json object. */ typedef boost::shared_ptr metawriter_json_ptr; } diff --git a/include/mapnik/metawriter_renderer.hpp b/include/mapnik/metawriter_renderer.hpp new file mode 100644 index 000000000..f3e2b9368 --- /dev/null +++ b/include/mapnik/metawriter_renderer.hpp @@ -0,0 +1,85 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2011 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifndef MAPNIK_METAWRITER_RENDERER_HPP +#define MAPNIK_METAWRITER_RENDERER_HPP + +// mapnik +#include +#include +#include +#include +#include + +// boost +#include +#include +#include +#include + +namespace agg { +struct trans_affine; +} + +namespace mapnik { + +class MAPNIK_DECL metawriter_renderer : public feature_style_processor, + private boost::noncopyable +{ + +public: + typedef metawriter_renderer processor_impl_type; + metawriter_renderer(Map const& m, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); + metawriter_renderer(Map const &m, boost::shared_ptr detector, + double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); + ~metawriter_renderer(); + void start_map_processing(Map const& map); + void end_map_processing(Map const& map); + void start_layer_processing(layer const& lay, box2d const& query_extent); + void end_layer_processing(layer const& lay); + + void start_style_processing(feature_type_style const& st); + void end_style_processing(feature_type_style const& st); + + /* + void process(point_symbolizer const& sym, + mapnik::feature_ptr const& feature, + proj_transform const& prj_trans); + */ + void process(line_symbolizer const& sym, + mapnik::feature_ptr const& feature, + proj_transform const& prj_trans); + void painted(bool painted); +private: + unsigned width_; + unsigned height_; + double scale_factor_; + CoordTransform t_; + freetype_engine font_engine_; + face_manager font_manager_; + boost::shared_ptr detector_; + box2d query_extent_; + void setup(Map const &m); +}; +} + +#endif // MAPNIK_METAWRITER_RENDERER_HPP diff --git a/include/mapnik/symbolizer.hpp b/include/mapnik/symbolizer.hpp index 2141d4833..21d1aa936 100644 --- a/include/mapnik/symbolizer.hpp +++ b/include/mapnik/symbolizer.hpp @@ -26,7 +26,7 @@ // mapnik #include #include -#include +#include #include #include @@ -52,12 +52,8 @@ public: /** Add a metawriter to this symbolizer using a name. */ void add_metawriter(std::string const& name, metawriter_properties const& properties); - /** Add a metawriter to this symbolizer using a pointer. - * The name is only needed if you intend to call save_map() some time. - * You don't need to call cache_metawriters() when using this function. - * Call this function with an NULL writer_ptr to remove a metawriter. - */ - void add_metawriter(metawriter_ptr writer_ptr, + + void add_metawriter(metawriter const& writer, metawriter_properties const& properties = metawriter_properties(), std::string const& name = ""); /** Cache metawriter objects to avoid repeated lookups while processing. @@ -96,7 +92,7 @@ private: metawriter_properties properties_; metawriter_properties properties_complete_; std::string writer_name_; - metawriter_ptr writer_ptr_; + metawriter writer_; composite_mode_e comp_op_; transform_type affine_transform_; bool clip_; diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index cd23e8431..db92b97d7 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -135,8 +135,8 @@ void agg_renderer::process(markers_symbolizer const& sym, // TODO - impl this for markers? //if (!sym.get_ignore_placement()) // detector_->insert(label_ext); - metawriter_with_properties writer = sym.get_metawriter(); - if (writer.first) writer.first->add_box(extent, *feature, t_, writer.second); + //metawriter_with_properties writer = sym.get_metawriter(); + //if (writer.first) writer.first->add_box(extent, *feature, t_, writer.second); } } else @@ -168,12 +168,12 @@ void agg_renderer::process(markers_symbolizer const& sym, // rotated itself } - if (writer.first) - { + //if (writer.first) + //{ //writer.first->add_box(label_ext, feature, t_, writer.second); - MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: metawriter do not yet supported for line placement"; - } + // MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: metawriter do not yet supported for line placement"; + //} } } } @@ -274,7 +274,7 @@ void agg_renderer::process(markers_symbolizer const& sym, } if (!sym.get_ignore_placement()) detector_->insert(label_ext); - if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); + //if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); } } else @@ -315,12 +315,12 @@ void agg_renderer::process(markers_symbolizer const& sym, // TODO - if (writer.first) - { + //if (writer.first) + //{ //writer.first->add_box(label_ext, feature, t_, writer.second); - MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: metawriter do not yet supported for line placement"; - } +// MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: metawriter do not yet supported for line placement"; + //} agg::conv_transform trans(marker, matrix); ras_ptr->add_path(trans); diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp index 28acacc44..a6138557f 100644 --- a/src/agg/process_point_symbolizer.cpp +++ b/src/agg/process_point_symbolizer.cpp @@ -100,8 +100,8 @@ void agg_renderer::process(point_symbolizer const& sym, if (!sym.get_ignore_placement()) detector_->insert(label_ext); - metawriter_with_properties writer = sym.get_metawriter(); - if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); + //metawriter_with_properties writer = sym.get_metawriter(); + //if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); } } } diff --git a/src/build.py b/src/build.py index 2e0e8183f..24be84270 100644 --- a/src/build.py +++ b/src/build.py @@ -273,6 +273,14 @@ source += Split( grid/process_text_symbolizer.cpp """) +# metawriter backend +# grid backend +source += Split( + """ + metawriter/metawriter_renderer.cpp + metawriter/process_line_symbolizer.cpp + """) + if env['SVG_RENDERER']: # svg backend source += Split( """ diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 958faa4ee..15959145d 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -1172,9 +1172,10 @@ void cairo_renderer_base::start_map_processing(Map const& map) if (!sym.get_ignore_placement()) detector_.insert(label_ext); metawriter_with_properties writer = sym.get_metawriter(); - if (writer.first) + if (check_metawriter(writer.first)) { - writer.first->add_box(label_ext, *feature, t_, writer.second); + //writer.first->add_box(label_ext, *feature, t_, writer.second); + add_box(writer.first, label_ext,*feature, t_, writer.second); } } } @@ -1439,7 +1440,11 @@ void cairo_renderer_base::start_map_processing(Map const& map) //if (!sym.get_ignore_placement()) // detector_.insert(label_ext); metawriter_with_properties writer = sym.get_metawriter(); - if (writer.first) writer.first->add_box(extent, *feature, t_, writer.second); + if (check_metawriter(writer.first)) + { + add_box(writer.first, extent,*feature, t_, writer.second); + // writer.first->add_box(extent, *feature, t_, writer.second); + } } } else @@ -1458,7 +1463,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) agg::trans_affine matrix = recenter * tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x, y); render_marker(pixel_position(x - 0.5 * w, y - 0.5 * h), **mark, matrix, sym.get_opacity(),false); - if (writer.first) + if (check_metawriter(writer.first)) { //writer.first->add_box(label_ext, feature, t_, writer.second); MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement"; @@ -1548,7 +1553,11 @@ void cairo_renderer_base::start_map_processing(Map const& map) } if (!sym.get_ignore_placement()) detector_.insert(label_ext); - if (writer.first) writer.first->add_box(label_ext, *feature, t_, writer.second); + if (check_metawriter(writer.first)) + { + add_box(writer.first, label_ext,*feature, t_, writer.second); + // writer.first->add_box(label_ext, *feature, t_, writer.second); + } } } else @@ -1585,7 +1594,7 @@ void cairo_renderer_base::start_map_processing(Map const& map) } // TODO - if (writer.first) + if (check_metawriter(writer.first)) { //writer.first->add_box(label_ext, feature, t_, writer.second); MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement"; diff --git a/src/feature_style_processor.cpp b/src/feature_style_processor.cpp index e7cff4fa7..cb39c9ba4 100644 --- a/src/feature_style_processor.cpp +++ b/src/feature_style_processor.cpp @@ -32,7 +32,7 @@ #include #include #include - +#include // boost #include #include @@ -78,7 +78,7 @@ struct process_impl boost::ignore_unused_variable_warning(f); boost::ignore_unused_variable_warning(tr); #ifdef MAPNIK_DEBUG - std::clog << "NO-OP ...\n"; + std::clog << "NO-OP " << typeid(sym).name() << std::endl; #endif } }; @@ -150,7 +150,7 @@ void feature_style_processor::apply() { projection proj(m_.srs()); - start_metawriters(m_,proj); + //start_metawriters(m_,proj); double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic()); scale_denom *= scale_factor_; @@ -164,7 +164,7 @@ void feature_style_processor::apply() } } - stop_metawriters(m_); + //stop_metawriters(m_); } catch (proj_init_error& ex) { @@ -203,30 +203,6 @@ void feature_style_processor::apply(mapnik::layer const& lyr, std::se p.end_map_processing(m_); } -template -void feature_style_processor::start_metawriters(Map const& m_, projection const& proj) -{ - Map::const_metawriter_iterator metaItr = m_.begin_metawriters(); - Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters(); - for (;metaItr!=metaItrEnd; ++metaItr) - { - metaItr->second->set_size(m_.width(), m_.height()); - metaItr->second->set_map_srs(proj); - metaItr->second->start(m_.metawriter_output_properties); - } -} - -template -void feature_style_processor::stop_metawriters(Map const& m_) -{ - Map::const_metawriter_iterator metaItr = m_.begin_metawriters(); - Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters(); - for (;metaItr!=metaItrEnd; ++metaItr) - { - metaItr->second->stop(); - } -} - template void feature_style_processor::apply_to_layer(layer const& lay, Processor & p, projection const& proj0, @@ -556,7 +532,7 @@ void feature_style_processor::render_style( // if the underlying renderer is not able to process the complete set of symbolizers, // process one by one. - if(!p.process(symbols,feature,prj_trans)) + // if(!p.process(symbols,feature,prj_trans)) { BOOST_FOREACH (symbolizer const& sym, symbols) @@ -584,7 +560,7 @@ void feature_style_processor::render_style( rule::symbolizers const& symbols = r->get_symbolizers(); // if the underlying renderer is not able to process the complete set of symbolizers, // process one by one. - if(!p.process(symbols,feature,prj_trans)) + //if(!p.process(symbols,feature,prj_trans)) { BOOST_FOREACH (symbolizer const& sym, symbols) { @@ -606,7 +582,7 @@ void feature_style_processor::render_style( rule::symbolizers const& symbols = r->get_symbolizers(); // if the underlying renderer is not able to process the complete set of symbolizers, // process one by one. - if(!p.process(symbols,feature,prj_trans)) + //if(!p.process(symbols,feature,prj_trans)) { BOOST_FOREACH (symbolizer const& sym, symbols) { @@ -656,6 +632,7 @@ template class feature_style_processor template class feature_style_processor >; template class feature_style_processor >; +template class feature_style_processor; } diff --git a/src/load_map.cpp b/src/load_map.cpp index bc9a1e5f3..486d4f40e 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -498,7 +498,7 @@ void map_parser::parse_style(Map & map, xml_node const& sty) void map_parser::parse_metawriter(Map & map, xml_node const& pt) { std::string name(""); - metawriter_ptr writer; + metawriter writer; try { name = pt.get_attr("name"); diff --git a/src/map.cpp b/src/map.cpp index 1b7f14905..12ad021bc 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -169,7 +169,7 @@ boost::optional Map::find_style(std::string const& na return boost::optional() ; } -bool Map::insert_metawriter(std::string const& name, metawriter_ptr const& writer) +bool Map::insert_metawriter(std::string const& name, metawriter const& writer) { return metawriters_.insert(make_pair(name, writer)).second; } @@ -179,16 +179,16 @@ void Map::remove_metawriter(std::string const& name) metawriters_.erase(name); } -metawriter_ptr Map::find_metawriter(std::string const& name) const +metawriter Map::find_metawriter(std::string const& name) const { - std::map::const_iterator itr = metawriters_.find(name); + std::map::const_iterator itr = metawriters_.find(name); if (itr != metawriters_.end()) return itr->second; else - return metawriter_ptr(); + return metawriter(); } -std::map const& Map::metawriters() const +std::map const& Map::metawriters() const { return metawriters_; } diff --git a/src/metawriter.cpp b/src/metawriter.cpp index f55298807..306503f4d 100644 --- a/src/metawriter.cpp +++ b/src/metawriter.cpp @@ -97,7 +97,7 @@ metawriter_json_stream::~metawriter_json_stream() metawriter_json_stream::metawriter_json_stream(metawriter_properties dflt_properties) - : metawriter(dflt_properties), count_(-1), output_empty_(true), + : metawriter_base(dflt_properties), count_(-1), output_empty_(true), trans_(0), output_srs_("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"), pixel_coordinates_(false), f_(0) { @@ -262,7 +262,8 @@ void metawriter_json_stream::add_text( } } -void metawriter_json_stream::add_polygon(path_type & path, +template +void metawriter_json_stream::add_polygon(T & path, Feature const& feature, CoordTransform const& t, metawriter_properties const& properties) @@ -272,17 +273,9 @@ void metawriter_json_stream::add_polygon(path_type & path, write_properties(feature, properties); } -void metawriter_json_stream::add_line(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties) -{ - write_feature_header("MultiLineString"); - write_line_polygon(path, t, false); - write_properties(feature, properties); -} -void metawriter_json_stream::write_line_polygon(path_type & path, CoordTransform const& t, bool /*polygon*/){ +template +void metawriter_json_stream::write_line_polygon(T & path, CoordTransform const& t, bool /*polygon*/){ *f_ << " ["; double x, y, last_x=0.0, last_y=0.0; unsigned cmd, last_cmd = SEG_END; @@ -327,7 +320,15 @@ void metawriter_json::start(metawriter_property_map const& properties) MAPNIK_LOG_DEBUG(metawriter) << "metawriter_json: Filename=" << filename_; - metawriter_json_stream::start(properties); + + assert(trans_); + if (output_empty_) { + write_header(); + } else { + count_ = HEADER_NOT_WRITTEN; + } + + //metawriter_json_stream::start(properties); } void metawriter_json::write_header() @@ -337,7 +338,7 @@ void metawriter_json::write_header() { MAPNIK_LOG_DEBUG(metawriter) << "metawriter_json: Failed to open file " << filename_; } - set_stream(&f_); + metawriter_json_stream::set_stream(&f_); metawriter_json_stream::write_header(); } diff --git a/src/metawriter/metawriter_renderer.cpp b/src/metawriter/metawriter_renderer.cpp new file mode 100644 index 000000000..fcc7de662 --- /dev/null +++ b/src/metawriter/metawriter_renderer.cpp @@ -0,0 +1,138 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2011 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// mapnik +#include +#include +#include +#include +#include +#include +#include +#include + +// boost +#include +#include +#include + +// stl +#include + +namespace mapnik +{ + +metawriter_renderer::metawriter_renderer(Map const& m,double scale_factor, unsigned offset_x, unsigned offset_y) + : feature_style_processor(m, scale_factor), + width_(m.width()), + height_(m.height()), + scale_factor_(scale_factor), + t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), + font_engine_(), + font_manager_(font_engine_), + detector_(boost::make_shared(box2d(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))) +{ + setup(m); +} + +metawriter_renderer::metawriter_renderer(Map const& m, boost::shared_ptr detector, + double scale_factor, unsigned offset_x, unsigned offset_y) + : feature_style_processor(m, scale_factor), + width_(m.width()), + height_(m.height()), + scale_factor_(scale_factor), + t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), + font_engine_(), + font_manager_(font_engine_), + detector_(detector) +{ + setup(m); +} + +void metawriter_renderer::setup(Map const &m) +{ + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: Scale=" << m.scale(); +} + +metawriter_renderer::~metawriter_renderer() {} + +void metawriter_renderer::start_map_processing(Map const& m) +{ + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: Start map processing bbox=" << m.get_current_extent(); + + projection proj(m.srs()); + Map::const_metawriter_iterator metaItr = m.begin_metawriters(); + Map::const_metawriter_iterator metaItrEnd = m.end_metawriters(); + for (;metaItr!=metaItrEnd; ++metaItr) + { + set_size(metaItr->second, m.width(), m.height()); + set_map_srs(metaItr->second, proj); + start(metaItr->second, m.metawriter_output_properties); + } +} + +void metawriter_renderer::end_map_processing(Map const& m) +{ + Map::const_metawriter_iterator metaItr = m.begin_metawriters(); + Map::const_metawriter_iterator metaItrEnd = m.end_metawriters(); + for (;metaItr!=metaItrEnd; ++metaItr) + { + stop(metaItr->second); + } + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: End map processing"; +} + +void metawriter_renderer::start_layer_processing(layer const& lay, box2d const& query_extent) +{ + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: Start processing layer=" << lay.name(); + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: -- datasource=" << lay.datasource().get(); + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: -- query_extent=" << query_extent; + + if (lay.clear_label_cache()) + { + detector_->clear(); + } + query_extent_ = query_extent; +} + +void metawriter_renderer::end_layer_processing(layer const&) +{ + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: End layer processing"; +} + +void metawriter_renderer::start_style_processing(feature_type_style const& st) +{ + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: Start processing style"; +} + +void metawriter_renderer::end_style_processing(feature_type_style const& st) +{ + MAPNIK_LOG_DEBUG(metawriter_renderer) << "metawriter_renderer: End processing style"; +} + +void metawriter_renderer::painted(bool painted) +{ + // +} + + +} diff --git a/src/metawriter/process_line_symbolizer.cpp b/src/metawriter/process_line_symbolizer.cpp new file mode 100644 index 000000000..b7104dbb7 --- /dev/null +++ b/src/metawriter/process_line_symbolizer.cpp @@ -0,0 +1,93 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2011 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +// boost +#include +// mapnik +#include +#include +#include +#include + +// stl +#include +#include + +namespace mapnik { + +struct metawriter_wrap +{ + metawriter_wrap(metawriter_with_properties const& w, feature_impl const& f, CoordTransform const& t) + : writer(w), + feature(f), + tr(t) + {} + + template + void add_path(T & path) + { + if (check_metawriter(writer.first)) + { + std::cout << "ADD PATH " << std::endl; + add_line(writer.first, path, feature, tr, writer.second); + } + } + + metawriter_with_properties const& writer; + feature_impl const& feature; + CoordTransform const& tr; +}; + +void metawriter_renderer::process(line_symbolizer const& sym, + mapnik::feature_ptr const& feature, + proj_transform const& prj_trans) + +{ + agg::trans_affine tr; + evaluate_transform(tr, *feature, sym.get_transform()); + metawriter_with_properties writer = sym.get_metawriter(); + metawriter_wrap wrap(writer,*feature,t_); + + typedef boost::mpl::vector conv_types; + + vertex_converter,metawriter_wrap,line_symbolizer,CoordTransform, proj_transform, agg::trans_affine, conv_types> + converter(query_extent_,wrap,sym,t_,prj_trans,tr,scale_factor_); + + if (sym.clip()) converter.set(); // optional clip (default: true) + converter.set(); // always transform + + BOOST_FOREACH( geometry_type & geom, feature->paths()) + { + if (geom.num_points() > 1) + { + converter.apply(geom); + } + } +} + +} diff --git a/src/metawriter_factory.cpp b/src/metawriter_factory.cpp index 2991dc207..c35d03aee 100644 --- a/src/metawriter_factory.cpp +++ b/src/metawriter_factory.cpp @@ -38,42 +38,49 @@ using std::string; namespace mapnik { -metawriter_ptr -metawriter_create(xml_node const& pt) +metawriter metawriter_create(xml_node const& pt) { - metawriter_ptr writer; + metawriter writer; string type = pt.get_attr("type"); - + optional properties = pt.get_opt_attr("default-output"); - if (type == "json") { + if (type == "json") + { string file = pt.get_attr("file"); metawriter_json_ptr json = boost::make_shared(properties, parse_path(file)); optional output_empty = pt.get_opt_attr("output-empty"); - if (output_empty) { + if (output_empty) + { json->set_output_empty(*output_empty); } - + optional pixel_coordinates = pt.get_opt_attr("pixel-coordinates"); - if (pixel_coordinates) { + if (pixel_coordinates) + { json->set_pixel_coordinates(*pixel_coordinates); } writer = json; - } else if (type == "inmem") { + } + else if (type == "inmem") + { metawriter_inmem_ptr inmem = boost::make_shared(properties); writer = inmem; - } else { + } + else + { throw config_error(string("Unknown type '") + type + "'", pt); } - + return writer; } -void -metawriter_save(const metawriter_ptr &metawriter, - boost::property_tree::ptree &metawriter_node, bool explicit_defaults) +void metawriter_save(metawriter const& writer, + boost::property_tree::ptree & metawriter_node, + bool explicit_defaults) { - + // FIXME + /* metawriter_json *json = dynamic_cast(metawriter.get()); if (json) { set_attr(metawriter_node, "type", "json"); @@ -91,6 +98,7 @@ metawriter_save(const metawriter_ptr &metawriter, if (!metawriter->get_default_properties().empty() || explicit_defaults) { set_attr(metawriter_node, "default-output", metawriter->get_default_properties().to_string()); } + */ } } // namespace mapnik diff --git a/src/metawriter_inmem.cpp b/src/metawriter_inmem.cpp index 744b910dc..cc64d55e1 100644 --- a/src/metawriter_inmem.cpp +++ b/src/metawriter_inmem.cpp @@ -28,49 +28,27 @@ // Boost #include -using std::map; -using std::string; - -namespace { - -using mapnik::value; -using mapnik::Feature; -using mapnik::metawriter_properties; - -// intersect a set of properties with those in the feature descriptor -map intersect_properties(Feature const& feature, metawriter_properties const& properties) { - - map nprops; - BOOST_FOREACH(string p, properties) - { - if (feature.has_key(p)) - nprops.insert(std::make_pair(p,feature.get(p))); - } - - return nprops; -}} // end anonymous namespace namespace mapnik { metawriter_inmem::metawriter_inmem(metawriter_properties dflt_properties) - : metawriter(dflt_properties) { + : metawriter_base(dflt_properties) { } metawriter_inmem::~metawriter_inmem() { } -void -metawriter_inmem::add_box(box2d const& box, Feature const& feature, +void metawriter_inmem::add_box(box2d const& box, Feature const& feature, CoordTransform const& /*t*/, - metawriter_properties const& properties) { + metawriter_properties const& properties) +{ meta_instance inst; inst.box = box; inst.properties = intersect_properties(feature, properties); instances_.push_back(inst); } -void -metawriter_inmem::add_text( +void metawriter_inmem::add_text( boost::ptr_vector & /*text*/, box2d const& extents, Feature const& feature, @@ -86,27 +64,21 @@ metawriter_inmem::add_text( } } -void -metawriter_inmem::add_polygon(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties) { +template +void metawriter_inmem::add_polygon(T & path, + Feature const& feature, + CoordTransform const& t, + metawriter_properties const& properties) +{ add_vertices(path, feature, t, properties); } -void -metawriter_inmem::add_line(path_type & path, - Feature const& feature, - CoordTransform const& t, - metawriter_properties const& properties) { - add_vertices(path, feature, t, properties); -} -void -metawriter_inmem::add_vertices(path_type & path, - Feature const& feature, - CoordTransform const& /*t*/, - metawriter_properties const& properties) { +template +void metawriter_inmem::add_vertices(T & path, + Feature const& feature, + CoordTransform const& /*t*/, + metawriter_properties const& properties) { box2d box; unsigned cmd; double x = 0.0, y = 0.0; diff --git a/src/save_map.cpp b/src/save_map.cpp index 15e9cf127..3a1f9a01e 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -698,8 +698,8 @@ void serialize_layer( ptree & map_node, const layer & layer, bool explicit_defau void serialize_metawriter(ptree & map_node, Map::const_metawriter_iterator metawriter_it, bool explicit_defaults) { std::string const& name = metawriter_it->first; - metawriter_ptr const& metawriter = metawriter_it->second; - + metawriter const& metawriter = metawriter_it->second; + ptree & metawriter_node = map_node.push_back( ptree::value_type("MetaWriter", ptree()))->second; diff --git a/src/symbolizer.cpp b/src/symbolizer.cpp index d23b85e09..a83719910 100644 --- a/src/symbolizer.cpp +++ b/src/symbolizer.cpp @@ -48,7 +48,7 @@ symbolizer_base::symbolizer_base() : properties_(), properties_complete_(), writer_name_(), - writer_ptr_(), + writer_(), comp_op_(src_over), clip_(true), smooth_value_(0.0) @@ -57,7 +57,11 @@ symbolizer_base::symbolizer_base() // copy ctor symbolizer_base::symbolizer_base(symbolizer_base const& other) - : comp_op_(other.comp_op_), + : properties_(other.properties_), + properties_complete_(other.properties_complete_), + writer_name_(other.writer_name_), + writer_(other.writer_), + comp_op_(other.comp_op_), affine_transform_(other.affine_transform_), clip_(other.clip_), smooth_value_(other.smooth_value_) {} @@ -68,16 +72,19 @@ void symbolizer_base::add_metawriter(std::string const& name, metawriter_propert properties_ = properties; } -void symbolizer_base::add_metawriter(metawriter_ptr writer_ptr, metawriter_properties const& properties, +void symbolizer_base::add_metawriter(metawriter const& writer, metawriter_properties const& properties, std::string const& name) { - writer_ptr_ = writer_ptr; + writer_ = writer; properties_ = properties; writer_name_ = name; - if (writer_ptr) { - properties_complete_ = writer_ptr->get_default_properties(); + if (check_metawriter(writer)) + { + //properties_complete_ = writer_->get_default_properties(); FIXME properties_complete_.insert(properties_.begin(), properties_.end()); - } else { + } + else + { properties_complete_.clear(); } } @@ -86,15 +93,17 @@ void symbolizer_base::cache_metawriters(Map const &m) { if (writer_name_.empty()) { properties_complete_.clear(); - writer_ptr_ = metawriter_ptr(); return; // No metawriter } - - writer_ptr_ = m.find_metawriter(writer_name_); - if (writer_ptr_) { - properties_complete_ = writer_ptr_->get_default_properties(); + + writer_ = m.find_metawriter(writer_name_); + if (check_metawriter(writer_)) + { + // properties_complete_ = writer_->get_default_properties(); FIXME properties_complete_.insert(properties_.begin(), properties_.end()); - } else { + } + else + { properties_complete_.clear(); MAPNIK_LOG_WARN(symbolizer) << "Metawriter '" << writer_name_ << "' used but not defined."; } @@ -102,7 +111,7 @@ void symbolizer_base::cache_metawriters(Map const &m) metawriter_with_properties symbolizer_base::get_metawriter() const { - return metawriter_with_properties(writer_ptr_, properties_complete_); + return metawriter_with_properties(writer_, properties_complete_); } void symbolizer_base::set_comp_op(composite_mode_e comp_op) diff --git a/src/symbolizer_helpers.cpp b/src/symbolizer_helpers.cpp index 695325cb9..71c391ad9 100644 --- a/src/symbolizer_helpers.cpp +++ b/src/symbolizer_helpers.cpp @@ -71,9 +71,9 @@ bool text_symbolizer_helper::next_line_placement() finder_->update_detector(); } geo_itr_ = geometries_to_process_.erase(geo_itr_); - if (writer_.first) writer_.first->add_text( - finder_->get_results(), finder_->get_extents(), - feature_, t_, writer_.second); + //if (writer_.first) writer_.first->add_text( + // finder_->get_results(), finder_->get_extents(), + // feature_, t_, writer_.second); return true; } //No placement for this geometry. Keep it in geometries_to_process_ for next try. @@ -101,9 +101,9 @@ bool text_symbolizer_helper::next_point_placement() { //Found a placement point_itr_ = points_.erase(point_itr_); - if (writer_.first) writer_.first->add_text( - finder_->get_results(), finder_->get_extents(), - feature_, t_, writer_.second); +// if (writer_.first) writer_.first->add_text( +// finder_->get_results(), finder_->get_extents(), +// feature_, t_, writer_.second); finder_->update_detector(); return true; } @@ -240,7 +240,7 @@ bool text_symbolizer_helper::next_placement() finder_ = boost::shared_ptr >(new placement_finder(feature_, *placement_, *info_, detector_, dims_)); // boost::make_shared >(feature_, *placement_, *info_, detector_, dims_); - if (writer_.first) finder_->set_collect_extents(true); + if (check_metawriter(writer_.first)) finder_->set_collect_extents(true); placement_valid_ = true; return true; @@ -316,11 +316,11 @@ bool shield_symbolizer_helper::next_point_placement() { detector_.insert(marker_ext_); finder_->update_detector(); - if (writer_.first) { - writer_.first->add_box(marker_ext_, feature_, t_, writer_.second); - writer_.first->add_text(finder_->get_results(), finder_->get_extents(), - feature_, t_, writer_.second); - } + //if (writer_.first) { + // writer_.first->add_box(marker_ext_, feature_, t_, writer_.second); + // writer_.first->add_text(finder_->get_results(), finder_->get_extents(), + // feature_, t_, writer_.second); + //} point_itr_ = points_.erase(point_itr_); return true; } @@ -393,7 +393,7 @@ pixel_position shield_symbolizer_helper::get_marker_pos marker_ext_.re_center(lx, ly); //label is added to detector by get_line_placement(), but marker isn't detector_.insert(marker_ext_); - if (writer_.first) writer_.first->add_box(marker_ext_, feature_, t_, writer_.second); + //if (writer_.first) writer_.first->add_box(marker_ext_, feature_, t_, writer_.second); // FIXME return pixel_position(px, py); } else { //collision_detector is already updated for point placement in get_point_placement()