| 184 | } |
| 185 | |
| 186 | void MiniRoundaboutTransformer::ProcessRoundabouts(std::function<void(feature::FeatureBuilder const &)> const & fn) |
| 187 | { |
| 188 | // Some mini-roundabouts are mapped in the middle of the road. These roads should be split |
| 189 | // in two parts on the opposite sides of the roundabout. New roads are saved in |fbsRoads|. |
| 190 | std::vector<feature::FeatureBuilder> fbsRoads; |
| 191 | size_t constexpr kReserveSize = 4 * 1024; |
| 192 | fbsRoads.reserve(kReserveSize); |
| 193 | |
| 194 | size_t transformed = 0; |
| 195 | for (auto const & rb : m_roundabouts) |
| 196 | { |
| 197 | bool allRoadsInOneMwm = true; |
| 198 | |
| 199 | // First of all collect Ways-Features and make sure that they are _transformable_. Do nothing otherwise. |
| 200 | std::vector<std::pair<feature::FeatureBuilder *, uint64_t>> features; |
| 201 | for (uint64_t const wayId : rb.m_ways) |
| 202 | { |
| 203 | base::GeoObjectId const geoWayId = base::MakeOsmWay(wayId); |
| 204 | auto const it = m_roads.find(geoWayId); |
| 205 | if (it == m_roads.end()) |
| 206 | continue; |
| 207 | |
| 208 | feature::FeatureBuilder & fb = it->second; |
| 209 | |
| 210 | // Transform only mini_roundabouts on roads contained in single mwm. |
| 211 | // They will overlap and break a picture, otherwise. |
| 212 | if (m_affiliation->GetAffiliations(fb).size() != 1) |
| 213 | { |
| 214 | LOG(LWARNING, ("Roundabout's connected way in many MWMs", geoWayId, rb.m_id)); |
| 215 | allRoadsInOneMwm = false; |
| 216 | break; |
| 217 | } |
| 218 | else |
| 219 | features.emplace_back(&fb, wayId); |
| 220 | } |
| 221 | if (!allRoadsInOneMwm) |
| 222 | continue; |
| 223 | |
| 224 | m2::PointD const center = mercator::FromLatLon(rb.m_coord); |
| 225 | PointsT circlePlain = PointToPolygon(center, m_radiusMercator); |
| 226 | uint32_t roadType = 0; |
| 227 | bool foundRoad = false; |
| 228 | |
| 229 | for (auto [feature, wayId] : features) |
| 230 | { |
| 231 | base::GeoObjectId const geoWayId = base::MakeOsmWay(wayId); |
| 232 | auto road = feature->GetOuterGeometry(); |
| 233 | |
| 234 | if (GetIterOnRoad(center, road) == road.end()) |
| 235 | { |
| 236 | feature = nullptr; |
| 237 | for (auto & rd : fbsRoads) |
| 238 | { |
| 239 | if (rd.GetMostGenericOsmId() == geoWayId) |
| 240 | { |
| 241 | road = rd.GetOuterGeometry(); |
| 242 | if (GetIterOnRoad(center, road) != road.end()) |
| 243 | { |
nothing calls this directly
no test coverage detected