MultiPolygon & MultiLineString Classes for Bing Maps Silverlight

Update: Check out the optimized version of this library available here.

When SQL 2008 came out one of the major features that a lot of us GIS people were looking forward to was the spatial tools. These tools were going to make managing and storing our mapping data easier. As true is this is, there has been one common stumbling block (ok, maybe more than one). The Bing Map AJAX and Silverlight controls support Pushpin, Polyline, and Polygon shapes, but there is no built in support for MutliLineStrings/MultiPolylines, MultiPolygons, MultiPoints, or GeometryCollections. For the AJAX control I came up with two solutions to help deal with this issue: MultiShapes and Virtual Earth, Advance Polygon Shapes in Virtual Earth.

When the CTP version of the Silverlight control came out Hugh Sallmans wrote an article that incorporated the ideas I used for the AJAX control into the Silverlight control. Recently I tried to implement the code and soon realized that some of the features that this code used from the CTP version didn’t make it into the final release. What’s a guy to do?

So I decided to try and make an updated version from scratch, but where to start?

After some brain storming and research I came up with a few ideas:

  1. Create a class that manages a list of shapes and their relationships with other shapes. This worked alright but wasn’t that easy to implement and required a lot of additional work to add shapes.
  2. Create a generic class that wraps a collection of MapBaseShape classes that the MapPolygons and MapPolylines inherit. This worked some what but again wasn’t easy to implement.
  3. Create an image in Silverlight and draw my shape on it similar to what was done here and then make it a scalable element. This approached requires doing a bunch of math. As much as I like doing math I knew that going with this approach meant that I would only be able to display the shape and would not be able to interact with it. This may be useful when displaying shapes that have a lot of points. I may come back to this in the near future.
  4. Create Silverlight shapes such as Line, Polygon and Path, calculate their bounding box and add them directly to a map layer. This worked for the simple shapes but when I used a Path I found out that this type of shape doesn’t scale, which was unfortunate as it makes for a nice way for creating polygons. Especially since overlapping polygons that were from the same path automatically created holes for you. https://msdn.microsoft.com/en-us/library/cc189068%28VS.95%29.aspx
  5. Take a closer look at the underlying architecture of the Bing Map Silverlight control and mimic what Microsoft does to create the MapPolygon class. This took a bit of time and a lot of digging through the assemblies. I ended up taking the MapBaseShape class and creating a modified version of it for handling multiple LocationCollections of points. I then created a MapMultiPolygon and MapMultiPolyline classes which use the Silverlight Path shape to create the polygons. Rather than create a Locations property for these shapes like the MapPolygon and MapPolyline shapes have I decided to create a Vertices property which is a List of LocationColloections as this made more sense. In the end this made for a much smoother implementation. Creating these shapes and adding them to the map is not much different than what you would do when creating a MapPolygon.

So after coming up with an idea that worked I put together a Silverlight Class Library that contains the MultiMapShapeBase, MultiPolygon, and MultiPolyline classes. You can either add the project to your solution or compile it and reference in the assembly. I’ve also put together a simple sample application that shows how to add a MultiPolygon and a MultiPolyline.

Here is a simple code snippet of how to add a MultiPolygon:

//Create a MapMutliPolygon object MapMultiPolygon myPoly = new MapMultiPolygon();

//Define the polygon rings myPoly.Vertices = points;   //Where points is a List<LocationCollection> object

//Set the fill and stroke color myPoly.Fill = new SolidColorBrush(Color.FromArgb(150, 0, 255, 0)); myPoly.Stroke = new SolidColorBrush(Color.FromArgb(150, 0, 0, 255));

//Add MultiPolygon to map layer myLayer.Children.Add(myPoly);

You can  find the source code and sample application here: https://cid-e7dba9a4bfd458c5.skydrive.live.com/self.aspx/VE%20Sample%20code/BingSLMultiShapes.zip

image