Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New interior for v3.0.x #3840

Merged
merged 6 commits into from
Jan 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 0 additions & 74 deletions include/mapnik/geom_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,80 +518,6 @@ bool hit_test(PathType & path, double x, double y, double tol)
return inside;
}

template <typename PathType>
bool interior_position(PathType & path, double & x, double & y)
{
// start with the centroid
if (!label::centroid(path, x,y))
return false;

// otherwise we find a horizontal line across the polygon and then return the
// center of the widest intersection between the polygon and the line.

std::vector<double> intersections; // only need to store the X as we know the y
geometry::point<double> p0, p1, move_to;
unsigned command = SEG_END;

path.rewind(0);

while (SEG_END != (command = path.vertex(&p0.x, &p0.y)))
{
switch (command)
{
case SEG_MOVETO:
move_to = p0;
break;
case SEG_CLOSE:
p0 = move_to;
case SEG_LINETO:
// if the segments overlap
if (p0.y == p1.y)
{
if (p0.y == y)
{
double xi = (p0.x + p1.x) / 2.0;
intersections.push_back(xi);
}
}
// if the path segment crosses the bisector
else if ((p0.y <= y && p1.y >= y) ||
(p0.y >= y && p1.y <= y))
{
// then calculate the intersection
double xi = p0.x;
if (p0.x != p1.x)
{
double m = (p1.y - p0.y) / (p1.x - p0.x);
double c = p0.y - m * p0.x;
xi = (y - c) / m;
}

intersections.push_back(xi);
}
break;
}
p1 = p0;
}

// no intersections we just return the default
if (intersections.empty())
return true;
std::sort(intersections.begin(), intersections.end());
double max_width = 0;
for (unsigned ii = 1; ii < intersections.size(); ii += 2)
{
double xlow = intersections[ii-1];
double xhigh = intersections[ii];
double width = xhigh - xlow;
if (width > max_width)
{
x = (xlow + xhigh) / 2.0;
max_width = width;
}
}
return true;
}

}}

#endif // MAPNIK_GEOM_UTIL_HPP
38 changes: 38 additions & 0 deletions include/mapnik/geometry/interior.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2017 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_GEOMETRY_INTERIOR_HPP
#define MAPNIK_GEOMETRY_INTERIOR_HPP

#include <mapnik/geometry.hpp>
#include <mapnik/config.hpp> // for MAPNIK_DECL

namespace mapnik { namespace geometry {

template <class T>
MAPNIK_DECL bool interior(polygon<T> const& polygon,
double scale_factor,
point<T> & pt);

} }

#endif // MAPNIK_GEOMETRY_INTERIOR_HPP
74 changes: 74 additions & 0 deletions include/mapnik/geometry/polygon_vertex_processor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2017 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_GEOMETRY_POLYGON_VERTEX_PROCESSOR_HPP
#define MAPNIK_GEOMETRY_POLYGON_VERTEX_PROCESSOR_HPP

// geometry
#include <mapnik/geometry.hpp>

namespace mapnik { namespace geometry {

template <typename T>
struct polygon_vertex_processor
{
template <typename Path>
void add_path(Path & path)
{
point<T> p;
unsigned cmd;
linear_ring<T> ring;
bool exterior = true;
while ((cmd = path.vertex(&p.x, &p.y)) != SEG_END)
{
switch (cmd)
{
case SEG_MOVETO:
case SEG_LINETO:
ring.emplace_back(p);
break;
case SEG_CLOSE:
if (!ring.empty())
{
ring.emplace_back(ring.front());
}
if (exterior)
{
polygon_.exterior_ring = std::move(ring);
exterior = false;
}
else
{
polygon_.interior_rings.emplace_back(std::move(ring));
}
ring = linear_ring<T>();
break;
}
}
}

polygon<T> polygon_;
};

} }

#endif // MAPNIK_GEOMETRY_POLYGON_VERTEX_PROCESSOR_HPP
1 change: 1 addition & 0 deletions include/mapnik/markers_placements/basic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct markers_placement_params
bool allow_overlap;
bool avoid_edges;
direction_enum direction;
double scale_factor;
};

class markers_basic_placement : util::noncopyable
Expand Down
12 changes: 11 additions & 1 deletion include/mapnik/markers_placements/interior.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <mapnik/markers_placements/point.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/geometry_types.hpp>
#include <mapnik/geometry/interior.hpp>
#include <mapnik/geometry/polygon_vertex_processor.hpp>

namespace mapnik {

Expand Down Expand Up @@ -58,11 +60,19 @@ class markers_interior_placement : public markers_point_placement<Locator, Detec
}
else
{
if (!label::interior_position(this->locator_, x, y))
geometry::polygon_vertex_processor<double> vertex_processor;
vertex_processor.add_path(this->locator_);
geometry::point<double> placement;
if (!geometry::interior(vertex_processor.polygon_,
this->params_.scale_factor,
placement))
{
this->done_ = true;
return false;
}

x = placement.x;
y = placement.y;
}

angle = 0;
Expand Down
5 changes: 2 additions & 3 deletions include/mapnik/renderer_common/process_point_symbolizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <mapnik/geometry_centroid.hpp>
#include <mapnik/geometry_type.hpp>
#include <mapnik/geometry_types.hpp>
#include <mapnik/geometry/interior.hpp>
#include <mapnik/vertex_adapters.hpp>
#include <mapnik/geom_util.hpp>

Expand Down Expand Up @@ -79,9 +80,7 @@ void render_point_symbolizer(point_symbolizer const &sym,
else if (type == mapnik::geometry::geometry_types::Polygon)
{
auto const& poly = mapnik::util::get<geometry::polygon<double> >(geometry);
geometry::polygon_vertex_adapter<double> va(poly);
if (!label::interior_position(va ,pt.x, pt.y))
return;
if (!geometry::interior(poly, common.scale_factor_, pt)) return;
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def ldconfig(*args,**kwargs):
datasource_cache_static.cpp
debug.cpp
geometry_reprojection.cpp
geometry/interior.cpp
expression_node.cpp
expression_string.cpp
expression.cpp
Expand Down