From 7d2e03be1aa863961d5d67d6258fbb5227b04014 Mon Sep 17 00:00:00 2001 From: Lars Ivar Hatledal Date: Sat, 16 Mar 2024 12:39:56 +0100 Subject: [PATCH] misc and add BingMaps --- examples/libs/CMakeLists.txt | 1 + .../libs/geo/providers/BingMapsProvider.hpp | 101 ++++++++++++++++++ .../geo/providers/OpenStreetMapsProvider.hpp | 16 ++- examples/projects/MapView/main.cpp | 1 + 4 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 examples/libs/geo/providers/BingMapsProvider.hpp diff --git a/examples/libs/CMakeLists.txt b/examples/libs/CMakeLists.txt index 4351fa65..a41d8e0b 100644 --- a/examples/libs/CMakeLists.txt +++ b/examples/libs/CMakeLists.txt @@ -44,6 +44,7 @@ if (CURL_FOUND) "${CMAKE_CURRENT_SOURCE_DIR}/geo/geometries/MapNodeGeometry.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/geo/providers/MapProvider.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/geo/providers/BingMapsProvider.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/geo/providers/OpenStreetMapsProvider.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/geo/utils/UnitUtils.hpp" diff --git a/examples/libs/geo/providers/BingMapsProvider.hpp b/examples/libs/geo/providers/BingMapsProvider.hpp new file mode 100644 index 00000000..8695c855 --- /dev/null +++ b/examples/libs/geo/providers/BingMapsProvider.hpp @@ -0,0 +1,101 @@ +// https://github.com/tentone/geo-three/blob/master/source/providers/BingMapsProvider.ts + +#ifndef THREEPP_BINGMAPSPROVIDER_HPP +#define THREEPP_BINGMAPSPROVIDER_HPP + +#include "../../utility/URLFetcher.hpp" +#include "../providers/MapProvider.hpp" + +#include "threepp/loaders/ImageLoader.hpp" + +#include +#include + + +namespace threepp { + + class BingMapProvider: public MapProvider { + + public: + enum class Type { + ARIAL, + ROAD + }; + + explicit BingMapProvider(Type type = Type::ROAD): type(type) { + + this->maxZoom = 19; + this->minZoom = 1; + } + + Image fetchTile(int zoom, int x, int y) override { + + std::stringstream ss; + ss << "http://ecn." << subDomain << ".tiles.virtualearth.net/tiles/" << getMapKey() << quadKey(zoom, x, y) << ".jpeg?g=1173"; + const auto url = ss.str(); + + std::vector data; + std::string cacheDir{".cache/bingmaps/" + getMapKey() + "/"}; + std::string cacheFilePath = cacheDir + std::to_string(zoom) + "_" + std::to_string(x) + "_" + std::to_string(y) + ".jpeg"; + + if (std::filesystem::exists(cacheFilePath)) { + // Load from cache file + std::ifstream file(cacheFilePath, std::ios::binary); + data = std::vector((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + } else if (urlFetcher.fetch(url, data)) { + // Save to cache file + std::filesystem::create_directories(cacheDir); + std::ofstream file(cacheFilePath, std::ios::binary); + file.write(reinterpret_cast(data.data()), data.size()); + } + + return *loader.load(data, 4, true); + } + + private: + Type type; + std::string subDomain{"t1"}; + + ImageLoader loader; + utils::UrlFetcher urlFetcher; + + std::string getMapKey() { + switch (type) { + case Type::ARIAL: + return "a"; + case Type::ROAD: + return "r"; + } + return ""; + } + + /** + * Convert x, y, zoom quadtree to a bing maps specific quadkey. + * + * Adapted from original C# code at https://msdn.microsoft.com/en-us/library/bb259689.aspx. + */ + static std::string quadKey(int zoom, int x, int y) { + std::string quad; + + for (int i = zoom; i > 0; i--) { + const int mask = 1 << (i - 1); + int cell = 0; + + if ((x & mask) != 0) { + cell++; + } + + if ((y & mask) != 0) { + cell += 2; + } + + quad += std::to_string(cell); + } + + return quad; + } + }; + +}// namespace threepp + +#endif//THREEPP_BINGMAPSPROVIDER_HPP diff --git a/examples/libs/geo/providers/OpenStreetMapsProvider.hpp b/examples/libs/geo/providers/OpenStreetMapsProvider.hpp index 8762d7e1..fc7baacb 100644 --- a/examples/libs/geo/providers/OpenStreetMapsProvider.hpp +++ b/examples/libs/geo/providers/OpenStreetMapsProvider.hpp @@ -17,8 +17,7 @@ namespace threepp { class OpenStreetMapProvider: public MapProvider { public: - explicit OpenStreetMapProvider(std::string address = "https://a.tile.openstreetmap.org/") - : address(std::move(address)) { + explicit OpenStreetMapProvider() { this->maxZoom = 19; } @@ -30,7 +29,7 @@ namespace threepp { const auto url = ss.str(); std::vector data; - std::string cacheFilePath = ".cache/openstreetmaps/" + std::to_string(zoom) + "_" + std::to_string(x) + "_" + std::to_string(y) + "." + format; + std::string cacheFilePath = cacheDir + std::to_string(zoom) + "_" + std::to_string(x) + "_" + std::to_string(y) + "." + format; if (std::filesystem::exists(cacheFilePath)) { // Load from cache file @@ -38,22 +37,21 @@ namespace threepp { data = std::vector((std::istreambuf_iterator(file)), std::istreambuf_iterator()); } else if (urlFetcher.fetch(url, data)) { // Save to cache file - std::filesystem::create_directories(".cache/openstreetmaps/"); + std::filesystem::create_directories(cacheDir); std::ofstream file(cacheFilePath, std::ios::binary); file.write(reinterpret_cast(data.data()), data.size()); } - return *loader.load(data, format == "png" ? 4 : 3, true); + return *loader.load(data, 4, true); } private: - std::string address; - std::string format = "png"; - ImageLoader loader; utils::UrlFetcher urlFetcher; - std::unordered_map> cache_{}; + std::string format{"png"}; + std::string cacheDir{".cache/openstreetmaps/"}; + std::string address{"https://a.tile.openstreetmap.org/"}; }; }// namespace threepp diff --git a/examples/projects/MapView/main.cpp b/examples/projects/MapView/main.cpp index 65b1742b..550b1cbc 100644 --- a/examples/projects/MapView/main.cpp +++ b/examples/projects/MapView/main.cpp @@ -3,6 +3,7 @@ #include "geo/MapView.hpp" #include "geo/providers/OpenStreetMapsProvider.hpp" +#include "geo/providers/BingMapsProvider.hpp" #include "geo/utils/UnitUtils.hpp" #include "geo/lod/LODRaycast.hpp" #include "geo/lod/LODRadial.hpp"