Merge branch 'master' into python-textplacement
This commit is contained in:
commit
ceda45249f
48 changed files with 748 additions and 633 deletions
|
@ -134,7 +134,7 @@ mapnik::value_holder get_params_by_key2(mapnik::parameters const& p, std::string
|
|||
|
||||
mapnik::parameter get_params_by_index(mapnik::parameters const& p, int index)
|
||||
{
|
||||
if (index < 0 || index > p.size())
|
||||
if (index < 0 || static_cast<unsigned>(index) > p.size())
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "Index is out of range");
|
||||
throw boost::python::error_already_set();
|
||||
|
@ -143,7 +143,7 @@ mapnik::parameter get_params_by_index(mapnik::parameters const& p, int index)
|
|||
parameters::const_iterator itr = p.begin();
|
||||
parameters::const_iterator end = p.end();
|
||||
|
||||
unsigned idx = 0;
|
||||
int idx = 0;
|
||||
while (itr != end)
|
||||
{
|
||||
if (idx == index)
|
||||
|
|
|
@ -60,13 +60,18 @@ public:
|
|||
attribute_descriptor& operator=(attribute_descriptor const& other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
name_=other.name_;
|
||||
type_=other.type_;
|
||||
primary_key_=other.primary_key_;
|
||||
size_=other.size_;
|
||||
precision_=other.precision_;
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
{
|
||||
name_=other.name_;
|
||||
type_=other.type_;
|
||||
primary_key_=other.primary_key_;
|
||||
size_=other.size_;
|
||||
precision_=other.precision_;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
std::string const& get_name() const
|
||||
|
|
|
@ -229,16 +229,17 @@ struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|||
("\\r", '\r')("\\t", '\t')("\\v", '\v')("\\\\", '\\')
|
||||
("\\\'", '\'')("\\\"", '\"')
|
||||
;
|
||||
|
||||
|
||||
#if BOOST_VERSION > 104500
|
||||
quote_char %= char_('\'') | char_('"');
|
||||
ustring %= omit[quote_char[_a = _1]]
|
||||
>> *(unesc_char | "\\x" >> hex | (char_ - lit(_a)))
|
||||
>> lit(_a);
|
||||
|
||||
quote_char %= char_('\'') | char_('"');
|
||||
|
||||
#if BOOST_VERSION > 104200
|
||||
attr %= '[' >> no_skip[+~char_(']')] >> ']';
|
||||
#else
|
||||
ustring %= lit('\'')
|
||||
>> *(unesc_char | "\\x" >> hex | (char_ - lit('\'')))
|
||||
>> lit('\'');
|
||||
attr %= '[' >> lexeme[+(char_ - ']')] >> ']';
|
||||
#endif
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
namespace mapnik
|
||||
{
|
||||
MAPNIK_DECL std::string to_expression_string(expr_node const& );
|
||||
MAPNIK_DECL std::string to_expression_string(expr_node const& node);
|
||||
}
|
||||
|
||||
#endif // MAPNIK_EXPRESSION_STRING_HPP
|
||||
|
|
|
@ -128,7 +128,9 @@ public:
|
|||
data_[itr->second] = val;
|
||||
}
|
||||
else
|
||||
throw std::out_of_range("Key doesn't exist");
|
||||
{
|
||||
throw std::out_of_range(std::string("Key does not exist: '") + key + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,7 +164,10 @@ public:
|
|||
{
|
||||
return data_[itr->second];
|
||||
}
|
||||
throw std::out_of_range("Key doesn't exist");
|
||||
else
|
||||
{
|
||||
throw std::out_of_range(std::string("Key does not exist: '") + key + "'");
|
||||
}
|
||||
}
|
||||
|
||||
value_type const& get(std::size_t index) const
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_FILL_HPP
|
||||
#define MAPNIK_FILL_HPP
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
class fill
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_FILL_HPP
|
2
include/mapnik/filter_factory.hpp
Normal file
2
include/mapnik/filter_factory.hpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#warning "filter_factory.hpp" is now called "expression.hpp"
|
||||
#include <mapnik/expression.hpp>
|
58
include/mapnik/formatting/expression.hpp
Normal file
58
include/mapnik/formatting/expression.hpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef FORMATTING_EXPRESSION_HPP
|
||||
#define FORMATTING_EXPRESSION_HPP
|
||||
|
||||
#include <mapnik/formatting/base.hpp>
|
||||
#include <mapnik/expression.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
namespace formatting {
|
||||
class expression_format: public node {
|
||||
public:
|
||||
void to_xml(boost::property_tree::ptree &xml) const;
|
||||
static node_ptr from_xml(boost::property_tree::ptree const& xml);
|
||||
virtual void apply(char_properties const& p, Feature const& feature, processed_text &output) const;
|
||||
virtual void add_expressions(expression_set &output) const;
|
||||
|
||||
void set_child(node_ptr child);
|
||||
node_ptr get_child() const;
|
||||
|
||||
expression_ptr face_name;
|
||||
expression_ptr text_size;
|
||||
expression_ptr character_spacing;
|
||||
expression_ptr line_spacing;
|
||||
expression_ptr text_opacity;
|
||||
expression_ptr wrap_before;
|
||||
expression_ptr wrap_char;
|
||||
expression_ptr fill;
|
||||
expression_ptr halo_fill;
|
||||
expression_ptr halo_radius;
|
||||
|
||||
private:
|
||||
node_ptr child_;
|
||||
static expression_ptr get_expression(boost::property_tree::ptree const& xml, std::string name);
|
||||
};
|
||||
} //ns formatting
|
||||
} //ns mapnik
|
||||
#endif // FORMATTING_EXPRESSION_HPP
|
|
@ -1,51 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_GAMMA_HPP
|
||||
#define MAPNIK_GAMMA_HPP
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
struct MAPNIK_DECL gamma
|
||||
{
|
||||
unsigned char g2l[256];
|
||||
unsigned char l2g[256];
|
||||
gamma(double gamma=2.0)
|
||||
{
|
||||
int result;
|
||||
for (int i=0;i< 256;i++)
|
||||
{
|
||||
result=(int)(std::pow(i/255.0,gamma) * 255.0 + 0.5);
|
||||
g2l[i]=(unsigned char)result;
|
||||
}
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
result = (int)(std::pow(i/255.0, 1/gamma) * 255.0 + 0.5);
|
||||
l2g[i] = (unsigned char)result;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAPNIK_GAMMA_HPP
|
|
@ -48,6 +48,7 @@ public:
|
|||
typedef T coord_type;
|
||||
typedef Container<coord_type> container_type;
|
||||
typedef typename container_type::value_type value_type;
|
||||
typedef typename container_type::size_type size_type;
|
||||
private:
|
||||
container_type cont_;
|
||||
eGeomType type_;
|
||||
|
@ -389,11 +390,7 @@ public:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_capacity(size_t size)
|
||||
{
|
||||
cont_.set_capacity(size);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef geometry<double,vertex_vector> geometry_type;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/gamma.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
|
|
|
@ -40,7 +40,8 @@ namespace mapnik { namespace json {
|
|||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
namespace ascii = boost::spirit::ascii;
|
||||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
struct generate_id
|
||||
{
|
||||
|
@ -58,7 +59,7 @@ struct generate_id
|
|||
|
||||
template <typename Iterator, typename FeatureType>
|
||||
struct feature_collection_grammar :
|
||||
qi::grammar<Iterator, std::vector<feature_ptr>(), ascii::space_type>
|
||||
qi::grammar<Iterator, std::vector<feature_ptr>(), space_type>
|
||||
{
|
||||
feature_collection_grammar(context_ptr const& ctx, mapnik::transcoder const& tr)
|
||||
: feature_collection_grammar::base_type(feature_collection,"feature-collection"),
|
||||
|
@ -113,10 +114,10 @@ struct feature_collection_grammar :
|
|||
}
|
||||
|
||||
context_ptr ctx_;
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(), ascii::space_type> feature_collection; // START
|
||||
qi::rule<Iterator, ascii::space_type> type;
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(), ascii::space_type> features;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(std::vector<feature_ptr>&), ascii::space_type> feature;
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(), space_type> feature_collection; // START
|
||||
qi::rule<Iterator, space_type> type;
|
||||
qi::rule<Iterator, std::vector<feature_ptr>(), space_type> features;
|
||||
qi::rule<Iterator, qi::locals<feature_ptr,int>, void(std::vector<feature_ptr>&), space_type> feature;
|
||||
feature_grammar<Iterator,FeatureType> feature_g;
|
||||
boost::phoenix::function<generate_id> generate_id_;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace mapnik { namespace json {
|
|||
namespace qi = boost::spirit::qi;
|
||||
namespace phoenix = boost::phoenix;
|
||||
namespace fusion = boost::fusion;
|
||||
namespace ascii = boost::spirit::ascii;
|
||||
namespace standard_wide = boost::spirit::standard_wide;
|
||||
using standard_wide::space_type;
|
||||
|
||||
class attribute_value_visitor
|
||||
: public boost::static_visitor<mapnik::value>
|
||||
|
@ -132,7 +133,7 @@ struct cleanup
|
|||
template <typename Iterator, typename FeatureType>
|
||||
struct feature_grammar :
|
||||
qi::grammar<Iterator, void(FeatureType&),
|
||||
ascii::space_type>
|
||||
space_type>
|
||||
{
|
||||
feature_grammar(mapnik::transcoder const& tr)
|
||||
: feature_grammar::base_type(feature,"feature"),
|
||||
|
@ -146,7 +147,7 @@ struct feature_grammar :
|
|||
#else
|
||||
using qi::lexeme;
|
||||
#endif
|
||||
using ascii::char_;
|
||||
using standard_wide::char_;
|
||||
using qi::_val;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
|
@ -328,49 +329,49 @@ struct feature_grammar :
|
|||
|
||||
// start
|
||||
// generic JSON
|
||||
qi::rule<Iterator,ascii::space_type> value;
|
||||
qi::rule<Iterator,space_type> value;
|
||||
qi::symbols<char const, char const> unesc_char;
|
||||
qi::uint_parser< unsigned, 16, 4, 4 > hex4 ;
|
||||
qi::rule<Iterator,std::string(), ascii::space_type> string_;
|
||||
qi::rule<Iterator,ascii::space_type> key_value;
|
||||
qi::rule<Iterator,boost::variant<value_null,bool,int,double>(),ascii::space_type> number;
|
||||
qi::rule<Iterator,ascii::space_type> object;
|
||||
qi::rule<Iterator,ascii::space_type> array;
|
||||
qi::rule<Iterator,ascii::space_type> pairs;
|
||||
qi::rule<Iterator,std::string(), space_type> string_;
|
||||
qi::rule<Iterator,space_type> key_value;
|
||||
qi::rule<Iterator,boost::variant<value_null,bool,int,double>(),space_type> number;
|
||||
qi::rule<Iterator,space_type> object;
|
||||
qi::rule<Iterator,space_type> array;
|
||||
qi::rule<Iterator,space_type> pairs;
|
||||
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
||||
|
||||
// geoJSON
|
||||
qi::rule<Iterator,void(FeatureType&),ascii::space_type> feature; // START
|
||||
qi::rule<Iterator,ascii::space_type> feature_type;
|
||||
qi::rule<Iterator,void(FeatureType&),space_type> feature; // START
|
||||
qi::rule<Iterator,space_type> feature_type;
|
||||
|
||||
// Nabialek trick //////////////////////////////////////
|
||||
//typedef typename qi::rule<Iterator,void(FeatureType &), ascii::space_type> dispatch_rule;
|
||||
//qi::rule<Iterator,qi::locals<dispatch_rule*>, void(FeatureType&),ascii::space_type> geometry;
|
||||
//typedef typename qi::rule<Iterator,void(FeatureType &), space_type> dispatch_rule;
|
||||
//qi::rule<Iterator,qi::locals<dispatch_rule*>, void(FeatureType&),space_type> geometry;
|
||||
//qi::symbols<char, dispatch_rule*> geometry_dispatch;
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
qi::rule<Iterator,qi::locals<int>, void(FeatureType&),ascii::space_type> geometry;
|
||||
qi::rule<Iterator,qi::locals<int>, void(FeatureType&),space_type> geometry;
|
||||
qi::symbols<char, int> geometry_dispatch;
|
||||
|
||||
qi::rule<Iterator,void(CommandType,geometry_type*),ascii::space_type> point;
|
||||
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),ascii::space_type> points;
|
||||
qi::rule<Iterator,void(FeatureType &,int),ascii::space_type> coordinates;
|
||||
qi::rule<Iterator,void(CommandType,geometry_type*),space_type> point;
|
||||
qi::rule<Iterator,qi::locals<CommandType>,void(geometry_type*),space_type> points;
|
||||
qi::rule<Iterator,void(FeatureType &,int),space_type> coordinates;
|
||||
//
|
||||
qi::rule<Iterator,qi::locals<geometry_type*>,
|
||||
void(boost::ptr_vector<mapnik::geometry_type>& ),ascii::space_type> point_coordinates;
|
||||
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> point_coordinates;
|
||||
qi::rule<Iterator,qi::locals<geometry_type*>,
|
||||
void(boost::ptr_vector<mapnik::geometry_type>& ),ascii::space_type> linestring_coordinates;
|
||||
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> linestring_coordinates;
|
||||
qi::rule<Iterator,qi::locals<geometry_type*>,
|
||||
void(boost::ptr_vector<mapnik::geometry_type>& ),ascii::space_type> polygon_coordinates;
|
||||
void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> polygon_coordinates;
|
||||
|
||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),ascii::space_type> multipoint_coordinates;
|
||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),ascii::space_type> multilinestring_coordinates;
|
||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),ascii::space_type> multipolygon_coordinates;
|
||||
qi::rule<Iterator,void(FeatureType&),ascii::space_type> geometry_collection;
|
||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipoint_coordinates;
|
||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multilinestring_coordinates;
|
||||
qi::rule<Iterator,void(boost::ptr_vector<mapnik::geometry_type>& ),space_type> multipolygon_coordinates;
|
||||
qi::rule<Iterator,void(FeatureType&),space_type> geometry_collection;
|
||||
|
||||
qi::rule<Iterator,void(FeatureType &),ascii::space_type> properties;
|
||||
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),ascii::space_type> attributes;
|
||||
qi::rule<Iterator,boost::variant<value_null,bool,int,double,std::string>(), ascii::space_type> attribute_value;
|
||||
qi::rule<Iterator,void(FeatureType &),space_type> properties;
|
||||
qi::rule<Iterator,qi::locals<std::string>, void(FeatureType &),space_type> attributes;
|
||||
qi::rule<Iterator,boost::variant<value_null,bool,int,double,std::string>(), space_type> attribute_value;
|
||||
|
||||
phoenix::function<put_property> put_property_;
|
||||
phoenix::function<extract_geometry> extract_geometry_;
|
||||
|
|
|
@ -23,232 +23,66 @@
|
|||
#ifndef MAPNIK_MARKERS_PLACEMENT_HPP
|
||||
#define MAPNIK_MARKERS_PLACEMENT_HPP
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
// stl
|
||||
#include <cmath>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename Locator, typename Detector>
|
||||
class markers_placement : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
/** Constructor for markers_placement object.
|
||||
* \param locator Path along which markers are placed (type: vertex source)
|
||||
* \param size Size of the marker
|
||||
* \param detector Collision detection
|
||||
* \param spacing Distance between markers. If the value is negative it is
|
||||
* converted to a positive value with similar magnitude, but
|
||||
* choosen to optimize marker placement. 0 = no markers
|
||||
*/
|
||||
markers_placement(Locator &locator, box2d<double> size, Detector &detector, double spacing, double max_error, bool allow_overlap);
|
||||
/** Start again at first marker.
|
||||
* \note Returns the same list of markers only works when they were NOT added
|
||||
* to the detector.
|
||||
*/
|
||||
void rewind();
|
||||
/** Get a point where the marker should be placed.
|
||||
* Each time this function is called a new point is returned.
|
||||
* \param x Return value for x position
|
||||
* \param y Return value for x position
|
||||
* \param angle Return value for rotation angle
|
||||
* \param add_to_detector Add selected position to detector
|
||||
* \return True if a place is found, false if none is found.
|
||||
*/
|
||||
bool get_point(double *x, double *y, double *angle, bool add_to_detector = true);
|
||||
private:
|
||||
Locator &locator_;
|
||||
box2d<double> size_;
|
||||
Detector &detector_;
|
||||
double spacing_;
|
||||
double max_error_;
|
||||
bool allow_overlap_;
|
||||
|
||||
bool done_;
|
||||
double last_x, last_y;
|
||||
double next_x, next_y;
|
||||
/** If a marker could not be placed at the exact point where it should
|
||||
* go the next markers distance will be a bit lower. */
|
||||
* go the next marker's distance will be a bit lower. */
|
||||
double error_;
|
||||
double max_error_;
|
||||
double spacing_left_;
|
||||
unsigned marker_nr_;
|
||||
bool allow_overlap_;
|
||||
|
||||
/** Rotates the size_ box and translates the position. */
|
||||
box2d<double> perform_transform(double angle, double dx, double dy);
|
||||
/** Automatically chooses spacing. */
|
||||
double find_optimal_spacing(double s);
|
||||
/** Set spacing_left_, adjusts error_ and performs sanity checks. */
|
||||
void set_spacing_left(double sl, bool allow_negative=false);
|
||||
};
|
||||
|
||||
/** Constructor for markers_placement object.
|
||||
* \param locator Path along which markers are placed (type: vertex source)
|
||||
* \param size Size of the marker
|
||||
* \param detector Collision detection
|
||||
* \param spacing Distance between markers. If the value is negative it is
|
||||
* converted to a positive value with similar magnitude, but
|
||||
* choosen to optimize marker placement. 0 = no markers
|
||||
*/
|
||||
template <typename Locator, typename Detector> markers_placement<Locator, Detector>::markers_placement(
|
||||
Locator &locator, box2d<double> size, Detector &detector, double spacing, double max_error, bool allow_overlap)
|
||||
: locator_(locator), size_(size), detector_(detector), max_error_(max_error), allow_overlap_(allow_overlap)
|
||||
{
|
||||
if (spacing >= 0)
|
||||
{
|
||||
spacing_ = spacing;
|
||||
} else if (spacing < 0)
|
||||
{
|
||||
spacing_ = find_optimal_spacing(-spacing);
|
||||
}
|
||||
rewind();
|
||||
}
|
||||
|
||||
/** Autmatically chooses spacing. */
|
||||
template <typename Locator, typename Detector> double markers_placement<Locator, Detector>::find_optimal_spacing(double s)
|
||||
{
|
||||
rewind();
|
||||
//Calculate total path length
|
||||
unsigned cmd = agg::path_cmd_move_to;
|
||||
double length = 0;
|
||||
while (!agg::is_stop(cmd))
|
||||
{
|
||||
double dx = next_x - last_x;
|
||||
double dy = next_y - last_y;
|
||||
length += std::sqrt(dx * dx + dy * dy);
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
while (agg::is_move_to(cmd = locator_.vertex(&next_x, &next_y)))
|
||||
{
|
||||
//Skip over "move" commands
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
}
|
||||
}
|
||||
unsigned points = round(length / s);
|
||||
if (points == 0) return 0.0; //Path to short
|
||||
return length / points;
|
||||
}
|
||||
|
||||
/** Start again at first marker.
|
||||
* \note Returning the same list of markers only works when they were NOT added
|
||||
* to the detector.
|
||||
*/
|
||||
template <typename Locator, typename Detector> void markers_placement<Locator, Detector>::rewind()
|
||||
{
|
||||
locator_.rewind(0);
|
||||
//Get first point
|
||||
done_ = agg::is_stop(locator_.vertex(&next_x, &next_y)) || spacing_ < size_.width();
|
||||
last_x = next_x;
|
||||
last_y = next_y; // Force request of new segment
|
||||
error_ = 0;
|
||||
marker_nr_ = 0;
|
||||
}
|
||||
|
||||
/** Get a point where the marker should be placed.
|
||||
* Each time this function is called a new point is returned.
|
||||
* \param x Return value for x position
|
||||
* \param y Return value for x position
|
||||
* \param angle Return value for rotation angle
|
||||
* \param add_to_detector Add selected position to detector
|
||||
* \return True if a place is found, false if none is found.
|
||||
*/
|
||||
template <typename Locator, typename Detector> bool markers_placement<Locator, Detector>::get_point(
|
||||
double *x, double *y, double *angle, bool add_to_detector)
|
||||
{
|
||||
if (done_) return false;
|
||||
|
||||
unsigned cmd;
|
||||
double spacing_left;
|
||||
if (marker_nr_++ == 0)
|
||||
{
|
||||
spacing_left = spacing_ / 2;
|
||||
} else
|
||||
{
|
||||
spacing_left = spacing_;
|
||||
}
|
||||
|
||||
spacing_left -= error_;
|
||||
error_ = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
//Loop exits when a position is found or when no more segments are available
|
||||
if (spacing_left < size_.width()/2)
|
||||
{
|
||||
//Do not place markers to close to the beginning of a segment
|
||||
error_ += size_.width()/2 - spacing_left;
|
||||
spacing_left = size_.width()/2;
|
||||
}
|
||||
if (abs(error_) > max_error_ * spacing_)
|
||||
{
|
||||
spacing_left += spacing_ - error_;
|
||||
error_ = 0;
|
||||
}
|
||||
double dx = next_x - last_x;
|
||||
double dy = next_y - last_y;
|
||||
double d = std::sqrt(dx * dx + dy * dy);
|
||||
if (d <= spacing_left)
|
||||
{
|
||||
//Segment is to short to place marker. Find next segment
|
||||
spacing_left -= d;
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
while (agg::is_move_to(cmd = locator_.vertex(&next_x, &next_y)))
|
||||
{
|
||||
//Skip over "move" commands
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
}
|
||||
if (agg::is_stop(cmd))
|
||||
{
|
||||
done_ = true;
|
||||
return false;
|
||||
}
|
||||
continue; //Try again
|
||||
}
|
||||
//Check if marker really fits in this segment
|
||||
if (d < size_.width())
|
||||
{
|
||||
//Segment to short => Skip this segment
|
||||
error_ += d + size_.width()/2 - spacing_left;
|
||||
spacing_left = d + size_.width()/2;
|
||||
continue;
|
||||
} else if (d - spacing_left < size_.width()/2)
|
||||
{
|
||||
//Segment is long enough, but we are to close to the end
|
||||
|
||||
//Note: This function moves backwards. This could lead to an infinite
|
||||
// loop when another function adds a positive offset. Therefore we
|
||||
// only move backwards when there is no offset
|
||||
if (error_ == 0)
|
||||
{
|
||||
error_ += d - size_.width()/2 - spacing_left;
|
||||
spacing_left = d - size_.width()/2;
|
||||
} else
|
||||
{
|
||||
//Skip this segment
|
||||
error_ += d + size_.width()/2 - spacing_left;
|
||||
spacing_left = d + size_.width()/2;
|
||||
}
|
||||
continue; //Force checking of max_error constraint
|
||||
}
|
||||
*angle = atan2(dy, dx);
|
||||
*x = last_x + dx * (spacing_left / d);
|
||||
*y = last_y + dy * (spacing_left / d);
|
||||
|
||||
box2d<double> box = perform_transform(*angle, *x, *y);
|
||||
if (!allow_overlap_ && !detector_.has_placement(box))
|
||||
{
|
||||
//10.0 is choosen arbitrarily
|
||||
error_ += spacing_ * max_error_ / 10.0;
|
||||
spacing_left += spacing_ * max_error_ / 10.0;
|
||||
continue;
|
||||
}
|
||||
if (add_to_detector) detector_.insert(box);
|
||||
last_x = *x;
|
||||
last_y = *y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Rotates the size_ box and translates the position. */
|
||||
template <typename Locator, typename Detector> box2d<double> markers_placement<Locator, Detector>::perform_transform(double angle, double dx, double dy)
|
||||
{
|
||||
double c = cos(angle), s = sin(angle);
|
||||
double x1 = size_.minx();
|
||||
double x2 = size_.maxx();
|
||||
double y1 = size_.miny();
|
||||
double y2 = size_.maxy();
|
||||
|
||||
double x1_ = dx + x1 * c - y1 * s;
|
||||
double y1_ = dy + x1 * s + y1 * c;
|
||||
double x2_ = dx + x2 * c - y2 * s;
|
||||
double y2_ = dy + x2 * s + y2 * c;
|
||||
|
||||
return box2d<double>(x1_, y1_, x2_, y2_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_MARKERS_PLACEMENT_HPP
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
class memory_featureset : public Featureset, private boost::noncopyable
|
||||
class memory_featureset : public Featureset
|
||||
{
|
||||
public:
|
||||
memory_featureset(box2d<double> const& bbox, memory_datasource const& ds)
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_STYLE_FACTORY_HPP
|
||||
#define MAPNIK_STYLE_FACTORY_HPP
|
||||
|
||||
//#include <mapnik/style.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
class style_factory
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // MAPNIK_STYLE_FACTORY_HPP
|
|
@ -129,7 +129,7 @@ public:
|
|||
virtual ~text_placements() {}
|
||||
|
||||
/** List of all properties used as the default for the subclasses. */
|
||||
text_symbolizer_properties properties;
|
||||
text_symbolizer_properties defaults;
|
||||
};
|
||||
|
||||
/** Pointer to object of class text_placements */
|
||||
|
|
|
@ -162,7 +162,7 @@ struct text_symbolizer_properties
|
|||
unsigned text_ratio;
|
||||
unsigned wrap_width;
|
||||
/** Default values for char_properties. */
|
||||
char_properties default_format;
|
||||
char_properties format;
|
||||
private:
|
||||
/** A tree of formatting::nodes which contain text and formatting information. */
|
||||
formatting::node_ptr tree_;
|
||||
|
|
|
@ -36,35 +36,35 @@
|
|||
|
||||
namespace boost { namespace spirit { namespace traits {
|
||||
|
||||
template <>
|
||||
struct is_container<mapnik::geometry_type const> : mpl::true_ {} ;
|
||||
template <>
|
||||
struct is_container<mapnik::geometry_type const> : mpl::true_ {} ;
|
||||
|
||||
template <>
|
||||
struct container_iterator<mapnik::geometry_type const>
|
||||
{
|
||||
typedef mapnik::util::vertex_iterator<double> type;
|
||||
};
|
||||
template <>
|
||||
struct container_iterator<mapnik::geometry_type const>
|
||||
{
|
||||
typedef mapnik::util::vertex_iterator<double> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct begin_container<mapnik::geometry_type const>
|
||||
{
|
||||
static mapnik::util::vertex_iterator<double>
|
||||
call (mapnik::geometry_type const& g)
|
||||
{
|
||||
return mapnik::util::vertex_iterator<double>(g.data());
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct begin_container<mapnik::geometry_type const>
|
||||
{
|
||||
static mapnik::util::vertex_iterator<double>
|
||||
call (mapnik::geometry_type const& g)
|
||||
{
|
||||
return mapnik::util::vertex_iterator<double>(g.data());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct end_container<mapnik::geometry_type const>
|
||||
{
|
||||
static mapnik::util::vertex_iterator<double>
|
||||
call (mapnik::geometry_type const& g)
|
||||
{
|
||||
return mapnik::util::vertex_iterator<double>();
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct end_container<mapnik::geometry_type const>
|
||||
{
|
||||
static mapnik::util::vertex_iterator<double>
|
||||
call (mapnik::geometry_type const& g)
|
||||
{
|
||||
return mapnik::util::vertex_iterator<double>();
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
}}}
|
||||
|
||||
#endif // CONTAINER_ADAPTER_HPP
|
||||
|
|
|
@ -46,12 +46,12 @@
|
|||
namespace boost { namespace spirit { namespace traits {
|
||||
|
||||
// make gcc and darwin toolsets happy.
|
||||
template <>
|
||||
struct is_container<mapnik::geometry_container>
|
||||
: mpl::false_
|
||||
{};
|
||||
template <>
|
||||
struct is_container<mapnik::geometry_container>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
}}}
|
||||
}}}
|
||||
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2011 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_VERTEX_TRANSFORM_HPP
|
||||
#define MAPNIK_VERTEX_TRANSFORM_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
template <typename T0 ,typename T1,int shift=8>
|
||||
struct Shift
|
||||
{
|
||||
typedef T0 value_type;
|
||||
typedef T1 return_type;
|
||||
static return_type apply(value_type val)
|
||||
{
|
||||
return static_cast<return_type>(val*(1<<shift));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T0,typename T1>
|
||||
struct Shift<T0,T1,0>
|
||||
{
|
||||
typedef T0 value_type;
|
||||
typedef T1 return_type;
|
||||
static return_type apply(value_type val)
|
||||
{
|
||||
return static_cast<return_type>(val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Shift<T,T,0>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T return_type;
|
||||
static T& apply(T& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Shift<double,double,0> NO_SHIFT;
|
||||
typedef Shift<double,int,0> SHIFT0;
|
||||
typedef Shift<double,int,8> SHIFT8;
|
||||
|
||||
|
||||
template <typename T0,typename T1,typename Trans>
|
||||
struct view_transform;
|
||||
|
||||
template <typename Trans>
|
||||
struct view_transform <vertex2d,vertex2d,Trans>
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
template <typename Trans>
|
||||
struct view_transform <vertex2d,vertex2i,Trans>
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
template <typename Trans>
|
||||
struct view_transform<box2d<double>,box2d<double>,Trans>
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAPNIK_VERTEX_TRANSFORM_HPP
|
|
@ -51,18 +51,20 @@ class vertex_vector : private boost::noncopyable
|
|||
block_mask = block_size - 1,
|
||||
grow_by = 256
|
||||
};
|
||||
|
||||
public:
|
||||
// required for iterators support
|
||||
typedef boost::tuple<unsigned,coord_type,coord_type> value_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
private:
|
||||
unsigned num_blocks_;
|
||||
unsigned max_blocks_;
|
||||
coord_type** vertices_;
|
||||
unsigned char** commands_;
|
||||
unsigned pos_;
|
||||
|
||||
size_type pos_;
|
||||
|
||||
public:
|
||||
// required for iterators support
|
||||
typedef typename boost::tuple<unsigned,coord_type,coord_type> value_type;
|
||||
|
||||
|
||||
vertex_vector()
|
||||
: num_blocks_(0),
|
||||
max_blocks_(0),
|
||||
|
@ -83,7 +85,7 @@ public:
|
|||
::operator delete(vertices_);
|
||||
}
|
||||
}
|
||||
unsigned size() const
|
||||
size_type size() const
|
||||
{
|
||||
return pos_;
|
||||
}
|
||||
|
@ -112,12 +114,7 @@ public:
|
|||
*y = (*vertex);
|
||||
return commands_[block] [pos & block_mask];
|
||||
}
|
||||
|
||||
void set_capacity(size_t)
|
||||
{
|
||||
//do nothing
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void allocate_block(unsigned block)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <boost/utility.hpp>
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
|
|
|
@ -857,7 +857,7 @@ boost::optional<mapnik::datasource::geometry_t> csv_datasource::get_geometry_typ
|
|||
boost::optional<mapnik::datasource::geometry_t> result;
|
||||
int multi_type = 0;
|
||||
unsigned num_features = features_.size();
|
||||
for (int i = 0; i < num_features && i < 5; ++i)
|
||||
for (unsigned i = 0; i < num_features && i < 5; ++i)
|
||||
{
|
||||
mapnik::util::to_ds_type(features_[i]->paths(),result);
|
||||
if (result)
|
||||
|
|
|
@ -373,8 +373,7 @@ void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
|
|||
if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE)
|
||||
{
|
||||
geometry_type* geom = new geometry_type(geom_type);
|
||||
if (geom) geom->set_capacity(ord_size);
|
||||
|
||||
|
||||
for (int i = SDO_ELEM_INFO_SIZE; i < elem_size; i+=3)
|
||||
{
|
||||
int next_offset = elem_info[i];
|
||||
|
@ -434,8 +433,6 @@ void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
|
|||
}
|
||||
|
||||
geom = new geometry_type(gtype);
|
||||
geom->set_capacity((next_offset - 1) - (offset - 1 - dimensions));
|
||||
|
||||
fill_geometry_type(geom,
|
||||
offset - 1,
|
||||
next_offset - 1,
|
||||
|
@ -458,8 +455,6 @@ void occi_featureset::convert_ordinates(mapnik::feature_ptr feature,
|
|||
else
|
||||
{
|
||||
geometry_type * geom = new geometry_type(geom_type);
|
||||
geom->set_capacity(ord_size);
|
||||
|
||||
fill_geometry_type(geom,
|
||||
offset - 1,
|
||||
ord_size,
|
||||
|
|
|
@ -137,7 +137,6 @@ void SDOPointType::writeSQL(oracle::occi::AnyData& streamOCCI_)
|
|||
|
||||
SDOPointType::~SDOPointType()
|
||||
{
|
||||
int i;
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
@ -309,6 +308,5 @@ void SDOGeometry::writeSQL(oracle::occi::AnyData& streamOCCI_)
|
|||
|
||||
SDOGeometry::~SDOGeometry()
|
||||
{
|
||||
int i;
|
||||
delete SDO_POINT;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,13 @@ if env['RUNTIME_LINK'] == 'static':
|
|||
plugin_env.ParseConfig(cmd)
|
||||
plugin_env['LIBS'].append('proj')
|
||||
|
||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header < 46:
|
||||
# avoid ubuntu issue with boost interprocess:
|
||||
# https://github.com/mapnik/mapnik/issues/1082
|
||||
plugin_env.Append(CXXFLAGS = '-fpermissive')
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../ogr', source=ogr_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
|
|
|
@ -87,7 +87,6 @@ void ogr_converter::convert_linestring(OGRLineString* geom, feature_ptr feature)
|
|||
{
|
||||
int num_points = geom->getNumPoints();
|
||||
geometry_type* line = new geometry_type(mapnik::LineString);
|
||||
line->set_capacity(num_points);
|
||||
line->move_to(geom->getX(0), geom->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
|
@ -108,7 +107,6 @@ void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature)
|
|||
capacity += interior->getNumPoints();
|
||||
}
|
||||
geometry_type* poly = new geometry_type(mapnik::Polygon);
|
||||
poly->set_capacity(num_points + capacity);
|
||||
poly->move_to(exterior->getX(0), exterior->getY(0));
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
|
|
|
@ -103,7 +103,6 @@ feature_ptr osm_featureset<filterT>::next()
|
|||
geom = new geometry_type(mapnik::LineString);
|
||||
}
|
||||
|
||||
geom->set_capacity(static_cast<osm_way*>(cur_item)->nodes.size());
|
||||
geom->move_to(static_cast<osm_way*>(cur_item)->nodes[0]->lon,
|
||||
static_cast<osm_way*>(cur_item)->nodes[0]->lat);
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ std::string postgis_datasource::sql_bbox(box2d<double> const& env) const
|
|||
{
|
||||
std::ostringstream b;
|
||||
if (srid_ > 0)
|
||||
b << "SetSRID(";
|
||||
b << "ST_SetSRID(";
|
||||
b << "'BOX3D(";
|
||||
b << std::setprecision(16);
|
||||
b << env.minx() << " " << env.miny() << ",";
|
||||
|
@ -502,15 +502,18 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
std::ostringstream s;
|
||||
s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
if (!key_field_.empty())
|
||||
{
|
||||
mapnik::sql_utils::quote_attr(s,key_field_);
|
||||
ctx->push(key_field_);
|
||||
}
|
||||
|
||||
std::set<std::string> const& props=q.property_names();
|
||||
std::set<std::string>::const_iterator pos=props.begin();
|
||||
std::set<std::string>::const_iterator end=props.end();
|
||||
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
for ( ;pos != end;++pos)
|
||||
{
|
||||
mapnik::sql_utils::quote_attr(s,*pos);
|
||||
|
@ -526,9 +529,6 @@ featureset_ptr postgis_datasource::features(const query& q) const
|
|||
}
|
||||
|
||||
boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
|
||||
unsigned num_attr = props.size();
|
||||
if (!key_field_.empty())
|
||||
++num_attr;
|
||||
return boost::make_shared<postgis_featureset>(rs, ctx, desc_.get_encoding(), !key_field_.empty());
|
||||
}
|
||||
else
|
||||
|
@ -574,11 +574,14 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
|
|||
std::ostringstream s;
|
||||
s << "SELECT ST_AsBinary(\"" << geometryColumn_ << "\") AS geom";
|
||||
|
||||
if (!key_field_.empty())
|
||||
mapnik::sql_utils::quote_attr(s,key_field_);
|
||||
|
||||
mapnik::context_ptr ctx = boost::make_shared<mapnik::context_type>();
|
||||
|
||||
if (!key_field_.empty())
|
||||
{
|
||||
mapnik::sql_utils::quote_attr(s,key_field_);
|
||||
ctx->push(key_field_);
|
||||
}
|
||||
|
||||
std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
|
||||
std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
|
||||
|
||||
|
|
|
@ -49,6 +49,13 @@ libraries.append('boost_filesystem%s' % env['BOOST_APPEND'])
|
|||
if env['SHAPE_MEMORY_MAPPED_FILE']:
|
||||
plugin_env.Append(CXXFLAGS = '-DSHAPE_MEMORY_MAPPED_FILE')
|
||||
|
||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header < 46:
|
||||
# avoid ubuntu issue with boost interprocess:
|
||||
# https://github.com/mapnik/mapnik/issues/1082
|
||||
plugin_env.Append(CXXFLAGS = '-fpermissive')
|
||||
|
||||
input_plugin = plugin_env.SharedLibrary('../shape', SHLIBSUFFIX='.input', source=shape_src, SHLIBPREFIX='', LIBS = libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
# if the plugin links to libmapnik ensure it is built first
|
||||
|
|
|
@ -60,8 +60,9 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
|
|||
unsigned g=fill_.green();
|
||||
unsigned b=fill_.blue();
|
||||
unsigned a=fill_.alpha();
|
||||
renb.clip_box(0,0,width_,height_);
|
||||
renderer ren(renb);
|
||||
|
||||
|
||||
ras_ptr->reset();
|
||||
switch (sym.get_gamma_method())
|
||||
{
|
||||
|
|
10
src/build.py
10
src/build.py
|
@ -164,6 +164,8 @@ source = Split(
|
|||
svg_transform_parser.cpp
|
||||
warp.cpp
|
||||
json/feature_collection_parser.cpp
|
||||
markers_placement.cpp
|
||||
formatting/expression.cpp
|
||||
"""
|
||||
)
|
||||
|
||||
|
@ -358,6 +360,8 @@ wkt_includes = glob.glob('../include/mapnik/wkt/*.hpp')
|
|||
grid_includes = glob.glob('../include/mapnik/grid/*.hpp')
|
||||
json_includes = glob.glob('../include/mapnik/json/*.hpp')
|
||||
util_includes = glob.glob('../include/mapnik/util/*.hpp')
|
||||
text_placements_includes = glob.glob('../include/mapnik/text_placements/*.hpp')
|
||||
formatting_includes = glob.glob('../include/mapnik/formatting/*.hpp')
|
||||
|
||||
inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik')
|
||||
svg_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/svg')
|
||||
|
@ -365,6 +369,8 @@ wkt_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/wkt')
|
|||
grid_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/grid')
|
||||
json_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/json')
|
||||
util_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/util')
|
||||
text_placements_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/text_placements')
|
||||
formatting_inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/formatting')
|
||||
|
||||
if 'uninstall' not in COMMAND_LINE_TARGETS:
|
||||
env.Alias(target='install', source=env.Install(inc_target, includes))
|
||||
|
@ -373,6 +379,8 @@ if 'uninstall' not in COMMAND_LINE_TARGETS:
|
|||
env.Alias(target='install', source=env.Install(grid_inc_target, grid_includes))
|
||||
env.Alias(target='install', source=env.Install(json_inc_target, json_includes))
|
||||
env.Alias(target='install', source=env.Install(util_inc_target, util_includes))
|
||||
env.Alias(target='install', source=env.Install(text_placements_inc_target, text_placements_includes))
|
||||
env.Alias(target='install', source=env.Install(formatting_inc_target, formatting_includes))
|
||||
|
||||
env['create_uninstall_target'](env, inc_target)
|
||||
env['create_uninstall_target'](env, svg_inc_target)
|
||||
|
@ -380,3 +388,5 @@ env['create_uninstall_target'](env, wkt_inc_target)
|
|||
env['create_uninstall_target'](env, grid_inc_target)
|
||||
env['create_uninstall_target'](env, json_inc_target)
|
||||
env['create_uninstall_target'](env, util_inc_target)
|
||||
env['create_uninstall_target'](env, text_placements_inc_target)
|
||||
env['create_uninstall_target'](env, formatting_inc_target)
|
||||
|
|
144
src/formatting/expression.cpp
Normal file
144
src/formatting/expression.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2012 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/formatting/expression.hpp>
|
||||
#include <mapnik/ptree_helpers.hpp>
|
||||
#include <mapnik/expression_string.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/text_properties.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
||||
// boost
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
namespace formatting
|
||||
{
|
||||
using boost::property_tree::ptree;
|
||||
void expression_format::to_xml(boost::property_tree::ptree &xml) const
|
||||
{
|
||||
ptree &new_node = xml.push_back(ptree::value_type("Format", ptree()))->second;
|
||||
if (face_name) set_attr(new_node, "face-name", to_expression_string(*face_name));
|
||||
if (text_size) set_attr(new_node, "size", to_expression_string(*text_size));
|
||||
if (character_spacing) set_attr(new_node, "character-spacing", to_expression_string*character_spacing);
|
||||
if (line_spacing) set_attr(new_node, "line-spacing", to_expression_string(*line_spacing));
|
||||
if (text_opacity) set_attr(new_node, "opacity", to_expression_string(*text_opacity));
|
||||
if (wrap_before) set_attr(new_node, "wrap-before", to_expression_string(*wrap_before));
|
||||
if (wrap_char) set_attr(new_node, "wrap-character", to_expression_string(*wrap_char));
|
||||
if (fill) set_attr(new_node, "fill", to_expression_string(*fill));
|
||||
if (halo_fill) set_attr(new_node, "halo-fill", to_expression_string(*halo_fill));
|
||||
if (halo_radius) set_attr(new_node, "halo-radius", to_expression_string(*halo_radius));
|
||||
if (child_) child_->to_xml(new_node);
|
||||
}
|
||||
|
||||
node_ptr expression_format::from_xml(ptree const& xml)
|
||||
{
|
||||
expression_format *n = new expression_format();
|
||||
node_ptr np(n);
|
||||
|
||||
node_ptr child = node::from_xml(xml);
|
||||
n->set_child(child);
|
||||
|
||||
n->face_name = get_expression(xml, "face-name");
|
||||
n->text_size = get_expression(xml, "size");
|
||||
n->character_spacing = get_expression(xml, "character-spacing");
|
||||
n->line_spacing = get_expression(xml, "line-spacing");
|
||||
n->text_opacity = get_expression(xml, "opactity");
|
||||
n->wrap_before = get_expression(xml, "wrap-before");
|
||||
n->wrap_char = get_expression(xml, "wrap-character");
|
||||
n->fill = get_expression(xml, "fill");
|
||||
n->halo_fill = get_expression(xml, "halo-fill");
|
||||
n->halo_radius = get_expression(xml, "halo-radius");
|
||||
return np;
|
||||
}
|
||||
|
||||
expression_ptr expression_format::get_expression(ptree const& xml, std::string name)
|
||||
{
|
||||
boost::optional<std::string> tmp = get_opt_attr<std::string>(xml, name);
|
||||
if (tmp) return parse_expression(*tmp);
|
||||
return expression_ptr();
|
||||
}
|
||||
|
||||
|
||||
void expression_format::apply(char_properties const& p, const Feature &feature, processed_text &output) const
|
||||
{
|
||||
char_properties new_properties = p;
|
||||
if (face_name) new_properties.face_name =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *face_name).to_string();
|
||||
if (text_size) new_properties.text_size =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_size).to_double();
|
||||
if (character_spacing) new_properties.character_spacing =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_double();
|
||||
if (line_spacing) new_properties.line_spacing =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *line_spacing).to_double();
|
||||
if (text_opacity) new_properties.text_opacity =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *text_opacity).to_double();
|
||||
if (wrap_before) new_properties.wrap_before =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *wrap_before).to_bool();
|
||||
if (wrap_char) new_properties.wrap_char =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *character_spacing).to_unicode()[0];
|
||||
// if (fill) new_properties.fill =
|
||||
// boost::apply_visitor(evaluate<Feature,value_type>(feature), *fill).to_color();
|
||||
// if (halo_fill) new_properties.halo_fill =
|
||||
// boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_fill).to_color();
|
||||
if (halo_radius) new_properties.halo_radius =
|
||||
boost::apply_visitor(evaluate<Feature,value_type>(feature), *halo_radius).to_double();
|
||||
|
||||
if (child_) {
|
||||
child_->apply(new_properties, feature, output);
|
||||
} else {
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::cerr << "Warning: Useless format: No text to format\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void expression_format::set_child(node_ptr child)
|
||||
{
|
||||
child_ = child;
|
||||
}
|
||||
|
||||
|
||||
node_ptr expression_format::get_child() const
|
||||
{
|
||||
return child_;
|
||||
}
|
||||
|
||||
void expression_format::add_expressions(expression_set &output) const
|
||||
{
|
||||
if (child_) child_->add_expressions(output);
|
||||
output.insert(face_name);
|
||||
output.insert(text_size);
|
||||
output.insert(character_spacing);
|
||||
output.insert(line_spacing);
|
||||
output.insert(text_opacity);
|
||||
output.insert(wrap_before);
|
||||
output.insert(wrap_char);
|
||||
output.insert(fill);
|
||||
output.insert(halo_fill);
|
||||
output.insert(halo_radius);
|
||||
}
|
||||
|
||||
} //ns formatting
|
||||
} //ns mapnik
|
|
@ -43,7 +43,7 @@ bool feature_collection_parser::parse(std::string const& json, std::vector<mapni
|
|||
using namespace boost::spirit;
|
||||
iterator_type first = json.begin();
|
||||
iterator_type last = json.end();
|
||||
return qi::phrase_parse(first, last, *grammar_, ascii::space, features);
|
||||
return qi::phrase_parse(first, last, *grammar_, standard_wide::space, features);
|
||||
#else
|
||||
std::ostringstream s;
|
||||
s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
|
|
|
@ -1281,10 +1281,10 @@ void map_parser::parse_text_symbolizer( rule & rule, ptree const & sym )
|
|||
placement_finder = text_placements_ptr(new text_placements_dummy());
|
||||
}
|
||||
|
||||
placement_finder->properties.from_xml(sym, fontsets_);
|
||||
placement_finder->defaults.from_xml(sym, fontsets_);
|
||||
if (strict_ &&
|
||||
!placement_finder->properties.default_format.fontset.size())
|
||||
ensure_font_face(placement_finder->properties.default_format.face_name);
|
||||
!placement_finder->defaults.format.fontset.size())
|
||||
ensure_font_face(placement_finder->defaults.format.face_name);
|
||||
if (list) {
|
||||
ptree::const_iterator symIter = sym.begin();
|
||||
ptree::const_iterator endSym = sym.end();
|
||||
|
@ -1299,8 +1299,8 @@ void map_parser::parse_text_symbolizer( rule & rule, ptree const & sym )
|
|||
text_symbolizer_properties & p = list->add();
|
||||
p.from_xml(symIter->second, fontsets_);
|
||||
if (strict_ &&
|
||||
!p.default_format.fontset.size())
|
||||
ensure_font_face(p.default_format.face_name);
|
||||
!p.format.fontset.size())
|
||||
ensure_font_face(p.format.face_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1354,10 +1354,10 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym )
|
|||
placement_finder = text_placements_ptr(new text_placements_dummy());
|
||||
}
|
||||
|
||||
placement_finder->properties.from_xml(sym, fontsets_);
|
||||
placement_finder->defaults.from_xml(sym, fontsets_);
|
||||
if (strict_ &&
|
||||
!placement_finder->properties.default_format.fontset.size())
|
||||
ensure_font_face(placement_finder->properties.default_format.face_name);
|
||||
!placement_finder->defaults.format.fontset.size())
|
||||
ensure_font_face(placement_finder->defaults.format.face_name);
|
||||
if (list) {
|
||||
ptree::const_iterator symIter = sym.begin();
|
||||
ptree::const_iterator endSym = sym.end();
|
||||
|
@ -1372,8 +1372,8 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym )
|
|||
text_symbolizer_properties & p = list->add();
|
||||
p.from_xml(symIter->second, fontsets_);
|
||||
if (strict_&&
|
||||
!placement_finder->properties.default_format.fontset.size())
|
||||
ensure_font_face(p.default_format.face_name);
|
||||
!p.format.fontset.size())
|
||||
ensure_font_face(p.format.face_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
232
src/markers_placement.cpp
Normal file
232
src/markers_placement.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
// mapnik
|
||||
#include <mapnik/markers_placement.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/ctrans.hpp>
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
||||
// stl
|
||||
#include <cmath>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
template <typename Locator, typename Detector>
|
||||
markers_placement<Locator, Detector>::markers_placement(
|
||||
Locator &locator, box2d<double> size, Detector &detector, double spacing, double max_error, bool allow_overlap)
|
||||
: locator_(locator), size_(size), detector_(detector), max_error_(max_error), allow_overlap_(allow_overlap)
|
||||
{
|
||||
if (spacing >= 0)
|
||||
{
|
||||
spacing_ = spacing;
|
||||
} else if (spacing < 0)
|
||||
{
|
||||
spacing_ = find_optimal_spacing(-spacing);
|
||||
}
|
||||
rewind();
|
||||
}
|
||||
|
||||
template <typename Locator, typename Detector>
|
||||
double markers_placement<Locator, Detector>::find_optimal_spacing(double s)
|
||||
{
|
||||
rewind();
|
||||
//Calculate total path length
|
||||
unsigned cmd = agg::path_cmd_move_to;
|
||||
double length = 0;
|
||||
while (!agg::is_stop(cmd))
|
||||
{
|
||||
double dx = next_x - last_x;
|
||||
double dy = next_y - last_y;
|
||||
length += std::sqrt(dx * dx + dy * dy);
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
while (agg::is_move_to(cmd = locator_.vertex(&next_x, &next_y)))
|
||||
{
|
||||
//Skip over "move" commands
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
}
|
||||
}
|
||||
unsigned points = round(length / s);
|
||||
if (points == 0) return 0.0; //Path to short
|
||||
return length / points;
|
||||
}
|
||||
|
||||
|
||||
template <typename Locator, typename Detector>
|
||||
void markers_placement<Locator, Detector>::rewind()
|
||||
{
|
||||
locator_.rewind(0);
|
||||
//Get first point
|
||||
done_ = agg::is_stop(locator_.vertex(&next_x, &next_y)) || spacing_ < size_.width();
|
||||
last_x = next_x;
|
||||
last_y = next_y; // Force request of new segment
|
||||
error_ = 0;
|
||||
marker_nr_ = 0;
|
||||
}
|
||||
|
||||
template <typename Locator, typename Detector>
|
||||
bool markers_placement<Locator, Detector>::get_point(
|
||||
double *x, double *y, double *angle, bool add_to_detector)
|
||||
{
|
||||
if (done_) return false;
|
||||
|
||||
unsigned cmd;
|
||||
|
||||
/* This functions starts at the position of the previous marker,
|
||||
walks along the path, counting how far it has to go in spacing_left.
|
||||
If one marker can't be placed at the position it should go to it is
|
||||
moved a bit. The error is compensated for in the next call to this
|
||||
function.
|
||||
|
||||
error > 0: Marker too near to the end of the path.
|
||||
error = 0: Perfect position.
|
||||
error < 0: Marker too near to the beginning of the path.
|
||||
*/
|
||||
|
||||
if (marker_nr_++ == 0)
|
||||
{
|
||||
//First marker
|
||||
spacing_left_ = spacing_ / 2;
|
||||
} else
|
||||
{
|
||||
spacing_left_ = spacing_;
|
||||
}
|
||||
|
||||
spacing_left_ -= error_;
|
||||
error_ = 0;
|
||||
|
||||
//Loop exits when a position is found or when no more segments are available
|
||||
while (true)
|
||||
{
|
||||
//Do not place markers too close to the beginning of a segment
|
||||
if (spacing_left_ < size_.width()/2)
|
||||
{
|
||||
set_spacing_left(size_.width()/2); //Only moves forward
|
||||
}
|
||||
//Error for this marker is too large. Skip to the next position.
|
||||
if (abs(error_) > max_error_ * spacing_)
|
||||
{
|
||||
if (error_ > spacing_) {
|
||||
error_ = 0; //Avoid moving backwards
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::cerr << "WARNING: Extremely large error in markers_placement. Please file a bug report.\n";
|
||||
#endif
|
||||
}
|
||||
spacing_left_ += spacing_ - error_;
|
||||
error_ = 0;
|
||||
}
|
||||
double dx = next_x - last_x;
|
||||
double dy = next_y - last_y;
|
||||
double segment_length = std::sqrt(dx * dx + dy * dy);
|
||||
if (segment_length <= spacing_left_)
|
||||
{
|
||||
//Segment is to short to place marker. Find next segment
|
||||
spacing_left_ -= segment_length;
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
while (agg::is_move_to(cmd = locator_.vertex(&next_x, &next_y)))
|
||||
{
|
||||
//Skip over "move" commands
|
||||
last_x = next_x;
|
||||
last_y = next_y;
|
||||
}
|
||||
if (agg::is_stop(cmd))
|
||||
{
|
||||
done_ = true;
|
||||
return false;
|
||||
}
|
||||
continue; //Try again
|
||||
}
|
||||
|
||||
/* At this point we know the following things:
|
||||
- segment_length > spacing_left
|
||||
- error is small enough
|
||||
- at least half a marker fits into this segment
|
||||
*/
|
||||
|
||||
//Check if marker really fits in this segment
|
||||
if (segment_length < size_.width())
|
||||
{
|
||||
//Segment to short => Skip this segment
|
||||
set_spacing_left(segment_length + size_.width()/2); //Only moves forward
|
||||
continue;
|
||||
} else if (segment_length - spacing_left_ < size_.width()/2)
|
||||
{
|
||||
//Segment is long enough, but we are to close to the end
|
||||
|
||||
//Note: This function moves backwards. This could lead to an infinite
|
||||
// loop when another function adds a positive offset. Therefore we
|
||||
// only move backwards when there is no offset
|
||||
if (error_ == 0)
|
||||
{
|
||||
set_spacing_left(segment_length - size_.width()/2, true);
|
||||
} else
|
||||
{
|
||||
//Skip this segment
|
||||
set_spacing_left(segment_length + size_.width()/2); //Only moves forward
|
||||
}
|
||||
continue; //Force checking of max_error constraint
|
||||
}
|
||||
*angle = atan2(dy, dx);
|
||||
*x = last_x + dx * (spacing_left_ / segment_length);
|
||||
*y = last_y + dy * (spacing_left_ / segment_length);
|
||||
|
||||
box2d<double> box = perform_transform(*angle, *x, *y);
|
||||
if (!allow_overlap_ && !detector_.has_placement(box))
|
||||
{
|
||||
//10.0 is the approxmiate number of positions tried and choosen arbitrarily
|
||||
set_spacing_left(spacing_left_ + spacing_ * max_error_ / 10.0); //Only moves forward
|
||||
continue;
|
||||
}
|
||||
if (add_to_detector) detector_.insert(box);
|
||||
last_x = *x;
|
||||
last_y = *y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Locator, typename Detector>
|
||||
box2d<double> markers_placement<Locator, Detector>::perform_transform(double angle, double dx, double dy)
|
||||
{
|
||||
double c = cos(angle), s = sin(angle);
|
||||
double x1 = size_.minx();
|
||||
double x2 = size_.maxx();
|
||||
double y1 = size_.miny();
|
||||
double y2 = size_.maxy();
|
||||
|
||||
double x1_ = dx + x1 * c - y1 * s;
|
||||
double y1_ = dy + x1 * s + y1 * c;
|
||||
double x2_ = dx + x2 * c - y2 * s;
|
||||
double y2_ = dy + x2 * s + y2 * c;
|
||||
|
||||
return box2d<double>(x1_, y1_, x2_, y2_);
|
||||
}
|
||||
|
||||
template <typename Locator, typename Detector>
|
||||
void markers_placement<Locator, Detector>::set_spacing_left(double sl, bool allow_negative)
|
||||
{
|
||||
double delta_error = sl - spacing_left_;
|
||||
if (!allow_negative && delta_error < 0)
|
||||
{
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::cerr << "WARNING: Unexpected negative error in markers_placement. Please file a bug report.\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef MAPNIK_DEBUG
|
||||
if (delta_error == 0.0)
|
||||
{
|
||||
std::cerr << "WARNING: Not moving at all in set_spacing_left()! Please file a bug report.\n";
|
||||
}
|
||||
#endif
|
||||
error_ += delta_error;
|
||||
spacing_left_ = sl;
|
||||
}
|
||||
|
||||
typedef coord_transform2<CoordTransform,geometry_type> path_type;
|
||||
template class markers_placement<path_type, label_collision_detector4>;
|
||||
|
||||
} //ns mapnik
|
|
@ -357,7 +357,7 @@ private:
|
|||
void add_font_attributes(ptree & node, const text_symbolizer & sym)
|
||||
{
|
||||
text_placements_ptr p = sym.get_placement_options();
|
||||
p->properties.to_xml(node, explicit_defaults_);
|
||||
p->defaults.to_xml(node, explicit_defaults_);
|
||||
/* Known types:
|
||||
- text_placements_dummy: no handling required
|
||||
- text_placements_simple: positions string
|
||||
|
@ -366,13 +366,14 @@ private:
|
|||
text_placements_simple *simple = dynamic_cast<text_placements_simple *>(p.get());
|
||||
text_placements_list *list = dynamic_cast<text_placements_list *>(p.get());
|
||||
if (simple) {
|
||||
set_attr(node, "placment-type", "simple");
|
||||
set_attr(node, "placement-type", "simple");
|
||||
set_attr(node, "placements", simple->get_positions());
|
||||
}
|
||||
if (list) {
|
||||
set_attr(node, "placment-type", "list");
|
||||
set_attr(node, "placement-type", "list");
|
||||
unsigned i;
|
||||
text_symbolizer_properties *dfl = &(list->properties);
|
||||
//dfl = last properties passed as default so only attributes that change are actually written
|
||||
text_symbolizer_properties *dfl = &(list->defaults);
|
||||
for (i=0; i < list->size(); i++) {
|
||||
ptree &placement_node = node.push_back(ptree::value_type("Placement", ptree()))->second;
|
||||
list->get(i).to_xml(placement_node, explicit_defaults_, *dfl);
|
||||
|
|
|
@ -68,7 +68,7 @@ void text_symbolizer_properties::process(processed_text &output, Feature const&
|
|||
{
|
||||
output.clear();
|
||||
if (tree_) {
|
||||
tree_->apply(default_format, feature, output);
|
||||
tree_->apply(format, feature, output);
|
||||
} else {
|
||||
#ifdef MAPNIK_DEBUG
|
||||
std::cerr << "Warning: text_symbolizer_properties can't produce text: No formatting tree!\n";
|
||||
|
@ -130,7 +130,7 @@ void text_symbolizer_properties::from_xml(boost::property_tree::ptree const &sym
|
|||
set_old_style_expression(parse_expression(*name_, "utf8"));
|
||||
}
|
||||
|
||||
default_format.from_xml(sym, fontsets);
|
||||
format.from_xml(sym, fontsets);
|
||||
formatting::node_ptr n(formatting::node::from_xml(sym));
|
||||
if (n) set_format_tree(n);
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ void text_symbolizer_properties::to_xml(boost::property_tree::ptree &node, bool
|
|||
{
|
||||
set_attr(node, "vertical-alignment", valign);
|
||||
}
|
||||
default_format.to_xml(node, explicit_defaults, dfl.default_format);
|
||||
format.to_xml(node, explicit_defaults, dfl.format);
|
||||
if (tree_) tree_->to_xml(node);
|
||||
}
|
||||
|
||||
|
@ -352,13 +352,13 @@ void char_properties::to_xml(boost::property_tree::ptree &node, bool explicit_de
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
text_placements::text_placements() : properties()
|
||||
text_placements::text_placements() : defaults()
|
||||
{
|
||||
}
|
||||
|
||||
void text_placements::add_expressions(expression_set &output)
|
||||
{
|
||||
properties.add_expressions(output);
|
||||
defaults.add_expressions(output);
|
||||
}
|
||||
|
||||
|
||||
|
@ -366,7 +366,7 @@ void text_placements::add_expressions(expression_set &output)
|
|||
|
||||
text_placement_info::text_placement_info(text_placements const* parent,
|
||||
double scale_factor_, dimension_type dim, bool has_dimensions_)
|
||||
: properties(parent->properties),
|
||||
: properties(parent->defaults),
|
||||
scale_factor(scale_factor_),
|
||||
has_dimensions(has_dimensions_),
|
||||
dimensions(dim),
|
||||
|
@ -397,7 +397,7 @@ bool text_placement_info_simple::next()
|
|||
if (state > 0)
|
||||
{
|
||||
if (state > parent_->text_sizes_.size()) return false;
|
||||
properties.default_format.text_size = parent_->text_sizes_[state-1];
|
||||
properties.format.text_size = parent_->text_sizes_[state-1];
|
||||
}
|
||||
if (!next_position_only()) {
|
||||
state++;
|
||||
|
@ -411,7 +411,7 @@ bool text_placement_info_simple::next()
|
|||
|
||||
bool text_placement_info_simple::next_position_only()
|
||||
{
|
||||
const position &pdisp = parent_->properties.displacement;
|
||||
const position &pdisp = parent_->defaults.displacement;
|
||||
position &displacement = properties.displacement;
|
||||
if (position_state >= parent_->direction_.size()) return false;
|
||||
directions_t dir = parent_->direction_[position_state];
|
||||
|
@ -523,7 +523,7 @@ std::string text_placements_simple::get_positions()
|
|||
bool text_placement_info_list::next()
|
||||
{
|
||||
if (state == 0) {
|
||||
properties = parent_->properties;
|
||||
properties = parent_->defaults;
|
||||
} else {
|
||||
if (state-1 >= parent_->list_.size()) return false;
|
||||
properties = parent_->list_[state-1];
|
||||
|
@ -538,7 +538,7 @@ text_symbolizer_properties & text_placements_list::add()
|
|||
text_symbolizer_properties &last = list_.back();
|
||||
list_.push_back(last); //Preinitialize with old values
|
||||
} else {
|
||||
list_.push_back(properties);
|
||||
list_.push_back(defaults);
|
||||
}
|
||||
return list_.back();
|
||||
}
|
||||
|
@ -564,7 +564,7 @@ text_placements_list::text_placements_list() : text_placements(), list_(0)
|
|||
|
||||
void text_placements_list::add_expressions(expression_set &output)
|
||||
{
|
||||
properties.add_expressions(output);
|
||||
defaults.add_expressions(output);
|
||||
|
||||
std::vector<text_symbolizer_properties>::const_iterator it;
|
||||
for (it=list_.begin(); it != list_.end(); it++)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <mapnik/formatting/text.hpp>
|
||||
#include <mapnik/formatting/list.hpp>
|
||||
#include <mapnik/formatting/format.hpp>
|
||||
#include <mapnik/formatting/expression.hpp>
|
||||
#include <mapnik/processed_text.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
@ -62,6 +63,8 @@ node_ptr node::from_xml(boost::property_tree::ptree const& xml)
|
|||
n = text_node::from_xml(itr->second);
|
||||
} else if (itr->first == "Format") {
|
||||
n = format_node::from_xml(itr->second);
|
||||
} else if (itr->first == "ExpressionFormat") {
|
||||
n = expression_format::from_xml(itr->second);
|
||||
} else if (itr->first != "<xmlcomment>" && itr->first != "<xmlattr>" && itr->first != "Placement") {
|
||||
throw config_error("Unknown item " + itr->first);
|
||||
}
|
||||
|
|
|
@ -138,312 +138,312 @@ expression_ptr text_symbolizer::get_name() const
|
|||
|
||||
void text_symbolizer::set_name(expression_ptr name)
|
||||
{
|
||||
placement_options_->properties.set_old_style_expression(name);
|
||||
placement_options_->defaults.set_old_style_expression(name);
|
||||
}
|
||||
|
||||
expression_ptr text_symbolizer::get_orientation() const
|
||||
{
|
||||
return placement_options_->properties.orientation;
|
||||
return placement_options_->defaults.orientation;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_orientation(expression_ptr orientation)
|
||||
{
|
||||
placement_options_->properties.orientation = orientation;
|
||||
placement_options_->defaults.orientation = orientation;
|
||||
}
|
||||
|
||||
std::string const& text_symbolizer::get_face_name() const
|
||||
{
|
||||
return placement_options_->properties.default_format.face_name;
|
||||
return placement_options_->defaults.format.face_name;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_face_name(std::string face_name)
|
||||
{
|
||||
placement_options_->properties.default_format.face_name = face_name;
|
||||
placement_options_->defaults.format.face_name = face_name;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_fontset(font_set const& fontset)
|
||||
{
|
||||
placement_options_->properties.default_format.fontset = fontset;
|
||||
placement_options_->defaults.format.fontset = fontset;
|
||||
}
|
||||
|
||||
font_set const& text_symbolizer::get_fontset() const
|
||||
{
|
||||
return placement_options_->properties.default_format.fontset;
|
||||
return placement_options_->defaults.format.fontset;
|
||||
}
|
||||
|
||||
unsigned text_symbolizer::get_text_ratio() const
|
||||
{
|
||||
return placement_options_->properties.text_ratio;
|
||||
return placement_options_->defaults.text_ratio;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_text_ratio(unsigned ratio)
|
||||
{
|
||||
placement_options_->properties.text_ratio = ratio;
|
||||
placement_options_->defaults.text_ratio = ratio;
|
||||
}
|
||||
|
||||
unsigned text_symbolizer::get_wrap_width() const
|
||||
{
|
||||
return placement_options_->properties.wrap_width;
|
||||
return placement_options_->defaults.wrap_width;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_wrap_width(unsigned width)
|
||||
{
|
||||
placement_options_->properties.wrap_width = width;
|
||||
placement_options_->defaults.wrap_width = width;
|
||||
}
|
||||
|
||||
bool text_symbolizer::get_wrap_before() const
|
||||
{
|
||||
return placement_options_->properties.default_format.wrap_before;
|
||||
return placement_options_->defaults.format.wrap_before;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_wrap_before(bool wrap_before)
|
||||
{
|
||||
placement_options_->properties.default_format.wrap_before = wrap_before;
|
||||
placement_options_->defaults.format.wrap_before = wrap_before;
|
||||
}
|
||||
|
||||
unsigned char text_symbolizer::get_wrap_char() const
|
||||
{
|
||||
return placement_options_->properties.default_format.wrap_char;
|
||||
return placement_options_->defaults.format.wrap_char;
|
||||
}
|
||||
|
||||
std::string text_symbolizer::get_wrap_char_string() const
|
||||
{
|
||||
return std::string(1, placement_options_->properties.default_format.wrap_char);
|
||||
return std::string(1, placement_options_->defaults.format.wrap_char);
|
||||
}
|
||||
|
||||
void text_symbolizer::set_wrap_char(unsigned char character)
|
||||
{
|
||||
placement_options_->properties.default_format.wrap_char = character;
|
||||
placement_options_->defaults.format.wrap_char = character;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_wrap_char_from_string(std::string const& character)
|
||||
{
|
||||
placement_options_->properties.default_format.wrap_char = (character)[0];
|
||||
placement_options_->defaults.format.wrap_char = (character)[0];
|
||||
}
|
||||
|
||||
text_transform_e text_symbolizer::get_text_transform() const
|
||||
{
|
||||
return placement_options_->properties.default_format.text_transform;
|
||||
return placement_options_->defaults.format.text_transform;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_text_transform(text_transform_e convert)
|
||||
{
|
||||
placement_options_->properties.default_format.text_transform = convert;
|
||||
placement_options_->defaults.format.text_transform = convert;
|
||||
}
|
||||
|
||||
unsigned text_symbolizer::get_line_spacing() const
|
||||
{
|
||||
return placement_options_->properties.default_format.line_spacing;
|
||||
return placement_options_->defaults.format.line_spacing;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_line_spacing(unsigned spacing)
|
||||
{
|
||||
placement_options_->properties.default_format.line_spacing = spacing;
|
||||
placement_options_->defaults.format.line_spacing = spacing;
|
||||
}
|
||||
|
||||
unsigned text_symbolizer::get_character_spacing() const
|
||||
{
|
||||
return placement_options_->properties.default_format.character_spacing;
|
||||
return placement_options_->defaults.format.character_spacing;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_character_spacing(unsigned spacing)
|
||||
{
|
||||
placement_options_->properties.default_format.character_spacing = spacing;
|
||||
placement_options_->defaults.format.character_spacing = spacing;
|
||||
}
|
||||
|
||||
unsigned text_symbolizer::get_label_spacing() const
|
||||
{
|
||||
return placement_options_->properties.label_spacing;
|
||||
return placement_options_->defaults.label_spacing;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_label_spacing(unsigned spacing)
|
||||
{
|
||||
placement_options_->properties.label_spacing = spacing;
|
||||
placement_options_->defaults.label_spacing = spacing;
|
||||
}
|
||||
|
||||
unsigned text_symbolizer::get_label_position_tolerance() const
|
||||
{
|
||||
return placement_options_->properties.label_position_tolerance;
|
||||
return placement_options_->defaults.label_position_tolerance;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_label_position_tolerance(unsigned tolerance)
|
||||
{
|
||||
placement_options_->properties.label_position_tolerance = tolerance;
|
||||
placement_options_->defaults.label_position_tolerance = tolerance;
|
||||
}
|
||||
|
||||
bool text_symbolizer::get_force_odd_labels() const
|
||||
{
|
||||
return placement_options_->properties.force_odd_labels;
|
||||
return placement_options_->defaults.force_odd_labels;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_force_odd_labels(bool force)
|
||||
{
|
||||
placement_options_->properties.force_odd_labels = force;
|
||||
placement_options_->defaults.force_odd_labels = force;
|
||||
}
|
||||
|
||||
double text_symbolizer::get_max_char_angle_delta() const
|
||||
{
|
||||
return placement_options_->properties.max_char_angle_delta;
|
||||
return placement_options_->defaults.max_char_angle_delta;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_max_char_angle_delta(double angle)
|
||||
{
|
||||
placement_options_->properties.max_char_angle_delta = angle;
|
||||
placement_options_->defaults.max_char_angle_delta = angle;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_text_size(float size)
|
||||
{
|
||||
placement_options_->properties.default_format.text_size = size;
|
||||
placement_options_->defaults.format.text_size = size;
|
||||
}
|
||||
|
||||
float text_symbolizer::get_text_size() const
|
||||
{
|
||||
return placement_options_->properties.default_format.text_size;
|
||||
return placement_options_->defaults.format.text_size;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_fill(color const& fill)
|
||||
{
|
||||
placement_options_->properties.default_format.fill = fill;
|
||||
placement_options_->defaults.format.fill = fill;
|
||||
}
|
||||
|
||||
color const& text_symbolizer::get_fill() const
|
||||
{
|
||||
return placement_options_->properties.default_format.fill;
|
||||
return placement_options_->defaults.format.fill;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_halo_fill(color const& fill)
|
||||
{
|
||||
placement_options_->properties.default_format.halo_fill = fill;
|
||||
placement_options_->defaults.format.halo_fill = fill;
|
||||
}
|
||||
|
||||
color const& text_symbolizer::get_halo_fill() const
|
||||
{
|
||||
return placement_options_->properties.default_format.halo_fill;
|
||||
return placement_options_->defaults.format.halo_fill;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_halo_radius(double radius)
|
||||
{
|
||||
placement_options_->properties.default_format.halo_radius = radius;
|
||||
placement_options_->defaults.format.halo_radius = radius;
|
||||
}
|
||||
|
||||
double text_symbolizer::get_halo_radius() const
|
||||
{
|
||||
return placement_options_->properties.default_format.halo_radius;
|
||||
return placement_options_->defaults.format.halo_radius;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_label_placement(label_placement_e label_p)
|
||||
{
|
||||
placement_options_->properties.label_placement = label_p;
|
||||
placement_options_->defaults.label_placement = label_p;
|
||||
}
|
||||
|
||||
label_placement_e text_symbolizer::get_label_placement() const
|
||||
{
|
||||
return placement_options_->properties.label_placement;
|
||||
return placement_options_->defaults.label_placement;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_displacement(double x, double y)
|
||||
{
|
||||
placement_options_->properties.displacement = std::make_pair(x,y);
|
||||
placement_options_->defaults.displacement = std::make_pair(x,y);
|
||||
}
|
||||
|
||||
void text_symbolizer::set_displacement(position const& p)
|
||||
{
|
||||
placement_options_->properties.displacement = p;
|
||||
placement_options_->defaults.displacement = p;
|
||||
}
|
||||
|
||||
position const& text_symbolizer::get_displacement() const
|
||||
{
|
||||
return placement_options_->properties.displacement;
|
||||
return placement_options_->defaults.displacement;
|
||||
}
|
||||
|
||||
bool text_symbolizer::get_avoid_edges() const
|
||||
{
|
||||
return placement_options_->properties.avoid_edges;
|
||||
return placement_options_->defaults.avoid_edges;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_avoid_edges(bool avoid)
|
||||
{
|
||||
placement_options_->properties.avoid_edges = avoid;
|
||||
placement_options_->defaults.avoid_edges = avoid;
|
||||
}
|
||||
|
||||
double text_symbolizer::get_minimum_distance() const
|
||||
{
|
||||
return placement_options_->properties.minimum_distance;
|
||||
return placement_options_->defaults.minimum_distance;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_minimum_distance(double distance)
|
||||
{
|
||||
placement_options_->properties.minimum_distance = distance;
|
||||
placement_options_->defaults.minimum_distance = distance;
|
||||
}
|
||||
|
||||
double text_symbolizer::get_minimum_padding() const
|
||||
{
|
||||
return placement_options_->properties.minimum_padding;
|
||||
return placement_options_->defaults.minimum_padding;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_minimum_padding(double distance)
|
||||
{
|
||||
placement_options_->properties.minimum_padding = distance;
|
||||
placement_options_->defaults.minimum_padding = distance;
|
||||
}
|
||||
|
||||
double text_symbolizer::get_minimum_path_length() const
|
||||
{
|
||||
return placement_options_->properties.minimum_path_length;
|
||||
return placement_options_->defaults.minimum_path_length;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_minimum_path_length(double size)
|
||||
{
|
||||
placement_options_->properties.minimum_path_length = size;
|
||||
placement_options_->defaults.minimum_path_length = size;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_allow_overlap(bool overlap)
|
||||
{
|
||||
placement_options_->properties.allow_overlap = overlap;
|
||||
placement_options_->defaults.allow_overlap = overlap;
|
||||
}
|
||||
|
||||
bool text_symbolizer::get_allow_overlap() const
|
||||
{
|
||||
return placement_options_->properties.allow_overlap;
|
||||
return placement_options_->defaults.allow_overlap;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_text_opacity(double text_opacity)
|
||||
{
|
||||
placement_options_->properties.default_format.text_opacity = text_opacity;
|
||||
placement_options_->defaults.format.text_opacity = text_opacity;
|
||||
}
|
||||
|
||||
double text_symbolizer::get_text_opacity() const
|
||||
{
|
||||
return placement_options_->properties.default_format.text_opacity;
|
||||
return placement_options_->defaults.format.text_opacity;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_vertical_alignment(vertical_alignment_e valign)
|
||||
{
|
||||
placement_options_->properties.valign = valign;
|
||||
placement_options_->defaults.valign = valign;
|
||||
}
|
||||
|
||||
vertical_alignment_e text_symbolizer::get_vertical_alignment() const
|
||||
{
|
||||
return placement_options_->properties.valign;
|
||||
return placement_options_->defaults.valign;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_horizontal_alignment(horizontal_alignment_e halign)
|
||||
{
|
||||
placement_options_->properties.halign = halign;
|
||||
placement_options_->defaults.halign = halign;
|
||||
}
|
||||
|
||||
horizontal_alignment_e text_symbolizer::get_horizontal_alignment() const
|
||||
{
|
||||
return placement_options_->properties.halign;
|
||||
return placement_options_->defaults.halign;
|
||||
}
|
||||
|
||||
void text_symbolizer::set_justify_alignment(justify_alignment_e jalign)
|
||||
{
|
||||
placement_options_->properties.jalign = jalign;
|
||||
placement_options_->defaults.jalign = jalign;
|
||||
}
|
||||
|
||||
justify_alignment_e text_symbolizer::get_justify_alignment() const
|
||||
{
|
||||
return placement_options_->properties.jalign;
|
||||
return placement_options_->defaults.jalign;
|
||||
}
|
||||
|
||||
text_placements_ptr text_symbolizer::get_placement_options() const
|
||||
|
|
|
@ -296,7 +296,6 @@ private:
|
|||
int num_points = read_integer();
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords(ar);
|
||||
line->set_capacity(num_points);
|
||||
line->move_to(ar[0].x, ar[0].y);
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
|
@ -321,7 +320,6 @@ private:
|
|||
int num_points = read_integer();
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords_xyz(ar);
|
||||
line->set_capacity(num_points);
|
||||
line->move_to(ar[0].x, ar[0].y);
|
||||
for (int i = 1; i < num_points; ++i)
|
||||
{
|
||||
|
@ -352,7 +350,6 @@ private:
|
|||
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)
|
||||
{
|
||||
|
@ -383,7 +380,6 @@ private:
|
|||
capacity += num_points;
|
||||
CoordinateArray ar(num_points);
|
||||
read_coords_xyz(ar);
|
||||
poly->set_capacity(capacity);
|
||||
poly->move_to(ar[0].x, ar[0].y);
|
||||
for (int j = 1; j < num_points; ++j)
|
||||
{
|
||||
|
|
|
@ -67,8 +67,11 @@ def test_feature_expression_evaluation_missing_attr():
|
|||
f['name'] = u'a'
|
||||
eq_(f['name'],u'a')
|
||||
expr = mapnik.Expression("[fielddoesnotexist]='a'")
|
||||
evaluated = expr.evaluate(f)
|
||||
eq_(evaluated,False)
|
||||
eq_(f.has_key('fielddoesnotexist'),False)
|
||||
try:
|
||||
evaluated = expr.evaluate(f)
|
||||
except Exception, e:
|
||||
eq_("Key does not exist" in str(e),True)
|
||||
num_attributes = len(f)
|
||||
eq_(num_attributes,1)
|
||||
eq_(f.id(),1)
|
||||
|
|
|
@ -16,17 +16,18 @@ def test_add_feature():
|
|||
featureset = md.features_at_point(mapnik.Coord(2,3))
|
||||
retrieved = []
|
||||
feat = featureset.next()
|
||||
while featureset.next():
|
||||
while feat:
|
||||
retrieved.append(feat)
|
||||
feat = featureset.next()
|
||||
|
||||
eq_(len(retrieved), 1)
|
||||
f = retrieved[0]
|
||||
eq_(f['foo'], 'bar')
|
||||
|
||||
featureset = md.features_at_point(Coord(20,30)).features
|
||||
featureset = md.features_at_point(mapnik.Coord(20,30))
|
||||
retrieved = []
|
||||
feat = featureset.next()
|
||||
while featureset.next():
|
||||
while feat:
|
||||
retrieved.append(feat)
|
||||
eq_(len(retrieved), 0)
|
||||
|
||||
|
|
BIN
tests/visual_tests/expressionformat-500-reference.png
Normal file
BIN
tests/visual_tests/expressionformat-500-reference.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
22
tests/visual_tests/expressionformat.xml
Normal file
22
tests/visual_tests/expressionformat.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map>
|
||||
<Map background-color="white" srs="+proj=latlong +datum=WGS84">
|
||||
|
||||
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
|
||||
<StyleName>My Style</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">shape</Parameter>
|
||||
<Parameter name="file">points.shp</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<Style name="My Style">
|
||||
<Rule>
|
||||
<PointSymbolizer/>
|
||||
<TextSymbolizer face-name="DejaVu Sans Book" placement="point" dx="0" dy="5">
|
||||
<ExpressionFormat size="[nr]">[name]</ExpressionFormat>
|
||||
</TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
</Map>
|
|
@ -13,7 +13,7 @@ filenames = ["list", "simple"]
|
|||
filenames_one_width = ["simple-E", "simple-NE", "simple-NW", "simple-N",
|
||||
"simple-SE", "simple-SW", "simple-S", "simple-W",
|
||||
"formating-1", "formating-2", "formating-3", "formating-4",
|
||||
"shieldsymbolizer-1"]
|
||||
"shieldsymbolizer-1", "expressionformat"]
|
||||
|
||||
def render(filename, width):
|
||||
print "Rendering style \"%s\" with width %d" % (filename, width)
|
||||
|
|
|
@ -41,6 +41,13 @@ boost_filesystem = 'boost_filesystem%s' % env['BOOST_APPEND']
|
|||
boost_system = 'boost_system%s' % env['BOOST_APPEND']
|
||||
libraries = [boost_program_options, boost_filesystem, boost_system]
|
||||
|
||||
if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||
boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
|
||||
if boost_version_from_header < 46:
|
||||
# avoid ubuntu issue with boost interprocess:
|
||||
# https://github.com/mapnik/mapnik/issues/1082
|
||||
program_env.Append(CXXFLAGS = '-fpermissive')
|
||||
|
||||
shapeindex = program_env.Program('shapeindex', source, CPPPATH=headers, LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS'])
|
||||
|
||||
Depends(shapeindex, env.subst('../../src/%s' % env['MAPNIK_LIB_NAME']))
|
||||
|
|
Loading…
Add table
Reference in a new issue