mirror of
https://github.com/mapnik/mapnik.git
synced 2025-12-08 20:13:09 +00:00
1. re-factored placement_finder to be more efficient. 'find_*' methods are templated on PathType.
2. PostGIS plug-in - optional 'multiple_geometries' parameter to control how Multi* geometries built. 3. MarkersSymbolizer (work in progress) to render vector shapes (markers) alonh a path with collision detection.
This commit is contained in:
parent
305b76012e
commit
8d51cb421b
@ -43,6 +43,7 @@ void export_rule()
|
||||
using mapnik::raster_symbolizer;
|
||||
using mapnik::shield_symbolizer;
|
||||
using mapnik::text_symbolizer;
|
||||
using mapnik::building_symbolizer;
|
||||
using mapnik::symbolizer;
|
||||
using mapnik::symbolizers;
|
||||
|
||||
@ -51,6 +52,7 @@ void export_rule()
|
||||
implicitly_convertible<line_symbolizer,symbolizer>();
|
||||
implicitly_convertible<line_pattern_symbolizer,symbolizer>();
|
||||
implicitly_convertible<polygon_symbolizer,symbolizer>();
|
||||
implicitly_convertible<building_symbolizer,symbolizer>();
|
||||
implicitly_convertible<polygon_pattern_symbolizer,symbolizer>();
|
||||
implicitly_convertible<raster_symbolizer,symbolizer>();
|
||||
implicitly_convertible<shield_symbolizer,symbolizer>();
|
||||
|
||||
@ -81,6 +81,9 @@ namespace mapnik {
|
||||
void process(building_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
void process(markers_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans);
|
||||
private:
|
||||
T & pixmap_;
|
||||
unsigned width_;
|
||||
@ -91,7 +94,7 @@ namespace mapnik {
|
||||
freetype_engine font_engine_;
|
||||
face_manager<freetype_engine> font_manager_;
|
||||
label_collision_detector4 detector_;
|
||||
placement_finder<label_collision_detector4> finder_;
|
||||
//placement_finder<label_collision_detector4> finder_;
|
||||
agg::rasterizer_scanline_aa<> ras_;
|
||||
};
|
||||
}
|
||||
|
||||
47
include/mapnik/arrow.hpp
Normal file
47
include/mapnik/arrow.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id$
|
||||
|
||||
#ifndef ARROW_HPP
|
||||
#define ARROW_HPP
|
||||
|
||||
#include <mapnik/envelope.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class arrow
|
||||
{
|
||||
public:
|
||||
arrow();
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double* x, double* y);
|
||||
Envelope<double> extent() const;
|
||||
private:
|
||||
unsigned pos_;
|
||||
double x_[7];
|
||||
double y_[7];
|
||||
unsigned cmd_[9];
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ARROW_HPP
|
||||
@ -58,7 +58,7 @@ namespace mapnik
|
||||
{
|
||||
output_.process(sym,f_,prj_trans_);
|
||||
}
|
||||
|
||||
|
||||
Processor & output_;
|
||||
Feature const& f_;
|
||||
proj_transform const& prj_trans_;
|
||||
|
||||
166
include/mapnik/markers_converter.hpp
Normal file
166
include/mapnik/markers_converter.hpp
Normal file
@ -0,0 +1,166 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id$
|
||||
|
||||
#ifndef MARKERS_CONVERTER_HPP
|
||||
#define MARKERS_CONVERTER_HPP
|
||||
|
||||
#include "agg_basics.h"
|
||||
#include "agg_trans_affine.h"
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
template <typename Locator, typename Shape, typename Detector>
|
||||
class markers_converter : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
markers_converter(Locator & locator,Shape & shape, Detector & detector);
|
||||
void rewind(unsigned path_id);
|
||||
unsigned vertex(double * x, double * y);
|
||||
private:
|
||||
enum status_e
|
||||
{
|
||||
initial,
|
||||
markers,
|
||||
polygon,
|
||||
stop
|
||||
};
|
||||
|
||||
Locator & locator_;
|
||||
Shape & shape_;
|
||||
Detector & detector_;
|
||||
status_e status_;
|
||||
agg::trans_affine transform_;
|
||||
agg::trans_affine mtx_;
|
||||
unsigned marker_;
|
||||
unsigned num_markers_;
|
||||
};
|
||||
|
||||
template <typename Locator,typename Shape,typename Detector>
|
||||
markers_converter<Locator,Shape,Detector>::markers_converter(Locator & locator,Shape & shape,
|
||||
Detector & detector)
|
||||
: locator_(locator),
|
||||
shape_(shape),
|
||||
detector_(detector),
|
||||
status_(initial),
|
||||
num_markers_(1),
|
||||
marker_(0) {}
|
||||
|
||||
template <typename Locator, typename Shape,typename Detector>
|
||||
void markers_converter<Locator,Shape,Detector>::rewind(unsigned path_id)
|
||||
{
|
||||
status_ = initial;
|
||||
marker_ = 0;
|
||||
num_markers_ = 1;
|
||||
}
|
||||
|
||||
template <typename Locator, typename Shape, typename Detector>
|
||||
unsigned markers_converter<Locator,Shape,Detector>::vertex( double * x, double * y)
|
||||
{
|
||||
unsigned cmd = agg::path_cmd_move_to;
|
||||
|
||||
double x1, y1, x2, y2;
|
||||
while (!agg::is_stop(cmd))
|
||||
{
|
||||
switch (status_)
|
||||
{
|
||||
case initial:
|
||||
if (num_markers_ == 0 )
|
||||
{
|
||||
cmd = agg::path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
locator_.rewind(marker_++);
|
||||
status_ = markers;
|
||||
num_markers_ = 0;
|
||||
break;
|
||||
case markers:
|
||||
{
|
||||
unsigned cmd1;
|
||||
while (agg::is_move_to(cmd1 = locator_.vertex(&x1,&y1)));
|
||||
if (agg::is_stop(cmd1))
|
||||
{
|
||||
status_ = stop;
|
||||
break;
|
||||
}
|
||||
unsigned cmd2 = locator_.vertex(&x2,&y2);
|
||||
if (agg::is_stop(cmd2))
|
||||
{
|
||||
status_ = stop;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
++num_markers_;
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
double d = ::sqrt(dx * dx + dy * dy);
|
||||
Envelope<double> ext = shape_.extent();
|
||||
if (d > ext.width())
|
||||
{
|
||||
mtx_ = transform_;
|
||||
mtx_ *= agg::trans_affine_rotation(::atan2(dy,dx));
|
||||
double marker_x = x1 + dx * 0.5;
|
||||
double marker_y = y1 + dy * 0.5;
|
||||
|
||||
mtx_ *= agg::trans_affine_translation(marker_x,marker_y);
|
||||
|
||||
double minx = ext.minx();
|
||||
double miny = ext.miny();
|
||||
double maxx = ext.maxx();
|
||||
double maxy = ext.maxy();
|
||||
mtx_.transform(&minx,&miny);
|
||||
mtx_.transform(&maxx,&maxy);
|
||||
|
||||
Envelope<double> e0(minx,miny,maxx,maxy);
|
||||
|
||||
if (detector_.has_placement(e0))
|
||||
{
|
||||
shape_.rewind(0);
|
||||
status_ = polygon;
|
||||
detector_.insert(ext);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case polygon:
|
||||
cmd = shape_.vertex(x,y);
|
||||
if (agg::is_stop(cmd))
|
||||
{
|
||||
cmd = agg::path_cmd_move_to;
|
||||
status_ = markers;
|
||||
break;
|
||||
}
|
||||
mtx_.transform(x,y);
|
||||
return cmd;
|
||||
case stop:
|
||||
cmd = agg::path_cmd_stop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MARKERS_CONVERTER_HPP
|
||||
41
include/mapnik/markers_symbolizer.hpp
Normal file
41
include/mapnik/markers_symbolizer.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id$
|
||||
|
||||
#ifndef MARKERS_SYMBOLIZER_HPP
|
||||
#define MARKERS_SYMBOLIZER_HPP
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct MAPNIK_DECL markers_symbolizer
|
||||
{
|
||||
public:
|
||||
markers_symbolizer()
|
||||
: allow_overlap_(false) {}
|
||||
private:
|
||||
bool allow_overlap_;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MARKERS_SYMBOLIZER_HPP
|
||||
@ -29,6 +29,7 @@
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/shield_symbolizer.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/text_path.hpp>
|
||||
|
||||
@ -39,33 +40,24 @@ namespace mapnik
|
||||
typedef text_path placement_element;
|
||||
|
||||
struct placement : boost::noncopyable
|
||||
{
|
||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||
{
|
||||
placement(string_info & info_,
|
||||
//path_type & shape_path_,
|
||||
shield_symbolizer const& sym);
|
||||
|
||||
template <typename SymbolizerT>
|
||||
placement(string_info *info_,
|
||||
CoordTransform *ctrans_,
|
||||
const proj_transform *proj_trans_,
|
||||
geometry2d const& geom_,
|
||||
SymbolizerT const& sym);
|
||||
placement(string_info & info_,
|
||||
//path_type & shape_path_,
|
||||
text_symbolizer const& sym);
|
||||
|
||||
~placement();
|
||||
|
||||
//helpers
|
||||
std::pair<double, double> get_position_at_distance(double target_distance);
|
||||
double get_total_distance();
|
||||
void clear_envelopes();
|
||||
|
||||
unsigned path_size() const;
|
||||
//std::pair<double, double> get_position_at_distance(double target_distance);
|
||||
//double get_total_distance();
|
||||
|
||||
string_info *info;
|
||||
|
||||
CoordTransform *ctrans;
|
||||
const proj_transform *proj_trans;
|
||||
geometry2d const& geom;
|
||||
path_type shape_path;
|
||||
|
||||
double total_distance_; //cache for distance
|
||||
string_info & info;
|
||||
//path_type & shape_path;
|
||||
//double total_distance_; //cache for distance
|
||||
|
||||
position displacement_;
|
||||
label_placement_e label_placement;
|
||||
@ -84,33 +76,47 @@ namespace mapnik
|
||||
|
||||
double max_char_angle_delta;
|
||||
double minimum_distance;
|
||||
|
||||
bool avoid_edges;
|
||||
|
||||
bool has_dimensions;
|
||||
std::pair<double, double> dimensions;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename DetectorT>
|
||||
class placement_finder : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
//e is the dimensions of the map, buffer is the buffer used for collission detection.
|
||||
//e is the dimensions of the map, buffer is the buffer used for collision detection.
|
||||
placement_finder(DetectorT & detector,Envelope<double> const& e);
|
||||
void find_placements(placement *p);
|
||||
|
||||
template <typename T>
|
||||
void find_placements(placement & p, T & path);
|
||||
|
||||
void find_point_placement(placement & p, double, double);
|
||||
|
||||
template <typename T>
|
||||
void find_placements_with_spacing(placement & p, T & path);
|
||||
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
bool find_placement_follow(placement *p);
|
||||
bool find_placement_horizontal(placement *p);
|
||||
bool build_path_follow(placement *p, double target_distance);
|
||||
bool build_path_horizontal(placement *p, double target_distance);
|
||||
std::vector<double> get_ideal_placements(placement *p);
|
||||
void update_detector(placement *p);
|
||||
private:
|
||||
template <typename T>
|
||||
bool find_placement_follow(placement & p, T & path);
|
||||
|
||||
template <typename T>
|
||||
bool find_placement_horizontal(placement & p, T & path);
|
||||
|
||||
template <typename T>
|
||||
bool build_path_follow(placement & p, double target_distance, T & path);
|
||||
|
||||
template <typename T>
|
||||
bool build_path_horizontal(placement & p, double target_distance, T & path);
|
||||
|
||||
void get_ideal_placements(placement & p, double distance, std::vector<double>&);
|
||||
|
||||
void update_detector(placement & p);
|
||||
|
||||
DetectorT & detector_;
|
||||
Envelope<double> dimensions_;
|
||||
Envelope<double> const& dimensions_;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -31,8 +31,10 @@
|
||||
#include <mapnik/raster_symbolizer.hpp>
|
||||
#include <mapnik/shield_symbolizer.hpp>
|
||||
#include <mapnik/text_symbolizer.hpp>
|
||||
#include <mapnik/markers_symbolizer.hpp>
|
||||
#include <mapnik/filter.hpp>
|
||||
#include <mapnik/filter_visitor.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
@ -94,6 +96,11 @@ namespace mapnik
|
||||
return (&lhs == &rhs);
|
||||
}
|
||||
|
||||
inline bool operator==(markers_symbolizer const& lhs,
|
||||
markers_symbolizer const& rhs)
|
||||
{
|
||||
return (&lhs == &rhs);
|
||||
}
|
||||
typedef boost::variant<point_symbolizer,
|
||||
line_symbolizer,
|
||||
line_pattern_symbolizer,
|
||||
@ -102,7 +109,8 @@ namespace mapnik
|
||||
raster_symbolizer,
|
||||
shield_symbolizer,
|
||||
text_symbolizer,
|
||||
building_symbolizer> symbolizer;
|
||||
building_symbolizer,
|
||||
markers_symbolizer> symbolizer;
|
||||
|
||||
|
||||
typedef std::vector<symbolizer> symbolizers;
|
||||
|
||||
@ -66,17 +66,17 @@ namespace mapnik
|
||||
characters_.push_back(new character_info(c, width, height));
|
||||
}
|
||||
|
||||
unsigned num_characters()
|
||||
unsigned num_characters() const
|
||||
{
|
||||
return characters_.size();
|
||||
}
|
||||
|
||||
character_info at(unsigned i)
|
||||
character_info at(unsigned i) const
|
||||
{
|
||||
return characters_[i];
|
||||
}
|
||||
|
||||
character_info operator[](unsigned i)
|
||||
character_info operator[](unsigned i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
@ -87,12 +87,13 @@ namespace mapnik
|
||||
height_ = height;
|
||||
}
|
||||
|
||||
std::pair<double, double> get_dimensions()
|
||||
std::pair<double, double> get_dimensions() const
|
||||
{
|
||||
return std::pair<double, double>(width_, height_);
|
||||
}
|
||||
|
||||
std::wstring get_string() {
|
||||
std::wstring const& get_string() const
|
||||
{
|
||||
return string_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -33,7 +33,7 @@ namespace mapnik
|
||||
class MAPNIK_DECL geometry_utils
|
||||
{
|
||||
public:
|
||||
static void from_wkb(Feature & feature,const char* wkb, unsigned size);
|
||||
static void from_wkb(Feature & feature,const char* wkb, unsigned size, bool multiple_geometries = false);
|
||||
private:
|
||||
geometry_utils();
|
||||
geometry_utils(geometry_utils const&);
|
||||
|
||||
@ -22,14 +22,21 @@
|
||||
|
||||
//$Id: postgis.cc 44 2005-04-22 18:53:54Z pavlenko $
|
||||
|
||||
// mapnik
|
||||
#include "connection_manager.hpp"
|
||||
#include "postgis.hpp"
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "connection_manager.hpp"
|
||||
#include "postgis.hpp"
|
||||
|
||||
|
||||
DATASOURCE_PLUGIN(postgis_datasource)
|
||||
|
||||
@ -61,7 +68,9 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
||||
|
||||
boost::optional<int> initial_size = params_.get<int>("inital_size",1);
|
||||
boost::optional<int> max_size = params_.get<int>("max_size",10);
|
||||
|
||||
|
||||
multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);
|
||||
|
||||
ConnectionManager *mgr=ConnectionManager::instance();
|
||||
mgr->registerPool(creator_, *initial_size, *max_size);
|
||||
|
||||
@ -194,7 +203,7 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
||||
std::clog << s.str() << "\n";
|
||||
#endif
|
||||
shared_ptr<ResultSet> rs=conn->executeQuery(s.str(),1);
|
||||
return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),props.size()));
|
||||
return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),multiple_geometries_,props.size()));
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
@ -233,7 +242,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
|
||||
std::clog << s.str() << "\n";
|
||||
#endif
|
||||
shared_ptr<ResultSet> rs=conn->executeQuery(s.str(),1);
|
||||
return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),size));
|
||||
return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),multiple_geometries_, size));
|
||||
}
|
||||
}
|
||||
return featureset_ptr();
|
||||
|
||||
@ -62,6 +62,7 @@ class postgis_datasource : public datasource
|
||||
mutable mapnik::Envelope<double> extent_;
|
||||
layer_descriptor desc_;
|
||||
ConnectionCreator<Connection> creator_;
|
||||
bool multiple_geometries_;
|
||||
static const std::string name_;
|
||||
public:
|
||||
static std::string name();
|
||||
@ -82,6 +83,7 @@ class postgis_featureset : public mapnik::Featureset
|
||||
{
|
||||
private:
|
||||
boost::shared_ptr<ResultSet> rs_;
|
||||
bool multiple_geometries_;
|
||||
unsigned num_attrs_;
|
||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||
mutable int totalGeomSize_;
|
||||
@ -89,6 +91,7 @@ class postgis_featureset : public mapnik::Featureset
|
||||
public:
|
||||
postgis_featureset(boost::shared_ptr<ResultSet> const& rs,
|
||||
std::string const& encoding,
|
||||
bool multiple_geometries,
|
||||
unsigned num_attrs);
|
||||
feature_ptr next();
|
||||
~postgis_featureset();
|
||||
|
||||
@ -39,8 +39,10 @@ using mapnik::geometry_utils;
|
||||
|
||||
postgis_featureset::postgis_featureset(boost::shared_ptr<ResultSet> const& rs,
|
||||
std::string const& encoding,
|
||||
bool multiple_geometries,
|
||||
unsigned num_attrs=0)
|
||||
: rs_(rs),
|
||||
multiple_geometries_(multiple_geometries),
|
||||
num_attrs_(num_attrs),
|
||||
tr_(new transcoder(encoding)),
|
||||
totalGeomSize_(0),
|
||||
@ -53,7 +55,7 @@ feature_ptr postgis_featureset::next()
|
||||
feature_ptr feature(new Feature(count_));
|
||||
int size=rs_->getFieldLength(0);
|
||||
const char *data = rs_->getValue(0);
|
||||
geometry_utils::from_wkb(*feature,data,size);
|
||||
geometry_utils::from_wkb(*feature,data,size,multiple_geometries_);
|
||||
totalGeomSize_+=size;
|
||||
|
||||
for (unsigned pos=1;pos<num_attrs_+1;++pos)
|
||||
|
||||
@ -67,6 +67,7 @@ source = Split(
|
||||
memory_datasource.cpp
|
||||
stroke.cpp
|
||||
symbolizer.cpp
|
||||
arrow.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@ -23,19 +23,17 @@
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/placement_finder.hpp>
|
||||
#include <mapnik/markers_converter.hpp>
|
||||
#include <mapnik/arrow.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.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_path_storage.h"
|
||||
#include "agg_span_allocator.h"
|
||||
#include "agg_span_pattern_rgba.h"
|
||||
@ -43,11 +41,11 @@
|
||||
#include "agg_conv_stroke.h"
|
||||
#include "agg_conv_dash.h"
|
||||
#include "agg_conv_contour.h"
|
||||
#include "agg_conv_clip_polyline.h"
|
||||
#include "agg_vcgen_stroke.h"
|
||||
#include "agg_conv_adaptor_vcgen.h"
|
||||
#include "agg_conv_smooth_poly1.h"
|
||||
#include "agg_conv_marker.h"
|
||||
#include "agg_arrowhead.h"
|
||||
#include "agg_vcgen_markers_term.h"
|
||||
#include "agg_renderer_outline_aa.h"
|
||||
#include "agg_rasterizer_outline_aa.h"
|
||||
@ -59,6 +57,7 @@
|
||||
#include "agg_pattern_filters_rgba.h"
|
||||
#include "agg_renderer_outline_image.h"
|
||||
#include "agg_vpgen_clip_polyline.h"
|
||||
#include "agg_arrowhead.h"
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
@ -107,8 +106,8 @@ namespace mapnik
|
||||
t_(m.getWidth(),m.getHeight(),m.getCurrentExtent(),offset_x,offset_y),
|
||||
font_engine_(),
|
||||
font_manager_(font_engine_),
|
||||
detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64)),
|
||||
finder_(detector_,Envelope<double>(0 ,0, m.getWidth(), m.getHeight()))
|
||||
detector_(Envelope<double>(-64 ,-64, m.getWidth() + 64 ,m.getHeight() + 64))
|
||||
//finder_(detector_,Envelope<double>(0 ,0, m.getWidth(), m.getHeight()))
|
||||
{
|
||||
boost::optional<Color> bg = m.background();
|
||||
if (bg) pixmap_.setBackground(*bg);
|
||||
@ -144,7 +143,7 @@ namespace mapnik
|
||||
#endif
|
||||
if (lay.clear_label_cache())
|
||||
{
|
||||
finder_.clear();
|
||||
//finder_.clear(); // FIXME!!!!!!!!
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +164,7 @@ namespace mapnik
|
||||
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
|
||||
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
||||
|
||||
Color const& fill_ = sym.get_fill();
|
||||
Color const& fill_ = sym.get_fill();
|
||||
ras_.reset();
|
||||
agg::scanline_u8 sl;
|
||||
ren_base renb(pixf_);
|
||||
@ -178,8 +177,12 @@ namespace mapnik
|
||||
geometry2d const& geom=feature.get_geometry(i);
|
||||
if (geom.num_points() > 2)
|
||||
{
|
||||
path_type path(t_,geom,prj_trans);
|
||||
path_type path(t_,geom,prj_trans);
|
||||
//agg::conv_smooth_poly1<path_type> smooth(path);
|
||||
//smooth.smooth_value(0.6);
|
||||
//agg::conv_curve<agg::conv_smooth_poly1<path_type> > curve(smooth);
|
||||
ras_.add_path(path);
|
||||
//ras_.add_path(curve);
|
||||
}
|
||||
}
|
||||
ren.color(agg::rgba8(r, g, b, int(255 * sym.get_opacity())));
|
||||
@ -229,7 +232,7 @@ namespace mapnik
|
||||
for (unsigned j=1;j<geom.num_points();++j)
|
||||
{
|
||||
double x,y;
|
||||
unsigned cm = geom.vertex(&x,&y);
|
||||
cm = geom.vertex(&x,&y);
|
||||
if (cm == SEG_MOVETO)
|
||||
{
|
||||
frame->move_to(x,y);
|
||||
@ -367,7 +370,6 @@ namespace mapnik
|
||||
else
|
||||
{
|
||||
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);
|
||||
@ -437,6 +439,7 @@ namespace mapnik
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||
std::wstring text = feature[sym.get_name()].to_unicode();
|
||||
boost::shared_ptr<ImageData32> const& data = sym.get_image();
|
||||
if (text.length() > 0 && data)
|
||||
@ -449,17 +452,21 @@ namespace mapnik
|
||||
ren.set_fill(sym.get_fill());
|
||||
string_info info(text);
|
||||
ren.get_string_info(&info);
|
||||
|
||||
Envelope<double> box(-64,-64,width_+64,height_+64);
|
||||
placement_finder<label_collision_detector4> finder(detector_,box);
|
||||
|
||||
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);
|
||||
path_type path(t_,geom,prj_trans);
|
||||
placement text_placement(info, sym);
|
||||
text_placement.avoid_edges = sym.get_avoid_edges();
|
||||
finder.find_placements<path_type>(text_placement,path);
|
||||
|
||||
finder_.find_placements(&text_placement);
|
||||
|
||||
for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
|
||||
{
|
||||
int w = data->width();
|
||||
@ -589,12 +596,53 @@ namespace mapnik
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||
typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
|
||||
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
|
||||
arrow arrow_;
|
||||
//double k = ::pow(1.2, 0.7);
|
||||
//arrow_.head(4 * k, 4 * k, 3 * k, 2 * k);
|
||||
//Color const& fill_ = sym.get_fill();
|
||||
ras_.reset();
|
||||
agg::scanline_u8 sl;
|
||||
ren_base renb(pixf_);
|
||||
unsigned r = 0;// fill_.red();
|
||||
unsigned g = 0; //fill_.green();
|
||||
unsigned b = 255; //fill_.blue();
|
||||
renderer ren(renb);
|
||||
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);
|
||||
|
||||
agg::conv_dash <path_type> dash(path);
|
||||
dash.add_dash(20.0,200.0);
|
||||
//dash.dash_start(100.0);
|
||||
markers_converter<agg::conv_dash<path_type>,
|
||||
arrow,
|
||||
label_collision_detector4>
|
||||
marker(dash, arrow_, detector_);
|
||||
ras_.add_path(marker);
|
||||
}
|
||||
}
|
||||
ren.color(agg::rgba8(r, g, b, 255));
|
||||
agg::render_scanlines(ras_, sl, ren);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::process(text_symbolizer const& sym,
|
||||
Feature const& feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
|
||||
typedef coord_transform2<CoordTransform,geometry2d> path_type;
|
||||
|
||||
std::wstring text = feature[sym.get_name()].to_unicode();
|
||||
if ( text.length() > 0 )
|
||||
{
|
||||
@ -608,7 +656,9 @@ namespace mapnik
|
||||
ren.set_halo_fill(sym.get_halo_fill());
|
||||
ren.set_halo_radius(sym.get_halo_radius());
|
||||
|
||||
Envelope<double> ext = t_.extent();
|
||||
Envelope<double> box(-64,-64,width_+64,height_+64);
|
||||
placement_finder<label_collision_detector4> finder(detector_,box);
|
||||
|
||||
string_info info(text);
|
||||
ren.get_string_info(&info);
|
||||
unsigned num_geom = feature.num_geometries();
|
||||
@ -617,38 +667,31 @@ namespace mapnik
|
||||
geometry2d const& geom = feature.get_geometry(i);
|
||||
if (geom.num_points() > 0) // don't bother with empty geometries
|
||||
{
|
||||
//agg::vpgen_clip_polyline clipped_path;
|
||||
// clip to the bbox
|
||||
path_type path(t_,geom,prj_trans);
|
||||
//agg::conv_clip_polyline<path_type> clipped_path(path);
|
||||
//clipped_path.clip_box(0,0,width_,height_);
|
||||
//placement<agg::conv_clip_polyline<path_type> >
|
||||
// text_placement(&info, &t_, &prj_trans, clipped_path, sym);
|
||||
//placement_finder<agg::conv_clip_polyline<path_type>,
|
||||
// label_collision_detector4> finder(detector_,box);
|
||||
placement text_placement(info,sym);
|
||||
if (sym.get_label_placement() == POINT_PLACEMENT)
|
||||
{
|
||||
double label_x, label_y, z=0.0;
|
||||
geom.label_position(&label_x, &label_y);
|
||||
prj_trans.backward(label_x,label_y, z);
|
||||
t_.forward(&label_x,&label_y);
|
||||
finder.find_point_placement(text_placement,label_x,label_y);
|
||||
}
|
||||
else if (sym.get_label_spacing() > 0 )
|
||||
{
|
||||
finder.find_placements_with_spacing<path_type>(text_placement,path);
|
||||
}
|
||||
else
|
||||
{
|
||||
finder.find_placements<path_type>(text_placement,path);
|
||||
}
|
||||
|
||||
//clipped_path.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
|
||||
|
||||
//for (unsigned j=0;j<geom.num_points();++j)
|
||||
//{
|
||||
// double x,y;
|
||||
/// unsigned c = geom.vertex(&x,&y);
|
||||
// if (c == SEG_MOVETO)
|
||||
// clipped_path.move_to(x,y);
|
||||
// else if (c == SEG_LINETO)
|
||||
// clipped_path.line_to(x,y);
|
||||
//}
|
||||
//line_string_impl line;
|
||||
//while (1)
|
||||
//{
|
||||
// double x,y;
|
||||
// unsigned cmd = clipped_path.vertex(&x,&y);
|
||||
// if (cmd == SEG_END) break;
|
||||
// else if (cmd == SEG_MOVETO)
|
||||
// {
|
||||
// line.move_to(x,y);
|
||||
// }
|
||||
// else if (cmd == SEG_LINETO)
|
||||
// {
|
||||
// line.line_to(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;
|
||||
|
||||
66
src/arrow.cpp
Normal file
66
src/arrow.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2006 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//$Id$
|
||||
|
||||
#include <mapnik/arrow.hpp>
|
||||
|
||||
#include <agg_basics.h>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
arrow::arrow()
|
||||
: pos_(0)
|
||||
{
|
||||
x_[0] = -7.0; y_[0] = 1.0; cmd_[0] = agg::path_cmd_move_to;
|
||||
x_[1] = 1.0; y_[1] = 1.0; cmd_[1] = agg::path_cmd_line_to;
|
||||
x_[2] = 1.0; y_[2] = 3.0; cmd_[2] = agg::path_cmd_line_to;
|
||||
x_[3] = 7.0; y_[3] = 0.0; cmd_[3] = agg::path_cmd_line_to;
|
||||
x_[4] = 1.0; y_[4] =-3.0; cmd_[4] = agg::path_cmd_line_to;
|
||||
x_[5] = 1.0; y_[5] =-1.0; cmd_[5] = agg::path_cmd_line_to;
|
||||
x_[6] = -7.0; y_[6] =-1.0; cmd_[6] = agg::path_cmd_line_to;
|
||||
cmd_[7] = agg::path_cmd_end_poly | agg::path_flags_close | agg::path_flags_ccw;
|
||||
cmd_[8] = agg::path_cmd_stop;
|
||||
}
|
||||
|
||||
void arrow::rewind(unsigned )
|
||||
{
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
unsigned arrow::vertex(double* x, double* y)
|
||||
{
|
||||
if(pos_ < 7 )
|
||||
{
|
||||
*x = x_[pos_];
|
||||
*y = y_[pos_];
|
||||
return cmd_[pos_++];
|
||||
}
|
||||
return agg::path_cmd_stop;
|
||||
}
|
||||
|
||||
Envelope<double> arrow::extent() const
|
||||
{
|
||||
return Envelope<double>(-7,-3,7,3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,6 +77,7 @@ namespace mapnik
|
||||
void parse_line_symbolizer( rule_type & rule, ptree const & sym);
|
||||
void parse_polygon_symbolizer( rule_type & rule, ptree const & sym);
|
||||
void parse_building_symbolizer( rule_type & rule, ptree const & sym );
|
||||
void parse_markers_symbolizer( rule_type & rule, ptree const & sym );
|
||||
|
||||
void ensure_font_face( const text_symbolizer & text_symbol );
|
||||
|
||||
@ -364,6 +365,11 @@ namespace mapnik
|
||||
{
|
||||
rule.append(raster_symbolizer());
|
||||
}
|
||||
else if ( sym.first == "MarkersSymbolizer")
|
||||
{
|
||||
rule.append(markers_symbolizer());
|
||||
}
|
||||
|
||||
else if ( sym.first != "MinScaleDenominator" &&
|
||||
sym.first != "MaxScaleDenominator" &&
|
||||
sym.first != "Filter" &&
|
||||
@ -584,7 +590,15 @@ namespace mapnik
|
||||
{
|
||||
text_symbol.set_allow_overlap( * allow_overlap );
|
||||
}
|
||||
|
||||
|
||||
// max_char_angle_delta
|
||||
optional<double> max_char_angle_delta =
|
||||
get_opt_attr<double>(sym, "max_char_angle_delta");
|
||||
if (max_char_angle_delta)
|
||||
{
|
||||
text_symbol.set_max_char_angle_delta( * max_char_angle_delta);
|
||||
}
|
||||
|
||||
if ( strict_ )
|
||||
{
|
||||
ensure_font_face( text_symbol );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -176,6 +176,11 @@ namespace mapnik
|
||||
set_css( sym_node, "fill-opacity", sym.get_opacity() );
|
||||
}
|
||||
}
|
||||
|
||||
void operator () ( markers_symbolizer const& )
|
||||
{
|
||||
// FIXME!!!!!
|
||||
}
|
||||
private:
|
||||
serialize_symbolizer();
|
||||
void add_image_attributes(ptree & node, const symbolizer_with_image & sym)
|
||||
|
||||
107
src/wkb.cpp
107
src/wkb.cpp
@ -70,7 +70,7 @@ namespace mapnik
|
||||
|
||||
~wkb_reader() {}
|
||||
|
||||
void read(Feature & feature)
|
||||
void read_multi(Feature & feature)
|
||||
{
|
||||
int type=read_integer();
|
||||
switch (type)
|
||||
@ -99,6 +99,36 @@ namespace mapnik
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void read(Feature & feature)
|
||||
{
|
||||
int type=read_integer();
|
||||
switch (type)
|
||||
{
|
||||
case wkbPoint:
|
||||
read_point(feature);
|
||||
break;
|
||||
case wkbLineString:
|
||||
read_linestring(feature);
|
||||
break;
|
||||
case wkbPolygon:
|
||||
read_polygon(feature);
|
||||
break;
|
||||
case wkbMultiPoint:
|
||||
read_multipoint_2(feature);
|
||||
break;
|
||||
case wkbMultiLineString:
|
||||
read_multilinestring_2(feature);
|
||||
break;
|
||||
case wkbMultiPolygon:
|
||||
read_multipolygon_2(feature);
|
||||
break;
|
||||
case wkbGeometryCollection:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
wkb_reader(const wkb_reader&);
|
||||
@ -189,6 +219,20 @@ namespace mapnik
|
||||
}
|
||||
}
|
||||
|
||||
void read_multipoint_2(Feature & feature)
|
||||
{
|
||||
geometry2d * pt = new point<vertex2d>;
|
||||
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);
|
||||
}
|
||||
feature.add_geometry(pt);
|
||||
}
|
||||
|
||||
void read_linestring(Feature & feature)
|
||||
{
|
||||
geometry2d * line = new line_string<vertex2d>;
|
||||
@ -214,17 +258,41 @@ namespace mapnik
|
||||
}
|
||||
}
|
||||
|
||||
void read_multilinestring_2(Feature & feature)
|
||||
{
|
||||
geometry2d * line = new line_string<vertex2d>;
|
||||
int num_lines=read_integer();
|
||||
unsigned capacity = 0;
|
||||
for (int i=0;i<num_lines;++i)
|
||||
{
|
||||
pos_+=5;
|
||||
int num_points=read_integer();
|
||||
capacity+=num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
line->set_capacity(capacity);
|
||||
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);
|
||||
}
|
||||
}
|
||||
feature.add_geometry(line);
|
||||
}
|
||||
|
||||
void read_polygon(Feature & feature)
|
||||
{
|
||||
geometry2d * poly = new polygon<vertex2d>;
|
||||
int num_rings=read_integer();
|
||||
unsigned capacity = 0;
|
||||
for (int i=0;i<num_rings;++i)
|
||||
{
|
||||
int num_points=read_integer();
|
||||
capacity+=num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
poly->set_capacity(capacity);
|
||||
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);
|
||||
@ -243,11 +311,42 @@ namespace mapnik
|
||||
read_polygon(feature);
|
||||
}
|
||||
}
|
||||
|
||||
void read_multipolygon_2(Feature & feature)
|
||||
{
|
||||
geometry2d * poly = new polygon<vertex2d>;
|
||||
int num_polys=read_integer();
|
||||
unsigned capacity = 0;
|
||||
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();
|
||||
capacity += num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
poly->set_capacity(capacity);
|
||||
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);
|
||||
}
|
||||
}
|
||||
feature.add_geometry(poly);
|
||||
}
|
||||
};
|
||||
|
||||
void geometry_utils::from_wkb(Feature & feature,const char* wkb, unsigned size)
|
||||
void geometry_utils::from_wkb(Feature & feature,const char* wkb, unsigned size, bool multiple_geometries)
|
||||
{
|
||||
wkb_reader reader(wkb,size);
|
||||
return reader.read(feature);
|
||||
if (multiple_geometries)
|
||||
return reader.read_multi(feature);
|
||||
else
|
||||
return reader.read(feature);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user