Merge branch 'pi-is-wrong' of https://github.com/lightmare/mapnik into lightmare-pi-is-wrong
This commit is contained in:
commit
af842a8bf9
21 changed files with 261 additions and 178 deletions
|
@ -123,14 +123,6 @@ inline double round(double val)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define _USE_MATH_DEFINES
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,24 +75,27 @@ protected:
|
|||
angle = 0;
|
||||
return true;
|
||||
case DIRECTION_DOWN:
|
||||
angle = M_PI;
|
||||
angle = util::pi;
|
||||
return true;
|
||||
case DIRECTION_AUTO:
|
||||
if (std::fabs(util::normalize_angle(angle)) > 0.5 * M_PI)
|
||||
angle += M_PI;
|
||||
angle = util::normalize_angle(angle);
|
||||
if (std::abs(angle) > util::pi / 2)
|
||||
angle += util::pi;
|
||||
return true;
|
||||
case DIRECTION_AUTO_DOWN:
|
||||
if (std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI)
|
||||
angle += M_PI;
|
||||
angle = util::normalize_angle(angle);
|
||||
if (std::abs(angle) < util::pi / 2)
|
||||
angle += util::pi;
|
||||
return true;
|
||||
case DIRECTION_LEFT:
|
||||
angle += M_PI;
|
||||
angle += util::pi;
|
||||
return true;
|
||||
case DIRECTION_LEFT_ONLY:
|
||||
angle += M_PI;
|
||||
return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
|
||||
angle = util::normalize_angle(angle + util::pi);
|
||||
return std::fabs(angle) < util::pi / 2;
|
||||
case DIRECTION_RIGHT_ONLY:
|
||||
return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
|
||||
angle = util::normalize_angle(angle);
|
||||
return std::fabs(angle) < util::pi / 2;
|
||||
case DIRECTION_RIGHT:
|
||||
default:
|
||||
return true;
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#ifdef MAPNIK_LOG
|
||||
#include <mapnik/debug.hpp>
|
||||
#endif
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/vertex_cache.hpp>
|
||||
|
||||
|
@ -184,13 +184,13 @@ private:
|
|||
|
||||
static double explement_reflex_angle(double angle)
|
||||
{
|
||||
if (angle > M_PI)
|
||||
if (angle > util::pi)
|
||||
{
|
||||
return angle - 2 * M_PI;
|
||||
return angle - util::tau;
|
||||
}
|
||||
else if (angle < -M_PI)
|
||||
else if (angle < -util::pi)
|
||||
{
|
||||
return angle + 2 * M_PI;
|
||||
return angle + util::tau;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -244,6 +244,30 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
double joint_angle(double x1x0, double y1y0, double x1x2, double y1y2) const
|
||||
{
|
||||
double dot = x1x0 * x1x2 + y1y0 * y1y2; // dot product
|
||||
double det = x1x0 * y1y2 - y1y0 * x1x2; // determinant
|
||||
double angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
||||
// angle in [-tau/2; tau/2]
|
||||
|
||||
if (offset_ > 0.0)
|
||||
{
|
||||
angle = util::tau - angle; // angle in [tau/2; tau*3/2]
|
||||
}
|
||||
else if (angle < 0)
|
||||
{
|
||||
angle += util::tau; // angle in [tau/2; tau]
|
||||
// angle may now be equal to tau, because if the original angle
|
||||
// is very small, the addition cancels it (epsilon + tau == tau)
|
||||
}
|
||||
if (angle >= util::tau)
|
||||
{
|
||||
angle -= util::tau;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Translate (vx, vy) by rotated (dx, dy).
|
||||
*/
|
||||
|
@ -423,13 +447,8 @@ private:
|
|||
cpt++;
|
||||
angle_a = std::atan2(-v_y1y0, -v_x1x0);
|
||||
}
|
||||
// dot product
|
||||
double dot;
|
||||
// determinate
|
||||
double det;
|
||||
double angle_b = std::atan2(v_y1y2, v_x1x2);
|
||||
// Angle between the two vectors
|
||||
double joint_angle;
|
||||
double curve_angle;
|
||||
|
||||
if (!is_polygon)
|
||||
|
@ -440,26 +459,15 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
|
||||
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
|
||||
|
||||
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
||||
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
|
||||
joint_angle = std::fmod(joint_angle, 2 * M_PI);
|
||||
|
||||
if (offset_ > 0.0)
|
||||
{
|
||||
joint_angle = 2 * M_PI - joint_angle;
|
||||
}
|
||||
|
||||
double joint_angle = this->joint_angle(v_x1x0, v_y1y0, v_x1x2, v_y1y2);
|
||||
int bulge_steps = 0;
|
||||
|
||||
if (std::abs(joint_angle) > M_PI)
|
||||
if (std::abs(joint_angle) > util::pi)
|
||||
{
|
||||
curve_angle = explement_reflex_angle(angle_b - angle_a);
|
||||
// Bulge steps should be determined by the inverse of the joint angle.
|
||||
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
|
||||
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
|
||||
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / util::pi));
|
||||
}
|
||||
|
||||
if (bulge_steps == 0)
|
||||
|
@ -545,26 +553,15 @@ private:
|
|||
// Calculate the new angle_b
|
||||
angle_b = std::atan2(v_y1y2, v_x1x2);
|
||||
|
||||
dot = v_x1x0 * v_x1x2 + v_y1y0 * v_y1y2; // dot product
|
||||
det = v_x1x0 * v_y1y2 - v_y1y0 * v_x1x2; // determinant
|
||||
|
||||
joint_angle = std::atan2(det, dot); // atan2(y, x) or atan2(sin, cos)
|
||||
if (joint_angle < 0) joint_angle = joint_angle + 2 * M_PI;
|
||||
joint_angle = std::fmod(joint_angle, 2 * M_PI);
|
||||
|
||||
if (offset_ > 0.0)
|
||||
{
|
||||
joint_angle = 2 * M_PI - joint_angle;
|
||||
}
|
||||
|
||||
double joint_angle = this->joint_angle(v_x1x0, v_y1y0, v_x1x2, v_y1y2);
|
||||
int bulge_steps = 0;
|
||||
|
||||
if (std::abs(joint_angle) > M_PI)
|
||||
if (std::abs(joint_angle) > util::pi)
|
||||
{
|
||||
curve_angle = explement_reflex_angle(angle_b - angle_a);
|
||||
// Bulge steps should be determined by the inverse of the joint angle.
|
||||
double half_turns = half_turn_segments_ * std::fabs(curve_angle);
|
||||
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / M_PI));
|
||||
bulge_steps = 1 + static_cast<int>(std::floor(half_turns / util::pi));
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_LOG
|
||||
|
@ -572,14 +569,16 @@ private:
|
|||
{
|
||||
// inside turn (sharp/obtuse angle)
|
||||
MAPNIK_LOG_DEBUG(ctrans) << "offset_converter:"
|
||||
<< " Sharp joint [<< inside turn " << int(joint_angle*180/M_PI)
|
||||
<< " Sharp joint [<< inside turn "
|
||||
<< static_cast<int>(util::degrees(joint_angle))
|
||||
<< " degrees >>]";
|
||||
}
|
||||
else
|
||||
{
|
||||
// outside turn (reflex angle)
|
||||
MAPNIK_LOG_DEBUG(ctrans) << "offset_converter:"
|
||||
<< " Bulge joint >)) outside turn " << int(joint_angle*180/M_PI)
|
||||
<< " Bulge joint >)) outside turn "
|
||||
<< static_cast<int>(util::degrees(joint_angle))
|
||||
<< " degrees ((< with " << bulge_steps << " segments";
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP
|
||||
|
||||
#include <mapnik/svg/svg_path_parser.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
|
@ -52,8 +53,6 @@ using svg_parse_context_type = x3::context<relative_tag, relative_type,
|
|||
x3::context<svg_path_tag, svg_converter_wrapper_type,
|
||||
phrase_parse_context_type>>;
|
||||
|
||||
inline double deg2rad(double deg) {return (M_PI * deg) / 180.0;}
|
||||
|
||||
}}}
|
||||
|
||||
#endif // MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#define MAPNIK_SVG_PATH_COMMANDS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
@ -35,12 +35,6 @@
|
|||
namespace mapnik {
|
||||
namespace svg {
|
||||
|
||||
|
||||
inline double deg2rad(double deg)
|
||||
{
|
||||
return (M_PI * deg) / 180.0;
|
||||
}
|
||||
|
||||
struct move_to
|
||||
{
|
||||
using result_type = void;
|
||||
|
@ -137,7 +131,7 @@ struct arc_to
|
|||
void operator()(PathType& path, T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
|
||||
{
|
||||
path.arc_to(boost::fusion::at_c<0>(rv), boost::fusion::at_c<1>(rv),
|
||||
deg2rad(angle), large_arc_flag, sweep_flag,
|
||||
util::radians(angle), large_arc_flag, sweep_flag,
|
||||
boost::fusion::at_c<0>(v), boost::fusion::at_c<1>(v),
|
||||
rel);
|
||||
}
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||
|
@ -123,8 +124,9 @@ auto const arc_to = [] (auto & ctx)
|
|||
int large_arc_flag = boost::fusion::at_c<2>(attr);
|
||||
int sweep_flag = boost::fusion::at_c<3>(attr);
|
||||
auto const& v = boost::fusion::at_c<4>(attr);
|
||||
extract_path(ctx).arc_to(std::get<0>(p),std::get<1>(p),
|
||||
deg2rad(angle), large_arc_flag, sweep_flag,
|
||||
x3::get<svg_path_tag>(ctx).get().arc_to(std::get<0>(p),std::get<1>(p),
|
||||
util::radians(angle),
|
||||
large_arc_flag, sweep_flag,
|
||||
std::get<0>(v),std::get<1>(v),
|
||||
x3::get<relative_tag>(ctx));
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/svg/svg_transform_grammar_x3.hpp>
|
||||
|
||||
// boost::fusion
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
@ -72,12 +73,12 @@ auto const rotate_action = [] (auto const& ctx)
|
|||
auto cy = boost::fusion::at_c<2>(attr) ? *boost::fusion::at_c<2>(attr) : 0.0;
|
||||
if (cx == 0.0 && cy == 0.0)
|
||||
{
|
||||
tr = agg::trans_affine_rotation(deg2rad(a)) * tr;
|
||||
tr = agg::trans_affine_rotation(agg::deg2rad(a)) * tr;
|
||||
}
|
||||
else
|
||||
{
|
||||
agg::trans_affine t = agg::trans_affine_translation(-cx, -cy);
|
||||
t *= agg::trans_affine_rotation(deg2rad(a));
|
||||
t *= agg::trans_affine_rotation(agg::deg2rad(a));
|
||||
t *= agg::trans_affine_translation(cx, cy);
|
||||
tr = t * tr;
|
||||
}
|
||||
|
@ -107,14 +108,14 @@ auto const skewX_action = [] (auto const& ctx)
|
|||
{
|
||||
auto & tr = extract_transform(ctx);
|
||||
auto skew_x = _attr(ctx);
|
||||
tr = agg::trans_affine_skewing(deg2rad(skew_x), 0.0) * tr;
|
||||
tr = agg::trans_affine_skewing(agg::deg2rad(skew_x), 0.0) * tr;
|
||||
};
|
||||
|
||||
auto const skewY_action = [] (auto const& ctx)
|
||||
{
|
||||
auto & tr = extract_transform(ctx);
|
||||
auto skew_y= _attr(ctx);
|
||||
tr = agg::trans_affine_skewing(0.0, deg2rad(skew_y)) * tr;
|
||||
tr = agg::trans_affine_skewing(0.0, agg::deg2rad(skew_y)) * tr;
|
||||
};
|
||||
|
||||
//exported rule
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <mapnik/value.hpp>
|
||||
#include <mapnik/transform/transform_expression.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -145,7 +146,7 @@ struct transform_processor
|
|||
|
||||
void operator() (rotate_node const& node) const
|
||||
{
|
||||
double angle = deg2rad(eval(node.angle_));
|
||||
double angle = agg::deg2rad(eval(node.angle_));
|
||||
double cx = eval(node.cx_, 0.0);
|
||||
double cy = eval(node.cy_, 0.0);
|
||||
transform_.translate(-cx, -cy);
|
||||
|
@ -156,28 +157,19 @@ struct transform_processor
|
|||
void operator() (skewX_node const& node) const
|
||||
{
|
||||
auto degrees = std::fmod(eval(node.angle_),90.0);
|
||||
if (degrees < -89.0) degrees = -89.0;
|
||||
else if (degrees > 89.0) degrees = 89.0;
|
||||
auto angle = deg2rad(degrees);
|
||||
auto angle = agg::deg2rad(util::clamp(degrees, -89.0, 89.0));
|
||||
transform_.multiply(agg::trans_affine_skewing(angle, 0.0));
|
||||
}
|
||||
|
||||
void operator() (skewY_node const& node) const
|
||||
{
|
||||
auto degrees = std::fmod(eval(node.angle_),90.0);
|
||||
if (degrees < -89.0) degrees = -89.0;
|
||||
else if (degrees > 89.0) degrees = 89.0;
|
||||
auto angle = deg2rad(degrees);
|
||||
auto angle = agg::deg2rad(util::clamp(degrees, -89.0, 89.0));
|
||||
transform_.multiply(agg::trans_affine_skewing(0.0, angle));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static double deg2rad(double d)
|
||||
{
|
||||
return d * M_PI / 180.0;
|
||||
}
|
||||
|
||||
double eval(expr_node const& x) const
|
||||
{
|
||||
mapnik::evaluate<feature_type, value_type, variable_type> e(feature_,vars_);
|
||||
|
|
|
@ -30,6 +30,22 @@ namespace mapnik { namespace util {
|
|||
constexpr double pi = 3.1415926535897932384626433832795;
|
||||
constexpr double tau = 6.283185307179586476925286766559;
|
||||
|
||||
template <typename T>
|
||||
constexpr T const& clamp(T const& v, T const& lo, T const& hi)
|
||||
{
|
||||
return v < lo ? lo : hi < v ? hi : v;
|
||||
}
|
||||
|
||||
constexpr double degrees(double rad)
|
||||
{
|
||||
return rad * (360 / tau);
|
||||
}
|
||||
|
||||
constexpr double radians(double deg)
|
||||
{
|
||||
return deg * (tau / 360);
|
||||
}
|
||||
|
||||
MAPNIK_DECL double normalize_angle(double angle);
|
||||
|
||||
}}
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#define MAPNIK_WELL_KNOWN_SRS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp> // for M_PI on windows
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/geometry/point.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
|
@ -34,7 +34,6 @@
|
|||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
namespace mapnik {
|
||||
|
@ -47,81 +46,27 @@ enum well_known_srs_enum : std::uint8_t {
|
|||
|
||||
DEFINE_ENUM( well_known_srs_e, well_known_srs_enum );
|
||||
|
||||
static const double EARTH_RADIUS = 6378137.0;
|
||||
static const double EARTH_DIAMETER = EARTH_RADIUS * 2.0;
|
||||
static const double EARTH_CIRCUMFERENCE = EARTH_DIAMETER * M_PI;
|
||||
static const double MAXEXTENT = EARTH_CIRCUMFERENCE / 2.0;
|
||||
static const double M_PI_by2 = M_PI / 2;
|
||||
static const double D2R = M_PI / 180.0;
|
||||
static const double R2D = 180.0 / M_PI;
|
||||
static const double M_PIby360 = M_PI / 360.0;
|
||||
static const double MAXEXTENTby180 = MAXEXTENT / 180.0;
|
||||
static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180.0 * D2R)) - M_PI_by2);
|
||||
static const std::string MAPNIK_LONGLAT_PROJ = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
|
||||
static const std::string MAPNIK_GMERC_PROJ = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over";
|
||||
constexpr double EARTH_RADIUS = 6378137.0;
|
||||
constexpr double EARTH_CIRCUMFERENCE = EARTH_RADIUS * util::tau;
|
||||
constexpr double MERC_MAX_EXTENT = EARTH_RADIUS * util::pi;
|
||||
constexpr double MERC_MAX_LATITUDE = 85.0511287798065923778;
|
||||
// MERC_MAX_LATITUDE = degrees(2 * atan(exp(pi)) - pi / 2)
|
||||
|
||||
boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs);
|
||||
extern MAPNIK_DECL std::string const MAPNIK_LONGLAT_PROJ;
|
||||
extern MAPNIK_DECL std::string const MAPNIK_GMERC_PROJ;
|
||||
|
||||
boost::optional<bool> is_known_geographic(std::string const& srs);
|
||||
MAPNIK_DECL boost::optional<bool> is_known_geographic(std::string const& srs);
|
||||
MAPNIK_DECL boost::optional<well_known_srs_e> is_well_known_srs(std::string const& srs);
|
||||
|
||||
static inline bool lonlat2merc(double * x, double * y, std::size_t point_count)
|
||||
{
|
||||
for (std::size_t i = 0; i < point_count; ++i)
|
||||
{
|
||||
if (x[i] > 180) x[i] = 180;
|
||||
else if (x[i] < -180) x[i] = -180;
|
||||
if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE;
|
||||
else if (y[i] < -MAX_LATITUDE) y[i] = -MAX_LATITUDE;
|
||||
x[i] = x[i] * MAXEXTENTby180;
|
||||
y[i] = std::log(std::tan((90.0 + y[i]) * M_PIby360)) * R2D * MAXEXTENTby180;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
MAPNIK_DECL bool lonlat2merc(double & x, double & y);
|
||||
MAPNIK_DECL bool lonlat2merc(double * x, double * y, std::size_t point_count,
|
||||
std::size_t stride = 1);
|
||||
MAPNIK_DECL bool lonlat2merc(std::vector<geometry::point<double>> & ls);
|
||||
|
||||
static inline bool merc2lonlat(double * x, double * y, std::size_t point_count)
|
||||
{
|
||||
for(std::size_t i = 0; i < point_count; ++i)
|
||||
{
|
||||
if (x[i] > MAXEXTENT) x[i] = MAXEXTENT;
|
||||
else if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT;
|
||||
if (y[i] > MAXEXTENT) y[i] = MAXEXTENT;
|
||||
else if (y[i] < -MAXEXTENT) y[i] = -MAXEXTENT;
|
||||
x[i] = (x[i] / MAXEXTENT) * 180;
|
||||
y[i] = (y[i] / MAXEXTENT) * 180;
|
||||
y[i] = R2D * (2 * std::atan(std::exp(y[i] * D2R)) - M_PI_by2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool lonlat2merc(std::vector<geometry::point<double>> & ls)
|
||||
{
|
||||
for (auto& p : ls)
|
||||
{
|
||||
if (p.x > 180) p.x = 180;
|
||||
else if (p.x < -180) p.x = -180;
|
||||
if (p.y > MAX_LATITUDE) p.y = MAX_LATITUDE;
|
||||
else if (p.y < -MAX_LATITUDE) p.y = -MAX_LATITUDE;
|
||||
p.x = p.x * MAXEXTENTby180;
|
||||
p.y = std::log(std::tan((90 + p.y) * M_PIby360)) * R2D;
|
||||
p.y = p.y * MAXEXTENTby180;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool merc2lonlat(std::vector<geometry::point<double>> & ls)
|
||||
{
|
||||
for (auto & p : ls)
|
||||
{
|
||||
if (p.x > MAXEXTENT) p.x = MAXEXTENT;
|
||||
else if (p.x < -MAXEXTENT) p.x = -MAXEXTENT;
|
||||
if (p.y > MAXEXTENT) p.y = MAXEXTENT;
|
||||
else if (p.y < -MAXEXTENT) p.y = -MAXEXTENT;
|
||||
p.x = (p.x / MAXEXTENT) * 180;
|
||||
p.y = (p.y / MAXEXTENT) * 180;
|
||||
p.y = R2D * (2 * std::atan(std::exp(p.y * D2R)) - M_PI_by2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
MAPNIK_DECL bool merc2lonlat(double & x, double & y);
|
||||
MAPNIK_DECL bool merc2lonlat(double * x, double * y, std::size_t point_count,
|
||||
std::size_t stride = 1);
|
||||
MAPNIK_DECL bool merc2lonlat(std::vector<geometry::point<double>> & ls);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ source = Split(
|
|||
renderer_common/render_markers_symbolizer.cpp
|
||||
renderer_common/render_pattern.cpp
|
||||
renderer_common/render_thunk_extractor.cpp
|
||||
math.cpp
|
||||
util/math.cpp
|
||||
value.cpp
|
||||
"""
|
||||
)
|
||||
|
|
|
@ -195,11 +195,11 @@ bool proj_transform::forward (double * x, double * y , double * z, int point_cou
|
|||
|
||||
if (wgs84_to_merc_)
|
||||
{
|
||||
return lonlat2merc(x,y,point_count);
|
||||
return lonlat2merc(x, y, point_count, offset);
|
||||
}
|
||||
else if (merc_to_wgs84_)
|
||||
{
|
||||
return merc2lonlat(x,y,point_count);
|
||||
return merc2lonlat(x, y, point_count, offset);
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_USE_PROJ4
|
||||
|
@ -244,11 +244,11 @@ bool proj_transform::backward (double * x, double * y , double * z, int point_co
|
|||
|
||||
if (wgs84_to_merc_)
|
||||
{
|
||||
return merc2lonlat(x,y,point_count);
|
||||
return merc2lonlat(x, y, point_count, offset);
|
||||
}
|
||||
else if (merc_to_wgs84_)
|
||||
{
|
||||
return lonlat2merc(x,y,point_count);
|
||||
return lonlat2merc(x, y, point_count, offset);
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_USE_PROJ4
|
||||
|
|
|
@ -135,11 +135,13 @@ text_upright_e placement_finder::simplify_upright(text_upright_e upright, double
|
|||
{
|
||||
if (upright == UPRIGHT_AUTO)
|
||||
{
|
||||
return (std::fabs(util::normalize_angle(angle)) > 0.5*M_PI) ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
||||
angle = util::normalize_angle(angle);
|
||||
return std::abs(angle) > util::tau / 4 ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
||||
}
|
||||
if (upright == UPRIGHT_AUTO_DOWN)
|
||||
{
|
||||
return (std::fabs(util::normalize_angle(angle)) < 0.5*M_PI) ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
||||
angle = util::normalize_angle(angle);
|
||||
return std::abs(angle) < util::tau / 4 ? UPRIGHT_LEFT : UPRIGHT_RIGHT;
|
||||
}
|
||||
if (upright == UPRIGHT_LEFT_ONLY)
|
||||
{
|
||||
|
@ -332,7 +334,7 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
|
|||
last_cluster_angle = angle;
|
||||
}
|
||||
|
||||
if (std::abs(angle) > M_PI/2)
|
||||
if (std::abs(angle) > util::tau / 4)
|
||||
{
|
||||
++upside_down_glyph_count;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/text/harfbuzz_shaper.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/make_unique.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -117,7 +118,7 @@ text_layout::text_layout(face_manager_freetype & font_manager,
|
|||
if (!wrap_str.empty()) wrap_char_ = wrap_str[0];
|
||||
wrap_width_ = util::apply_visitor(extract_value<value_double>(feature,attrs), layout_properties_.wrap_width);
|
||||
double angle = util::apply_visitor(extract_value<value_double>(feature,attrs), layout_properties_.orientation);
|
||||
orientation_.init(angle * M_PI/ 180.0);
|
||||
orientation_.init(util::radians(angle));
|
||||
wrap_before_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.wrap_before);
|
||||
repeat_wrap_char_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.repeat_wrap_char);
|
||||
rotate_displacement_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.rotate_displacement);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/text/text_properties.hpp>
|
||||
#include <mapnik/text/text_layout.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
@ -59,7 +60,7 @@ evaluated_text_properties_ptr evaluate_text_properties(text_symbolizer_propertie
|
|||
prop->minimum_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_distance);
|
||||
prop->minimum_padding = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_padding);
|
||||
prop->minimum_path_length = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_path_length);
|
||||
prop->max_char_angle_delta = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.max_char_angle_delta) * M_PI/180;
|
||||
prop->max_char_angle_delta = util::radians(util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.max_char_angle_delta));
|
||||
prop->allow_overlap = util::apply_visitor(extract_value<value_bool>(feature,attrs), text_prop.expressions.allow_overlap);
|
||||
prop->largest_bbox_only = util::apply_visitor(extract_value<value_bool>(feature,attrs), text_prop.expressions.largest_bbox_only);
|
||||
prop->upright = util::apply_visitor(extract_value<text_upright_enum>(feature,attrs), text_prop.expressions.upright);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*****************************************************************************/
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/vertex_cache.hpp>
|
||||
#include <mapnik/offset_converter.hpp>
|
||||
#include <mapnik/make_unique.hpp>
|
||||
|
@ -75,7 +75,7 @@ double vertex_cache::angle(double width)
|
|||
angle_ = current_segment_angle();
|
||||
}
|
||||
}
|
||||
return width >= 0 ? angle_ : angle_ + M_PI;
|
||||
return width >= 0 ? angle_ : angle_ + util::pi;
|
||||
}
|
||||
|
||||
bool vertex_cache::next_subpath()
|
||||
|
|
|
@ -30,8 +30,18 @@
|
|||
#include <boost/optional.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <cmath>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
extern std::string const MAPNIK_LONGLAT_PROJ =
|
||||
"+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";
|
||||
|
||||
extern std::string const MAPNIK_GMERC_PROJ =
|
||||
"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0"
|
||||
" +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over";
|
||||
|
||||
static const char * well_known_srs_strings[] = {
|
||||
"mapnik-longlat",
|
||||
"mapnik-gmerc",
|
||||
|
@ -82,4 +92,60 @@ boost::optional<bool> is_known_geographic(std::string const& srs)
|
|||
|
||||
IMPLEMENT_ENUM( well_known_srs_e, well_known_srs_strings )
|
||||
|
||||
bool lonlat2merc(double & x, double & y)
|
||||
{
|
||||
using namespace util;
|
||||
auto dx = clamp(x, -180.0, 180.0);
|
||||
auto dy = clamp(y, -MERC_MAX_LATITUDE, MERC_MAX_LATITUDE);
|
||||
x = EARTH_RADIUS * radians(dx);
|
||||
y = EARTH_RADIUS * std::log(std::tan(radians(90 + dy) / 2));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lonlat2merc(double * x, double * y, std::size_t point_count, std::size_t stride)
|
||||
{
|
||||
for (std::size_t i = 0; i < point_count; ++i)
|
||||
{
|
||||
lonlat2merc(x[i * stride], y[i * stride]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lonlat2merc(std::vector<geometry::point<double>> & ls)
|
||||
{
|
||||
for (auto & p : ls)
|
||||
{
|
||||
lonlat2merc(p.x, p.y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool merc2lonlat(double & x, double & y)
|
||||
{
|
||||
using namespace util;
|
||||
auto rx = clamp(x / EARTH_RADIUS, -pi, pi);
|
||||
auto ry = clamp(y / EARTH_RADIUS, -pi, pi);
|
||||
x = degrees(rx);
|
||||
y = degrees(2 * std::atan(std::exp(ry)) - pi / 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool merc2lonlat(double * x, double * y, std::size_t point_count, std::size_t stride)
|
||||
{
|
||||
for(std::size_t i = 0; i < point_count; ++i)
|
||||
{
|
||||
merc2lonlat(x[i * stride], y[i * stride]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool merc2lonlat(std::vector<geometry::point<double>> & ls)
|
||||
{
|
||||
for (auto & p : ls)
|
||||
{
|
||||
merc2lonlat(p.x, p.y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -206,4 +206,73 @@ SECTION("Test proj antimeridian bbox")
|
|||
}
|
||||
}
|
||||
|
||||
SECTION("proj_transform of coordinate arrays with stride > 1")
|
||||
{
|
||||
mapnik::projection const proj_4326("+init=epsg:4326");
|
||||
mapnik::projection const proj_3857("+init=epsg:3857");
|
||||
mapnik::projection const proj_2193("+init=epsg:2193");
|
||||
|
||||
SECTION("lonlat <-> Web Mercator")
|
||||
{
|
||||
// cs2cs -Ef %.10f +init=epsg:4326 +to +init=epsg:3857 <<END
|
||||
// 170.142139 -43.595056
|
||||
// 175.566667 -39.283333
|
||||
// END
|
||||
//
|
||||
// 170.142139 -43.595056 18940136.2759583741 -5402988.5324898539
|
||||
// 175.566667 -39.283333 19543991.9707122259 -4762338.2380718365
|
||||
//
|
||||
mapnik::geometry::point<double> points[] = {{ 170.142139, -43.595056 },
|
||||
{ 175.566667, -39.283333 }};
|
||||
// this transform is calculated by Mapnik (well_known_srs.cpp)
|
||||
mapnik::proj_transform lonlat_to_webmerc(proj_4326, proj_3857);
|
||||
CHECKED_IF(lonlat_to_webmerc.forward(&points[0].x, &points[0].y, nullptr, 2, 2))
|
||||
{
|
||||
CHECK(points[0].x == Approx(18940136.2759583741));
|
||||
CHECK(points[0].y == Approx(-5402988.5324898539));
|
||||
CHECK(points[1].x == Approx(19543991.9707122259));
|
||||
CHECK(points[1].y == Approx(-4762338.2380718365));
|
||||
}
|
||||
CHECKED_IF(lonlat_to_webmerc.backward(&points[0].x, &points[0].y, nullptr, 2, 2))
|
||||
{
|
||||
CHECK(points[0].x == Approx(170.142139));
|
||||
CHECK(points[0].y == Approx(-43.595056));
|
||||
CHECK(points[1].x == Approx(175.566667));
|
||||
CHECK(points[1].y == Approx(-39.283333));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPNIK_USE_PROJ4
|
||||
SECTION("lonlat <-> New Zealand Transverse Mercator 2000")
|
||||
{
|
||||
// cs2cs -Ef %.10f +init=epsg:4326 +to +init=epsg:2193 <<END
|
||||
// 170.142139 -43.595056
|
||||
// 175.566667 -39.283333
|
||||
// END
|
||||
//
|
||||
// 170.142139 -43.595056 1369316.0970041484 5169132.9750701785
|
||||
// 175.566667 -39.283333 1821377.9170061364 5648640.2106032455
|
||||
//
|
||||
mapnik::geometry::point<double> points[] = {{ 170.142139, -43.595056 },
|
||||
{ 175.566667, -39.283333 }};
|
||||
// this transform is not calculated by Mapnik (needs Proj4)
|
||||
mapnik::proj_transform lonlat_to_nztm(proj_4326, proj_2193);
|
||||
CHECKED_IF(lonlat_to_nztm.forward(&points[0].x, &points[0].y, nullptr, 2, 2))
|
||||
{
|
||||
CHECK(points[0].x == Approx(1369316.0970041484));
|
||||
CHECK(points[0].y == Approx(5169132.9750701785));
|
||||
CHECK(points[1].x == Approx(1821377.9170061364));
|
||||
CHECK(points[1].y == Approx(5648640.2106032455));
|
||||
}
|
||||
CHECKED_IF(lonlat_to_nztm.backward(&points[0].x, &points[0].y, nullptr, 2, 2))
|
||||
{
|
||||
CHECK(points[0].x == Approx(170.142139));
|
||||
CHECK(points[0].y == Approx(-43.595056));
|
||||
CHECK(points[1].x == Approx(175.566667));
|
||||
CHECK(points[1].y == Approx(-39.283333));
|
||||
}
|
||||
}
|
||||
#endif // MAPNIK_USE_PROJ4
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include "fake_path.hpp"
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/util/math.hpp>
|
||||
#include <mapnik/vertex_cache.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
|
||||
// stl
|
||||
#include <iostream>
|
||||
|
@ -55,7 +55,7 @@ void test_offset_curve(double const &offset) {
|
|||
std::vector<double> pos, off_pos;
|
||||
const size_t max_i = 1000;
|
||||
for (size_t i = 0; i <= max_i; ++i) {
|
||||
double x = M_PI * double(i) / max_i;
|
||||
double x = mapnik::util::pi * double(i) / max_i;
|
||||
pos.push_back(-std::cos(x)); pos.push_back(std::sin(x));
|
||||
off_pos.push_back(-r * std::cos(x)); off_pos.push_back(r * std::sin(x));
|
||||
}
|
||||
|
@ -88,12 +88,12 @@ void test_s_shaped_curve(double const &offset) {
|
|||
std::vector<double> pos, off_pos;
|
||||
const size_t max_i = 1000;
|
||||
for (size_t i = 0; i <= max_i; ++i) {
|
||||
double x = M_PI * double(i) / max_i;
|
||||
double x = mapnik::util::pi * double(i) / max_i;
|
||||
pos.push_back(-std::cos(x) - 1); pos.push_back(std::sin(x));
|
||||
off_pos.push_back(-r * std::cos(x) - 1); off_pos.push_back(r * std::sin(x));
|
||||
}
|
||||
for (size_t i = 0; i <= max_i; ++i) {
|
||||
double x = M_PI * double(i) / max_i;
|
||||
double x = mapnik::util::pi * double(i) / max_i;
|
||||
pos.push_back(-std::cos(x) + 1); pos.push_back(-std::sin(x));
|
||||
off_pos.push_back(-r2 * std::cos(x) + 1); off_pos.push_back(-r2 * std::sin(x));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/offset_converter.hpp>
|
||||
#include <mapnik/util/math.hpp>
|
||||
|
||||
// stl
|
||||
#include <iostream>
|
||||
|
@ -134,7 +135,7 @@ void test_offset_curve(double const &offset) {
|
|||
std::vector<double> pos, off_pos;
|
||||
const size_t max_i = 1000;
|
||||
for (size_t i = 0; i <= max_i; ++i) {
|
||||
double x = M_PI * double(i) / max_i;
|
||||
double x = mapnik::util::pi * double(i) / max_i;
|
||||
pos.push_back(-std::cos(x)); pos.push_back(std::sin(x));
|
||||
off_pos.push_back(-r * std::cos(x)); off_pos.push_back(r * std::sin(x));
|
||||
}
|
||||
|
@ -185,12 +186,12 @@ void test_s_shaped_curve(double const &offset) {
|
|||
std::vector<double> pos, off_pos;
|
||||
const size_t max_i = 1000;
|
||||
for (size_t i = 0; i <= max_i; ++i) {
|
||||
double x = M_PI * double(i) / max_i;
|
||||
double x = mapnik::util::pi * double(i) / max_i;
|
||||
pos.push_back(-std::cos(x) - 1); pos.push_back(std::sin(x));
|
||||
off_pos.push_back(-r * std::cos(x) - 1); off_pos.push_back(r * std::sin(x));
|
||||
}
|
||||
for (size_t i = 0; i <= max_i; ++i) {
|
||||
double x = M_PI * double(i) / max_i;
|
||||
double x = mapnik::util::pi * double(i) / max_i;
|
||||
pos.push_back(-std::cos(x) + 1); pos.push_back(-std::sin(x));
|
||||
off_pos.push_back(-r2 * std::cos(x) + 1); off_pos.push_back(-r2 * std::sin(x));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue