start experimenting with making the rendering api less dependent on a complex map object and more driven by flexible arrays of styles and layers
This commit is contained in:
parent
72d88cfd79
commit
2406c0e79d
11 changed files with 86 additions and 336 deletions
|
@ -34,7 +34,8 @@
|
|||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
//#include <mapnik/util/deepcopy.hpp>
|
||||
#include <mapnik/scale_denominator.hpp>
|
||||
#include <mapnik/util/map_query.hpp>
|
||||
#include "mapnik_enumeration.hpp"
|
||||
|
||||
using mapnik::color;
|
||||
|
@ -77,8 +78,7 @@ mapnik::featureset_ptr query_point(mapnik::Map const& m, int index, double x, do
|
|||
PyErr_SetString(PyExc_IndexError, "Please provide a layer index >= 0");
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
unsigned idx = index;
|
||||
return m.query_point(idx, x, y);
|
||||
return mapnik::util::query_point(m, static_cast<unsigned>(index), x, y);
|
||||
}
|
||||
|
||||
mapnik::featureset_ptr query_map_point(mapnik::Map const& m, int index, double x, double y)
|
||||
|
@ -87,8 +87,23 @@ mapnik::featureset_ptr query_map_point(mapnik::Map const& m, int index, double x
|
|||
PyErr_SetString(PyExc_IndexError, "Please provide a layer index >= 0");
|
||||
boost::python::throw_error_already_set();
|
||||
}
|
||||
unsigned idx = index;
|
||||
return m.query_map_point(idx, x, y);
|
||||
return mapnik::util::query_map_point(m, static_cast<unsigned>(index), x, y);
|
||||
}
|
||||
|
||||
void zoom_all(mapnik::Map & m)
|
||||
{
|
||||
m.zoom_to_box(mapnik::util::get_extent(m));
|
||||
}
|
||||
|
||||
mapnik::CoordTransform get_view_transform(mapnik::Map const& map)
|
||||
{
|
||||
return mapnik::CoordTransform(map.width(),map.height(),map.get_current_extent());
|
||||
}
|
||||
|
||||
double get_scale_denominator(mapnik::Map const& map)
|
||||
{
|
||||
mapnik::projection map_proj(map.srs());
|
||||
return mapnik::scale_denominator( map.scale(), map_proj.is_geographic());
|
||||
}
|
||||
|
||||
// deepcopy
|
||||
|
@ -337,14 +352,14 @@ void export_map()
|
|||
">>> m.scale()\n"
|
||||
)
|
||||
|
||||
.def("scale_denominator", &Map::scale_denominator,
|
||||
.def("scale_denominator", get_scale_denominator,
|
||||
"Return the Map Scale Denominator.\n"
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
">>> m.scale_denominator()\n"
|
||||
)
|
||||
|
||||
.def("view_transform",&Map::view_transform,
|
||||
.def("view_transform",get_view_transform,
|
||||
"Return the map ViewTransform object\n"
|
||||
"which is used internally to convert between\n"
|
||||
"geographic coordinates and screen coordinates.\n"
|
||||
|
@ -364,7 +379,7 @@ void export_map()
|
|||
">>> m.zoom(0.25)\n"
|
||||
)
|
||||
|
||||
.def("zoom_all",&Map::zoom_all,
|
||||
.def("zoom_all",&zoom_all,
|
||||
"Set the geographical extent of the map\n"
|
||||
"to the combined extents of all active layers.\n"
|
||||
"\n"
|
||||
|
|
|
@ -126,8 +126,7 @@ void render(const mapnik::Map& map,
|
|||
{
|
||||
python_unblock_auto_block b;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,scale_factor,offset_x, offset_y);
|
||||
ren.apply();
|
||||
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render_with_detector(
|
||||
|
@ -140,7 +139,7 @@ void render_with_detector(
|
|||
{
|
||||
python_unblock_auto_block b;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,detector);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render_layer2(const mapnik::Map& map,
|
||||
|
@ -160,7 +159,7 @@ void render_layer2(const mapnik::Map& map,
|
|||
mapnik::layer const& layer = layers[layer_idx];
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,1.0,0,0);
|
||||
std::set<std::string> names;
|
||||
ren.apply(layer,names);
|
||||
ren.apply(layer,map.styles(),names);
|
||||
}
|
||||
|
||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||
|
@ -174,7 +173,7 @@ void render3(const mapnik::Map& map,
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_surface_ptr surface(cairo_surface_reference(py_surface->surface), mapnik::cairo_surface_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> ren(map,surface,scale_factor,offset_x,offset_y);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render4(const mapnik::Map& map, PycairoSurface* py_surface)
|
||||
|
@ -182,7 +181,7 @@ void render4(const mapnik::Map& map, PycairoSurface* py_surface)
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_surface_ptr surface(cairo_surface_reference(py_surface->surface), mapnik::cairo_surface_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> ren(map,surface);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render5(const mapnik::Map& map,
|
||||
|
@ -194,7 +193,7 @@ void render5(const mapnik::Map& map,
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_ptr context(py_context->ctx, mapnik::cairo_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map,context,scale_factor,offset_x, offset_y);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render6(const mapnik::Map& map, PycairoContext* py_context)
|
||||
|
@ -202,7 +201,7 @@ void render6(const mapnik::Map& map, PycairoContext* py_context)
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_ptr context(py_context->ctx, mapnik::cairo_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map,context);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render_with_detector2(
|
||||
|
@ -213,7 +212,7 @@ void render_with_detector2(
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_ptr context(py_context->ctx, mapnik::cairo_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map,context,detector);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render_with_detector3(
|
||||
|
@ -227,7 +226,7 @@ void render_with_detector3(
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_ptr context(py_context->ctx, mapnik::cairo_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map,context,detector,scale_factor,offset_x,offset_y);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render_with_detector4(
|
||||
|
@ -238,7 +237,7 @@ void render_with_detector4(
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_surface_ptr surface(cairo_surface_reference(py_surface->surface), mapnik::cairo_surface_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> ren(map, surface, detector);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
void render_with_detector5(
|
||||
|
@ -252,7 +251,7 @@ void render_with_detector5(
|
|||
python_unblock_auto_block b;
|
||||
mapnik::cairo_surface_ptr surface(cairo_surface_reference(py_surface->surface), mapnik::cairo_surface_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> ren(map, surface, detector, scale_factor, offset_x, offset_y);
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -392,7 +392,7 @@ void render_layer_for_grid(mapnik::Map const& map,
|
|||
|
||||
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
|
||||
mapnik::layer const& layer = layers[layer_idx];
|
||||
ren.apply(layer,attributes);
|
||||
ren.apply(layer,map.styles(),attributes);
|
||||
}
|
||||
|
||||
/* old, original impl - to be removed after further testing
|
||||
|
@ -455,7 +455,7 @@ boost::python::dict render_grid(mapnik::Map const& map,
|
|||
{
|
||||
mapnik::grid_renderer<mapnik::grid> ren(map,grid,1.0,0,0);
|
||||
mapnik::layer const& layer = layers[layer_idx];
|
||||
ren.apply(layer,attributes);
|
||||
ren.apply(layer,map.styles(),attributes);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
|
@ -262,7 +262,7 @@ int main ( int argc , char** argv)
|
|||
|
||||
image_32 buf(m.width(),m.height());
|
||||
agg_renderer<image_32> ren(m,buf);
|
||||
ren.apply();
|
||||
ren.apply(m.layers(),m.styles());
|
||||
|
||||
save_to_file(buf,"demo.jpg","jpeg");
|
||||
save_to_file(buf,"demo.png","png");
|
||||
|
@ -294,7 +294,7 @@ int main ( int argc , char** argv)
|
|||
double scale_factor = 1.0;
|
||||
cairo_ptr image_context = (create_context(image_surface));
|
||||
mapnik::cairo_renderer<cairo_ptr> png_render(m,image_context,scale_factor);
|
||||
png_render.apply();
|
||||
png_render.apply(m.layers(),m.styles());
|
||||
// we can now write to png with cairo functionality
|
||||
cairo_surface_write_to_png(&*image_surface, "cairo-demo.png");
|
||||
// but we can also benefit from quantization by converting
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
|
||||
// qt
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QApplication>
|
||||
#include <QStringList>
|
||||
#include <QSettings>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <mapnik/feature_kv_iterator.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/util/map_query.hpp>
|
||||
|
||||
#ifdef HAVE_CAIRO
|
||||
// cairo
|
||||
|
@ -176,7 +177,7 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
|
|||
projection layer_proj(layer.srs());
|
||||
mapnik::proj_transform prj_trans(map_proj,layer_proj);
|
||||
//std::auto_ptr<mapnik::memory_datasource> data(new mapnik::memory_datasource);
|
||||
mapnik::featureset_ptr fs = map_->query_map_point(index,x,y);
|
||||
mapnik::featureset_ptr fs = mapnik::util::query_map_point(map,index,x,y);
|
||||
|
||||
if (fs)
|
||||
{
|
||||
|
@ -483,7 +484,7 @@ void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::strin
|
|||
{
|
||||
//image_32 image(width,height);
|
||||
//agg_renderer renderer(map,image);
|
||||
//renderer.apply();
|
||||
//renderer.apply(map.layers(),map.styles());
|
||||
//image.saveToFile(filename,type);
|
||||
std::cout << "Export to file .." << std::endl;
|
||||
}
|
||||
|
@ -505,7 +506,7 @@ void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
|||
{
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
ren.apply();
|
||||
ren.apply(map.layers(),map.styles());
|
||||
}
|
||||
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);
|
||||
pix = QPixmap::fromImage(image.rgbSwapped());
|
||||
|
@ -538,7 +539,7 @@ void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
|||
mapnik::cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32,map.width(),map.height()),
|
||||
mapnik::cairo_surface_closer());
|
||||
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> renderer(map, image_surface, scaling_factor);
|
||||
renderer.apply();
|
||||
renderer.apply(map.layers(),map.styles());
|
||||
image_32 buf(image_surface);
|
||||
QImage image((uchar*)buf.raw_data(),buf.width(),buf.height(),QImage::Format_ARGB32);
|
||||
pix = QPixmap::fromImage(image.rgbSwapped());
|
||||
|
|
|
@ -59,18 +59,22 @@ public:
|
|||
/*!
|
||||
* \brief apply renderer to all map layers.
|
||||
*/
|
||||
void apply(double scale_denom_override=0.0);
|
||||
void apply(std::vector<mapnik::layer> const& layers,
|
||||
std::map<std::string,feature_type_style> const& styles,
|
||||
double scale_denom_override=0.0);
|
||||
|
||||
/*!
|
||||
* \brief apply renderer to a single layer, providing pre-populated set of query attribute names.
|
||||
*/
|
||||
void apply(mapnik::layer const& lyr,
|
||||
std::map<std::string,feature_type_style> const& styles,
|
||||
std::set<std::string>& names,
|
||||
double scale_denom_override=0.0);
|
||||
/*!
|
||||
* \brief render a layer given a projection and scale.
|
||||
*/
|
||||
void apply_to_layer(layer const& lay,
|
||||
std::map<std::string,feature_type_style> const& styles,
|
||||
Processor & p,
|
||||
projection const& proj0,
|
||||
double scale,
|
||||
|
@ -79,14 +83,14 @@ public:
|
|||
unsigned height,
|
||||
box2d<double> const& extent,
|
||||
int buffer_size,
|
||||
std::set<std::string>& names);
|
||||
std::set<std::string>& names,
|
||||
boost::optional<box2d<double> > const& maximum_extent);
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief renders a featureset with the given styles.
|
||||
*/
|
||||
void render_style(layer const& lay,
|
||||
Processor & p,
|
||||
void render_style(Processor & p,
|
||||
feature_type_style const* style,
|
||||
rule_cache const& rules,
|
||||
std::string const& style_name,
|
||||
|
|
|
@ -56,12 +56,6 @@
|
|||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
#include <mapnik/timer.hpp>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
@ -150,13 +144,10 @@ feature_style_processor<Processor>::feature_style_processor(Map const& m, double
|
|||
}
|
||||
|
||||
template <typename Processor>
|
||||
void feature_style_processor<Processor>::apply(double scale_denom)
|
||||
void feature_style_processor<Processor>::apply(std::vector<mapnik::layer> const& layers,
|
||||
std::map<std::string,feature_type_style> const& styles,
|
||||
double scale_denom)
|
||||
{
|
||||
#if defined(RENDERING_STATS)
|
||||
std::clog << "\n//-- starting rendering timer...\n";
|
||||
mapnik::progress_timer t(std::clog, "total map rendering");
|
||||
#endif
|
||||
|
||||
Processor & p = static_cast<Processor&>(*this);
|
||||
p.start_map_processing(m_);
|
||||
|
||||
|
@ -165,12 +156,13 @@ void feature_style_processor<Processor>::apply(double scale_denom)
|
|||
scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic());
|
||||
scale_denom *= scale_factor_;
|
||||
|
||||
BOOST_FOREACH ( layer const& lyr, m_.layers() )
|
||||
BOOST_FOREACH ( layer const& lyr, layers )
|
||||
{
|
||||
if (lyr.visible(scale_denom))
|
||||
{
|
||||
std::set<std::string> names;
|
||||
apply_to_layer(lyr,
|
||||
styles,
|
||||
p,
|
||||
proj,
|
||||
m_.scale(),
|
||||
|
@ -179,22 +171,18 @@ void feature_style_processor<Processor>::apply(double scale_denom)
|
|||
m_.height(),
|
||||
m_.get_current_extent(),
|
||||
m_.buffer_size(),
|
||||
names);
|
||||
names,
|
||||
m_.maximum_extent());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
p.end_map_processing(m_);
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
t.stop();
|
||||
std::clog << "//-- rendering timer stopped...\n\n";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
template <typename Processor>
|
||||
void feature_style_processor<Processor>::apply(mapnik::layer const& lyr,
|
||||
std::map<std::string,feature_type_style> const& styles,
|
||||
std::set<std::string>& names,
|
||||
double scale_denom)
|
||||
{
|
||||
|
@ -208,6 +196,7 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr,
|
|||
if (lyr.visible(scale_denom))
|
||||
{
|
||||
apply_to_layer(lyr,
|
||||
styles,
|
||||
p,
|
||||
proj,
|
||||
m_.scale(),
|
||||
|
@ -216,13 +205,16 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr,
|
|||
m_.height(),
|
||||
m_.get_current_extent(),
|
||||
m_.buffer_size(),
|
||||
names);
|
||||
names,
|
||||
m_.maximum_extent());
|
||||
}
|
||||
p.end_map_processing(m_);
|
||||
}
|
||||
|
||||
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,
|
||||
std::map<std::string,feature_type_style> const& styles,
|
||||
Processor & p,
|
||||
projection const& proj0,
|
||||
double scale,
|
||||
double scale_denom,
|
||||
|
@ -230,7 +222,8 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
unsigned height,
|
||||
box2d<double> const& extent,
|
||||
int buffer_size,
|
||||
std::set<std::string>& names)
|
||||
std::set<std::string>& names,
|
||||
boost::optional<box2d<double> > const& maximum_extent)
|
||||
{
|
||||
std::vector<std::string> const& style_names = lay.styles();
|
||||
|
||||
|
@ -250,23 +243,9 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
progress_timer layer_timer(std::clog, "rendering total for layer: '" + lay.name() + "'");
|
||||
#endif
|
||||
|
||||
projection proj1(lay.srs(),true);
|
||||
proj_transform prj_trans(proj0,proj1);
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
if (! prj_trans.equal())
|
||||
{
|
||||
std::clog << "notice: reprojecting layer: '" << lay.name() << "' from/to:\n\t'"
|
||||
<< lay.srs() << "'\n\t'"
|
||||
<< m_.srs() << "'\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
box2d<double> query_ext = extent; // unbuffered
|
||||
box2d<double> buffered_query_ext(query_ext); // buffered
|
||||
|
||||
|
@ -284,7 +263,6 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
buffered_query_ext.height(query_ext.height() + buffer_padding);
|
||||
|
||||
// clip buffered extent by maximum extent, if supplied
|
||||
boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
|
||||
if (maximum_extent) {
|
||||
buffered_query_ext.clip(*maximum_extent);
|
||||
}
|
||||
|
@ -329,24 +307,23 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
// https://github.com/mapnik/mapnik/issues/1477
|
||||
BOOST_FOREACH(std::string const& style_name, style_names)
|
||||
{
|
||||
boost::optional<feature_type_style const&> style=m_.find_style(style_name);
|
||||
if (!style)
|
||||
std::map<std::string,feature_type_style>::const_iterator itr = styles.find(style_name);
|
||||
if (itr == styles.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (style->comp_op() || style->image_filters().size() > 0)
|
||||
feature_type_style const& style = itr->second;
|
||||
|
||||
if (style.comp_op() || style.image_filters().size() > 0)
|
||||
{
|
||||
if (style->active(scale_denom))
|
||||
if (style.active(scale_denom))
|
||||
{
|
||||
// trigger any needed compositing ops
|
||||
p.start_style_processing(*style);
|
||||
p.end_style_processing(*style);
|
||||
p.start_style_processing(style);
|
||||
p.end_style_processing(style);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(RENDERING_STATS)
|
||||
layer_timer.discard();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -391,17 +368,16 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
// iterate through all named styles collecting active styles and attribute names
|
||||
BOOST_FOREACH(std::string const& style_name, style_names)
|
||||
{
|
||||
boost::optional<feature_type_style const&> style=m_.find_style(style_name);
|
||||
if (!style)
|
||||
std::map<std::string,feature_type_style>::const_iterator itr = styles.find(style_name);
|
||||
if (itr == styles.end())
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(feature_style_processor)
|
||||
<< "feature_style_processor: Style=" << style_name
|
||||
<< " required for layer=" << lay.name() << " does not exist.";
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<rule> const& rules = style->get_rules();
|
||||
feature_type_style const& style = itr->second;
|
||||
std::vector<rule> const& rules = style.get_rules();
|
||||
bool active_rules = false;
|
||||
std::auto_ptr<rule_cache> rc(new rule_cache);
|
||||
BOOST_FOREACH(rule const& r, rules)
|
||||
|
@ -420,7 +396,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
if (active_rules)
|
||||
{
|
||||
rule_caches.push_back(rc);
|
||||
active_styles.push_back(&(*style));
|
||||
active_styles.push_back(&style);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,7 +467,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
int i = 0;
|
||||
BOOST_FOREACH (feature_type_style const* style, active_styles)
|
||||
{
|
||||
render_style(lay, p, style, rule_caches[i], style_names[i],
|
||||
render_style(p, style, rule_caches[i], style_names[i],
|
||||
cache.features(q), prj_trans);
|
||||
i++;
|
||||
}
|
||||
|
@ -504,7 +480,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
int i = 0;
|
||||
BOOST_FOREACH (feature_type_style const* style, active_styles)
|
||||
{
|
||||
render_style(lay, p, style, rule_caches[i], style_names[i],
|
||||
render_style(p, style, rule_caches[i], style_names[i],
|
||||
cache.features(q), prj_trans);
|
||||
i++;
|
||||
}
|
||||
|
@ -525,7 +501,7 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
int i = 0;
|
||||
BOOST_FOREACH (feature_type_style const* style, active_styles)
|
||||
{
|
||||
render_style(lay, p, style, rule_caches[i], style_names[i],
|
||||
render_style(p, style, rule_caches[i], style_names[i],
|
||||
cache.features(q), prj_trans);
|
||||
i++;
|
||||
}
|
||||
|
@ -536,24 +512,19 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
|||
int i = 0;
|
||||
BOOST_FOREACH (feature_type_style const* style, active_styles)
|
||||
{
|
||||
render_style(lay, p, style, rule_caches[i], style_names[i],
|
||||
render_style(p, style, rule_caches[i], style_names[i],
|
||||
ds->features(q), prj_trans);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
layer_timer.stop();
|
||||
#endif
|
||||
|
||||
p.end_layer_processing(lay);
|
||||
}
|
||||
|
||||
|
||||
template <typename Processor>
|
||||
void feature_style_processor<Processor>::render_style(
|
||||
layer const& lay,
|
||||
Processor & p,
|
||||
feature_type_style const* style,
|
||||
rule_cache const& rc,
|
||||
|
@ -568,24 +539,9 @@ void feature_style_processor<Processor>::render_style(
|
|||
return;
|
||||
}
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
std::ostringstream s1;
|
||||
s1 << "rendering style for layer: '" << lay.name()
|
||||
<< "' and style '" << style_name << "'";
|
||||
mapnik::progress_timer style_timer(std::clog, s1.str());
|
||||
|
||||
int feature_processed_count = 0;
|
||||
int feature_count = 0;
|
||||
#endif
|
||||
|
||||
feature_ptr feature;
|
||||
while ((feature = features->next()))
|
||||
{
|
||||
#if defined(RENDERING_STATS)
|
||||
feature_count++;
|
||||
bool feat_processed = false;
|
||||
#endif
|
||||
|
||||
bool do_else = true;
|
||||
bool do_also = false;
|
||||
|
||||
|
@ -595,10 +551,6 @@ void feature_style_processor<Processor>::render_style(
|
|||
value_type result = boost::apply_visitor(evaluate<feature_impl,value_type>(*feature),*expr);
|
||||
if (result.to_bool())
|
||||
{
|
||||
#if defined(RENDERING_STATS)
|
||||
feat_processed = true;
|
||||
#endif
|
||||
|
||||
p.painted(true);
|
||||
|
||||
do_else=false;
|
||||
|
@ -627,10 +579,6 @@ void feature_style_processor<Processor>::render_style(
|
|||
{
|
||||
BOOST_FOREACH( rule const* r, rc.get_else_rules() )
|
||||
{
|
||||
#if defined(RENDERING_STATS)
|
||||
feat_processed = true;
|
||||
#endif
|
||||
|
||||
p.painted(true);
|
||||
|
||||
rule::symbolizers const& symbols = r->get_symbolizers();
|
||||
|
@ -649,10 +597,6 @@ void feature_style_processor<Processor>::render_style(
|
|||
{
|
||||
BOOST_FOREACH( rule const* r, rc.get_also_rules() )
|
||||
{
|
||||
#if defined(RENDERING_STATS)
|
||||
feat_processed = true;
|
||||
#endif
|
||||
|
||||
p.painted(true);
|
||||
|
||||
rule::symbolizers const& symbols = r->get_symbolizers();
|
||||
|
@ -667,32 +611,7 @@ void feature_style_processor<Processor>::render_style(
|
|||
}
|
||||
}
|
||||
}
|
||||
#if defined(RENDERING_STATS)
|
||||
if (feat_processed)
|
||||
feature_processed_count++;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(RENDERING_STATS)
|
||||
style_timer.stop();
|
||||
|
||||
// done with style
|
||||
std::ostringstream s;
|
||||
if (feature_count > 0)
|
||||
{
|
||||
double perc_processed = ((double)feature_processed_count/(double)feature_count)*100.0;
|
||||
|
||||
s << "percent rendered: " << perc_processed << "% - " << feature_processed_count
|
||||
<< " rendered for " << feature_count << " queried for ";
|
||||
s << std::setw(15 - (int)s.tellp()) << " layer '" << lay.name() << "' and style '" << style_name << "'\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "" << std::setw(15) << "- no features returned from query for layer '" << lay.name() << "' and style '" << style_name << "'\n";
|
||||
}
|
||||
std::clog << s.str();
|
||||
style_timer.discard();
|
||||
#endif
|
||||
p.end_style_processing(*style);
|
||||
}
|
||||
|
||||
|
|
|
@ -329,10 +329,6 @@ public:
|
|||
*/
|
||||
void zoom_to_box(box2d<double> const& box);
|
||||
|
||||
/*! \brief Zoom the map to show all data.
|
||||
*/
|
||||
void zoom_all();
|
||||
|
||||
void pan(int x,int y);
|
||||
|
||||
void pan_and_zoom(int x,int y,double zoom);
|
||||
|
@ -352,36 +348,6 @@ public:
|
|||
*/
|
||||
double scale() const;
|
||||
|
||||
double scale_denominator() const;
|
||||
|
||||
CoordTransform view_transform() const;
|
||||
|
||||
/*!
|
||||
* @brief Query a Map layer (by layer index) for features
|
||||
*
|
||||
* Intersecting the given x,y location in the coordinates
|
||||
* of map projection.
|
||||
*
|
||||
* @param index The index of the layer to query from.
|
||||
* @param x The x coordinate where to query.
|
||||
* @param y The y coordinate where to query.
|
||||
* @return A Mapnik Featureset if successful otherwise will return NULL.
|
||||
*/
|
||||
featureset_ptr query_point(unsigned index, double x, double y) const;
|
||||
|
||||
/*!
|
||||
* @brief Query a Map layer (by layer index) for features
|
||||
*
|
||||
* Intersecting the given x,y location in the coordinates
|
||||
* of the pixmap or map surface.
|
||||
*
|
||||
* @param index The index of the layer to query from.
|
||||
* @param x The x coordinate where to query.
|
||||
* @param y The y coordinate where to query.
|
||||
* @return A Mapnik Featureset if successful otherwise will return NULL.
|
||||
*/
|
||||
featureset_ptr query_map_point(unsigned index, double x, double y) const;
|
||||
|
||||
~Map();
|
||||
|
||||
inline void set_aspect_fix_mode(aspect_fix_mode afm) { aspectFixMode_ = afm; }
|
||||
|
|
|
@ -468,7 +468,7 @@ void save_to_cairo_file(mapnik::Map const& map,
|
|||
*/
|
||||
|
||||
mapnik::cairo_renderer<cairo_ptr> ren(map, create_context(surface), scale_factor);
|
||||
ren.apply(scale_denominator);
|
||||
ren.apply(map.layers(),map.styles(),scale_denominator);
|
||||
|
||||
if (type == "ARGB32" || type == "RGB24")
|
||||
{
|
||||
|
|
154
src/map.cpp
154
src/map.cpp
|
@ -29,13 +29,8 @@
|
|||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/filter_featureset.hpp>
|
||||
#include <mapnik/hit_test_filter.hpp>
|
||||
#include <mapnik/scale_denominator.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
#include <mapnik/config.hpp> // for PROJ_ENVELOPE_POINTS
|
||||
|
||||
|
@ -357,78 +352,6 @@ void Map::zoom(double factor)
|
|||
fixAspectRatio();
|
||||
}
|
||||
|
||||
void Map::zoom_all()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (layers_.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
projection proj0(srs_);
|
||||
box2d<double> ext;
|
||||
bool success = false;
|
||||
bool first = true;
|
||||
std::vector<layer>::const_iterator itr = layers_.begin();
|
||||
std::vector<layer>::const_iterator end = layers_.end();
|
||||
while (itr != end)
|
||||
{
|
||||
if (itr->active())
|
||||
{
|
||||
std::string const& layer_srs = itr->srs();
|
||||
projection proj1(layer_srs);
|
||||
proj_transform prj_trans(proj0,proj1);
|
||||
box2d<double> layer_ext = itr->envelope();
|
||||
if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS))
|
||||
{
|
||||
success = true;
|
||||
MAPNIK_LOG_DEBUG(map) << "map: Layer " << itr->name() << " original ext=" << itr->envelope();
|
||||
MAPNIK_LOG_DEBUG(map) << "map: Layer " << itr->name() << " transformed to map srs=" << layer_ext;
|
||||
if (first)
|
||||
{
|
||||
ext = layer_ext;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ext.expand_to_include(layer_ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
if (maximum_extent_) {
|
||||
ext.clip(*maximum_extent_);
|
||||
}
|
||||
zoom_to_box(ext);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (maximum_extent_)
|
||||
{
|
||||
MAPNIK_LOG_ERROR(map) << "could not zoom to combined layer extents"
|
||||
<< " so falling back to maximum-extent for zoom_all result";
|
||||
zoom_to_box(*maximum_extent_);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "could not zoom to combined layer extents "
|
||||
<< "using zoom_all because proj4 could not "
|
||||
<< "back project any layer extents into the map srs "
|
||||
<< "(set map 'maximum-extent' to override layer extents)";
|
||||
throw std::runtime_error(s.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (proj_init_error const& ex)
|
||||
{
|
||||
throw mapnik::config_error(std::string("Projection error during map.zoom_all: ") + ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Map::zoom_to_box(box2d<double> const& box)
|
||||
{
|
||||
current_extent_=box;
|
||||
|
@ -530,83 +453,6 @@ double Map::scale() const
|
|||
return current_extent_.width();
|
||||
}
|
||||
|
||||
double Map::scale_denominator() const
|
||||
{
|
||||
projection map_proj(srs_);
|
||||
return mapnik::scale_denominator( scale(), map_proj.is_geographic());
|
||||
}
|
||||
|
||||
CoordTransform Map::view_transform() const
|
||||
{
|
||||
return CoordTransform(width_,height_,current_extent_);
|
||||
}
|
||||
|
||||
featureset_ptr Map::query_point(unsigned index, double x, double y) const
|
||||
{
|
||||
if (!current_extent_.valid())
|
||||
{
|
||||
throw std::runtime_error("query_point: map extent is not intialized, you need to set a valid extent before querying");
|
||||
}
|
||||
if (!current_extent_.intersects(x,y))
|
||||
{
|
||||
throw std::runtime_error("query_point: x,y coords do not intersect map extent");
|
||||
}
|
||||
if (index < layers_.size())
|
||||
{
|
||||
mapnik::layer const& layer = layers_[index];
|
||||
mapnik::datasource_ptr ds = layer.datasource();
|
||||
if (ds)
|
||||
{
|
||||
mapnik::projection dest(srs_);
|
||||
mapnik::projection source(layer.srs());
|
||||
proj_transform prj_trans(source,dest);
|
||||
double z = 0;
|
||||
if (!prj_trans.equal() && !prj_trans.backward(x,y,z))
|
||||
{
|
||||
throw std::runtime_error("query_point: could not project x,y into layer srs");
|
||||
}
|
||||
// calculate default tolerance
|
||||
mapnik::box2d<double> map_ex = current_extent_;
|
||||
if (maximum_extent_)
|
||||
{
|
||||
map_ex.clip(*maximum_extent_);
|
||||
}
|
||||
if (!prj_trans.backward(map_ex,PROJ_ENVELOPE_POINTS))
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "query_point: could not project map extent '" << map_ex
|
||||
<< "' into layer srs for tolerance calculation";
|
||||
throw std::runtime_error(s.str());
|
||||
}
|
||||
double tol = (map_ex.maxx() - map_ex.minx()) / width_ * 3;
|
||||
featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y), tol);
|
||||
MAPNIK_LOG_DEBUG(map) << "map: Query at point tol=" << tol << "(" << x << "," << y << ")";
|
||||
if (fs)
|
||||
{
|
||||
return boost::make_shared<filter_featureset<hit_test_filter> >(fs,
|
||||
hit_test_filter(x,y,tol));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "Invalid layer index passed to query_point: '" << index << "'";
|
||||
if (!layers_.empty()) s << " for map with " << layers_.size() << " layers(s)";
|
||||
else s << " (map has no layers)";
|
||||
throw std::out_of_range(s.str());
|
||||
}
|
||||
return featureset_ptr();
|
||||
}
|
||||
|
||||
featureset_ptr Map::query_map_point(unsigned index, double x, double y) const
|
||||
{
|
||||
CoordTransform tr = view_transform();
|
||||
tr.backward(&x,&y);
|
||||
return query_point(index,x,y);
|
||||
}
|
||||
|
||||
|
||||
parameters const& Map::get_extra_parameters() const
|
||||
{
|
||||
return extra_params_;
|
||||
|
|
Loading…
Reference in a new issue