pelicanmapping / rocky

3D Geospatial SDK (C++17 / Vulkan / VSG)
MIT License
91 stars 15 forks source link

Add support for Bing and Azure maps #50

Closed AnyOldName3 closed 1 month ago

AnyOldName3 commented 1 month ago

I've split this PR into four commits of varying controversy.

The first two are fixes, and fairly straightforward. Not having them will inevitably lead to problems with something else later as they're not specific to the Bing/Azure stuff.

The next one is the one that actually adds Bing and Azure support. The Azure part's straightforward as the tile interface is simple, but it doesn't support elevation and satellite and aerial photography isn't available in the free tier, so even though it's deprecated, I also added Bing support. The specifics of that take some inspiration from the equivalent in osgEarth, e.g. getting the specific tile URL via the metadata API and caching the URL, but again it's pretty straightforward.

The final commit might be clever, a hack, or both, but it helps a lot to avoid the API rate limiting with Bing Maps and to reduce the number of redundant fetches, while also avoiding #47 even if you do still manage to hit a limit. There's more of a description in the commit message but the gist is that it uses weak_ptrs to track which source images are still referenced, and a vector of shared_ptrs in tiles produced by assembleImage to ensure that the source tiles that make up the composite image are kept alive. I think it's fine for a temporary solution, but it might not be what ends up used forever.

AnyOldName3 commented 1 month ago

I've determined that even with the mitigations I've put in place, it's still easy to get rate limited for Bing Maps if you're looking at LOD 19 or 20 just from loading the scene without any panning. Part of this is due to a limitation in the thing I implemented - as I didn't do anything to stop two tiles on two threads requesting the same data at once (and only ensure only one of the results would actually get used) some duplicate requests get through, which will count towards the quota. However, it's also partially because of Rocky's strategy for fetching tiles. Every lower-quality LOD level than the required one will get a corresponding assembleImage call, and they'll fetch all the source images that overlap the tile, even though it might only be a tiny corner of the tile that actually overlaps the screen, so as few as one source image per LOD level might genuinely be necessary. Finally, there's the simple issue that once there are multiple tiles on the screen, I'm under the impression that Rocky considers starting to load a tile once its parent is loaded, so over time, more tiles become eligible to be loaded at once after you're past the threshold where tiles stop covering the whole screen.

ComradeMashkov commented 1 month ago

Looks awesome! It would be great if you write a simple example of how to use Bing & Azure API in Rocky for such newbies as me :)

gwaldron commented 1 month ago

Thanks Chris. These all look good, and I agree that your weak_ptr solution is good enough for now even if we decide to change it later.