microsoft / MapsSDK-Unity

This repository contains samples, documentation, and supporting scripts for Maps SDK, a Microsoft Garage project.
MIT License
650 stars 128 forks source link

Displaying vector data #30

Closed keenanwoodall closed 8 months ago

keenanwoodall commented 4 years ago

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?

kircher1 commented 4 years 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).

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!

keenanwoodall commented 4 years ago

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

kircher1 commented 4 years ago

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.

keenanwoodall commented 4 years ago

Great, thanks!

kircher1 commented 4 years ago

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!

keenanwoodall commented 4 years ago

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 👍

YohanBaillot commented 3 years ago

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..com/{x}/{y}/{zoomlevel}, but what are the parameter to change with their corresponding value and what are the one to use as is? This is not made clear. Is the URL supposed to follow this exact format X/Y/Zoom or is the format hereunder (Zoom/X/Y) acceptable?

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!

YohanBaillot commented 3 years ago

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

mlathrop-bell commented 3 years ago

@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?

peterclemenko commented 3 years ago

I'd like to know where this is in the pipe as well

juvelez commented 2 years ago

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?

keenanwoodall commented 2 years ago

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.