| 166 | } |
| 167 | |
| 168 | void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType & feature, |
| 169 | geometry::Altitudes const * altitudes, RoadAttrsGetter & attrs) |
| 170 | { |
| 171 | size_t const count = feature.GetPointsCount(); |
| 172 | CHECK_GREATER(count, 1, ()); |
| 173 | CHECK(altitudes == nullptr || altitudes->size() == count, ()); |
| 174 | |
| 175 | feature::TypesHolder types(feature); |
| 176 | m_highwayType = vehicleModel.GetHighwayType(types); |
| 177 | |
| 178 | m_valid = vehicleModel.IsRoad(types); |
| 179 | m_isOneWay = vehicleModel.IsOneWay(types); |
| 180 | m_isPassThroughAllowed = vehicleModel.IsPassThroughAllowed(types); |
| 181 | |
| 182 | uint32_t const fID = feature.GetID().m_index; |
| 183 | m_inCity = attrs.m_cityRoads.IsCityRoad(fID); |
| 184 | |
| 185 | SpeedParams params(attrs.m_maxSpeeds.GetMaxspeed(fID), |
| 186 | m_highwayType ? attrs.m_maxSpeeds.GetDefaultSpeed(m_inCity, *m_highwayType) : kInvalidSpeed, |
| 187 | m_inCity); |
| 188 | params.m_forward = true; |
| 189 | m_forwardSpeed = vehicleModel.GetSpeed(types, params); |
| 190 | params.m_forward = false; |
| 191 | m_backwardSpeed = vehicleModel.GetSpeed(types, params); |
| 192 | |
| 193 | auto const & optionsClassfier = RoutingOptionsClassifier::Instance(); |
| 194 | for (uint32_t type : types) |
| 195 | { |
| 196 | if (auto const it = optionsClassfier.Get(type)) |
| 197 | { |
| 198 | if (*it == RoutingOptions::Road::Dirty && m_routingOptions.Has(RoutingOptions::Road::Paved)) |
| 199 | continue; |
| 200 | |
| 201 | m_routingOptions.Add(*it); |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | m_junctions.clear(); |
| 206 | m_junctions.reserve(count); |
| 207 | for (size_t i = 0; i < count; ++i) |
| 208 | { |
| 209 | auto const ll = mercator::ToLatLon(feature.GetPoint(i)); |
| 210 | m_junctions.emplace_back(ll, altitudes ? (*altitudes)[i] : geometry::kDefaultAltitudeMeters); |
| 211 | |
| 212 | #ifdef DEBUG |
| 213 | // I'd like to check these big jumps manually, if any. |
| 214 | if (altitudes && i > 0) |
| 215 | { |
| 216 | // Since we store integer altitudes, 1 is a possible error for 2 points. |
| 217 | geometry::Altitude constexpr kError = 1; |
| 218 | |
| 219 | auto const altDiff = (*altitudes)[i] - (*altitudes)[i - 1]; |
| 220 | auto const absDiff = abs(altDiff) - kError; |
| 221 | if (absDiff > 0) |
| 222 | { |
| 223 | double const dist = ms::DistanceOnEarth(m_junctions[i - 1].GetLatLon(), m_junctions[i].GetLatLon()); |
| 224 | if (absDiff / dist >= 1.0) |
| 225 | LOG(LWARNING, ("Altitudes jump:", altDiff, "/", dist, m_junctions[i - 1], m_junctions[i])); |
no test coverage detected