Silverlight Bing Maps: Draw Circle Around a Latitude/Longitude Location

SLBingMaps_DrawCircles Over 2 years ago I posted an example of how to draw circles on the Bing Maps JavaScript control. I thought it was about time to update that post to demonstrate how to do this using the Bing Maps Silverlight control. This is basically a C# port of the original JavaScript code.

Sometimes this can be really useful, but it isn’t built into the Sivleright Bing Maps Control. So you need to implement it yourself in order to do it. However, instead of writing from scratch, feel free to copy the code from this post.

Download Full Source: SLBingMaps_DrawCircle.zip

Here’s example usage:

// Draw circle at the location where the user clicked
private void Map_MouseClick(object sender, Microsoft.Maps.MapControl.MapMouseEventArgs e)
{
    // Get the location the mouse clicked
    var mousePoint = e.ViewportPoint;
    var clickedLocation = MainMap.ViewportPointToLocation(mousePoint);

    // Calculate the points to make up a circle with radius of 200 miles
    var locations = GeoCodeCalc.CreateCircle(clickedLocation, 200, DistanceMeasure.Miles);

    // Add Red Polyline to the Map
    var poly = new MapPolyline();
    poly.Locations = locations;
    poly.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
    poly.StrokeThickness = 2;
    MainMap.Children.Add(poly);            
}

And, here’s the code that calculates the location points to make up the circle:

/*
 * Written by Chris Pietschmann ()
 * This code is derived from the code posted in the following location:
 * /post/2010/03/02/Bing-Maps-JS-Calculate-Area-of-Circle-and-Draw-Circle-on-Map.aspx
*/
using System;
using System.Collections.Generic;
using Microsoft.Maps.MapControl;

namespace SLBingMaps_DrawCircle
{
    public enum DistanceMeasure
    {
        Miles,
        Kilometers
    }

    public class GeoCodeCalc
    {
        public const double EarthRadiusInMiles = 3956.0;
        public const double EarthRadiusInKilometers = 6367.0;

        public static double ToRadian(double degrees)
        {
            return degrees * (Math.PI / 180);
        }

        public static double ToDegrees(double radians)
        {
            return radians * (180 / Math.PI);
        }

        public static LocationCollection CreateCircle(Location center, double radius, DistanceMeasure units)
        {
            var earthRadius = (units == DistanceMeasure.Miles ? GeoCodeCalc.EarthRadiusInMiles : GeoCodeCalc.EarthRadiusInKilometers);
            var lat = ToRadian(center.Latitude); //radians
            var lng = ToRadian(center.Longitude); //radians
            var d = radius / earthRadius; // d = angular distance covered on earth's surface
            var locations = new LocationCollection();

            for (var x = 0; x <= 360; x++)
            {
                var brng = ToRadian(x);
                var latRadians = Math.Asin(Math.Sin(lat) * Math.Cos(d) + Math.Cos(lat) * Math.Sin(d) * Math.Cos(brng));
                var lngRadians = lng + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(lat), Math.Cos(d) - Math.Sin(lat) * Math.Sin(latRadians));

                locations.Add(new Location(ToDegrees(latRadians), ToDegrees(lngRadians)));
            }

            return locations;
        }
    }
}