Compare commits
21 commits
master
...
metawriter
Author | SHA1 | Date | |
---|---|---|---|
|
9655491b7f | ||
|
2ac6384992 | ||
|
de7d3383d1 | ||
|
f35584c8ab | ||
|
b8f375a0cd | ||
|
9125ff33ba | ||
|
5f30f85357 | ||
|
a3c4813d73 | ||
|
203e0fd392 | ||
|
49b49362a8 | ||
|
4c45d3c478 | ||
|
a942388bd1 | ||
|
d3b86bbbc6 | ||
|
b1eacdc527 | ||
|
24dc1f60e2 | ||
|
e22b422455 | ||
|
1f15012c3c | ||
|
bca033e358 | ||
|
9c98ced7ad | ||
|
6f14cc4b63 | ||
|
b37212d9a0 |
34 changed files with 1380 additions and 429 deletions
|
@ -102,6 +102,7 @@ PLUGINS = { # plugins with external dependencies
|
||||||
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||||
'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||||
'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||||
|
'geojson': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||||
'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,16 +150,17 @@ bool has_metawriter(mapnik::Map const& m)
|
||||||
|
|
||||||
// returns empty shared_ptr when the metawriter isn't found, or is
|
// 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.
|
// 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) {
|
//mapnik::metawriter_inmem_ptr find_inmem_metawriter(const mapnik::Map & m, std::string const& name) {
|
||||||
inmem = boost::dynamic_pointer_cast<mapnik::metawriter_inmem>(metawriter);
|
// mapnik::metawriter_ptr metawriter = m.find_metawriter(name);
|
||||||
}
|
/// mapnik::metawriter_inmem_ptr inmem;
|
||||||
|
|
||||||
return inmem;
|
// if (metawriter) {
|
||||||
}
|
// inmem = boost::dynamic_pointer_cast<mapnik::metawriter_inmem>(metawriter);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return inmem;
|
||||||
|
//}
|
||||||
|
|
||||||
// TODO - we likely should allow indexing by negative number from python
|
// TODO - we likely should allow indexing by negative number from python
|
||||||
// for now, protect against negative values and kindly throw
|
// for now, protect against negative values and kindly throw
|
||||||
|
@ -482,13 +483,14 @@ void export_map()
|
||||||
"\n"
|
"\n"
|
||||||
"Use a path like \"[z]/[x]/[y].json\" to create filenames.\n"
|
"Use a path like \"[z]/[x]/[y].json\" to create filenames.\n"
|
||||||
)
|
)
|
||||||
.def("find_inmem_metawriter", find_inmem_metawriter,
|
|
||||||
(arg("name")),
|
// .def("find_inmem_metawriter", find_inmem_metawriter,
|
||||||
"Gets an inmem metawriter, or None if no such metawriter "
|
// (arg("name")),
|
||||||
"exists.\n"
|
// "Gets an inmem metawriter, or None if no such metawriter "
|
||||||
"Use this after the map has been rendered to retrieve information "
|
// "exists.\n"
|
||||||
"about the hit areas rendered on the map.\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)
|
.def("__deepcopy__",&map_deepcopy)
|
||||||
.add_property("parameters",make_function(params_nonconst,return_value_policy<reference_existing_object>()),"TODO")
|
.add_property("parameters",make_function(params_nonconst,return_value_policy<reference_existing_object>()),"TODO")
|
||||||
|
|
|
@ -39,6 +39,12 @@
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/load_map.hpp>
|
#include <mapnik/load_map.hpp>
|
||||||
#include <mapnik/save_map.hpp>
|
#include <mapnik/save_map.hpp>
|
||||||
|
#include <mapnik/metawriter_renderer.hpp>
|
||||||
|
#ifdef HAVE_CAIRO
|
||||||
|
// cairo
|
||||||
|
#include <mapnik/cairo_renderer.hpp>
|
||||||
|
#include <cairomm/surface.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// qt
|
// qt
|
||||||
|
@ -49,6 +55,8 @@
|
||||||
#include "layerdelegate.hpp"
|
#include "layerdelegate.hpp"
|
||||||
#include "about_dialog.hpp"
|
#include "about_dialog.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: filename_(),
|
: filename_(),
|
||||||
default_extent_(-20037508.3428,-20037508.3428,20037508.3428,20037508.3428)
|
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<QAction *>(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<mapnik::Map> map_ptr = mapWidget_->getMap();
|
||||||
|
if (map_ptr)
|
||||||
|
{
|
||||||
|
Cairo::RefPtr<Cairo::Surface> surface;
|
||||||
|
surface = Cairo::PdfSurface::create(fileName.toStdString().c_str(), map_ptr->width(),map_ptr->height());
|
||||||
|
mapnik::cairo_renderer<Cairo::Surface> pdf_render(*map_ptr, surface);
|
||||||
|
pdf_render.apply();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::export_as_meta()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(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<mapnik::Map> map_ptr = mapWidget_->getMap();
|
||||||
|
if (map_ptr)
|
||||||
|
{
|
||||||
|
mapnik::metawriter_renderer ren(*map_ptr);
|
||||||
|
ren.apply();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::print()
|
void MainWindow::print()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -328,6 +386,14 @@ void MainWindow::createActions()
|
||||||
exportAsActs.append(action);
|
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 = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this);
|
||||||
printAct->setShortcut(tr("Ctrl+E"));
|
printAct->setShortcut(tr("Ctrl+E"));
|
||||||
connect(printAct, SIGNAL(triggered()), this, SLOT(print()));
|
connect(printAct, SIGNAL(triggered()), this, SLOT(print()));
|
||||||
|
@ -349,6 +415,8 @@ void MainWindow::createMenus()
|
||||||
fileMenu = new QMenu(tr("&File"),this);
|
fileMenu = new QMenu(tr("&File"),this);
|
||||||
fileMenu->addAction(openAct);
|
fileMenu->addAction(openAct);
|
||||||
fileMenu->addAction(saveAct);
|
fileMenu->addAction(saveAct);
|
||||||
|
fileMenu->addAction(exportPdfAction);
|
||||||
|
fileMenu->addAction(exportMetaAction);
|
||||||
fileMenu->addMenu(exportMenu);
|
fileMenu->addMenu(exportMenu);
|
||||||
fileMenu->addAction(printAct);
|
fileMenu->addAction(printAct);
|
||||||
fileMenu->addSeparator();
|
fileMenu->addSeparator();
|
||||||
|
|
|
@ -54,6 +54,8 @@ public slots:
|
||||||
void pan();
|
void pan();
|
||||||
void info();
|
void info();
|
||||||
void export_as();
|
void export_as();
|
||||||
|
void export_as_pdf();
|
||||||
|
void export_as_meta();
|
||||||
void open(QString const& path = QString());
|
void open(QString const& path = QString());
|
||||||
void reload();
|
void reload();
|
||||||
void save();
|
void save();
|
||||||
|
@ -88,6 +90,8 @@ private:
|
||||||
QAction *infoAct;
|
QAction *infoAct;
|
||||||
QAction *openAct;
|
QAction *openAct;
|
||||||
QAction *saveAct;
|
QAction *saveAct;
|
||||||
|
QAction *exportPdfAction;
|
||||||
|
QAction *exportMetaAction;
|
||||||
QAction *printAct;
|
QAction *printAct;
|
||||||
QAction *exitAct;
|
QAction *exitAct;
|
||||||
QAction *aboutAct;
|
QAction *aboutAct;
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct feature_collection_grammar :
|
||||||
features = lit("\"features\"")
|
features = lit("\"features\"")
|
||||||
> lit(":")
|
> lit(":")
|
||||||
> lit('[')
|
> lit('[')
|
||||||
> feature(_val) % lit(',')
|
> -(feature(_val) % lit(','))
|
||||||
> lit(']')
|
> lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ struct feature_grammar :
|
||||||
using qi::_pass;
|
using qi::_pass;
|
||||||
using qi::eps;
|
using qi::eps;
|
||||||
using qi::raw;
|
using qi::raw;
|
||||||
|
|
||||||
using phoenix::new_;
|
using phoenix::new_;
|
||||||
using phoenix::push_back;
|
using phoenix::push_back;
|
||||||
using phoenix::construct;
|
using phoenix::construct;
|
||||||
|
@ -197,7 +197,7 @@ struct feature_grammar :
|
||||||
unesc_char.add
|
unesc_char.add
|
||||||
("\\\"", '\"') // quotation mark
|
("\\\"", '\"') // quotation mark
|
||||||
("\\\\", '\\') // reverse solidus
|
("\\\\", '\\') // reverse solidus
|
||||||
("\\/", '/') // solidus
|
("\\/", '/') // solidus
|
||||||
("\\b", '\b') // backspace
|
("\\b", '\b') // backspace
|
||||||
("\\f", '\f') // formfeed
|
("\\f", '\f') // formfeed
|
||||||
("\\n", '\n') // newline
|
("\\n", '\n') // newline
|
||||||
|
@ -207,7 +207,7 @@ struct feature_grammar :
|
||||||
|
|
||||||
string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"')
|
string_ %= lit('"') >> *(unesc_char | "\\u" >> hex4 | (char_ - lit('"'))) >> lit('"')
|
||||||
;
|
;
|
||||||
|
|
||||||
// geojson types
|
// geojson types
|
||||||
|
|
||||||
feature_type = lit("\"type\"")
|
feature_type = lit("\"type\"")
|
||||||
|
@ -244,17 +244,17 @@ struct feature_grammar :
|
||||||
// ;
|
// ;
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
geometry = (lit('{')[_a = 0 ]
|
geometry = (lit('{')[_a = 0 ]
|
||||||
>> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick!
|
>> lit("\"type\"") >> lit(':') >> geometry_dispatch[_a = _1] // <---- should be Nabialek trick!
|
||||||
>> lit(',')
|
>> lit(',')
|
||||||
>> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a)
|
>> (lit("\"coordinates\"") > lit(':') > coordinates(_r1,_a)
|
||||||
|
|
|
|
||||||
lit("\"geometries\"") > lit(':')
|
lit("\"geometries\"") > lit(':')
|
||||||
>> lit('[') >> geometry_collection(_r1) >> lit(']'))
|
>> lit('[') >> geometry_collection(_r1) >> lit(']'))
|
||||||
>> lit('}'))
|
>> lit('}'))
|
||||||
| lit("null")
|
| lit("null")
|
||||||
;
|
;
|
||||||
|
|
||||||
geometry_dispatch.add
|
geometry_dispatch.add
|
||||||
("\"Point\"",1)
|
("\"Point\"",1)
|
||||||
("\"LineString\"",2)
|
("\"LineString\"",2)
|
||||||
|
@ -265,7 +265,7 @@ struct feature_grammar :
|
||||||
("\"GeometryCollection\"",7)
|
("\"GeometryCollection\"",7)
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
|
|
||||||
coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)))
|
coordinates = (eps(_r2 == 1) > point_coordinates(extract_geometry_(_r1)))
|
||||||
| (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)))
|
| (eps(_r2 == 2) > linestring_coordinates(extract_geometry_(_r1)))
|
||||||
| (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)))
|
| (eps(_r2 == 3) > polygon_coordinates(extract_geometry_(_r1)))
|
||||||
|
@ -273,46 +273,45 @@ struct feature_grammar :
|
||||||
| (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)))
|
| (eps(_r2 == 5) > multilinestring_coordinates(extract_geometry_(_r1)))
|
||||||
| (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)))
|
| (eps(_r2 == 6) > multipolygon_coordinates(extract_geometry_(_r1)))
|
||||||
;
|
;
|
||||||
|
|
||||||
point_coordinates = eps[ _a = new_<geometry_type>(Point) ]
|
point_coordinates = eps[ _a = new_<geometry_type>(Point) ]
|
||||||
> ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] )
|
> ( point(SEG_MOVETO,_a) [push_back(_r1,_a)] | eps[cleanup_(_a)][_pass = false] )
|
||||||
;
|
;
|
||||||
|
|
||||||
linestring_coordinates = eps[ _a = new_<geometry_type>(LineString)]
|
linestring_coordinates = eps[ _a = new_<geometry_type>(LineString)]
|
||||||
> (points(_a) [push_back(_r1,_a)]
|
> -(points(_a) [push_back(_r1,_a)]
|
||||||
| eps[cleanup_(_a)][_pass = false])
|
| eps[cleanup_(_a)][_pass = false])
|
||||||
;
|
;
|
||||||
|
|
||||||
polygon_coordinates = eps[ _a = new_<geometry_type>(Polygon) ]
|
polygon_coordinates = eps[ _a = new_<geometry_type>(Polygon) ]
|
||||||
> ((lit('[')
|
> ((lit('[')
|
||||||
> points(_a) % lit(',')
|
> -(points(_a) % lit(','))
|
||||||
> lit(']')) [push_back(_r1,_a)]
|
> lit(']')) [push_back(_r1,_a)]
|
||||||
| eps[cleanup_(_a)][_pass = false])
|
| eps[cleanup_(_a)][_pass = false])
|
||||||
;
|
;
|
||||||
|
|
||||||
multipoint_coordinates = lit('[')
|
multipoint_coordinates = lit('[')
|
||||||
> (point_coordinates(_r1) % lit(','))
|
> -(point_coordinates(_r1) % lit(','))
|
||||||
> lit(']')
|
> lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
multilinestring_coordinates = lit('[')
|
multilinestring_coordinates = lit('[')
|
||||||
> (linestring_coordinates(_r1) % lit(','))
|
> -(linestring_coordinates(_r1) % lit(','))
|
||||||
> lit(']')
|
> lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
multipolygon_coordinates = lit('[')
|
multipolygon_coordinates = lit('[')
|
||||||
> (polygon_coordinates(_r1) % lit(','))
|
> -(polygon_coordinates(_r1) % lit(','))
|
||||||
> lit(']')
|
> lit(']')
|
||||||
;
|
;
|
||||||
|
|
||||||
geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1))
|
geometry_collection = *geometry(_r1) >> *(lit(',') >> geometry(_r1))
|
||||||
;
|
;
|
||||||
|
|
||||||
// point
|
|
||||||
point = (lit('[') > double_ > lit(',') > double_ > lit(']')) [push_vertex_(_r1,_r2,_1,_2)];
|
|
||||||
// points
|
|
||||||
points = lit('[')[_a = SEG_MOVETO] > point (_a,_r1) % lit(',') [_a = SEG_LINETO] > lit(']');
|
|
||||||
|
|
||||||
|
// point
|
||||||
|
point = lit('[') > -((double_ > lit(',') > double_)[push_vertex_(_r1,_r2,_1,_2)]) > lit(']');
|
||||||
|
// points
|
||||||
|
points = lit('[')[_a = SEG_MOVETO] > -(point (_a,_r1) % lit(',')[_a = SEG_LINETO]) > lit(']');
|
||||||
on_error<fail>
|
on_error<fail>
|
||||||
(
|
(
|
||||||
feature
|
feature
|
||||||
|
@ -362,7 +361,7 @@ struct feature_grammar :
|
||||||
qi::rule<Iterator,qi::locals<geometry_type*>,
|
qi::rule<Iterator,qi::locals<geometry_type*>,
|
||||||
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> linestring_coordinates;
|
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> linestring_coordinates;
|
||||||
qi::rule<Iterator,qi::locals<geometry_type*>,
|
qi::rule<Iterator,qi::locals<geometry_type*>,
|
||||||
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> polygon_coordinates;
|
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> polygon_coordinates;
|
||||||
|
|
||||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipoint_coordinates;
|
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipoint_coordinates;
|
||||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multilinestring_coordinates;
|
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multilinestring_coordinates;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <mapnik/feature_type_style.hpp>
|
#include <mapnik/feature_type_style.hpp>
|
||||||
#include <mapnik/datasource.hpp>
|
#include <mapnik/datasource.hpp>
|
||||||
#include <mapnik/layer.hpp>
|
#include <mapnik/layer.hpp>
|
||||||
#include <mapnik/metawriter.hpp>
|
#include <mapnik/metawriter_factory.hpp>
|
||||||
#include <mapnik/params.hpp>
|
#include <mapnik/params.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
@ -72,7 +72,7 @@ private:
|
||||||
boost::optional<color> background_;
|
boost::optional<color> background_;
|
||||||
boost::optional<std::string> background_image_;
|
boost::optional<std::string> background_image_;
|
||||||
std::map<std::string,feature_type_style> styles_;
|
std::map<std::string,feature_type_style> styles_;
|
||||||
std::map<std::string,metawriter_ptr> metawriters_;
|
std::map<std::string,metawriter> metawriters_;
|
||||||
std::map<std::string,font_set> fontsets_;
|
std::map<std::string,font_set> fontsets_;
|
||||||
std::vector<layer> layers_;
|
std::vector<layer> layers_;
|
||||||
aspect_fix_mode aspectFixMode_;
|
aspect_fix_mode aspectFixMode_;
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
typedef std::map<std::string,feature_type_style>::iterator style_iterator;
|
typedef std::map<std::string,feature_type_style>::iterator style_iterator;
|
||||||
typedef std::map<std::string,font_set>::const_iterator const_fontset_iterator;
|
typedef std::map<std::string,font_set>::const_iterator const_fontset_iterator;
|
||||||
typedef std::map<std::string,font_set>::iterator fontset_iterator;
|
typedef std::map<std::string,font_set>::iterator fontset_iterator;
|
||||||
typedef std::map<std::string,metawriter_ptr>::const_iterator const_metawriter_iterator;
|
typedef std::map<std::string,metawriter>::const_iterator const_metawriter_iterator;
|
||||||
|
|
||||||
/*! \brief Default constructor.
|
/*! \brief Default constructor.
|
||||||
*
|
*
|
||||||
|
@ -173,7 +173,7 @@ public:
|
||||||
* @return true If success.
|
* @return true If success.
|
||||||
* @return false If no 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.
|
/*! \brief Remove a metawriter from the map.
|
||||||
* @param name The name of the writer.
|
* @param name The name of the writer.
|
||||||
|
@ -184,12 +184,12 @@ public:
|
||||||
* @param name The name of the writer.
|
* @param name The name of the writer.
|
||||||
* @return The writer if found. If not found return 0.
|
* @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.
|
/*! \brief Get all metawriters.
|
||||||
* @return Const reference to metawriters.
|
* @return Const reference to metawriters.
|
||||||
*/
|
*/
|
||||||
std::map<std::string,metawriter_ptr> const& metawriters() const;
|
std::map<std::string,metawriter> const& metawriters() const;
|
||||||
|
|
||||||
/*! \brief Get first iterator in metawriters.
|
/*! \brief Get first iterator in metawriters.
|
||||||
* @return Constant metawriter iterator.
|
* @return Constant metawriter iterator.
|
||||||
|
|
|
@ -27,13 +27,12 @@
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/ctrans.hpp>
|
#include <mapnik/ctrans.hpp>
|
||||||
#include <mapnik/projection.hpp>
|
#include <mapnik/projection.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/concept_check.hpp>
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -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<std::string>
|
class metawriter_properties : public std::set<std::string>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -90,76 +89,23 @@ public:
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Abstract baseclass for all metawriter classes. */
|
// Abstract baseclass for all metawriter classes.
|
||||||
class metawriter
|
class metawriter_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef coord_transform<CoordTransform,geometry_type> path_type;
|
explicit metawriter_base(metawriter_properties dflt_properties) :
|
||||||
metawriter(metawriter_properties dflt_properties) :
|
|
||||||
dflt_properties_(dflt_properties),
|
dflt_properties_(dflt_properties),
|
||||||
width_(0),
|
width_(0),
|
||||||
height_(0) {}
|
height_(0) {}
|
||||||
virtual ~metawriter() {}
|
|
||||||
/** Output a rectangular area.
|
void set_size(int width, int height) { width_ = width; height_ = height; }
|
||||||
* \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<double> const& box, Feature const& feature,
|
|
||||||
CoordTransform const& t,
|
|
||||||
metawriter_properties const& properties)=0;
|
|
||||||
virtual void add_text(boost::ptr_vector<text_path> &placements,
|
|
||||||
box2d<double> 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. */
|
|
||||||
metawriter_properties const& get_default_properties() const { return dflt_properties_;}
|
metawriter_properties const& get_default_properties() const { return dflt_properties_;}
|
||||||
protected:
|
protected:
|
||||||
metawriter_properties dflt_properties_;
|
metawriter_properties dflt_properties_;
|
||||||
/** Output width (pixels). */
|
|
||||||
int width_;
|
int width_;
|
||||||
/** Output height (pixels). */
|
|
||||||
int height_;
|
int height_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shared pointer to metawriter object. */
|
|
||||||
typedef boost::shared_ptr<metawriter> metawriter_ptr;
|
|
||||||
/** Metawriter object + properties. */
|
|
||||||
typedef std::pair<metawriter_ptr, metawriter_properties> metawriter_with_properties;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MAPNIK_METAWRITER_HPP
|
#endif // MAPNIK_METAWRITER_HPP
|
||||||
|
|
|
@ -25,28 +25,198 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/metawriter.hpp>
|
#include <mapnik/metawriter.hpp>
|
||||||
|
#include <mapnik/metawriter_json.hpp>
|
||||||
|
#include <mapnik/metawriter_inmem.hpp>
|
||||||
// boost
|
// boost
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
|
||||||
class xml_node;
|
class xml_node;
|
||||||
|
|
||||||
|
struct is_valid : boost::static_visitor<bool>
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
bool operator() (T const& writer_ptr) const
|
||||||
|
{
|
||||||
|
return (writer_ptr.get()!=0) ? true : false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct add_box_ : boost::static_visitor<>
|
||||||
|
{
|
||||||
|
add_box_(box2d<double> const& box, Feature const& feature,
|
||||||
|
CoordTransform const& t,
|
||||||
|
metawriter_properties const& properties)
|
||||||
|
: box_(box),
|
||||||
|
feature_(feature),
|
||||||
|
t_(t),
|
||||||
|
properties_(properties)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator() (T const& writer_ptr) const
|
||||||
|
{
|
||||||
|
return writer_ptr->add_box(box_,feature_,t_, properties_);
|
||||||
|
}
|
||||||
|
|
||||||
|
box2d<double> const& box_;
|
||||||
|
Feature const& feature_;
|
||||||
|
CoordTransform const& t_;
|
||||||
|
metawriter_properties const& properties_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
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 <typename U>
|
||||||
|
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 <typename U>
|
||||||
|
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 <typename U>
|
||||||
|
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 <typename U>
|
||||||
|
void operator() (U const& writer_ptr) const
|
||||||
|
{
|
||||||
|
return writer_ptr->set_map_srs(proj_);
|
||||||
|
}
|
||||||
|
|
||||||
|
projection const& proj_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stop_ : boost::static_visitor<>
|
||||||
|
{
|
||||||
|
template <typename U>
|
||||||
|
void operator() (U const& writer_ptr) const
|
||||||
|
{
|
||||||
|
return writer_ptr->stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef boost::variant<metawriter_json_ptr, metawriter_inmem_ptr> metawriter;
|
||||||
|
|
||||||
|
inline bool check_metawriter(metawriter const& m)
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(is_valid(), m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void add_box(metawriter const& m,
|
||||||
|
box2d<double> 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 <typename T>
|
||||||
|
void add_line(metawriter const& m,
|
||||||
|
T & path,
|
||||||
|
Feature const& feature,
|
||||||
|
CoordTransform const& t,
|
||||||
|
metawriter_properties const& properties)
|
||||||
|
{
|
||||||
|
add_line_<T> 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, metawriter_properties> metawriter_with_properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a metawriter with the properties specified in the property
|
* Creates a metawriter with the properties specified in the property
|
||||||
* tree argument. Currently, this is hard-coded to the JSON and inmem
|
* tree argument. Currently, this is hard-coded to the JSON and inmem
|
||||||
* metawriters, but should provide an easy point to make them a
|
* metawriters, but should provide an easy point to make them a
|
||||||
* proper factory method if this is wanted in the future.
|
* 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
|
* Writes properties into the given property tree representing the
|
||||||
* metawriter argument, and which can be used to reconstruct it.
|
* metawriter argument, and which can be used to reconstruct it.
|
||||||
*/
|
*/
|
||||||
void metawriter_save(
|
void metawriter_save(
|
||||||
const metawriter_ptr &m,
|
metawriter const& m,
|
||||||
boost::property_tree::ptree &pt,
|
boost::property_tree::ptree & pt,
|
||||||
bool explicit_defaults);
|
bool explicit_defaults);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
@ -50,37 +52,76 @@ namespace mapnik {
|
||||||
* very common in the rendered image will increase memory usage, especially if
|
* very common in the rendered image will increase memory usage, especially if
|
||||||
* many attributes are also kept.
|
* 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<std::string,value> intersect_properties(Feature const& feature, metawriter_properties const& properties)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::map<std::string,value> 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
|
class MAPNIK_DECL metawriter_inmem
|
||||||
: public metawriter, private boost::noncopyable {
|
: public metawriter_base, private boost::noncopyable
|
||||||
|
{
|
||||||
public:
|
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(metawriter_properties dflt_properties);
|
||||||
~metawriter_inmem();
|
~metawriter_inmem();
|
||||||
|
|
||||||
virtual void add_box(box2d<double> const& box, Feature const& feature,
|
void add_box(box2d<double> const& box, Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties);
|
metawriter_properties const& properties);
|
||||||
virtual void add_text(boost::ptr_vector<text_path> &placements,
|
void add_text(boost::ptr_vector<text_path> &placements,
|
||||||
box2d<double> const& extents,
|
box2d<double> const& extents,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties);
|
metawriter_properties const& properties);
|
||||||
virtual void add_polygon(path_type & path,
|
|
||||||
Feature const& feature,
|
template <typename T>
|
||||||
CoordTransform const& t,
|
void add_polygon(T & path,
|
||||||
metawriter_properties const& properties);
|
Feature const& feature,
|
||||||
virtual void add_line(path_type & path,
|
CoordTransform const& t,
|
||||||
Feature const& feature,
|
metawriter_properties const& properties);
|
||||||
CoordTransform const& t,
|
|
||||||
metawriter_properties const& properties);
|
template <typename T>
|
||||||
|
void add_line(T & path,
|
||||||
virtual void start(metawriter_property_map const& properties);
|
Feature const& feature,
|
||||||
|
CoordTransform const& t,
|
||||||
|
metawriter_properties const& properties)
|
||||||
|
{
|
||||||
|
box2d<double> 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
|
* An instance of a rendered feature. The box represents the image
|
||||||
* coordinates of a bounding box around the feature. The properties
|
* coordinates of a bounding box around the feature. The properties
|
||||||
|
@ -105,7 +146,8 @@ private:
|
||||||
|
|
||||||
std::list<meta_instance> instances_;
|
std::list<meta_instance> instances_;
|
||||||
|
|
||||||
void add_vertices(path_type & path,
|
template <typename T>
|
||||||
|
void add_vertices(T & path,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties);
|
metawriter_properties const& properties);
|
||||||
|
|
|
@ -35,44 +35,68 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
class metawriter_json_stream : public metawriter_base,
|
||||||
/** Write JSON data to a stream object. */
|
private boost::noncopyable
|
||||||
class metawriter_json_stream : public metawriter, private boost::noncopyable
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
metawriter_json_stream(metawriter_properties dflt_properties);
|
explicit metawriter_json_stream(metawriter_properties dflt_properties);
|
||||||
~metawriter_json_stream();
|
~metawriter_json_stream();
|
||||||
virtual void add_box(box2d<double> const& box, Feature const& feature,
|
void add_box(box2d<double> const& box, Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties);
|
metawriter_properties const& properties);
|
||||||
virtual void add_text(boost::ptr_vector<text_path> &placements,
|
void add_text(boost::ptr_vector<text_path> &placements,
|
||||||
box2d<double> const& extents,
|
box2d<double> const& extents,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties);
|
metawriter_properties const& properties);
|
||||||
virtual void add_polygon(path_type & path,
|
template <typename T>
|
||||||
Feature const& feature,
|
void add_polygon(T & path,
|
||||||
CoordTransform const& t,
|
Feature const& feature,
|
||||||
metawriter_properties const& properties);
|
CoordTransform const& t,
|
||||||
virtual void add_line(path_type & path,
|
metawriter_properties const& properties);
|
||||||
Feature const& feature,
|
|
||||||
CoordTransform const& t,
|
template <typename T>
|
||||||
metawriter_properties const& properties);
|
void add_line(T & path,
|
||||||
|
Feature const& feature,
|
||||||
virtual void start(metawriter_property_map const& properties);
|
CoordTransform const& t,
|
||||||
virtual void stop();
|
metawriter_properties const& properties)
|
||||||
/** Set output stream. This function has to be called before the first output is made. */
|
{
|
||||||
void set_stream(std::ostream *f) { f_ = f; }
|
write_feature_header("MultiLineString");
|
||||||
/** Get output stream. */
|
*f_ << " [";
|
||||||
std::ostream *get_stream() const { return f_; }
|
|
||||||
/** Only write header/footer to file with one or more features. */
|
path.rewind(0);
|
||||||
void set_output_empty(bool output_empty) { output_empty_ = output_empty; }
|
double x, y;
|
||||||
/** See set_output_empty(). */
|
unsigned cmd;
|
||||||
|
int ring_count = 0;
|
||||||
|
while ((cmd = path.vertex(&x, &y)) != SEG_END)
|
||||||
|
{
|
||||||
|
if (cmd == SEG_MOVETO)
|
||||||
|
{
|
||||||
|
if (ring_count++ != 0) *f_ << "], ";
|
||||||
|
*f_ << "[";
|
||||||
|
write_point(t, x, y, true);
|
||||||
|
}
|
||||||
|
else if (cmd == SEG_LINETO)
|
||||||
|
{
|
||||||
|
*f_ << ",";
|
||||||
|
write_point(t, x, y, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ring_count != 0) *f_ << "]";
|
||||||
|
*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_; }
|
bool get_output_empty() { return output_empty_; }
|
||||||
void set_pixel_coordinates(bool on) { pixel_coordinates_ = on; }
|
void set_pixel_coordinates(bool on) { pixel_coordinates_ = on; }
|
||||||
bool get_pixel_coordinates() { return pixel_coordinates_; }
|
bool get_pixel_coordinates() { return pixel_coordinates_; }
|
||||||
virtual void set_map_srs(projection const& proj);
|
void set_map_srs(projection const& proj);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum {
|
enum {
|
||||||
HEADER_NOT_WRITTEN = -1,
|
HEADER_NOT_WRITTEN = -1,
|
||||||
|
@ -87,10 +111,10 @@ protected:
|
||||||
proj_transform *trans_;
|
proj_transform *trans_;
|
||||||
projection output_srs_;
|
projection output_srs_;
|
||||||
bool pixel_coordinates_;
|
bool pixel_coordinates_;
|
||||||
|
|
||||||
virtual void write_header();
|
void write_header();
|
||||||
|
inline void write_feature_header(std::string type)
|
||||||
inline void write_feature_header(std::string type) {
|
{
|
||||||
if (count_ == STOPPED)
|
if (count_ == STOPPED)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_WARN(metawrite_json) << "Metawriter: instance not started before using it.";
|
MAPNIK_LOG_WARN(metawrite_json) << "Metawriter: instance not started before using it.";
|
||||||
|
@ -116,43 +140,32 @@ protected:
|
||||||
*f_ << ",";
|
*f_ << ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_line_polygon(path_type & path, CoordTransform const& t, bool polygon);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostream *f_;
|
std::ostream *f_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shared pointer to metawriter_json_stream object. */
|
//typedef boost::shared_ptr<metawriter_json_stream> metawriter_json_stream_ptr;
|
||||||
typedef boost::shared_ptr<metawriter_json_stream> metawriter_json_stream_ptr;
|
|
||||||
|
|
||||||
/** JSON writer. */
|
// JSON writer.
|
||||||
class metawriter_json : public metawriter_json_stream
|
class metawriter_json : public metawriter_json_stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
metawriter_json(metawriter_properties dflt_properties, path_expression_ptr fn);
|
metawriter_json(metawriter_properties dflt_properties, path_expression_ptr fn);
|
||||||
|
void start(metawriter_property_map const& properties);
|
||||||
virtual void start(metawriter_property_map const& properties);
|
void stop();
|
||||||
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 set_filename(path_expression_ptr fn);
|
void set_filename(path_expression_ptr fn);
|
||||||
/** Get filename template. */
|
|
||||||
path_expression_ptr get_filename() const;
|
path_expression_ptr get_filename() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
path_expression_ptr fn_;
|
path_expression_ptr fn_;
|
||||||
std::fstream f_;
|
std::fstream f_;
|
||||||
std::string filename_;
|
std::string filename_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void write_header();
|
void write_header();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shared pointer to metawriter_json object. */
|
|
||||||
typedef boost::shared_ptr<metawriter_json> metawriter_json_ptr;
|
typedef boost::shared_ptr<metawriter_json> metawriter_json_ptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
83
include/mapnik/metawriter_renderer.hpp
Normal file
83
include/mapnik/metawriter_renderer.hpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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 <mapnik/config.hpp>
|
||||||
|
#include <mapnik/feature_style_processor.hpp>
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#include <mapnik/label_collision_detector.hpp>
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
namespace agg {
|
||||||
|
struct trans_affine;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
class MAPNIK_DECL metawriter_renderer : public feature_style_processor<metawriter_renderer>,
|
||||||
|
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<label_collision_detector4> 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<double> 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<freetype_engine> font_manager_;
|
||||||
|
boost::shared_ptr<label_collision_detector4> detector_;
|
||||||
|
box2d<double> query_extent_;
|
||||||
|
void setup(Map const &m);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MAPNIK_METAWRITER_RENDERER_HPP
|
|
@ -26,7 +26,7 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/metawriter.hpp>
|
#include <mapnik/metawriter_factory.hpp>
|
||||||
#include <mapnik/image_compositing.hpp>
|
#include <mapnik/image_compositing.hpp>
|
||||||
#include <mapnik/transform_expression.hpp>
|
#include <mapnik/transform_expression.hpp>
|
||||||
|
|
||||||
|
@ -52,12 +52,8 @@ public:
|
||||||
|
|
||||||
/** Add a metawriter to this symbolizer using a name. */
|
/** Add a metawriter to this symbolizer using a name. */
|
||||||
void add_metawriter(std::string const& name, metawriter_properties const& properties);
|
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.
|
void add_metawriter(metawriter const& writer,
|
||||||
* 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,
|
|
||||||
metawriter_properties const& properties = metawriter_properties(),
|
metawriter_properties const& properties = metawriter_properties(),
|
||||||
std::string const& name = "");
|
std::string const& name = "");
|
||||||
/** Cache metawriter objects to avoid repeated lookups while processing.
|
/** Cache metawriter objects to avoid repeated lookups while processing.
|
||||||
|
@ -96,7 +92,7 @@ private:
|
||||||
metawriter_properties properties_;
|
metawriter_properties properties_;
|
||||||
metawriter_properties properties_complete_;
|
metawriter_properties properties_complete_;
|
||||||
std::string writer_name_;
|
std::string writer_name_;
|
||||||
metawriter_ptr writer_ptr_;
|
metawriter writer_;
|
||||||
composite_mode_e comp_op_;
|
composite_mode_e comp_op_;
|
||||||
transform_type affine_transform_;
|
transform_type affine_transform_;
|
||||||
bool clip_;
|
bool clip_;
|
||||||
|
|
51
plugins/input/geojson/build.py
Normal file
51
plugins/input/geojson/build.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#
|
||||||
|
# This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012 Artem Pavlenko
|
||||||
|
#
|
||||||
|
# Mapnik 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
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
Import ('plugin_base')
|
||||||
|
Import ('env')
|
||||||
|
|
||||||
|
prefix = env['PREFIX']
|
||||||
|
|
||||||
|
plugin_env = plugin_base.Clone()
|
||||||
|
|
||||||
|
geojson_src = Split(
|
||||||
|
"""
|
||||||
|
geojson_datasource.cpp
|
||||||
|
geojson_featureset.cpp
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
libraries = []
|
||||||
|
# Link Library to Dependencies
|
||||||
|
libraries.append('mapnik')
|
||||||
|
libraries.append(env['ICU_LIB_NAME'])
|
||||||
|
libraries.append('boost_system%s' % env['BOOST_APPEND'])
|
||||||
|
if env['THREADING'] == 'multi':
|
||||||
|
libraries.append('boost_thread%s' % env['BOOST_APPEND'])
|
||||||
|
|
||||||
|
input_plugin = plugin_env.SharedLibrary('../geojson', source=geojson_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||||
|
|
||||||
|
# if the plugin links to libmapnik ensure it is built first
|
||||||
|
Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||||
|
|
||||||
|
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||||
|
env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], input_plugin)
|
||||||
|
env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
|
165
plugins/input/geojson/geojson_datasource.cpp
Normal file
165
plugins/input/geojson/geojson_datasource.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 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
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "geojson_datasource.hpp"
|
||||||
|
#include "geojson_featureset.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
// boost
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/spirit/include/support_multi_pass.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/geometry/geometries/box.hpp>
|
||||||
|
#include <boost/geometry/geometries/geometries.hpp>
|
||||||
|
#include <boost/geometry.hpp>
|
||||||
|
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/box2d.hpp>
|
||||||
|
#include <mapnik/proj_transform.hpp>
|
||||||
|
#include <mapnik/projection.hpp>
|
||||||
|
#include <mapnik/json/feature_collection_parser.hpp>
|
||||||
|
|
||||||
|
using mapnik::datasource;
|
||||||
|
using mapnik::parameters;
|
||||||
|
|
||||||
|
DATASOURCE_PLUGIN(geojson_datasource)
|
||||||
|
|
||||||
|
geojson_datasource::geojson_datasource(parameters const& params, bool bind)
|
||||||
|
: datasource(params),
|
||||||
|
type_(datasource::Vector),
|
||||||
|
desc_(*params_.get<std::string>("type"),
|
||||||
|
*params_.get<std::string>("encoding","utf-8")),
|
||||||
|
file_(*params_.get<std::string>("file","")),
|
||||||
|
extent_(),
|
||||||
|
tr_(new mapnik::transcoder(*params_.get<std::string>("encoding","utf-8"))),
|
||||||
|
features_(),
|
||||||
|
tree_(16,1)
|
||||||
|
{
|
||||||
|
if (file_.empty()) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");
|
||||||
|
if (bind)
|
||||||
|
{
|
||||||
|
this->bind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void geojson_datasource::bind() const
|
||||||
|
{
|
||||||
|
if (is_bound_) return;
|
||||||
|
|
||||||
|
typedef std::istreambuf_iterator<char> base_iterator_type;
|
||||||
|
|
||||||
|
std::ifstream is(file_.c_str());
|
||||||
|
boost::spirit::multi_pass<base_iterator_type> begin =
|
||||||
|
boost::spirit::make_default_multi_pass(base_iterator_type(is));
|
||||||
|
|
||||||
|
boost::spirit::multi_pass<base_iterator_type> end =
|
||||||
|
boost::spirit::make_default_multi_pass(base_iterator_type());
|
||||||
|
|
||||||
|
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||||
|
mapnik::json::feature_collection_parser<boost::spirit::multi_pass<base_iterator_type> > p(ctx,*tr_);
|
||||||
|
bool result = p.parse(begin,end, features_);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_WARN(geojson) << "geojson_datasource: Failed parse GeoJSON file " << file_;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
std::size_t count=0;
|
||||||
|
BOOST_FOREACH (mapnik::feature_ptr f, features_)
|
||||||
|
{
|
||||||
|
mapnik::box2d<double> const& box = f->envelope();
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
extent_ = box;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extent_.expand_to_include(box);
|
||||||
|
}
|
||||||
|
tree_.insert(box_type(point_type(box.minx(),box.miny()),point_type(box.maxx(),box.maxy())), count++);
|
||||||
|
}
|
||||||
|
is_bound_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
geojson_datasource::~geojson_datasource() { }
|
||||||
|
|
||||||
|
std::string const geojson_datasource::name_="geojson";
|
||||||
|
|
||||||
|
std::string geojson_datasource::name()
|
||||||
|
{
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> geojson_datasource::get_geometry_type() const
|
||||||
|
{
|
||||||
|
return boost::optional<mapnik::datasource::geometry_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::datasource::datasource_t geojson_datasource::type() const
|
||||||
|
{
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, mapnik::parameters> geojson_datasource::get_statistics() const
|
||||||
|
{
|
||||||
|
return statistics_;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::box2d<double> geojson_datasource::envelope() const
|
||||||
|
{
|
||||||
|
if (!is_bound_) bind();
|
||||||
|
return extent_;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::layer_descriptor geojson_datasource::get_descriptor() const
|
||||||
|
{
|
||||||
|
if (!is_bound_) bind();
|
||||||
|
|
||||||
|
return desc_;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) const
|
||||||
|
{
|
||||||
|
if (!is_bound_) bind();
|
||||||
|
|
||||||
|
// if the query box intersects our world extent then query for features
|
||||||
|
mapnik::box2d<double> const& b = q.get_bbox();
|
||||||
|
if (extent_.intersects(b))
|
||||||
|
{
|
||||||
|
box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy()));
|
||||||
|
index_array_ = tree_.find(box);
|
||||||
|
return boost::make_shared<geojson_featureset>(features_, index_array_.begin(), index_array_.end());
|
||||||
|
}
|
||||||
|
// otherwise return an empty featureset pointer
|
||||||
|
return mapnik::featureset_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt) const
|
||||||
|
{
|
||||||
|
if (!is_bound_) bind();
|
||||||
|
return mapnik::featureset_ptr();
|
||||||
|
}
|
69
plugins/input/geojson/geojson_datasource.hpp
Normal file
69
plugins/input/geojson/geojson_datasource.hpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 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 GEOJSON_DATASOURCE_HPP
|
||||||
|
#define GEOJSON_DATASOURCE_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
// boost
|
||||||
|
#include <boost/geometry/geometries/box.hpp>
|
||||||
|
#include <boost/geometry/geometries/point_xy.hpp>
|
||||||
|
#include <boost/geometry/algorithms/area.hpp>
|
||||||
|
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||||
|
#include <boost/geometry/geometries/geometries.hpp>
|
||||||
|
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
|
||||||
|
|
||||||
|
class geojson_datasource : public mapnik::datasource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::geometry::model::d2::point_xy<double> point_type;
|
||||||
|
typedef boost::geometry::model::box<point_type> box_type;
|
||||||
|
typedef boost::geometry::index::rtree<box_type,std::size_t> spatial_index_type;
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
geojson_datasource(mapnik::parameters const& params, bool bind=true);
|
||||||
|
virtual ~geojson_datasource ();
|
||||||
|
mapnik::datasource::datasource_t type() const;
|
||||||
|
static std::string name();
|
||||||
|
mapnik::featureset_ptr features(mapnik::query const& q) const;
|
||||||
|
mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt) const;
|
||||||
|
mapnik::box2d<double> envelope() const;
|
||||||
|
mapnik::layer_descriptor get_descriptor() const;
|
||||||
|
std::map<std::string, mapnik::parameters> get_statistics() const;
|
||||||
|
boost::optional<mapnik::datasource::geometry_t> get_geometry_type() const;
|
||||||
|
void bind() const;
|
||||||
|
private:
|
||||||
|
static const std::string name_;
|
||||||
|
mapnik::datasource::datasource_t type_;
|
||||||
|
mutable std::map<std::string, mapnik::parameters> statistics_;
|
||||||
|
mutable mapnik::layer_descriptor desc_;
|
||||||
|
mutable std::string file_;
|
||||||
|
mutable mapnik::box2d<double> extent_;
|
||||||
|
boost::shared_ptr<mapnik::transcoder> tr_;
|
||||||
|
mutable std::vector<mapnik::feature_ptr> features_;
|
||||||
|
mutable spatial_index_type tree_;
|
||||||
|
mutable std::deque<std::size_t> index_array_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FILE_DATASOURCE_HPP
|
52
plugins/input/geojson/geojson_featureset.cpp
Normal file
52
plugins/input/geojson/geojson_featureset.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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 <mapnik/feature.hpp>
|
||||||
|
// stl
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "geojson_featureset.hpp"
|
||||||
|
|
||||||
|
geojson_featureset::geojson_featureset(std::vector<mapnik::feature_ptr> const& features,
|
||||||
|
std::deque<std::size_t>::const_iterator index_itr,
|
||||||
|
std::deque<std::size_t>::const_iterator index_end)
|
||||||
|
: features_(features),
|
||||||
|
index_itr_(index_itr),
|
||||||
|
index_end_(index_end) {}
|
||||||
|
|
||||||
|
geojson_featureset::~geojson_featureset() {}
|
||||||
|
|
||||||
|
mapnik::feature_ptr geojson_featureset::next()
|
||||||
|
{
|
||||||
|
if (index_itr_ != index_end_)
|
||||||
|
{
|
||||||
|
std::size_t index = *index_itr_++;
|
||||||
|
if ( index < features_.size())
|
||||||
|
{
|
||||||
|
return features_.at(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mapnik::feature_ptr();
|
||||||
|
}
|
27
plugins/input/geojson/geojson_featureset.hpp
Normal file
27
plugins/input/geojson/geojson_featureset.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef GEOJSON_FEATURESET_HPP
|
||||||
|
#define GEOJSON_FEATURESET_HPP
|
||||||
|
|
||||||
|
#include <mapnik/datasource.hpp>
|
||||||
|
#include "geojson_datasource.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
|
||||||
|
class geojson_featureset : public mapnik::Featureset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
geojson_featureset(std::vector<mapnik::feature_ptr> const& features,
|
||||||
|
std::deque<std::size_t>::const_iterator index_itr,
|
||||||
|
std::deque<std::size_t>::const_iterator index_end);
|
||||||
|
virtual ~geojson_featureset();
|
||||||
|
mapnik::feature_ptr next();
|
||||||
|
|
||||||
|
private:
|
||||||
|
mapnik::box2d<double> box_;
|
||||||
|
std::vector<mapnik::feature_ptr> const& features_;
|
||||||
|
std::deque<std::size_t>::const_iterator index_itr_;
|
||||||
|
std::deque<std::size_t>::const_iterator index_end_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GEOJSON_FEATURESET_HPP
|
|
@ -135,8 +135,8 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
// TODO - impl this for markers?
|
// TODO - impl this for markers?
|
||||||
//if (!sym.get_ignore_placement())
|
//if (!sym.get_ignore_placement())
|
||||||
// detector_->insert(label_ext);
|
// detector_->insert(label_ext);
|
||||||
metawriter_with_properties writer = sym.get_metawriter();
|
//metawriter_with_properties writer = sym.get_metawriter();
|
||||||
if (writer.first) writer.first->add_box(extent, *feature, t_, writer.second);
|
//if (writer.first) writer.first->add_box(extent, *feature, t_, writer.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -168,12 +168,12 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
// rotated itself
|
// rotated itself
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writer.first)
|
//if (writer.first)
|
||||||
{
|
//{
|
||||||
//writer.first->add_box(label_ext, feature, t_, writer.second);
|
//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<T>::process(markers_symbolizer const& sym,
|
||||||
}
|
}
|
||||||
if (!sym.get_ignore_placement())
|
if (!sym.get_ignore_placement())
|
||||||
detector_->insert(label_ext);
|
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
|
else
|
||||||
|
@ -315,12 +315,12 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
if (writer.first)
|
//if (writer.first)
|
||||||
{
|
//{
|
||||||
//writer.first->add_box(label_ext, feature, t_, writer.second);
|
//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<agg::path_storage, agg::trans_affine> trans(marker, matrix);
|
agg::conv_transform<agg::path_storage, agg::trans_affine> trans(marker, matrix);
|
||||||
ras_ptr->add_path(trans);
|
ras_ptr->add_path(trans);
|
||||||
|
|
|
@ -100,8 +100,8 @@ void agg_renderer<T>::process(point_symbolizer const& sym,
|
||||||
|
|
||||||
if (!sym.get_ignore_placement())
|
if (!sym.get_ignore_placement())
|
||||||
detector_->insert(label_ext);
|
detector_->insert(label_ext);
|
||||||
metawriter_with_properties writer = sym.get_metawriter();
|
//metawriter_with_properties writer = sym.get_metawriter();
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,6 +273,15 @@ source += Split(
|
||||||
grid/process_text_symbolizer.cpp
|
grid/process_text_symbolizer.cpp
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
# metawriter backend
|
||||||
|
# grid backend
|
||||||
|
source += Split(
|
||||||
|
"""
|
||||||
|
metawriter/metawriter_renderer.cpp
|
||||||
|
metawriter/process_line_symbolizer.cpp
|
||||||
|
metawriter/process_point_symbolizer.cpp
|
||||||
|
""")
|
||||||
|
|
||||||
if env['SVG_RENDERER']: # svg backend
|
if env['SVG_RENDERER']: # svg backend
|
||||||
source += Split(
|
source += Split(
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1172,9 +1172,10 @@ void cairo_renderer_base::start_map_processing(Map const& map)
|
||||||
if (!sym.get_ignore_placement())
|
if (!sym.get_ignore_placement())
|
||||||
detector_.insert(label_ext);
|
detector_.insert(label_ext);
|
||||||
metawriter_with_properties writer = sym.get_metawriter();
|
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())
|
//if (!sym.get_ignore_placement())
|
||||||
// detector_.insert(label_ext);
|
// detector_.insert(label_ext);
|
||||||
metawriter_with_properties writer = sym.get_metawriter();
|
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
|
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);
|
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);
|
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);
|
//writer.first->add_box(label_ext, feature, t_, writer.second);
|
||||||
MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement";
|
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())
|
if (!sym.get_ignore_placement())
|
||||||
detector_.insert(label_ext);
|
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
|
else
|
||||||
|
@ -1585,7 +1594,7 @@ void cairo_renderer_base::start_map_processing(Map const& map)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
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);
|
||||||
MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement";
|
MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement";
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <mapnik/scale_denominator.hpp>
|
#include <mapnik/scale_denominator.hpp>
|
||||||
#include <mapnik/agg_renderer.hpp>
|
#include <mapnik/agg_renderer.hpp>
|
||||||
#include <mapnik/grid/grid_renderer.hpp>
|
#include <mapnik/grid/grid_renderer.hpp>
|
||||||
|
#include <mapnik/metawriter_renderer.hpp>
|
||||||
// boost
|
// boost
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/concept_check.hpp>
|
#include <boost/concept_check.hpp>
|
||||||
|
@ -78,7 +78,7 @@ struct process_impl<false>
|
||||||
boost::ignore_unused_variable_warning(f);
|
boost::ignore_unused_variable_warning(f);
|
||||||
boost::ignore_unused_variable_warning(tr);
|
boost::ignore_unused_variable_warning(tr);
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::clog << "NO-OP ...\n";
|
std::clog << "NO-OP " << typeid(sym).name() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -98,35 +98,35 @@ struct feature_style_processor<Processor>::symbol_dispatch : public boost::stati
|
||||||
: output_(output),
|
: output_(output),
|
||||||
f_(f),
|
f_(f),
|
||||||
prj_trans_(prj_trans) {}
|
prj_trans_(prj_trans) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator () (T const& sym) const
|
void operator () (T const& sym) const
|
||||||
{
|
{
|
||||||
process_impl<has_process<Processor,T>::value>::process(output_,sym,f_,prj_trans_);
|
process_impl<has_process<Processor,T>::value>::process(output_,sym,f_,prj_trans_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Processor & output_;
|
Processor & output_;
|
||||||
mapnik::feature_ptr const& f_;
|
mapnik::feature_ptr const& f_;
|
||||||
proj_transform const& prj_trans_;
|
proj_transform const& prj_trans_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef char (&no_tag)[1];
|
typedef char (&no_tag)[1];
|
||||||
typedef char (&yes_tag)[2];
|
typedef char (&yes_tag)[2];
|
||||||
|
|
||||||
template <typename T0, typename T1, void (T0::*)(T1 const&, mapnik::feature_ptr const&, proj_transform const&) >
|
template <typename T0, typename T1, void (T0::*)(T1 const&, mapnik::feature_ptr const&, proj_transform const&) >
|
||||||
struct process_memfun_helper {};
|
struct process_memfun_helper {};
|
||||||
|
|
||||||
template <typename T0, typename T1> no_tag has_process_helper(...);
|
template <typename T0, typename T1> no_tag has_process_helper(...);
|
||||||
template <typename T0, typename T1> yes_tag has_process_helper(process_memfun_helper<T0, T1, &T0::process>* p);
|
template <typename T0, typename T1> yes_tag has_process_helper(process_memfun_helper<T0, T1, &T0::process>* p);
|
||||||
|
|
||||||
template<typename T0,typename T1>
|
template<typename T0,typename T1>
|
||||||
struct has_process
|
struct has_process
|
||||||
{
|
{
|
||||||
typedef typename T0::processor_impl_type processor_impl_type;
|
typedef typename T0::processor_impl_type processor_impl_type;
|
||||||
BOOST_STATIC_CONSTANT(bool
|
BOOST_STATIC_CONSTANT(bool
|
||||||
, value = sizeof(has_process_helper<processor_impl_type,T1>(0)) == sizeof(yes_tag)
|
, value = sizeof(has_process_helper<processor_impl_type,T1>(0)) == sizeof(yes_tag)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename Processor>
|
template <typename Processor>
|
||||||
|
@ -149,9 +149,6 @@ void feature_style_processor<Processor>::apply()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
projection proj(m_.srs());
|
projection proj(m_.srs());
|
||||||
|
|
||||||
start_metawriters(m_,proj);
|
|
||||||
|
|
||||||
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
|
double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
|
||||||
scale_denom *= scale_factor_;
|
scale_denom *= scale_factor_;
|
||||||
|
|
||||||
|
@ -163,8 +160,6 @@ void feature_style_processor<Processor>::apply()
|
||||||
apply_to_layer(lyr, p, proj, scale_denom, names);
|
apply_to_layer(lyr, p, proj, scale_denom, names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_metawriters(m_);
|
|
||||||
}
|
}
|
||||||
catch (proj_init_error& ex)
|
catch (proj_init_error& ex)
|
||||||
{
|
{
|
||||||
|
@ -203,30 +198,6 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr, std::se
|
||||||
p.end_map_processing(m_);
|
p.end_map_processing(m_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Processor>
|
|
||||||
void feature_style_processor<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 <typename Processor>
|
|
||||||
void feature_style_processor<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 <typename Processor>
|
template <typename Processor>
|
||||||
void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Processor & p,
|
void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Processor & p,
|
||||||
projection const& proj0,
|
projection const& proj0,
|
||||||
|
@ -516,7 +487,7 @@ void feature_style_processor<Processor>::render_style(
|
||||||
{
|
{
|
||||||
|
|
||||||
p.start_style_processing(*style);
|
p.start_style_processing(*style);
|
||||||
|
|
||||||
#if defined(RENDERING_STATS)
|
#if defined(RENDERING_STATS)
|
||||||
std::ostringstream s1;
|
std::ostringstream s1;
|
||||||
s1 << "rendering style for layer: '" << lay.name()
|
s1 << "rendering style for layer: '" << lay.name()
|
||||||
|
@ -552,18 +523,13 @@ void feature_style_processor<Processor>::render_style(
|
||||||
|
|
||||||
do_else=false;
|
do_else=false;
|
||||||
do_also=true;
|
do_also=true;
|
||||||
|
|
||||||
rule::symbolizers const& symbols = r->get_symbolizers();
|
rule::symbolizers const& symbols = r->get_symbolizers();
|
||||||
|
BOOST_FOREACH (symbolizer const& sym, symbols)
|
||||||
// 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))
|
|
||||||
{
|
{
|
||||||
|
boost::apply_visitor(symbol_dispatch(p,feature,prj_trans),sym);
|
||||||
BOOST_FOREACH (symbolizer const& sym, symbols)
|
|
||||||
{
|
|
||||||
boost::apply_visitor(symbol_dispatch(p,feature,prj_trans),sym);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (style->get_filter_mode() == FILTER_FIRST)
|
if (style->get_filter_mode() == FILTER_FIRST)
|
||||||
{
|
{
|
||||||
// Stop iterating over rules and proceed with next feature.
|
// Stop iterating over rules and proceed with next feature.
|
||||||
|
@ -582,14 +548,9 @@ void feature_style_processor<Processor>::render_style(
|
||||||
p.painted(true);
|
p.painted(true);
|
||||||
|
|
||||||
rule::symbolizers const& symbols = r->get_symbolizers();
|
rule::symbolizers const& symbols = r->get_symbolizers();
|
||||||
// if the underlying renderer is not able to process the complete set of symbolizers,
|
BOOST_FOREACH (symbolizer const& sym, symbols)
|
||||||
// process one by one.
|
|
||||||
if(!p.process(symbols,feature,prj_trans))
|
|
||||||
{
|
{
|
||||||
BOOST_FOREACH (symbolizer const& sym, symbols)
|
boost::apply_visitor(symbol_dispatch(p,feature,prj_trans),sym);
|
||||||
{
|
|
||||||
boost::apply_visitor(symbol_dispatch(p,feature,prj_trans),sym);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,14 +565,10 @@ void feature_style_processor<Processor>::render_style(
|
||||||
p.painted(true);
|
p.painted(true);
|
||||||
|
|
||||||
rule::symbolizers const& symbols = r->get_symbolizers();
|
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.
|
BOOST_FOREACH (symbolizer const& sym, symbols)
|
||||||
if(!p.process(symbols,feature,prj_trans))
|
|
||||||
{
|
{
|
||||||
BOOST_FOREACH (symbolizer const& sym, symbols)
|
boost::apply_visitor(symbol_dispatch(p,feature,prj_trans),sym);
|
||||||
{
|
|
||||||
boost::apply_visitor(symbol_dispatch(p,feature,prj_trans),sym);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -656,6 +613,6 @@ template class feature_style_processor<svg_renderer<std::ostream_iterator<char>
|
||||||
|
|
||||||
template class feature_style_processor<grid_renderer<grid> >;
|
template class feature_style_processor<grid_renderer<grid> >;
|
||||||
template class feature_style_processor<agg_renderer<image_32> >;
|
template class feature_style_processor<agg_renderer<image_32> >;
|
||||||
|
template class feature_style_processor<metawriter_renderer>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
void map_parser::parse_metawriter(Map & map, xml_node const& pt)
|
||||||
{
|
{
|
||||||
std::string name("<missing name>");
|
std::string name("<missing name>");
|
||||||
metawriter_ptr writer;
|
metawriter writer;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
name = pt.get_attr<std::string>("name");
|
name = pt.get_attr<std::string>("name");
|
||||||
|
|
10
src/map.cpp
10
src/map.cpp
|
@ -169,7 +169,7 @@ boost::optional<feature_type_style const&> Map::find_style(std::string const& na
|
||||||
return boost::optional<feature_type_style const&>() ;
|
return boost::optional<feature_type_style const&>() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return metawriters_.insert(make_pair(name, writer)).second;
|
||||||
}
|
}
|
||||||
|
@ -179,16 +179,16 @@ void Map::remove_metawriter(std::string const& name)
|
||||||
metawriters_.erase(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<std::string, metawriter_ptr>::const_iterator itr = metawriters_.find(name);
|
std::map<std::string, metawriter>::const_iterator itr = metawriters_.find(name);
|
||||||
if (itr != metawriters_.end())
|
if (itr != metawriters_.end())
|
||||||
return itr->second;
|
return itr->second;
|
||||||
else
|
else
|
||||||
return metawriter_ptr();
|
return metawriter();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string,metawriter_ptr> const& Map::metawriters() const
|
std::map<std::string,metawriter> const& Map::metawriters() const
|
||||||
{
|
{
|
||||||
return metawriters_;
|
return metawriters_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ metawriter_json_stream::~metawriter_json_stream()
|
||||||
|
|
||||||
|
|
||||||
metawriter_json_stream::metawriter_json_stream(metawriter_properties dflt_properties)
|
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"),
|
trans_(0), output_srs_("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"),
|
||||||
pixel_coordinates_(false), f_(0)
|
pixel_coordinates_(false), f_(0)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +170,8 @@ void metawriter_json_stream::add_box(box2d<double> const &box, Feature const& fe
|
||||||
minx << ", " << miny << "], [" <<
|
minx << ", " << miny << "], [" <<
|
||||||
maxx << ", " << miny << "], [" <<
|
maxx << ", " << miny << "], [" <<
|
||||||
maxx << ", " << maxy << "], [" <<
|
maxx << ", " << maxy << "], [" <<
|
||||||
minx << ", " << maxy << "] ] ]";
|
minx << ", " << maxy << "], [" <<
|
||||||
|
minx << ", " << miny << "] ] ]";
|
||||||
|
|
||||||
write_properties(feature, properties);
|
write_properties(feature, properties);
|
||||||
|
|
||||||
|
@ -262,7 +263,8 @@ void metawriter_json_stream::add_text(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void metawriter_json_stream::add_polygon(path_type & path,
|
template <typename T>
|
||||||
|
void metawriter_json_stream::add_polygon(T & path,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties)
|
metawriter_properties const& properties)
|
||||||
|
@ -272,42 +274,6 @@ void metawriter_json_stream::add_polygon(path_type & path,
|
||||||
write_properties(feature, properties);
|
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*/){
|
|
||||||
*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_ << "]]";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void metawriter_json_stream::set_map_srs(projection const& input_srs_)
|
void metawriter_json_stream::set_map_srs(projection const& input_srs_)
|
||||||
{
|
{
|
||||||
if (trans_) delete trans_;
|
if (trans_) delete trans_;
|
||||||
|
@ -327,7 +293,15 @@ void metawriter_json::start(metawriter_property_map const& properties)
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(metawriter) << "metawriter_json: Filename=" << filename_;
|
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()
|
void metawriter_json::write_header()
|
||||||
|
@ -337,7 +311,7 @@ void metawriter_json::write_header()
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(metawriter) << "metawriter_json: Failed to open file " << filename_;
|
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();
|
metawriter_json_stream::write_header();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
138
src/metawriter/metawriter_renderer.cpp
Normal file
138
src/metawriter/metawriter_renderer.cpp
Normal file
|
@ -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 <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/metawriter_renderer.hpp>
|
||||||
|
#include <mapnik/marker.hpp>
|
||||||
|
#include <mapnik/marker_cache.hpp>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
#include <mapnik/font_set.hpp>
|
||||||
|
#include <mapnik/parse_path.hpp>
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <boost/math/special_functions/round.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
metawriter_renderer::metawriter_renderer(Map const& m,double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<metawriter_renderer>(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<label_collision_detector4>(box2d<double>(-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<label_collision_detector4> detector,
|
||||||
|
double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<metawriter_renderer>(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<double> 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
92
src/metawriter/process_line_symbolizer.cpp
Normal file
92
src/metawriter/process_line_symbolizer.cpp
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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 <boost/foreach.hpp>
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/metawriter_renderer.hpp>
|
||||||
|
#include <mapnik/metawriter_factory.hpp>
|
||||||
|
#include <mapnik/line_symbolizer.hpp>
|
||||||
|
#include <mapnik/vertex_converters.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <string>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
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 <typename T>
|
||||||
|
void add_path(T & path)
|
||||||
|
{
|
||||||
|
if (check_metawriter(writer.first))
|
||||||
|
{
|
||||||
|
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<clip_line_tag,
|
||||||
|
transform_tag,
|
||||||
|
offset_transform_tag,
|
||||||
|
affine_transform_tag,
|
||||||
|
smooth_tag,
|
||||||
|
dash_tag,
|
||||||
|
stroke_tag> conv_types;
|
||||||
|
|
||||||
|
vertex_converter<box2d<double>,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<clip_line_tag>(); // optional clip (default: true)
|
||||||
|
converter.set<transform_tag>(); // always transform
|
||||||
|
|
||||||
|
BOOST_FOREACH( geometry_type & geom, feature->paths())
|
||||||
|
{
|
||||||
|
if (geom.num_points() > 1)
|
||||||
|
{
|
||||||
|
converter.apply(geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
95
src/metawriter/process_point_symbolizer.cpp
Normal file
95
src/metawriter/process_point_symbolizer.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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 <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/marker.hpp>
|
||||||
|
#include <mapnik/marker_cache.hpp>
|
||||||
|
#include <mapnik/point_symbolizer.hpp>
|
||||||
|
#include <mapnik/metawriter_renderer.hpp>
|
||||||
|
#include <mapnik/metawriter_factory.hpp>
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
void metawriter_renderer::process(point_symbolizer const& sym,
|
||||||
|
mapnik::feature_ptr const& feature,
|
||||||
|
proj_transform const& prj_trans)
|
||||||
|
{
|
||||||
|
std::string filename = path_processor_type::evaluate(*sym.get_filename(), *feature);
|
||||||
|
|
||||||
|
boost::optional<mapnik::marker_ptr> marker;
|
||||||
|
if ( !filename.empty() )
|
||||||
|
{
|
||||||
|
marker = marker_cache::instance()->find(filename, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
marker.reset(boost::make_shared<mapnik::marker>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (marker)
|
||||||
|
{
|
||||||
|
box2d<double> const& bbox = (*marker)->bounding_box();
|
||||||
|
coord2d const center = bbox.center();
|
||||||
|
|
||||||
|
agg::trans_affine tr;
|
||||||
|
evaluate_transform(tr, *feature, sym.get_image_transform());
|
||||||
|
|
||||||
|
agg::trans_affine_translation const recenter(-center.x, -center.y);
|
||||||
|
agg::trans_affine const recenter_tr = recenter * tr;
|
||||||
|
box2d<double> label_ext = bbox * recenter_tr;
|
||||||
|
|
||||||
|
for (unsigned i=0; i<feature->num_geometries(); ++i)
|
||||||
|
{
|
||||||
|
geometry_type const& geom = feature->get_geometry(i);
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z=0;
|
||||||
|
if (sym.get_point_placement() == CENTROID_POINT_PLACEMENT)
|
||||||
|
geom.label_position(&x, &y);
|
||||||
|
else
|
||||||
|
geom.label_interior_position(&x, &y);
|
||||||
|
|
||||||
|
prj_trans.backward(x,y,z);
|
||||||
|
t_.forward(&x,&y);
|
||||||
|
label_ext.re_center(x,y);
|
||||||
|
|
||||||
|
if (sym.get_allow_overlap() ||
|
||||||
|
detector_->has_placement(label_ext))
|
||||||
|
{
|
||||||
|
if (!sym.get_ignore_placement())
|
||||||
|
detector_->insert(label_ext);
|
||||||
|
metawriter_with_properties writer = sym.get_metawriter();
|
||||||
|
add_box(writer.first, label_ext,*feature, t_, writer.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,42 +38,49 @@ using std::string;
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
metawriter_ptr
|
metawriter metawriter_create(xml_node const& pt)
|
||||||
metawriter_create(xml_node const& pt)
|
|
||||||
{
|
{
|
||||||
metawriter_ptr writer;
|
metawriter writer;
|
||||||
string type = pt.get_attr<string>("type");
|
string type = pt.get_attr<string>("type");
|
||||||
|
|
||||||
optional<string> properties = pt.get_opt_attr<string>("default-output");
|
optional<string> properties = pt.get_opt_attr<string>("default-output");
|
||||||
if (type == "json") {
|
if (type == "json")
|
||||||
|
{
|
||||||
string file = pt.get_attr<string>("file");
|
string file = pt.get_attr<string>("file");
|
||||||
metawriter_json_ptr json = boost::make_shared<metawriter_json>(properties, parse_path(file));
|
metawriter_json_ptr json = boost::make_shared<metawriter_json>(properties, parse_path(file));
|
||||||
optional<boolean> output_empty = pt.get_opt_attr<boolean>("output-empty");
|
optional<boolean> output_empty = pt.get_opt_attr<boolean>("output-empty");
|
||||||
if (output_empty) {
|
if (output_empty)
|
||||||
|
{
|
||||||
json->set_output_empty(*output_empty);
|
json->set_output_empty(*output_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<boolean> pixel_coordinates = pt.get_opt_attr<boolean>("pixel-coordinates");
|
optional<boolean> pixel_coordinates = pt.get_opt_attr<boolean>("pixel-coordinates");
|
||||||
if (pixel_coordinates) {
|
if (pixel_coordinates)
|
||||||
|
{
|
||||||
json->set_pixel_coordinates(*pixel_coordinates);
|
json->set_pixel_coordinates(*pixel_coordinates);
|
||||||
}
|
}
|
||||||
writer = json;
|
writer = json;
|
||||||
|
|
||||||
} else if (type == "inmem") {
|
}
|
||||||
|
else if (type == "inmem")
|
||||||
|
{
|
||||||
metawriter_inmem_ptr inmem = boost::make_shared<metawriter_inmem>(properties);
|
metawriter_inmem_ptr inmem = boost::make_shared<metawriter_inmem>(properties);
|
||||||
writer = inmem;
|
writer = inmem;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw config_error(string("Unknown type '") + type + "'", pt);
|
throw config_error(string("Unknown type '") + type + "'", pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void metawriter_save(metawriter const& writer,
|
||||||
metawriter_save(const metawriter_ptr &metawriter,
|
boost::property_tree::ptree & metawriter_node,
|
||||||
boost::property_tree::ptree &metawriter_node, bool explicit_defaults)
|
bool explicit_defaults)
|
||||||
{
|
{
|
||||||
|
// FIXME
|
||||||
|
/*
|
||||||
metawriter_json *json = dynamic_cast<metawriter_json *>(metawriter.get());
|
metawriter_json *json = dynamic_cast<metawriter_json *>(metawriter.get());
|
||||||
if (json) {
|
if (json) {
|
||||||
set_attr(metawriter_node, "type", "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) {
|
if (!metawriter->get_default_properties().empty() || explicit_defaults) {
|
||||||
set_attr(metawriter_node, "default-output", metawriter->get_default_properties().to_string());
|
set_attr(metawriter_node, "default-output", metawriter->get_default_properties().to_string());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mapnik
|
} // namespace mapnik
|
||||||
|
|
|
@ -28,49 +28,27 @@
|
||||||
// Boost
|
// Boost
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
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<string,value> intersect_properties(Feature const& feature, metawriter_properties const& properties) {
|
|
||||||
|
|
||||||
map<string,value> 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 {
|
namespace mapnik {
|
||||||
|
|
||||||
metawriter_inmem::metawriter_inmem(metawriter_properties dflt_properties)
|
metawriter_inmem::metawriter_inmem(metawriter_properties dflt_properties)
|
||||||
: metawriter(dflt_properties) {
|
: metawriter_base(dflt_properties) {
|
||||||
}
|
}
|
||||||
|
|
||||||
metawriter_inmem::~metawriter_inmem() {
|
metawriter_inmem::~metawriter_inmem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void metawriter_inmem::add_box(box2d<double> const& box, Feature const& feature,
|
||||||
metawriter_inmem::add_box(box2d<double> const& box, Feature const& feature,
|
|
||||||
CoordTransform const& /*t*/,
|
CoordTransform const& /*t*/,
|
||||||
metawriter_properties const& properties) {
|
metawriter_properties const& properties)
|
||||||
|
{
|
||||||
meta_instance inst;
|
meta_instance inst;
|
||||||
inst.box = box;
|
inst.box = box;
|
||||||
inst.properties = intersect_properties(feature, properties);
|
inst.properties = intersect_properties(feature, properties);
|
||||||
instances_.push_back(inst);
|
instances_.push_back(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void metawriter_inmem::add_text(
|
||||||
metawriter_inmem::add_text(
|
|
||||||
boost::ptr_vector<text_path> & /*text*/,
|
boost::ptr_vector<text_path> & /*text*/,
|
||||||
box2d<double> const& extents,
|
box2d<double> const& extents,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
|
@ -86,27 +64,21 @@ metawriter_inmem::add_text(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
template <typename T>
|
||||||
metawriter_inmem::add_polygon(path_type & path,
|
void metawriter_inmem::add_polygon(T & path,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
metawriter_properties const& properties) {
|
metawriter_properties const& properties)
|
||||||
|
{
|
||||||
add_vertices(path, feature, t, 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
|
template <typename T>
|
||||||
metawriter_inmem::add_vertices(path_type & path,
|
void metawriter_inmem::add_vertices(T & path,
|
||||||
Feature const& feature,
|
Feature const& feature,
|
||||||
CoordTransform const& /*t*/,
|
CoordTransform const& /*t*/,
|
||||||
metawriter_properties const& properties) {
|
metawriter_properties const& properties) {
|
||||||
box2d<double> box;
|
box2d<double> box;
|
||||||
unsigned cmd;
|
unsigned cmd;
|
||||||
double x = 0.0, y = 0.0;
|
double x = 0.0, y = 0.0;
|
||||||
|
|
|
@ -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)
|
void serialize_metawriter(ptree & map_node, Map::const_metawriter_iterator metawriter_it, bool explicit_defaults)
|
||||||
{
|
{
|
||||||
std::string const& name = metawriter_it->first;
|
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 & metawriter_node = map_node.push_back(
|
||||||
ptree::value_type("MetaWriter", ptree()))->second;
|
ptree::value_type("MetaWriter", ptree()))->second;
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ symbolizer_base::symbolizer_base()
|
||||||
: properties_(),
|
: properties_(),
|
||||||
properties_complete_(),
|
properties_complete_(),
|
||||||
writer_name_(),
|
writer_name_(),
|
||||||
writer_ptr_(),
|
writer_(),
|
||||||
comp_op_(src_over),
|
comp_op_(src_over),
|
||||||
clip_(true),
|
clip_(true),
|
||||||
smooth_value_(0.0)
|
smooth_value_(0.0)
|
||||||
|
@ -57,7 +57,11 @@ symbolizer_base::symbolizer_base()
|
||||||
|
|
||||||
// copy ctor
|
// copy ctor
|
||||||
symbolizer_base::symbolizer_base(symbolizer_base const& other)
|
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_),
|
affine_transform_(other.affine_transform_),
|
||||||
clip_(other.clip_),
|
clip_(other.clip_),
|
||||||
smooth_value_(other.smooth_value_) {}
|
smooth_value_(other.smooth_value_) {}
|
||||||
|
@ -68,16 +72,19 @@ void symbolizer_base::add_metawriter(std::string const& name, metawriter_propert
|
||||||
properties_ = properties;
|
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)
|
std::string const& name)
|
||||||
{
|
{
|
||||||
writer_ptr_ = writer_ptr;
|
writer_ = writer;
|
||||||
properties_ = properties;
|
properties_ = properties;
|
||||||
writer_name_ = name;
|
writer_name_ = name;
|
||||||
if (writer_ptr) {
|
if (check_metawriter(writer))
|
||||||
properties_complete_ = writer_ptr->get_default_properties();
|
{
|
||||||
|
//properties_complete_ = writer_->get_default_properties(); FIXME
|
||||||
properties_complete_.insert(properties_.begin(), properties_.end());
|
properties_complete_.insert(properties_.begin(), properties_.end());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
properties_complete_.clear();
|
properties_complete_.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,15 +93,17 @@ void symbolizer_base::cache_metawriters(Map const &m)
|
||||||
{
|
{
|
||||||
if (writer_name_.empty()) {
|
if (writer_name_.empty()) {
|
||||||
properties_complete_.clear();
|
properties_complete_.clear();
|
||||||
writer_ptr_ = metawriter_ptr();
|
|
||||||
return; // No metawriter
|
return; // No metawriter
|
||||||
}
|
}
|
||||||
|
|
||||||
writer_ptr_ = m.find_metawriter(writer_name_);
|
writer_ = m.find_metawriter(writer_name_);
|
||||||
if (writer_ptr_) {
|
if (check_metawriter(writer_))
|
||||||
properties_complete_ = writer_ptr_->get_default_properties();
|
{
|
||||||
|
// properties_complete_ = writer_->get_default_properties(); FIXME
|
||||||
properties_complete_.insert(properties_.begin(), properties_.end());
|
properties_complete_.insert(properties_.begin(), properties_.end());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
properties_complete_.clear();
|
properties_complete_.clear();
|
||||||
MAPNIK_LOG_WARN(symbolizer) << "Metawriter '" << writer_name_ << "' used but not defined.";
|
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
|
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)
|
void symbolizer_base::set_comp_op(composite_mode_e comp_op)
|
||||||
|
|
|
@ -71,9 +71,9 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_line_placement()
|
||||||
finder_->update_detector();
|
finder_->update_detector();
|
||||||
}
|
}
|
||||||
geo_itr_ = geometries_to_process_.erase(geo_itr_);
|
geo_itr_ = geometries_to_process_.erase(geo_itr_);
|
||||||
if (writer_.first) writer_.first->add_text(
|
//if (writer_.first) writer_.first->add_text(
|
||||||
finder_->get_results(), finder_->get_extents(),
|
// finder_->get_results(), finder_->get_extents(),
|
||||||
feature_, t_, writer_.second);
|
// feature_, t_, writer_.second);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//No placement for this geometry. Keep it in geometries_to_process_ for next try.
|
//No placement for this geometry. Keep it in geometries_to_process_ for next try.
|
||||||
|
@ -101,9 +101,9 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
||||||
{
|
{
|
||||||
//Found a placement
|
//Found a placement
|
||||||
point_itr_ = points_.erase(point_itr_);
|
point_itr_ = points_.erase(point_itr_);
|
||||||
if (writer_.first) writer_.first->add_text(
|
// if (writer_.first) writer_.first->add_text(
|
||||||
finder_->get_results(), finder_->get_extents(),
|
// finder_->get_results(), finder_->get_extents(),
|
||||||
feature_, t_, writer_.second);
|
// feature_, t_, writer_.second);
|
||||||
finder_->update_detector();
|
finder_->update_detector();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement()
|
||||||
finder_ = boost::shared_ptr<placement_finder<DetectorT> >(new placement_finder<DetectorT>(feature_, *placement_, *info_, detector_, dims_));
|
finder_ = boost::shared_ptr<placement_finder<DetectorT> >(new placement_finder<DetectorT>(feature_, *placement_, *info_, detector_, dims_));
|
||||||
// boost::make_shared<placement_finder<DetectorT> >(feature_, *placement_, *info_, detector_, dims_);
|
// boost::make_shared<placement_finder<DetectorT> >(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;
|
placement_valid_ = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -316,11 +316,11 @@ bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
||||||
{
|
{
|
||||||
detector_.insert(marker_ext_);
|
detector_.insert(marker_ext_);
|
||||||
finder_->update_detector();
|
finder_->update_detector();
|
||||||
if (writer_.first) {
|
//if (writer_.first) {
|
||||||
writer_.first->add_box(marker_ext_, feature_, t_, writer_.second);
|
// writer_.first->add_box(marker_ext_, feature_, t_, writer_.second);
|
||||||
writer_.first->add_text(finder_->get_results(), finder_->get_extents(),
|
// writer_.first->add_text(finder_->get_results(), finder_->get_extents(),
|
||||||
feature_, t_, writer_.second);
|
// feature_, t_, writer_.second);
|
||||||
}
|
//}
|
||||||
point_itr_ = points_.erase(point_itr_);
|
point_itr_ = points_.erase(point_itr_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +393,7 @@ pixel_position shield_symbolizer_helper<FaceManagerT, DetectorT>::get_marker_pos
|
||||||
marker_ext_.re_center(lx, ly);
|
marker_ext_.re_center(lx, ly);
|
||||||
//label is added to detector by get_line_placement(), but marker isn't
|
//label is added to detector by get_line_placement(), but marker isn't
|
||||||
detector_.insert(marker_ext_);
|
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);
|
return pixel_position(px, py);
|
||||||
} else {
|
} else {
|
||||||
//collision_detector is already updated for point placement in get_point_placement()
|
//collision_detector is already updated for point placement in get_point_placement()
|
||||||
|
|
Loading…
Reference in a new issue