1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#pragma once
#include "generator/osm_element.hpp"
#include "generator/routing_helpers.hpp"
#include "routing/base/followed_polyline.hpp"
#include "routing/routing_helpers.hpp"
#include "routing/speed_camera_ser_des.hpp"
#include "indexer/data_source.hpp"
#include "indexer/feature_data.hpp"
#include "indexer/feature_decl.hpp"
#include "indexer/scales.hpp"
#include "coding/file_writer.hpp"
#include "coding/write_to_sink.hpp"
#include "geometry/point2d.hpp"
#include "geometry/segment2d.hpp"
#include "base/geo_object_id.hpp"
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <utility>
#include <vector>
namespace generator
{
class CamerasInfoCollector
{
public:
CamerasInfoCollector(std::string const & dataFilePath, std::string const & camerasInfoPath,
std::string const & osmIdsToFeatureIdsPath);
void Serialize(FileWriter & writer) const;
private:
struct Camera
{
inline static double constexpr kCoordEqualityEps = 1e-5;
Camera(m2::PointD const & center, uint8_t maxSpeed, std::vector<routing::SpeedCameraMwmPosition> && ways)
: m_data(center, maxSpeed, std::move(ways))
{
}
void ParseDirection()
{
// After some research we understood, that camera's direction is a random option.
// This fact was checked with randomly chosen cameras and google maps 3d view.
// The real direction and the one indicated in the OSM differed.
// So we left space in mwm for this feature and wait until good data appears in OSM
}
// Modify m_ways vector. Set for each way - id of the closest segment.
void FindClosestSegment(FrozenDataSource const & dataSource, MwmSet::MwmId const & mwmId);
/// \brief Try to FindClosestSegment in |m_ways|. Look to FindMyself() for more details.
/// \return true if we could find closest segment. And false if we should use geometry index.
bool FindClosestSegmentInInnerWays(FrozenDataSource const & dataSource, MwmSet::MwmId const & mwmId);
/// \brief Use when |m_ways| is empty. Try to FindClosestSegment using geometry index.
void FindClosestSegmentWithGeometryIndex(FrozenDataSource const & dataSource);
// Returns empty object, if current feature - |wayId| is not the car road.
// Otherwise returns id of segment from feature with id - |wayId|, which starts (or ends) at camera's
// center and coefficient - where it placed at the segment: 0.0 (or 1.0).
std::optional<std::pair<double, uint32_t>> FindMyself(uint32_t wayFeatureId,
FrozenDataSource const & dataSource,
MwmSet::MwmId const & mwmId) const;
void Serialize(FileWriter & writer, uint32_t & prevFeatureId) const;
routing::SpeedCameraMetadata m_data;
};
inline static double constexpr kMaxDistFromCameraToClosestSegmentMeters = 20.0;
inline static double constexpr kSearchCameraRadiusMeters = 10.0;
bool ParseIntermediateInfo(std::string const & camerasInfoPath,
routing::OsmIdToFeatureIds const & osmIdToFeatureIds);
std::vector<Camera> m_cameras;
};
// To start building camera info, the following data must be ready:
// 1. GenerateIntermediateData(). Cached data about camera node to ways.
// 2. GenerateFeatures(). Data about cameras from OSM.
// 3. GenerateFinalFeatures(). Calculate some data for features.
// 4. BuildOffsetsTable().
// 5. BuildIndexFromDataFile() - for doing search in rect.
void BuildCamerasInfo(std::string const & dataFilePath, std::string const & camerasInfoPath,
std::string const & osmIdsToFeatureIdsPath);
} // namespace generator
|