Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
106
tools/topography_generator/utils/contours.hpp
Normal file
106
tools/topography_generator/utils/contours.hpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#pragma once
|
||||
|
||||
#include "generator/feature_helpers.hpp"
|
||||
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/region2d.hpp"
|
||||
|
||||
#include "indexer/scales.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace topography_generator
|
||||
{
|
||||
using Contour = std::vector<m2::PointD>;
|
||||
|
||||
template <typename ValueType>
|
||||
struct Contours
|
||||
{
|
||||
enum class Version : uint8_t
|
||||
{
|
||||
V0 = 0,
|
||||
Latest = V0
|
||||
};
|
||||
|
||||
std::unordered_map<ValueType, std::vector<Contour>> m_contours;
|
||||
ValueType m_minValue = 0;
|
||||
ValueType m_maxValue = 0;
|
||||
ValueType m_valueStep = 0;
|
||||
size_t m_invalidValuesCount = 0; // for debug purpose only.
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
void CropContours(m2::RectD & rect, std::vector<m2::RegionD> & regions, size_t maxLength, size_t valueStepFactor,
|
||||
Contours<ValueType> & contours)
|
||||
{
|
||||
static_assert(std::is_integral<ValueType>::value, "Only integral types are supported.");
|
||||
|
||||
contours.m_minValue = std::numeric_limits<ValueType>::max();
|
||||
contours.m_maxValue = std::numeric_limits<ValueType>::min();
|
||||
|
||||
auto it = contours.m_contours.begin();
|
||||
while (it != contours.m_contours.end())
|
||||
{
|
||||
std::vector<Contour> levelCroppedContours;
|
||||
|
||||
if (it->first % static_cast<ValueType>(contours.m_valueStep * valueStepFactor) == 0)
|
||||
{
|
||||
for (auto const & contour : it->second)
|
||||
{
|
||||
Contour cropped;
|
||||
cropped.reserve(contour.size());
|
||||
for (auto const & pt : contour)
|
||||
{
|
||||
cropped.push_back(pt);
|
||||
auto const isInside = rect.IsPointInside(pt) && RegionsContain(regions, pt);
|
||||
if (!isInside || cropped.size() == maxLength)
|
||||
{
|
||||
if (cropped.size() > 1)
|
||||
levelCroppedContours.emplace_back(std::move(cropped));
|
||||
cropped.clear();
|
||||
if (isInside)
|
||||
cropped.push_back(pt);
|
||||
}
|
||||
}
|
||||
if (cropped.size() > 1)
|
||||
levelCroppedContours.emplace_back(std::move(cropped));
|
||||
}
|
||||
}
|
||||
it->second = std::move(levelCroppedContours);
|
||||
|
||||
if (!it->second.empty())
|
||||
{
|
||||
contours.m_minValue = std::min(it->first, contours.m_minValue);
|
||||
contours.m_maxValue = std::max(it->first, contours.m_maxValue);
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = contours.m_contours.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
void SimplifyContours(int simplificationZoom, Contours<ValueType> & contours)
|
||||
{
|
||||
for (auto & levelContours : contours.m_contours)
|
||||
{
|
||||
for (auto & contour : levelContours.second)
|
||||
{
|
||||
std::vector<m2::PointD> contourSimple;
|
||||
feature::SimplifyPoints(m2::SquaredDistanceFromSegmentToPoint(), simplificationZoom, contour, contourSimple);
|
||||
CHECK_GREATER(contourSimple.size(), 1, ());
|
||||
// Discard closed lines which are degenerate (<=3 points) or too small for the requested zoom level.
|
||||
/// @todo it doesn't fix all cases as the simplification algo
|
||||
/// can produce e.g. a 5 points closed but degenerate line ("flat", not a loop anymore).
|
||||
if (contourSimple.front() == contourSimple.back() &&
|
||||
!scales::IsGoodOutlineForLevel(simplificationZoom, contourSimple))
|
||||
contour.clear();
|
||||
else
|
||||
contour = std::move(contourSimple);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace topography_generator
|
||||
Loading…
Add table
Add a link
Reference in a new issue