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(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('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('BIDI', 'BIDI support', '')
opts.Add(BoolOption('BIDI', 'BIDI support', 'False'))
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)
@ -99,9 +100,12 @@ if env['BIDI']:
if env['FRIBIDI_INCLUDES'] not in env['CPPPATH']:
env['CPPPATH'].append(env['FRIBIDI_INCLUDES'])
if env['FRIBIDI_LIBS'] not in env['LIBPATH']:
env['CPPPATH'].append(env['FRIBIDI_LIBS'])
env['LIBPATH'].append(env['FRIBIDI_LIBS'])
env['LIBS'].append('fribidi')
if env['XMLPARSER'] == 'tinyxml':
env.Append(CXXFLAGS = '-DBOOST_PROPERTY_TREE_XML_PARSER_TINYXML -DTIXML_USE_STL')
C_LIBSHEADERS = [
['m', 'math.h', True],
['ltdl', 'ltdl.h', True],
@ -122,7 +126,7 @@ if env['BIDI'] : C_LIBSHEADERS.append(['fribidi','fribidi/fribidi.h',True])
BOOST_LIBSHEADERS = [
['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],
['regex', 'boost/regex.hpp', True],
['program_options', 'boost/program_options.hpp', False]
@ -221,9 +225,9 @@ if env['PLATFORM'] == 'Darwin': pthread = ''
else: pthread = '-pthread'
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:
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

View file

@ -33,10 +33,10 @@
// Provides faster access for massive pixel operations,
// 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):
#define AGG_RENDERING_BUFFER row_accessor<int8u>
// #define AGG_RENDERING_BUFFER row_accessor<int8u>
//
// You can still use both of them simultaneouslyin your applications
// This #define is used only for default rendering_buffer type,

View file

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

View file

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

View file

@ -26,7 +26,7 @@
#include <mapnik/projection.hpp>
namespace {
mapnik::coord2d forward(mapnik::coord2d const& pt,
mapnik::coord2d forward_pt(mapnik::coord2d const& pt,
mapnik::projection const& prj)
{
double x = pt.x;
@ -35,7 +35,7 @@ namespace {
return mapnik::coord2d(x,y);
}
mapnik::coord2d inverse(mapnik::coord2d const& pt,
mapnik::coord2d inverse_pt(mapnik::coord2d const& pt,
mapnik::projection const& prj)
{
double x = pt.x;
@ -43,7 +43,31 @@ namespace {
prj.inverse(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 ()
@ -57,7 +81,9 @@ void export_projection ()
.add_property ("geographic",&projection::is_geographic)
;
def("forward_",&forward);
def("inverse_",&inverse);
def("forward_",&forward_pt);
def("inverse_",&inverse_pt);
def("forward_",&forward_env);
def("inverse_",&inverse_env);
}

View file

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

View file

@ -163,7 +163,7 @@ struct symbolizer_icon : public boost::static_visitor<QIcon>
{
QPixmap pix(16,16);
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()));
painter.fillRect(0, 0, 16, 16, brush);
return QIcon(pix);
@ -180,6 +180,21 @@ struct symbolizer_icon : public boost::static_visitor<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>
QIcon operator() (T const& ) const

View file

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

View file

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

View file

@ -30,111 +30,147 @@
#include <mapnik/proj_transform.hpp>
namespace mapnik {
typedef coord_array<coord2d> CoordinateArray;
typedef coord_array<coord2d> CoordinateArray;
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform
{
coord_transform(Transform const& t, Geometry& geom)
: t_(t), geom_(geom) {}
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform
{
coord_transform(Transform const& t, Geometry& geom)
: t_(t), geom_(geom) {}
unsigned vertex(double *x , double *y) const
{
unsigned command = geom_.vertex(x,y);
t_.forward(x,y);
return command;
}
unsigned vertex(double *x , double *y) const
{
unsigned command = geom_.vertex(x,y);
t_.forward(x,y);
return command;
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
private:
Transform const& t_;
Geometry& geom_;
};
private:
Transform const& t_;
Geometry& geom_;
};
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform2
{
coord_transform2(Transform const& t,
Geometry& geom,
proj_transform const& prj_trans)
: t_(t),
geom_(geom),
prj_trans_(prj_trans) {}
template <typename Transform,typename Geometry>
struct MAPNIK_DECL coord_transform2
{
coord_transform2(Transform const& t,
Geometry const& geom,
proj_transform const& prj_trans)
: t_(t),
geom_(geom),
prj_trans_(prj_trans) {}
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);
return command;
}
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);
return command;
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
void rewind (unsigned pos)
{
geom_.rewind(pos);
}
private:
Transform const& t_;
Geometry& geom_;
proj_transform const& prj_trans_;
};
private:
Transform const& t_;
Geometry const& geom_;
proj_transform const& prj_trans_;
};
class CoordTransform
{
private:
int width;
int height;
double scale_;
Envelope<double> extent_;
double offset_x_,offset_y_;
public:
CoordTransform(int width,int height,const Envelope<double>& extent,
double offset_x = 0, double offset_y = 0)
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
{
private:
int width;
int height;
double scale_;
Envelope<double> extent_;
double offset_x_;
double offset_y_;
public:
CoordTransform(int width,int height,const Envelope<double>& extent,
double offset_x = 0, double offset_y = 0)
:width(width),height(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y)
{
{
double sx=((double)width)/extent_.width();
double sy=((double)height)/extent_.height();
scale_=std::min(sx,sy);
}
}
inline double scale() const
{
inline double scale() const
{
return scale_;
}
}
inline void forward(double * x, double * y) const
{
inline void forward(double * x, double * y) const
{
*x = (*x - extent_.minx()) * scale_ - offset_x_;
*y = (extent_.maxy() - *y) * scale_ - offset_y_;
}
}
inline void backward(double * x, double * y) const
{
inline void backward(double * x, double * y) const
{
*x = extent_.minx() + (*x + offset_x_)/scale_;
*y = extent_.maxy() - (*y + offset_y_)/scale_;
}
}
inline coord2d& forward(coord2d& c) const
{
inline coord2d& forward(coord2d& c) const
{
forward(&c.x,&c.y);
return c;
}
}
inline coord2d& backward(coord2d& c) const
{
inline coord2d& backward(coord2d& c) const
{
backward(&c.x,&c.y);
return c;
}
}
inline Envelope<double> forward(const Envelope<double>& e) const
{
inline Envelope<double> forward(const Envelope<double>& e) const
{
double x0 = e.minx();
double y0 = e.miny();
double x1 = e.maxx();
@ -142,10 +178,10 @@ namespace mapnik {
forward(&x0,&y0);
forward(&x1,&y1);
return Envelope<double>(x0,y0,x1,y1);
}
}
inline Envelope<double> backward(const Envelope<double>& e) const
{
inline Envelope<double> backward(const Envelope<double>& e) const
{
double x0 = e.minx();
double y0 = e.miny();
double x1 = e.maxx();
@ -153,26 +189,26 @@ namespace mapnik {
backward(&x0,&y0);
backward(&x1,&y1);
return Envelope<double>(x0,y0,x1,y1);
}
}
inline CoordinateArray& forward(CoordinateArray& coords) const
{
inline CoordinateArray& forward(CoordinateArray& coords) const
{
for (unsigned i=0;i<coords.size();++i)
{
forward(coords[i]);
forward(coords[i]);
}
return coords;
}
}
inline CoordinateArray& backward(CoordinateArray& coords) const
{
inline CoordinateArray& backward(CoordinateArray& coords) const
{
for (unsigned i=0;i<coords.size();++i)
{
backward(coords[i]);
backward(coords[i]);
}
return coords;
}
};
}
};
}
#endif //CTRANS_HPP

View file

@ -36,100 +36,111 @@
#include <mapnik/raster.hpp>
namespace mapnik {
typedef boost::shared_ptr<raster> raster_ptr;
typedef boost::associative_property_map<
std::map<std::string,value
> > properties;
template <typename T1,typename T2>
struct feature : public properties,
private boost::noncopyable
{
public:
typedef T1 geometry_type;
typedef T2 raster_type;
typedef std::map<std::string,value>::value_type value_type;
typedef std::map<std::string,value>::size_type size_type;
private:
int id_;
geometry_type geom_;
raster_type raster_;
std::map<std::string,value> props_;
public:
typedef std::map<std::string,value>::iterator iterator;
explicit feature(int id)
typedef boost::shared_ptr<raster> raster_ptr;
typedef boost::associative_property_map<
std::map<std::string,value
> > properties;
template <typename T1,typename T2>
struct feature : public properties,
private boost::noncopyable
{
public:
typedef T1 geometry_type;
typedef T2 raster_type;
typedef std::map<std::string,value>::value_type value_type;
typedef std::map<std::string,value>::size_type size_type;
private:
int id_;
boost::ptr_vector<geometry_type> geom_cont_;
raster_type raster_;
std::map<std::string,value> props_;
public:
typedef std::map<std::string,value>::iterator iterator;
explicit feature(int id)
: properties(props_),
id_(id),
geom_(),
geom_cont_(),
raster_() {}
feature(int id,const geometry_type& geom)
: properties(props_),
id_(id),
geom_(geom),
raster_() {}
int id() const
{
//feature(int id,const geometry_type& geom)
// : properties(props_),
// id_(id),
// geom_(geom),
// raster_() {}
int id() const
{
return id_;
}
void set_geometry(geometry_type& geom)
{
geom_=geom;
}
geometry_type const& get_geometry() const
{
return geom_;
}
const raster_type& get_raster() const
{
}
void add_geometry(geometry_type * geom)
{
geom_cont_.push_back(geom);
}
unsigned num_geometries() const
{
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
{
return raster_;
}
void set_raster(raster_type const& raster)
{
}
void set_raster(raster_type const& raster)
{
raster_=raster;
}
std::map<std::string,value> const& props() const
{
}
std::map<std::string,value> const& props() const
{
return props_;
}
iterator begin() const
{
}
iterator begin() const
{
return props_.begin();
}
iterator end() const
{
}
iterator end() const
{
return props_.end();
}
std::string to_string() const
{
}
std::string to_string() const
{
std::stringstream ss;
ss << "feature (" << std::endl;
for (std::map<std::string,value>::const_iterator itr=props_.begin();
itr != props_.end();++itr)
{
ss << " " << itr->first << ":" << itr->second << std::endl;
ss << " " << itr->first << ":" << itr->second << std::endl;
}
ss << ")" << std::endl;
return ss.str();
}
};
typedef feature<geometry_ptr,raster_ptr> Feature;
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
{
out << f.to_string();
return out;
}
}
};
typedef feature<geometry2d,raster_ptr> Feature;
inline std::ostream& operator<< (std::ostream & out,Feature const& f)
{
out << f.to_string();
return out;
}
}
#endif //FEATURE_HPP

View file

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

View file

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

View file

@ -41,7 +41,7 @@ namespace mapnik
{
//if (pData_) memset(pData_,0,sizeof(T)*width_*height_);
}
ImageData(const ImageData<T>& rhs)
:width_(rhs.width_),
height_(rhs.height_),

View file

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

View file

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

View file

@ -39,6 +39,37 @@ namespace mapnik
: 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_;
};
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_;

View file

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

View file

@ -30,131 +30,134 @@
namespace mapnik
{
struct character_info
{
int character;
double width, height;
struct character_info
{
int character;
double width, height;
character_info() : character(0), width(0), height(0) {}
character_info(int c_, double width_, double height_) : character(c_), width(width_), height(height_) {}
~character_info() {}
character_info() : character(0), width(0), height(0) {}
character_info(int c_, double width_, double height_) : character(c_), width(width_), height(height_) {}
~character_info() {}
character_info(const character_info &ci)
: character(ci.character), width(ci.width), height(ci.height)
{
}
character_info(const character_info &ci)
: character(ci.character), width(ci.width), height(ci.height)
{
}
};
};
class string_info : private boost::noncopyable
{
protected:
typedef boost::ptr_vector<character_info> characters_t;
std::wstring string_;
characters_t characters_;
class string_info : private boost::noncopyable
{
protected:
typedef boost::ptr_vector<character_info> characters_t;
std::wstring string_;
characters_t characters_;
double width_;
double height_;
public:
string_info(std::wstring string)
: string_(string),
width_(0),
height_(0) {}
double width_;
double height_;
public:
string_info(std::wstring string)
: string_(string),
width_(0),
height_(0) {}
void add_info(int c, double width, double height)
{
characters_.push_back(new character_info(c, width, height));
}
void add_info(int c, double width, double height)
{
characters_.push_back(new character_info(c, width, height));
}
unsigned num_characters()
{
return characters_.size();
}
unsigned num_characters()
{
return characters_.size();
}
character_info at(unsigned i)
{
return characters_[i];
}
character_info at(unsigned i)
{
return characters_[i];
}
character_info operator[](unsigned i)
{
return at(i);
}
character_info operator[](unsigned i)
{
return at(i);
}
void set_dimensions(double width, double height)
{
width_ = width;
height_ = height;
}
void set_dimensions(double width, double height)
{
width_ = width;
height_ = height;
}
std::pair<double, double> get_dimensions()
{
return std::pair<double, double>(width_, height_);
}
std::pair<double, double> get_dimensions()
{
return std::pair<double, double>(width_, height_);
}
std::wstring get_string() {
return string_;
}
};
std::wstring get_string() {
return string_;
}
};
struct text_path
{
struct character_node
{
int c;
double x, y, angle;
character_node(int c_, double x_, double y_, double angle_) : c(c_), x(x_), y(y_), angle(angle_) {}
~character_node() {}
void vertex(int *c_, double *x_, double *y_, double *angle_)
{
*c_ = c;
*x_ = x;
*y_ = y;
*angle_ = angle;
}
};
typedef std::vector<character_node> character_nodes_t;
character_nodes_t nodes_;
int itr_;
std::pair<unsigned,unsigned> string_dimensions;
text_path() : itr_(0) {}
text_path(const text_path & other) : itr_(0)
{
nodes_ = other.nodes_;
string_dimensions = other.string_dimensions;
}
~text_path() {}
struct text_path : boost::noncopyable
{
struct character_node
{
int c;
double x, y, angle;
character_node(int c_, double x_, double y_, double angle_)
: c(c_), x(x_), y(y_), angle(angle_) {}
~character_node() {}
void vertex(int *c_, double *x_, double *y_, double *angle_)
{
*c_ = c;
*x_ = x;
*y_ = y;
*angle_ = angle;
}
};
typedef std::vector<character_node> character_nodes_t;
double starting_x;
double starting_y;
character_nodes_t nodes_;
int itr_;
void add_node(int c, double x, double y, double angle)
{
std::pair<unsigned,unsigned> string_dimensions;
text_path()
: starting_x(0),
starting_y(0),
itr_(0) {}
//text_path(text_path const& other) :
// itr_(0),
// nodes_(other.nodes_),
// string_dimensions(other.string_dimensions)
//{}
~text_path() {}
void add_node(int c, double x, double y, double angle)
{
nodes_.push_back(character_node(c, x, y, angle));
}
}
void vertex(int *c, double *x, double *y, double *angle)
{
void vertex(int *c, double *x, double *y, double *angle)
{
nodes_[itr_++].vertex(c, x, y, angle);
}
}
int num_nodes()
{
int num_nodes()
{
return nodes_.size();
}
void clear()
{
nodes_.clear();
}
};
}
void clear()
{
nodes_.clear();
}
};
}
#endif

View file

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

View file

@ -34,6 +34,8 @@ gdal_src = Split(
libraries = ['gdal' ]
if env['PLATFORM'] == 'Darwin':
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)

View file

@ -33,7 +33,7 @@ using boost::bad_lexical_cast;
using boost::trim;
using std::string;
using mapnik::Feature;
using mapnik::geometry_ptr;
using mapnik::geometry2d;
using mapnik::byte;
using mapnik::geometry_utils;
@ -53,58 +53,53 @@ feature_ptr postgis_featureset::next()
feature_ptr feature(new Feature(count_));
int size=rs_->getFieldLength(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;
if (geom)
for (unsigned pos=1;pos<num_attrs_+1;++pos)
{
feature->set_geometry(geom);
for (unsigned pos=1;pos<num_attrs_+1;++pos)
{
std::string name = rs_->getFieldName(pos);
const char* buf=rs_->getValue(pos);
int oid = rs_->getTypeOID(pos);
if (oid==23) //int4
{
int val = int4net(buf);
boost::put(*feature,name,val);
}
else if (oid==21) //int2
{
int val = int2net(buf);
boost::put(*feature,name,val);
}
else if (oid == 700) // float4
{
float val;
float4net(val,buf);
boost::put(*feature,name,val);
}
else if (oid == 701) // float8
{
double val;
float8net(val,buf);
boost::put(*feature,name,val);
}
else if (oid==25 || oid==1042 || oid==1043) // text or bpchar or varchar
{
std::string str(buf);
trim(str);
std::wstring wstr = tr_->transcode(str);
boost::put(*feature,name,wstr);
}
else
{
std::string name = rs_->getFieldName(pos);
const char* buf=rs_->getValue(pos);
int oid = rs_->getTypeOID(pos);
if (oid==23) //int4
{
int val = int4net(buf);
boost::put(*feature,name,val);
}
else if (oid==21) //int2
{
int val = int2net(buf);
boost::put(*feature,name,val);
}
else if (oid == 700) // float4
{
float val;
float4net(val,buf);
boost::put(*feature,name,val);
}
else if (oid == 701) // float8
{
double val;
float8net(val,buf);
boost::put(*feature,name,val);
}
else if (oid==25 || oid==1042 || oid==1043) // text or bpchar or varchar
{
std::string str(buf);
trim(str);
std::wstring wstr = tr_->transcode(str);
boost::put(*feature,name,wstr);
}
else
{
#ifdef MAPNIK_DEBUG
std::clog << "uknown OID = " << oid << " FIXME \n";
std::clog << "uknown OID = " << oid << " FIXME \n";
#endif
//boost::put(*feature,name,0);
}
}
++count_;
//boost::put(*feature,name,0);
}
}
++count_;
return feature;
}
else

View file

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

View file

@ -41,6 +41,8 @@ libraries = []
if env['PLATFORM'] == 'Darwin':
libraries.append('mapnik')
libraries.append('iconv')
if env['BIDI'] : libraries.append('fribidi')
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)
: datasource (params),
shape_name_(*params_.get<std::string>("file","")),
type_(datasource::Vector),
shape_name_(*params_.get<std::string>("file","")),
file_length_(0),
indexed_(false),
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)
@ -59,9 +60,9 @@ template <typename filterT>
feature_ptr shape_featureset<filterT>::next()
{
using mapnik::point_impl;
using mapnik::point_impl;
std::streampos pos=shape_.shp().pos();
if (pos < std::streampos(file_length_ * 2))
{
shape_.move_to(pos);
@ -71,9 +72,9 @@ feature_ptr shape_featureset<filterT>::next()
{
double x=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);
feature->set_geometry(point);
feature->add_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointm)
@ -81,9 +82,9 @@ feature_ptr shape_featureset<filterT>::next()
double x=shape_.shp().read_double();
double y=shape_.shp().read_double();
shape_.shp().read_double();//m
geometry_ptr point(new point_impl);
geometry2d * point = new point_impl;
point->move_to(x,y);
feature->set_geometry(point);
feature->add_geometry(point);
++count_;
}
else if (type == shape_io::shape_pointz)
@ -92,9 +93,9 @@ feature_ptr shape_featureset<filterT>::next()
double y=shape_.shp().read_double();
shape_.shp().read_double();//z
shape_.shp().read_double();//m
geometry_ptr point(new point_impl);
geometry2d * point=new point_impl;
point->move_to(x,y);
feature->set_geometry(point);
feature->add_geometry(point);
++count_;
}
else
@ -119,43 +120,43 @@ feature_ptr shape_featureset<filterT>::next()
case shape_io::shape_polyline:
{
geometry_ptr line = shape_.read_polyline();
feature->set_geometry(line);
geometry2d * line = shape_.read_polyline();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinem:
{
geometry_ptr line = shape_.read_polylinem();
feature->set_geometry(line);
geometry2d * line = shape_.read_polylinem();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polylinez:
{
geometry_ptr line = shape_.read_polylinez();
feature->set_geometry(line);
geometry2d * line = shape_.read_polylinez();
feature->add_geometry(line);
++count_;
break;
}
case shape_io::shape_polygon:
{
geometry_ptr poly = shape_.read_polygon();
feature->set_geometry(poly);
geometry2d * poly = shape_.read_polygon();
feature->add_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonm:
{
geometry_ptr poly = shape_.read_polygonm();
feature->set_geometry(poly);
geometry2d * poly = shape_.read_polygonm();
feature->add_geometry(poly);
++count_;
break;
}
case shape_io::shape_polygonz:
{
geometry_ptr poly = shape_.read_polygonz();
feature->set_geometry(poly);
geometry2d * poly = shape_.read_polygonz();
feature->add_geometry(poly);
++count_;
break;
}

View file

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

View file

@ -31,395 +31,395 @@ const std::string shape_io::SHP = ".shp";
const std::string shape_io::DBF = ".dbf";
shape_io::shape_io(const std::string& shape_name)
: type_(shape_null),
reclength_(0),
id_(0)
: type_(shape_null),
reclength_(0),
id_(0)
{
bool ok = (shp_.open(shape_name + SHP) &&
dbf_.open(shape_name + DBF));
if (!ok)
{
throw datasource_exception("cannot read shape file");
}
bool ok = (shp_.open(shape_name + SHP) &&
dbf_.open(shape_name + DBF));
if (!ok)
{
throw datasource_exception("cannot read shape file");
}
}
shape_io::~shape_io()
{
shp_.close();
dbf_.close();
shp_.close();
dbf_.close();
}
void shape_io::move_to (int pos)
{
shp_.seek(pos);
id_ = shp_.read_xdr_integer();
reclength_ = shp_.read_xdr_integer();
type_ = shp_.read_ndr_integer();
shp_.seek(pos);
id_ = shp_.read_xdr_integer();
reclength_ = shp_.read_xdr_integer();
type_ = shp_.read_ndr_integer();
if (type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
{
shp_.read_envelope(cur_extent_);
}
if (type_ != shape_point && type_ != shape_pointm && type_ != shape_pointz)
{
shp_.read_envelope(cur_extent_);
}
}
int shape_io::type() const
{
return type_;
return type_;
}
const Envelope<double>& shape_io::current_extent() const
{
return cur_extent_;
return cur_extent_;
}
shape_file& shape_io::shp()
{
return shp_;
return shp_;
}
shape_file& shape_io::shx()
{
return shx_;
return shx_;
}
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;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_ptr line(new line_string_impl);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
line->set_capacity(num_points + 1);
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
using mapnik::line_string_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry2d * line = new line_string_impl;
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
line->set_capacity(num_points + 1);
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
return line;
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
return line;
}
geometry_ptr shape_io::read_polylinem()
geometry2d * shape_io::read_polylinem()
{
using mapnik::line_string_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_ptr line(new line_string_impl);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
using mapnik::line_string_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry2d * line = new line_string_impl;
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_ptr shape_io::read_polylinez()
{
using mapnik::line_string_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry_ptr line(new line_string_impl);
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
else
end=parts[k+1];
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
// {
// double z=record.read_double();
// }
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_ptr shape_io::read_polygon()
{
using mapnik::polygon_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_ptr poly(new polygon_impl);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
}
else
{
else
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
return poly;
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_ptr shape_io::read_polygonm()
geometry2d * shape_io::read_polylinez()
{
using mapnik::polygon_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_ptr poly(new polygon_impl);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
using mapnik::line_string_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
geometry2d * line = new line_string_impl;
line->set_capacity(num_points + num_parts);
if (num_parts == 1)
{
record.skip(4);
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int i=1;i<num_points;++i)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
else
{
std::vector<int> parts(num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
int start,end;
for (int k=0;k<num_parts;++k)
{
start=parts[k];
if (k==num_parts-1)
end=num_points;
}
else
{
else
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
double x=record.read_double();
double y=record.read_double();
line->move_to(x,y);
for (int j=start+1;j<end;++j)
{
x=record.read_double();
y=record.read_double();
line->line_to(x,y);
}
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
// {
// double z=record.read_double();
// }
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return line;
}
geometry_ptr shape_io::read_polygonz()
geometry2d * shape_io::read_polygon()
{
using mapnik::polygon_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry_ptr poly(new polygon_impl);
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
using mapnik::polygon_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry2d * poly = new polygon_impl;
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double z=record.read_double();
//}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
return poly;
}
geometry2d * shape_io::read_polygonm()
{
using mapnik::polygon_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry2d * poly = new polygon_impl;
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
}
geometry2d * shape_io::read_polygonz()
{
using mapnik::polygon_impl;
shape_record record(reclength_*2-36);
shp_.read_record(record);
int num_parts=record.read_ndr_integer();
int num_points=record.read_ndr_integer();
std::vector<int> parts(num_parts);
geometry2d * poly=new polygon_impl;
poly->set_capacity(num_points + num_parts);
for (int i=0;i<num_parts;++i)
{
parts[i]=record.read_ndr_integer();
}
for (int k=0;k<num_parts;k++)
{
int start=parts[k];
int end;
if (k==num_parts-1)
{
end=num_points;
}
else
{
end=parts[k+1];
}
double x=record.read_double();
double y=record.read_double();
poly->move_to(x,y);
for (int j=start+1;j<end;j++)
{
x=record.read_double();
y=record.read_double();
poly->line_to(x,y);
}
}
// z-range
//double z0=record.read_double();
//double z1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double z=record.read_double();
//}
// m-range
//double m0=record.read_double();
//double m1=record.read_double();
//for (int i=0;i<num_points;++i)
//{
// double m=record.read_double();
//}
return poly;
}

View file

@ -27,7 +27,7 @@
#include "shapefile.hpp"
#include "shp_index.hpp"
using mapnik::geometry_ptr;
using mapnik::geometry2d;
struct shape_io
{
@ -62,25 +62,24 @@ public:
shape_multipatch = 31
};
shape_io(const std::string& shape_name);
~shape_io();
shape_file& shp();
shape_file& shx();
dbf_file& dbf();
void move_to(int id);
int type() const;
const Envelope<double>& current_extent() const;
geometry_ptr read_polyline();
geometry_ptr read_polylinem();
geometry_ptr read_polylinez();
geometry_ptr read_polygon();
geometry_ptr read_polygonm();
geometry_ptr read_polygonz();
private:
//void read_record(const shape_record& record);
// no copying
shape_io(const shape_io&);
shape_io& operator=(const shape_io&);
shape_io(const std::string& shape_name);
~shape_io();
shape_file& shp();
shape_file& shx();
dbf_file& dbf();
void move_to(int id);
int type() const;
const Envelope<double>& current_extent() const;
geometry2d * read_polyline();
geometry2d * read_polylinem();
geometry2d * read_polylinez();
geometry2d * read_polygon();
geometry2d * read_polygonm();
geometry2d * read_polygonz();
private:
//void read_record(const shape_record& record);
// no copying
shape_io(const shape_io&);
shape_io& operator=(const shape_io&);
};
#endif //SHAPE_IO_HH

View file

@ -25,14 +25,16 @@
#include <iostream>
// boost
#include <boost/utility.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/tuple/tuple.hpp>
// agg
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
//#include "agg_rendering_buffer.h"
//#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgba.h"
//#include "agg_pixfmt_rgba.h"
#include "agg_path_storage.h"
#include "agg_span_allocator.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)
: feature_style_processor<agg_renderer>(m),
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),
detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64)),
finder_(detector_,Envelope<double>(0 ,0, m.getWidth(), m.getHeight()))
@ -111,6 +117,7 @@ namespace mapnik
std::clog << "start map processing bbox="
<< map.getCurrentExtent() << "\n";
#endif
ras_.clip_box(0,0,width_,height_);
}
template <typename T>
@ -147,33 +154,141 @@ namespace mapnik
Feature const& feature,
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_scanline_aa_solid<ren_base> renderer;
Color const& fill_ = sym.get_fill();
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 2)
ras_.reset();
agg::scanline_u8 sl;
ren_base renb(pixf_);
unsigned r=fill_.red();
unsigned g=fill_.green();
unsigned b=fill_.blue();
renderer ren(renb);
for (unsigned i=0;i<feature.num_geometries();++i)
{
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 g=fill_.green();
unsigned b=fill_.blue();
renderer ren(renb);
geometry2d const& geom=feature.get_geometry(i);
if (geom.num_points() > 2)
{
path_type path(t_,geom,prj_trans);
ras_.add_path(path);
}
}
ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity())));
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);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
ras.clip_box(0,0,width,height);
ras.add_path(path);
ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity())));
agg::render_scanlines(ras, sl, ren);
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,134 +298,113 @@ namespace mapnik
proj_transform const& prj_trans)
{
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::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 1)
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();
renderer ren(renb);
ras_.reset();
agg::scanline_p8 sl;
for (unsigned i=0;i<feature.num_geometries();++i)
{
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();
Color const& col = stroke_.get_color();
unsigned r=col.red();
unsigned g=col.green();
unsigned b=col.blue();
if (stroke_.has_dash())
geometry2d const& geom = feature.get_geometry(i);
if (geom.num_points() > 1)
{
renderer ren(renb);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
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();
while (itr != end)
{
dash.add_dash(itr->first, itr->second);
++itr;
path_type path(t_,geom,prj_trans);
if (stroke_.has_dash())
{
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());
ras_.add_path(stroke);
}
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());
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())));
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
{
renderer ren(renb);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
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.clip_box(0,0,pixmap_.width(),pixmap_.height());
ras.add_path(stroke);
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
agg::render_scanlines(ras, sl, ren);
{
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_.add_path(stroke);
}
}
}
ren.color(agg::rgba8(r, g, b, int(255*stroke_.get_opacity())));
agg::render_scanlines(ras_, sl, ren);
}
template <typename T>
void agg_renderer<T>::process(point_symbolizer const& sym,
Feature const& feature,
proj_transform const& prj_trans)
{
geometry_ptr const& geom=feature.get_geometry();
if (geom)
double x;
double y;
double z=0;
boost::shared_ptr<ImageData32> const& data = sym.get_data();
if ( data )
{
double x;
double y;
double z=0;
boost::shared_ptr<ImageData32> const& data = sym.get_data();
if ( data )
for (unsigned i=0;i<feature.num_geometries();++i)
{
geom->label_position(&x,&y);
geometry2d const& geom = feature.get_geometry(i);
geom.label_position(&x,&y);
prj_trans.backward(x,y,z);
t_.forward(&x,&y);
int w = data->width();
@ -336,79 +430,80 @@ namespace mapnik
Feature const& feature,
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();
boost::shared_ptr<ImageData32> const& data = sym.get_background_image();
if (text.length() > 0 && data)
{
std::wstring text = feature[sym.get_name()].to_unicode();
boost::shared_ptr<ImageData32> const& data = sym.get_background_image();
if (text.length() > 0 && data)
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
{
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
text_renderer<mapnik::Image32> ren(pixmap_,face);
ren.set_pixel_size(sym.get_text_size());
ren.set_fill(sym.get_fill());
string_info info(text);
ren.get_string_info(&info);
unsigned num_geom = feature.num_geometries();
for (unsigned i=0;i<num_geom;++i)
{
text_renderer<mapnik::Image32> ren(pixmap_,face);
ren.set_pixel_size(sym.get_text_size());
ren.set_fill(sym.get_fill());
string_info info(text);
ren.get_string_info(&info);
placement text_placement(&info, &t_, &prj_trans, geom, sym);
text_placement.avoid_edges = sym.get_avoid_edges();
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);
text_placement.avoid_edges = sym.get_avoid_edges();
finder_.find_placements(&text_placement);
finder_.find_placements(&text_placement);
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));
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);
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
pixmap_.set_rectangle_alpha(px,py,*data);
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii].path);
ren.render(x,y);
ren.render(x,y);
}
}
}
}
}
}
template <typename T>
void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
Feature const& feature,
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::renderer_base<agg::pixfmt_rgba32> renderer_base;
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
geometry_ptr const& geom=feature.get_geometry();
if (geom && geom->num_points() > 1)
ImageData32 const& pat = sym.get_pattern();
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)
{
unsigned width = pixmap_.width();
unsigned height = pixmap_.height();
ImageData32 const& pat = sym.get_pattern();
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);
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);
ras.add_path(path);
geometry2d const& geom = feature.get_geometry(i);
if (geom.num_points() > 1)
{
path_type path(t_,geom,prj_trans);
ras.add_path(path);
}
}
}
@ -417,11 +512,13 @@ namespace mapnik
Feature const& feature,
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::wrap_mode_repeat wrap_x_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_y_type> img_source_type;
@ -430,42 +527,41 @@ namespace mapnik
typedef agg::renderer_scanline_aa<ren_base,
agg::span_allocator<agg::rgba8>,
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();
unsigned w=pattern.width();
unsigned h=pattern.height();
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.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)
{
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 h=pattern.height();
agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)pattern.getBytes(),w,h,w*4);
double x0,y0;
path_type path(t_,feature.get_geometry(0),prj_trans);
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::pixfmt_rgba32 pixf_pattern(pattern_rbuf);
img_source_type img_src(pixf_pattern);
span_gen_type sg(img_src, offset_x, offset_y);
renderer_type rp(renb,sa, sg);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
ras.clip_box(0,0,width,height);
ras.add_path(path);
agg::render_scanlines(ras, sl, rp);
}
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_.add_path(path);
}
}
agg::render_scanlines(ras_, sl, rp);
}
template <typename T>
@ -480,7 +576,7 @@ namespace mapnik
if (raster)
{
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_);
pixmap_.set_rectangle(int(ext.minx()),int(ext.miny()),target);
}
@ -491,41 +587,41 @@ namespace mapnik
Feature const& feature,
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();
if ( text.length() > 0 )
{
std::wstring text = feature[sym.get_name()].to_unicode();
if ( text.length() > 0 )
Color const& fill = sym.get_fill();
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
{
Color const& fill = sym.get_fill();
face_ptr face = font_manager_.get_face(sym.get_face_name());
if (face)
text_renderer<mapnik::Image32> ren(pixmap_,face);
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());
string_info info(text);
ren.get_string_info(&info);
unsigned num_geom = feature.num_geometries();
for (unsigned i=0;i<num_geom;++i)
{
text_renderer<mapnik::Image32> ren(pixmap_,face);
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());
string_info info(text);
ren.get_string_info(&info);
placement text_placement(&info, &t_, &prj_trans, geom, sym);
finder_.find_placements(&text_placement);
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
geometry2d const& geom = feature.get_geometry(i);
if (geom.num_points() > 0) // don't bother with empty geometries
{
double x = text_placement.placements[ii].starting_x;
double y = text_placement.placements[ii].starting_y;
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii].path);
ren.render(x,y);
placement text_placement(&info, &t_, &prj_trans, geom, sym);
finder_.find_placements(&text_placement);
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;
Envelope<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
ren.render(x,y);
}
}
}
}
}
}
}
}
}
template class agg_renderer<Image32>;
}

View file

@ -167,7 +167,7 @@ namespace mapnik
}
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_);
}

View file

@ -441,6 +441,40 @@ namespace mapnik
}
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")
{
rule.append(raster_symbolizer());

View file

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

View file

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

View file

@ -49,15 +49,15 @@ namespace mapnik
{
template<>
placement::placement(string_info *info_,
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry_ptr geom_,
shield_symbolizer sym)
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry2d const& geom_,
shield_symbolizer const& sym)
: info(info_),
ctrans(ctrans_),
proj_trans(proj_trans_),
geom(geom_),
shape_path(*ctrans_, *geom_, *proj_trans_),
shape_path(*ctrans_, geom_, *proj_trans_),
total_distance_(-1.0),
displacement_(sym.get_displacement()),
label_placement(sym.get_label_placement()),
@ -77,15 +77,15 @@ namespace mapnik
template<>
placement::placement(string_info *info_,
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry_ptr geom_,
text_symbolizer sym)
CoordTransform *ctrans_,
const proj_transform *proj_trans_,
geometry2d const& geom_,
text_symbolizer const& sym)
: info(info_),
ctrans(ctrans_),
proj_trans(proj_trans_),
geom(geom_),
shape_path(*ctrans_, *geom_, *proj_trans_),
shape_path(*ctrans_, geom_, *proj_trans_),
total_distance_(-1.0),
displacement_(sym.get_displacement()),
label_placement(sym.get_label_placement()),
@ -109,7 +109,7 @@ namespace mapnik
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)
@ -122,7 +122,7 @@ namespace mapnik
shape_path.rewind(0);
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)
{
double dx, dy;
@ -162,7 +162,7 @@ namespace mapnik
total_distance_ = 0.0;
unsigned num_points = geom->num_points();
unsigned num_points = geom.num_points();
for (unsigned i = 1; i < num_points ; ++i)
{
double dx, dy;
@ -268,9 +268,9 @@ namespace mapnik
}
return;
}
std::vector<double> ideal_label_distances = get_ideal_placements(p);
double delta, tolerance, distance;
distance = p->get_total_distance();
tolerance = p->label_position_tolerance;
@ -327,9 +327,10 @@ namespace mapnik
double angle = 0.0;
int orientation = 0;
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;
x = y = 0.0;
@ -344,7 +345,7 @@ namespace mapnik
p->shape_path.vertex(&new_x,&new_y);
old_x = new_x;
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)
{
double dx, dy;
@ -365,8 +366,8 @@ namespace mapnik
if (distance > target_distance)
{
// 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;
p->current_placement.starting_y = new_y - dy*(distance - target_distance)/segment_length;
current_placement->starting_x = new_x - dx*(distance - target_distance)/segment_length;
current_placement->starting_y = new_y - dy*(distance - target_distance)/segment_length;
// angle text starts at and orientation
angle = atan2(-dy, dx);
@ -403,7 +404,7 @@ namespace mapnik
cur_node++;
if (cur_node >= p->geom->num_points()) {
if (cur_node >= p->geom.num_points()) {
return false;
}
@ -491,14 +492,15 @@ namespace mapnik
}
p->current_placement.path.add_node(c,render_x - p->current_placement.starting_x,
-render_y + p->current_placement.starting_y,
render_angle);
current_placement->add_node(c,render_x - current_placement->starting_x,
-render_y + current_placement->starting_y,
render_angle);
x += next_char_x;
y -= next_char_y;
}
p->placements.push_back(p->current_placement);
p->placements.push_back(current_placement.release());
return true;
}
@ -507,8 +509,9 @@ namespace mapnik
{
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();
double string_width = string_dimensions.first;
double string_height = string_dimensions.second;
@ -538,7 +541,7 @@ namespace mapnik
double word_height = 0;
for (unsigned int ii = 0; ii < p->info->num_characters(); ii++)
{
character_info ci;;
character_info ci;
ci = p->info->at(ii);
unsigned c = ci.character;
@ -581,25 +584,25 @@ namespace mapnik
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);
p->current_placement.starting_x = starting_pos.first;
p->current_placement.starting_y = starting_pos.second;
current_placement->starting_x = starting_pos.first;
current_placement->starting_y = starting_pos.second;
}
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:
// 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)?
double z=0;
p->proj_trans->backward(p->current_placement.starting_x, p->current_placement.starting_y, z);
p->ctrans->forward(&p->current_placement.starting_x, &p->current_placement.starting_y);
p->proj_trans->backward(current_placement->starting_x,current_placement->starting_y, z);
p->ctrans->forward(&current_placement->starting_x, &current_placement->starting_y);
// apply displacement ( in pixels )
p->current_placement.starting_x += boost::tuples::get<0>(p->displacement_);
p->current_placement.starting_y += boost::tuples::get<1>(p->displacement_);
current_placement->starting_x += boost::tuples::get<0>(p->displacement_);
current_placement->starting_y += boost::tuples::get<1>(p->displacement_);
}
double line_height = 0;
@ -627,22 +630,22 @@ namespace mapnik
}
else
{
p->current_placement.path.add_node(c, x, y, 0.0);
current_placement->add_node(c, x, y, 0.0);
Envelope<double> e;
if (p->has_dimensions)
{
e.init(p->current_placement.starting_x - (p->dimensions.first/2.0),
p->current_placement.starting_y - (p->dimensions.second/2.0),
p->current_placement.starting_x + (p->dimensions.first/2.0),
p->current_placement.starting_y + (p->dimensions.second/2.0));
e.init(current_placement->starting_x - (p->dimensions.first/2.0),
current_placement->starting_y - (p->dimensions.second/2.0),
current_placement->starting_x + (p->dimensions.first/2.0),
current_placement->starting_y + (p->dimensions.second/2.0));
}
else
{
e.init(p->current_placement.starting_x + x,
p->current_placement.starting_y - y,
p->current_placement.starting_x + x + ci.width,
p->current_placement.starting_y - y - ci.height);
e.init(current_placement->starting_x + x,
current_placement->starting_y - y,
current_placement->starting_x + x + ci.width,
current_placement->starting_y - y - ci.height);
}
if (!detector_.has_placement(e, p->info->get_string(), p->minimum_distance))
@ -660,8 +663,8 @@ namespace mapnik
x += ci.width;
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;
}

View file

@ -24,24 +24,25 @@
#include <mapnik/wkb.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/feature.hpp>
namespace mapnik
{
struct wkb_reader
{
private:
enum wkbByteOrder {
struct wkb_reader
{
private:
enum wkbByteOrder {
wkbXDR=0,
wkbNDR=1
};
const char* wkb_;
unsigned size_;
unsigned pos_;
wkbByteOrder byteOrder_;
bool needSwap_;
public:
};
const char* wkb_;
unsigned size_;
unsigned pos_;
wkbByteOrder byteOrder_;
bool needSwap_;
public:
enum wkbGeometryType {
enum wkbGeometryType {
wkbPoint=1,
wkbLineString=2,
wkbPolygon=3,
@ -49,14 +50,14 @@ namespace mapnik
wkbMultiLineString=5,
wkbMultiPolygon=6,
wkbGeometryCollection=7
};
};
wkb_reader(const char* wkb,unsigned size)
wkb_reader(const char* wkb,unsigned size)
: wkb_(wkb),
size_(size),
pos_(0),
byteOrder_((wkbByteOrder)wkb_[0])
{
{
++pos_;
#ifndef WORDS_BIGENDIAN
@ -64,138 +65,132 @@ namespace mapnik
#else
needSwap_=byteOrder_?wkbNDR:wkbXDR;
#endif
}
}
~wkb_reader() {}
~wkb_reader() {}
geometry_ptr read()
{
geometry_ptr geom;
void read(Feature & feature)
{
int type=read_integer();
switch (type)
{
case wkbPoint:
geom = read_point();
break;
case wkbLineString:
geom = read_linestring();
break;
case wkbPolygon:
geom = read_polygon();
break;
case wkbMultiPoint:
geom = read_multipoint();
break;
case wkbMultiLineString:
geom = read_multilinestring();
break;
case wkbMultiPolygon:
geom=read_multipolygon();
break;
case wkbGeometryCollection:
break;
default:
break;
case wkbPoint:
read_point(feature);
break;
case wkbLineString:
read_linestring(feature);
break;
case wkbPolygon:
read_polygon(feature);
break;
case wkbMultiPoint:
read_multipoint(feature);
break;
case wkbMultiLineString:
read_multilinestring(feature);
break;
case wkbMultiPolygon:
read_multipolygon(feature);
break;
case wkbGeometryCollection:
break;
default:
break;
}
return geom;
}
}
private:
wkb_reader(const wkb_reader&);
wkb_reader& operator=(const wkb_reader&);
private:
wkb_reader(const wkb_reader&);
wkb_reader& operator=(const wkb_reader&);
int read_integer()
{
int read_integer()
{
int n;
if (!needSwap_)
{
memcpy(&n,wkb_+pos_,4);
memcpy(&n,wkb_+pos_,4);
}
else
{
const char* b=wkb_+pos_;
n = b[3]&0xff | (b[2]&0xff)<<8 | (b[1]&0xff)<<16 | (b[0]&0xff)<<24;
const char* b=wkb_+pos_;
n = b[3]&0xff | (b[2]&0xff)<<8 | (b[1]&0xff)<<16 | (b[0]&0xff)<<24;
}
pos_+=4;
return n;
}
}
double read_double()
{
double read_double()
{
double d;
if (!needSwap_)
{
memcpy(&d,wkb_+pos_,8);
memcpy(&d,wkb_+pos_,8);
}
else
{
// we rely on the fact that "long long" is in C standard,
// but not in C++ yet
// this is not quite portable
const char* b= wkb_+pos_;
long long n = (long long)b[7]&0xff |
((long long)b[6]&0xff)<<8 |
((long long)b[5]&0xff)<<16 |
((long long)b[4]&0xff)<<24 |
((long long)b[3]&0xff)<<32 |
((long long)b[2]&0xff)<<40 |
((long long)b[1]&0xff)<<48 |
((long long)b[0]&0xff)<<56;
memcpy(&d,&n,8);
// we rely on the fact that "long long" is in C standard,
// but not in C++ yet
// this is not quite portable
const char* b= wkb_+pos_;
long long n = (long long)b[7]&0xff |
((long long)b[6]&0xff)<<8 |
((long long)b[5]&0xff)<<16 |
((long long)b[4]&0xff)<<24 |
((long long)b[3]&0xff)<<32 |
((long long)b[2]&0xff)<<40 |
((long long)b[1]&0xff)<<48 |
((long long)b[0]&0xff)<<56;
memcpy(&d,&n,8);
}
pos_+=8;
return d;
}
}
void read_coords(CoordinateArray& ar)
{
void read_coords(CoordinateArray& ar)
{
int size=sizeof(coord<double,2>)*ar.size();
if (!needSwap_)
{
std::memcpy(&ar[0],wkb_+pos_,size);
std::memcpy(&ar[0],wkb_+pos_,size);
}
else
{
for (unsigned i=0;i<ar.size();++i)
{
ar[i].x=read_double();
ar[i].y=read_double();
}
for (unsigned i=0;i<ar.size();++i)
{
ar[i].x=read_double();
ar[i].y=read_double();
}
}
pos_+=size;
}
}
geometry_ptr read_point()
{
geometry_ptr pt(new point<vertex2d>);
void read_point(Feature & feature)
{
geometry2d * pt = new point<vertex2d>;
double x = read_double();
double y = read_double();
pt->move_to(x,y);
return pt;
}
geometry_ptr read_multipoint()
{
geometry_ptr pt(new point<vertex2d>);
feature.add_geometry(pt);
}
void read_multipoint(Feature & feature)
{
int num_points = read_integer();
for (int i=0;i<num_points;++i)
{
pos_+=5;
double x = read_double();
double y = read_double();
pt->move_to(x,y);
pos_+=5;
read_point(feature);
}
return pt;
}
geometry_ptr read_linestring()
{
geometry_ptr line(new line_string<vertex2d>);
}
void read_linestring(Feature & feature)
{
geometry2d * line = new line_string<vertex2d>;
int num_points=read_integer();
CoordinateArray ar(num_points);
read_coords(ar);
@ -203,85 +198,55 @@ namespace mapnik
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);
line->line_to(ar[i].x,ar[i].y);
}
return line;
}
geometry_ptr read_multilinestring()
{
geometry_ptr line(new line_string<vertex2d>);
feature.add_geometry(line);
}
void read_multilinestring(Feature & feature)
{
int num_lines=read_integer();
for (int i=0;i<num_lines;++i)
{
pos_+=5;
int num_points=read_integer();
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);
}
pos_+=5;
read_linestring(feature);
}
return line;
}
}
geometry_ptr read_polygon()
{
geometry_ptr poly(new polygon<vertex2d>);
void read_polygon(Feature & feature)
{
geometry2d * poly = new polygon<vertex2d>;
int num_rings=read_integer();
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);
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);
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;
}
feature.add_geometry(poly);
}
geometry_ptr read_multipolygon()
{
geometry_ptr poly(new polygon<vertex2d>);
void read_multipolygon(Feature & feature)
{
int num_polys=read_integer();
for (int i=0;i<num_polys;++i)
{
pos_+=5;
int num_rings=read_integer();
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);
}
pos_+=5;
read_polygon(feature);
}
return poly;
}
};
geometry_ptr geometry_utils::from_wkb(const char* wkb, unsigned size)
{
wkb_reader reader(wkb,size);
return reader.read();
}
}
};
void geometry_utils::from_wkb(Feature & feature,const char* wkb, unsigned size)
{
wkb_reader reader(wkb,size);
return reader.read(feature);
}
}