Bing blogs

This is a place devoted to giving you deeper insight
into the news, trends, people and technology behind Bing.

Bing Developer blog

June
07

Writing Your First Bing Map 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

Ben Lemmon – Bing Maps Developer

 

 

Comments

  • Is there any tutorials on how to start an app I see there are many people who know apps but I would not where to start.

  • Much too complicated an example

  • Nice. Great about Bing Maps :)

    I'll try it right now

  • Nice

    I'll try it right now

    <a href="http://www.essaywritingservices.co.uk">Essay Writing Services</a>

  • articles are very interesting for me, I hope always to get the information from this web, so making new knowledge, thanks be to provide information, become more attractive. hopefully always update to the article http://www.cahayameubel.com/

  • thanks, I'll try it ...

  • I really like this blog and the articles are very interesting for me, but everything is in English haha.

    Thank you very much.

    http://www.dankogames.com

  • articles are very interesting for me, I hope always to get the information from this web, so making new knowledge

    <a href="www.furnitureduco.com/">Furniture Duco</a>

  • http://www.furnitureduco.com/ terima kasih atas infonya

  • www.thienthanmaytinh.com