Scott Ferguson
Scott Ferguson

Reputation: 7830

How to attach a label to a Bing Maps MapPolygon?

I'm using a Silverlight Bing Maps Control, and have defined a number of MapPolygon areas as children to the map control. What I want ideally, is the ability to add a TextBlock label to the center of the interior of the MapPolygon.

How should I go about doing this?

Upvotes: 1

Views: 2101

Answers (1)

schummbo
schummbo

Reputation: 900

If you only need an approximate center of the polygon, you can find the center of its bounding box and programatically add a TextBlock over the polygon.

So something like this might work:

(XAML)

    <MapControl:Map x:Name="MyMap">
        <MapControl:Map.Children>
            <MapControl:MapPolygon Fill="Red" Stroke="Yellow" StrokeThickness="5" Opacity="0.7">
                <MapControl:MapPolygon.Locations>
                    <m:LocationCollection>
                        <m:Location>20, -20</m:Location>
                        <m:Location>20, 20</m:Location>
                        <m:Location>-20, 20</m:Location>
                        <m:Location>-20, -20</m:Location>
                    </m:LocationCollection>
                </MapControl:MapPolygon.Locations>
            </MapControl:MapPolygon>
        </MapControl:Map.Children>
    </MapControl:Map>

(Codebehind)

     public partial class MainPage : UserControl
{
    private MapLayer tbLayer;

    public MainPage()
    {
        InitializeComponent();

        tbLayer = new MapLayer();

        List<TextBlock> newTbs = new List<TextBlock>();

        // loop through the maps children and find the polygons
        foreach (var child in MyMap.Children)
        {
            if (child is MapPolygon)
            {
                var poly = child as MapPolygon;

                // get the average lat and long to calculate the "center"-ish of the polygon
                var avgLat = poly.Locations.Select(l => l.Latitude).Average();
                var avgLon = poly.Locations.Select(l => l.Longitude).Average();

                TextBlock tb = new TextBlock
                                   {
                                           Text = "Hey there. I'm a polygon."
                                   };

                // set the position of the textblock and add it to a new map layer
                MapLayer.SetPositionOrigin(tb, PositionOrigin.Center);
                MapLayer.SetPosition(tb, new Location(avgLat, avgLon));
                tbLayer.Children.Add(tb);
            }
        }

        // add the new maplayer to the parent map
        MyMap.Children.Add(tbLayer);

    }
}

If your polygons are oddly shaped and not nice little squares like my generic example, then you might need to get a little dirtier. In which case, you may need a web service (WCF) that can calculate your centroid of the polygon. I don't think theres a simple way in Silverlight to do this.

It would be a process similar to the following:

  1. Send the points to a WCF service method.
  2. Load up a SqlGeometry object with your points, probably by forming WKT with those points and using SqlGeometry.Parse
  3. Call STCentroid on your SqlGeometry object.
  4. return SqlGeometry.STAsText to return the WKT of the point you just got by calling STCentroid.

It's a bit of a mess, but doing spatial stuff in Silverlight is always messy in my experience.

Hope that helps and wasn't too long winded :)

Upvotes: 1

Related Questions