| 269 | } |
| 270 | |
| 271 | bool ParseMaxspeedTag(std::string const & maxspeedValue, routing::SpeedInUnits & speed) |
| 272 | { |
| 273 | if (RoadCategoryToSpeed(maxspeedValue, speed)) |
| 274 | return true; |
| 275 | |
| 276 | if (maxspeedValue == "none") |
| 277 | { |
| 278 | speed.SetSpeed(routing::kNoneMaxSpeed); |
| 279 | speed.SetUnits(Units::Metric); // It's dummy value in case of kNoneMaxSpeed |
| 280 | return true; |
| 281 | } |
| 282 | |
| 283 | if (maxspeedValue == "walk") |
| 284 | { |
| 285 | speed.SetSpeed(routing::kWalkMaxSpeed); |
| 286 | speed.SetUnits(Units::Metric); // It's dummy value in case of kWalkMaxSpeed |
| 287 | return true; |
| 288 | } |
| 289 | |
| 290 | // strings::to_int doesn't work here because of bad errno. |
| 291 | std::string speedStr; |
| 292 | size_t i; |
| 293 | for (i = 0; i < maxspeedValue.size(); ++i) |
| 294 | { |
| 295 | if (!isdigit(maxspeedValue[i])) |
| 296 | break; |
| 297 | |
| 298 | speedStr += maxspeedValue[i]; |
| 299 | } |
| 300 | |
| 301 | while (i < maxspeedValue.size() && strings::IsASCIISpace(maxspeedValue[i])) |
| 302 | ++i; |
| 303 | |
| 304 | if (maxspeedValue.size() == i || maxspeedValue.substr(i).starts_with("kmh")) |
| 305 | { |
| 306 | uint64_t kmph = 0; |
| 307 | if (!strings::to_uint64(speedStr.c_str(), kmph) || kmph == 0 || kmph > std::numeric_limits<uint16_t>::max()) |
| 308 | return false; |
| 309 | |
| 310 | speed.SetSpeed(static_cast<uint16_t>(kmph)); |
| 311 | speed.SetUnits(Units::Metric); |
| 312 | return true; |
| 313 | } |
| 314 | |
| 315 | if (maxspeedValue.substr(i).starts_with("mph")) |
| 316 | { |
| 317 | uint64_t mph = 0; |
| 318 | if (!strings::to_uint64(speedStr.c_str(), mph) || mph == 0 || mph > std::numeric_limits<uint16_t>::max()) |
| 319 | return false; |
| 320 | |
| 321 | speed.SetSpeed(static_cast<uint16_t>(mph)); |
| 322 | speed.SetUnits(Units::Imperial); |
| 323 | return true; |
| 324 | } |
| 325 | |
| 326 | return false; |
| 327 | } |
| 328 | |