From 621dd5ca54544b649045585815587f2dbcf12db8 Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Mon, 29 Aug 2011 20:09:44 +0300 Subject: [PATCH] Added Osm ID debug output for FeatureBuilder1. It should help for coastline merging --- generator/feature_builder.cpp | 25 +++++++++-- generator/feature_builder.hpp | 12 +++++- generator/feature_merger.cpp | 3 ++ generator/first_pass_parser.hpp | 2 +- generator/generator.pro | 2 + generator/generator_tests/generator_tests.pro | 1 + generator/generator_tests/osm_id_test.cpp | 23 ++++++++++ generator/osm_element.hpp | 15 ++++++- generator/osm_id.cpp | 43 +++++++++++++++++++ generator/osm_id.hpp | 20 +++++++++ 10 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 generator/generator_tests/osm_id_test.cpp create mode 100644 generator/osm_id.cpp create mode 100644 generator/osm_id.hpp diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index cdb7e59356..50f6f57c22 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -1,5 +1,3 @@ -#include "../base/SRC_FIRST.hpp" - #include "feature_builder.hpp" #include "../indexer/feature_impl.hpp" @@ -11,8 +9,6 @@ #include "../coding/byte_stream.hpp" -#include "../base/start_mem_debug.hpp" - using namespace feature; @@ -272,6 +268,27 @@ void FeatureBuilder1::Deserialize(buffer_t & data) CHECK ( CheckValid(), () ); } +void FeatureBuilder1::AddOsmId(string const & type, uint64_t osmId) +{ + m_osmIds.push_back(osm::OsmId(type, osmId)); +} + +string debug_print(FeatureBuilder1 const & f) +{ + ostringstream out; + for (size_t i = 0; i < f.m_osmIds.size(); ++i) + out << f.m_osmIds[i].Type() << " id=" << f.m_osmIds[i].Id() << " "; + switch (f.GetGeomType()) + { + case feature::GEOM_POINT: out << "(" << f.m_Center << ")"; break; + case feature::GEOM_LINE: out << "line with " << f.GetPointsCount() << "points"; break; + case feature::GEOM_AREA: out << "area with " << f.GetPointsCount() << "points"; break; + default: + out << "ERROR: unknown geometry type"; break; + } + return out.str(); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // FeatureBuilderGeomRef implementation /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp index 5e533faf7f..6f8563c4bb 100644 --- a/generator/feature_builder.hpp +++ b/generator/feature_builder.hpp @@ -1,16 +1,21 @@ #pragma once + +#include "osm_id.hpp" + #include "../indexer/feature.hpp" #include "../coding/file_reader.hpp" #include "../std/bind.hpp" - namespace serial { class CodingParams; } /// Used for serialization\deserialization of features during --generate_features. class FeatureBuilder1 { + /// For debugging + friend string debug_print(FeatureBuilder1 const & f); + public: /// @name Geometry manipulating functions. //@{ @@ -78,7 +83,12 @@ public: inline void SetParams(FeatureParams const & params) { m_Params = params; } + /// For OSM debugging, store original OSM id + void AddOsmId(string const & type, uint64_t osmId); + protected: + /// Used for feature debugging + vector m_osmIds; /// @name For diagnostic use only. //@{ diff --git a/generator/feature_merger.cpp b/generator/feature_merger.cpp index 7d8a794fc3..27403f8319 100644 --- a/generator/feature_merger.cpp +++ b/generator/feature_merger.cpp @@ -18,6 +18,9 @@ void MergedFeatureBuilder1::SetRound() void MergedFeatureBuilder1::AppendFeature(MergedFeatureBuilder1 const & fb, bool fromBegin, bool toBack) { + // Also merge Osm IDs for debugging + m_osmIds.insert(m_osmIds.end(), fb.m_osmIds.begin(), fb.m_osmIds.end()); + if (fb.m_isRound) { if (toBack) diff --git a/generator/first_pass_parser.hpp b/generator/first_pass_parser.hpp index a38e879beb..96e4c12a2e 100644 --- a/generator/first_pass_parser.hpp +++ b/generator/first_pass_parser.hpp @@ -43,7 +43,7 @@ protected: { // store way - WayElement e; + WayElement e(id); bool bUnite = false; bool bEmptyTags = true; diff --git a/generator/generator.pro b/generator/generator.pro index 48e3d60df6..4b3ce5f46d 100644 --- a/generator/generator.pro +++ b/generator/generator.pro @@ -28,6 +28,7 @@ SOURCES += \ dumper.cpp \ unpack_mwm.cpp \ feature_builder.cpp \ + osm_id.cpp \ osm_decl.cpp \ HEADERS += \ @@ -54,4 +55,5 @@ HEADERS += \ generate_info.hpp \ unpack_mwm.hpp \ feature_builder.hpp \ + osm_id.hpp \ osm_decl.hpp \ diff --git a/generator/generator_tests/generator_tests.pro b/generator/generator_tests/generator_tests.pro index 26cbd7d33d..7c755b33e5 100644 --- a/generator/generator_tests/generator_tests.pro +++ b/generator/generator_tests/generator_tests.pro @@ -25,3 +25,4 @@ SOURCES += \ osm_parser_test.cpp \ feature_merger_test.cpp \ osm_type_test.cpp \ + osm_id_test.cpp \ diff --git a/generator/generator_tests/osm_id_test.cpp b/generator/generator_tests/osm_id_test.cpp new file mode 100644 index 0000000000..31e237e6ad --- /dev/null +++ b/generator/generator_tests/osm_id_test.cpp @@ -0,0 +1,23 @@ +#include "../../testing/testing.hpp" + +#include "../osm_id.hpp" +#include "../feature_builder.hpp" + +#include "../../base/logging.hpp" + +using namespace osm; + +UNIT_TEST(OsmId) +{ + OsmId node("node", 12345); + TEST_EQUAL(node.Id(), 12345ULL, ()); + TEST_EQUAL(node.Type(), "node", ()); + + OsmId way("way", 93245123456332ULL); + TEST_EQUAL(way.Id(), 93245123456332ULL, ()); + TEST_EQUAL(way.Type(), "way", ()); + + OsmId relation("relation", 5); + TEST_EQUAL(relation.Id(), 5ULL, ()); + TEST_EQUAL(relation.Type(), "relation", ()); +} diff --git a/generator/osm_element.hpp b/generator/osm_element.hpp index 01164a1fcc..c6f9e4fefd 100644 --- a/generator/osm_element.hpp +++ b/generator/osm_element.hpp @@ -64,7 +64,7 @@ protected: void GetWay(uint64_t id, way_map_t & m) { - shared_ptr e(new WayElement()); + shared_ptr e(new WayElement(id)); if (m_holder.GetWay(id, *e) && e->IsValid()) { m.insert(make_pair(e->nodes.front(), e)); @@ -75,7 +75,7 @@ protected: template void ForEachWayPoint(uint64_t id, ToDo toDo) { - WayElement e; + WayElement e(id); if (m_holder.GetWay(id, e)) { process_points process(this, toDo); @@ -419,13 +419,20 @@ protected: feature_t f; InitFeature(fValue, f); + for (typename base_type::way_map_t::iterator it = wayMap.begin(); it != wayMap.end(); ++it) + f.AddOsmId("way", it->second->m_wayOsmId); + base_type::ProcessWayPoints(wayMap, bind(&base_type::feature_builder_t::AddPoint, ref(f), _1)); if (f.IsGeometryClosed()) { f.SetAreaAddHoles(holes.m_holes); if (f.PreSerialize()) + { + // add osm id for debugging + f.AddOsmId("relation", id); base_type::m_emitter(f); + } } } @@ -433,7 +440,11 @@ protected: } if (ft.PreSerialize()) + { + // add osm id for debugging + ft.AddOsmId(p->name, id); base_type::m_emitter(ft); + } } public: diff --git a/generator/osm_id.cpp b/generator/osm_id.cpp new file mode 100644 index 0000000000..3dafee3b7c --- /dev/null +++ b/generator/osm_id.cpp @@ -0,0 +1,43 @@ +#include "osm_id.hpp" + +#include "../base/assert.hpp" + +namespace osm +{ + +// Use 3 higher bits to encode type +static const uint64_t NODE = 0x2000000000000000ULL; +static const uint64_t WAY = 0x4000000000000000ULL; +static const uint64_t RELATION = 0x8000000000000000ULL; +static const uint64_t RESET = ~(NODE | WAY | RELATION); + +OsmId::OsmId(string const & type, uint64_t osmId) + : m_id(osmId) +{ + if (type == "node") + m_id |= NODE; + else if (type == "way") + m_id |= WAY; + else + { + m_id |= RELATION; + ASSERT_EQUAL(type, "relation", ("Invalid osm type:", type)); + } +} + +uint64_t OsmId::Id() const +{ + return m_id & RESET; +} + +string OsmId::Type() const +{ + if (m_id & NODE) + return "node"; + else if (m_id & WAY) + return "way"; + else + return "relation"; +} + +} // namespace osm diff --git a/generator/osm_id.hpp b/generator/osm_id.hpp new file mode 100644 index 0000000000..7e746c0d20 --- /dev/null +++ b/generator/osm_id.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "../std/stdint.hpp" +#include "../std/string.hpp" + +namespace osm +{ + +class OsmId +{ + uint64_t m_id; + +public: + /// @param[in] type "node" "way" or "relation" + OsmId(string const & type, uint64_t osmId); + uint64_t Id() const; + string Type() const; +}; + +} // namespace osm