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
|
||||
138
tools/topography_generator/utils/contours_serdes.hpp
Normal file
138
tools/topography_generator/utils/contours_serdes.hpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#pragma once
|
||||
|
||||
#include "topography_generator/utils/contours.hpp"
|
||||
|
||||
#include "coding/file_reader.hpp"
|
||||
#include "coding/file_writer.hpp"
|
||||
#include "coding/geometry_coding.hpp"
|
||||
#include "coding/internal/file_data.hpp"
|
||||
|
||||
namespace topography_generator
|
||||
{
|
||||
template <typename ValueType>
|
||||
class SerializerContours
|
||||
{
|
||||
public:
|
||||
explicit SerializerContours(Contours<ValueType> && contours) : m_contours(std::move(contours)) {}
|
||||
|
||||
template <typename Sink>
|
||||
void Serialize(Sink & sink)
|
||||
{
|
||||
WriteToSink(sink, base::Underlying(Contours<ValueType>::Version::Latest));
|
||||
WriteToSink(sink, m_contours.m_minValue);
|
||||
WriteToSink(sink, m_contours.m_maxValue);
|
||||
WriteToSink(sink, m_contours.m_valueStep);
|
||||
WriteToSink(sink, static_cast<uint32_t>(m_contours.m_invalidValuesCount));
|
||||
|
||||
WriteToSink(sink, static_cast<uint32_t>(m_contours.m_contours.size()));
|
||||
for (auto const & levelContours : m_contours.m_contours)
|
||||
SerializeContours(sink, levelContours.first, levelContours.second);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Sink>
|
||||
void SerializeContours(Sink & sink, ValueType value, std::vector<topography_generator::Contour> const & contours)
|
||||
{
|
||||
WriteToSink(sink, value);
|
||||
WriteToSink(sink, static_cast<uint32_t>(contours.size()));
|
||||
for (auto const & contour : contours)
|
||||
SerializeContour(sink, contour);
|
||||
}
|
||||
|
||||
template <typename Sink>
|
||||
void SerializeContour(Sink & sink, topography_generator::Contour const & contour)
|
||||
{
|
||||
serial::GeometryCodingParams codingParams(kPointCoordBits, contour[0]);
|
||||
codingParams.Save(sink);
|
||||
serial::SaveOuterPath(contour, codingParams, sink);
|
||||
}
|
||||
|
||||
Contours<ValueType> m_contours;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
class DeserializerContours
|
||||
{
|
||||
public:
|
||||
template <typename Reader>
|
||||
void Deserialize(Reader & reader, Contours<ValueType> & contours)
|
||||
{
|
||||
NonOwningReaderSource source(reader);
|
||||
|
||||
using VersT = typename Contours<ValueType>::Version;
|
||||
auto const v = static_cast<VersT>(ReadPrimitiveFromSource<std::underlying_type_t<VersT>>(source));
|
||||
CHECK(v == Contours<ValueType>::Version::Latest, ());
|
||||
|
||||
contours.m_minValue = ReadPrimitiveFromSource<ValueType>(source);
|
||||
contours.m_maxValue = ReadPrimitiveFromSource<ValueType>(source);
|
||||
contours.m_valueStep = ReadPrimitiveFromSource<ValueType>(source);
|
||||
contours.m_invalidValuesCount = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
|
||||
size_t const levelsCount = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
for (size_t i = 0; i < levelsCount; ++i)
|
||||
{
|
||||
ValueType levelValue;
|
||||
std::vector<topography_generator::Contour> levelContours;
|
||||
DeserializeContours(source, levelValue, levelContours);
|
||||
contours.m_contours[levelValue] = std::move(levelContours);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void DeserializeContours(NonOwningReaderSource & source, ValueType & value,
|
||||
std::vector<topography_generator::Contour> & contours)
|
||||
{
|
||||
value = ReadPrimitiveFromSource<ValueType>(source);
|
||||
size_t const contoursCount = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
contours.resize(contoursCount);
|
||||
for (auto & contour : contours)
|
||||
DeserializeContour(source, contour);
|
||||
}
|
||||
|
||||
void DeserializeContour(NonOwningReaderSource & source, topography_generator::Contour & contour)
|
||||
{
|
||||
serial::GeometryCodingParams codingParams;
|
||||
codingParams.Load(source);
|
||||
std::vector<m2::PointD> points;
|
||||
serial::LoadOuterPath(source, codingParams, points);
|
||||
contour = std::move(points);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
bool SaveContrours(std::string const & filePath, Contours<ValueType> && contours)
|
||||
{
|
||||
auto const tmpFilePath = filePath + ".tmp";
|
||||
try
|
||||
{
|
||||
FileWriter file(tmpFilePath);
|
||||
SerializerContours<ValueType> ser(std::move(contours));
|
||||
ser.Serialize(file);
|
||||
}
|
||||
catch (FileWriter::Exception const & ex)
|
||||
{
|
||||
LOG(LWARNING, ("File writer exception raised:", ex.what(), ", file", tmpFilePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECK(base::RenameFileX(tmpFilePath, filePath), (tmpFilePath, filePath));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
bool LoadContours(std::string const & filePath, Contours<ValueType> & contours)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileReader file(filePath);
|
||||
DeserializerContours<ValueType> des;
|
||||
des.Deserialize(file, contours);
|
||||
}
|
||||
catch (FileReader::Exception const & ex)
|
||||
{
|
||||
LOG(LWARNING, ("File reader exception raised:", ex.what(), ", file", filePath));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace topography_generator
|
||||
16
tools/topography_generator/utils/values_provider.hpp
Normal file
16
tools/topography_generator/utils/values_provider.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "geometry/latlon.hpp"
|
||||
|
||||
namespace topography_generator
|
||||
{
|
||||
template <typename ValueType>
|
||||
class ValuesProvider
|
||||
{
|
||||
public:
|
||||
virtual ~ValuesProvider() = default;
|
||||
|
||||
virtual ValueType GetValue(ms::LatLon const & pos) = 0;
|
||||
virtual ValueType GetInvalidValue() const = 0;
|
||||
};
|
||||
} // namespace topography_generator
|
||||
Loading…
Add table
Add a link
Reference in a new issue