10 October 2015

Windows 10 maps part 6 - scenes and camera

Intro
Picking up the thread where I left it rushing into an IoT series, which I wanted to have ready before the Microsoft devices event that took place on October 6th, I will now write bit about scenes and camera. These are features that are part are designed to work with the new 3D view, that already made an appearance in the previous part of this series.

The problem
Maps in were always 2D previously. You can play with the pitch and show landmarks on it, and that gets a bit of a 3D effect, but the map itself is still flat, and the view on your map is orthogonal (that is, straight from above), like you are holding a paper map. Only the zoom level (i.e. the distance from your eye to the map) and the point directly below you (the map center) determined what you look at. This approach no longer works when you use a 3D map like Windows 10 features. Now, you are basically floating in space next to a sphere (Earth, to be specific) and you can look in any direction you want - directly below the point you are floating next to (or above, whatever) but you can also look sideways, to the 'top' of the sphere, or even from it. You can rotate so South is up. So although the point directly below you and the distance between ('height') are still a factor in what you can see, they are no longer the only factor.

To illustrate what I mean, I can best show a few pictures. First, here we have Earth, and we are floating directly over the Netherlands. Basically, there's not much different from a normal orthogonal map, although this shows a bit of the curve of the Earth

image

Now let's play a little with the controls:

  • First I changed the pitch using the canvas (the controls on the right of the map, the 2nd one from above)
  • Then I rotated about 180 degrees using the top canvas control

You get a totally different view now!

image

Space, the final frontier ;) .

The solution
We need a new helper class, something that helps us create a view given a number of parameters. And luckily, Microsoft have provided not one but actually two: MapCamera and MapScene.

My demo solution actually does very little with both: the save scene button saves the current way you are looking at the map (Earth), and Restore brings you back to it.

private MapScene lastScene;

private void SaveScene(object sender, RoutedEventArgs e)
{
  lastScene = MapScene.CreateFromCamera(MyMap.ActualCamera);
}

private void RestoreScene(object sender, RoutedEventArgs e)
{
  if (lastScene != null)
  {
    MyMap.TrySetSceneAsync(lastScene);
  }
}
MyMap.TrySetSceneAsync is actually async so it could be awaited, but since this is a simple fire-and-forget method I can't be bothered with that.

If we put a breakpoint in SaveScene we can see the MapCamera's values

image

And it's location

image

So apparently I am looking almost due South (Heading 181), from a location that about 1600km above a point that is a bit west and a whole lot more north than the Netherlands (latitude and longitude for the center of our tiny spec by the sea is about 52, 5), pitched upward almost 40°, and rolled a wee bit to the right. My app does not support setting all camera features, but you if you set a breakpoint on SaveScene and change the roll value to 90 before you let it continue, you will get this effect on hitting restore - and you can imagine looking out of a forward-looking window of your spaceship in orbit - that is presumably in some pretty unlikely polar orbit considering the direction it's travelling into

image

The properties of the MapCamera are all excellently explained here in the official documentation and there's also a very good picture illustrating what I mean with 'floating next to a sphere and lookup down on it'

Now Microsoft have recognized the fact that not everyone is a spatial expert and that it may indeed be very hard to create a view in a 3D map that shows all what you want using just the camera, especially when there are blocking features. That's where the MapScene class comes into place. As you may already have noticed, the Map's Camera itself is read only, you can only use the camera to create a Scene from, then put it back to a map.

The intent though is that you create a Scene using one of the static methods the class provides. There is a method to create a camera from a bounding box, optionally specifying a heading an a pitch, a method to create one from a location and a radius, but the best I like is the one that makes sure any number of points in a list will show up. This is a great feature to show all your initial points in your 3D map app - for instance, all flying airplanes in 3D within the target area of your map.

Conclusion
Lots of talk this time, little code. MapCamera and (especially) MapScene make programmatically navigating around a map a lot easier, but it still take some experimenting to check if you get desired results. For me, having grown up in a world of 2D maps and having worked in 2D GIS for 20+ years, it's just as hard as you ;)

No comments: