forked from mapnik/mapnik
-
Notifications
You must be signed in to change notification settings - Fork 1
/
basic.hpp
113 lines (99 loc) · 3.55 KB
/
basic.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2016 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_MARKERS_PLACEMENTS_BASIC_HPP
#define MAPNIK_MARKERS_PLACEMENTS_BASIC_HPP
// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
#include <mapnik/util/math.hpp>
#include <mapnik/util/noncopyable.hpp>
// agg
#include "agg_basics.h"
#include "agg_trans_affine.h"
namespace mapnik {
struct markers_placement_params
{
box2d<double> size;
agg::trans_affine tr;
double spacing;
double max_error;
bool allow_overlap;
bool avoid_edges;
direction_enum direction;
};
class markers_basic_placement : util::noncopyable
{
public:
markers_basic_placement(markers_placement_params const& params)
: params_(params)
{
}
virtual ~markers_basic_placement()
{
// empty but necessary
}
// Start again at first marker. Returns the same list of markers only works when they were NOT added to the detector.
virtual void rewind() = 0;
// Get next point where the marker should be placed. Returns true if a place is found, false if none is found.
virtual bool get_point(double &x, double &y, double &angle, bool ignore_placement) = 0;
protected:
markers_placement_params const& params_;
// Rotates the size_ box and translates the position.
box2d<double> perform_transform(double angle, double dx, double dy) const
{
auto tr = params_.tr * agg::trans_affine_rotation(angle).translate(dx, dy);
return box2d<double>(params_.size, tr);
}
bool set_direction(double & angle) const
{
switch (params_.direction)
{
case DIRECTION_UP:
angle = 0;
return true;
case DIRECTION_DOWN:
angle = M_PI;
return true;
case DIRECTION_AUTO:
if (std::fabs(util::normalize_angle(angle)) > 0.5 * M_PI)
angle += M_PI;
return true;
case DIRECTION_AUTO_DOWN:
if (std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI)
angle += M_PI;
return true;
case DIRECTION_LEFT:
angle += M_PI;
return true;
case DIRECTION_LEFT_ONLY:
angle += M_PI;
return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
case DIRECTION_RIGHT_ONLY:
return std::fabs(util::normalize_angle(angle)) < 0.5 * M_PI;
case DIRECTION_RIGHT:
default:
return true;
}
}
};
} // namespace mapnik
#endif // MAPNIK_MARKERS_PLACEMENTS_BASIC_HPP