Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View 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

View 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

View 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