28 May 2013

Workaround for selecting the last vertex of a Windows Phone MapPolyline

Fellow MVP - and fellow map maniac - Morten Nielsen brought me into contact with a Windows Phone developer called Jonathan Aghachi. He was struggling to select MapPolylines drawn on a Map using Map.GetMapElementsAt. For those not familiar with he concept of selecting stuff on a Wiindows Phone 8 map – you cannot select the shapes on the map directly like on Windows RT – they do not expose any events. In stead, you can trap the Tap event of the Map object, and retrieve all objects on that location like this:

private void Map_Tap(object sender, GestureEventArgs e)
{
  var selected = Map.GetMapElementsAt(e.GetPosition(Map));
}

selectbug

The problem

There is apparently a bug in Map.GetMapElementsAt when trying to select the line by using a point on the last vertex, i.e. that piece of the MapPolyline that runs between the 2nd to last point and the last point. If a MapPolyline has only one vertex (that is, only a start and an end point, with no points in between) you will not be able at all to select it using Map.GetMapElementsAt  This was exactly what Jonathan was experiencing. It can be clearly demonstrated by this very simple application, that looks like displayed on the right. It draws thee MapPolylines on the map, each with a different color. The Tap function of the map is a more extended version of the sample above and looks like displayed below:

 

private void Map_Tap(object sender, GestureEventArgs e)
{
  var selected = 
Map.GetMapElementsAt(e.GetPosition(Map)).FirstOrDefault() as MapPolyline; if (selected != null) { TitleText.Foreground = new SolidColorBrush( selected.StrokeColor); MessageBox.Show("MapPolyline selected"); } }

This should show the TitleText text (showing “MAPPOLYGON BUG") in the color of the selected MapPolyline, and show a message box as well. If you download the sample solution that goes with this post, you will notice:

  • You can tap on the red line as much as you want – but you will never get the message box
  • You can select the yellow line, but only if you tap on the horizontal part. The part that runs diagonally to the north-east will never get you a message box

The workaround

As you may have noticed, the green line, although it has only two points, can be selected by tapping on it. The reason for that is very simple – it does not have two points, but three. I have added the last point twice to the to the line, effectively creating a vertex of zero length. Then the first vertex isn’t the last anymore, and presto. See this little code excerpt:

var line1 = new MapPolyline();
line1.Path.Add(new GeoCoordinate(52.154346, 5.36974));
line1.Path.Add(new GeoCoordinate(52.154346, 5.411282));
line1.StrokeColor = Colors.Red;
line1.StrokeThickness = 10;
Map.MapElements.Add(line1);

var line3 = new MapPolyline();
line3.Path.Add(new GeoCoordinate(52.165509, 5.36974));
line3.Path.Add(new GeoCoordinate(52.165509, 5.411282));
line3.Path.Add(new GeoCoordinate(52.165509, 5.411282));
line3.StrokeColor = Colors.Green;
line3.StrokeThickness = 10;
Map.MapElements.Add(line3);

Some concluding remarks

My contacts at the Windows Phone team have confirmed this as a bug. I think this is very minor indeed, and using this simple work around makes circumventing it pretty easy. I know Jonathan is happily moving forward now with my workaround.

For the record: I actually wrote both code and blog post in Plön, in the north of Germany, during my holiday there. It was quite rainy that day, so what the heck ;-)

No comments: