This project has moved. For the latest updates, please go here.

polygons with holes

Feb 10, 2015 at 2:15 PM
Hi! It's possible to draw complex polygons i.e. polygons whit holes or donuts?
Thanks a lot
Coordinator
Feb 10, 2015 at 3:37 PM
Edited Feb 10, 2015 at 6:26 PM
What luck! I've just changed the MapPath class, so that it also implements the UpdateData() method. You could now assign its Data property to an arbitrary Geometry defined in projected (cartesian) map coordinates, like
<map:MapPath Fill="Aqua" Opacity="0.5">
    <map:MapPath.Data>
        <GeometryGroup FillRule="EvenOdd">
            <EllipseGeometry Center="8.2,63.5" RadiusX="0.025" RadiusY="0.025"/>
            <EllipseGeometry Center="8.2,63.5" RadiusX="0.015" RadiusY="0.015"/>
        </GeometryGroup>
    </map:MapPath.Data>
</map:MapPath>
You may also want to take a look at MapPolyline.WPF.cs to get idea of how to transform geometry points from world to cartesian map coordinates.
Feb 10, 2015 at 3:53 PM
Edited Feb 10, 2015 at 4:14 PM
thanks a lot, ClemensF, you make my day!
But... it's for silverlight also?
Coordinator
Feb 10, 2015 at 5:17 PM
Edited Feb 10, 2015 at 6:06 PM
Yes, but there may be an issue with updating the Geometry's Transform after changing the Data (because it isn't possible to override dependency property metadata in Silverlight). If that is your problem, you may derive from MapPath and call UpdateData() internally whenever the Data property has changed. I'll also take a look into that.
Coordinator
Feb 10, 2015 at 8:12 PM
Just added a work-around for the missing automatic UpdateData call in Silverlight. You may now simply assign a Geometry to the Data property, and the Map's ViewportTransform will automatically be applied to the Geometry's Transform property. Of course you still need to create a Geometry in projected map coordinates, e.g. as is done in e.g. MapPolyline.Silverlight.WinRT.cs.
Feb 11, 2015 at 7:04 AM
Great!
Thanks a lot!
Feb 11, 2015 at 9:23 AM
Edited Feb 11, 2015 at 9:45 AM
Sorry Clemens,
with your latest release i've find a strange behaviour in the code.

Before the release both the point (code before patch) and the image were drawn at the correct point. After the release there are some problems with the point using the code before patch and even using the code after patch the point is drawn at the incorrect place.
P.S. the location is at the center of Rome.
Thanks in advance
Francesco
   'Point before patch
    Dim path As New MapPath
    Dim geom As New EllipseGeometry With {.RadiusX = 20, .RadiusY = 20}
    With path
      .Data = geom
      .Fill = New SolidColorBrush(Colors.Red)
    End With

    MapPanel.SetLocation(path, New Location(41.8892648281484, 12.4828987521694))
    maplayer.Children.Add(path)

    'point after patch
    Dim path As New MapPath
   ' coordinates inversion Point vs Location
    Dim geom As New EllipseGeometry With {.Center = New Point(12.4828987521694, 41.8892648281484), .RadiusX = 0.5, .RadiusY = 0.5}
    With path
      .Data = geom
      .Fill = New SolidColorBrush(Colors.Red)
    End With
    maplayer.Children.Add(path)


    'image 
    Dim Image As New Image
    With Image
      .Source = New BitmapImage(New Uri("http://susanweinroth.typepad.com/photos/uncategorized/2008/04/23/circle.jpg", UriKind.RelativeOrAbsolute))
      .Width = 32
      .Height = 32
      .HorizontalAlignment = HorizontalAlignment.Center
      .VerticalAlignment = VerticalAlignment.Center
    End With

    MapPanel.SetLocation(Image, New Location(41.8892648281484, 12.4828987521694)) 
    maplayer.Children.Add(Image)
    
    
Coordinator
Feb 11, 2015 at 10:21 AM
Edited Feb 11, 2015 at 10:21 AM
As said before, MapPath takes a Geometry defined in projected coordinates, which means you would have to use the Map's MapTransform to transform from lat/lon to projected coordinates.

So you would create the EllipseGeometry somehow like shown below (in C#). Note that the radii are also measured in longitude degrees, so they should be rather small.
var geom = new EllipseGeometry
{
    Center = maplayer.MapTransform.Transform(
        new Location(41.8892648281484, 12.4828987521694)),
    RadiusX = 0.05,
    RadiusY = 0.05
};
Feb 11, 2015 at 10:23 AM
ops...
sorry :)
Coordinator
Feb 11, 2015 at 10:26 AM
Edited Feb 11, 2015 at 10:28 AM
If you want to specify the Ellipse radii in meters, you could do it like this:
var center = new Location(41.8892648281484, 12.4828987521694);
var scale = maplayer.MapTransform.RelativeScale(center) / TileSource.MetersPerDegree;
var geom = new EllipseGeometry
{
    Center = maplayer.MapTransform.Transform(center),
    RadiusX = radiusX * scale,
    RadiusY = radiusY * scale
};