Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
d7d088cc97
9 changed files with 516 additions and 273 deletions
|
@ -63,5 +63,9 @@ void export_line_symbolizer()
|
|||
&line_symbolizer::smooth,
|
||||
&line_symbolizer::set_smooth,
|
||||
"smooth value (0..1.0)")
|
||||
.add_property("offset",
|
||||
&line_symbolizer::offset,
|
||||
&line_symbolizer::set_offset,
|
||||
"offset value")
|
||||
;
|
||||
}
|
||||
|
|
|
@ -109,6 +109,13 @@ If you see bits of code around that do not follow these please don't hesitate to
|
|||
|
||||
#### Shared pointers should be created with [boost::make_shared](http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/make_shared.html) where possible
|
||||
|
||||
#### Use assignment operator for zero initialized numbers
|
||||
|
||||
double num = 0; // please
|
||||
|
||||
double num(0); // no
|
||||
|
||||
|
||||
#### Function definitions should not be separated from their arguments:
|
||||
|
||||
void foo(int a) // please
|
||||
|
|
|
@ -122,8 +122,10 @@ public:
|
|||
// nothing to do
|
||||
}
|
||||
|
||||
protected:
|
||||
void render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & mtx, double opacity=1.0, bool recenter=true);
|
||||
void render_box(box2d<double> const& b);
|
||||
protected:
|
||||
|
||||
|
||||
Map const& m_;
|
||||
Cairo::RefPtr<Cairo::Context> context_;
|
||||
|
|
|
@ -113,7 +113,7 @@ struct vector_markers_rasterizer_dispatch
|
|||
}
|
||||
else
|
||||
{
|
||||
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
|
||||
markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_,
|
||||
sym_.get_spacing() * scale_factor_,
|
||||
sym_.get_max_error(),
|
||||
sym_.get_allow_overlap());
|
||||
|
@ -251,7 +251,7 @@ struct raster_markers_rasterizer_dispatch
|
|||
typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
|
||||
interpolator_type> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa_alpha<renderer_base,
|
||||
agg::span_allocator<agg::rgba8>,
|
||||
agg::span_allocator<color_type>,
|
||||
span_gen_type> renderer_type;
|
||||
img_accessor_type ia(pixf);
|
||||
interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) );
|
||||
|
|
|
@ -344,8 +344,8 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
{
|
||||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands...";
|
||||
|
||||
int hasNoData(0);
|
||||
double nodata(0);
|
||||
int hasNoData = 0;
|
||||
double nodata = 0.0;
|
||||
if (nodata_value_)
|
||||
{
|
||||
hasNoData = 1;
|
||||
|
|
|
@ -143,6 +143,7 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
|
|||
|
||||
path_type path(t_,*frame,prj_trans);
|
||||
agg::conv_stroke<path_type> stroke(path);
|
||||
stroke.width(scale_factor_);
|
||||
ras_ptr->add_path(stroke);
|
||||
ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(255 * sym.get_opacity())));
|
||||
agg::render_scanlines(*ras_ptr, sl, ren);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
#include <mapnik/vertex_converters.hpp>
|
||||
|
||||
#include <mapnik/marker_helpers.hpp>
|
||||
// cairo
|
||||
#include <cairomm/context.h>
|
||||
#include <cairomm/surface.h>
|
||||
|
@ -623,6 +623,24 @@ public:
|
|||
context_->restore();
|
||||
}
|
||||
|
||||
void add_image(agg::trans_affine const& tr, image_data_32 & data, double opacity = 1.0)
|
||||
{
|
||||
cairo_pattern pattern(data);
|
||||
if (!tr.is_identity())
|
||||
{
|
||||
double m[6];
|
||||
tr.store_to(m);
|
||||
Cairo::Matrix cairo_matrix(m[0],m[1],m[2],m[3],m[4],m[5]);
|
||||
cairo_matrix.invert();
|
||||
pattern.set_matrix(cairo_matrix);
|
||||
}
|
||||
context_->save();
|
||||
context_->set_source(pattern.pattern());
|
||||
context_->paint_with_alpha(opacity);
|
||||
context_->restore();
|
||||
}
|
||||
|
||||
|
||||
void set_font_face(cairo_face_manager & manager, face_ptr face)
|
||||
{
|
||||
context_->set_font_face(manager.get_face(face)->face());
|
||||
|
@ -1017,37 +1035,40 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
|
|||
context.stroke();
|
||||
}
|
||||
|
||||
void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity, bool recenter)
|
||||
|
||||
void cairo_renderer_base::render_box(box2d<double> const& b)
|
||||
{
|
||||
cairo_context context(context_);
|
||||
context.move_to(b.minx(), b.miny());
|
||||
context.line_to(b.minx(), b.maxy());
|
||||
context.line_to(b.maxx(), b.maxy());
|
||||
context.line_to(b.maxx(), b.miny());
|
||||
context.close_path();
|
||||
|
||||
if (marker.is_vector())
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
void render_vector_marker(cairo_context & context, pixel_position const& pos, mapnik::svg_storage_type & vmarker,
|
||||
agg::pod_bvector<svg::path_attributes> const & attributes,
|
||||
agg::trans_affine const& tr, double opacity, bool recenter)
|
||||
{
|
||||
box2d<double> bbox;
|
||||
bbox = (*marker.get_vector_data())->bounding_box();
|
||||
using namespace mapnik::svg;
|
||||
box2d<double> bbox = vmarker.bounding_box();
|
||||
|
||||
agg::trans_affine mtx = tr;
|
||||
|
||||
if (recenter)
|
||||
{
|
||||
coord<double,2> c = bbox.center();
|
||||
// center the svg marker on '0,0'
|
||||
mtx = agg::trans_affine_translation(-c.x,-c.y);
|
||||
// apply symbol transformation to get to map space
|
||||
mtx *= tr;
|
||||
// render the marker at the center of the marker box
|
||||
mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height());
|
||||
mtx.translate(pos.x, pos.y);
|
||||
}
|
||||
|
||||
typedef coord_transform<CoordTransform,geometry_type> path_type;
|
||||
agg::trans_affine transform;
|
||||
mapnik::svg_path_ptr vmarker = *marker.get_vector_data();
|
||||
using namespace mapnik::svg;
|
||||
agg::pod_bvector<path_attributes> const & attributes_ = vmarker->attributes();
|
||||
for(unsigned i = 0; i < attributes_.size(); ++i)
|
||||
|
||||
for(unsigned i = 0; i < attributes.size(); ++i)
|
||||
{
|
||||
mapnik::svg::path_attributes const& attr = attributes_[i];
|
||||
mapnik::svg::path_attributes const& attr = attributes[i];
|
||||
if (!attr.visibility_flag)
|
||||
continue;
|
||||
|
||||
|
@ -1066,7 +1087,7 @@ void cairo_renderer_base::render_marker(pixel_position const& pos, marker const&
|
|||
context.transform(Cairo::Matrix(m[0],m[1],m[2],m[3],m[4],m[5]));
|
||||
}
|
||||
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(vmarker->source());
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(vmarker.source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
|
||||
if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
|
||||
|
@ -1123,6 +1144,22 @@ void cairo_renderer_base::render_marker(pixel_position const& pos, marker const&
|
|||
context.restore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity, bool recenter)
|
||||
|
||||
{
|
||||
cairo_context context(context_);
|
||||
|
||||
if (marker.is_vector())
|
||||
{
|
||||
mapnik::svg_path_ptr vmarker = *marker.get_vector_data();
|
||||
if (vmarker)
|
||||
{
|
||||
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
|
||||
render_vector_marker(context, pos, *vmarker, attributes, tr, opacity, recenter);
|
||||
}
|
||||
}
|
||||
else if (marker.is_bitmap())
|
||||
{
|
||||
context.add_image(pos.x, pos.y, **marker.get_bitmap_data(), opacity);
|
||||
|
@ -1385,89 +1422,304 @@ void cairo_renderer_base::process(raster_symbolizer const& sym,
|
|||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Context, typename SvgPath, typename Attributes, typename Detector>
|
||||
struct markers_dispatch
|
||||
{
|
||||
markers_dispatch(Context & ctx,
|
||||
SvgPath & marker,
|
||||
Attributes const& attributes,
|
||||
Detector & detector,
|
||||
markers_symbolizer const& sym,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
double scale_factor)
|
||||
:ctx_(ctx),
|
||||
marker_(marker),
|
||||
attributes_(attributes),
|
||||
detector_(detector),
|
||||
sym_(sym),
|
||||
bbox_(bbox),
|
||||
marker_trans_(marker_trans),
|
||||
scale_factor_(scale_factor) {}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void add_path(T & path)
|
||||
{
|
||||
marker_placement_e placement_method = sym_.get_marker_placement();
|
||||
|
||||
if (placement_method != MARKER_LINE_PLACEMENT)
|
||||
{
|
||||
double x,y;
|
||||
path.rewind(0);
|
||||
if (placement_method == MARKER_INTERIOR_PLACEMENT)
|
||||
{
|
||||
label::interior_position(path, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
label::centroid(path, x, y);
|
||||
}
|
||||
coord2d center = bbox_.center();
|
||||
agg::trans_affine matrix = agg::trans_affine_translation(-center.x, -center.y);
|
||||
matrix *= marker_trans_;
|
||||
matrix *=agg::trans_affine_translation(x, y);
|
||||
|
||||
box2d<double> transformed_bbox = bbox_ * matrix;
|
||||
|
||||
if (sym_.get_allow_overlap() ||
|
||||
detector_.has_placement(transformed_bbox))
|
||||
{
|
||||
render_vector_marker(ctx_, pixel_position(x,y), marker_, attributes_, marker_trans_, sym_.get_opacity(), true);
|
||||
|
||||
if (!sym_.get_ignore_placement())
|
||||
{
|
||||
detector_.insert(transformed_bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
|
||||
sym_.get_spacing() * scale_factor_,
|
||||
sym_.get_max_error(),
|
||||
sym_.get_allow_overlap());
|
||||
double x, y, angle;
|
||||
while (placement.get_point(x, y, angle))
|
||||
{
|
||||
agg::trans_affine matrix = marker_trans_;
|
||||
matrix.rotate(angle);
|
||||
render_vector_marker(ctx_, pixel_position(x,y),marker_, attributes_, matrix, sym_.get_opacity(), true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context & ctx_;
|
||||
SvgPath & marker_;
|
||||
Attributes const& attributes_;
|
||||
Detector & detector_;
|
||||
markers_symbolizer const& sym_;
|
||||
box2d<double> const& bbox_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
double scale_factor_;
|
||||
};
|
||||
|
||||
template <typename Context, typename ImageMarker, typename Detector>
|
||||
struct markers_dispatch_2
|
||||
{
|
||||
markers_dispatch_2(Context & ctx,
|
||||
ImageMarker & marker,
|
||||
Detector & detector,
|
||||
markers_symbolizer const& sym,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
double scale_factor)
|
||||
:ctx_(ctx),
|
||||
marker_(marker),
|
||||
detector_(detector),
|
||||
sym_(sym),
|
||||
bbox_(bbox),
|
||||
marker_trans_(marker_trans),
|
||||
scale_factor_(scale_factor) {}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void add_path(T & path)
|
||||
{
|
||||
marker_placement_e placement_method = sym_.get_marker_placement();
|
||||
|
||||
if (placement_method != MARKER_LINE_PLACEMENT)
|
||||
{
|
||||
double x,y;
|
||||
path.rewind(0);
|
||||
if (placement_method == MARKER_INTERIOR_PLACEMENT)
|
||||
{
|
||||
label::interior_position(path, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
label::centroid(path, x, y);
|
||||
}
|
||||
coord2d center = bbox_.center();
|
||||
agg::trans_affine matrix = agg::trans_affine_translation(-center.x, -center.y);
|
||||
matrix *= marker_trans_;
|
||||
matrix *=agg::trans_affine_translation(x, y);
|
||||
|
||||
box2d<double> transformed_bbox = bbox_ * matrix;
|
||||
|
||||
if (sym_.get_allow_overlap() ||
|
||||
detector_.has_placement(transformed_bbox))
|
||||
{
|
||||
ctx_.add_image(matrix, *marker_, sym_.get_opacity());
|
||||
if (!sym_.get_ignore_placement())
|
||||
{
|
||||
detector_.insert(transformed_bbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
|
||||
sym_.get_spacing() * scale_factor_,
|
||||
sym_.get_max_error(),
|
||||
sym_.get_allow_overlap());
|
||||
double x, y, angle;
|
||||
while (placement.get_point(x, y, angle))
|
||||
{
|
||||
coord2d center = bbox_.center();
|
||||
agg::trans_affine matrix = agg::trans_affine_translation(-center.x, -center.y);
|
||||
matrix *= marker_trans_;
|
||||
matrix *= agg::trans_affine_rotation(angle);
|
||||
matrix *= agg::trans_affine_translation(x, y);
|
||||
ctx_.add_image(matrix, *marker_, sym_.get_opacity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context & ctx_;
|
||||
ImageMarker & marker_;
|
||||
Detector & detector_;
|
||||
markers_symbolizer const& sym_;
|
||||
box2d<double> const& bbox_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
double scale_factor_;
|
||||
};
|
||||
|
||||
}
|
||||
void cairo_renderer_base::process(markers_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
typedef boost::mpl::vector<clip_line_tag,clip_poly_tag,transform_tag,smooth_tag> conv_types;
|
||||
|
||||
cairo_context context(context_);
|
||||
context.set_operator(sym.comp_op());
|
||||
|
||||
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
|
||||
typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
|
||||
agg::trans_affine tr = agg::trans_affine_scaling(scale_factor_);
|
||||
|
||||
agg::trans_affine tr;
|
||||
evaluate_transform(tr, feature, sym.get_image_transform());
|
||||
|
||||
tr = agg::trans_affine_scaling(scale_factor_) * tr;
|
||||
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
|
||||
marker_placement_e placement_method = sym.get_marker_placement();
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance()->find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
if (!(*mark)->is_vector())
|
||||
agg::trans_affine geom_tr;
|
||||
evaluate_transform(geom_tr, feature, sym.get_transform());
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
setup_label_transform(tr, bbox, feature, sym);
|
||||
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: markers_symbolizer does not yet support non-SVG markers";
|
||||
|
||||
return;
|
||||
}
|
||||
boost::optional<svg_path_ptr> marker = (*mark)->get_vector_data();
|
||||
box2d<double> const& bbox = (*marker)->bounding_box();
|
||||
double x1 = bbox.minx();
|
||||
double y1 = bbox.miny();
|
||||
double x2 = bbox.maxx();
|
||||
double y2 = bbox.maxy();
|
||||
double w = (*mark)->width();
|
||||
double h = (*mark)->height();
|
||||
|
||||
agg::trans_affine recenter = agg::trans_affine_translation(-0.5*(x1+x2),-0.5*(y1+y2));
|
||||
tr.transform(&x1,&y1);
|
||||
tr.transform(&x2,&y2);
|
||||
box2d<double> extent(x1,y1,x2,y2);
|
||||
using namespace mapnik::svg;
|
||||
typedef agg::pod_bvector<path_attributes> svg_attributes_type;
|
||||
typedef detail::markers_dispatch<cairo_context, mapnik::svg_storage_type,
|
||||
svg_attributes_type,label_collision_detector4> dispatch_type;
|
||||
|
||||
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
||||
{
|
||||
geometry_type & geom = feature.get_geometry(i);
|
||||
// TODO - merge this code with point_symbolizer rendering
|
||||
if (placement_method == MARKER_POINT_PLACEMENT || geom.size() <= 1)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z=0;
|
||||
label::interior_position(geom, x, y);
|
||||
prj_trans.backward(x,y,z);
|
||||
t_.forward(&x,&y);
|
||||
extent.re_center(x,y);
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
|
||||
|
||||
if (sym.get_allow_overlap() ||
|
||||
detector_.has_placement(extent))
|
||||
{
|
||||
render_marker(pixel_position(x - 0.5 * w, y - 0.5 * h) ,**mark, tr, 1);
|
||||
expression_ptr const& width_expr = sym.get_width();
|
||||
expression_ptr const& height_expr = sym.get_height();
|
||||
|
||||
if (!sym.get_ignore_placement())
|
||||
detector_.insert(extent);
|
||||
// special case for simple ellipse markers
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename == "shape://ellipse"
|
||||
&& (width_expr || height_expr))
|
||||
{
|
||||
svg_storage_type marker_ellipse;
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse.source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
build_ellipse(sym, feature, marker_ellipse, svg_path);
|
||||
svg_attributes_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
agg::trans_affine marker_tr = agg::trans_affine_scaling(scale_factor_);
|
||||
evaluate_transform(marker_tr, feature, sym.get_image_transform());
|
||||
box2d<double> bbox = marker_ellipse.bounding_box();
|
||||
|
||||
dispatch_type dispatch(context, marker_ellipse, result?attributes:(*stock_vector_marker)->attributes(),
|
||||
detector_, sym, bbox, marker_tr, scale_factor_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(query_extent_, dispatch, sym, t_, prj_trans, marker_tr, scale_factor_);
|
||||
|
||||
if (sym.clip() && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
eGeomType type = feature.paths()[0].type();
|
||||
if (type == Polygon)
|
||||
converter.set<clip_poly_tag>();
|
||||
else if (type == LineString)
|
||||
converter.set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
BOOST_FOREACH(geometry_type & geom, feature.paths())
|
||||
{
|
||||
converter.apply(geom);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clipped_geometry_type clipped(geom);
|
||||
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
|
||||
path_type path(t_,clipped,prj_trans);
|
||||
markers_placement<path_type, label_collision_detector4> placement(path, extent, recenter * tr, detector_,
|
||||
sym.get_spacing() * scale_factor_,
|
||||
sym.get_max_error(),
|
||||
sym.get_allow_overlap());
|
||||
double x, y, angle;
|
||||
while (placement.get_point(x, y, angle))
|
||||
svg_attributes_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
|
||||
dispatch_type dispatch(context, **stock_vector_marker, result?attributes:(*stock_vector_marker)->attributes(),
|
||||
detector_, sym, bbox, tr, scale_factor_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(query_extent_, dispatch, sym, t_, prj_trans, tr, scale_factor_);
|
||||
|
||||
if (sym.clip() && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
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, 1,false);
|
||||
eGeomType type = feature.paths()[0].type();
|
||||
if (type == Polygon)
|
||||
converter.set<clip_poly_tag>();
|
||||
else if (type == LineString)
|
||||
converter.set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
BOOST_FOREACH(geometry_type & geom, feature.paths())
|
||||
{
|
||||
converter.apply(geom);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
typedef detail::markers_dispatch_2<cairo_context,
|
||||
mapnik::image_ptr,
|
||||
label_collision_detector4> dispatch_type;
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
if ( marker )
|
||||
{
|
||||
dispatch_type dispatch(context, *marker,
|
||||
detector_, sym, bbox, tr, scale_factor_);
|
||||
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(query_extent_, dispatch, sym, t_, prj_trans, tr, scale_factor_);
|
||||
|
||||
if (sym.clip() && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
eGeomType type = feature.paths()[0].type();
|
||||
if (type == Polygon)
|
||||
converter.set<clip_poly_tag>();
|
||||
else if (type == LineString)
|
||||
converter.set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
BOOST_FOREACH(geometry_type & geom, feature.paths())
|
||||
{
|
||||
converter.apply(geom);
|
||||
}
|
||||
}
|
||||
context.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,14 +224,14 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
|
|||
else
|
||||
{
|
||||
std::ostringstream s_err;
|
||||
s_err << "failed to parse 'maximum-extent'";
|
||||
s_err << "failed to parse Map maximum-extent '" << *maximum_extent << "'";
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(s_err.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_WARN(load_map) << "map_parser: " << s_err.str();
|
||||
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -649,14 +649,14 @@ void map_parser::parse_layer(Map & map, xml_node const& node)
|
|||
else
|
||||
{
|
||||
std::ostringstream s_err;
|
||||
s_err << "failed to parse 'maximum-extent' in layer " << name;
|
||||
s_err << "failed to parse Layer maximum-extent '" << *maximum_extent << "' for '" << name << "'";
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(s_err.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_WARN(load_map) << "map_parser: " << s_err.str();
|
||||
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -872,11 +872,9 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
|
|||
if (!mapnik::parse_transform(*tl, *geometry_transform_wkt, pt.get_tree().transform_expr_grammar))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Could not parse transform from '" << geometry_transform_wkt << "', expected transform attribute";
|
||||
if (strict_)
|
||||
throw config_error(ss.str()); // value_error here?
|
||||
else
|
||||
MAPNIK_LOG_WARN(load_map) << "### WARNING: " << ss;
|
||||
ss << "Could not parse transform from '" << *geometry_transform_wkt
|
||||
<< "', expected transform attribute";
|
||||
throw config_error(ss.str());
|
||||
}
|
||||
sym.set_transform(tl);
|
||||
}
|
||||
|
@ -948,17 +946,7 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym)
|
|||
mapnik::transform_list_ptr tl = boost::make_shared<mapnik::transform_list>();
|
||||
if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Could not parse transform from '" << *image_transform_wkt
|
||||
<< "', expected transform attribute";
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(ss.str()); // value_error here?
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss;
|
||||
}
|
||||
throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'");
|
||||
}
|
||||
symbol.set_image_transform(tl);
|
||||
}
|
||||
|
@ -983,8 +971,6 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
|
|||
optional<std::string> base = node.get_opt_attr<std::string>("base");
|
||||
|
||||
if (file && !file->empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (base)
|
||||
{
|
||||
|
@ -997,19 +983,6 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
|
|||
|
||||
filename = ensure_relative_to_xml(file);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::string msg("Failed to load marker file '" + *file + "'!");
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_WARN(load_map) << "map_parser: " << msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
optional<std::string> marker_type = node.get_opt_attr<std::string>("marker-type");
|
||||
if (marker_type)
|
||||
|
@ -1055,17 +1028,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& node)
|
|||
mapnik::transform_list_ptr tl = boost::make_shared<mapnik::transform_list>();
|
||||
if (!mapnik::parse_transform(*tl, *image_transform_wkt, node.get_tree().transform_expr_grammar))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Could not parse transform from '" << *image_transform_wkt
|
||||
<< "', expected transform attribute";
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(ss.str()); // value_error here?
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss;
|
||||
}
|
||||
throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'");
|
||||
}
|
||||
sym.set_image_transform(tl);
|
||||
}
|
||||
|
@ -1257,17 +1220,7 @@ void map_parser::parse_shield_symbolizer(rule & rule, xml_node const& sym)
|
|||
mapnik::transform_list_ptr tl = boost::make_shared<mapnik::transform_list>();
|
||||
if (!mapnik::parse_transform(*tl, *image_transform_wkt, sym.get_tree().transform_expr_grammar))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Could not parse transform from '" << *image_transform_wkt
|
||||
<< "', expected transform attribute";
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(ss.str()); // value_error here?
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_WARN(load_map) << "map_parser: " << ss;
|
||||
}
|
||||
throw mapnik::config_error("Failed to parse transform: '" + *image_transform_wkt + "'");
|
||||
}
|
||||
shield_symbol.set_image_transform(tl);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,51 @@ def setup():
|
|||
# from another directory we need to chdir()
|
||||
os.chdir(execution_path('.'))
|
||||
|
||||
def show_grids(name,g1,g2):
|
||||
g1_file = '/tmp/mapnik-%s-actual.json' % name
|
||||
open(g1_file,'w').write(json.dumps(g1,sort_keys=True))
|
||||
g2_file = '/tmp/mapnik-%s-expected.json' % name
|
||||
open(g2_file,'w').write(json.dumps(g2,sort_keys=True))
|
||||
val = 'JSON does not match ->\n'
|
||||
if g1['grid'] != g2['grid']:
|
||||
val += ' X grid does not match\n'
|
||||
else:
|
||||
val += ' ✓ grid matches\n'
|
||||
if g1['data'].keys() != g2['data'].keys():
|
||||
val += ' X data does not match\n'
|
||||
else:
|
||||
val += ' ✓ data matches\n'
|
||||
if g1['keys'] != g2['keys']:
|
||||
val += ' X keys do not\n'
|
||||
else:
|
||||
val += ' ✓ keys match\n'
|
||||
val += '\n\t%s\n\t%s' % (g1_file,g2_file)
|
||||
return val
|
||||
|
||||
def show_grids2(name,g1,g2):
|
||||
g2_expected = '../data/grids/mapnik-%s-actual.json' % name
|
||||
if not os.path.exists(g2_expected):
|
||||
# create test fixture based on actual results
|
||||
open(g2_expected,'a+').write(json.dumps(g1,sort_keys=True))
|
||||
return
|
||||
g1_file = '/tmp/mapnik-%s-actual.json' % name
|
||||
open(g1_file,'w').write(json.dumps(g1,sort_keys=True))
|
||||
val = 'JSON does not match ->\n'
|
||||
if g1['grid'] != g2['grid']:
|
||||
val += ' X grid does not match\n'
|
||||
else:
|
||||
val += ' ✓ grid matches\n'
|
||||
if g1['data'].keys() != g2['data'].keys():
|
||||
val += ' X data does not match\n'
|
||||
else:
|
||||
val += ' ✓ data matches\n'
|
||||
if g1['keys'] != g2['keys']:
|
||||
val += ' X keys do not\n'
|
||||
else:
|
||||
val += ' ✓ keys match\n'
|
||||
val += '\n\t%s\n\t%s' % (g1_file,g2_expected)
|
||||
return val
|
||||
|
||||
# first pass impl where resolution is passed as render
|
||||
# time rather than encoding time, likely will be deprecated soon
|
||||
grid_correct_old = {"keys": ["", "North West", "North East", "South West", "South East"], "data": {"South East": {"Name": "South East"}, "North East": {"Name": "North East"}, "North West": {"Name": "North West"}, "South West": {"Name": "South West"}}, "grid": [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " !!! ### ", " !!!!! ##### ", " !!!!! ##### ", " !!! ### ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " $$$$ %%%% ", " $$$$$ %%%%% ", " $$$$$ %%%%% ", " $$$ %%% ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "]}
|
||||
|
@ -44,7 +89,7 @@ def resolve(grid,row,col):
|
|||
return grid['data'].get(key)
|
||||
|
||||
|
||||
def create_grid_map(width,height,marker=True):
|
||||
def create_grid_map(width,height,sym):
|
||||
ds = mapnik.MemoryDatasource()
|
||||
context = mapnik.Context()
|
||||
context.push('Name')
|
||||
|
@ -69,15 +114,8 @@ def create_grid_map(width,height,marker=True):
|
|||
ds.add_feature(f)
|
||||
s = mapnik.Style()
|
||||
r = mapnik.Rule()
|
||||
if marker:
|
||||
symb = mapnik.MarkersSymbolizer()
|
||||
symb.width = mapnik.Expression('10')
|
||||
symb.height = mapnik.Expression('10')
|
||||
else:
|
||||
symb = mapnik.PointSymbolizer(mapnik.PathExpression('../data/images/dummy.png'))
|
||||
symb.allow_overlap = True
|
||||
r.symbols.append(symb)
|
||||
|
||||
sym.allow_overlap = True
|
||||
r.symbols.append(sym)
|
||||
s.rules.append(r)
|
||||
lyr = mapnik.Layer('Places')
|
||||
lyr.datasource = ds
|
||||
|
@ -87,31 +125,14 @@ def create_grid_map(width,height,marker=True):
|
|||
m.layers.append(lyr)
|
||||
return m
|
||||
|
||||
def show_grids(name,g1,g2):
|
||||
g1_file = '/tmp/mapnik-%s-actual.json' % name
|
||||
open(g1_file,'w').write(json.dumps(g1,sort_keys=True))
|
||||
g2_file = '/tmp/mapnik-%s-expected.json' % name
|
||||
open(g2_file,'w').write(json.dumps(g2,sort_keys=True))
|
||||
val = 'JSON does not match ->\n'
|
||||
if g1['grid'] != g2['grid']:
|
||||
val += ' X grid does not match\n'
|
||||
else:
|
||||
val += ' ✓ grid matches\n'
|
||||
if g1['data'].keys() != g2['data'].keys():
|
||||
val += ' X data does not match\n'
|
||||
else:
|
||||
val += ' ✓ data matches\n'
|
||||
if g1['keys'] != g2['keys']:
|
||||
val += ' X keys do not\n'
|
||||
else:
|
||||
val += ' ✓ keys match\n'
|
||||
val += '\n\t%s\n\t%s' % (g1_file,g2_file)
|
||||
return val
|
||||
|
||||
def test_render_grid_old():
|
||||
""" test old method """
|
||||
width,height = 256,256
|
||||
m = create_grid_map(width,height)
|
||||
symb = mapnik.PointSymbolizer(mapnik.PathExpression('../data/images/dummy.png'))
|
||||
sym = mapnik.MarkersSymbolizer()
|
||||
sym.width = mapnik.Expression('10')
|
||||
sym.height = mapnik.Expression('10')
|
||||
m = create_grid_map(width,height,sym)
|
||||
#print mapnik.save_map_to_string(m)
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
|
@ -131,7 +152,10 @@ def test_render_grid_old():
|
|||
def test_render_grid_new():
|
||||
""" test old against new"""
|
||||
width,height = 256,256
|
||||
m = create_grid_map(width,height)
|
||||
sym = mapnik.MarkersSymbolizer()
|
||||
sym.width = mapnik.Expression('10')
|
||||
sym.height = mapnik.Expression('10')
|
||||
m = create_grid_map(width,height,sym)
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat))
|
||||
|
@ -169,7 +193,10 @@ grid_feat_id2 = {"data": {"1": {"Name": "South East"}, "2": {"Name": "South West
|
|||
def test_render_grid3():
|
||||
""" test using feature id"""
|
||||
width,height = 256,256
|
||||
m = create_grid_map(width,height)
|
||||
sym = mapnik.MarkersSymbolizer()
|
||||
sym.width = mapnik.Expression('10')
|
||||
sym.height = mapnik.Expression('10')
|
||||
m = create_grid_map(width,height,sym)
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat))
|
||||
|
@ -280,22 +307,19 @@ def test_line_rendering():
|
|||
mapnik.render_layer(m,grid,layer=0,fields=['__id__','Name'])
|
||||
utf1 = grid.encode()
|
||||
eq_(utf1,line_expected,show_grids('line',utf1,line_expected))
|
||||
#open('test.json','w').write(json.dumps(grid.encode()))
|
||||
|
||||
point_expected = {"data": {"1": {"Name": "South East"}, "2": {"Name": "South West"}, "3": {"Name": "North West"}, "4": {"Name": "North East"}}, "grid": [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " !!!! #### ", " !!!! #### ", " !!!! #### ", " !!!! #### ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " $$$$ %%%% ", " $$$$ %%%% ", " $$$$ %%%% ", " $$$$ %%%% ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "], "keys": ["", "3", "4", "2", "1"]}
|
||||
|
||||
def test_point_symbolizer_grid():
|
||||
width,height = 256,256
|
||||
m = create_grid_map(width,height,marker=False)
|
||||
sym = mapnik.PointSymbolizer(mapnik.PathExpression('../data/images/dummy.png'))
|
||||
m = create_grid_map(width,height,sym)
|
||||
ul_lonlat = mapnik.Coord(142.30,-38.20)
|
||||
lr_lonlat = mapnik.Coord(143.40,-38.80)
|
||||
m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat))
|
||||
#mapnik.render_to_file(m,'test.png')
|
||||
#print mapnik.save_map_to_string(m)
|
||||
grid = mapnik.Grid(m.width,m.height)
|
||||
mapnik.render_layer(m,grid,layer=0,fields=['Name'])
|
||||
utf1 = grid.encode()
|
||||
#open('test.json','w').write(json.dumps(grid.encode()))
|
||||
eq_(utf1,point_expected,show_grids('point-sym',utf1,point_expected))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue