Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Byko-Ianko <v.bykoianko@corp.mail.ru>2018-10-26 18:44:59 +0300
committermpimenov <mpimenov@users.noreply.github.com>2018-11-23 17:58:49 +0300
commit59e6a501acf6d44f2e7f92e214a897b67cc8435a (patch)
tree1bdbeaf42e1f9cdef2f550a767df5893c6913d69
parentc596afea3b4b70bcbba1db015b891b97c8b3da4e (diff)
[routing] Quick build maxspeed section implementation.
-rw-r--r--base/base_tests/geo_object_id_tests.cpp6
-rw-r--r--base/geo_object_id.cpp6
-rw-r--r--generator/generator_tool/generator_tool.cpp2
-rw-r--r--generator/maxspeed_builder.cpp150
-rw-r--r--generator/maxspeed_builder.hpp28
-rwxr-xr-xtools/unix/generate_planet.sh2
6 files changed, 178 insertions, 16 deletions
diff --git a/base/base_tests/geo_object_id_tests.cpp b/base/base_tests/geo_object_id_tests.cpp
index 6ce7e8b671..9467d94857 100644
--- a/base/base_tests/geo_object_id_tests.cpp
+++ b/base/base_tests/geo_object_id_tests.cpp
@@ -13,17 +13,17 @@ UNIT_TEST(GeoObjectId)
GeoObjectId const node(GeoObjectId::Type::ObsoleteOsmNode, 12345);
TEST_EQUAL(node.GetSerialId(), 12345ULL, ());
TEST_EQUAL(node.GetType(), GeoObjectId::Type::ObsoleteOsmNode, ());
- TEST_EQUAL(DebugPrint(node), "Osm Node 12345", ());
+ TEST_EQUAL(DebugPrint(node), "Obsolete Osm Node 12345", ());
GeoObjectId const way(GeoObjectId::Type::ObsoleteOsmWay, 93245123456332ULL);
TEST_EQUAL(way.GetSerialId(), 93245123456332ULL, ());
TEST_EQUAL(way.GetType(), GeoObjectId::Type::ObsoleteOsmWay, ());
- TEST_EQUAL(DebugPrint(way), "Osm Way 93245123456332", ());
+ TEST_EQUAL(DebugPrint(way), "Obsolete Osm Way 93245123456332", ());
GeoObjectId const relation(GeoObjectId::Type::ObsoleteOsmRelation, 5);
TEST_EQUAL(relation.GetSerialId(), 5ULL, ());
TEST_EQUAL(relation.GetType(), GeoObjectId::Type::ObsoleteOsmRelation, ());
- TEST_EQUAL(DebugPrint(relation), "Osm Relation 5", ());
+ TEST_EQUAL(DebugPrint(relation), "Obsolete Osm Relation 5", ());
// 2^48 - 1, maximal possible serial id.
GeoObjectId const surrogate(GeoObjectId::Type::OsmSurrogate, 281474976710655ULL);
diff --git a/base/geo_object_id.cpp b/base/geo_object_id.cpp
index adaf312449..232cdae355 100644
--- a/base/geo_object_id.cpp
+++ b/base/geo_object_id.cpp
@@ -84,9 +84,9 @@ std::string DebugPrint(GeoObjectId::Type const & t)
case GeoObjectId::Type::BookingComNode: return "Booking.com";
case GeoObjectId::Type::OsmSurrogate: return "Osm Surrogate";
case GeoObjectId::Type::Fias: return "FIAS";
- case GeoObjectId::Type::ObsoleteOsmNode: return "Osm Node";
- case GeoObjectId::Type::ObsoleteOsmWay: return "Osm Way";
- case GeoObjectId::Type::ObsoleteOsmRelation: return "Osm Relation";
+ case GeoObjectId::Type::ObsoleteOsmNode: return "Obsolete Osm Node";
+ case GeoObjectId::Type::ObsoleteOsmWay: return "Obsolete Osm Way";
+ case GeoObjectId::Type::ObsoleteOsmRelation: return "Obsolete Osm Relation";
}
CHECK_SWITCH();
}
diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp
index 80e88348ab..4d3949ce8d 100644
--- a/generator/generator_tool/generator_tool.cpp
+++ b/generator/generator_tool/generator_tool.cpp
@@ -532,7 +532,7 @@ int main(int argc, char ** argv)
{
LOG(LINFO, ("Generating maxspeed section for", datFile));
string const maxspeedFilename = genInfo.GetIntermediateFileName(MAXSPEED_FILENAME);
- CHECK(BuildMaxspeed(datFile, osmToFeatureFilename, maxspeedFilename),
+ CHECK(routing::BuildMaxspeed(datFile, osmToFeatureFilename, maxspeedFilename),
("Generating maxspeed section error."));
}
diff --git a/generator/maxspeed_builder.cpp b/generator/maxspeed_builder.cpp
index 511cc853ff..a6bb5f1541 100644
--- a/generator/maxspeed_builder.cpp
+++ b/generator/maxspeed_builder.cpp
@@ -1,12 +1,152 @@
#include "generator/maxspeed_builder.hpp"
+#include "generator/maxspeed_parser.hpp"
+#include "generator/routing_helpers.hpp"
+
#include "routing/maxspeed_conversion.hpp"
+#include "routing/maxspeed_serialization.hpp"
+
+#include "indexer/feature.hpp"
+#include "indexer/feature_data.hpp"
+#include "indexer/feature_processor.hpp"
+
+#include "coding/file_container.hpp"
+#include "coding/file_writer.hpp"
+
+#include "base/assert.hpp"
+#include "base/logging.hpp"
+#include "base/string_utils.hpp"
+
+#include <algorithm>
+#include <cstdint>
+#include <fstream>
+#include <utility>
-namespace generator
+#include "defines.hpp"
+
+// Important note. The code below in this file will be rewritten and covered by tests within the PR.
+// Now it's written quickly to make a test map build this weekend.
+
+namespace
{
-bool BuildMaxspeed(std::string const & dataPath, std::string const & osmToFeaturePath,
- std::string const & maxspeedFilename)
+char const kDelim[] = ", \t\r\n";
+
+bool ParseOneSpeedValue(strings::SimpleTokenizer & iter, uint16_t & value)
{
- return false;
+ uint64_t parsedSpeed = 0;
+ if (!strings::to_uint64(*iter, parsedSpeed))
+ return false;
+ if (parsedSpeed > std::numeric_limits<uint16_t>::max())
+ return false;
+ value = static_cast<uint16_t>(parsedSpeed);
+ ++iter;
+ return true;
+}
+} // namespace
+
+namespace routing
+{
+using namespace feature;
+using namespace generator;
+using namespace std;
+
+// @TODO(bykoianko) Consider implement a maxspeed collector class instead of ParseMaxspeeds() and
+// part of BuildMaxspeed() methods.
+bool ParseMaxspeeds(string const & maxspeedFilename, OsmIdToMaxspeed & osmIdToMaxspeed)
+{
+ osmIdToMaxspeed.clear();
+
+ ifstream stream(maxspeedFilename);
+ if (stream.fail())
+ return false;
+
+ string line;
+ while (std::getline(stream, line))
+ {
+ strings::SimpleTokenizer iter(line, kDelim);
+ if (!iter) // the line is empty
+ return false;
+
+ uint64_t osmId = 0;
+ if (!strings::to_uint64(*iter, osmId))
+ return false;
+ ++iter;
+
+ ParsedMaxspeed speed;
+ speed.m_units = StringToUnits(*iter);
+ ++iter;
+
+ if (!ParseOneSpeedValue(iter, speed.m_forward))
+ return false;
+
+ if (iter)
+ {
+ // There's backward maxspeed limit.
+ if (!ParseOneSpeedValue(iter, speed.m_backward))
+ return false;
+
+ if (iter)
+ return false;
+ }
+
+ auto const res = osmIdToMaxspeed.insert(make_pair(base::MakeOsmWay(osmId), speed));
+ if (!res.second)
+ return false;
+ }
+ return true;
+}
+
+void SerializeMaxspeed(string const & dataPath, vector<FeatureMaxspeed> && speeds)
+{
+ LOG(LINFO, ("SerializeMaxspeed(", dataPath, ", ...) speeds size:", speeds.size()));
+ if (speeds.empty())
+ return;
+
+ LOG(LINFO, ("SerializeMaxspeed() The fisrt speed", speeds[0]));
+
+ FilesContainerW cont(dataPath, FileWriter::OP_WRITE_EXISTING);
+ FileWriter writer = cont.GetWriter(MAXSPEED_FILE_TAG);
+
+ MaxspeedSerializer::Serialize(speeds, writer);
+}
+
+bool BuildMaxspeed(string const & dataPath, string const & osmToFeaturePath,
+ string const & maxspeedFilename)
+{
+ LOG(LINFO, ("BuildMaxspeed(", dataPath, ",", osmToFeaturePath, ",", maxspeedFilename, ")"));
+
+ OsmIdToMaxspeed osmIdToMaxspeed;
+ CHECK(ParseMaxspeeds(maxspeedFilename, osmIdToMaxspeed), ());
+ LOG(LINFO, ("BuildMaxspeed() osmIdToMaxspeed size:", osmIdToMaxspeed.size()));
+
+ map<uint32_t, base::GeoObjectId> featureIdToOsmId;
+ CHECK(ParseFeatureIdToOsmIdMapping(osmToFeaturePath, featureIdToOsmId), ());
+ LOG(LINFO, ("BuildMaxspeed() featureIdToOsmId size:", featureIdToOsmId.size()));
+
+ vector<FeatureMaxspeed> speeds;
+ ForEachFromDat(dataPath, [&](FeatureType & ft, uint32_t fid) {
+ if (!routing::IsCarRoad(TypesHolder(ft)))
+ return;
+
+ auto const osmIdIt = featureIdToOsmId.find(fid);
+ if (osmIdIt == featureIdToOsmId.cend())
+ return;
+
+ // @TODO Consider adding check here. |fid| should be in |featureIdToOsmId| anyway.
+ auto const maxspeedIt = osmIdToMaxspeed.find(osmIdIt->second);
+ if (maxspeedIt == osmIdToMaxspeed.cend())
+ return;
+
+ auto const & parsedMaxspeed = maxspeedIt->second;
+ // Note. It's wrong that by default if there's no maxspeed backward SpeedInUnits::m_units
+ // is Metric and according to this code it's be saved as Imperial for country
+ // with imperial metrics. Anyway this code should be rewritten before merge.
+ speeds.push_back(
+ FeatureMaxspeed(fid, SpeedInUnits(parsedMaxspeed.m_forward, parsedMaxspeed.m_units),
+ SpeedInUnits(parsedMaxspeed.m_backward, parsedMaxspeed.m_units)));
+ });
+
+ SerializeMaxspeed(dataPath, move(speeds));
+ return true;
}
-} // namespace generator
+} // namespace routing
diff --git a/generator/maxspeed_builder.hpp b/generator/maxspeed_builder.hpp
index 1c66922471..0a71ebed48 100644
--- a/generator/maxspeed_builder.hpp
+++ b/generator/maxspeed_builder.hpp
@@ -1,10 +1,32 @@
#pragma once
+#include "routing/maxspeed_conversion.hpp"
+#include "platform/measurement_utils.hpp"
+
+#include "base/geo_object_id.hpp"
+
+#include <map>
#include <string>
+#include <vector>
-namespace generator
+namespace routing
{
-/// \brief Builds maxspeed section.
+struct ParsedMaxspeed
+{
+ measurement_utils::Units m_units = measurement_utils::Units::Metric;
+ uint16_t m_forward = routing::kInvalidSpeed;
+ uint16_t m_backward = routing::kInvalidSpeed;
+};
+
+using OsmIdToMaxspeed = std::map<base::GeoObjectId, ParsedMaxspeed>;
+
+bool ParseMaxspeeds(std::string const & maxspeedFilename, OsmIdToMaxspeed & osmIdToMaxspeed);
+
+/// \brief Write |speeds| to maxspeed section to mwm with |dataPath|.
+void SerializeMaxspeed(std::string const & dataPath, std::vector<FeatureMaxspeed> && speeds);
+
+/// \brief Builds maxspeed section in mwm with |dataPath|. This section contains max speed limits
+/// if it's available.
/// \param maxspeedFilename file name to csv file with maxspeed tag values.
/// \note To start building the section, the following data must be ready:
/// 1. GenerateIntermediateData(). Saves to a file data about maxspeed tags value of road features
@@ -12,4 +34,4 @@ namespace generator
/// 3. Generates geometry
bool BuildMaxspeed(std::string const & dataPath, std::string const & osmToFeaturePath,
std::string const & maxspeedFilename);
-} // namespace generator
+} // namespace routing
diff --git a/tools/unix/generate_planet.sh b/tools/unix/generate_planet.sh
index 76208ab7d6..1f80cadb67 100755
--- a/tools/unix/generate_planet.sh
+++ b/tools/unix/generate_planet.sh
@@ -512,7 +512,7 @@ if [ "$MODE" == "mwm" ]; then
fi
if [ -z "$NO_REGIONS" ]; then
- PARAMS_WITH_SEARCH="$PARAMS --generate_search_index --cities_boundaries_data=$CITIES_BOUNDARIES_DATA --make_city_roads"
+ PARAMS_WITH_SEARCH="$PARAMS --generate_search_index --cities_boundaries_data=$CITIES_BOUNDARIES_DATA --make_city_roads --generate_maxspeed"
[ -n "${SRTM_PATH-}" -a -d "${SRTM_PATH-}" ] && PARAMS_WITH_SEARCH="$PARAMS_WITH_SEARCH --srtm_path=$SRTM_PATH"
[ -f "$UGC_FILE" ] && PARAMS_WITH_SEARCH="$PARAMS_WITH_SEARCH --ugc_data=$UGC_FILE"
[ -f "$POPULAR_PLACES_FILE" ] && PARAMS_WITH_SEARCH="$PARAMS_WITH_SEARCH --popular_places_data=$POPULAR_PLACES_FILE --generate_popular_places"