| 210 | } |
| 211 | |
| 212 | std::string FormatOsmLink(double lat, double lon, int zoom) |
| 213 | { |
| 214 | static constexpr char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_~"; |
| 215 | |
| 216 | // Same as (lon + 180) / 360 * 1UL << 32, but without warnings. |
| 217 | double constexpr factor = (1 << 30) / 90.0; |
| 218 | auto const x = static_cast<uint32_t>(std::lround((lon + 180.0) * factor)); |
| 219 | auto const y = static_cast<uint32_t>(std::lround((lat + 90.0) * factor * 2.0)); |
| 220 | uint64_t const code = bits::BitwiseMerge(y, x); |
| 221 | std::string osmUrl = "https://osm.org/go/"; |
| 222 | |
| 223 | for (int i = 0; i < (zoom + 10) / 3; ++i) |
| 224 | { |
| 225 | uint64_t const digit = (code >> (58 - 6 * i)) & 0x3f; |
| 226 | ASSERT_LESS(digit, ARRAY_SIZE(chars), ()); |
| 227 | osmUrl += chars[digit]; |
| 228 | } |
| 229 | |
| 230 | for (int i = 0; i < (zoom + 8) % 3; ++i) |
| 231 | osmUrl += "-"; |
| 232 | // ?m tells OSM to display a marker |
| 233 | return osmUrl + "?m"; |
| 234 | } |
| 235 | |
| 236 | bool OSMDistanceToMeters(std::string const & osmRawValue, double & outMeters) |
| 237 | { |