From a00db1949e1655703d5a1b7eba48dcaf7e759c4b Mon Sep 17 00:00:00 2001 From: vng Date: Wed, 25 May 2011 02:03:07 +0300 Subject: [PATCH] Make simple conversion of feature types during world generating. --- generator/feature_merger.cpp | 55 ++++++++++++++++++++++++++++--- generator/feature_merger.hpp | 41 +++++++++++++++++++++-- generator/world_map_generator.hpp | 42 +++++++++++------------ indexer/feature_data.cpp | 5 --- indexer/feature_data.hpp | 1 - 5 files changed, 110 insertions(+), 34 deletions(-) diff --git a/generator/feature_merger.cpp b/generator/feature_merger.cpp index 6f1a8896de..a7ea704234 100644 --- a/generator/feature_merger.cpp +++ b/generator/feature_merger.cpp @@ -1,16 +1,20 @@ #include "feature_merger.hpp" #include "../indexer/point_to_int64.hpp" +#include "../indexer/classificator.hpp" -MergedFeatureBuilder1::MergedFeatureBuilder1(FeatureBuilder1 const & fb) - : FeatureBuilder1(fb) +MergedFeatureBuilder1::MergedFeatureBuilder1(FeatureBuilder1 const & fb, bool isOK) + : FeatureBuilder1(fb), m_isOK(isOK) { - m_Params.SortTypes(); + m_Params.FinishAddingTypes(); } void MergedFeatureBuilder1::AppendFeature(MergedFeatureBuilder1 const & fb, bool toBack) { + if (fb.m_isOK) + m_isOK = true; + m2::PointD const pt = toBack ? LastPoint() : FirstPoint(); bool fromEnd = false; @@ -54,8 +58,11 @@ FeatureMergeProcessor::FeatureMergeProcessor(uint32_t coordBits) void FeatureMergeProcessor::operator() (FeatureBuilder1 const & fb) { - MergedFeatureBuilder1 * p = new MergedFeatureBuilder1(fb); + this->operator() (new MergedFeatureBuilder1(fb, true)); +} +void FeatureMergeProcessor::operator() (MergedFeatureBuilder1 * p) +{ key_t const k1 = get_key(p->FirstPoint()); key_t const k2 = get_key(p->LastPoint()); @@ -163,3 +170,43 @@ void FeatureMergeProcessor::DoMerge(FeatureEmitterIFace & emitter) if (m_last.NotEmpty()) emitter(m_last); } + + +uint32_t FeatureTypesProcessor::GetType(char const * arr[2]) +{ + uint32_t const type = classif().GetTypeByPath(vector(arr, arr + 2)); + CHECK_NOT_EQUAL(type, ftype::GetEmptyValue(), ()); + return type; +} + +void FeatureTypesProcessor::CorrectType(uint32_t & t) const +{ + // 1. get normalized type: + // highway-motorway-bridge => highway-motorway + uint32_t normal = ftype::GetEmptyValue(); + uint8_t v; + if (!ftype::GetValue(t, 0, v)) return; + ftype::PushValue(normal, v); + if (!ftype::GetValue(t, 1, v)) return; + ftype::PushValue(normal, v); + + t = normal; + + // 2. get mapping type: + map::const_iterator i = m_mapping.find(t); + if (i != m_mapping.end()) t = i->second; +} + +void FeatureTypesProcessor::SetMappingTypes(char const * arr1[2], char const * arr2[2]) +{ + m_mapping[GetType(arr1)] = GetType(arr2); +} + +MergedFeatureBuilder1 * FeatureTypesProcessor::operator() (FeatureBuilder1 const & fb) +{ + MergedFeatureBuilder1 * p = new MergedFeatureBuilder1(fb, true); + + p->ForEachChangeTypes(do_change_types(*this)); + + return p; +} diff --git a/generator/feature_merger.hpp b/generator/feature_merger.hpp index 89763578ca..1ef1224899 100644 --- a/generator/feature_merger.hpp +++ b/generator/feature_merger.hpp @@ -7,11 +7,14 @@ #include "../std/vector.hpp" +/// Feature builder class that used while feature type processing and merging. class MergedFeatureBuilder1 : public FeatureBuilder1 { + bool m_isOK; + public: - MergedFeatureBuilder1() {} - MergedFeatureBuilder1(FeatureBuilder1 const & fb); + MergedFeatureBuilder1() : m_isOK(false) {} + MergedFeatureBuilder1(FeatureBuilder1 const & fb, bool isOK); void AppendFeature(MergedFeatureBuilder1 const & fb, bool toBack); @@ -25,9 +28,15 @@ public: inline void SetType(uint32_t type) { m_Params.SetType(type); } inline bool PopAnyType(uint32_t & type) { return m_Params.PopAnyType(type); } inline bool PopExactType(uint32_t type) { return m_Params.PopExactType(type); } + + template void ForEachChangeTypes(ToDo toDo) + { + for_each(m_Params.m_Types.begin(), m_Params.m_Types.end(), toDo); + m_Params.FinishAddingTypes(); + } }; - +/// Feature merger. class FeatureMergeProcessor { typedef int64_t key_t; @@ -48,6 +57,32 @@ public: FeatureMergeProcessor(uint32_t coordBits); void operator() (FeatureBuilder1 const & fb); + void operator() (MergedFeatureBuilder1 * p); void DoMerge(FeatureEmitterIFace & emitter); }; + + +/// Feature types corrector. +class FeatureTypesProcessor +{ + map m_mapping; + + static uint32_t GetType(char const * arr[2]); + + void CorrectType(uint32_t & t) const; + + class do_change_types + { + FeatureTypesProcessor const & m_pr; + public: + do_change_types(FeatureTypesProcessor const & pr) : m_pr(pr) {} + void operator() (uint32_t & t) { m_pr.CorrectType(t); } + }; + +public: + /// For example: highway-motorway_link => highway-motorway + void SetMappingTypes(char const * arr1[2], char const * arr2[2]); + + MergedFeatureBuilder1 * operator() (FeatureBuilder1 const & fb); +}; diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp index 35e869a796..07a45a05a0 100644 --- a/generator/world_map_generator.hpp +++ b/generator/world_map_generator.hpp @@ -52,36 +52,36 @@ class WorldMapGenerator /// features visible before or at this scale level will go to World map bool m_mergeCoastlines; - FeatureMergeProcessor m_processor; + FeatureTypesProcessor m_typesCorrector; + FeatureMergeProcessor m_merger; public: WorldMapGenerator(int maxWorldScale, bool mergeCoastlines, typename FeatureOutT::InitDataType const & initData) - : m_mergeCoastlines(mergeCoastlines), m_processor(30) + : m_mergeCoastlines(mergeCoastlines), m_merger(30) { if (maxWorldScale >= 0) m_worldBucket.reset(new WorldEmitter(maxWorldScale, initData)); - // fill vector with types that need to be merged - //static size_t const MAX_TYPES_IN_PATH = 3; - //char const * arrMerge[][MAX_TYPES_IN_PATH] = { - // {"natural", "coastline", ""}, - // {"boundary", "administrative", "2"}, + // fill vector with types that need to be replaced + char const * arrReplace[][3] = { + {"highway", "motorway_link", "motorway"}, + {"highway", "motorway_junction", "motorway"}, + {"highway", "primary_link", "primary"}, + {"highway", "trunk_link", "trunk"}, + {"highway", "secondary_link", "secondary"}, + {"highway", "tertiary_link", "tertiary"} + }; - // {"highway", "motorway", ""}, - // {"highway", "motorway_link", ""}, - // {"highway", "motorway", "oneway"}, - // {"highway", "motorway_link", "oneway"}, + for (size_t i = 0; i < ARRAY_SIZE(arrReplace); ++i) + { + char const * arr1[] = { arrReplace[i][0], arrReplace[i][1] }; + char const * arr2[] = { arrReplace[i][0], arrReplace[i][2] }; - // {"highway", "primary", ""}, - // {"highway", "primary_link", ""}, - - // {"highway", "trunk", ""}, - // {"highway", "trunk_link", ""}, - - // {"natural", "water", ""} - //}; + m_typesCorrector.SetMappingTypes(arr1, arr2); + } } + ~WorldMapGenerator() { DoMerge(); @@ -92,7 +92,7 @@ public: if (m_worldBucket && m_worldBucket->NeedPushToWorld(fb)) { if (m_mergeCoastlines && (fb.GetGeomType() == feature::GEOM_LINE)) - m_processor(fb); + m_merger(m_typesCorrector(fb)); else m_worldBucket->PushSure(fb); } @@ -101,6 +101,6 @@ public: void DoMerge() { if (m_worldBucket) - m_processor.DoMerge(*m_worldBucket); + m_merger.DoMerge(*m_worldBucket); } }; diff --git a/indexer/feature_data.cpp b/indexer/feature_data.cpp index 6272eb32f9..0a654f89f6 100644 --- a/indexer/feature_data.cpp +++ b/indexer/feature_data.cpp @@ -53,11 +53,6 @@ void FeatureParams::AddTypes(FeatureParams const & rhs) m_Types.insert(m_Types.end(), rhs.m_Types.begin(), rhs.m_Types.end()); } -void FeatureParams::SortTypes() -{ - sort(m_Types.begin(), m_Types.end()); -} - void FeatureParams::FinishAddingTypes() { sort(m_Types.begin(), m_Types.end()); diff --git a/indexer/feature_data.hpp b/indexer/feature_data.hpp index 27fadeba65..3bf3bbe6d3 100644 --- a/indexer/feature_data.hpp +++ b/indexer/feature_data.hpp @@ -144,7 +144,6 @@ public: m_Types.assign(b, e); } - void SortTypes(); void FinishAddingTypes(); void SetType(uint32_t t);