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

Graphical bug when filling Polylines

May 23, 2013 at 7:25 AM
Edited May 23, 2013 at 7:26 AM
I have a strange bug when filling polylines with a color. It looks like a graphic card bug but can be seen on every PC we have.
It occurs especially when touch or clicking inside the zone or when putting several polylines at the same location.

Here is an example of the bug:

I think it may come from the MapPanel itself and the fact that MeasureOverride of the MapPolyline is called only at creation (and returns Size(1,1)!) but never been called later (even when manipulating the map).

What do you think?

Thank you.
May 23, 2013 at 3:29 PM
No idea what it is. However, MeasureOverride only needs to be called once, as the polyline is later on only transformed by the Map's ViewportTransform and doesn't need to be re-measured. Which platform is it?
May 24, 2013 at 1:42 PM
Platform is a classic Win7 x64 but the problem doesn't come from this. In fact the field Geometry of MapPolyline has to be a Dependency Property so WPF will know that the region has to be rendered and thus it will avoid rendering glitches (dirty regions flickering).
May 24, 2013 at 5:45 PM
WPF needs to be notified every time that a property change involves a redraw.

In the current implementation, MapPolyline is redrawn when the viewport of the Map changes, WPF calls onRender but does not update layout data. Thus, WPF does not known the new size and position of MapPolylines when it lists all ellements in the dirty region that is going to redraw (WPF uses a dirty region mecanism is to reduce the amount of pixels sent to the output merger stage of the GPU pipeline, it helps reduce the geometry that needs to be re-tessellated when redrawing). That's why, you may have rendering glitches when you move an object above a MapPolyline, glitches that disappear when you move the map.

To avoid, these rendering glitches, you need a DependencyProperty with at least the FrameworkPropertyMetadata.AffectsRender metadata.
As the Geometry property of MapShape is used for WinRT, Silverlight and WPF, the easier way is to create a fake property that will only be used to help WPF redraw MapPolyline correctly
        /// <summary>
        ///     Key to set FooProperty
        /// </summary>
        private static readonly DependencyPropertyKey FooPropertyKey = 
            DependencyProperty.RegisterReadOnly("Foo", typeof(Transform), typeof(MapPolyline), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

        /// <summary>
        /// Foo Dependency Property
        /// </summary>
        public static readonly DependencyProperty FooProperty = FooPropertyKey.DependencyProperty;

        /// <summary>
        ///  Gets the Fooproperty
        /// </summary>
        /// <remarks>
        ///     This property is only used to recompute layout and redraw our polyline when the viewport of our parent map changes
        /// </remarks>
        public Transform Foo
            get { return (Transform)GetValue(FooProperty ); }
            protected set { SetValue(FooPropertyKey , value); }
and in UpdateGeometry, you will need to associated it to the viewportTransform of the parent map. With this, each time the viewport of the parent map is updated, WPF will recompute the layout of MapPolyline and redraw it
Foo = ParentMap.ViewportTransform
NB: MapRectangle does not have rendering glitches in WPF, because the viewportTRansform of the parent map is linked to RenderTransform which is a DependencyProperty with the AffectsRender metadata
 RenderTransform = ParentMap.ViewportTransform;
May 25, 2013 at 7:30 AM
Edited May 25, 2013 at 7:43 AM
I've changed the readonly field Geometry into a dependency property named Data, like the one that was already present in the WinRT and Silverlight version, where MapShape derives from System.Windows.Shapes.Path instead of System.Windows.Shapes.Shape. Please note that defining this property is only necessary because System.Windows.Shapes.Path is sealed in WPF.

As there now is a public Data property that sets the geometry of a map shape, I consequently also renamed MapShape to MapPath.