Software solutions for a mobile world

I have just written a new application for Windows Phone 8, called APPA Photo Navigator. The app allows you to browse your photo albums, select a photograph and get EXIF info about the photograph, and position one, many or all of your photographs on the map. There are a couple of similar apps out there (surprise, surprise), but none appeared to be tailored for Windows Phone 8.

My first hurdle was the EXIF information, but this article from Igor Ralić and this one from Tim Heuer came to my rescue. So, we could now browse and choose albums, browse and choose photos, and display EXIF information about the.

Next step - add mapping, plot the images on the map, and allow route planning. This wasn't seen as a problem, as APPA Traffic uses Nokia Maps for displaying traffic incidents, and APPA FSA Food Hygiene plots locations and does route planning.

However, both these apps just use polygons as markers. Anyone who had used mapping in WP7 knows that you can use custom pushpins and plot them on the map. The excellent Windows Phone Toolkit supports map extensions, but I wasn't able to get it to display images. I did lots of searching, all types of experimentation, but couldn't get the images to display. From one of my twitter colleagues came a suggestion of using a user control, and I decided to try this out.

I added a user control to the project, and then dropped into Blend to design the control. I thought of an image with an arrow pointing, so looking in Blend, the callout looked just the part. So first of all I added a callout:-

Then I added an image in the callout rectangle:-


I saved this and went back to my project. The resulting XAML is:-

<Grid x:Name="LayoutRoot" Margin="0,0,0,0" Width="128" Height="144">
        <edc:Callout AnchorPoint="0,1.3" CalloutStyle="RoundedRectangle" FontSize="14.666999816894531" 
="Left" Height="100" Margin="0,10,0,0" Stroke="Blue" VerticalAlignment="Top" 
="128" RenderTransformOrigin="0.508,0.05" Fill="#FF2765A0">             <Image Height="96" Width="118"  x:Name="imgPhoto" RenderTransformOrigin="0.516,0.146" VerticalAlignment="Top" Margin="0,6"/>         

I kept the ratio for the photograph the same, so it wouldn't look odd. So now the control was done, I turned my attention to the code. Most of the code was already done, including several attempts to get the picture to display. So it was just a matter of setting a new instance of our NokiaPushPin, setting the image source, geocode and adding it to the mapping layer.

     MapOverlay overlaypp = new MapOverlay();     
     NokiaPushPin npp = new NokiaPushPin();     
     npp.imgPhoto.Source = img;     
     npp.Tag = new GeoCoordinate(coordinate.Latitude, coordinate.Longitude);     
     overlaypp.GeoCoordinate = new GeoCoordinate(coordinate.Latitude, coordinate.Longitude);     
     overlaypp.Content = npp;     
     npp.DoubleTap += npp_DoubleTap;     
     overlaypp.PositionOrigin = new Point(0, .3);     


The 'img' above is a BitMapImage passed to the routine. I decided to use a double-tap on the pushpin so that it didn't get confused using pinch and zoom, and to use the Tag property to hold the co-ordinates so I could retrieve them in the double-tap procedure.

  void npp_DoubleTap(object sender, GestureEventArgs e)
                NokiaPushPin npp = (NokiaPushPin)sender;
                GeoCoordinate geoCoordinate = (GeoCoordinate)npp.Tag;
                Geolocator geolocator = new Geolocator();
                MyDestinationCoordinate = (GeoCoordinate) npp.Tag;


The result of plotting the above is shown below. Because 'landmarks' are currently set to 'on', the colosseum shows up nicely on the map. The picture was taken from a bar facing the colosseum :) 

 There may be other ways of skinning this particular cat, but I think this is a neat customisable solution.

Originally posted 10/Feb/2013


M: +44 (0)7860 907493




Twitter Feed