use integer approximation for polyline generalization
This commit is contained in:
parent
21eb5b661d
commit
f3ad14cb7f
@ -38,25 +38,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
DouglasPeucker::DouglasPeucker()
|
DouglasPeucker::DouglasPeucker()
|
||||||
: douglas_peucker_thresholds({262144.f, // z0
|
: douglas_peucker_thresholds({2621440, // z0
|
||||||
131072.f, // z1
|
1310720, // z1
|
||||||
65536.f, // z2
|
655360, // z2
|
||||||
32768.f, // z3
|
327680, // z3
|
||||||
16384.f, // z4
|
163840, // z4
|
||||||
8192.f, // z5
|
81920, // z5
|
||||||
4096.f, // z6
|
40960, // z6
|
||||||
2048.f, // z7
|
20480, // z7
|
||||||
960.f, // z8
|
9600, // z8
|
||||||
480.f, // z9
|
4800, // z9
|
||||||
240.f, // z10
|
2800, // z10
|
||||||
90.f, // z11
|
900, // z11
|
||||||
50.f, // z12
|
600, // z12
|
||||||
25.f, // z13
|
275, // z13
|
||||||
15.f, // z14
|
160, // z14
|
||||||
5.f, // z15
|
60, // z15
|
||||||
.65f, // z16
|
8, // z16
|
||||||
.5f, // z17
|
6, // z17
|
||||||
.35f // z18
|
4 // z18
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -79,16 +79,10 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
|
|||||||
// Sweep over array and identify those ranges that need to be checked
|
// Sweep over array and identify those ranges that need to be checked
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!input_geometry[left_border].necessary)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "broken interval [" << left_border << "," << right_border << "]";
|
|
||||||
}
|
|
||||||
BOOST_ASSERT_MSG(input_geometry[left_border].necessary,
|
|
||||||
"left border must be necessary");
|
|
||||||
BOOST_ASSERT_MSG(input_geometry.back().necessary, "right border must be necessary");
|
|
||||||
|
|
||||||
if (input_geometry[right_border].necessary)
|
if (input_geometry[right_border].necessary)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(input_geometry[left_border].necessary);
|
||||||
|
BOOST_ASSERT(input_geometry[right_border].necessary);
|
||||||
recursion_stack.emplace(left_border, right_border);
|
recursion_stack.emplace(left_border, right_border);
|
||||||
left_border = right_border;
|
left_border = right_border;
|
||||||
}
|
}
|
||||||
@ -104,24 +98,24 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
|
|||||||
BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
|
BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
|
||||||
BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
|
BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
|
||||||
BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
|
BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
|
||||||
float max_distance = std::numeric_limits<float>::min();
|
int max_int_distance = 0;
|
||||||
|
|
||||||
unsigned farthest_element_index = pair.second;
|
unsigned farthest_element_index = pair.second;
|
||||||
// find index idx of element with max_distance
|
// find index idx of element with max_distance
|
||||||
for (unsigned i = pair.first + 1; i < pair.second; ++i)
|
for (unsigned i = pair.first + 1; i < pair.second; ++i)
|
||||||
{
|
{
|
||||||
const float temp_dist = FixedPointCoordinate::ComputePerpendicularDistance(
|
const int int_dist = FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
|
||||||
input_geometry[i].location,
|
input_geometry[i].location,
|
||||||
input_geometry[pair.first].location,
|
input_geometry[pair.first].location,
|
||||||
input_geometry[pair.second].location);
|
input_geometry[pair.second].location);
|
||||||
const float distance = std::abs(temp_dist);
|
|
||||||
if (distance > douglas_peucker_thresholds[zoom_level] && distance > max_distance)
|
if (int_dist > max_int_distance && int_dist > douglas_peucker_thresholds[zoom_level])
|
||||||
{
|
{
|
||||||
farthest_element_index = i;
|
farthest_element_index = i;
|
||||||
max_distance = distance;
|
max_int_distance = int_dist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (max_distance > douglas_peucker_thresholds[zoom_level])
|
if (max_int_distance > douglas_peucker_thresholds[zoom_level])
|
||||||
{
|
{
|
||||||
// mark idx as necessary
|
// mark idx as necessary
|
||||||
input_geometry[farthest_element_index].necessary = true;
|
input_geometry[farthest_element_index].necessary = true;
|
||||||
|
@ -44,7 +44,7 @@ struct SegmentInformation;
|
|||||||
class DouglasPeucker
|
class DouglasPeucker
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<float> douglas_peucker_thresholds;
|
std::vector<int> douglas_peucker_thresholds;
|
||||||
|
|
||||||
typedef std::pair<unsigned, unsigned> GeometryRange;
|
typedef std::pair<unsigned, unsigned> GeometryRange;
|
||||||
// Stack to simulate the recursion
|
// Stack to simulate the recursion
|
||||||
|
Loading…
Reference in New Issue
Block a user