mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 04:53:36 +00:00
[feature] Added Feature V1 version with free Header2 bits.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
This commit is contained in:
committed by
Konstantin Pastbin
parent
588028c9eb
commit
550455a14a
@@ -11,16 +11,13 @@
|
||||
#include "coding/byte_stream.hpp"
|
||||
#include "coding/geometry_coding.hpp"
|
||||
#include "coding/read_write_utils.hpp"
|
||||
#include "coding/reader.hpp"
|
||||
|
||||
#include "geometry/region2d.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/math.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace feature
|
||||
@@ -630,7 +627,9 @@ void FeatureBuilder::SerializeForMwm(SupportingData & data, serial::GeometryCodi
|
||||
PushBackByteSink<Buffer> sink(data.m_buffer);
|
||||
FeatureParams(m_params).Write(sink);
|
||||
|
||||
if (m_params.GetGeomType() == GeomType::Point)
|
||||
GeomType const type = m_params.GetGeomType();
|
||||
CHECK(type != GeomType::Undefined, ());
|
||||
if (type == GeomType::Point)
|
||||
{
|
||||
serial::SavePoint(sink, m_center, params);
|
||||
return;
|
||||
@@ -640,26 +639,23 @@ void FeatureBuilder::SerializeForMwm(SupportingData & data, serial::GeometryCodi
|
||||
uint8_t trgCount = base::asserted_cast<uint8_t>(data.m_innerTrg.size());
|
||||
if (trgCount > 0)
|
||||
{
|
||||
ASSERT_GREATER(trgCount, 2, ());
|
||||
CHECK_GREATER(trgCount, 2, ());
|
||||
trgCount -= 2;
|
||||
}
|
||||
|
||||
GeomType const type = m_params.GetGeomType();
|
||||
|
||||
{
|
||||
BitWriter<PushBackByteSink<Buffer>> bitSink(sink);
|
||||
|
||||
if (type == GeomType::Line)
|
||||
{
|
||||
bitSink.Write(ptsCount, 4);
|
||||
if (ptsCount == 0)
|
||||
bitSink.Write(data.m_ptsMask, 4);
|
||||
bitSink.Write(ptsCount != 0 ? ptsCount : data.m_ptsMask, 4);
|
||||
bitSink.Write(ptsCount == 0 ? 1 : 0, 1);
|
||||
}
|
||||
else if (type == GeomType::Area)
|
||||
else
|
||||
{
|
||||
bitSink.Write(trgCount, 4);
|
||||
if (trgCount == 0)
|
||||
bitSink.Write(data.m_trgMask, 4);
|
||||
CHECK_EQUAL(type, GeomType::Area, ());
|
||||
bitSink.Write(trgCount != 0 ? trgCount : data.m_trgMask, 4);
|
||||
bitSink.Write(trgCount == 0 ? 1 : 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,6 +667,7 @@ void FeatureBuilder::SerializeForMwm(SupportingData & data, serial::GeometryCodi
|
||||
{
|
||||
uint32_t v = data.m_ptsSimpMask;
|
||||
int const count = (ptsCount - 2 + 3) / 4;
|
||||
CHECK_LESS(count, 4, ());
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
WriteToSink(sink, static_cast<uint8_t>(v));
|
||||
@@ -683,7 +680,7 @@ void FeatureBuilder::SerializeForMwm(SupportingData & data, serial::GeometryCodi
|
||||
else
|
||||
{
|
||||
auto const & poly = GetOuterGeometry();
|
||||
ASSERT_GREATER(poly.size(), 2, ());
|
||||
CHECK_GREATER(poly.size(), 2, ());
|
||||
|
||||
// Store first point once for outer linear features.
|
||||
serial::SavePoint(sink, poly[0], params);
|
||||
@@ -693,8 +690,10 @@ void FeatureBuilder::SerializeForMwm(SupportingData & data, serial::GeometryCodi
|
||||
WriteVarUintArray(data.m_ptsOffset, sink);
|
||||
}
|
||||
}
|
||||
else if (type == GeomType::Area)
|
||||
else
|
||||
{
|
||||
CHECK_EQUAL(type, GeomType::Area, ());
|
||||
|
||||
if (trgCount > 0)
|
||||
serial::SaveInnerTriangles(data.m_innerTrg, params, sink);
|
||||
else
|
||||
|
||||
@@ -10,13 +10,13 @@ public:
|
||||
enum class Version : uint8_t
|
||||
{
|
||||
V0 = 0,
|
||||
Latest = V0
|
||||
V1, // 2025.06, get some free bits in Feature::Header2
|
||||
Latest = V1
|
||||
};
|
||||
|
||||
template <typename Sink>
|
||||
void Serialize(Sink & sink) const
|
||||
{
|
||||
CHECK_EQUAL(m_version, Version::V0, ());
|
||||
WriteToSink(sink, static_cast<uint8_t>(m_version));
|
||||
WriteToSink(sink, m_featuresOffset);
|
||||
WriteToSink(sink, m_featuresSize);
|
||||
@@ -26,7 +26,8 @@ public:
|
||||
void Read(Source & source)
|
||||
{
|
||||
m_version = static_cast<Version>(ReadPrimitiveFromSource<uint8_t>(source));
|
||||
CHECK_EQUAL(static_cast<uint8_t>(m_version), static_cast<uint8_t>(Version::V0), ());
|
||||
CHECK(Version::V0 <= m_version && m_version <= Version::Latest, (m_version));
|
||||
|
||||
m_featuresOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_featuresSize = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
}
|
||||
@@ -39,7 +40,10 @@ public:
|
||||
|
||||
inline std::string DebugPrint(DatSectionHeader::Version v)
|
||||
{
|
||||
CHECK(v == DatSectionHeader::Version::V0, ());
|
||||
return "V0";
|
||||
switch (v)
|
||||
{
|
||||
case DatSectionHeader::Version::V0: return "V0";
|
||||
default: return "Latest(V1)";
|
||||
}
|
||||
}
|
||||
} // namespace feature
|
||||
|
||||
@@ -297,7 +297,6 @@ void FeatureType::ParseCommon()
|
||||
if (m_parsed.m_common)
|
||||
return;
|
||||
|
||||
CHECK(m_loadInfo, ());
|
||||
ParseTypes();
|
||||
|
||||
ArrayByteSource source(m_data.data() + m_offsets.m_common);
|
||||
@@ -342,21 +341,35 @@ void FeatureType::ParseHeader2()
|
||||
if (m_parsed.m_header2)
|
||||
return;
|
||||
|
||||
CHECK(m_loadInfo, ());
|
||||
ParseCommon();
|
||||
|
||||
uint8_t elemsCount = 0, geomScalesMask = 0;
|
||||
BitSource bitSource(m_data.data() + m_offsets.m_header2);
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
m_parsed.m_header2 = true;
|
||||
|
||||
if (headerGeomType == HeaderGeomType::Line || headerGeomType == HeaderGeomType::Area)
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
if (headerGeomType != HeaderGeomType::Line && headerGeomType != HeaderGeomType::Area)
|
||||
return;
|
||||
|
||||
BitSource bitSource(m_data.data() + m_offsets.m_header2);
|
||||
uint8_t elemsCount = bitSource.Read(4);
|
||||
uint8_t geomScalesMask = 0;
|
||||
|
||||
if (m_loadInfo->m_version == DatSectionHeader::Version::V0)
|
||||
{
|
||||
elemsCount = bitSource.Read(4);
|
||||
// For outer geometry read the geom scales (offsets) mask.
|
||||
// For inner geometry remaining 4 bits are not used.
|
||||
if (elemsCount == 0)
|
||||
geomScalesMask = bitSource.Read(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQUAL(m_loadInfo->m_version, DatSectionHeader::Version::V1, ());
|
||||
bool const isOuter = (bitSource.Read(1) == 1);
|
||||
if (isOuter)
|
||||
{
|
||||
geomScalesMask = elemsCount;
|
||||
elemsCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayByteSource src(bitSource.RoundPtr());
|
||||
serial::GeometryCodingParams const & cp = m_loadInfo->GetDefGeometryCodingParams();
|
||||
@@ -370,7 +383,8 @@ void FeatureType::ParseHeader2()
|
||||
// first and last points are never simplified/discarded,
|
||||
// 2 bits are used per each other point, i.e.
|
||||
// 3-6 pts - 1 byte, 7-10 pts - 2b, 11-14 pts - 3b.
|
||||
int const count = ((elemsCount - 2) + 4 - 1) / 4;
|
||||
/// @see FeatureBuilder::SerializeForMwm
|
||||
int const count = (elemsCount - 2 + 3) / 4;
|
||||
ASSERT_LESS(count, 4, ());
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
@@ -393,8 +407,9 @@ void FeatureType::ParseHeader2()
|
||||
ReadOffsets(*m_loadInfo, src, geomScalesMask, m_offsets.m_pts);
|
||||
}
|
||||
}
|
||||
else if (headerGeomType == HeaderGeomType::Area)
|
||||
else
|
||||
{
|
||||
ASSERT(headerGeomType == HeaderGeomType::Area, ());
|
||||
if (elemsCount > 0)
|
||||
{
|
||||
// Inner geometry (strips).
|
||||
@@ -413,7 +428,6 @@ void FeatureType::ParseHeader2()
|
||||
|
||||
// Size of the whole header incl. inner geometry / triangles.
|
||||
m_innerStats.m_size = CalcOffset(src, m_data.data());
|
||||
m_parsed.m_header2 = true;
|
||||
}
|
||||
|
||||
void FeatureType::ResetGeometry()
|
||||
@@ -438,7 +452,6 @@ void FeatureType::ParseGeometry(int scale)
|
||||
{
|
||||
if (!m_parsed.m_points)
|
||||
{
|
||||
CHECK(m_loadInfo, ());
|
||||
ParseHeader2();
|
||||
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
@@ -539,7 +552,6 @@ void FeatureType::ParseTriangles(int scale)
|
||||
{
|
||||
if (!m_parsed.m_triangles)
|
||||
{
|
||||
CHECK(m_loadInfo, ());
|
||||
ParseHeader2();
|
||||
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
|
||||
@@ -21,7 +21,8 @@ void FeaturesVector::InitRecordsReader()
|
||||
feature::DatSectionHeader header;
|
||||
header.Read(src);
|
||||
|
||||
CHECK_EQUAL(header.m_version, feature::DatSectionHeader::Version::V0, ());
|
||||
m_loadInfo.m_version = header.m_version;
|
||||
|
||||
m_recordReader = std::make_unique<RecordReader>(reader.SubReader(header.m_featuresOffset, header.m_featuresSize));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "indexer/dat_section_header.hpp"
|
||||
#include "indexer/data_header.hpp"
|
||||
|
||||
#include "coding/files_container.hpp"
|
||||
@@ -47,6 +48,7 @@ private:
|
||||
|
||||
public:
|
||||
indexer::MetadataDeserializer * m_metaDeserializer;
|
||||
feature::DatSectionHeader::Version m_version;
|
||||
|
||||
DISALLOW_COPY_AND_MOVE(SharedLoadInfo);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user