28 April 2015

Windows 10 build 10061 fixes MapIcon woes!

I discovered this while preparing for my Techdays 2015 talk and you probably have to be a mapping nut like me to appreciate this fully, but some things cannot wait until my session itself, so here’s this thing I found out while pressed a dot after a MapIcon type variable after having upgraded to Windows 10 build 10061.

Windows Phone 8.1 brought an awesome new map control that introduced the concept of MapIcon. Previously, if you had to draw point objects on a map depicted by an image, you had to resort to drawing XAML elements on top of the map. While the map itself took care of the position of the icon, behind the scenes it was not the map, but the UI thread taking care of drawing the icons, which is quite resource-heavy as anyone who has tried to draw a lot of points on a Windows Phone map will acknowledge. This resulted also in the icons lagging visibly behind when you change position, something you (unfortunately) can see very good when you use my Sensorcore app Travalyzer.

Enter Windows Phone 8.1, that as I said introduced the MapIcon – an icon with optional label type of object that is drawn by the map, that does not lag behind…. and was, for all but a few limited scenarios, not really useful for real world use, for two reasons,

First of all, it sported a bug, making it ignore the Z-index.If you used any other shapes on the same map (lines or polygons) they always appear over the icons, effectively blocking them from view. This is not what you want in a GIS application.

What was even worse was the ‘best effort drawing feature’. To optimize performance, the map component opted to omit drawing MapIcons on ‘collision’, that is, when a lot of them were drawn too close together. This had the unfortunate side effect of icons popping in and out of existence when you zoomed or panned, you had no control which icons appeared (or not) and to make matters worse, if you checked for the presence of a MapIcon by using FindMapElementsAtOffset it returned nothing, even if you actually had put the icon on the map.

Both of these issues have been fixed.The most major fix is the addition of the property CollisionBehaviorDesired property to the MapIcon, which is an enumeration:

namespace Windows.UI.Xaml.Controls.Maps
{
  [ContractVersion(typeof(UniversalApiContract), 65536)]
  [WebHostHidden]
  public enum MapElementCollisionBehavior
  {
    HideOnCollision = 0,

    ShowOnCollision = 1
  }
}

By simply setting the CollisionBehaviorDesired property of every icon MapElementCollisionBehavior.ShowOnCollision the icon is always displayed.

The difference is quite clear:

map1Map-2

Then I wondered “well have they maybe fixed the Z-index issue too?”, and lo and behold the icon is clearly drawn on top of the fat bluish line:

map-3

The CollisionBehaviorDesired property will probably come with a performance hit, but mapping fans will most likely agree these changes make MapIcon now very much usable in broader scenarios.

Update May 1st, 2015: the enumeration has been slightly changed as of build 10074. Now it's

namespace Windows.UI.Xaml.Controls.Maps
{
  [ContractVersion(typeof(UniversalApiContract), 65536)]
  [WebHostHidden]
  public enum MapElementCollisionBehavior
  {
    Hide = 0,
    RemainVisible = 1
  }
}

No comments: