Technology Blog

Archive for the ‘Uncategorized’ Category

Creating Striking Mapping Applications On Windows Phone 7 Using Bing Maps and CloudMade

Thursday, January 20th, 2011

After presenting at the Bing Maps User Group recently in which i discussed how to implement a custom mapping tile layer using the Deep Earth Silverlight control (http://deepearth.codeplex.com) and the Cloudmade mapping service (http://www.cloudmade.com) I began thinking about using this method to create a mapping application for Windows Phone 7 which more fits in with metro theme.

image

To begin with let’s have a look at the app we are going to build, as you can see the tiles being displayed are completely different to the standard Bing Maps tiles. Not only are you able to choose from thousands of pre-set map styles but you can also create your own too!

Ok lets kick off building this, to begin you are going to need to head off to the Bing Maps Portal to sign up and create yourself an application key. Once you have done this head off to CloudMade and create yourself a developer account. We are now in a position to actually write some code, create a new WP7 project and add a reference Microsoft.Phone.Controls.Maps.dll. We can now add some code to our MainPage.xaml as below.

Add two namespace statements to the top of the page:

xmlns:maps="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"

 

xmlns:core="clr-namespace:Microsoft.Phone.Controls.Maps.Core;assembly=Microsoft.Phone.Controls.Maps"

 

Then add a map control to the page also, setting the map mode as below:

 

<maps:Map CredentialsProvider="{Enter Your Bing Maps Key Here}"

 

VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1" Name="map1" >

 

    <maps:Map.Mode>

 

        <core:MercatorMode></core:MercatorMode>

 

    </maps:Map.Mode>

 

</maps:Map>

 

If you run the application at this point you will not see a great deal of anything, in effect what we have done is turn off the standard Bing Map tiles. We now need to create our custom tile provider to serve the tiles from CloudMade to our app using the code below:

public class CloudMadeTileSource : TileSource

 

{

 

    private const string _tilePath= "http://{S}.tile.cloudmade.com/{creds}/{style}/256/{Z}/{X}/{Y}.png";

 

    private readonly Random _rand = new Random();

 

    private readonly string[] TilePathPrefixes = new[] { "a", "b", "c" };

 

    public string CloudMadeCredentialsProvider { get; set; }

 

    public string CloudMadeMapStyleId { get; set; }

 

    public override Uri GetUri(int x, int y, int zoomLevel)

 

    {

 

        string url = string.Empty;

 

        string prefix = string.Empty;

 

        prefix = TilePathPrefixes[_rand.Next(3)];

 

        url = _tilePath;

 

        //Randomize to different OSM Servers based on URL prefix

 

        url = url.Replace("{creds}", CloudMadeCredentialsProvider);

 

        url = url.Replace("{style}", CloudMadeMapStyleId);

 

        url = url.Replace("{S}", prefix);

 

        url = url.Replace("{Z}", zoomLevel.ToString());

 

        url = url.Replace("{X}", x.ToString());

 

        url = url.Replace("{Y}", y.ToString());

 

        return new Uri(url);

 

    }

 

}

Here we are inheriting from the TileSource class and overiding the GetUri method which gives the mapping control the uri to the image file for a tile on the map. this is done by taking a URL which has placeholders for the important pieces of information the CloudMade system requires which is described very well on the CloudMade site. we also have properties for setting the CloudMade credentials and style id so these can be set in xaml.

We can now add a a reference to this class in our xaml as so:

xmlns:local="clr-namespace:StylisedMap"

 

Then add the TileSource to the map in our xaml:

 

<maps:Map CredentialsProvider="{Enter Your Bing Maps Key Here}"

 

    VerticalAlignment="Stretch" HorizontalAlignment="Stretch"

 

Grid.Row="1" Name="map1" >

 

    <maps:Map.Mode>

 

        <core:MercatorMode></core:MercatorMode>

 

    </maps:Map.Mode>

 

    <maps:MapTileLayer>

 

        <maps:MapTileLayer.TileSources>

 

            <local:CloudMadeTileSource

 

CloudMadeCredentialsProvider="{Enter Your CloudMade Key Here}"

 

CloudMadeMapStyleId="{Enter Your Chosen Map Style Id Here}" />

 

        </maps:MapTileLayer.TileSources>

 

    </maps:MapTileLayer>

 

</maps:Map>

If you now build and run the application you have a working Bing Map Windows Phone Application with custom map tiles. Enjoy!!

You can download the sample project here.

Uncharted Territory

Tuesday, December 14th, 2010

A recent ASP MVC 3 project has required us to create some simple charts. As it’s a .NET 4 project we hoped to use the lovely new charting controls provided by Microsoft. You can read all about them in Scott Guthrie’s blog here and as you can see they look very pretty and appear simple to implement.

NastyPieThat was the theory at least. There is a simple tutorial on how to use the controls in an MVC project here. The problem is that the output looks nothing like the charts in Scott Gu’s blog - far from it in fact with no fancy 3d effects and as a bonus nasty jpeg compression artefacts appear. While eliminating the compression artefacts is straightforward, (pass the write method a parameter of “.png”) gaining control of the styling is far more convoluted process.

The style of the charts is controlled by the chart.theme parameter, with only four themes available. None of them are terribly exciting and there are no obvious methods for customisation. So far so disappointing. Viewing the class definition in Visual Studio reveals that ChartTheme is a static class with each theme being a constant, declared as a string that appears to be XML mark-up. We wondered if it would be possible to extend this class, adding our own new themes along the way. Incredibly, it’s possible to do exactly that by creating a static partial class that mirrors the original with the exception of the tweaks we want to make to the XML.

Vanilla theme from ChartTheme

 public const string Vanilla = @"<Chart Palette=""SemiTransparent""
BorderColor=""#000"" BorderWidth=""2"" BorderlineDashStyle=""Solid"">
<ChartAreas>
    <ChartArea _Template_=""All"" Name=""Default"">
            <AxisX>
                <MinorGrid Enabled=""False"" />
                <MajorGrid Enabled=""False"" />
            </AxisX>
            <AxisY>
                <MajorGrid Enabled=""False"" />
                <MinorGrid Enabled=""False"" />
            </AxisY>
    </ChartArea>
</ChartAreas>
</Chart>";
Of course making those XML tweaks really isn’t easy – there’s a lot there and a trial and error process is always time consuming. Furthermore, guessing missing parameters hasn’t ever really worked well for me in the past and I don’t anticipate psychic coding to bear fruit in the future either.

At this point it seemed sensible to have another look at Scott Gu’s blog. It contains a sample project that demonstrates the features of the ASP.net chart controls. This gives us a way of generating the xml we need to theme our charts. It also has a sort of WYSIWYG editor for each chart so we can style the chart to our taste. The Chart class includes a SaveXml method that predictably saves the chart to an xml file. Inserting a call to this method generates the xml we need for our partial class.

Strip out all the data, leaving just the formatting information and there you have it – a chart theme you can reuse throughout your MVC project. Here is the code for a tasteful pie chart…

public const string JMW3D = @"

<Chart BackColor=""WhiteSmoke"" BackGradientStyle=""TopBottom""
BackSecondaryColor=""White"" BorderColor=""26, 59, 105""
BorderWidth=""2"">
  <Series>
    <Series ChartArea=""Default"" Font=""Trebuchet MS, 4.25pt,
style=Bold"" ChartType=""Pie""  Name=""Default""
Legend=""Default"" XValueType=""String"" YValueType=""Double""
Color=""220, 65, 140, 240"" BorderColor=""180, 26, 59, 105""
CustomProperties=""DoughnutRadius=60, PieLabelStyle=Disabled,
PieDrawingStyle=Concave"">
    </Series>
  </Series>
  <ChartAreas>
    <ChartArea Name=""Default"" BackColor=""Transparent""
BackSecondaryColor=""Transparent"" ShadowColor=""Transparent""
BorderColor=""64, 64, 64, 64"" BorderWidth=""0"">
      <AxisY LineColor=""64, 64, 64, 64"">
        <MajorGrid LineColor=""64, 64, 64, 64"" />
        <LabelStyle Font=""Trebuchet MS, 8.25pt, style=Bold"" />
      </AxisY>
      <AxisX LineColor=""64, 64, 64, 64"">
        <MajorGrid LineColor=""64, 64, 64, 64"" />
        <LabelStyle Font=""Trebuchet MS, 8.25pt, style=Bold"" />
      </AxisX>
      <Area3DStyle Rotation=""0"" />
    </ChartArea>
  </ChartAreas>
  <Legends>
    <Legend LegendStyle=""Table"" Name=""Default""
IsTextAutoFit=""true"" BackColor=""Transparent""
Font=""Trebuchet MS, 8.25pt, style=Bold"" Alignment=""Center""
Docking=""Bottom"">
    </Legend>
  </Legends>
  <Titles>
    <Title Font=""Arial, 10.25pt, style=Bold"" ForeColor=""black""
ShadowOffset=""0"" ShadowColor=""32, 0, 0, 0"" Name=""Title1"">
    </Title>
  </Titles>
  <BorderSkin SkinStyle=""None"" />
</Chart>";

NicePieAnd it’s results:

It’s admittedly one of the most round about methods I have used for doing, well anything. But it works. Feel free to download a sample project file containing a couple of examples in full.

Syndication

Links

Archives

May 2013
M T W T F S S
« Feb    
 12345
6789101112
13141516171819
20212223242526
2728293031  

Other