| 251 | } |
| 252 | |
| 253 | std::optional<std::pair<double, uint32_t>> CamerasInfoCollector::Camera::FindMyself(uint32_t wayFeatureId, |
| 254 | FrozenDataSource const & dataSource, |
| 255 | MwmSet::MwmId const & mwmId) const |
| 256 | { |
| 257 | double coef = 0.0; |
| 258 | bool isRoad = true; |
| 259 | uint32_t result = 0; |
| 260 | bool cannotFindMyself = false; |
| 261 | |
| 262 | auto const readFeature = [&](FeatureType & ft) |
| 263 | { |
| 264 | bool found = false; |
| 265 | isRoad = routing::IsRoad(feature::TypesHolder(ft)); |
| 266 | if (!isRoad) |
| 267 | return; |
| 268 | |
| 269 | auto const findPoint = [&result, &found, this](m2::PointD const & pt) |
| 270 | { |
| 271 | if (found) |
| 272 | return; |
| 273 | |
| 274 | if (AlmostEqualAbs(m_data.m_center, pt, kCoordEqualityEps)) |
| 275 | found = true; |
| 276 | else |
| 277 | ++result; |
| 278 | }; |
| 279 | |
| 280 | ft.ForEachPoint(findPoint, scales::GetUpperScale()); |
| 281 | |
| 282 | if (!found) |
| 283 | { |
| 284 | cannotFindMyself = true; |
| 285 | return; |
| 286 | } |
| 287 | |
| 288 | // If point with number - N, is end of feature, we cannot say: segmentId = N, |
| 289 | // because number of segments is N - 1, so we say segmentId = N - 1, and coef = 1 |
| 290 | // which means, that camera placed at the end of (N - 1)'th segment. |
| 291 | if (result + 1 == ft.GetPointsCount()) |
| 292 | { |
| 293 | CHECK_NOT_EQUAL(result, 0, ("Feature consists of one point!")); |
| 294 | --result; |
| 295 | coef = 1.0; |
| 296 | } |
| 297 | }; |
| 298 | |
| 299 | FeatureID featureID(mwmId, wayFeatureId); |
| 300 | dataSource.ReadFeature(readFeature, featureID); |
| 301 | |
| 302 | if (cannotFindMyself) |
| 303 | { |
| 304 | // Note. Speed camera with coords |m_data.m_center| is not located at any point of |wayFeatureId|. |
| 305 | // It may happens if osm feature corresponds to |wayFeatureId| is split by a mini_roundabout |
| 306 | // or turning_loop. There are two cases: |
| 307 | // * |m_data.m_center| is located at a point of another part of the whole osm feature. In |
| 308 | // that case it will be found on another call of FindMyself() method. |
| 309 | // * |m_data.m_center| coincides with point of mini_roundabout or turning_loop. It means |
| 310 | // there on feature point which coincides with speed camera (|m_data.m_center|). |
nothing calls this directly
no test coverage detected