Bing Map App Development Resources

As part of the King of Bing Maps contest, I wanted to share some resources available to help you rise to the crown.

First, download the SDK from Microsoft Connect. Bring it down into Visual Studio 2010 and ensure you have Silverlight 4 installed.

Second, King of Bing MapsBen Lemmon, Bing Maps Developer, posted a code sample on the Bing Developer Blog outlining how to create a map app illustrating where the planets in our solar system are at any given time. This is a great tutorial for getting started with writing your first Bing Map App (below). You can access the full solution from this link.

Next, if you have a KML file hosted somewhere on the web, you can import that KML file, wrap it up and call it a Bing Map App. Remember, content is king…if you want to be king. You do this via the Bing Maps Portal (this is also where you submit your application).

There’s also a template application in the SDK. So, check that out once you download the SDK from Microsoft Connect.

Within the Bing Community we created the Bing Map App developers forum. You’ll want to go there to ask questions of the community. Plus, we’re monitoring the Bing Map App forums for comments, questions and clarifications so if someone in the community doesn’t answer your questions one of us will.

Finally, check out the video Earthware created which provides a useful overview of Bing Map Apps, how apps are created and submission guidelines.

BingMapsResources_0

Developing Bing Map Apps – Overview from Brian Norman on Vimeo.

/////////////////

//Ben Lemmon’s Planet Tracker App

////////////////

With the Bing Maps Apps SDK just released, it’s time to get started writing apps using the Bing Maps platform. The first thing you need is something to map. I wanted to do something a little more interesting than your typical "Hello World!" app, so I chose to map the locations of the planets relative to the earth. The necessary calculations are taken care of by the CodePlex project AAPlus. To get started, download the AAPlus code from CodePlex, and compile it against the Silverlight runtime, or use the DLL included in the attached source project. After you have that ready, you should set up your solution by following the steps in this post.

Now that you’re set up and ready to go, let’s get to coding! We’ll start by making a class that extends Microsoft.Maps.Plugins.Plugin. The Plugin class is used to import and export functionality needed, and it also acts as the entry point for your app. We will need to use several contracts provided by the SDK. To get a reference to those contracts, simple create public properties on your plugin class, and decorate them with an ImportSingleAttribute, and the name of the contact to import. For this sample, we will add the following properties to import the desired functionality.

/// <summary>

/// Import the LayerManagerContract so we can add the AstronomyLayer upon activation

/// </summary>

[ImportSingle(“Microsoft/LayerManagerContract”, ImportLoadPolicy.Synchronous)]

public LayerManagerContract LayerManagerContract { get; set; }

/// <summary>

/// Import the PushpinFactoryContract so we can add standard pushpins to the map

/// </summary>

[ImportSingle(“Microsoft/PushpinFactoryContract”, ImportLoadPolicy.Synchronous)]

public PushpinFactoryContract PushpinFactoryContract { get; set; }

/// <summary>

/// Import the PopupContract so we can register each entity to show a popup on hover

/// </summary>

[ImportSingle(“Microsoft/PopupContract”, ImportLoadPolicy.Synchronous)]

public PopupContract PopupContract { get; set; }

/// <summary>

/// Import the map contract so we can zoom out to world view upon activation

/// </summary>

[ImportSingle(“Microsoft/MapContract”, ImportLoadPolicy.Synchronous)]

public MapContract MapContract { get; set; }

These properties will automatically be set before Initialize is called. In Initialize, we just want to set up our primary layer. A layer is what allows you to add items to the map, and show UI in the left pane. A plugin can have multiple layers, but it’s more common to just have one layer per plugin, which is the case here. Since there will only ever be one layer, we set it up in our Initialize method.

// The singleton layer that contains each of the AstronomyEntities

private AstronomyLayer _layer;

/// <summary>

/// Called after all the imports are populated

/// </summary>

public override void Initialize()

{

base.Initialize();

_layer = new AstronomyLayer(this);

}

Activate can be thought of as one of the entry points to your application. The other entry point is layer deserialization via permalinks, but I won’t cover that in this post. In the Activate method, we want to add our layer or bring it to the front. This is done by using the LayerManagerContract which we previously imported. We also set the map view using the MapContract to show the entire world.

/// <summary>

/// Called when the user launches the application

/// Either add the AstronomyLayer or bring it to the front, then zoom out so the entire world is visible.

/// </summary>

public override void Activate(IDictionary<string, string> activationParameters)

{

base.Activate(activationParameters);

if (LayerManagerContract.ContainsLayer(_layer))

{

LayerManagerContract.BringToFront(_layer);

}

else

{

LayerManagerContract.AddLayer(_layer);

}

// The the view to show the whole world

MapContract.SetView(new LocationRect(90, -180, -90, 180));

}

We now need to provide an implementation of AstronomyLayer which will add each planet to the layer, and update their positions based on the simulated time.

// Add each planet to the list of enties

// Each entity in this.Entites will be rendered by Entity.Primitive on the map.

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Mercury, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Venus, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Mars, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Jupiter, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Saturn, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Uranus, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Neptune, plugin.PushpinFactoryContract));

this.Entities.Add(new AstronomyEntity(Elliptical.EllipticalObject.Pluto, plugin.PushpinFactoryContract));

An entity on a layer is a point of interest, business, location, region or other item that you want to place on the map surface. We create a custom entity class called AstronomyEntity which holds information about which planet the entity represents, and calls the AAPluss library to find the location of the planet at a given time.

/// <summary>

/// Represents a planet we are tracking on the map

/// </summary>

public class AstronomyEntity : Entity

{

/// <summary>

/// The planet enum value

/// </summary>

private Elliptical.EllipticalObject _ellipticalObject;

/// <summary>

/// Creates a new AstronomyEntity

/// </summary>

/// <param name=”ellipticalObject”>The planet to track</param>

/// <param name=”pushpinFactory”>The PushpinFactoryContract used to create pushpins</param>

public AstronomyEntity(Elliptical.EllipticalObject ellipticalObject, PushpinFactoryContract pushpinFactory)

{

_ellipticalObject = ellipticalObject;

// Create a pushpin with the first letter of the planet name in it

// Setting the primitive is what will give the entity a visual representation

// We can use the default constructor on Location, because we just replace the location as soon as UpdateLocation is called.

Primitive = pushpinFactory.CreateStandardPushpin(new Location(), _ellipticalObject.ToString().Substring(0, 1));

// Set the entity’s name to show in the popup

Name = _ellipticalObject.ToString();

}

/// <summary>

/// Updates the location of the entity to match where the planet would be at a given julian day.

/// </summary>

/// <param name=”julianDay”>The julian day</param>

public void UpdateLocation(double julianDay)

{

EllipticalPlanetaryDetails details = Elliptical.Calculate(julianDay, _ellipticalObject);

((PointPrimitive)Primitive).Location = new Location(details.ApparentGeocentricLatitude, details.ApparentGeocentricLongitude);

}

/// <summary>

/// The name of the planet

/// </summary>

public string Name { get; private set; }

}

In our AstronomyEntityClass we set the Primitive to a PointPrimitive which is generated using the PushpinFactoryContract we imported. In UpdateLocation, we set the PointPrimitive’s location to the position of the planet at the given time. Now we just need to call UpdateLocation to get the planets to their correct location. We add the following line to the AstronomyLayer’s constructor:

// Initialize the planet locations to their position today

DisplayDate = DateTime.Now;

Then add the display date property that converts the DateTime to a Julian day, and updates each AstronomyEntity’s location.

/// <summary>

/// The current date that the planets are positioned to.

/// </summary>

public DateTime DisplayDate

{

get { return _displayDate; }

set

{

_displayDate = value;

DateTime utcDate = _displayDate.ToUniversalTime();

Date date = new Date(utcDate.Year, utcDate.Month, utcDate.Day, true);

double julianDay = date.Julian();

foreach (AstronomyEntity entity in this.Entities)

{

entity.UpdateLocation(julianDay);

}

}

}

We now have enough code to get some pins on the map. Go ahead and try your plugin out and you’ll see the planets placed on the map surface near the equator!

I’ve added a few more features (noted below) to the attached sample. Download it and try it out, then try extending it further or writing your own app.

  • Animating the DisplayDate so you can watch the planets follow their path over the earth
  • Showing popups over the pushpins so you can tell the difference between Mercury and Mars
  • Showing custom UI in the left panel

Follow me @BingMaps, ^CP

Join the conversation

3 comments
  1. sashaeve

    >> if you have a KML file hosted somewhere on the web, you can import that KML file, wrap it up and call it a Bing Map App.

    Any example of how to do it?

  2. Lowry

    Thank you for update.

Comments are closed.