Add new angled-point marker placement mode for lines
This adds a new mode called 'angled-point' to the marker-placement modes. The full list of modes is then: point, angled-point, interior, line, vertex-first, vertex-last Angled point is identical to point, except that when placing a marker on a line, the marker's angle is taken from the angle of the line segment. There is another possible use of the "angled-point" concept for polygons, and that is for placing labels on stand (aka erf) polygons. By computing a dominant angle for a mostly rectangular polygon, this can produce quite good results. I'm not sure whether I should implement that now, or if I could do that later.
This commit is contained in:
parent
f02a259011
commit
05849f0da5
5 changed files with 31 additions and 5 deletions
12
include/mapnik/geom_util.hpp
Normal file → Executable file
12
include/mapnik/geom_util.hpp
Normal file → Executable file
|
@ -35,6 +35,12 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -298,7 +304,7 @@ bool hit_test_first(PathType & path, double x, double y)
|
||||||
namespace label {
|
namespace label {
|
||||||
|
|
||||||
template <typename PathType>
|
template <typename PathType>
|
||||||
bool middle_point(PathType & path, double & x, double & y)
|
bool middle_point(PathType & path, double & x, double & y, boost::optional<double&> angle = boost::none)
|
||||||
{
|
{
|
||||||
double x0 = 0;
|
double x0 = 0;
|
||||||
double y0 = 0;
|
double y0 = 0;
|
||||||
|
@ -319,6 +325,10 @@ bool middle_point(PathType & path, double & x, double & y)
|
||||||
double r = (mid_length - dist)/seg_length;
|
double r = (mid_length - dist)/seg_length;
|
||||||
x = x0 + (x1 - x0) * r;
|
x = x0 + (x1 - x0) * r;
|
||||||
y = y0 + (y1 - y0) * r;
|
y = y0 + (y1 - y0) * r;
|
||||||
|
if (angle)
|
||||||
|
{
|
||||||
|
*angle = atan2(y1 - y0, x1 - x0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dist += seg_length;
|
dist += seg_length;
|
||||||
|
|
|
@ -49,6 +49,10 @@ public:
|
||||||
case MARKER_POINT_PLACEMENT:
|
case MARKER_POINT_PLACEMENT:
|
||||||
construct(&point_, locator, detector, params);
|
construct(&point_, locator, detector, params);
|
||||||
break;
|
break;
|
||||||
|
case MARKER_ANGLED_POINT_PLACEMENT:
|
||||||
|
construct(&point_, locator, detector, params);
|
||||||
|
point_.use_angle(true);
|
||||||
|
break;
|
||||||
case MARKER_INTERIOR_PLACEMENT:
|
case MARKER_INTERIOR_PLACEMENT:
|
||||||
construct(&interior_, locator, detector, params);
|
construct(&interior_, locator, detector, params);
|
||||||
break;
|
break;
|
||||||
|
@ -70,6 +74,7 @@ public:
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case MARKER_POINT_PLACEMENT:
|
case MARKER_POINT_PLACEMENT:
|
||||||
|
case MARKER_ANGLED_POINT_PLACEMENT:
|
||||||
destroy(&point_);
|
destroy(&point_);
|
||||||
break;
|
break;
|
||||||
case MARKER_INTERIOR_PLACEMENT:
|
case MARKER_INTERIOR_PLACEMENT:
|
||||||
|
@ -94,6 +99,7 @@ public:
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case MARKER_POINT_PLACEMENT:
|
case MARKER_POINT_PLACEMENT:
|
||||||
|
case MARKER_ANGLED_POINT_PLACEMENT:
|
||||||
return point_.get_point(x, y, angle, ignore_placement);
|
return point_.get_point(x, y, angle, ignore_placement);
|
||||||
case MARKER_INTERIOR_PLACEMENT:
|
case MARKER_INTERIOR_PLACEMENT:
|
||||||
return interior_.get_point(x, y, angle, ignore_placement);
|
return interior_.get_point(x, y, angle, ignore_placement);
|
||||||
|
|
16
include/mapnik/markers_placements/point.hpp
Normal file → Executable file
16
include/mapnik/markers_placements/point.hpp
Normal file → Executable file
|
@ -38,11 +38,18 @@ public:
|
||||||
: markers_basic_placement(params),
|
: markers_basic_placement(params),
|
||||||
locator_(locator),
|
locator_(locator),
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
done_(false)
|
done_(false),
|
||||||
|
use_angle_(false)
|
||||||
{
|
{
|
||||||
locator_.rewind(0);
|
locator_.rewind(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use angle of line
|
||||||
|
void use_angle(bool enable)
|
||||||
|
{
|
||||||
|
use_angle_ = enable;
|
||||||
|
}
|
||||||
|
|
||||||
// Start again at first marker. Returns the same list of markers only works when they were NOT added to the detector.
|
// Start again at first marker. Returns the same list of markers only works when they were NOT added to the detector.
|
||||||
void rewind()
|
void rewind()
|
||||||
{
|
{
|
||||||
|
@ -58,9 +65,11 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
angle = 0;
|
||||||
|
|
||||||
if (this->locator_.type() == geometry::geometry_types::LineString)
|
if (this->locator_.type() == geometry::geometry_types::LineString)
|
||||||
{
|
{
|
||||||
if (!label::middle_point(this->locator_, x, y))
|
if (!label::middle_point(this->locator_, x, y, use_angle_ ? boost::optional<double&>(angle) : boost::none))
|
||||||
{
|
{
|
||||||
this->done_ = true;
|
this->done_ = true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -75,8 +84,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
angle = 0;
|
|
||||||
|
|
||||||
if (!this->push_to_detector(x, y, angle, ignore_placement))
|
if (!this->push_to_detector(x, y, angle, ignore_placement))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -90,6 +97,7 @@ protected:
|
||||||
Locator & locator_;
|
Locator & locator_;
|
||||||
Detector & detector_;
|
Detector & detector_;
|
||||||
bool done_;
|
bool done_;
|
||||||
|
bool use_angle_;
|
||||||
|
|
||||||
// Checks transformed box placement with collision detector.
|
// Checks transformed box placement with collision detector.
|
||||||
// returns false if the box:
|
// returns false if the box:
|
||||||
|
|
|
@ -105,6 +105,7 @@ enum marker_placement_enum : std::uint8_t
|
||||||
MARKER_LINE_PLACEMENT,
|
MARKER_LINE_PLACEMENT,
|
||||||
MARKER_VERTEX_FIRST_PLACEMENT,
|
MARKER_VERTEX_FIRST_PLACEMENT,
|
||||||
MARKER_VERTEX_LAST_PLACEMENT,
|
MARKER_VERTEX_LAST_PLACEMENT,
|
||||||
|
MARKER_ANGLED_POINT_PLACEMENT,
|
||||||
marker_placement_enum_MAX
|
marker_placement_enum_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ static const char * marker_placement_strings[] = {
|
||||||
"line",
|
"line",
|
||||||
"vertex-first",
|
"vertex-first",
|
||||||
"vertex-last",
|
"vertex-last",
|
||||||
|
"angled-point",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue