1. Changed internal geometry representation (explicit support for multi geometries)

(FIXME : label_spacing is still, too slow!!) 
2. Re-use some agg objects.
3. placement_finder cleanups! 
4. Added support for 'building_symbolizer' - extruded polygons
This commit is contained in:
Artem Pavlenko 2007-09-16 11:23:51 +00:00
parent d38dedad68
commit 8e071f84c7
36 changed files with 1534 additions and 1292 deletions

View file

@ -52,10 +52,11 @@ opts.Add(PathOption('GIGABASE_LIBS', 'Search path for Gigabase library files', '
opts.Add(PathOption('PYTHON','Python executable', sys.executable)) opts.Add(PathOption('PYTHON','Python executable', sys.executable))
opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal','gigabase'])) opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal','gigabase']))
opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python'])) opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python']))
opts.Add('DEBUG', 'Compile a debug version of mapnik', '') opts.Add(BoolOption('DEBUG', 'Compile a debug version of mapnik', 'False'))
opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/') opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/')
opts.Add('BIDI', 'BIDI support', '') opts.Add(BoolOption('BIDI', 'BIDI support', 'False'))
opts.Add(EnumOption('THREADING','Set threading support','multi', ['multi','single'])) opts.Add(EnumOption('THREADING','Set threading support','multi', ['multi','single']))
opts.Add(EnumOption('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit']))
env = Environment(ENV=os.environ, options=opts) env = Environment(ENV=os.environ, options=opts)
@ -99,9 +100,12 @@ if env['BIDI']:
if env['FRIBIDI_INCLUDES'] not in env['CPPPATH']: if env['FRIBIDI_INCLUDES'] not in env['CPPPATH']:
env['CPPPATH'].append(env['FRIBIDI_INCLUDES']) env['CPPPATH'].append(env['FRIBIDI_INCLUDES'])
if env['FRIBIDI_LIBS'] not in env['LIBPATH']: if env['FRIBIDI_LIBS'] not in env['LIBPATH']:
env['CPPPATH'].append(env['FRIBIDI_LIBS']) env['LIBPATH'].append(env['FRIBIDI_LIBS'])
env['LIBS'].append('fribidi') env['LIBS'].append('fribidi')
if env['XMLPARSER'] == 'tinyxml':
env.Append(CXXFLAGS = '-DBOOST_PROPERTY_TREE_XML_PARSER_TINYXML -DTIXML_USE_STL')
C_LIBSHEADERS = [ C_LIBSHEADERS = [
['m', 'math.h', True], ['m', 'math.h', True],
['ltdl', 'ltdl.h', True], ['ltdl', 'ltdl.h', True],
@ -122,7 +126,7 @@ if env['BIDI'] : C_LIBSHEADERS.append(['fribidi','fribidi/fribidi.h',True])
BOOST_LIBSHEADERS = [ BOOST_LIBSHEADERS = [
['thread', 'boost/thread/mutex.hpp', True], ['thread', 'boost/thread/mutex.hpp', True],
# ['system', 'boost/system/system_error.hpp', True], # uncomment this on Darwin + boost_1_35 ['system', 'boost/system/system_error.hpp', True], # uncomment this on Darwin + boost_1_35
['filesystem', 'boost/filesystem/operations.hpp', True], ['filesystem', 'boost/filesystem/operations.hpp', True],
['regex', 'boost/regex.hpp', True], ['regex', 'boost/regex.hpp', True],
['program_options', 'boost/program_options.hpp', False] ['program_options', 'boost/program_options.hpp', False]
@ -221,9 +225,9 @@ if env['PLATFORM'] == 'Darwin': pthread = ''
else: pthread = '-pthread' else: pthread = '-pthread'
if env['DEBUG']: if env['DEBUG']:
env.Append(CXXFLAGS = '-ansi -Wall %s -ftemplate-depth-100 -O0 -fno-inline -g -DDEBUG -DMAPNIK_DEBUG -D%s -DBOOST_PROPERTY_TREE_XML_PARSER_TINYXML -DTIXML_USE_STL' % (pthread, env['PLATFORM'].upper())) env.Append(CXXFLAGS = '-ansi -Wall %s -ftemplate-depth-100 -O0 -fno-inline -g -DDEBUG -DMAPNIK_DEBUG -D%s ' % (pthread, env['PLATFORM'].upper()))
else: else:
env.Append(CXXFLAGS = '-ansi -Wall %s -ftemplate-depth-100 -O3 -finline-functions -Wno-inline -DNDEBUG -D%s -DBOOST_PROPERTY_TREE_XML_PARSER_TINYXML -DTIXML_USE_STL' % (pthread,env['PLATFORM'].upper())) env.Append(CXXFLAGS = '-ansi -Wall %s -ftemplate-depth-100 -O2 -finline-functions -Wno-inline -DNDEBUG -D%s' % (pthread,env['PLATFORM'].upper()))
# Install some free default fonts # Install some free default fonts

View file

@ -33,10 +33,10 @@
// Provides faster access for massive pixel operations, // Provides faster access for massive pixel operations,
// such as blur, image filtering: // such as blur, image filtering:
// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u> #define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
// //
// Provides cheaper creation and destruction (no mem allocs): // Provides cheaper creation and destruction (no mem allocs):
#define AGG_RENDERING_BUFFER row_accessor<int8u> // #define AGG_RENDERING_BUFFER row_accessor<int8u>
// //
// You can still use both of them simultaneouslyin your applications // You can still use both of them simultaneouslyin your applications
// This #define is used only for default rendering_buffer type, // This #define is used only for default rendering_buffer type,

View file

@ -290,8 +290,8 @@ namespace agg
#ifdef AGG_RENDERING_BUFFER #ifdef AGG_RENDERING_BUFFER
typedef AGG_RENDERING_BUFFER rendering_buffer; typedef AGG_RENDERING_BUFFER rendering_buffer;
#else #else
// typedef row_ptr_cache<int8u> rendering_buffer; typedef row_ptr_cache<int8u> rendering_buffer;
typedef row_accessor<int8u> rendering_buffer; //typedef row_accessor<int8u> rendering_buffer;
#endif #endif
} }

View file

@ -53,10 +53,10 @@ class _Envelope(Envelope,_injector):
(self.minx,self.miny,self.maxx,self.maxy) (self.minx,self.miny,self.maxx,self.maxy)
class _Projection(Projection,_injector): class _Projection(Projection,_injector):
def forward(self,pt): def forward(self,obj):
return forward_(pt,self) return forward_(obj,self)
def inverse(self,pt): def inverse(self,obj):
return inverse_(pt,self) return inverse_(obj,self)
class _Datasource(Datasource,_injector): class _Datasource(Datasource,_injector):
def describe(self): def describe(self):

View file

@ -26,7 +26,7 @@
#include <mapnik/projection.hpp> #include <mapnik/projection.hpp>
namespace { namespace {
mapnik::coord2d forward(mapnik::coord2d const& pt, mapnik::coord2d forward_pt(mapnik::coord2d const& pt,
mapnik::projection const& prj) mapnik::projection const& prj)
{ {
double x = pt.x; double x = pt.x;
@ -35,7 +35,7 @@ namespace {
return mapnik::coord2d(x,y); return mapnik::coord2d(x,y);
} }
mapnik::coord2d inverse(mapnik::coord2d const& pt, mapnik::coord2d inverse_pt(mapnik::coord2d const& pt,
mapnik::projection const& prj) mapnik::projection const& prj)
{ {
double x = pt.x; double x = pt.x;
@ -44,6 +44,30 @@ namespace {
return mapnik::coord2d(x,y); return mapnik::coord2d(x,y);
} }
mapnik::Envelope<double> forward_env(mapnik::Envelope<double> const & box,
mapnik::projection const& prj)
{
double minx = box.minx();
double miny = box.miny();
double maxx = box.maxx();
double maxy = box.maxy();
prj.forward(minx,miny);
prj.forward(maxx,maxy);
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
}
mapnik::Envelope<double> inverse_env(mapnik::Envelope<double> const & box,
mapnik::projection const& prj)
{
double minx = box.minx();
double miny = box.miny();
double maxx = box.maxx();
double maxy = box.maxy();
prj.inverse(minx,miny);
prj.inverse(maxx,maxy);
return mapnik::Envelope<double>(minx,miny,maxx,maxy);
}
} }
void export_projection () void export_projection ()
@ -57,7 +81,9 @@ void export_projection ()
.add_property ("geographic",&projection::is_geographic) .add_property ("geographic",&projection::is_geographic)
; ;
def("forward_",&forward); def("forward_",&forward_pt);
def("inverse_",&inverse); def("inverse_",&inverse_pt);
def("forward_",&forward_env);
def("inverse_",&inverse_env);
} }

View file

@ -171,10 +171,10 @@ void MapWidget::mousePressEvent(QMouseEvent* e)
} }
} }
geometry_ptr geom = feat->get_geometry(); if (feat->num_geometries() > 0)
if (geom)
{ {
(*feat)["mapnik:geometry"] = geom->type(); mapnik::geometry2d & geom = feat->get_geometry(0);
(*feat)["mapnik:geometry"] = geom.type();
data->push(feat); data->push(feat);
} }
} }

View file

@ -163,7 +163,7 @@ struct symbolizer_icon : public boost::static_visitor<QIcon>
{ {
QPixmap pix(16,16); QPixmap pix(16,16);
QPainter painter(&pix); QPainter painter(&pix);
mapnik::Color fill = sym.get_fill(); mapnik::Color const& fill = sym.get_fill();
QBrush brush(QColor(fill.red(),fill.green(),fill.blue(),fill.alpha())); QBrush brush(QColor(fill.red(),fill.green(),fill.blue(),fill.alpha()));
painter.fillRect(0, 0, 16, 16, brush); painter.fillRect(0, 0, 16, 16, brush);
return QIcon(pix); return QIcon(pix);
@ -180,6 +180,21 @@ struct symbolizer_icon : public boost::static_visitor<QIcon>
} }
return QIcon(); return QIcon();
} }
QIcon operator() (mapnik::line_symbolizer const& sym) const
{
QPixmap pix(48,16);
pix.fill();
QPainter painter(&pix);
mapnik::stroke const& strk = sym.get_stroke();
mapnik::Color const& col = strk.get_color();
QPen pen(QColor(col.red(),col.green(),col.blue(),col.alpha()));
pen.setWidth(strk.get_width());
painter.setPen(pen);
painter.drawLine(0,7,47,7);
//painter.drawLine(7,15,12,0);
//painter.drawLine(12,0,8,15);
return QIcon(pix);
}
template <typename T> template <typename T>
QIcon operator() (T const& ) const QIcon operator() (T const& ) const

View file

@ -7,10 +7,10 @@ TEMPLATE = app
INCLUDEPATH += /usr/local/include INCLUDEPATH += /usr/local/include
INCLUDEPATH += /opt/boost_1_35/include/boost-1_35 INCLUDEPATH += /opt/boost_1_35/include/boost-1_35
INCLUDEPATH += /usr/local/include/freetype2 INCLUDEPATH += /usr/local/include/freetype2
INCLUDEPATH += /Users/artem/projects/mapnik/agg/include
INCLUDEPATH += . INCLUDEPATH += .
QMAKE_CXXFLAGS +=' -DDARWIN'
unix:LIBS = -L/usr/local/lib -lmapnik -lfreetype unix:LIBS = -L/usr/local/lib -lmapnik -lfreetype
# Input # Input

View file

@ -35,6 +35,10 @@
#include <mapnik/label_collision_detector.hpp> #include <mapnik/label_collision_detector.hpp>
#include <mapnik/placement_finder.hpp> #include <mapnik/placement_finder.hpp>
#include <mapnik/map.hpp> #include <mapnik/map.hpp>
// agg
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_rasterizer_scanline_aa.h"
namespace mapnik { namespace mapnik {
template <typename T> template <typename T>
@ -71,12 +75,20 @@ namespace mapnik {
void process(text_symbolizer const& sym, void process(text_symbolizer const& sym,
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans); proj_transform const& prj_trans);
void process(building_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans);
private: private:
T & pixmap_; T & pixmap_;
unsigned width_;
unsigned height_;
agg::row_ptr_cache<agg::int8u> buf_;
agg::pixfmt_rgba32 pixf_;
CoordTransform t_; CoordTransform t_;
face_manager<freetype_engine> font_manager_; face_manager<freetype_engine> font_manager_;
label_collision_detector4 detector_; label_collision_detector4 detector_;
placement_finder<label_collision_detector4> finder_; placement_finder<label_collision_detector4> finder_;
agg::rasterizer_scanline_aa<> ras_;
}; };
} }

View file

@ -59,7 +59,7 @@ namespace mapnik {
struct MAPNIK_DECL coord_transform2 struct MAPNIK_DECL coord_transform2
{ {
coord_transform2(Transform const& t, coord_transform2(Transform const& t,
Geometry& geom, Geometry const& geom,
proj_transform const& prj_trans) proj_transform const& prj_trans)
: t_(t), : t_(t),
geom_(geom), geom_(geom),
@ -81,10 +81,45 @@ namespace mapnik {
private: private:
Transform const& t_; Transform const& t_;
Geometry& geom_; Geometry const& geom_;
proj_transform const& prj_trans_; proj_transform const& prj_trans_;
}; };
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform3
{
coord_transform3(Transform const& t,
Geometry const& geom,
proj_transform const& prj_trans,
int dx, int dy)
: t_(t),
geom_(geom),
prj_trans_(prj_trans),
dx_(dx), dy_(dy) {}
unsigned vertex(double * x , double * y) const
{
unsigned command = geom_.vertex(x,y);
double z=0;
prj_trans_.backward(*x,*y,z);
t_.forward(x,y);
*x+=dx_;
*y+=dy_;
return command;
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
private:
Transform const& t_;
Geometry const& geom_;
proj_transform const& prj_trans_;
int dx_;
int dy_;
};
class CoordTransform class CoordTransform
{ {
@ -93,7 +128,8 @@ namespace mapnik {
int height; int height;
double scale_; double scale_;
Envelope<double> extent_; Envelope<double> extent_;
double offset_x_,offset_y_; double offset_x_;
double offset_y_;
public: public:
CoordTransform(int width,int height,const Envelope<double>& extent, CoordTransform(int width,int height,const Envelope<double>& extent,
double offset_x = 0, double offset_y = 0) double offset_x = 0, double offset_y = 0)

View file

@ -53,7 +53,7 @@ namespace mapnik {
private: private:
int id_; int id_;
geometry_type geom_; boost::ptr_vector<geometry_type> geom_cont_;
raster_type raster_; raster_type raster_;
std::map<std::string,value> props_; std::map<std::string,value> props_;
public: public:
@ -61,34 +61,45 @@ namespace mapnik {
explicit feature(int id) explicit feature(int id)
: properties(props_), : properties(props_),
id_(id), id_(id),
geom_(), geom_cont_(),
raster_() {} raster_() {}
feature(int id,const geometry_type& geom) //feature(int id,const geometry_type& geom)
: properties(props_), // : properties(props_),
id_(id), // id_(id),
geom_(geom), // geom_(geom),
raster_() {} // raster_() {}
int id() const int id() const
{ {
return id_; return id_;
} }
void set_geometry(geometry_type& geom) void add_geometry(geometry_type * geom)
{ {
geom_=geom; geom_cont_.push_back(geom);
} }
geometry_type const& get_geometry() const unsigned num_geometries() const
{ {
return geom_; return geom_cont_.size();
}
geometry_type const& get_geometry(unsigned index) const
{
return geom_cont_[index];
}
geometry_type& get_geometry(unsigned index)
{
return geom_cont_[index];
} }
const raster_type& get_raster() const const raster_type& get_raster() const
{ {
return raster_; return raster_;
} }
void set_raster(raster_type const& raster) void set_raster(raster_type const& raster)
{ {
raster_=raster; raster_=raster;
@ -123,7 +134,7 @@ namespace mapnik {
} }
}; };
typedef feature<geometry_ptr,raster_ptr> Feature; typedef feature<geometry2d,raster_ptr> Feature;
inline std::ostream& operator<< (std::ostream & out,Feature const& f) inline std::ostream& operator<< (std::ostream & out,Feature const& f)
{ {

View file

@ -29,6 +29,7 @@
// boost // boost
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
// mapnik // mapnik
#include <mapnik/vertex_vector.hpp> #include <mapnik/vertex_vector.hpp>
#include <mapnik/ctrans.hpp> #include <mapnik/ctrans.hpp>
@ -76,8 +77,8 @@ namespace mapnik {
virtual void move_to(value_type x,value_type y)=0; virtual void move_to(value_type x,value_type y)=0;
virtual void line_to(value_type x,value_type y)=0; virtual void line_to(value_type x,value_type y)=0;
virtual unsigned num_points() const = 0; virtual unsigned num_points() const = 0;
virtual unsigned vertex(double* x, double* y)=0; virtual unsigned vertex(double* x, double* y) const=0;
virtual void rewind(unsigned )=0; virtual void rewind(unsigned) const=0;
virtual void set_capacity(size_t size)=0; virtual void set_capacity(size_t size)=0;
virtual ~geometry() {} virtual ~geometry() {}
}; };
@ -117,14 +118,14 @@ namespace mapnik {
return 1; return 1;
} }
unsigned vertex(double* x, double* y) unsigned vertex(double* x, double* y) const
{ {
*x = pt_.x; *x = pt_.x;
*y = pt_.y; *y = pt_.y;
return SEG_LINETO; return SEG_LINETO;
} }
void rewind(unsigned ) {} void rewind(unsigned ) const {}
bool hit_test(value_type x,value_type y, double tol) const bool hit_test(value_type x,value_type y, double tol) const
{ {
@ -209,12 +210,12 @@ namespace mapnik {
return cont_.size(); return cont_.size();
} }
unsigned vertex(double* x, double* y) unsigned vertex(double* x, double* y) const
{ {
return cont_.get_vertex(itr_++,x,y); return cont_.get_vertex(itr_++,x,y);
} }
void rewind(unsigned ) void rewind(unsigned ) const
{ {
itr_=0; itr_=0;
} }
@ -318,12 +319,12 @@ namespace mapnik {
return cont_.size(); return cont_.size();
} }
unsigned vertex(double* x, double* y) unsigned vertex(double* x, double* y) const
{ {
return cont_.get_vertex(itr_++,x,y); return cont_.get_vertex(itr_++,x,y);
} }
void rewind(unsigned ) void rewind(unsigned ) const
{ {
itr_=0; itr_=0;
} }
@ -344,8 +345,9 @@ namespace mapnik {
typedef line_string<vertex2d,vertex_vector2> line_string_impl; typedef line_string<vertex2d,vertex_vector2> line_string_impl;
typedef polygon<vertex2d,vertex_vector2> polygon_impl; typedef polygon<vertex2d,vertex_vector2> polygon_impl;
typedef geometry<vertex2d> geometry_type; typedef geometry<vertex2d> geometry2d;
typedef boost::shared_ptr<geometry_type> geometry_ptr; typedef boost::shared_ptr<geometry2d> geometry_ptr;
typedef boost::ptr_vector<geometry2d> geometry_containter;
} }
#endif //GEOMETRY_HPP #endif //GEOMETRY_HPP

View file

@ -38,9 +38,12 @@ namespace mapnik {
bool pass(Feature const& feature) bool pass(Feature const& feature)
{ {
geometry_ptr geom = feature.get_geometry(); for (unsigned i=0;i<feature.num_geometries();++i)
if (geom && geom->hit_test(x_,y_,tol_)) {
geometry2d const& geom = feature.get_geometry(i);
if (geom.hit_test(x_,y_,tol_))
return true; return true;
}
return false; return false;
} }

View file

@ -41,6 +41,7 @@ namespace mapnik {
feature_ptr next() feature_ptr next()
{ {
/*
while (pos_ != end_) while (pos_ != end_)
{ {
geometry_ptr geom = (*pos_)->get_geometry(); geometry_ptr geom = (*pos_)->get_geometry();
@ -50,6 +51,7 @@ namespace mapnik {
} }
++pos_; ++pos_;
} }
*/
return feature_ptr(); return feature_ptr();
} }

View file

@ -36,25 +36,18 @@
namespace mapnik namespace mapnik
{ {
typedef text_path placement_element;
struct placement_element struct placement : boost::noncopyable
{ {
double starting_x; typedef coord_transform2<CoordTransform,geometry2d> path_type;
double starting_y;
text_path path;
};
struct placement
{
typedef coord_transform2<CoordTransform,geometry_type> path_type;
template <typename SymbolizerT> template <typename SymbolizerT>
placement(string_info *info_, placement(string_info *info_,
CoordTransform *ctrans_, CoordTransform *ctrans_,
const proj_transform *proj_trans_, const proj_transform *proj_trans_,
geometry_ptr geom_, geometry2d const& geom_,
SymbolizerT sym); SymbolizerT const& sym);
~placement(); ~placement();
@ -69,7 +62,7 @@ namespace mapnik
CoordTransform *ctrans; CoordTransform *ctrans;
const proj_transform *proj_trans; const proj_transform *proj_trans;
geometry_ptr geom; geometry2d const& geom;
path_type shape_path; path_type shape_path;
double total_distance_; //cache for distance double total_distance_; //cache for distance
@ -80,10 +73,7 @@ namespace mapnik
std::queue< Envelope<double> > envelopes; std::queue< Envelope<double> > envelopes;
//output //output
std::vector<placement_element> placements; boost::ptr_vector<placement_element> placements;
// caching output
placement_element current_placement;
int wrap_width; int wrap_width;
int text_ratio; int text_ratio;

View file

@ -59,6 +59,37 @@ namespace mapnik
Color fill_; Color fill_;
float opacity_; float opacity_;
}; };
struct MAPNIK_DECL building_symbolizer
{
explicit building_symbolizer()
: fill_(Color(128,128,128)),
opacity_(1.0) {}
building_symbolizer(Color const& fill)
: fill_(fill),
opacity_(1.0) {}
Color const& get_fill() const
{
return fill_;
}
void set_fill(Color const& fill)
{
fill_ = fill;
}
void set_opacity(float opacity)
{
opacity_ = opacity;
}
float get_opacity() const
{
return opacity_;
}
private:
Color fill_;
float opacity_;
};
} }
#endif // POLYGON_SYMBOLIZER_HPP #endif // POLYGON_SYMBOLIZER_HPP

View file

@ -88,6 +88,12 @@ namespace mapnik
return (&lhs == &rhs); return (&lhs == &rhs);
} }
inline bool operator==(building_symbolizer const& lhs,
building_symbolizer const& rhs)
{
return (&lhs == &rhs);
}
typedef boost::variant<point_symbolizer, typedef boost::variant<point_symbolizer,
line_symbolizer, line_symbolizer,
line_pattern_symbolizer, line_pattern_symbolizer,
@ -95,7 +101,8 @@ namespace mapnik
polygon_pattern_symbolizer, polygon_pattern_symbolizer,
raster_symbolizer, raster_symbolizer,
shield_symbolizer, shield_symbolizer,
text_symbolizer> symbolizer; text_symbolizer,
building_symbolizer> symbolizer;
typedef std::vector<symbolizer> symbolizers; typedef std::vector<symbolizer> symbolizers;

View file

@ -49,10 +49,7 @@ namespace mapnik
class string_info : private boost::noncopyable class string_info : private boost::noncopyable
{ {
protected: protected:
typedef boost::ptr_vector<character_info> characters_t; typedef boost::ptr_vector<character_info> characters_t;
std::wstring string_; std::wstring string_;
characters_t characters_; characters_t characters_;
@ -100,14 +97,15 @@ namespace mapnik
} }
}; };
struct text_path struct text_path : boost::noncopyable
{ {
struct character_node struct character_node
{ {
int c; int c;
double x, y, angle; double x, y, angle;
character_node(int c_, double x_, double y_, double angle_) : c(c_), x(x_), y(y_), angle(angle_) {} character_node(int c_, double x_, double y_, double angle_)
: c(c_), x(x_), y(y_), angle(angle_) {}
~character_node() {} ~character_node() {}
void vertex(int *c_, double *x_, double *y_, double *angle_) void vertex(int *c_, double *x_, double *y_, double *angle_)
@ -120,18 +118,23 @@ namespace mapnik
}; };
typedef std::vector<character_node> character_nodes_t; typedef std::vector<character_node> character_nodes_t;
double starting_x;
double starting_y;
character_nodes_t nodes_; character_nodes_t nodes_;
int itr_; int itr_;
std::pair<unsigned,unsigned> string_dimensions; std::pair<unsigned,unsigned> string_dimensions;
text_path() : itr_(0) {} text_path()
text_path(const text_path & other) : itr_(0) : starting_x(0),
{ starting_y(0),
nodes_ = other.nodes_; itr_(0) {}
string_dimensions = other.string_dimensions;
} //text_path(text_path const& other) :
// itr_(0),
// nodes_(other.nodes_),
// string_dimensions(other.string_dimensions)
//{}
~text_path() {} ~text_path() {}

View file

@ -27,13 +27,13 @@
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/ctrans.hpp> #include <mapnik/ctrans.hpp>
#include <mapnik/feature.hpp>
namespace mapnik namespace mapnik
{ {
class MAPNIK_DECL geometry_utils class MAPNIK_DECL geometry_utils
{ {
public: public:
static geometry_ptr from_wkb(const char* wkb, unsigned size); static void from_wkb(Feature & feature,const char* wkb, unsigned size);
private: private:
geometry_utils(); geometry_utils();
geometry_utils(geometry_utils const&); geometry_utils(geometry_utils const&);

View file

@ -34,6 +34,8 @@ gdal_src = Split(
libraries = ['gdal' ] libraries = ['gdal' ]
if env['PLATFORM'] == 'Darwin': if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik') libraries.append('mapnik')
libraries.append('iconv')
if env['BIDI'] : libraries.append('fribidi')
gdal_inputdriver = env.SharedLibrary('gdal', source=gdal_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries) gdal_inputdriver = env.SharedLibrary('gdal', source=gdal_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries)

View file

@ -33,7 +33,7 @@ using boost::bad_lexical_cast;
using boost::trim; using boost::trim;
using std::string; using std::string;
using mapnik::Feature; using mapnik::Feature;
using mapnik::geometry_ptr; using mapnik::geometry2d;
using mapnik::byte; using mapnik::byte;
using mapnik::geometry_utils; using mapnik::geometry_utils;
@ -53,13 +53,9 @@ feature_ptr postgis_featureset::next()
feature_ptr feature(new Feature(count_)); feature_ptr feature(new Feature(count_));
int size=rs_->getFieldLength(0); int size=rs_->getFieldLength(0);
const char *data = rs_->getValue(0); const char *data = rs_->getValue(0);
geometry_ptr geom = geometry_utils::from_wkb(data,size); geometry_utils::from_wkb(*feature,data,size);
totalGeomSize_+=size; totalGeomSize_+=size;
if (geom)
{
feature->set_geometry(geom);
for (unsigned pos=1;pos<num_attrs_+1;++pos) for (unsigned pos=1;pos<num_attrs_+1;++pos)
{ {
std::string name = rs_->getFieldName(pos); std::string name = rs_->getFieldName(pos);
@ -104,7 +100,6 @@ feature_ptr postgis_featureset::next()
} }
} }
++count_; ++count_;
}
return feature; return feature;
} }
else else

View file

@ -35,6 +35,7 @@ raster_src = Split(
libraries = [] libraries = []
if env['PLATFORM'] == 'Darwin': if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik') libraries.append('mapnik')
if env['BIDI'] : libraries.append('fribidi')
raster_inputdriver = env.SharedLibrary('raster', source=raster_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries) raster_inputdriver = env.SharedLibrary('raster', source=raster_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries)

View file

@ -41,6 +41,8 @@ libraries = []
if env['PLATFORM'] == 'Darwin': if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik') libraries.append('mapnik')
libraries.append('iconv') libraries.append('iconv')
if env['BIDI'] : libraries.append('fribidi')
shape_inputdriver = env.SharedLibrary('shape', SHLIBSUFFIX='.input', source=shape_src, SHLIBPREFIX='', LIBS = libraries) shape_inputdriver = env.SharedLibrary('shape', SHLIBSUFFIX='.input', source=shape_src, SHLIBPREFIX='', LIBS = libraries)

View file

@ -40,8 +40,8 @@ using mapnik::attribute_descriptor;
shape_datasource::shape_datasource(const parameters &params) shape_datasource::shape_datasource(const parameters &params)
: datasource (params), : datasource (params),
shape_name_(*params_.get<std::string>("file","")),
type_(datasource::Vector), type_(datasource::Vector),
shape_name_(*params_.get<std::string>("file","")),
file_length_(0), file_length_(0),
indexed_(false), indexed_(false),
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8")) desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding","utf-8"))

View file

@ -1,3 +1,4 @@
/***************************************************************************** /*****************************************************************************
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
@ -71,9 +72,9 @@ feature_ptr shape_featureset<filterT>::next()
{ {
double x=shape_.shp().read_double(); double x=shape_.shp().read_double();
double y=shape_.shp().read_double(); double y=shape_.shp().read_double();
geometry_ptr point(new point_impl); geometry2d * point = new point_impl;
point->move_to(x,y); point->move_to(x,y);
feature->set_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointm) else if (type == shape_io::shape_pointm)
@ -81,9 +82,9 @@ feature_ptr shape_featureset<filterT>::next()
double x=shape_.shp().read_double(); double x=shape_.shp().read_double();
double y=shape_.shp().read_double(); double y=shape_.shp().read_double();
shape_.shp().read_double();//m shape_.shp().read_double();//m
geometry_ptr point(new point_impl); geometry2d * point = new point_impl;
point->move_to(x,y); point->move_to(x,y);
feature->set_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointz) else if (type == shape_io::shape_pointz)
@ -92,9 +93,9 @@ feature_ptr shape_featureset<filterT>::next()
double y=shape_.shp().read_double(); double y=shape_.shp().read_double();
shape_.shp().read_double();//z shape_.shp().read_double();//z
shape_.shp().read_double();//m shape_.shp().read_double();//m
geometry_ptr point(new point_impl); geometry2d * point=new point_impl;
point->move_to(x,y); point->move_to(x,y);
feature->set_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else else
@ -119,43 +120,43 @@ feature_ptr shape_featureset<filterT>::next()
case shape_io::shape_polyline: case shape_io::shape_polyline:
{ {
geometry_ptr line = shape_.read_polyline(); geometry2d * line = shape_.read_polyline();
feature->set_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinem: case shape_io::shape_polylinem:
{ {
geometry_ptr line = shape_.read_polylinem(); geometry2d * line = shape_.read_polylinem();
feature->set_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinez: case shape_io::shape_polylinez:
{ {
geometry_ptr line = shape_.read_polylinez(); geometry2d * line = shape_.read_polylinez();
feature->set_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygon: case shape_io::shape_polygon:
{ {
geometry_ptr poly = shape_.read_polygon(); geometry2d * poly = shape_.read_polygon();
feature->set_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonm: case shape_io::shape_polygonm:
{ {
geometry_ptr poly = shape_.read_polygonm(); geometry2d * poly = shape_.read_polygonm();
feature->set_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonz: case shape_io::shape_polygonz:
{ {
geometry_ptr poly = shape_.read_polygonz(); geometry2d * poly = shape_.read_polygonz();
feature->set_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }

View file

@ -85,9 +85,9 @@ feature_ptr shape_index_featureset<filterT>::next()
{ {
double x=shape_.shp().read_double(); double x=shape_.shp().read_double();
double y=shape_.shp().read_double(); double y=shape_.shp().read_double();
geometry_ptr point(new point_impl); geometry2d * point = new point_impl;
point->move_to(x,y); point->move_to(x,y);
feature->set_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointm) else if (type == shape_io::shape_pointm)
@ -95,9 +95,9 @@ feature_ptr shape_index_featureset<filterT>::next()
double x=shape_.shp().read_double(); double x=shape_.shp().read_double();
double y=shape_.shp().read_double(); double y=shape_.shp().read_double();
shape_.shp().read_double();// m shape_.shp().read_double();// m
geometry_ptr point(new point_impl); geometry2d * point = new point_impl;
point->move_to(x,y); point->move_to(x,y);
feature->set_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else if (type == shape_io::shape_pointz) else if (type == shape_io::shape_pointz)
@ -106,9 +106,9 @@ feature_ptr shape_index_featureset<filterT>::next()
double y=shape_.shp().read_double(); double y=shape_.shp().read_double();
shape_.shp().read_double();// z shape_.shp().read_double();// z
shape_.shp().read_double();// m shape_.shp().read_double();// m
geometry_ptr point(new point_impl); geometry2d * point = new point_impl;
point->move_to(x,y); point->move_to(x,y);
feature->set_geometry(point); feature->add_geometry(point);
++count_; ++count_;
} }
else else
@ -124,44 +124,44 @@ feature_ptr shape_index_featureset<filterT>::next()
{ {
case shape_io::shape_polyline: case shape_io::shape_polyline:
{ {
geometry_ptr line = shape_.read_polyline(); geometry2d * line = shape_.read_polyline();
feature->set_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinem: case shape_io::shape_polylinem:
{ {
geometry_ptr line = shape_.read_polylinem(); geometry2d * line = shape_.read_polylinem();
feature->set_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polylinez: case shape_io::shape_polylinez:
{ {
geometry_ptr line = shape_.read_polylinez(); geometry2d * line = shape_.read_polylinez();
feature->set_geometry(line); feature->add_geometry(line);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygon: case shape_io::shape_polygon:
{ {
geometry_ptr poly = shape_.read_polygon(); geometry2d * poly = shape_.read_polygon();
feature->set_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonm: case shape_io::shape_polygonm:
{ {
geometry_ptr poly = shape_.read_polygonm(); geometry2d * poly = shape_.read_polygonm();
feature->set_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }
case shape_io::shape_polygonz: case shape_io::shape_polygonz:
{ {
geometry_ptr poly = shape_.read_polygonz(); geometry2d * poly = shape_.read_polygonz();
feature->set_geometry(poly); feature->add_geometry(poly);
++count_; ++count_;
break; break;
} }

View file

@ -89,14 +89,14 @@ dbf_file& shape_io::dbf()
return dbf_; return dbf_;
} }
geometry_ptr shape_io::read_polyline() geometry2d * shape_io::read_polyline()
{ {
using mapnik::line_string_impl; using mapnik::line_string_impl;
shape_record record(reclength_*2-36); shape_record record(reclength_*2-36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer(); int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_points=record.read_ndr_integer();
geometry_ptr line(new line_string_impl); geometry2d * line = new line_string_impl;
line->set_capacity(num_points + num_parts); line->set_capacity(num_points + num_parts);
if (num_parts == 1) if (num_parts == 1)
{ {
@ -144,14 +144,14 @@ geometry_ptr shape_io::read_polyline()
return line; return line;
} }
geometry_ptr shape_io::read_polylinem() geometry2d * shape_io::read_polylinem()
{ {
using mapnik::line_string_impl; using mapnik::line_string_impl;
shape_record record(reclength_*2-36); shape_record record(reclength_*2-36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer(); int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_points=record.read_ndr_integer();
geometry_ptr line(new line_string_impl); geometry2d * line = new line_string_impl;
line->set_capacity(num_points + num_parts); line->set_capacity(num_points + num_parts);
if (num_parts == 1) if (num_parts == 1)
{ {
@ -207,14 +207,14 @@ geometry_ptr shape_io::read_polylinem()
return line; return line;
} }
geometry_ptr shape_io::read_polylinez() geometry2d * shape_io::read_polylinez()
{ {
using mapnik::line_string_impl; using mapnik::line_string_impl;
shape_record record(reclength_*2-36); shape_record record(reclength_*2-36);
shp_.read_record(record); shp_.read_record(record);
int num_parts=record.read_ndr_integer(); int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_points=record.read_ndr_integer();
geometry_ptr line(new line_string_impl); geometry2d * line = new line_string_impl;
line->set_capacity(num_points + num_parts); line->set_capacity(num_points + num_parts);
if (num_parts == 1) if (num_parts == 1)
{ {
@ -277,7 +277,7 @@ geometry_ptr shape_io::read_polylinez()
return line; return line;
} }
geometry_ptr shape_io::read_polygon() geometry2d * shape_io::read_polygon()
{ {
using mapnik::polygon_impl; using mapnik::polygon_impl;
shape_record record(reclength_*2-36); shape_record record(reclength_*2-36);
@ -285,7 +285,7 @@ geometry_ptr shape_io::read_polygon()
int num_parts=record.read_ndr_integer(); int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts); std::vector<int> parts(num_parts);
geometry_ptr poly(new polygon_impl); geometry2d * poly = new polygon_impl;
poly->set_capacity(num_points + num_parts); poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i) for (int i=0;i<num_parts;++i)
{ {
@ -318,7 +318,7 @@ geometry_ptr shape_io::read_polygon()
return poly; return poly;
} }
geometry_ptr shape_io::read_polygonm() geometry2d * shape_io::read_polygonm()
{ {
using mapnik::polygon_impl; using mapnik::polygon_impl;
shape_record record(reclength_*2-36); shape_record record(reclength_*2-36);
@ -326,7 +326,7 @@ geometry_ptr shape_io::read_polygonm()
int num_parts=record.read_ndr_integer(); int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts); std::vector<int> parts(num_parts);
geometry_ptr poly(new polygon_impl); geometry2d * poly = new polygon_impl;
poly->set_capacity(num_points + num_parts); poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i) for (int i=0;i<num_parts;++i)
{ {
@ -367,7 +367,7 @@ geometry_ptr shape_io::read_polygonm()
return poly; return poly;
} }
geometry_ptr shape_io::read_polygonz() geometry2d * shape_io::read_polygonz()
{ {
using mapnik::polygon_impl; using mapnik::polygon_impl;
shape_record record(reclength_*2-36); shape_record record(reclength_*2-36);
@ -375,7 +375,7 @@ geometry_ptr shape_io::read_polygonz()
int num_parts=record.read_ndr_integer(); int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer(); int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts); std::vector<int> parts(num_parts);
geometry_ptr poly(new polygon_impl); geometry2d * poly=new polygon_impl;
poly->set_capacity(num_points + num_parts); poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i) for (int i=0;i<num_parts;++i)
{ {

View file

@ -27,7 +27,7 @@
#include "shapefile.hpp" #include "shapefile.hpp"
#include "shp_index.hpp" #include "shp_index.hpp"
using mapnik::geometry_ptr; using mapnik::geometry2d;
struct shape_io struct shape_io
{ {
@ -70,14 +70,13 @@ public:
void move_to(int id); void move_to(int id);
int type() const; int type() const;
const Envelope<double>& current_extent() const; const Envelope<double>& current_extent() const;
geometry2d * read_polyline();
geometry_ptr read_polyline(); geometry2d * read_polylinem();
geometry_ptr read_polylinem(); geometry2d * read_polylinez();
geometry_ptr read_polylinez(); geometry2d * read_polygon();
geometry_ptr read_polygon(); geometry2d * read_polygonm();
geometry_ptr read_polygonm(); geometry2d * read_polygonz();
geometry_ptr read_polygonz(); private:
private:
//void read_record(const shape_record& record); //void read_record(const shape_record& record);
// no copying // no copying
shape_io(const shape_io&); shape_io(const shape_io&);

View file

@ -25,14 +25,16 @@
#include <iostream> #include <iostream>
// boost // boost
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/tuple/tuple.hpp>
// agg // agg
#include "agg_basics.h" #include "agg_basics.h"
#include "agg_rendering_buffer.h" //#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h" //#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h" #include "agg_scanline_p.h"
#include "agg_scanline_u.h" #include "agg_scanline_u.h"
#include "agg_renderer_scanline.h" #include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgba.h" //#include "agg_pixfmt_rgba.h"
#include "agg_path_storage.h" #include "agg_path_storage.h"
#include "agg_span_allocator.h" #include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h" #include "agg_span_pattern_rgba.h"
@ -93,6 +95,10 @@ namespace mapnik
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, unsigned offset_x, unsigned offset_y) agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, unsigned offset_x, unsigned offset_y)
: feature_style_processor<agg_renderer>(m), : feature_style_processor<agg_renderer>(m),
pixmap_(pixmap), pixmap_(pixmap),
width_(pixmap_.width()),
height_(pixmap_.height()),
buf_(pixmap_.raw_data(),width_,height_, width_ * 4),
pixf_(buf_),
t_(m.getWidth(),m.getHeight(),m.getCurrentExtent(),offset_x,offset_y), t_(m.getWidth(),m.getHeight(),m.getCurrentExtent(),offset_x,offset_y),
detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64)), detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64)),
finder_(detector_,Envelope<double>(0 ,0, m.getWidth(), m.getHeight())) finder_(detector_,Envelope<double>(0 ,0, m.getWidth(), m.getHeight()))
@ -111,6 +117,7 @@ namespace mapnik
std::clog << "start map processing bbox=" std::clog << "start map processing bbox="
<< map.getCurrentExtent() << "\n"; << map.getCurrentExtent() << "\n";
#endif #endif
ras_.clip_box(0,0,width_,height_);
} }
template <typename T> template <typename T>
@ -147,33 +154,141 @@ namespace mapnik
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry2d> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer; typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
Color const& fill_ = sym.get_fill(); Color const& fill_ = sym.get_fill();
ras_.reset();
geometry_ptr const& geom=feature.get_geometry(); agg::scanline_u8 sl;
if (geom && geom->num_points() > 2) ren_base renb(pixf_);
{
unsigned width = pixmap_.width();
unsigned height = pixmap_.height();
path_type path(t_,*geom,prj_trans);
agg::row_accessor<agg::int8u> buf(pixmap_.raw_data(),width,height,width * 4);
agg::pixfmt_rgba32 pixf(buf);
ren_base renb(pixf);
unsigned r=fill_.red(); unsigned r=fill_.red();
unsigned g=fill_.green(); unsigned g=fill_.green();
unsigned b=fill_.blue(); unsigned b=fill_.blue();
renderer ren(renb); renderer ren(renb);
for (unsigned i=0;i<feature.num_geometries();++i)
agg::rasterizer_scanline_aa<> ras; {
agg::scanline_u8 sl; geometry2d const& geom=feature.get_geometry(i);
ras.clip_box(0,0,width,height); if (geom.num_points() > 2)
ras.add_path(path); {
path_type path(t_,geom,prj_trans);
ras_.add_path(path);
}
}
ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity()))); ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity())));
agg::render_scanlines(ras, sl, ren); agg::render_scanlines(ras_, 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> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
ren_base renb(pixf_);
Color const& fill_ = sym.get_fill();
unsigned r=fill_.red();
unsigned g=fill_.green();
unsigned b=fill_.blue();
renderer ren(renb);
agg::scanline_u8 sl;
ras_.reset();
int height = 60 << 8;
for (unsigned i=0;i<feature.num_geometries();++i)
{
geometry2d const& geom = feature.get_geometry(i);
if (geom.num_points() > 2)
{
boost::scoped_ptr<geometry2d> frame(new line_string_impl);
boost::scoped_ptr<geometry2d> roof(new polygon_impl);
std::deque<segment_t> face_segments;
double x0,y0;
for (unsigned j=0;j<geom.num_points();++j)
{
double x,y;
unsigned cm = geom.vertex(&x,&y);
if (cm == SEG_MOVETO)
{
frame->move_to(x,y);
}
else if (cm == SEG_LINETO)
{
frame->line_to(x,y);
}
if (j!=0)
{
face_segments.push_back(segment_t(x0,y0,x,y));
}
x0 = x;
y0 = y;
}
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)
{
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_.add_path(faces_path);
ren.color(agg::rgba8(int(r*0.7), int(g*0.7), int(b*0.7), int(255 * sym.get_opacity())));
agg::render_scanlines(ras_, sl, ren);
ras_.reset();
frame->move_to(itr->get<0>(),itr->get<1>());
frame->line_to(itr->get<0>(),itr->get<1>()+height);
}
geom.rewind(0);
for (unsigned j=0;j<geom.num_points();++j)
{
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);
}
}
path_type path(t_,*frame,prj_trans);
agg::conv_stroke<path_type> stroke(path);
ras_.add_path(stroke);
ren.color(agg::rgba8(128, 128, 128, int(255 * sym.get_opacity())));
agg::render_scanlines(ras_, sl, ren);
ras_.reset();
path_type roof_path (t_,*roof,prj_trans);
ras_.add_path(roof_path);
ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity())));
agg::render_scanlines(ras_, sl, ren);
}
} }
} }
@ -183,43 +298,39 @@ namespace mapnik
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry2d> path_type;
typedef agg::renderer_outline_aa<ren_base> renderer_oaa; typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa; typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer; typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
geometry_ptr const& geom=feature.get_geometry(); ren_base renb(pixf_);
if (geom && geom->num_points() > 1)
{
path_type path(t_,*geom,prj_trans);
agg::row_accessor<agg::int8u> buf(pixmap_.raw_data(),
pixmap_.width(),
pixmap_.height(),
pixmap_.width()*4);
agg::pixfmt_rgba32 pixf(buf);
ren_base renb(pixf);
mapnik::stroke const& stroke_ = sym.get_stroke(); mapnik::stroke const& stroke_ = sym.get_stroke();
Color const& col = stroke_.get_color(); Color const& col = stroke_.get_color();
unsigned r=col.red(); unsigned r=col.red();
unsigned g=col.green(); unsigned g=col.green();
unsigned b=col.blue(); unsigned b=col.blue();
renderer ren(renb);
ras_.reset();
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)
{
path_type path(t_,geom,prj_trans);
if (stroke_.has_dash()) if (stroke_.has_dash())
{ {
renderer ren(renb);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::conv_dash<path_type> dash(path); agg::conv_dash<path_type> dash(path);
dash_array const& d = stroke_.get_dash_array(); dash_array const& d = stroke_.get_dash_array();
dash_array::const_iterator itr = d.begin(); dash_array::const_iterator itr = d.begin();
dash_array::const_iterator end = d.end(); dash_array::const_iterator end = d.end();
while (itr != end) for (;itr != end;++itr)
{ {
dash.add_dash(itr->first, itr->second); dash.add_dash(itr->first, itr->second);
++itr;
} }
agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash); agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
line_join_e join=stroke_.get_line_join(); line_join_e join=stroke_.get_line_join();
@ -243,28 +354,11 @@ namespace mapnik
stroke.generator().miter_limit(4.0); stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width()); stroke.generator().width(stroke_.get_width());
ras.clip_box(0,0,pixmap_.width(),pixmap_.height()); ras_.add_path(stroke);
ras.add_path(stroke);
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
agg::render_scanlines(ras, sl, ren);
} }
//else if (stroke_.get_width() <= 1.0)
//{
// agg::line_profile_aa prof;
// prof.width(stroke_.get_width());
// renderer_oaa ren_oaa(renb, prof);
// rasterizer_outline_aa ras_oaa(ren_oaa);
// ren_oaa.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
// ren_oaa.clip_box(0,0,pixmap_.width(),pixmap_.height());
// ras_oaa.add_path(path);
// }
else else
{ {
renderer ren(renb);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
agg::conv_stroke<path_type> stroke(path); agg::conv_stroke<path_type> stroke(path);
line_join_e join=stroke_.get_line_join(); line_join_e join=stroke_.get_line_join();
@ -287,22 +381,18 @@ namespace mapnik
stroke.generator().miter_limit(4.0); stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_.get_width()); stroke.generator().width(stroke_.get_width());
ras_.add_path(stroke);
ras.clip_box(0,0,pixmap_.width(),pixmap_.height()); }
ras.add_path(stroke); }
}
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity()))); ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
agg::render_scanlines(ras, sl, ren); agg::render_scanlines(ras_, sl, ren);
}
}
} }
template <typename T> template <typename T>
void agg_renderer<T>::process(point_symbolizer const& sym, void agg_renderer<T>::process(point_symbolizer const& sym,
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{
geometry_ptr const& geom=feature.get_geometry();
if (geom)
{ {
double x; double x;
double y; double y;
@ -310,7 +400,11 @@ namespace mapnik
boost::shared_ptr<ImageData32> const& data = sym.get_data(); boost::shared_ptr<ImageData32> const& data = sym.get_data();
if ( data ) if ( data )
{ {
geom->label_position(&x,&y); for (unsigned i=0;i<feature.num_geometries();++i)
{
geometry2d const& geom = feature.get_geometry(i);
geom.label_position(&x,&y);
prj_trans.backward(x,y,z); prj_trans.backward(x,y,z);
t_.forward(&x,&y); t_.forward(&x,&y);
int w = data->width(); int w = data->width();
@ -335,13 +429,9 @@ namespace mapnik
void agg_renderer<T>::process(shield_symbolizer const& sym, void agg_renderer<T>::process(shield_symbolizer const& sym,
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 0)
{ {
std::wstring text = feature[sym.get_name()].to_unicode(); std::wstring text = feature[sym.get_name()].to_unicode();
boost::shared_ptr<ImageData32> const& data = sym.get_background_image(); boost::shared_ptr<ImageData32> const& data = sym.get_background_image();
if (text.length() > 0 && data) if (text.length() > 0 && data)
{ {
face_ptr face = font_manager_.get_face(sym.get_face_name()); face_ptr face = font_manager_.get_face(sym.get_face_name());
@ -350,10 +440,14 @@ namespace mapnik
text_renderer<mapnik::Image32> ren(pixmap_,face); text_renderer<mapnik::Image32> ren(pixmap_,face);
ren.set_pixel_size(sym.get_text_size()); ren.set_pixel_size(sym.get_text_size());
ren.set_fill(sym.get_fill()); ren.set_fill(sym.get_fill());
string_info info(text); string_info info(text);
ren.get_string_info(&info); ren.get_string_info(&info);
unsigned num_geom = feature.num_geometries();
for (unsigned i=0;i<num_geom;++i)
{
geometry2d const& geom = feature.get_geometry(i);
if (geom.num_points() > 0) // don't bother with empty geometries
{
placement text_placement(&info, &t_, &prj_trans, geom, sym); placement text_placement(&info, &t_, &prj_trans, geom, sym);
text_placement.avoid_edges = sym.get_avoid_edges(); text_placement.avoid_edges = sym.get_avoid_edges();
@ -372,7 +466,7 @@ namespace mapnik
pixmap_.set_rectangle_alpha(px,py,*data); pixmap_.set_rectangle_alpha(px,py,*data);
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii].path); Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
ren.render(x,y); ren.render(x,y);
} }
@ -380,48 +474,51 @@ namespace mapnik
} }
} }
} }
}
template <typename T> template <typename T>
void agg_renderer<T>::process(line_pattern_symbolizer const& sym, void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry2d> path_type;
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type; typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> renderer_base; typedef agg::renderer_base<agg::pixfmt_rgba32> renderer_base;
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type; typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 1)
{
unsigned width = pixmap_.width();
unsigned height = pixmap_.height();
ImageData32 const& pat = sym.get_pattern(); ImageData32 const& pat = sym.get_pattern();
path_type path(t_,*geom,prj_trans); renderer_base ren_base(pixf_);
agg::row_accessor<agg::int8u> buf(pixmap_.raw_data(), width, height,width*4);
agg::pixfmt_rgba32 pixf(buf);
renderer_base ren_base(pixf);
agg::pattern_filter_bilinear_rgba8 filter; agg::pattern_filter_bilinear_rgba8 filter;
pattern_source source(pat); pattern_source source(pat);
pattern_type pattern (filter,source); pattern_type pattern (filter,source);
renderer_type ren(ren_base, pattern); renderer_type ren(ren_base, pattern);
ren.clip_box(0,0,width,height); ren.clip_box(0,0,width_,height_);
rasterizer_type ras(ren); 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)
{
path_type path(t_,geom,prj_trans);
ras.add_path(path); ras.add_path(path);
} }
} }
}
template <typename T> template <typename T>
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym, void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry2d> path_type;
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base; typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
typedef agg::wrap_mode_repeat wrap_x_type; typedef agg::wrap_mode_repeat wrap_x_type;
typedef agg::wrap_mode_repeat wrap_y_type; typedef agg::wrap_mode_repeat wrap_y_type;
typedef agg::image_accessor_wrap<agg::pixfmt_rgba32, 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_x_type,
wrap_y_type> img_source_type; wrap_y_type> img_source_type;
@ -430,43 +527,42 @@ namespace mapnik
typedef agg::renderer_scanline_aa<ren_base, typedef agg::renderer_scanline_aa<ren_base,
agg::span_allocator<agg::rgba8>, agg::span_allocator<agg::rgba8>,
span_gen_type> renderer_type; span_gen_type> renderer_type;
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 2) ras_.reset();
{ ren_base renb(pixf_);
agg::scanline_u8 sl;
ImageData32 const& pattern = sym.get_pattern(); ImageData32 const& pattern = sym.get_pattern();
unsigned width = pixmap_.width();
unsigned height = pixmap_.height();
path_type path(t_,*geom,prj_trans);
agg::row_accessor<agg::int8u> buf(pixmap_.raw_data(),width,height,width * 4);
agg::pixfmt_rgba32 pixf(buf);
ren_base renb(pixf);
unsigned w=pattern.width(); unsigned w=pattern.width();
unsigned h=pattern.height(); unsigned h=pattern.height();
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.getBytes(),w,h,w*4); agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.getBytes(),w,h,w*4);
double x0,y0;
path.vertex(&x0,&y0);
path.rewind(0);
unsigned offset_x = unsigned(width - x0);
unsigned offset_y = unsigned(height - y0);
agg::span_allocator<agg::rgba8> sa; agg::span_allocator<agg::rgba8> sa;
agg::pixfmt_rgba32 pixf_pattern(pattern_rbuf); 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); 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); span_gen_type sg(img_src, offset_x, offset_y);
renderer_type rp(renb,sa, sg); renderer_type rp(renb,sa, sg);
for (unsigned i=0;i<num_geometries;++i)
agg::rasterizer_scanline_aa<> ras; {
agg::scanline_u8 sl; geometry2d const& geom = feature.get_geometry(i);
ras.clip_box(0,0,width,height); if (geom.num_points() > 2)
ras.add_path(path); {
agg::render_scanlines(ras, sl, rp); path_type path(t_,geom,prj_trans);
ras_.add_path(path);
} }
} }
agg::render_scanlines(ras_, sl, rp);
}
template <typename T> template <typename T>
void agg_renderer<T>::process(raster_symbolizer const&, void agg_renderer<T>::process(raster_symbolizer const&,
@ -480,7 +576,7 @@ namespace mapnik
if (raster) if (raster)
{ {
Envelope<double> ext=t_.forward(raster->ext_); Envelope<double> ext=t_.forward(raster->ext_);
ImageData32 target((int)(ext.width() + 0.5),(int)(ext.height() + 0.5)); ImageData32 target(int(ext.width() + 0.5),int(ext.height() + 0.5));
scale_image<ImageData32>(target,raster->data_); scale_image<ImageData32>(target,raster->data_);
pixmap_.set_rectangle(int(ext.minx()),int(ext.miny()),target); pixmap_.set_rectangle(int(ext.minx()),int(ext.miny()),target);
} }
@ -491,10 +587,7 @@ namespace mapnik
Feature const& feature, Feature const& feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 0)
{
std::wstring text = feature[sym.get_name()].to_unicode(); std::wstring text = feature[sym.get_name()].to_unicode();
if ( text.length() > 0 ) if ( text.length() > 0 )
{ {
@ -510,22 +603,25 @@ namespace mapnik
string_info info(text); string_info info(text);
ren.get_string_info(&info); ren.get_string_info(&info);
unsigned num_geom = feature.num_geometries();
for (unsigned i=0;i<num_geom;++i)
{
geometry2d const& geom = feature.get_geometry(i);
if (geom.num_points() > 0) // don't bother with empty geometries
{
placement text_placement(&info, &t_, &prj_trans, geom, sym); placement text_placement(&info, &t_, &prj_trans, geom, sym);
finder_.find_placements(&text_placement); finder_.find_placements(&text_placement);
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
{ {
double x = text_placement.placements[ii].starting_x; double x = text_placement.placements[ii].starting_x;
double y = text_placement.placements[ii].starting_y; double y = text_placement.placements[ii].starting_y;
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii].path); Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
ren.render(x,y); ren.render(x,y);
} }
} }
} }
} }
} }
}
template class agg_renderer<Image32>; template class agg_renderer<Image32>;
} }

View file

@ -167,7 +167,7 @@ namespace mapnik
} }
template <typename T> template <typename T>
bool Envelope<T>::intersects(T x,T y) const inline bool Envelope<T>::intersects(T x,T y) const
{ {
return !(x>maxx_ || x<minx_ || y>maxy_ || y<miny_); return !(x>maxx_ || x<minx_ || y>maxy_ || y<miny_);
} }

View file

@ -441,6 +441,40 @@ namespace mapnik
} }
rule.append(poly_sym); rule.append(poly_sym);
} }
else if ( sym.first == "BuildingSymbolizer")
{
building_symbolizer building_sym;
ptree::const_iterator cssIter = sym.second.begin();
ptree::const_iterator endCss = sym.second.end();
for(; cssIter != endCss; ++cssIter)
{
ptree::value_type const& css = * cssIter;
std::string css_name =
css.second.get<std::string>("<xmlattr>.name");
std::string data = css.second.data();
if (css_name == "fill")
{
Color c = color_factory::from_string(css.second.data().c_str());
building_sym.set_fill(c);
}
else if (css_name == "fill-opacity")
{
try
{
float opacity = lexical_cast<float>(data);
building_sym.set_opacity(opacity);
}
catch (bad_lexical_cast & ex)
{
std::clog << ex.what() << "\n";
}
}
}
rule.append(building_sym);
}
else if ( sym.first == "RasterSymbolizer") else if ( sym.first == "RasterSymbolizer")
{ {
rule.append(raster_symbolizer()); rule.append(raster_symbolizer());

View file

@ -267,7 +267,7 @@ namespace mapnik
} }
catch (proj_init_error & ex) catch (proj_init_error & ex)
{ {
std::clog << ex.what() << '\n'; std::clog << "proj_init_error:" << ex.what() << '\n';
} }
} }

View file

@ -33,16 +33,18 @@ namespace mapnik {
void operator() (feature_ptr feat) void operator() (feature_ptr feat)
{ {
geometry_ptr geom = feat->get_geometry(); for (unsigned i=0;i<feat->num_geometries();++i)
if ( !geom ) return; {
geometry2d & geom = feat->get_geometry(i);
if ( first_ ) if ( first_ )
{ {
first_ = false; first_ = false;
ext_ = geom->envelope(); ext_ = geom.envelope();
} }
else else
{ {
ext_.expand_to_include(geom->envelope()); ext_.expand_to_include(geom.envelope());
}
} }
} }

View file

@ -51,13 +51,13 @@ namespace mapnik
placement::placement(string_info *info_, placement::placement(string_info *info_,
CoordTransform *ctrans_, CoordTransform *ctrans_,
const proj_transform *proj_trans_, const proj_transform *proj_trans_,
geometry_ptr geom_, geometry2d const& geom_,
shield_symbolizer sym) shield_symbolizer const& sym)
: info(info_), : info(info_),
ctrans(ctrans_), ctrans(ctrans_),
proj_trans(proj_trans_), proj_trans(proj_trans_),
geom(geom_), geom(geom_),
shape_path(*ctrans_, *geom_, *proj_trans_), shape_path(*ctrans_, geom_, *proj_trans_),
total_distance_(-1.0), total_distance_(-1.0),
displacement_(sym.get_displacement()), displacement_(sym.get_displacement()),
label_placement(sym.get_label_placement()), label_placement(sym.get_label_placement()),
@ -79,13 +79,13 @@ namespace mapnik
placement::placement(string_info *info_, placement::placement(string_info *info_,
CoordTransform *ctrans_, CoordTransform *ctrans_,
const proj_transform *proj_trans_, const proj_transform *proj_trans_,
geometry_ptr geom_, geometry2d const& geom_,
text_symbolizer sym) text_symbolizer const& sym)
: info(info_), : info(info_),
ctrans(ctrans_), ctrans(ctrans_),
proj_trans(proj_trans_), proj_trans(proj_trans_),
geom(geom_), geom(geom_),
shape_path(*ctrans_, *geom_, *proj_trans_), shape_path(*ctrans_, geom_, *proj_trans_),
total_distance_(-1.0), total_distance_(-1.0),
displacement_(sym.get_displacement()), displacement_(sym.get_displacement()),
label_placement(sym.get_label_placement()), label_placement(sym.get_label_placement()),
@ -109,7 +109,7 @@ namespace mapnik
unsigned placement::path_size() const unsigned placement::path_size() const
{ {
return geom->num_points(); return geom.num_points();
} }
std::pair<double, double> placement::get_position_at_distance(double target_distance) std::pair<double, double> placement::get_position_at_distance(double target_distance)
@ -122,7 +122,7 @@ namespace mapnik
shape_path.rewind(0); shape_path.rewind(0);
shape_path.vertex(&new_x,&new_y); shape_path.vertex(&new_x,&new_y);
unsigned num_points = geom->num_points(); unsigned num_points = geom.num_points();
for (unsigned i = 1; i < num_points; ++i) for (unsigned i = 1; i < num_points; ++i)
{ {
double dx, dy; double dx, dy;
@ -162,7 +162,7 @@ namespace mapnik
total_distance_ = 0.0; total_distance_ = 0.0;
unsigned num_points = geom->num_points(); unsigned num_points = geom.num_points();
for (unsigned i = 1; i < num_points ; ++i) for (unsigned i = 1; i < num_points ; ++i)
{ {
double dx, dy; double dx, dy;
@ -328,7 +328,8 @@ namespace mapnik
int orientation = 0; int orientation = 0;
double displacement = boost::tuples::get<1>(p->displacement_); // displace by dy double displacement = boost::tuples::get<1>(p->displacement_); // displace by dy
p->current_placement.path.clear(); //p->current_placement.clear(); //TODO !!
std::auto_ptr<placement_element> current_placement(new placement_element);
double x, y; double x, y;
x = y = 0.0; x = y = 0.0;
@ -344,7 +345,7 @@ namespace mapnik
p->shape_path.vertex(&new_x,&new_y); p->shape_path.vertex(&new_x,&new_y);
old_x = new_x; old_x = new_x;
old_y = new_y; old_y = new_y;
unsigned num_points = p->geom->num_points(); unsigned num_points = p->geom.num_points();
for (unsigned i = 1; i < num_points; ++i) for (unsigned i = 1; i < num_points; ++i)
{ {
double dx, dy; double dx, dy;
@ -365,8 +366,8 @@ namespace mapnik
if (distance > target_distance) if (distance > target_distance)
{ {
// this segment is greater that the target starting distance so start here // this segment is greater that the target starting distance so start here
p->current_placement.starting_x = new_x - dx*(distance - target_distance)/segment_length; current_placement->starting_x = new_x - dx*(distance - target_distance)/segment_length;
p->current_placement.starting_y = new_y - dy*(distance - target_distance)/segment_length; current_placement->starting_y = new_y - dy*(distance - target_distance)/segment_length;
// angle text starts at and orientation // angle text starts at and orientation
angle = atan2(-dy, dx); angle = atan2(-dy, dx);
@ -403,7 +404,7 @@ namespace mapnik
cur_node++; cur_node++;
if (cur_node >= p->geom->num_points()) { if (cur_node >= p->geom.num_points()) {
return false; return false;
} }
@ -491,13 +492,14 @@ namespace mapnik
} }
p->current_placement.path.add_node(c,render_x - p->current_placement.starting_x, current_placement->add_node(c,render_x - current_placement->starting_x,
-render_y + p->current_placement.starting_y, -render_y + current_placement->starting_y,
render_angle); render_angle);
x += next_char_x; x += next_char_x;
y -= next_char_y; y -= next_char_y;
} }
p->placements.push_back(p->current_placement);
p->placements.push_back(current_placement.release());
return true; return true;
} }
@ -507,7 +509,8 @@ namespace mapnik
{ {
double x, y; double x, y;
p->current_placement.path.clear(); //p->current_placement.clear(); // TODO
std::auto_ptr<placement_element> current_placement(new placement_element);
std::pair<double, double> string_dimensions = p->info->get_dimensions(); std::pair<double, double> string_dimensions = p->info->get_dimensions();
double string_width = string_dimensions.first; double string_width = string_dimensions.first;
@ -538,7 +541,7 @@ namespace mapnik
double word_height = 0; double word_height = 0;
for (unsigned int ii = 0; ii < p->info->num_characters(); ii++) for (unsigned int ii = 0; ii < p->info->num_characters(); ii++)
{ {
character_info ci;; character_info ci;
ci = p->info->at(ii); ci = p->info->at(ii);
unsigned c = ci.character; unsigned c = ci.character;
@ -581,25 +584,25 @@ namespace mapnik
p->info->set_dimensions(string_width, string_height); p->info->set_dimensions(string_width, string_height);
if (p->geom->type() == LineString) if (p->geom.type() == LineString)
{ {
std::pair<double, double> starting_pos = p->get_position_at_distance(target_distance); std::pair<double, double> starting_pos = p->get_position_at_distance(target_distance);
p->current_placement.starting_x = starting_pos.first; current_placement->starting_x = starting_pos.first;
p->current_placement.starting_y = starting_pos.second; current_placement->starting_y = starting_pos.second;
} }
else else
{ {
p->geom->label_position(&p->current_placement.starting_x, &p->current_placement.starting_y); p->geom.label_position(&current_placement->starting_x, &current_placement->starting_y);
// TODO: // TODO:
// We would only want label position in final 'paper' coords. // We would only want label position in final 'paper' coords.
// Move view and proj transforms to e.g. label_position(x,y,proj_trans,ctrans)? // Move view and proj transforms to e.g. label_position(x,y,proj_trans,ctrans)?
double z=0; double z=0;
p->proj_trans->backward(p->current_placement.starting_x, p->current_placement.starting_y, z); p->proj_trans->backward(current_placement->starting_x,current_placement->starting_y, z);
p->ctrans->forward(&p->current_placement.starting_x, &p->current_placement.starting_y); p->ctrans->forward(&current_placement->starting_x, &current_placement->starting_y);
// apply displacement ( in pixels ) // apply displacement ( in pixels )
p->current_placement.starting_x += boost::tuples::get<0>(p->displacement_); current_placement->starting_x += boost::tuples::get<0>(p->displacement_);
p->current_placement.starting_y += boost::tuples::get<1>(p->displacement_); current_placement->starting_y += boost::tuples::get<1>(p->displacement_);
} }
double line_height = 0; double line_height = 0;
@ -627,22 +630,22 @@ namespace mapnik
} }
else else
{ {
p->current_placement.path.add_node(c, x, y, 0.0); current_placement->add_node(c, x, y, 0.0);
Envelope<double> e; Envelope<double> e;
if (p->has_dimensions) if (p->has_dimensions)
{ {
e.init(p->current_placement.starting_x - (p->dimensions.first/2.0), e.init(current_placement->starting_x - (p->dimensions.first/2.0),
p->current_placement.starting_y - (p->dimensions.second/2.0), current_placement->starting_y - (p->dimensions.second/2.0),
p->current_placement.starting_x + (p->dimensions.first/2.0), current_placement->starting_x + (p->dimensions.first/2.0),
p->current_placement.starting_y + (p->dimensions.second/2.0)); current_placement->starting_y + (p->dimensions.second/2.0));
} }
else else
{ {
e.init(p->current_placement.starting_x + x, e.init(current_placement->starting_x + x,
p->current_placement.starting_y - y, current_placement->starting_y - y,
p->current_placement.starting_x + x + ci.width, current_placement->starting_x + x + ci.width,
p->current_placement.starting_y - y - ci.height); current_placement->starting_y - y - ci.height);
} }
if (!detector_.has_placement(e, p->info->get_string(), p->minimum_distance)) if (!detector_.has_placement(e, p->info->get_string(), p->minimum_distance))
@ -660,7 +663,7 @@ namespace mapnik
x += ci.width; x += ci.width;
line_height = line_height > ci.height ? line_height : ci.height; line_height = line_height > ci.height ? line_height : ci.height;
} }
p->placements.push_back(p->current_placement); p->placements.push_back(current_placement.release());
return true; return true;
} }

View file

@ -24,6 +24,7 @@
#include <mapnik/wkb.hpp> #include <mapnik/wkb.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>
namespace mapnik namespace mapnik
{ {
@ -68,36 +69,34 @@ namespace mapnik
~wkb_reader() {} ~wkb_reader() {}
geometry_ptr read() void read(Feature & feature)
{ {
geometry_ptr geom;
int type=read_integer(); int type=read_integer();
switch (type) switch (type)
{ {
case wkbPoint: case wkbPoint:
geom = read_point(); read_point(feature);
break; break;
case wkbLineString: case wkbLineString:
geom = read_linestring(); read_linestring(feature);
break; break;
case wkbPolygon: case wkbPolygon:
geom = read_polygon(); read_polygon(feature);
break; break;
case wkbMultiPoint: case wkbMultiPoint:
geom = read_multipoint(); read_multipoint(feature);
break; break;
case wkbMultiLineString: case wkbMultiLineString:
geom = read_multilinestring(); read_multilinestring(feature);
break; break;
case wkbMultiPolygon: case wkbMultiPolygon:
geom=read_multipolygon(); read_multipolygon(feature);
break; break;
case wkbGeometryCollection: case wkbGeometryCollection:
break; break;
default: default:
break; break;
} }
return geom;
} }
private: private:
@ -170,32 +169,28 @@ namespace mapnik
pos_+=size; pos_+=size;
} }
geometry_ptr read_point() void read_point(Feature & feature)
{ {
geometry_ptr pt(new point<vertex2d>); geometry2d * pt = new point<vertex2d>;
double x = read_double(); double x = read_double();
double y = read_double(); double y = read_double();
pt->move_to(x,y); pt->move_to(x,y);
return pt; feature.add_geometry(pt);
} }
geometry_ptr read_multipoint() void read_multipoint(Feature & feature)
{ {
geometry_ptr pt(new point<vertex2d>);
int num_points = read_integer(); int num_points = read_integer();
for (int i=0;i<num_points;++i) for (int i=0;i<num_points;++i)
{ {
pos_+=5; pos_+=5;
double x = read_double(); read_point(feature);
double y = read_double();
pt->move_to(x,y);
} }
return pt;
} }
geometry_ptr read_linestring() void read_linestring(Feature & feature)
{ {
geometry_ptr line(new line_string<vertex2d>); geometry2d * line = new line_string<vertex2d>;
int num_points=read_integer(); int num_points=read_integer();
CoordinateArray ar(num_points); CoordinateArray ar(num_points);
read_coords(ar); read_coords(ar);
@ -205,37 +200,23 @@ namespace mapnik
{ {
line->line_to(ar[i].x,ar[i].y); line->line_to(ar[i].x,ar[i].y);
} }
return line; feature.add_geometry(line);
} }
geometry_ptr read_multilinestring() void read_multilinestring(Feature & feature)
{ {
geometry_ptr line(new line_string<vertex2d>);
int num_lines=read_integer(); int num_lines=read_integer();
for (int i=0;i<num_lines;++i) for (int i=0;i<num_lines;++i)
{ {
pos_+=5; pos_+=5;
read_linestring(feature);
}
}
int num_points=read_integer(); void read_polygon(Feature & feature)
CoordinateArray ar(num_points);
read_coords(ar);
line->move_to(ar[0].x,ar[0].y);
for (int i=1;i<num_points;++i)
{ {
line->line_to(ar[i].x,ar[i].y); geometry2d * poly = new polygon<vertex2d>;
}
}
return line;
}
geometry_ptr read_polygon()
{
geometry_ptr poly(new polygon<vertex2d>);
int num_rings=read_integer(); int num_rings=read_integer();
for (int i=0;i<num_rings;++i) for (int i=0;i<num_rings;++i)
{ {
int num_points=read_integer(); int num_points=read_integer();
@ -248,40 +229,24 @@ namespace mapnik
poly->line_to(ar[j].x,ar[j].y); poly->line_to(ar[j].x,ar[j].y);
} }
poly->line_to(ar[0].x,ar[0].y); poly->line_to(ar[0].x,ar[0].y);
} }
return poly; feature.add_geometry(poly);
} }
geometry_ptr read_multipolygon() void read_multipolygon(Feature & feature)
{ {
geometry_ptr poly(new polygon<vertex2d>);
int num_polys=read_integer(); int num_polys=read_integer();
for (int i=0;i<num_polys;++i) for (int i=0;i<num_polys;++i)
{ {
pos_+=5; pos_+=5;
int num_rings=read_integer(); read_polygon(feature);
for (int i=0;i<num_rings;++i)
{
int num_points=read_integer();
CoordinateArray ar(num_points);
read_coords(ar);
poly->move_to(ar[0].x,ar[0].y);
for (int j=1;j<num_points;++j)
{
poly->line_to(ar[j].x,ar[j].y);
} }
poly->line_to(ar[0].x,ar[0].y);
}
}
return poly;
} }
}; };
geometry_ptr geometry_utils::from_wkb(const char* wkb, unsigned size) void geometry_utils::from_wkb(Feature & feature,const char* wkb, unsigned size)
{ {
wkb_reader reader(wkb,size); wkb_reader reader(wkb,size);
return reader.read(); return reader.read(feature);
} }
} }