2006-03-31 12:32:02 +02:00
|
|
|
/*****************************************************************************
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
*
|
2006-03-31 12:32:02 +02:00
|
|
|
* This file is part of Mapnik (c++ mapping toolkit)
|
|
|
|
*
|
2006-02-07 15:41:41 +01:00
|
|
|
* Copyright (C) 2006 Artem Pavlenko
|
|
|
|
*
|
2006-03-31 12:32:02 +02:00
|
|
|
* 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.
|
2006-02-07 15:41:41 +01:00
|
|
|
*
|
2006-03-31 12:32:02 +02:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
2006-02-07 15:41:41 +01:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2006-03-31 12:32:02 +02:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2006-02-07 15:41:41 +01:00
|
|
|
*
|
2006-03-31 12:32:02 +02:00
|
|
|
* 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
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
2006-02-07 15:41:41 +01:00
|
|
|
//$Id$
|
|
|
|
|
2007-10-08 19:42:41 +02:00
|
|
|
// mapnik
|
|
|
|
#include <mapnik/agg_renderer.hpp>
|
|
|
|
#include <mapnik/image_util.hpp>
|
2009-12-16 21:02:06 +01:00
|
|
|
#include <mapnik/image_cache.hpp>
|
2010-05-27 13:41:02 +02:00
|
|
|
#include <mapnik/svg/marker_cache.hpp>
|
2007-10-08 19:42:41 +02:00
|
|
|
#include <mapnik/unicode.hpp>
|
|
|
|
#include <mapnik/placement_finder.hpp>
|
2010-05-30 05:16:51 +02:00
|
|
|
#include <mapnik/markers_placement.hpp>
|
2007-11-02 13:50:15 +01:00
|
|
|
#include <mapnik/arrow.hpp>
|
2008-01-23 22:56:04 +01:00
|
|
|
#include <mapnik/config_error.hpp>
|
2008-06-29 12:58:48 +02:00
|
|
|
#include <mapnik/font_set.hpp>
|
2009-12-16 21:02:06 +01:00
|
|
|
#include <mapnik/path_expression_grammar.hpp>
|
2010-05-27 12:20:03 +02:00
|
|
|
#include <mapnik/text_path.hpp>
|
2007-10-08 19:42:41 +02:00
|
|
|
|
2006-10-04 13:22:18 +02:00
|
|
|
// agg
|
2008-06-29 12:58:29 +02:00
|
|
|
#define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
|
2008-02-05 14:58:47 +01:00
|
|
|
#include "agg_rendering_buffer.h"
|
|
|
|
#include "agg_pixfmt_rgba.h"
|
|
|
|
#include "agg_rasterizer_scanline_aa.h"
|
2006-02-07 15:41:41 +01:00
|
|
|
#include "agg_basics.h"
|
|
|
|
#include "agg_scanline_p.h"
|
|
|
|
#include "agg_scanline_u.h"
|
|
|
|
#include "agg_renderer_scanline.h"
|
|
|
|
#include "agg_path_storage.h"
|
|
|
|
#include "agg_span_allocator.h"
|
|
|
|
#include "agg_span_pattern_rgba.h"
|
|
|
|
#include "agg_image_accessors.h"
|
|
|
|
#include "agg_conv_stroke.h"
|
|
|
|
#include "agg_conv_dash.h"
|
|
|
|
#include "agg_conv_contour.h"
|
2007-11-02 13:50:15 +01:00
|
|
|
#include "agg_conv_clip_polyline.h"
|
2006-02-07 15:41:41 +01:00
|
|
|
#include "agg_vcgen_stroke.h"
|
|
|
|
#include "agg_conv_adaptor_vcgen.h"
|
|
|
|
#include "agg_conv_smooth_poly1.h"
|
|
|
|
#include "agg_conv_marker.h"
|
|
|
|
#include "agg_vcgen_markers_term.h"
|
|
|
|
#include "agg_renderer_outline_aa.h"
|
|
|
|
#include "agg_rasterizer_outline_aa.h"
|
|
|
|
#include "agg_rasterizer_outline.h"
|
|
|
|
#include "agg_renderer_outline_image.h"
|
|
|
|
#include "agg_span_allocator.h"
|
|
|
|
#include "agg_span_pattern_rgba.h"
|
|
|
|
#include "agg_renderer_scanline.h"
|
|
|
|
#include "agg_pattern_filters_rgba.h"
|
|
|
|
#include "agg_renderer_outline_image.h"
|
2007-10-05 13:27:00 +02:00
|
|
|
#include "agg_vpgen_clip_polyline.h"
|
2007-11-02 13:50:15 +01:00
|
|
|
#include "agg_arrowhead.h"
|
2007-10-05 13:27:00 +02:00
|
|
|
|
2007-10-08 19:42:41 +02:00
|
|
|
// boost
|
|
|
|
#include <boost/utility.hpp>
|
|
|
|
#include <boost/tuple/tuple.hpp>
|
|
|
|
|
|
|
|
// stl
|
2008-02-05 14:58:47 +01:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2007-10-08 19:42:41 +02:00
|
|
|
#include <iostream>
|
2008-02-05 14:58:47 +01:00
|
|
|
#endif
|
2006-10-17 16:12:53 +02:00
|
|
|
|
2010-03-12 00:19:12 +01:00
|
|
|
#include <cmath>
|
|
|
|
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
namespace mapnik
|
2006-02-07 15:41:41 +01:00
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
class pattern_source : private boost::noncopyable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
pattern_source(image_data_32 const& pattern)
|
|
|
|
: pattern_(pattern) {}
|
|
|
|
|
|
|
|
unsigned int width() const
|
|
|
|
{
|
|
|
|
return pattern_.width();
|
|
|
|
}
|
|
|
|
unsigned int height() const
|
|
|
|
{
|
|
|
|
return pattern_.height();
|
|
|
|
}
|
|
|
|
agg::rgba8 pixel(int x, int y) const
|
|
|
|
{
|
|
|
|
unsigned c = pattern_(x,y);
|
|
|
|
return agg::rgba8(c & 0xff,
|
|
|
|
(c >> 8) & 0xff,
|
|
|
|
(c >> 16) & 0xff,
|
|
|
|
(c >> 24) & 0xff);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
image_data_32 const& pattern_;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rasterizer : agg::rasterizer_scanline_aa<>, boost::noncopyable {};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, unsigned offset_x, unsigned offset_y)
|
|
|
|
: feature_style_processor<agg_renderer>(m),
|
|
|
|
pixmap_(pixmap),
|
|
|
|
width_(pixmap_.width()),
|
|
|
|
height_(pixmap_.height()),
|
|
|
|
t_(m.getWidth(),m.getHeight(),m.getCurrentExtent(),offset_x,offset_y),
|
|
|
|
font_engine_(),
|
|
|
|
font_manager_(font_engine_),
|
|
|
|
detector_(box2d<double>(-m.buffer_size(), -m.buffer_size(), m.getWidth() + m.buffer_size() ,m.getHeight() + m.buffer_size())),
|
|
|
|
ras_ptr(new rasterizer)
|
|
|
|
{
|
|
|
|
boost::optional<color> bg = m.background();
|
|
|
|
if (bg) pixmap_.set_background(*bg);
|
2006-11-19 18:13:33 +01:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2009-12-16 21:02:06 +01:00
|
|
|
std::clog << "scale=" << m.scale() << "\n";
|
2006-11-19 18:13:33 +01:00
|
|
|
#endif
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template <typename T>
|
|
|
|
agg_renderer<T>::~agg_renderer() {}
|
2008-02-05 14:58:47 +01:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::start_map_processing(Map const& map)
|
|
|
|
{
|
2006-11-19 18:13:33 +01:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2009-12-16 21:02:06 +01:00
|
|
|
std::clog << "start map processing bbox="
|
|
|
|
<< map.getCurrentExtent() << "\n";
|
2006-11-19 18:13:33 +01:00
|
|
|
#endif
|
2009-12-16 21:02:06 +01:00
|
|
|
ras_ptr->clip_box(0,0,width_,height_);
|
|
|
|
}
|
2006-02-21 20:55:24 +01:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::end_map_processing(Map const& )
|
|
|
|
{
|
2006-11-19 18:13:33 +01:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2009-12-16 21:02:06 +01:00
|
|
|
std::clog << "end map processing\n";
|
2006-11-19 18:13:33 +01:00
|
|
|
#endif
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::start_layer_processing(layer const& lay)
|
|
|
|
{
|
2006-11-19 18:13:33 +01:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2009-12-16 21:02:06 +01:00
|
|
|
std::clog << "start layer processing : " << lay.name() << "\n";
|
|
|
|
std::clog << "datasource = " << lay.datasource().get() << "\n";
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
#endif
|
2009-12-16 21:02:06 +01:00
|
|
|
if (lay.clear_label_cache())
|
|
|
|
{
|
|
|
|
detector_.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::end_layer_processing(layer const&)
|
|
|
|
{
|
2006-11-19 18:13:33 +01:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2009-12-16 21:02:06 +01:00
|
|
|
std::clog << "end layer processing\n";
|
2006-11-19 18:13:33 +01:00
|
|
|
#endif
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(polygon_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
|
|
|
|
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
|
|
|
|
|
|
|
color const& fill_ = sym.get_fill();
|
|
|
|
agg::scanline_u8 sl;
|
|
|
|
|
|
|
|
agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
|
|
|
|
agg::pixfmt_rgba32_plain pixf(buf);
|
|
|
|
|
|
|
|
ren_base renb(pixf);
|
|
|
|
unsigned r=fill_.red();
|
|
|
|
unsigned g=fill_.green();
|
|
|
|
unsigned b=fill_.blue();
|
|
|
|
unsigned a=fill_.alpha();
|
|
|
|
renderer ren(renb);
|
|
|
|
|
|
|
|
ras_ptr->reset();
|
2010-01-13 01:31:45 +01:00
|
|
|
ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma()));
|
2009-12-16 21:02:06 +01:00
|
|
|
|
|
|
|
for (unsigned i=0;i<feature.num_geometries();++i)
|
|
|
|
{
|
|
|
|
geometry2d const& geom=feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 2)
|
|
|
|
{
|
2007-11-02 13:50:15 +01:00
|
|
|
path_type path(t_,geom,prj_trans);
|
2008-02-05 14:58:47 +01:00
|
|
|
ras_ptr->add_path(path);
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
|
|
|
|
agg::render_scanlines(*ras_ptr, sl, ren);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef boost::tuple<double,double,double,double> segment_t;
|
|
|
|
bool y_order(segment_t const& first,segment_t const& second)
|
|
|
|
{
|
|
|
|
double miny0 = std::min(first.get<1>(),first.get<3>());
|
|
|
|
double miny1 = std::min(second.get<1>(),second.get<3>());
|
|
|
|
return miny0 > miny1;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(building_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
typedef coord_transform3<CoordTransform,geometry2d> path_type_roof;
|
|
|
|
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
|
|
|
|
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
|
|
|
|
|
|
|
agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
|
|
|
|
agg::pixfmt_rgba32_plain pixf(buf);
|
|
|
|
ren_base renb(pixf);
|
|
|
|
|
|
|
|
color const& fill_ = sym.get_fill();
|
|
|
|
unsigned r=fill_.red();
|
|
|
|
unsigned g=fill_.green();
|
|
|
|
unsigned b=fill_.blue();
|
|
|
|
unsigned a=fill_.alpha();
|
|
|
|
renderer ren(renb);
|
|
|
|
agg::scanline_u8 sl;
|
|
|
|
|
|
|
|
ras_ptr->reset();
|
2010-02-09 18:28:17 +01:00
|
|
|
ras_ptr->gamma(agg::gamma_linear());
|
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
double height = 0.7071 * sym.height(); // height in meters
|
|
|
|
|
|
|
|
for (unsigned i=0;i<feature.num_geometries();++i)
|
|
|
|
{
|
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 2)
|
|
|
|
{
|
2007-09-16 13:23:51 +02:00
|
|
|
boost::scoped_ptr<geometry2d> frame(new line_string_impl);
|
|
|
|
boost::scoped_ptr<geometry2d> roof(new polygon_impl);
|
|
|
|
std::deque<segment_t> face_segments;
|
2007-09-25 20:47:12 +02:00
|
|
|
double x0(0);
|
|
|
|
double y0(0);
|
2007-10-05 13:27:00 +02:00
|
|
|
unsigned cm = geom.vertex(&x0,&y0);
|
|
|
|
for (unsigned j=1;j<geom.num_points();++j)
|
2007-09-16 13:23:51 +02:00
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
double x,y;
|
|
|
|
cm = geom.vertex(&x,&y);
|
|
|
|
if (cm == SEG_MOVETO)
|
|
|
|
{
|
|
|
|
frame->move_to(x,y);
|
|
|
|
}
|
|
|
|
else if (cm == SEG_LINETO)
|
|
|
|
{
|
|
|
|
frame->line_to(x,y);
|
|
|
|
face_segments.push_back(segment_t(x0,y0,x,y));
|
|
|
|
}
|
2010-05-27 12:20:03 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
x0 = x;
|
|
|
|
y0 = y;
|
2007-09-16 13:23:51 +02:00
|
|
|
}
|
|
|
|
std::sort(face_segments.begin(),face_segments.end(), y_order);
|
|
|
|
std::deque<segment_t>::const_iterator itr=face_segments.begin();
|
|
|
|
for (;itr!=face_segments.end();++itr)
|
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
boost::scoped_ptr<geometry2d> faces(new polygon_impl);
|
|
|
|
faces->move_to(itr->get<0>(),itr->get<1>());
|
|
|
|
faces->line_to(itr->get<2>(),itr->get<3>());
|
|
|
|
faces->line_to(itr->get<2>(),itr->get<3>() + height);
|
|
|
|
faces->line_to(itr->get<0>(),itr->get<1>() + height);
|
|
|
|
|
|
|
|
path_type faces_path (t_,*faces,prj_trans);
|
|
|
|
ras_ptr->add_path(faces_path);
|
|
|
|
ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(a * sym.get_opacity())));
|
|
|
|
agg::render_scanlines(*ras_ptr, sl, ren);
|
|
|
|
ras_ptr->reset();
|
|
|
|
|
|
|
|
frame->move_to(itr->get<0>(),itr->get<1>());
|
|
|
|
frame->line_to(itr->get<0>(),itr->get<1>()+height);
|
2007-09-16 13:23:51 +02:00
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2007-09-16 13:23:51 +02:00
|
|
|
geom.rewind(0);
|
|
|
|
for (unsigned j=0;j<geom.num_points();++j)
|
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
double x,y;
|
|
|
|
unsigned cm = geom.vertex(&x,&y);
|
|
|
|
if (cm == SEG_MOVETO)
|
|
|
|
{
|
|
|
|
frame->move_to(x,y+height);
|
|
|
|
roof->move_to(x,y+height);
|
|
|
|
}
|
|
|
|
else if (cm == SEG_LINETO)
|
|
|
|
{
|
|
|
|
frame->line_to(x,y+height);
|
|
|
|
roof->line_to(x,y+height);
|
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
}
|
|
|
|
path_type path(t_,*frame,prj_trans);
|
2007-09-16 13:23:51 +02:00
|
|
|
agg::conv_stroke<path_type> stroke(path);
|
2008-02-05 14:58:47 +01:00
|
|
|
ras_ptr->add_path(stroke);
|
2010-05-27 12:20:03 +02:00
|
|
|
ren.color(agg::rgba8(r * 0.8, g * 0.8 , b * 0.8, int(255 * sym.get_opacity())));
|
2008-02-05 14:58:47 +01:00
|
|
|
agg::render_scanlines(*ras_ptr, sl, ren);
|
|
|
|
ras_ptr->reset();
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2007-09-16 13:23:51 +02:00
|
|
|
path_type roof_path (t_,*roof,prj_trans);
|
2008-02-05 14:58:47 +01:00
|
|
|
ras_ptr->add_path(roof_path);
|
2009-02-07 15:09:23 +01:00
|
|
|
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
|
2008-02-05 14:58:47 +01:00
|
|
|
agg::render_scanlines(*ras_ptr, sl, ren);
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-02-10 18:13:02 +01:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(line_symbolizer const& sym,
|
2008-02-05 14:58:47 +01:00
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
2009-12-16 21:02:06 +01:00
|
|
|
{
|
|
|
|
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
|
|
|
|
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
|
|
|
|
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
|
|
|
|
|
|
|
agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
|
|
|
|
agg::pixfmt_rgba32_plain pixf(buf);
|
|
|
|
|
|
|
|
ren_base renb(pixf);
|
|
|
|
mapnik::stroke const& stroke_ = sym.get_stroke();
|
|
|
|
color const& col = stroke_.get_color();
|
|
|
|
unsigned r=col.red();
|
|
|
|
unsigned g=col.green();
|
|
|
|
unsigned b=col.blue();
|
|
|
|
unsigned a=col.alpha();
|
|
|
|
renderer ren(renb);
|
|
|
|
ras_ptr->reset();
|
2010-02-09 18:28:17 +01:00
|
|
|
ras_ptr->gamma(agg::gamma_linear());
|
2010-04-09 20:46:25 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
agg::scanline_p8 sl;
|
|
|
|
|
|
|
|
for (unsigned i=0;i<feature.num_geometries();++i)
|
|
|
|
{
|
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 1)
|
|
|
|
{
|
2007-09-16 13:23:51 +02:00
|
|
|
path_type path(t_,geom,prj_trans);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2007-09-16 13:23:51 +02:00
|
|
|
if (stroke_.has_dash())
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
agg::conv_dash<path_type> dash(path);
|
|
|
|
dash_array const& d = stroke_.get_dash_array();
|
|
|
|
dash_array::const_iterator itr = d.begin();
|
|
|
|
dash_array::const_iterator end = d.end();
|
|
|
|
for (;itr != end;++itr)
|
|
|
|
{
|
|
|
|
dash.add_dash(itr->first, itr->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
|
|
|
|
|
|
|
|
line_join_e join=stroke_.get_line_join();
|
|
|
|
if ( join == MITER_JOIN)
|
|
|
|
stroke.generator().line_join(agg::miter_join);
|
|
|
|
else if( join == MITER_REVERT_JOIN)
|
|
|
|
stroke.generator().line_join(agg::miter_join);
|
|
|
|
else if( join == ROUND_JOIN)
|
|
|
|
stroke.generator().line_join(agg::round_join);
|
|
|
|
else
|
|
|
|
stroke.generator().line_join(agg::bevel_join);
|
|
|
|
|
|
|
|
line_cap_e cap=stroke_.get_line_cap();
|
|
|
|
if (cap == BUTT_CAP)
|
|
|
|
stroke.generator().line_cap(agg::butt_cap);
|
|
|
|
else if (cap == SQUARE_CAP)
|
|
|
|
stroke.generator().line_cap(agg::square_cap);
|
|
|
|
else
|
|
|
|
stroke.generator().line_cap(agg::round_cap);
|
|
|
|
|
|
|
|
stroke.generator().miter_limit(4.0);
|
|
|
|
stroke.generator().width(stroke_.get_width());
|
2010-04-09 20:46:25 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
ras_ptr->add_path(stroke);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2007-09-16 13:23:51 +02:00
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
else
|
2007-09-16 13:23:51 +02:00
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
agg::conv_stroke<path_type> stroke(path);
|
|
|
|
line_join_e join=stroke_.get_line_join();
|
|
|
|
if ( join == MITER_JOIN)
|
|
|
|
stroke.generator().line_join(agg::miter_join);
|
|
|
|
else if( join == MITER_REVERT_JOIN)
|
|
|
|
stroke.generator().line_join(agg::miter_join);
|
|
|
|
else if( join == ROUND_JOIN)
|
|
|
|
stroke.generator().line_join(agg::round_join);
|
|
|
|
else
|
|
|
|
stroke.generator().line_join(agg::bevel_join);
|
|
|
|
|
|
|
|
line_cap_e cap=stroke_.get_line_cap();
|
|
|
|
if (cap == BUTT_CAP)
|
|
|
|
stroke.generator().line_cap(agg::butt_cap);
|
|
|
|
else if (cap == SQUARE_CAP)
|
|
|
|
stroke.generator().line_cap(agg::square_cap);
|
|
|
|
else
|
|
|
|
stroke.generator().line_cap(agg::round_cap);
|
|
|
|
|
|
|
|
stroke.generator().miter_limit(4.0);
|
|
|
|
stroke.generator().width(stroke_.get_width());
|
|
|
|
ras_ptr->add_path(stroke);
|
2007-09-16 13:23:51 +02:00
|
|
|
}
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
|
|
|
|
agg::render_scanlines(*ras_ptr, sl, ren);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(point_symbolizer const& sym,
|
2008-02-05 14:58:47 +01:00
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
2009-12-16 21:02:06 +01:00
|
|
|
{
|
|
|
|
double x;
|
|
|
|
double y;
|
|
|
|
double z=0;
|
|
|
|
|
|
|
|
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
|
2010-03-03 04:26:12 +01:00
|
|
|
boost::optional<mapnik::image_ptr> data;
|
2009-12-16 21:02:06 +01:00
|
|
|
|
2010-03-03 04:26:12 +01:00
|
|
|
if ( filename.empty() )
|
|
|
|
{
|
2010-05-27 13:18:53 +02:00
|
|
|
// default OGC 4x4 black square
|
2010-03-03 04:26:12 +01:00
|
|
|
data = boost::optional<mapnik::image_ptr>(new image_data_32(4,4));
|
|
|
|
(*data)->set(0xff000000);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data = mapnik::image_cache::instance()->find(filename,true);
|
|
|
|
}
|
2010-05-27 13:18:53 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
if ( data )
|
|
|
|
{
|
|
|
|
for (unsigned i=0;i<feature.num_geometries();++i)
|
|
|
|
{
|
2007-09-16 13:23:51 +02:00
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2007-09-16 13:23:51 +02:00
|
|
|
geom.label_position(&x,&y);
|
2007-02-06 15:27:21 +01:00
|
|
|
prj_trans.backward(x,y,z);
|
|
|
|
t_.forward(&x,&y);
|
2009-12-16 21:02:06 +01:00
|
|
|
int w = (*data)->width();
|
|
|
|
int h = (*data)->height();
|
2007-02-06 15:27:21 +01:00
|
|
|
int px=int(floor(x - 0.5 * w));
|
|
|
|
int py=int(floor(y - 0.5 * h));
|
2009-12-16 21:02:06 +01:00
|
|
|
box2d<double> label_ext (floor(x - 0.5 * w),
|
|
|
|
floor(y - 0.5 * h),
|
|
|
|
ceil (x + 0.5 * w),
|
|
|
|
ceil (y + 0.5 * h));
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
if (sym.get_allow_overlap() ||
|
2007-05-12 13:34:55 +02:00
|
|
|
detector_.has_placement(label_ext))
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
pixmap_.set_rectangle_alpha2(*(*data),px,py,sym.get_opacity());
|
|
|
|
detector_.insert(label_ext);
|
2006-05-23 18:52:10 +02:00
|
|
|
}
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(shield_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
|
|
|
|
UnicodeString text;
|
|
|
|
if( sym.get_no_text() )
|
|
|
|
text = UnicodeString( " " ); // TODO: fix->use 'space' as the text to render
|
|
|
|
else
|
|
|
|
{
|
|
|
|
expression_ptr name_expr = sym.get_name();
|
|
|
|
if (!name_expr) return;
|
|
|
|
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*name_expr);
|
|
|
|
text = result.to_unicode();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( sym.get_text_convert() == TOUPPER)
|
|
|
|
{
|
|
|
|
text = text.toUpper();
|
|
|
|
}
|
|
|
|
else if ( sym.get_text_convert() == TOLOWER)
|
|
|
|
{
|
|
|
|
text = text.toLower();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
|
|
|
|
boost::optional<mapnik::image_ptr> data = mapnik::image_cache::instance()->find(filename,true);
|
|
|
|
|
|
|
|
if (text.length() > 0 && data)
|
|
|
|
{
|
|
|
|
face_set_ptr faces;
|
|
|
|
|
|
|
|
if (sym.get_fontset().size() > 0)
|
|
|
|
{
|
2008-07-25 02:23:33 +02:00
|
|
|
faces = font_manager_.get_face_set(sym.get_fontset());
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-07-25 02:23:33 +02:00
|
|
|
faces = font_manager_.get_face_set(sym.get_face_name());
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
2008-07-25 02:23:33 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
if (faces->size() > 0)
|
|
|
|
{
|
2009-03-31 11:23:23 +02:00
|
|
|
text_renderer<T> ren(pixmap_, faces);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-04-12 17:22:27 +02:00
|
|
|
ren.set_pixel_size(sym.get_text_size());
|
|
|
|
ren.set_fill(sym.get_fill());
|
2008-09-15 10:48:21 +02:00
|
|
|
ren.set_halo_fill(sym.get_halo_fill());
|
|
|
|
ren.set_halo_radius(sym.get_halo_radius());
|
|
|
|
|
|
|
|
placement_finder<label_collision_detector4> finder(detector_);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-04-12 17:22:27 +02:00
|
|
|
string_info info(text);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-09-15 10:48:21 +02:00
|
|
|
faces->get_string_info(info);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-09-15 10:48:21 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
int w = (*data)->width();
|
|
|
|
int h = (*data)->height();
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-04-12 17:22:27 +02:00
|
|
|
unsigned num_geom = feature.num_geometries();
|
|
|
|
for (unsigned i=0;i<num_geom;++i)
|
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 0 )
|
|
|
|
{
|
|
|
|
path_type path(t_,geom,prj_trans);
|
|
|
|
|
|
|
|
label_placement_enum how_placed = sym.get_label_placement();
|
|
|
|
if (how_placed == POINT_PLACEMENT || how_placed == VERTEX_PLACEMENT)
|
|
|
|
{
|
|
|
|
// for every vertex, try and place a shield/text
|
|
|
|
geom.rewind(0);
|
|
|
|
for( unsigned jj = 0; jj < geom.num_points(); jj++ )
|
|
|
|
{
|
|
|
|
double label_x;
|
|
|
|
double label_y;
|
|
|
|
double z=0.0;
|
|
|
|
placement text_placement(info, sym, w, h, false);
|
|
|
|
text_placement.avoid_edges = sym.get_avoid_edges();
|
|
|
|
text_placement.allow_overlap = sym.get_allow_overlap();
|
|
|
|
if( how_placed == VERTEX_PLACEMENT )
|
|
|
|
geom.vertex(&label_x,&label_y); // by vertex
|
|
|
|
else
|
|
|
|
geom.label_position(&label_x, &label_y); // by middle of line or by point
|
|
|
|
prj_trans.backward(label_x,label_y, z);
|
|
|
|
t_.forward(&label_x,&label_y);
|
|
|
|
|
2010-05-27 12:20:03 +02:00
|
|
|
finder.find_point_placement( text_placement,label_x,label_y,0.0,sym.get_vertical_alignment(),sym.get_line_spacing(),
|
2009-12-16 21:02:06 +01:00
|
|
|
sym.get_character_spacing(),sym.get_horizontal_alignment(),sym.get_justify_alignment() );
|
|
|
|
|
|
|
|
// check to see if image overlaps anything too, there is only ever 1 placement found for points and verticies
|
|
|
|
if( text_placement.placements.size() > 0)
|
|
|
|
{
|
|
|
|
double x = text_placement.placements[0].starting_x;
|
|
|
|
double y = text_placement.placements[0].starting_y;
|
|
|
|
int px;
|
|
|
|
int py;
|
|
|
|
box2d<double> label_ext;
|
|
|
|
|
|
|
|
if( !sym.get_unlock_image() )
|
|
|
|
{ // center image at text center position
|
|
|
|
// remove displacement from image label
|
|
|
|
position pos = sym.get_displacement();
|
|
|
|
double lx = x - boost::get<0>(pos);
|
|
|
|
double ly = y - boost::get<1>(pos);
|
|
|
|
px=int(floor(lx - (0.5 * w))) ;
|
|
|
|
py=int(floor(ly - (0.5 * h))) ;
|
|
|
|
label_ext.init( floor(lx - 0.5 * w), floor(ly - 0.5 * h), ceil (lx + 0.5 * w), ceil (ly + 0.5 * h) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // center image at reference location
|
|
|
|
px=int(floor(label_x - 0.5 * w));
|
|
|
|
py=int(floor(label_y - 0.5 * h));
|
|
|
|
label_ext.init( floor(label_x - 0.5 * w), floor(label_y - 0.5 * h), ceil (label_x + 0.5 * w), ceil (label_y + 0.5 * h));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) )
|
|
|
|
{
|
|
|
|
//pixmap_.set_rectangle_alpha(px,py,*data);
|
2010-03-12 00:19:12 +01:00
|
|
|
pixmap_.set_rectangle_alpha2(*(*data),px,py,float(sym.get_opacity()));
|
2009-12-16 21:02:06 +01:00
|
|
|
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
|
|
|
|
ren.render(x,y);
|
|
|
|
detector_.insert(label_ext);
|
|
|
|
finder.update_detector(text_placement);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT)
|
|
|
|
{
|
|
|
|
placement text_placement(info, sym, w, h, true);
|
|
|
|
text_placement.avoid_edges = sym.get_avoid_edges();
|
|
|
|
finder.find_point_placements<path_type>(text_placement,path);
|
|
|
|
|
|
|
|
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
|
|
|
|
{
|
|
|
|
int w = (*data)->width();
|
|
|
|
int h = (*data)->height();
|
|
|
|
double x = text_placement.placements[ii].starting_x;
|
|
|
|
double y = text_placement.placements[ii].starting_y;
|
|
|
|
|
|
|
|
int px=int(x - (w/2));
|
|
|
|
int py=int(y - (h/2));
|
|
|
|
|
|
|
|
pixmap_.set_rectangle_alpha(px,py,*(*data));
|
|
|
|
|
|
|
|
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
|
|
|
ren.render(x,y);
|
|
|
|
}
|
|
|
|
finder.update_detector(text_placement);
|
|
|
|
}
|
|
|
|
}
|
2006-10-17 16:12:53 +02:00
|
|
|
}
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
|
2008-02-05 14:58:47 +01:00
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
2009-12-16 21:02:06 +01:00
|
|
|
{
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
|
|
|
|
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base;
|
|
|
|
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
|
|
|
|
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
|
|
|
|
|
|
|
|
agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
|
|
|
|
agg::pixfmt_rgba32_plain pixf(buf);
|
|
|
|
|
|
|
|
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
|
|
|
|
boost::optional<mapnik::image_ptr> pat = mapnik::image_cache::instance()->find(filename,true);
|
|
|
|
|
|
|
|
if (!pat) return;
|
|
|
|
|
|
|
|
renderer_base ren_base(pixf);
|
|
|
|
agg::pattern_filter_bilinear_rgba8 filter;
|
|
|
|
pattern_source source(*(*pat));
|
|
|
|
pattern_type pattern (filter,source);
|
|
|
|
renderer_type ren(ren_base, pattern);
|
|
|
|
ren.clip_box(0,0,width_,height_);
|
|
|
|
rasterizer_type ras(ren);
|
|
|
|
|
|
|
|
for (unsigned i=0;i<feature.num_geometries();++i)
|
|
|
|
{
|
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 1)
|
|
|
|
{
|
2007-09-16 13:23:51 +02:00
|
|
|
path_type path(t_,geom,prj_trans);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
ras.add_path(path);
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
|
|
|
|
typedef agg::wrap_mode_repeat wrap_x_type;
|
|
|
|
typedef agg::wrap_mode_repeat wrap_y_type;
|
|
|
|
typedef agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32,
|
|
|
|
agg::row_accessor<agg::int8u>, agg::pixel32_type> rendering_buffer;
|
|
|
|
typedef agg::image_accessor_wrap<rendering_buffer,
|
|
|
|
wrap_x_type,
|
|
|
|
wrap_y_type> img_source_type;
|
|
|
|
|
|
|
|
typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
|
|
|
|
|
|
|
|
typedef agg::renderer_scanline_aa<ren_base,
|
|
|
|
agg::span_allocator<agg::rgba8>,
|
|
|
|
span_gen_type> renderer_type;
|
|
|
|
|
|
|
|
|
|
|
|
agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
|
|
|
|
agg::pixfmt_rgba32_plain pixf(buf);
|
|
|
|
ren_base renb(pixf);
|
|
|
|
|
|
|
|
agg::scanline_u8 sl;
|
|
|
|
ras_ptr->reset();
|
2010-02-09 18:28:17 +01:00
|
|
|
ras_ptr->gamma(agg::gamma_linear());
|
2009-12-16 21:02:06 +01:00
|
|
|
|
|
|
|
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
|
|
|
|
boost::optional<mapnik::image_ptr> pat = mapnik::image_cache::instance()->find(filename,true);
|
|
|
|
|
|
|
|
if (!pat) return;
|
|
|
|
|
|
|
|
unsigned w=(*pat)->width();
|
|
|
|
unsigned h=(*pat)->height();
|
|
|
|
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)(*pat)->getBytes(),w,h,w*4);
|
|
|
|
agg::span_allocator<agg::rgba8> sa;
|
|
|
|
agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32,
|
|
|
|
agg::row_accessor<agg::int8u>, agg::pixel32_type> pixf_pattern(pattern_rbuf);
|
|
|
|
img_source_type img_src(pixf_pattern);
|
|
|
|
|
|
|
|
double x0=0,y0=0;
|
|
|
|
unsigned num_geometries = feature.num_geometries();
|
|
|
|
if (num_geometries>0)
|
|
|
|
{
|
|
|
|
path_type path(t_,feature.get_geometry(0),prj_trans);
|
|
|
|
path.vertex(&x0,&y0);
|
|
|
|
}
|
|
|
|
unsigned offset_x = unsigned(width_-x0);
|
|
|
|
unsigned offset_y = unsigned(height_-y0);
|
|
|
|
span_gen_type sg(img_src, offset_x, offset_y);
|
|
|
|
renderer_type rp(renb,sa, sg);
|
|
|
|
for (unsigned i=0;i<num_geometries;++i)
|
|
|
|
{
|
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 2)
|
|
|
|
{
|
|
|
|
path_type path(t_,geom,prj_trans);
|
|
|
|
ras_ptr->add_path(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
agg::render_scanlines(*ras_ptr, sl, rp);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(raster_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
raster_ptr const& raster=feature.get_raster();
|
|
|
|
if (raster)
|
|
|
|
{
|
2010-03-12 14:34:13 +01:00
|
|
|
// If there's a colorizer defined, use it to color the raster in-place
|
|
|
|
raster_colorizer_ptr colorizer = sym.get_colorizer();
|
|
|
|
if (colorizer)
|
|
|
|
colorizer->colorize(raster);
|
2010-02-03 13:19:49 +01:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
box2d<double> ext=t_.forward(raster->ext_);
|
|
|
|
|
2010-03-12 00:19:12 +01:00
|
|
|
int start_x = rint(ext.minx());
|
|
|
|
int start_y = rint(ext.miny());
|
|
|
|
int raster_width = rint(ext.width());
|
|
|
|
int raster_height = rint(ext.height());
|
2010-03-03 04:23:53 +01:00
|
|
|
int end_x = start_x + raster_width;
|
|
|
|
int end_y = start_y + raster_height;
|
|
|
|
double err_offs_x = (ext.minx()-start_x + ext.maxx()-end_x)/2;
|
|
|
|
double err_offs_y = (ext.miny()-start_y + ext.maxy()-end_y)/2;
|
2009-12-16 21:02:06 +01:00
|
|
|
|
2010-02-03 13:19:49 +01:00
|
|
|
if ( raster_width > 0 && raster_height > 0)
|
|
|
|
{
|
|
|
|
image_data_32 target(raster_width,raster_height);
|
|
|
|
|
|
|
|
if (sym.get_scaling() == "fast") {
|
|
|
|
scale_image<image_data_32>(target,raster->data_);
|
|
|
|
} else if (sym.get_scaling() == "bilinear"){
|
2010-03-03 04:23:53 +01:00
|
|
|
scale_image_bilinear<image_data_32>(target,raster->data_, err_offs_x, err_offs_y);
|
2010-02-03 13:19:49 +01:00
|
|
|
} else if (sym.get_scaling() == "bilinear8"){
|
2010-03-03 04:23:53 +01:00
|
|
|
scale_image_bilinear8<image_data_32>(target,raster->data_, err_offs_x, err_offs_y);
|
2009-12-16 21:02:06 +01:00
|
|
|
} else {
|
2010-02-03 13:19:49 +01:00
|
|
|
scale_image<image_data_32>(target,raster->data_);
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
2010-02-03 13:19:49 +01:00
|
|
|
|
|
|
|
if (sym.get_mode() == "normal"){
|
|
|
|
if (sym.get_opacity() == 1.0) {
|
|
|
|
pixmap_.set_rectangle(start_x,start_y,target);
|
|
|
|
} else {
|
|
|
|
pixmap_.set_rectangle_alpha2(target,start_x,start_y, sym.get_opacity());
|
|
|
|
}
|
|
|
|
} else if (sym.get_mode() == "grain_merge"){
|
|
|
|
pixmap_.template merge_rectangle<MergeGrain> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "grain_merge2"){
|
|
|
|
pixmap_.template merge_rectangle<MergeGrain2> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "multiply"){
|
|
|
|
pixmap_.template merge_rectangle<Multiply> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "multiply2"){
|
|
|
|
pixmap_.template merge_rectangle<Multiply2> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "divide"){
|
|
|
|
pixmap_.template merge_rectangle<Divide> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "divide2"){
|
|
|
|
pixmap_.template merge_rectangle<Divide2> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "screen"){
|
|
|
|
pixmap_.template merge_rectangle<Screen> (target,start_x,start_y, sym.get_opacity());
|
|
|
|
} else if (sym.get_mode() == "hard_light"){
|
|
|
|
pixmap_.template merge_rectangle<HardLight> (target,start_x,start_y, sym.get_opacity());
|
2009-12-16 21:02:06 +01:00
|
|
|
} else {
|
2010-02-03 13:19:49 +01:00
|
|
|
if (sym.get_opacity() == 1.0){
|
|
|
|
pixmap_.set_rectangle(start_x,start_y,target);
|
|
|
|
} else {
|
|
|
|
pixmap_.set_rectangle_alpha2(target,start_x,start_y, sym.get_opacity());
|
|
|
|
}
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
2010-02-03 13:19:49 +01:00
|
|
|
// TODO: other modes? (add,diff,sub,...)
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(markers_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
2010-05-30 05:16:51 +02:00
|
|
|
{
|
2010-05-27 16:21:31 +02:00
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
typedef agg::pixfmt_rgba32 pixfmt;
|
|
|
|
typedef agg::renderer_base<pixfmt> renderer_base;
|
|
|
|
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
|
2010-05-30 05:16:51 +02:00
|
|
|
|
|
|
|
bool svg_marker;
|
|
|
|
arrow arrow_;
|
|
|
|
box2d<double> extent;
|
|
|
|
boost::optional<path_ptr> marker;
|
|
|
|
|
|
|
|
ras_ptr->reset();
|
|
|
|
ras_ptr->gamma(agg::gamma_linear());
|
|
|
|
agg::scanline_u8 sl;
|
|
|
|
agg::rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_ * 4);
|
|
|
|
pixfmt pixf(buf);
|
|
|
|
renderer_base renb(pixf);
|
|
|
|
renderer_solid ren(renb);
|
|
|
|
|
|
|
|
color const& fill_ = sym.get_fill();
|
|
|
|
unsigned r = fill_.red();
|
|
|
|
unsigned g = fill_.green();
|
|
|
|
unsigned b = fill_.blue();
|
|
|
|
unsigned a = fill_.alpha();
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i=0; i<feature.num_geometries(); ++i)
|
2009-12-16 21:02:06 +01:00
|
|
|
{
|
2010-05-30 05:16:51 +02:00
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() <= 1) continue;
|
|
|
|
|
|
|
|
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
|
|
|
|
|
|
|
|
if (!filename.empty())
|
|
|
|
{
|
|
|
|
marker = mapnik::marker_cache::instance()->find(filename, true);
|
|
|
|
if (marker && *marker)
|
|
|
|
{
|
|
|
|
svg_marker = true;
|
|
|
|
double x1, y1, x2, y2;
|
|
|
|
(*marker)->bounding_rect(&x1, &y1, &x2, &y2);
|
|
|
|
extent.init(x1, y1, x2, y2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
svg_marker = false;
|
|
|
|
extent = arrow_.extent();
|
|
|
|
}
|
|
|
|
|
|
|
|
path_type path(t_,geom,prj_trans);
|
|
|
|
markers_placement<path_type, label_collision_detector4> placement(path, extent, detector_, sym.get_spacing(), sym.get_max_error(), sym.get_allow_overlap());
|
|
|
|
|
|
|
|
double x, y, angle;
|
|
|
|
|
|
|
|
while (placement.get_point(&x, &y, &angle))
|
|
|
|
{
|
|
|
|
agg::trans_affine matrix = agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x, y);
|
|
|
|
if (svg_marker)
|
|
|
|
{
|
|
|
|
(*marker)->render(*ras_ptr, sl, ren, matrix, renb.clip_box(), 1.0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
agg::conv_transform<arrow, agg::trans_affine> trans(arrow_, matrix);
|
|
|
|
ras_ptr->add_path(trans);
|
|
|
|
ren.color(agg::rgba8(r, g, b, a));
|
|
|
|
agg::render_scanlines(*ras_ptr, sl, ren);
|
|
|
|
}
|
|
|
|
}
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(text_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
|
|
|
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
|
|
|
|
|
|
|
expression_ptr name_expr = sym.get_name();
|
|
|
|
if (!name_expr) return;
|
|
|
|
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*name_expr);
|
|
|
|
UnicodeString text = result.to_unicode();
|
|
|
|
|
|
|
|
if ( sym.get_text_convert() == TOUPPER)
|
|
|
|
{
|
|
|
|
text = text.toUpper();
|
|
|
|
}
|
|
|
|
else if ( sym.get_text_convert() == TOLOWER)
|
|
|
|
{
|
|
|
|
text = text.toLower();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( text.length() > 0 )
|
|
|
|
{
|
|
|
|
color const& fill = sym.get_fill();
|
|
|
|
|
|
|
|
face_set_ptr faces;
|
|
|
|
|
|
|
|
if (sym.get_fontset().size() > 0)
|
|
|
|
{
|
2008-07-25 02:23:33 +02:00
|
|
|
faces = font_manager_.get_face_set(sym.get_fontset());
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-07-25 02:23:33 +02:00
|
|
|
faces = font_manager_.get_face_set(sym.get_face_name());
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
2008-07-25 02:23:33 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
if (faces->size() > 0)
|
|
|
|
{
|
2009-03-31 11:23:23 +02:00
|
|
|
text_renderer<T> ren(pixmap_, faces);
|
2008-04-12 17:22:27 +02:00
|
|
|
ren.set_pixel_size(sym.get_text_size());
|
|
|
|
ren.set_fill(fill);
|
|
|
|
ren.set_halo_fill(sym.get_halo_fill());
|
|
|
|
ren.set_halo_radius(sym.get_halo_radius());
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
ren.set_opacity(sym.get_opacity());
|
|
|
|
|
2008-04-12 17:22:27 +02:00
|
|
|
placement_finder<label_collision_detector4> finder(detector_);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-04-12 17:22:27 +02:00
|
|
|
string_info info(text);
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
|
2008-07-25 02:23:33 +02:00
|
|
|
faces->get_string_info(info);
|
2008-04-12 17:22:27 +02:00
|
|
|
unsigned num_geom = feature.num_geometries();
|
|
|
|
for (unsigned i=0;i<num_geom;++i)
|
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
geometry2d const& geom = feature.get_geometry(i);
|
|
|
|
if (geom.num_points() > 0) // don't bother with empty geometries
|
2010-05-27 12:20:03 +02:00
|
|
|
{
|
2009-12-16 21:02:06 +01:00
|
|
|
placement text_placement(info,sym);
|
|
|
|
text_placement.avoid_edges = sym.get_avoid_edges();
|
|
|
|
if (sym.get_label_placement() == POINT_PLACEMENT)
|
|
|
|
{
|
|
|
|
double label_x, label_y, z=0.0;
|
|
|
|
geom.label_position(&label_x, &label_y);
|
|
|
|
prj_trans.backward(label_x,label_y, z);
|
|
|
|
t_.forward(&label_x,&label_y);
|
2010-05-27 12:20:03 +02:00
|
|
|
|
|
|
|
double angle = 0.0;
|
|
|
|
expression_ptr angle_expr = sym.get_orientation();
|
|
|
|
if (angle_expr)
|
|
|
|
{
|
|
|
|
// apply rotation
|
|
|
|
value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*angle_expr);
|
|
|
|
angle = result.to_double();
|
|
|
|
}
|
|
|
|
|
|
|
|
finder.find_point_placement(text_placement,label_x,label_y, angle, sym.get_vertical_alignment(),sym.get_line_spacing(),
|
2009-12-16 21:02:06 +01:00
|
|
|
sym.get_character_spacing(),sym.get_horizontal_alignment(),sym.get_justify_alignment());
|
2010-05-27 12:20:03 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
finder.update_detector(text_placement);
|
|
|
|
}
|
|
|
|
else if ( geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT)
|
|
|
|
{
|
2010-05-27 12:20:03 +02:00
|
|
|
path_type path(t_,geom,prj_trans);
|
2009-12-16 21:02:06 +01:00
|
|
|
finder.find_line_placements<path_type>(text_placement,path);
|
|
|
|
}
|
2010-05-27 12:20:03 +02:00
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
|
|
|
|
{
|
|
|
|
double x = text_placement.placements[ii].starting_x;
|
|
|
|
double y = text_placement.placements[ii].starting_y;
|
|
|
|
box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
|
|
|
|
ren.render(x,y);
|
|
|
|
}
|
|
|
|
}
|
Patch from David Eastcott :
1. Modified Text Symbolizer
a) corrected line fragment centering (for 2nd and subsequent lines, when line breaks occur).
b) adjusted vertical alignment calculation so that:
i) middle -> has the center of the text line(s) at the point origin
ii) bottom -> has the text line(s) below the point origin
iii) top -> has the text line(s) above the point origin
c) added new text_symbolizer attribute: 'wrap_before', value range: true/false, default == false
allows line breaks at first wrap_char before wrap_width as an alternative to the original
which was to create the line break at the first wrap_char after wrap_width
d) added new text_symbolizer attribute: 'horizontal_alignment', value range: left/middle/right, default == middle
i) left -> has all text line(s) to left of the point origin
ii) middle -> has all text line(s) centered on the the point origin
iii) right -> has all text line(s) to the right of the point origin
NOTE: dx, dy position adjustments are applied after alignments and before Justify.
e) added new text_symbolizer attribute: 'justify_alignment', value range: left/middle/right, default == middle
i) left -> after alignments, has all text line(s) are left justified (left to right reading)
ii) middle -> after alignments, has all text line(s) center justified
iii) right -> after alignments, has all text line(s) right justified (right to left reading)
f) added new text_symbolizer attribute: 'opacity', value range: 0.0 thru 1.0; 1.0 == fully opaque
g) modified positioning to compensate for both line_spacing and character_spacing, to ensure proper
centering of the text envelope. Also ensure that centering occurs correctly even if no wrapping
occurs. Line spacing is uniform and consistent and compensates for errors between text_size and
the actual size (ci.height is inconsistent, depending on case and character); fixes issue with
multi-line text where some lines have a slight gap and others are compressed together.
2. Modified shield_symbolizer
a) added the attributes:
i) allow_overlap
ii) vertical_alignment
iii) horizontal_alignment
iv) justify_alignment
v) wrap_width
vi) wrap_character
vii) wrap_before
viii) text_convert
ix) line_spacing
x) character_spacing
xi) opacity
b) added new shield_symbolizer attribute: 'unlock_image', value range: true/false, default == false
i) false == image and text placement behaviour same as before
ii) true == image placement independant of text, image is always centered at geometry point, text placed per attributes,
dx/dy only affect text.
Allows user to create point markers with text, but both the text and image rendering collision detection are done
as a pair (they come and go together - solves problem if using point_symbolizer and text_symbolizers where one or the
other are omitted due to overlaps, but not both)
c) extended choices for the attribute 'placement' to include vertex; effect is limited to the shield_symbolizer
Allows an attempted placement at every vertex available, gives additional shield placement volume when using line geometry
d) ensured that the text placement was not updating the detector unless a shield image was actually placed.
e) added new shield_symbolizer attribute: 'no_text', value range: true/false, default = false
When set true, the text for the feature is ignored ('space' subsituted) so that pure graphic symbols can be used
and no text is rendered over top of them.
2009-10-19 15:52:53 +02:00
|
|
|
}
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-04-12 17:22:27 +02:00
|
|
|
throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
|
2009-12-16 21:02:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-03-18 21:04:35 +01:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void agg_renderer<T>::process(glyph_symbolizer const& sym,
|
|
|
|
Feature const& feature,
|
|
|
|
proj_transform const& prj_trans)
|
|
|
|
{
|
2010-03-18 21:05:08 +01:00
|
|
|
face_set_ptr faces = font_manager_.get_face_set(sym.get_face_name());
|
|
|
|
if (faces->size() > 0)
|
|
|
|
{
|
|
|
|
// Get x and y from geometry and translate to pixmap coords.
|
|
|
|
double x, y, z=0.0;
|
|
|
|
feature.get_geometry(0).label_position(&x, &y);
|
|
|
|
prj_trans.backward(x,y,z);
|
|
|
|
t_.forward(&x, &y);
|
|
|
|
|
|
|
|
text_renderer<T> ren(pixmap_, faces);
|
2010-03-19 10:33:57 +01:00
|
|
|
|
|
|
|
// set fill and halo colors
|
2010-03-18 21:05:08 +01:00
|
|
|
color fill = sym.eval_color(feature);
|
|
|
|
ren.set_fill(fill);
|
|
|
|
if (fill != color("transparent")) {
|
|
|
|
ren.set_halo_fill(sym.get_halo_fill());
|
|
|
|
ren.set_halo_radius(sym.get_halo_radius());
|
|
|
|
}
|
|
|
|
|
2010-03-19 10:33:57 +01:00
|
|
|
// set font size
|
|
|
|
unsigned size = sym.eval_size(feature);
|
|
|
|
ren.set_pixel_size(size);
|
|
|
|
faces->set_pixel_sizes(size);
|
|
|
|
|
2010-03-18 21:05:08 +01:00
|
|
|
// Get and render text path
|
|
|
|
//
|
|
|
|
text_path_ptr path = sym.get_text_path(faces, feature);
|
|
|
|
// apply displacement
|
|
|
|
position pos = sym.get_displacement();
|
|
|
|
double dx = boost::get<0>(pos);
|
|
|
|
double dy = boost::get<1>(pos);
|
|
|
|
path->starting_x = x = x+dx;
|
|
|
|
path->starting_y = y = y+dy;
|
|
|
|
|
|
|
|
// Prepare glyphs to set internal state and calculate the marker's
|
|
|
|
// final box so we can check for a valid placement
|
|
|
|
box2d<double> dim = ren.prepare_glyphs(path.get());
|
|
|
|
double bsize = (dim.width()>dim.height()?dim.width():dim.height())/2;
|
|
|
|
box2d<double> ext(
|
|
|
|
floor(x-bsize), floor(y-bsize), ceil(x+bsize), ceil(y+bsize)
|
|
|
|
);
|
|
|
|
if ((sym.get_allow_overlap() || detector_.has_placement(ext)) &&
|
|
|
|
(!sym.get_avoid_edges() || detector_.extent().contains(ext)))
|
|
|
|
{
|
|
|
|
// Placement is valid, render glyph and update detector.
|
|
|
|
ren.render(x, y);
|
|
|
|
detector_.insert(ext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw config_error(
|
|
|
|
"Unable to find specified font face in GlyphSymbolizer"
|
|
|
|
);
|
|
|
|
}
|
2010-03-18 21:04:35 +01:00
|
|
|
}
|
|
|
|
|
2009-12-16 21:02:06 +01:00
|
|
|
template class agg_renderer<image_32>;
|
2006-02-07 15:41:41 +01:00
|
|
|
}
|