Closed keenanwoodall closed 8 months ago
Hi @keenanwoodall, thanks for checking out the SDK!
For now, using the HttpTextureTileLayer is a good solution since you can pull down pre-rasterized tiles to convey the vector data. Although quality-wise, I understand a raster tile approach is not nearly as ideal as rendering the vectors directly.
Broadly speaking, the SDK should have some support for rendering primitives like lines and polygons in the future. Having support for this would go a long ways to help lay the groundwork for rendering vector data-- No specific time line for this, but it is on our roadmap!
In the meantime, if you want to attempt to read certain types of primitives out of a vector data tile, you may be able to get fairly far using the MapPin system. This system allows you to anchor arbitrary Unity GameObjects to the map at a specified lat-lon, and it automatically enables or disables the pin when it is inside or outside the map's view. This MapPin system also handles resampling the elevations of these objects to keep them pinned at an altitude offset relative to the surface of the terrain, which would be especially useful if the vector data you are reading does not contain altitude values. (If you are using flat-mode for the map, i.e. no terrain elevations or 3D cities, this is a non-issue).
For point-based vector data, converting to these MapPins (I'm thinking like city labels, business locations, icons, etc) would be fairly straight forward. Leveraging components like TextMeshPro would be a great way to get clean text rendering. Rendering 2D icons with this system should also be quite straight forward.
Lines (for streets, highways, routes etc) would be a bit more tricky with the MapPin system although doable. You could create a pin for each point in the line and periodically update the vertices of the line based on the pins sample altitudes.
For polygonal vector data, I don't have a good suggestion. It would probably be quite a bit of work, but in theory, you could implement a custom TextureTileLayer that rasterizes polygons to 2D textures on the fly. You could use Unity render textures although I'm not sure how efficient or simple it would be since it would require triangulating the data. Ideally this would be leveraging some sort of 2D rasterization library (like D2D).
In any case, perf may become an issue if the vector data is especially dense.
Note there are also extension methods on the MapRenderer to transform LatLons and Mercator coordinates to 3D world or local space positions for the current map view. This would be useful if you are working outside of the MapPin system, but it won't help manage the task of adjusting elevations of objects you want to pin to the map, for that, you would have to use a MapPin. Again though, elevation sampling is non-issue if you are using flat-mode.
That's a lot, but hopefully points you in the right direction!
Thanks a bunch for the quick response and in-depth writeup. This gives me a lot of things to try out!
I think it would help a lot if there was a way to register some interface whose methods get called when tiles are loaded, destroyed, hidden or shown (I'm assuming those are a tiles different states.) This would make it easier to load and display arbitrary data, like vector tiles.
Unless I'm missing something, there isn't even a way to get the map renderer's current list of tiles? I see there's a Bounds
property, but I'm not sure how to calculate a list of "x/y/zoomLevels" from it.
I'm sure I don't know the best way to structure a system like this, but being able to create custom tile handlers would be pretty great
Yeah, that's a good point. Having generic events for tiles coming in and out of view would make building a system like this easier.
There are however helper methods in the Microsoft.Geospatial namespace that can be used to compute the tiles that are currently in the map's view. See GetCoveredTileIds. Pass this method the Bounds of the MapRenderer and a TileLevelOfDetail derived from the MapRenderer's ZoomLevel (just round zoom level to nearest short).
Then you should be able to recompute the tiles that are in view as part of some script's Update method and fire off events accordingly. Note, recomputing covered tiles actually only needs to be done when the Center/ZoomLevel or MapDimension changes.
Great, thanks!
Another option you may be interested in is the Bing Maps imagery API. This service does allow for custom map styling. The Map Style Sheet Editor app is a great tool to interactively build the style sheets needed for these requests.
I also suggest checking the terms of this SDK or any other service that you may be using for sourcing vector data or imagery. I'm not in a position to say if it applies to your case, but there could be clauses that disallow for using another providers data within another mapping service. For this SDK, the Bing Maps terms are currently here. There's a contact page here which can be used to follow up with licensing questions!
Oh great, I evidently didn't look into the style API enough. I didn't know there was an editor for it! Also thanks for giving me a heads up about a potential licensing conflict with other map providers, I'll make sure to look into it 👍
I have a question not directly related to the original request but that people here seem to be clear about so please let me know if you have any suggestion. We want to add raster and vector layers to our map. We see there is a TextureTileLayer component that we can add to the map, but the documentation is fuzzy about what this address looks like without a concrete example
The documentation for TextureTileLayer (https://github.com/microsoft/MapsSDK-Unity/wiki/TextureTileLayer) is saying to use a URL with this placeholder http://www.
This page https://docs.microsoft.com/en-us/bingmaps/v8-web-control/map-control-concepts/layers/x-y-zoom-tilelayer related to the native Bing map seems to suggest that the address https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/{zoom}/{x}/{y}.png could be such a formatted address but entering this, or without the .png at end of even replacing zoom
Same on this page with Quadkey, seems that URL does not work either https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk/tilelayerquadkey
All of these attempt are returning 505 or 404 and no tile is displayed or an exclamation mark
It would be really useful to have at least one simple URL as a reference so we know what the URL should look like
Does anyone has an any suggestion? Thanks!
I believe I figure it out, one example that works is https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/{zoomLevel}/{x}/{y}, so the same format as on this sample page for the JS API, but replacing zoom by zoomLevel, and leave those parameters (zoomLevel, x, y) exactly as is. This is not really straightforward for people not working with maps tiles and should be clarified
@kircher1 I just wanted to follow up on this feature request. Did a system for rendering 2D Vector data (such as GeoJSON) ever get implemented? Or at least something that allows drawing polygons?
I'd like to know where this is in the pipe as well
Another option you may be interested in is the Bing Maps imagery API. This service does allow for custom map styling. The Map Style Sheet Editor app is a great tool to interactively build the style sheets needed for these requests.
I also suggest checking the terms of this SDK or any other service that you may be using for sourcing vector data or imagery. I'm not in a position to say if it applies to your case, but there could be clauses that disallow for using another providers data within another mapping service. For this SDK, the Bing Maps terms are currently here. There's a contact page here which can be used to follow up with licensing questions!
@kircher1 I am just starting to study this Bing SDK for Unity and what I am looking for is precisely the styling workflow, to use custom colors, you mention the Bing Maps Imagery API, but how can be used within Unity SDK?
@keenanwoodall you mention you are using Mapbox to perform custom styling, you could give us a clue about how you are achieving that?
I don't have access to the project anymore, but services like Mapbox will provide a url you can configure with and x, y and zoom level. At that url you can get a raster tile. Example here The Http Texture Tile Layer lets you supply a url format where it will download tile textures from. You simply need to provide a url that points at the server that hosts the tiles.
First off I want to say thanks for making such a polished product. This is miles better than every other mapping solution I've tried. The editor controls are great and the API is very clean. Great work 👍
I'm using an Http Texture Tile Layer to display custom tiles styled in Mapbox and am curious if there'd be a way to make a custom Tile Layer for displaying vector data.
I'm assuming a custom tile layer is the best approach, but am open to anything.
[edit] To clarify - while having a vector data layer built into the sdk would be great I understand that's a big ask, so that's not really what I'm requesting. If I were to develop a system for parsing and drawing vector tiles, where would be the best place in the sdk to hook in?