diff options
author | VladiMihaylenko <vxmihaylenko@gmail.com> | 2018-09-03 18:34:08 +0300 |
---|---|---|
committer | Vladimir Byko-Ianko <bykoianko@gmail.com> | 2018-09-13 13:43:03 +0300 |
commit | 7d757db649d952160e7bf608ec84345e5362905a (patch) | |
tree | 7c01afdd2ac18f85917c2a7c5db1ec48b499c304 /track_generator | |
parent | 165028d073eb6bf69257b6be00d5b29696aeccaa (diff) |
Track generator tool
Diffstat (limited to 'track_generator')
-rw-r--r-- | track_generator/CMakeLists.txt | 37 | ||||
-rw-r--r-- | track_generator/track_generator_tool.cpp | 49 | ||||
-rw-r--r-- | track_generator/utils.cpp | 150 | ||||
-rw-r--r-- | track_generator/utils.hpp | 10 |
4 files changed, 246 insertions, 0 deletions
diff --git a/track_generator/CMakeLists.txt b/track_generator/CMakeLists.txt new file mode 100644 index 0000000000..6e8d6af066 --- /dev/null +++ b/track_generator/CMakeLists.txt @@ -0,0 +1,37 @@ +project(track_generator_tool) + +include_directories( + ${OMIM_ROOT}/3party/gflags/src +) + +set( + SRC + track_generator_tool.cpp + utils.cpp + utils.hpp +) + +omim_add_executable(${PROJECT_NAME} ${SRC}) + +omim_link_libraries( + ${PROJECT_NAME} + routing_quality + routing_common + routing + kml + indexer + platform + bsdiff + geometry + coding + base + icu + protobuf + expat + stats_client + gflags + ${LIBZ} +) + +link_qt5_core(${PROJECT_NAME}) +link_qt5_network(${PROJECT_NAME}) diff --git a/track_generator/track_generator_tool.cpp b/track_generator/track_generator_tool.cpp new file mode 100644 index 0000000000..d9ba7f4b7b --- /dev/null +++ b/track_generator/track_generator_tool.cpp @@ -0,0 +1,49 @@ +#include "track_generator/utils.hpp" + +#include "routing/vehicle_mask.hpp" + +#include "base/assert.hpp" +#include "base/logging.hpp" + +#include <string> + +#include "3party/gflags/src/gflags/gflags.h" + +DEFINE_string(inputDir, "", "Path to kmls."); + +DEFINE_string(outputDir, "", "Path to converted kmls."); + +DEFINE_int32(vehicleType, 0, "Numeric value of routing::VehicleType enum. " + "Pedestrian by default."); + +DEFINE_bool(showHelp, false, "Show help on all flags."); + +int main(int argc, char ** argv) +{ + google::SetUsageMessage("The tool is used to generate more smooth track based on " + "waypoints from the kml. The kml has to contain points " + "within LineString tag. If the router can't build the route " + "than the specific path will be untouched. Multiple kmls into " + " the directory are supported.\n\n" + "Usage example: " + "./track_generator_tool -cmd=generate -inputDir=path/to/input/ -outputDir=/path/to/output"); + + google::ParseCommandLineFlags(&argc, &argv, true /* remove_flags */); + + if (argc == 1 || FLAGS_showHelp) + { + google::ShowUsageWithFlags(argv[0]); + return 0; + } + + if (FLAGS_inputDir.empty() || FLAGS_outputDir.empty()) + { + LOG(LINFO, (FLAGS_inputDir.empty() ? "Input" : "Output", "directory is required.")); + google::ShowUsageWithFlags(argv[0]); + return 1; + } + + track_generator_tool::GenerateTracks(FLAGS_inputDir, FLAGS_outputDir, + static_cast<routing::VehicleType>(FLAGS_vehicleType)); + return 0; +} diff --git a/track_generator/utils.cpp b/track_generator/utils.cpp new file mode 100644 index 0000000000..c3105e5c94 --- /dev/null +++ b/track_generator/utils.cpp @@ -0,0 +1,150 @@ +#include "track_generator/utils.hpp" + +#include "kml/serdes.hpp" +#include "kml/type_utils.hpp" +#include "kml/types.hpp" + +#include "routing/base/followed_polyline.hpp" +#include "routing/route.hpp" +#include "routing/routing_callbacks.hpp" +#include "routing/routing_quality/utils.hpp" + +#include "coding/file_name_utils.hpp" +#include "coding/file_reader.hpp" +#include "coding/file_writer.hpp" + +#include "platform/platform.hpp" + +#include "base/assert.hpp" +#include "base/logging.hpp" + +#include <cstdint> +#include <utility> +#include <vector> + +using namespace std; + +namespace +{ +vector<m2::PointD> GetTrackPoints(routing::Route && route) +{ + CHECK(route.IsValid(), ()); + auto const & segments = route.GetRouteSegments(); + auto const size = segments.size(); + vector<m2::PointD> result; + result.reserve(size); + + for (size_t i = 0; i < size;) + { + size_t j = i + 1; + size_t consecutiveNumber = 1; + /// Check number of consecutive junctions with the same point. + while (j < size && segments[j].GetJunction().GetPoint() == segments[i].GetJunction().GetPoint()) + { + ++j; + ++consecutiveNumber; + } + + /// S3 S4 + /// ⥀ ⥀ + /// * | + /// ⋀ S5 + /// | | + /// S2 ⋁ + /// | * + /// —— S1 ——> * —— S6 ——> * + + /// If there is 3 or more consecutive point than it's an intermediate point + /// which is the start and the end of the subroute simultaneously. + if (consecutiveNumber >= 3) + { + /// —— S1 ——> * + /// | + /// S2 + /// | + /// ⋁ + /// * + + /// Check if there are two perpendicular fake segments and get rid from both of them. + if (!result.empty() && result.back() == segments[j].GetJunction().GetPoint()) + { + result.pop_back(); + ++j; + } + } + else + { + result.emplace_back(segments[i].GetJunction().GetPoint()); + } + + i = j; + } + + return result; +} +} // namespace + +namespace track_generator_tool +{ +void GenerateTracks(string const & inputDir, string const & outputDir, routing::VehicleType type) +{ + CHECK(!inputDir.empty(), ()); + CHECK(!outputDir.empty(), ()); + CHECK_LESS(type, routing::VehicleType::Count, ()); + + Platform::FilesList files; + Platform::GetFilesByExt(inputDir, ".kml", files); + CHECK(!files.empty(), ("Input directory doesn't contain kmls.")); + + for (auto const & file : files) + { + LOG(LINFO, ("Start generating tracks for file", file)); + kml::FileData data; + try + { + kml::DeserializerKml des(data); + FileReader r(my::JoinPath(inputDir, file)); + des.Deserialize(r); + } + catch (FileReader::Exception const & ex) + { + CHECK(false, ("Can't convert file", file, "\nException:", ex.what())); + } + catch (kml::DeserializerKml::DeserializeException const & ex) + { + CHECK(false, ("Can't deserialize file", file, "\nException:", ex.what())); + } + + CHECK(!data.m_tracksData.empty(), ("No tracks in file", file)); + for (auto & track : data.m_tracksData) + { + auto waypoints = track.m_points; + auto result = routing_quality::GetRoute(move(waypoints), type); + if (result.m_code != routing::RouterResultCode::NoError) + { + LOG(LINFO, ("Can't convert track", track.m_id, "from file", file)); + continue; + } + + track.m_points = GetTrackPoints(move(result.m_route)); + } + + try + { + kml::SerializerKml ser(data); + FileWriter sink(my::JoinPath(outputDir, file)); + ser.Serialize(sink); + } + catch (FileWriter::Exception const & ex) + { + CHECK(false, ("Can't save file", file, "\nException:", ex.what())); + } + catch (kml::SerializerKml::SerializeException const & ex) + { + CHECK(false, ("Can't serialize file", file, "\nException:", ex.what())); + } + + LOG(LINFO, ("Finished generating tracks for file", file)); + } +} +} // namespace track_generator_tool diff --git a/track_generator/utils.hpp b/track_generator/utils.hpp new file mode 100644 index 0000000000..0d376c52d2 --- /dev/null +++ b/track_generator/utils.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "routing/vehicle_mask.hpp" + +#include <string> + +namespace track_generator_tool +{ +void GenerateTracks(std::string const & inputDir, std::string const & outputDir, routing::VehicleType type); +} // namespace track_generator_tool |