Compare commits

...

12 commits

15 changed files with 286 additions and 244 deletions

View file

@ -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());
}
void set_maximum_extent(mapnik::Map & m, boost::optional<mapnik::box2d<double> > const& box)
@ -326,14 +341,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"
@ -353,7 +368,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"

View file

@ -130,8 +130,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(
@ -144,7 +143,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,
@ -164,7 +163,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)
@ -178,7 +177,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)
@ -186,7 +185,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,
@ -198,7 +197,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)
@ -206,7 +205,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(
@ -217,7 +216,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(
@ -231,7 +230,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(
@ -242,7 +241,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(
@ -256,7 +255,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

View file

@ -394,7 +394,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
@ -457,7 +457,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 (...)
{

View file

@ -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

View file

@ -19,7 +19,7 @@
// qt
#include <QtWidgets/QApplication>
#include <QApplication>
#include <QStringList>
#include <QSettings>
#include <mapnik/datasource_cache.hpp>

View file

@ -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());

View file

@ -24,11 +24,15 @@
#define MAPNIK_FEATURE_STYLE_PROCESSOR_HPP
// mapnik
#include <mapnik/datasource.hpp> // for featureset_ptr
#include <mapnik/config.hpp>
#include <mapnik/featureset.hpp>
// boost
#include <boost/optional.hpp>
// stl
#include <set>
#include <map>
#include <string>
#include <vector>
@ -41,6 +45,7 @@ class projection;
class proj_transform;
class feature_type_style;
class rule_cache;
template <typename T> class box2d;
enum eAttributeCollectionPolicy
{
@ -59,18 +64,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,7 +88,8 @@ 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:
/*!

View file

@ -138,7 +138,9 @@ 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)
{
Processor & p = static_cast<Processor&>(*this);
p.start_map_processing(m_);
@ -148,12 +150,13 @@ void feature_style_processor<Processor>::apply(double scale_denom)
scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic());
scale_denom *= p.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(),
@ -162,17 +165,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_);
}
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)
{
@ -186,6 +190,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(),
@ -194,13 +199,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,
@ -208,7 +216,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();
@ -248,7 +257,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);
@ -294,18 +302,20 @@ 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);
}
}
}
@ -351,17 +361,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)
@ -376,7 +385,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);
}
}

View file

@ -0,0 +1,47 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 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_FEATURESET_HPP
#define MAPNIK_FEATURESET_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/noncopyable.hpp>
// boost
#include <boost/shared_ptr.hpp>
namespace mapnik {
class feature_impl;
struct MAPNIK_DECL Featureset : private mapnik::noncopyable
{
virtual boost::shared_ptr<feature_impl> next() = 0;
virtual ~Featureset() {}
};
typedef boost::shared_ptr<Featureset> featureset_ptr;
}
#endif // MAPNIK_FEATURESET_HPP

View file

@ -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; }

View file

@ -0,0 +1,148 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2013 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_UTIL_MAP_QUERY
#define MAPNIK_UTIL_MAP_QUERY
#include <mapnik/map.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/filter_featureset.hpp>
#include <mapnik/hit_test_filter.hpp>
#include <boost/make_shared.hpp>
#include <boost/foreach.hpp>
#include <sstream>
#include <stdexcept>
namespace mapnik { namespace util {
static mapnik::box2d<double> get_extent(mapnik::Map const& map)
{
std::vector<mapnik::layer> const& layers = map.layers();
if (layers.empty())
{
throw std::runtime_error("map has no layers so unable to get extent");
}
box2d<double> ext;
bool success = false;
projection proj0(map.srs());
bool first = true;
BOOST_FOREACH ( layer const& lay, map.layers() )
{
if (lay.active())
{
projection proj1(lay.srs());
proj_transform prj_trans(proj0,proj1);
box2d<double> layer_ext = lay.envelope();
if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS))
{
success = true;
if (first)
{
ext = layer_ext;
first = false;
}
else
{
ext.expand_to_include(layer_ext);
}
}
}
}
if (!success)
{
throw std::runtime_error("could not zoom to combined layer extents");
}
return ext;
}
static featureset_ptr query_point(mapnik::Map const& map, unsigned index, double x, double y)
{
if (!map.get_current_extent().valid())
{
throw std::runtime_error("query_point: map extent is not intialized, you need to set a valid extent before querying");
}
if (!map.get_current_extent().intersects(x,y))
{
throw std::runtime_error("query_point: x,y coords do not intersect map extent");
}
std::vector<mapnik::layer> const& layers = map.layers();
if (index < layers.size())
{
mapnik::layer const& layer = layers[index];
mapnik::datasource_ptr ds = layer.datasource();
if (ds)
{
mapnik::projection dest(map.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 = map.get_current_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()) / map.width() * 3;
featureset_ptr fs = ds->features_at_point(mapnik::coord2d(x,y), tol);
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();
}
static featureset_ptr query_map_point(mapnik::Map const& map, unsigned index, double x, double y)
{
CoordTransform tr(map.width(),map.height(),map.get_current_extent());
tr.backward(&x,&y);
return query_point(map,index,x,y);
}
}}
#endif // MAPNIK_UTIL_MAP_QUERY

View file

@ -559,7 +559,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")
{

View file

@ -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_;

View file

@ -21,6 +21,7 @@
#include <mapnik/util/fs.hpp>
#include <vector>
#include <algorithm>
#include <mapnik/util/map_query.hpp>
#include "utils.hpp"
@ -64,13 +65,13 @@ int main(int argc, char** argv)
l.add_style("style");
mapnik::Map m = map;
m.addLayer(l);
m.zoom_all();
m.zoom_to_box(mapnik::util::get_extent(m));
mapnik::image_32 im(m.width(),m.height());
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
//std::clog << mapnik::save_map_to_string(m) << "\n";
BOOST_TEST(true);
// should throw here with "CSV Plugin: no attribute 'foo'. Valid attributes are: x,y."
ren.apply();
ren.apply(m.layers(),m.styles());
BOOST_TEST(false);
} catch (...) {
BOOST_TEST(true);

View file

@ -67,7 +67,7 @@ int main(int argc, char** argv)
256,256));
mapnik::image_32 buf(m.width(),m.height());
mapnik::agg_renderer<mapnik::image_32> ren(m,buf);
ren.apply();
ren.apply(m.layers(),m.styles());
} catch (std::exception const& ex) {
BOOST_TEST_EQ(std::string(ex.what()),std::string("No valid font face could be loaded for font set: 'fontset'"));
}