diff --git a/coding/byte_stream.hpp b/coding/byte_stream.hpp index e006ced5ef..0bc7d613ac 100644 --- a/coding/byte_stream.hpp +++ b/coding/byte_stream.hpp @@ -1,8 +1,9 @@ #pragma once #include "../base/base.hpp" + #include "../std/vector.hpp" #include "../std/memcpy.hpp" -#include "../base/start_mem_debug.hpp" + class ArrayByteSource { @@ -56,5 +57,3 @@ private: TStorage & m_Storage; size_t m_InitialStorageSize; }; - -#include "../base/stop_mem_debug.hpp" diff --git a/coding/var_record_reader.hpp b/coding/var_record_reader.hpp index d6e0129d68..f710e51582 100644 --- a/coding/var_record_reader.hpp +++ b/coding/var_record_reader.hpp @@ -60,7 +60,8 @@ public: { uint32_t offset; uint64_t nextPos = ReadRecord(pos, buffer, offset); - f(pos, &buffer[offset], buffer.size() - offset); + // uint64_t -> uint32_t : assume that feature dat file not more than 4Gb + f(static_cast(pos), &buffer[offset], static_cast(buffer.size() - offset)); pos = nextPos; } ASSERT_EQUAL(pos, m_ReaderSize, ()); diff --git a/indexer/covering.cpp b/indexer/covering.cpp index 22d7364943..d5c8ab1246 100644 --- a/indexer/covering.cpp +++ b/indexer/covering.cpp @@ -68,13 +68,15 @@ namespace }; } -vector covering::CoverFeature(Feature const & feature) +vector covering::CoverFeature(FeatureGeom const & feature) { vector geometry; feature.ForEachPoint(MakeBackInsertFunctor(geometry)); + ASSERT(!geometry.empty(), ()); if (geometry.empty()) return vector(); + vector ids; if (geometry.size() > 1) // TODO: Tweak CoverPolyLine() depth level. diff --git a/indexer/covering.hpp b/indexer/covering.hpp index 854b92f623..5decac86b6 100644 --- a/indexer/covering.hpp +++ b/indexer/covering.hpp @@ -1,16 +1,18 @@ #pragma once #include "../geometry/rect2d.hpp" + #include "../base/base.hpp" + #include "../std/utility.hpp" #include "../std/vector.hpp" -class Feature; +class FeatureGeom; namespace covering { // Cover feature with RectIds and return their integer representations. - vector CoverFeature(Feature const & feature); + vector CoverFeature(FeatureGeom const & feature); // Cover viewport with RectIds and append their RectIds as well. vector > CoverViewportAndAppendLowerLevels(m2::RectD const & rect); // Given a vector of intervals [a, b), sort them and merge overlapping intervals. diff --git a/indexer/feature.cpp b/indexer/feature.cpp index 85e515d97a..e489bbeb38 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -1,12 +1,17 @@ #include "feature.hpp" +#include "cell_id.hpp" + #include "../geometry/rect2d.hpp" + #include "../coding/byte_stream.hpp" #include "../coding/reader.hpp" #include "../coding/varint.hpp" #include "../coding/write_to_sink.hpp" + #include "../base/logging.hpp" -#include "../std/bind.hpp" -#include "../std/map.hpp" + +#include "../base/start_mem_debug.hpp" + namespace pts { @@ -21,6 +26,10 @@ namespace pts } } +/////////////////////////////////////////////////////////////////////////////////////////////////// +// FeatureBuilder implementation +/////////////////////////////////////////////////////////////////////////////////////////////////// + FeatureBuilder::FeatureBuilder() : m_Layer(0) { } @@ -80,16 +89,16 @@ void FeatureBuilder::Serialize(vector & data) const // Serializing header. uint8_t header = static_cast(m_Types.size()); if (m_Layer != 0) - header |= Feature::HEADER_HAS_LAYER; + header |= FeatureBase::HEADER_HAS_LAYER; if (m_Geometry.size() > 1) { if (m_Triangles.empty()) - header |= Feature::HEADER_IS_LINE; + header |= FeatureBase::HEADER_IS_LINE; else - header |= Feature::HEADER_IS_AREA; + header |= FeatureBase::HEADER_IS_AREA; } if (!m_Name.empty()) - header |= Feature::HEADER_HAS_NAME; + header |= FeatureBase::HEADER_HAS_NAME; WriteToSink(sink, header); // Serializing types. @@ -102,6 +111,13 @@ void FeatureBuilder::Serialize(vector & data) const if (m_Layer != 0) WriteVarInt(sink, m_Layer); + // Serializing name. + if (!m_Name.empty()) + { + WriteVarUint(sink, m_Name.size() - 1); + sink.Write(&m_Name[0], m_Name.size()); + } + // Serializing geometry. if (m_Geometry.size() == 1) { @@ -123,67 +139,64 @@ void FeatureBuilder::Serialize(vector & data) const WriteVarInt(sink, i == 0 ? m_Triangles[i] : (m_Triangles[i] - m_Triangles[i-1])); } - // Serializing name. - if (!m_Name.empty()) - { - WriteVarUint(sink, m_Name.size() - 1); - sink.Write(&m_Name[0], m_Name.size()); - } + ASSERT ( CheckCorrect(data), () ); +} - -#ifdef DEBUG +bool FeatureBuilder::CheckCorrect(vector const & data) const +{ vector data1 = data; - Feature feature; + FeatureGeom feature; feature.DeserializeAndParse(data1); - FeatureBuilder const fb = feature.GetFeatureBuilder(); - ASSERT_EQUAL(m_Types, fb.m_Types, (feature.DebugString())); - ASSERT_EQUAL(m_Layer, fb.m_Layer, (feature.DebugString())); - ASSERT_EQUAL(m_Geometry, fb.m_Geometry, (feature.DebugString())); - ASSERT_EQUAL(m_Triangles, fb.m_Triangles, (feature.DebugString())); - ASSERT_EQUAL(m_Name, fb.m_Name, (feature.DebugString())); - ASSERT(*this == fb, (feature.DebugString())); -#endif + FeatureBuilder fb; + feature.InitFeatureBuilder(fb); + + string const s = feature.DebugString(); + + ASSERT_EQUAL(m_Types, fb.m_Types, (s)); + ASSERT_EQUAL(m_Layer, fb.m_Layer, (s)); + ASSERT_EQUAL(m_Geometry, fb.m_Geometry, (s)); + ASSERT_EQUAL(m_Triangles, fb.m_Triangles, (s)); + ASSERT_EQUAL(m_Name, fb.m_Name, (s)); + ASSERT(*this == fb, (s)); + + return true; } -Feature FeatureBuilder::GetFeature() const -{ - vector data; - Serialize(data); - Feature feature; - feature.Deserialize(data); - return feature; -} +/////////////////////////////////////////////////////////////////////////////////////////////////// +// FeatureBase implementation +/////////////////////////////////////////////////////////////////////////////////////////////////// -Feature::Feature(vector & data, uint32_t offset) -{ - Deserialize(data, offset); -} - -void Feature::Deserialize(vector & data, uint32_t offset) +void FeatureBase::Deserialize(vector & data, uint32_t offset) { m_Offset = offset; m_Data.swap(data); m_LayerOffset = m_GeometryOffset = m_TrianglesOffset = m_NameOffset = 0; m_bTypesParsed = m_bLayerParsed = m_bGeometryParsed = m_bTrianglesParsed = m_bNameParsed = false; - m_Layer = m_TriangleCount = 0; - m_Geometry.clear(); - m_Triangles.clear(); + + m_Layer = 0; m_Name.clear(); m_LimitRect = m2::RectD(); } -void Feature::ParseTypes() const +uint32_t FeatureBase::CalcOffset(ArrayByteSource const & source) const +{ + return static_cast(static_cast(source.Ptr()) - DataPtr()); +} + +void FeatureBase::ParseTypes() const { ASSERT(!m_bTypesParsed, ()); + ArrayByteSource source(DataPtr() + 1); for (size_t i = 0; i < GetTypesCount(); ++i) m_Types[i] = ReadVarUint(source); - m_LayerOffset = static_cast(static_cast(source.Ptr()) - DataPtr()); + m_bTypesParsed = true; + m_LayerOffset = CalcOffset(source); } -void Feature::ParseLayer() const +void FeatureBase::ParseLayer() const { ASSERT(!m_bLayerParsed, ()); if (!m_bTypesParsed) @@ -193,76 +206,31 @@ void Feature::ParseLayer() const if (Header() & HEADER_HAS_LAYER) m_Layer = ReadVarInt(source); - m_GeometryOffset = static_cast(static_cast(source.Ptr()) - DataPtr()); m_bLayerParsed = true; + m_NameOffset = CalcOffset(source); } -void Feature::ParseGeometry() const -{ - ASSERT(!m_bGeometryParsed, ()); - if (!m_bLayerParsed) - ParseLayer(); - ArrayByteSource source(DataPtr() + m_GeometryOffset); - uint32_t const geometrySize = - (GetFeatureType() == FEATURE_TYPE_POINT ? 1 : ReadVarUint(source) + 1); - m_Geometry.resize(geometrySize); - int64_t id = 0; - for (size_t i = 0; i < geometrySize; ++i) - m_LimitRect.Add(m_Geometry[i] = pts::ToPoint(id += ReadVarInt(source))); - m_TrianglesOffset = static_cast(static_cast(source.Ptr()) - DataPtr()); - m_bGeometryParsed = true; -} - -void Feature::ParseTriangles() const -{ - ASSERT(!m_bTrianglesParsed, ()); - if (!m_bGeometryParsed) - ParseGeometry(); - ArrayByteSource source(DataPtr() + m_TrianglesOffset); - if (GetFeatureType() == FEATURE_TYPE_AREA) - { - m_TriangleCount = ReadVarUint(source) + 1; - uint32_t const trianglePoints = m_TriangleCount * 3; - m_Triangles.resize(trianglePoints); - int64_t id = 0; - for (size_t i = 0; i < trianglePoints; ++i) - m_Triangles[i] = pts::ToPoint(id += ReadVarInt(source)); - } - m_NameOffset = static_cast(static_cast(source.Ptr()) - DataPtr()); - m_bTrianglesParsed = true; -} - -void Feature::ParseName() const +void FeatureBase::ParseName() const { ASSERT(!m_bNameParsed, ()); - if (!m_bTrianglesParsed) - ParseTriangles(); + if (!m_bLayerParsed) + ParseLayer(); + ArrayByteSource source(DataPtr() + m_NameOffset); if (Header() & HEADER_HAS_NAME) { m_Name.resize(ReadVarUint(source) + 1); source.Read(&m_Name[0], m_Name.size()); } + m_bNameParsed = true; - ASSERT_EQUAL(static_cast(static_cast(source.Ptr()) - DataPtr()), - m_Data.size() - m_Offset, ()); + m_GeometryOffset = CalcOffset(source); } -void Feature::ParseAll() const +string FeatureBase::DebugString() const { - if (!m_bNameParsed) - ParseName(); -} + ASSERT(m_bNameParsed, ()); -void Feature::DeserializeAndParse(vector & data, uint32_t offset) -{ - Deserialize(data, offset); - ParseAll(); -} - -string Feature::DebugString() const -{ - ParseAll(); string res("Feature("); res += "'" + m_Name + "' "; @@ -270,23 +238,105 @@ string Feature::DebugString() const res += "Type:" + debug_print(m_Types[i]) + " "; res += "Layer:" + debug_print(m_Layer) + " "; + return res; +} + +void FeatureBase::InitFeatureBuilder(FeatureBuilder & fb) const +{ + ASSERT(m_bNameParsed, ()); + + fb.AddTypes(m_Types, m_Types + GetTypesCount()); + fb.AddLayer(m_Layer); + fb.AddName(m_Name); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// FeatureGeom implementation +/////////////////////////////////////////////////////////////////////////////////////////////////// + +FeatureGeom::FeatureGeom(vector & data, uint32_t offset) +{ + Deserialize(data, offset); +} + +void FeatureGeom::Deserialize(vector & data, uint32_t offset) +{ + base_type::Deserialize(data, offset); + + m_Geometry.clear(); + m_Triangles.clear(); +} + +void FeatureGeom::ParseGeometry() const +{ + ASSERT(!m_bGeometryParsed, ()); + if (!m_bNameParsed) + ParseName(); + + ArrayByteSource source(DataPtr() + m_GeometryOffset); + uint32_t const geometrySize = + (GetFeatureType() == FEATURE_TYPE_POINT ? 1 : ReadVarUint(source) + 1); + + m_Geometry.resize(geometrySize); + int64_t id = 0; + for (size_t i = 0; i < geometrySize; ++i) + m_LimitRect.Add(m_Geometry[i] = pts::ToPoint(id += ReadVarInt(source))); + + m_bGeometryParsed = true; + m_TrianglesOffset = CalcOffset(source); +} + +void FeatureGeom::ParseTriangles() const +{ + ASSERT(!m_bTrianglesParsed, ()); + if (!m_bGeometryParsed) + ParseGeometry(); + + ArrayByteSource source(DataPtr() + m_TrianglesOffset); + if (GetFeatureType() == FEATURE_TYPE_AREA) + { + uint32_t const trgPoints = (ReadVarUint(source) + 1) * 3; + m_Triangles.resize(trgPoints); + int64_t id = 0; + for (size_t i = 0; i < trgPoints; ++i) + m_Triangles[i] = pts::ToPoint(id += ReadVarInt(source)); + } + + m_bTrianglesParsed = true; + ASSERT_EQUAL ( CalcOffset(source), m_Data.size() - m_Offset, () ); +} + +void FeatureGeom::ParseAll() const +{ + if (!m_bTrianglesParsed) + ParseTriangles(); +} + +void FeatureGeom::DeserializeAndParse(vector & data, uint32_t offset) +{ + Deserialize(data, offset); + ParseAll(); +} + +string FeatureGeom::DebugString() const +{ + ParseAll(); + string res = base_type::DebugString(); res += debug_print(m_Geometry) + " "; res += debug_print(m_Triangles) + ")"; return res; } -FeatureBuilder Feature::GetFeatureBuilder() const +void FeatureGeom::InitFeatureBuilder(FeatureBuilder & fb) const { ParseAll(); - FeatureBuilder fb; - fb.AddTypes(m_Types, m_Types + GetTypesCount()); - fb.AddLayer(m_Layer); + base_type::InitFeatureBuilder(fb); + for (size_t i = 0; i < m_Geometry.size(); ++i) fb.AddPoint(m_Geometry[i]); + ASSERT_EQUAL(m_Triangles.size() % 3, 0, ()); uint32_t const triangleCount = m_Triangles.size() / 3; for (size_t i = 0; i < triangleCount; ++i) fb.AddTriangle(m_Triangles[3*i + 0], m_Triangles[3*i + 1], m_Triangles[3*i + 2]); - fb.AddName(m_Name); - return fb; } diff --git a/indexer/feature.hpp b/indexer/feature.hpp index 7447fd5a02..83cd069d45 100644 --- a/indexer/feature.hpp +++ b/indexer/feature.hpp @@ -1,7 +1,5 @@ #pragma once -#include "cell_id.hpp" - #include "../geometry/point2d.hpp" #include "../geometry/rect2d.hpp" @@ -9,10 +7,9 @@ #include "../std/string.hpp" #include "../std/vector.hpp" -#include "../std/iterator.hpp" -#include "../std/algorithm.hpp" -class Feature; +class ArrayByteSource; + class FeatureBuilder { @@ -39,15 +36,14 @@ public: void Serialize(vector & data) const; - // Returns corresponding feature. Does Serialize() and feature.Deserialize() internally. - Feature GetFeature() const; - bool IsGeometryClosed() const; size_t GetPointsCount() const { return m_Geometry.size(); } bool operator == (FeatureBuilder const &) const; private: + bool CheckCorrect(vector const & data) const; + int32_t m_Layer; string m_Name; vector m_Types; @@ -55,7 +51,7 @@ private: vector m_Triangles; }; -class Feature +class FeatureBase { public: enum FeatureType @@ -66,15 +62,14 @@ public: FEATURE_TYPE_UNKNOWN = 17 }; - Feature() {} - Feature(vector & data, uint32_t offset = 0); + FeatureBase() {} + /// @name Use like polymorfic functions. Need to overwrite in derived classes. + //@{ void Deserialize(vector & data, uint32_t offset = 0); - void DeserializeAndParse(vector & data, uint32_t offset = 0); - string DebugString() const; - - FeatureBuilder GetFeatureBuilder() const; + void InitFeatureBuilder(FeatureBuilder & fb) const; + //@} inline FeatureType GetFeatureType() const { @@ -96,27 +91,6 @@ public: return m_Layer; } - inline m2::RectD GetLimitRect() const - { - if (!m_bGeometryParsed) - ParseGeometry(); - return m_LimitRect; - } - - inline uint32_t GetGeometrySize() const - { - if (!m_bGeometryParsed) - ParseGeometry(); - return m_Geometry.size(); - } - - inline uint32_t GetTriangleCount() const - { - if (!m_bTrianglesParsed) - ParseTriangles(); - return m_TriangleCount; - } - inline string GetName() const { if (!(Header() & HEADER_HAS_NAME)) @@ -126,6 +100,12 @@ public: return m_Name; } + inline m2::RectD GetLimitRect() const + { + ASSERT(m_bGeometryParsed, ()); + return m_LimitRect; + } + class GetTypesFn { public: @@ -148,6 +128,83 @@ public: f(m_Types[i]); } + enum + { + HEADER_HAS_LAYER = 1U << 7, + HEADER_HAS_NAME = 1U << 6, + HEADER_IS_AREA = 1U << 5, + HEADER_IS_LINE = 1U << 4 + }; + +protected: + vector m_Data; + uint32_t m_Offset; + + inline char const * DataPtr() const { return &m_Data[m_Offset]; } + inline uint8_t Header() const { return static_cast(*DataPtr()); } + uint32_t CalcOffset(ArrayByteSource const & source) const; + + mutable uint32_t m_Types[16]; + mutable int32_t m_Layer; + mutable string m_Name; + + mutable m2::RectD m_LimitRect; + + mutable uint32_t m_LayerOffset; + mutable uint32_t m_NameOffset; + mutable uint32_t m_GeometryOffset; + mutable uint32_t m_TrianglesOffset; + + mutable bool m_bTypesParsed; + mutable bool m_bLayerParsed; + mutable bool m_bNameParsed; + mutable bool m_bGeometryParsed; + mutable bool m_bTrianglesParsed; + + void ParseTypes() const; + void ParseLayer() const; + void ParseName() const; +}; + +class FeatureGeom : public FeatureBase +{ + typedef FeatureBase base_type; + +public: + FeatureGeom() {} + FeatureGeom(vector & data, uint32_t offset = 0); + + /// @name Overwrite from base_type. + //@{ + void Deserialize(vector & data, uint32_t offset = 0); + string DebugString() const; + void InitFeatureBuilder(FeatureBuilder & fb) const; + //@} + + inline m2::RectD GetLimitRect() const + { + if (!m_bGeometryParsed) + ParseGeometry(); + return base_type::GetLimitRect(); + } + + void ParseAll() const; + void DeserializeAndParse(vector & data, uint32_t offset = 0); + + inline uint32_t GetGeometrySize() const + { + if (!m_bGeometryParsed) + ParseGeometry(); + return m_Geometry.size(); + } + + inline uint32_t GetTriangleCount() const + { + if (!m_bTrianglesParsed) + ParseTriangles(); + return (m_Triangles.size() / 3); + } + template void ForEachPointRef(FunctorT & f) const { @@ -183,49 +240,21 @@ public: f.EndPrimitive(); } - enum - { - HEADER_HAS_LAYER = 1U << 7, - HEADER_HAS_NAME = 1U << 6, - HEADER_IS_AREA = 1U << 5, - HEADER_IS_LINE = 1U << 4 - }; - private: - vector m_Data; - uint32_t m_Offset; - inline char const * DataPtr() const { return &m_Data[m_Offset]; } - inline uint8_t Header() const { return static_cast(*DataPtr()); } - - mutable uint32_t m_Types[16]; - mutable int32_t m_Layer; mutable vector m_Geometry; - mutable m2::RectD m_LimitRect; mutable vector m_Triangles; - mutable uint32_t m_TriangleCount; - mutable string m_Name; - mutable uint32_t m_LayerOffset; - mutable uint32_t m_GeometryOffset; - mutable uint32_t m_TrianglesOffset; - mutable uint32_t m_NameOffset; - - mutable bool m_bTypesParsed; - mutable bool m_bLayerParsed; - mutable bool m_bGeometryParsed; - mutable bool m_bTrianglesParsed; - mutable bool m_bNameParsed; - - void ParseTypes() const; - void ParseLayer() const; void ParseGeometry() const; void ParseTriangles() const; - void ParseName() const; - void ParseAll() const; }; -inline string debug_print(Feature const & f) +class FeatureGeomRef : public FeatureBase +{ + +}; + +inline string debug_print(FeatureGeom const & f) { return f.DebugString(); } diff --git a/indexer/feature_processor.hpp b/indexer/feature_processor.hpp index 92167fcccf..559bfdc931 100644 --- a/indexer/feature_processor.hpp +++ b/indexer/feature_processor.hpp @@ -9,8 +9,8 @@ namespace feature { - template - void ReadFromSource(TSource & src, Feature & ft) + template + void ReadFromSource(TSource & src, TFeature & ft) { uint32_t const sz = ReadVarUint(src); vector buffer(sz); @@ -40,7 +40,7 @@ namespace feature // read features one by one while (currPos < fSize) { - Feature ft; + FeatureGeom ft; ReadFromSource(src, ft); toDo(ft, currPos); currPos = src.Pos(); diff --git a/indexer/feature_visibility.cpp b/indexer/feature_visibility.cpp index b2f65c8443..051ccd56ed 100644 --- a/indexer/feature_visibility.cpp +++ b/indexer/feature_visibility.cpp @@ -112,16 +112,16 @@ namespace }; } -int GetDrawRule(Feature const & f, int level, vector & keys, string & names) +int GetDrawRule(FeatureBase const & f, int level, vector & keys, string & names) { - Feature::FeatureType const geoType = f.GetFeatureType(); - if (geoType == Feature::FEATURE_TYPE_UNKNOWN) + FeatureBase::FeatureType const geoType = f.GetFeatureType(); + if (geoType == FeatureBase::FEATURE_TYPE_UNKNOWN) { ASSERT ( false, ("Logic Error! Unknown feature type.") ); - return Feature::FEATURE_TYPE_UNKNOWN; + return FeatureBase::FEATURE_TYPE_UNKNOWN; } - Feature::GetTypesFn types; + FeatureBase::GetTypesFn types; f.ForEachTypeRef(types); ASSERT ( keys.empty(), () ); @@ -196,13 +196,13 @@ bool IsDrawableLike(vector const & types, feature_geo_t ft) return false; } -bool IsDrawableForIndex(Feature const & f, int level) +bool IsDrawableForIndex(FeatureBase const & f, int level) { - if (f.GetFeatureType() == Feature::FEATURE_TYPE_AREA) + if (f.GetFeatureType() == FeatureBase::FEATURE_TYPE_AREA) if (!scales::IsGoodForLevel(level, f.GetLimitRect())) return false; - Feature::GetTypesFn types; + FeatureBase::GetTypesFn types; f.ForEachTypeRef(types); Classificator const & c = classif(); @@ -215,15 +215,15 @@ bool IsDrawableForIndex(Feature const & f, int level) return false; } -uint32_t MinDrawableScaleForFeature(Feature const & f) +int MinDrawableScaleForFeature(FeatureBase const & f) { - uint32_t const upBound = scales::GetUpperScale(); + int const upBound = scales::GetUpperScale(); - for (uint32_t level = 0; level <= upBound; ++level) + for (int level = 0; level <= upBound; ++level) if (feature::IsDrawableForIndex(f, level)) return level; - return uint32_t(-1); + return -1; } } diff --git a/indexer/feature_visibility.hpp b/indexer/feature_visibility.hpp index 00c32ec3e2..eb75d73006 100644 --- a/indexer/feature_visibility.hpp +++ b/indexer/feature_visibility.hpp @@ -7,7 +7,7 @@ #include "../std/vector.hpp" #include "../std/string.hpp" -class Feature; +class FeatureBase; namespace feature { @@ -15,9 +15,9 @@ namespace feature bool IsDrawableAny(uint32_t type); bool IsDrawableLike(vector const & type, feature_geo_t ft); - bool IsDrawableForIndex(Feature const & f, int level); - uint32_t MinDrawableScaleForFeature(Feature const & f); + bool IsDrawableForIndex(FeatureBase const & f, int level); + int MinDrawableScaleForFeature(FeatureBase const & f); - int GetDrawRule(Feature const & f, int level, vector & keys, string & names); + int GetDrawRule(FeatureBase const & f, int level, vector & keys, string & names); } diff --git a/indexer/features_vector.hpp b/indexer/features_vector.hpp index 8000ea66fa..5aa1d748ad 100644 --- a/indexer/features_vector.hpp +++ b/indexer/features_vector.hpp @@ -1,12 +1,18 @@ #pragma once #include "../indexer/feature.hpp" + #include "../coding/var_record_reader.hpp" + #include "../base/base.hpp" + #include "../std/bind.hpp" + template class FeaturesVector { + typedef FeatureGeom feature_t; + public: typedef ReaderT ReaderType; @@ -14,7 +20,7 @@ public: { } - void Get(uint64_t pos, Feature & feature) const + void Get(uint64_t pos, feature_t & feature) const { vector record; uint32_t offset; @@ -24,14 +30,14 @@ public: template void ForEachOffset(TDo const & toDo) const { - Feature f; + feature_t f; m_RecordReader.ForEachRecord( bind(toDo, bind(&FeaturesVector::DeserializeFeature, this, _2, _3, &f), _1)); } template void ForEach(TDo const & toDo) const { - Feature f; + feature_t f; m_RecordReader.ForEachRecord( bind(toDo, bind(&FeaturesVector::DeserializeFeature, this, _2, _3, &f))); } @@ -42,7 +48,7 @@ public: } private: - Feature const & DeserializeFeature(char const * data, uint32_t size, Feature * pFeature) const + feature_t const & DeserializeFeature(char const * data, uint32_t size, feature_t * pFeature) const { vector data1(data, data + size); pFeature->Deserialize(data1); diff --git a/indexer/index.hpp b/indexer/index.hpp index 969576874b..f3a11484f0 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -150,17 +150,21 @@ private: FeatureVectorT m_FeatureVector; template - struct OffsetToFeatureReplacer + class OffsetToFeatureReplacer { + typedef FeatureGeom feature_t; + + FeatureVectorT const & m_V; + F const & m_F; + + public: OffsetToFeatureReplacer(FeatureVectorT const & v, F const & f) : m_V(v), m_F(f) {} void operator() (uint32_t offset) const { - Feature feature; + feature_t feature; m_V.Get(offset, feature); m_F(feature); } - FeatureVectorT const & m_V; - F const & m_F; }; }; diff --git a/indexer/indexer_tests/feature_bucketer_test.cpp b/indexer/indexer_tests/feature_bucketer_test.cpp index 504cc6bd42..44d68b3b31 100644 --- a/indexer/indexer_tests/feature_bucketer_test.cpp +++ b/indexer/indexer_tests/feature_bucketer_test.cpp @@ -1,10 +1,18 @@ #include "../../testing/testing.hpp" + #include "../indexer_tool/feature_bucketer.hpp" + #include "../feature.hpp" +#include "../mercator.hpp" +#include "../cell_id.hpp" + #include "../../base/stl_add.hpp" + namespace { + typedef FeatureGeom feature_t; + class PushBackFeatureDebugStringOutput { public: @@ -13,7 +21,7 @@ namespace PushBackFeatureDebugStringOutput(string const & name, InitDataType const & initData) : m_pContainer(&((*initData)[name])) {} - void operator() (Feature const & feature) + void operator() (feature_t const & feature) { m_pContainer->push_back(feature.DebugString()); } @@ -29,11 +37,11 @@ namespace RectId > FeatureBucketer; - Feature MakeFeature(FeatureBuilder const & fb) + feature_t MakeFeature(FeatureBuilder const & fb) { vector data; fb.Serialize(data); - return Feature(data, 0); + return feature_t(data, 0); } } diff --git a/indexer/indexer_tests/feature_test.cpp b/indexer/indexer_tests/feature_test.cpp index 33fff0bbc2..47fca3b5c3 100644 --- a/indexer/indexer_tests/feature_test.cpp +++ b/indexer/indexer_tests/feature_test.cpp @@ -1,6 +1,10 @@ #include "../../testing/testing.hpp" + #include "../feature.hpp" +#include "../cell_id.hpp" + #include "../../geometry/point2d.hpp" + #include "../../base/stl_add.hpp" namespace @@ -30,6 +34,8 @@ namespace UNIT_TEST(Feature_Deserialize) { + typedef FeatureGeom feature_t; + vector a; a.push_back(1); a.push_back(2); @@ -65,11 +71,11 @@ UNIT_TEST(Feature_Deserialize) vector serial; builder.Serialize(serial); vector serial1 = serial; - Feature f(serial1); + feature_t f(serial1); - TEST_EQUAL(f.GetFeatureType(), Feature::FEATURE_TYPE_AREA, ()); + TEST_EQUAL(f.GetFeatureType(), FeatureBase::FEATURE_TYPE_AREA, ()); - Feature::GetTypesFn types; + FeatureBase::GetTypesFn types; f.ForEachTypeRef(types); TEST_EQUAL(types.m_types, vector(arrTypes, arrTypes + typesCount), ()); @@ -92,7 +98,10 @@ UNIT_TEST(Feature_Deserialize) TEST_LESS(fabs(f.GetLimitRect().maxY() - 1.00), 0.0001, ()); vector serial2; - f.GetFeatureBuilder().Serialize(serial2); + FeatureBuilder builder2; + f.InitFeatureBuilder(builder2); + builder2.Serialize(serial2); + TEST_EQUAL(serial, serial2, - (f.DebugString(), Feature(serial2).DebugString())); + (f.DebugString(), feature_t(serial2).DebugString())); } diff --git a/indexer/indexer_tool/feature_bucketer.hpp b/indexer/indexer_tool/feature_bucketer.hpp index 39756392d3..afa6b4fbf0 100644 --- a/indexer/indexer_tool/feature_bucketer.hpp +++ b/indexer/indexer_tool/feature_bucketer.hpp @@ -9,7 +9,6 @@ #include "../../indexer/feature.hpp" #include "../../indexer/feature_visibility.hpp" -#include "../../std/map.hpp" #include "../../std/string.hpp" #include @@ -23,6 +22,8 @@ namespace feature template class CellFeatureBucketer { + typedef FeatureGeom feature_t; + public: CellFeatureBucketer(int level, typename FeatureOutT::InitDataType const & featureOutInitData, int maxWorldZoom = -1) @@ -44,25 +45,22 @@ public: } } - void operator () (Feature const & feature) + void operator () (feature_t const & f) { // separately store features needed for world map - if (m_worldBucket - && m_maxWorldZoom >= feature::MinDrawableScaleForFeature(feature)) - { - (*m_worldBucket)(feature); - } + if (m_worldBucket && m_maxWorldZoom >= feature::MinDrawableScaleForFeature(f)) + (*m_worldBucket)(f); - FeatureClipperT clipper(feature); + FeatureClipperT clipper(f); // TODO: Is feature fully inside GetLimitRect()? - m2::RectD const limitRect = feature.GetLimitRect(); + m2::RectD const limitRect = f.GetLimitRect(); for (uint32_t i = 0; i < m_Buckets.size(); ++i) { // First quick and dirty limit rect intersection. // Clipper may (or may not) do a better intersection. if (m_Buckets[i].m_Rect.IsIntersect(limitRect)) { - Feature clippedFeature; + feature_t clippedFeature; if (clipper(m_Buckets[i].m_Rect, clippedFeature)) { if (!m_Buckets[i].m_pOut) @@ -74,7 +72,14 @@ public: } } - void operator () (FeatureBuilder const & fb) { (*this)(fb.GetFeature()); } + void operator () (FeatureBuilder const & fb) + { + vector data; + fb.Serialize(data); + feature_t f; + f.Deserialize(data); + this->operator()(f); + } template void GetBucketNames(F f) const { @@ -108,19 +113,21 @@ private: class SimpleFeatureClipper { + typedef FeatureGeom feature_t; + public: - explicit SimpleFeatureClipper(Feature const & feature) : m_Feature(feature) + explicit SimpleFeatureClipper(feature_t const & f) : m_Feature(f) { } - bool operator () (m2::RectD const & /*rect*/, Feature & clippedFeature) const + bool operator () (m2::RectD const & /*rect*/, feature_t & clippedFeature) const { clippedFeature = m_Feature; return true; } private: - Feature const & m_Feature; + feature_t const & m_Feature; }; } diff --git a/indexer/indexer_tool/feature_generator.cpp b/indexer/indexer_tool/feature_generator.cpp index 537cd6fc1c..91789a0369 100644 --- a/indexer/indexer_tool/feature_generator.cpp +++ b/indexer/indexer_tool/feature_generator.cpp @@ -2,16 +2,23 @@ #include "feature_bucketer.hpp" #include "data_cache_file.hpp" #include "osm_element.hpp" + #include "../../indexer/data_header.hpp" #include "../../indexer/osm_decl.hpp" #include "../../indexer/data_header_reader.hpp" +#include "../../indexer/mercator.hpp" +#include "../../indexer/cell_id.hpp" + #include "../../coding/varint.hpp" + #include "../../base/assert.hpp" #include "../../base/logging.hpp" #include "../../base/stl_add.hpp" + #include "../../std/bind.hpp" #include "../../std/unordered_map.hpp" + namespace feature { @@ -146,7 +153,7 @@ void FeaturesCollector::operator() (FeatureBuilder const & f) // .dat file should be less than 4Gb uint64_t const pos = m_datFile.Pos(); ASSERT_EQUAL ( static_cast(static_cast(pos)), pos, - ("Feature offset is out of 32bit boundary :(") ); + ("Feature offset is out of 32bit boundary!") ); #endif vector bytes; @@ -159,11 +166,18 @@ void FeaturesCollector::operator() (FeatureBuilder const & f) WriteVarUint(m_datFile, sz); m_datFile.Write(&bytes[0], sz); - Feature feature(bytes); - m_bounds.Add(feature.GetLimitRect()); + feature_t f(bytes); + m_bounds.Add(f.GetLimitRect()); } } +void FeaturesCollector::operator() (feature_t const & f) +{ + FeatureBuilder fb; + f.InitFeatureBuilder(fb); + this->operator()(fb); +} + FeaturesCollector::~FeaturesCollector() { // rewrite map information with actual data diff --git a/indexer/indexer_tool/feature_generator.hpp b/indexer/indexer_tool/feature_generator.hpp index 8224e51aad..3f786f5422 100644 --- a/indexer/indexer_tool/feature_generator.hpp +++ b/indexer/indexer_tool/feature_generator.hpp @@ -1,10 +1,17 @@ + #pragma once -#include "../../indexer/feature.hpp" #include "../../indexer/osm_decl.hpp" + #include "../../geometry/rect2d.hpp" + #include "../../coding/file_writer.hpp" + +#include "../../std/vector.hpp" #include "../../std/string.hpp" +class FeatureBuilder; +class FeatureGeom; + namespace feature { struct GenerateInfo @@ -30,6 +37,8 @@ namespace feature void Init(); + typedef FeatureGeom feature_t; + public: ~FeaturesCollector(); @@ -40,6 +49,6 @@ namespace feature FeaturesCollector(string const & bucketName, InitDataType const & datFilePrefixSuffix); void operator() (FeatureBuilder const & f); - void operator() (Feature const & f) { (*this)(f.GetFeatureBuilder()); } + void operator() (feature_t const & f); }; } diff --git a/indexer/indexer_tool/feature_sorter.cpp b/indexer/indexer_tool/feature_sorter.cpp index d2b849bcef..dd7e1d734d 100644 --- a/indexer/indexer_tool/feature_sorter.cpp +++ b/indexer/indexer_tool/feature_sorter.cpp @@ -1,11 +1,10 @@ #include "feature_sorter.hpp" #include "feature_generator.hpp" -#include "../../indexer/data_header.hpp" -#include "../../indexer/data_header_reader.hpp" #include "../../indexer/feature_processor.hpp" #include "../../indexer/feature_visibility.hpp" #include "../../indexer/scales.hpp" +#include "../../indexer/cell_id.hpp" #include "../../platform/platform.hpp" @@ -28,7 +27,7 @@ namespace public: std::vector m_vec; - void operator() (Feature const & ft, uint64_t pos) + void operator() (FeatureGeom const & ft, uint64_t pos) { // reset state m_midX = 0.0; @@ -39,10 +38,10 @@ namespace m_midY /= m_counter; uint64_t const pointAsInt64 = PointToInt64(m_midX, m_midY); - uint64_t const featureScale = feature::MinDrawableScaleForFeature(ft); - CHECK(featureScale <= scales::GetUpperScale(), ("Dat file contain invisible feature")); + uint64_t const minScale = feature::MinDrawableScaleForFeature(ft); + CHECK(minScale <= scales::GetUpperScale(), ("Dat file contain invisible feature")); - uint64_t const order = (featureScale << 59) | (pointAsInt64 >> 5); + uint64_t const order = (minScale << 59) | (pointAsInt64 >> 5); m_vec.push_back(make_pair(order, pos)); } @@ -60,7 +59,7 @@ namespace } template - void ReadFeature(TReader const & reader, Feature & ft, uint64_t offset) + void ReadFeature(TReader const & reader, FeatureGeom & ft, uint64_t offset) { ReaderSource src(reader); src.Skip(offset); @@ -95,11 +94,12 @@ namespace feature { FeaturesCollector collector(datFilePath); FileReader notSortedFileReader(tempDatFilePath); - Feature ft; + + FeatureGeom ft; for (size_t i = 0; i < midPoints.m_vec.size(); ++i) { ReadFeature(notSortedFileReader, ft, midPoints.m_vec[i].second); - collector(ft.GetFeatureBuilder()); + collector(ft); } } diff --git a/indexer/indexer_tool/tesselator.cpp b/indexer/indexer_tool/tesselator.cpp index ea69e89b50..83e08c2b02 100644 --- a/indexer/indexer_tool/tesselator.cpp +++ b/indexer/indexer_tool/tesselator.cpp @@ -1,6 +1,9 @@ -#include "../../3party/sgitess/interface.h" #include "osm_element.hpp" +#include "../cell_id.hpp" + +#include "../../3party/sgitess/interface.h" + namespace feature { struct AddTessPointF @@ -14,59 +17,59 @@ namespace feature } }; - void TesselateInterior(FeatureBuilder & featureBuilder, feature::holes_cont_t const & holes) + void TesselateInterior(FeatureBuilder & fb, feature::holes_cont_t const & holes) { - vector serial; - featureBuilder.Serialize(serial); - Feature feature(serial); + ASSERT(fb.IsGeometryClosed(), ()); - ASSERT(featureBuilder.IsGeometryClosed(), ()); + tess::VectorDispatcher disp; + tess::Tesselator tess; + tess.setDispatcher(&disp); + tess.setWindingRule(tess::WindingOdd); + + tess.beginPolygon(); + + tess.beginContour(); { - tess::VectorDispatcher disp; - tess::Tesselator tess; - tess.setDispatcher(&disp); - tess.setWindingRule(tess::WindingOdd); - - tess.beginPolygon(); + vector data; + fb.Serialize(data); + FeatureGeom f(data); + f.ForEachPoint(AddTessPointF(tess)); + } + tess.endContour(); + for (feature::holes_cont_t::const_iterator it = holes.begin(); it != holes.end(); ++it) + { tess.beginContour(); - feature.ForEachPoint(AddTessPointF(tess)); + for (size_t i = 0; i < (*it).size(); ++i) + tess.add(tess::Vertex((*it)[i].x, (*it)[i].y)); tess.endContour(); + } - for (feature::holes_cont_t::const_iterator it = holes.begin(); it != holes.end(); ++it) + tess.endPolygon(); + + for (size_t i = 0; i < disp.indices().size(); ++i) + { + vector vertices; + switch (disp.indices()[i].first) { - tess.beginContour(); - for (size_t i = 0; i < (*it).size(); ++i) - tess.add(tess::Vertex((*it)[i].x, (*it)[i].y)); - tess.endContour(); + case tess::TrianglesFan: + case tess::TrianglesStrip: + case tess::LineLoop: + ASSERT(0, ("We've got invalid type during teselation:", disp.indices()[i].first)); + case tess::TrianglesList: break; } - tess.endPolygon(); - - for (size_t i = 0; i < disp.indices().size(); ++i) + for (size_t j = 0; j < disp.indices()[i].second.size(); ++j) { - vector vertices; - switch (disp.indices()[i].first) - { - case tess::TrianglesFan: - case tess::TrianglesStrip: - case tess::LineLoop: - ASSERT(0, ("We've got invalid type during teselation:", disp.indices()[i].first)); - case tess::TrianglesList: break; - } - - for (size_t j = 0; j < disp.indices()[i].second.size(); ++j) - { - int const idx = disp.indices()[i].second[j]; - tess::Vertex const & v = disp.vertices()[idx]; - vertices.push_back(m2::PointD(v.x, v.y)); - } - - ASSERT_EQUAL(vertices.size() % 3, 0, ()); - size_t const triangleCount = vertices.size() / 3; - for (size_t i = 0; i < triangleCount; ++i) - featureBuilder.AddTriangle(vertices[3*i + 0], vertices[3*i + 1], vertices[3*i + 2]); + int const idx = disp.indices()[i].second[j]; + tess::Vertex const & v = disp.vertices()[idx]; + vertices.push_back(m2::PointD(v.x, v.y)); } + + ASSERT_EQUAL(vertices.size() % 3, 0, ()); + size_t const triangleCount = vertices.size() / 3; + for (size_t i = 0; i < triangleCount; ++i) + fb.AddTriangle(vertices[3*i + 0], vertices[3*i + 1], vertices[3*i + 2]); } } } diff --git a/indexer/scale_index_builder.hpp b/indexer/scale_index_builder.hpp index 834b8acbc9..042c3afcac 100644 --- a/indexer/scale_index_builder.hpp +++ b/indexer/scale_index_builder.hpp @@ -2,8 +2,8 @@ #include "scale_index.hpp" #include "feature_visibility.hpp" #include "covering.hpp" -#include "feature.hpp" #include "interval_index_builder.hpp" +#include "cell_id.hpp" #include "../geometry/covering_stream_optimizer.hpp" @@ -52,7 +52,8 @@ public: { } - void operator() (Feature const & f, uint32_t offset) const + template + void operator() (TFeature const & f, uint32_t offset) const { if (FeatureShouldBeIndexed(f)) { @@ -64,10 +65,13 @@ public: } } - bool FeatureShouldBeIndexed(Feature const & f) const + template + bool FeatureShouldBeIndexed(TFeature const & f) const { - uint32_t const minDrawableScale = feature::MinDrawableScaleForFeature(f); - return m_ScaleRange.first <= minDrawableScale && minDrawableScale < m_ScaleRange.second; + (void)f.GetLimitRect(); // dummy call to force TFeature::ParseGeometry + + uint32_t const minScale = feature::MinDrawableScaleForFeature(f); + return (m_ScaleRange.first <= minScale && minScale < m_ScaleRange.second); } private: @@ -84,7 +88,8 @@ public: void operator() (int64_t cellId, uint64_t value) const { - CellFeaturePair cellFeaturePair(cellId, value); + // uint64_t -> uint32_t : assume that feature dat file not more than 4Gb + CellFeaturePair cellFeaturePair(cellId, static_cast(value)); m_Sink.Write(&cellFeaturePair, sizeof(cellFeaturePair)); } diff --git a/map/framework.cpp b/map/framework.cpp index fb9345c7b1..6d940aa071 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -98,7 +98,7 @@ namespace fwork } \ } - bool DrawProcessor::operator()(Feature const & f) + bool DrawProcessor::operator()(feature_t const & f) { if (m_paintEvent->isCancelled()) throw redraw_operation_cancelled(); @@ -123,11 +123,11 @@ namespace fwork bool isExist = false; switch (type) { - case Feature::FEATURE_TYPE_POINT: + case FeatureBase::FEATURE_TYPE_POINT: GET_POINTS(get_pts::one_point, ForEachPointRef, assign_point) break; - case Feature::FEATURE_TYPE_AREA: + case FeatureBase::FEATURE_TYPE_AREA: GET_POINTS(filter_screenpts_adapter, ForEachTriangleExRef, assign_area) { // if area feature has any line-drawing-rules, than draw it like line @@ -138,11 +138,11 @@ namespace fwork } draw_line: - case Feature::FEATURE_TYPE_LINE: + case FeatureBase::FEATURE_TYPE_LINE: GET_POINTS(filter_screenpts_adapter, ForEachPointRef, assign_path) break; - case Feature::FEATURE_TYPE_UNKNOWN: + case FeatureBase::FEATURE_TYPE_UNKNOWN: ASSERT(0, ("Feature type is unknown")); } diff --git a/map/framework.hpp b/map/framework.hpp index a93c48145b..6babfd65b8 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -5,7 +5,6 @@ #include "render_queue.hpp" #include "../indexer/drawing_rule_def.hpp" -#include "../indexer/feature.hpp" #include "../indexer/mercator.hpp" #include "../indexer/data_header_reader.hpp" #include "../indexer/data_header.hpp" @@ -35,7 +34,9 @@ #include "../base/start_mem_debug.hpp" -class Feature; + +class FeatureGeom; + namespace di { class DrawInfo; } namespace drule { class BaseRule; } @@ -43,6 +44,8 @@ class redraw_operation_cancelled {}; namespace fwork { + typedef FeatureGeom feature_t; + class DrawProcessor { m2::RectD m_rect; @@ -68,7 +71,7 @@ namespace fwork shared_ptr paintEvent, int scaleLevel); - bool operator() (Feature const & f); + bool operator() (feature_t const & f); }; } @@ -424,11 +427,11 @@ public: UpdateNow(); } - void ShowFeature(Feature const & f) - { - m_navigator.SetFromRect(f.GetLimitRect()); - Repaint(); - } + //void ShowFeature(Feature const & f) + //{ + // m_navigator.SetFromRect(f.GetLimitRect()); + // Repaint(); + //} void Repaint() { diff --git a/map/map_tests/map_foreach_test.cpp b/map/map_tests/map_foreach_test.cpp index 7a41df7f88..b199b9662c 100644 --- a/map/map_tests/map_foreach_test.cpp +++ b/map/map_tests/map_foreach_test.cpp @@ -22,7 +22,8 @@ #include "../../base/start_mem_debug.hpp" -typedef vector > feature_cont_t; +typedef FeatureGeom feature_t; +typedef vector > feature_cont_t; class AccumulatorBase { @@ -31,12 +32,12 @@ class AccumulatorBase feature_cont_t & m_cont; protected: - bool is_drawable(Feature const & f) const + bool is_drawable(feature_t const & f) const { return feature::IsDrawableForIndex(f, m_scale); } - void add(Feature const & f) const + void add(feature_t const & f) const { string const s = f.DebugString(); m_cont.push_back(make_pair(f, s)); @@ -49,7 +50,7 @@ public: m_scale = scales::GetScaleLevel(r); } - void operator() (Feature const & f) const + void operator() (feature_t const & f) const { ASSERT ( f.DebugString() == f.DebugString(), () ); @@ -97,7 +98,7 @@ class AccumulatorEtalon : public AccumulatorBase m2::RectD m_rect; - bool is_intersect(Feature const & f) const + bool is_intersect(feature_t const & f) const { IntersectCheck check(m_rect); f.ForEachPointRef(check); @@ -110,7 +111,7 @@ public: { } - void operator() (Feature const & f, uint64_t /*offset*/) const + void operator() (feature_t const & f, uint64_t /*offset*/) const { ASSERT ( f.DebugString() == f.DebugString(), () ); @@ -215,11 +216,11 @@ namespace { class FindOffset { - pair const & m_test; + pair const & m_test; public: - FindOffset(pair const & test) : m_test(test) {} + FindOffset(pair const & test) : m_test(test) {} - void operator() (Feature const & f, uint64_t offset) + void operator() (feature_t const & f, uint64_t offset) { if (f.DebugString() == m_test.second) { diff --git a/qt/searchwindow.cpp b/qt/searchwindow.cpp index c179a6d972..fb545d4068 100644 --- a/qt/searchwindow.cpp +++ b/qt/searchwindow.cpp @@ -25,7 +25,7 @@ FindTableWnd::FindTableWnd(QWidget * pParent, FindEditorWnd * pEditor, model_t * connect(m_pEditor, SIGNAL(textChanged(QString const &)), this, SLOT(OnTextChanged(QString const &))); } -bool FindTableWnd::AddFeature(Feature const & f) +bool FindTableWnd::AddFeature(feature_t const & f) { string name = f.GetName(); @@ -61,7 +61,7 @@ void FindTableWnd::OnTextChanged(QString const & s) } } -Feature const & FindTableWnd::GetFeature(size_t row) const +FindTableWnd::feature_t const & FindTableWnd::GetFeature(size_t row) const { ASSERT ( row < m_features.size(), (row, m_features.size()) ); return m_features[row]; diff --git a/qt/searchwindow.hpp b/qt/searchwindow.hpp index 72e2985043..d0f52f24e6 100644 --- a/qt/searchwindow.hpp +++ b/qt/searchwindow.hpp @@ -1,6 +1,7 @@ #pragma once #include "../indexer/feature.hpp" + #include "../std/vector.hpp" #include @@ -30,18 +31,20 @@ namespace qt FindEditorWnd * m_pEditor; model_t * m_pModel; + typedef FeatureGeom feature_t; + public: FindTableWnd(QWidget * pParent, FindEditorWnd * pEditor, model_t * pModel); - Feature const & GetFeature(size_t row) const; + feature_t const & GetFeature(size_t row) const; protected: - bool AddFeature(Feature const & f); + bool AddFeature(feature_t const & f); protected Q_SLOTS: void OnTextChanged(QString const & s); private: - vector m_features; + vector m_features; }; }