diff --git a/MapControl/Shared/MapShape.cs b/MapControl/Shared/MapShape.cs index 7d1dac23..4b9d5147 100644 --- a/MapControl/Shared/MapShape.cs +++ b/MapControl/Shared/MapShape.cs @@ -59,10 +59,16 @@ namespace MapControl parentMap.ViewportChanged += OnViewportChanged; } - ParentMapChanged(); + SetDataTransform(); + UpdateData(); } } + protected MapShape() + : this(new PathGeometry()) + { + } + protected MapShape(Geometry data) { Data = data; @@ -70,6 +76,8 @@ namespace MapControl MapPanel.InitMapElement(this); } + partial void SetDataTransform(); // WPF only + protected abstract void UpdateData(); protected Point LocationToPoint(Location location) diff --git a/MapControl/UWP/MapPolygon.UWP.cs b/MapControl/UWP/MapPolygon.UWP.cs index a024159d..8bbd439e 100644 --- a/MapControl/UWP/MapPolygon.UWP.cs +++ b/MapControl/UWP/MapPolygon.UWP.cs @@ -3,7 +3,6 @@ // Licensed under the Microsoft Public License (Ms-PL) using System.Collections.Generic; -using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -18,11 +17,6 @@ namespace MapControl nameof(Locations), typeof(IEnumerable), typeof(MapPolygon), new PropertyMetadata(null, (o, e) => ((MapPolygon)o).LocationsPropertyChanged(e))); - public MapPolygon() - : base(new PathGeometry()) - { - } - /// /// Gets or sets the Locations that define the polyline points. /// @@ -34,22 +28,12 @@ namespace MapControl protected override void UpdateData() { - ((PathGeometry)Data).Figures.Clear(); + var figures = ((PathGeometry)Data).Figures; + figures.Clear(); - if (ParentMap != null && Locations != null && Locations.Count() >= 2) + if (ParentMap != null) { - var locations = Locations; - var offset = GetLongitudeOffset(); - - if (offset != 0d) - { - locations = locations.Select(loc => new Location(loc.Latitude, loc.Longitude + offset)); - } - - var points = locations.Select(loc => LocationToViewportPoint(loc)).ToList(); - points.Add(points[0]); - - CreatePolylineFigures(points); + AddPolylineFigures(figures, Locations, true); } } } diff --git a/MapControl/UWP/MapPolyline.UWP.cs b/MapControl/UWP/MapPolyline.UWP.cs index e373f845..7ac88ce8 100644 --- a/MapControl/UWP/MapPolyline.UWP.cs +++ b/MapControl/UWP/MapPolyline.UWP.cs @@ -3,7 +3,6 @@ // Licensed under the Microsoft Public License (Ms-PL) using System.Collections.Generic; -using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -18,11 +17,6 @@ namespace MapControl nameof(Locations), typeof(IEnumerable), typeof(MapPolyline), new PropertyMetadata(null, (o, e) => ((MapPolyline)o).LocationsPropertyChanged(e))); - public MapPolyline() - : base(new PathGeometry()) - { - } - /// /// Gets or sets the Locations that define the polyline points. /// @@ -34,21 +28,12 @@ namespace MapControl protected override void UpdateData() { - ((PathGeometry)Data).Figures.Clear(); + var figures = ((PathGeometry)Data).Figures; + figures.Clear(); - if (ParentMap != null && Locations != null && Locations.Count() >= 2) + if (ParentMap != null) { - var locations = Locations; - var offset = GetLongitudeOffset(); - - if (offset != 0d) - { - locations = locations.Select(loc => new Location(loc.Latitude, loc.Longitude + offset)); - } - - var points = locations.Select(loc => LocationToViewportPoint(loc)).ToList(); - - CreatePolylineFigures(points); + AddPolylineFigures(figures, Locations, false); } } } diff --git a/MapControl/UWP/MapShape.UWP.cs b/MapControl/UWP/MapShape.UWP.cs index 42939056..a052dc70 100644 --- a/MapControl/UWP/MapShape.UWP.cs +++ b/MapControl/UWP/MapShape.UWP.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Collections.Specialized; +using System.Linq; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; @@ -13,11 +14,6 @@ namespace MapControl { public abstract partial class MapShape : Path { - private void ParentMapChanged() - { - UpdateData(); - } - private void OnViewportChanged(object sender, ViewportChangedEventArgs e) { UpdateData(); @@ -25,17 +21,16 @@ namespace MapControl protected void LocationsPropertyChanged(DependencyPropertyChangedEventArgs e) { - var oldCollection = e.OldValue as INotifyCollectionChanged; - var newCollection = e.NewValue as INotifyCollectionChanged; + INotifyCollectionChanged collection; - if (oldCollection != null) + if ((collection = e.OldValue as INotifyCollectionChanged) != null) { - oldCollection.CollectionChanged -= LocationCollectionChanged; + collection.CollectionChanged -= LocationCollectionChanged; } - if (newCollection != null) + if ((collection = e.NewValue as INotifyCollectionChanged) != null) { - newCollection.CollectionChanged += LocationCollectionChanged; + collection.CollectionChanged += LocationCollectionChanged; } UpdateData(); @@ -46,36 +41,56 @@ namespace MapControl UpdateData(); } - protected void CreatePolylineFigures(IList points) + protected void AddPolylineFigures(PathFigureCollection figures, IEnumerable locations, bool closed) { - var viewport = new Rect(0, 0, ParentMap.RenderSize.Width, ParentMap.RenderSize.Height); - var figures = ((PathGeometry)Data).Figures; - - PathFigure figure = null; - PolyLineSegment segment = null; - - for (int i = 1; i < points.Count; i++) + if (locations != null && locations.Count() >= 2) { - var p1 = points[i - 1]; - var p2 = points[i]; - var inside = Intersections.GetIntersections(ref p1, ref p2, viewport); + var viewport = new Rect(0, 0, ParentMap.RenderSize.Width, ParentMap.RenderSize.Height); + var offset = GetLongitudeOffset(); - if (inside) + if (offset != 0d) { - if (figure == null) - { - figure = new PathFigure { StartPoint = p1, IsClosed = false, IsFilled = false }; - segment = new PolyLineSegment(); - figure.Segments.Add(segment); - figures.Add(figure); - } - - segment.Points.Add(p2); + locations = locations.Select(loc => new Location(loc.Latitude, loc.Longitude + offset)); } - if (!inside || p2 != points[i]) + var points = locations.Select(loc => LocationToViewportPoint(loc)).ToList(); + if (closed) { - figure = null; + points.Add(points[0]); + } + + PathFigure figure = null; + PolyLineSegment segment = null; + + for (int i = 1; i < points.Count; i++) + { + var p1 = points[i - 1]; + var p2 = points[i]; + var inside = Intersections.GetIntersections(ref p1, ref p2, viewport); + + if (inside) + { + if (figure == null) + { + figure = new PathFigure + { + StartPoint = p1, + IsClosed = false, + IsFilled = false + }; + + segment = new PolyLineSegment(); + figure.Segments.Add(segment); + figures.Add(figure); + } + + segment.Points.Add(p2); + } + + if (!inside || p2 != points[i]) + { + figure = null; + } } } } diff --git a/MapControl/WPF/MapMultiPolygon.WPF.cs b/MapControl/WPF/MapMultiPolygon.WPF.cs index 872d7744..85f3136b 100644 --- a/MapControl/WPF/MapMultiPolygon.WPF.cs +++ b/MapControl/WPF/MapMultiPolygon.WPF.cs @@ -3,7 +3,6 @@ // Licensed under the Microsoft Public License (Ms-PL) using System.Collections.Generic; -using System.Linq; using System.Windows; using System.Windows.Media; @@ -23,11 +22,6 @@ namespace MapControl nameof(Polygons), typeof(IEnumerable>), typeof(MapMultiPolygon), new PropertyMetadata(null, (o, e) => ((MapMultiPolygon)o).DataCollectionPropertyChanged(e))); - public MapMultiPolygon() - : base(new PathGeometry()) - { - } - /// /// Gets or sets the Locations that define the multi-polygon points. /// @@ -44,12 +38,9 @@ namespace MapControl if (ParentMap != null && Polygons != null) { - foreach (var polygon in Polygons.Where(p => p.Count() >= 2)) + foreach (var polygon in Polygons) { - var points = polygon.Select(loc => LocationToPoint(loc)); - var polyline = new PolyLineSegment(points.Skip(1), true); - - figures.Add(new PathFigure(points.First(), new PathSegment[] { polyline }, true)); + AddPolylineFigure(figures, polygon, true); } } } diff --git a/MapControl/WPF/MapPolygon.WPF.cs b/MapControl/WPF/MapPolygon.WPF.cs index 94b49605..839acf2e 100644 --- a/MapControl/WPF/MapPolygon.WPF.cs +++ b/MapControl/WPF/MapPolygon.WPF.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.ComponentModel; -using System.Linq; using System.Windows; using System.Windows.Media; @@ -19,16 +18,6 @@ namespace MapControl nameof(Locations), typeof(IEnumerable), typeof(MapPolygon), new PropertyMetadata(null, (o, e) => ((MapPolygon)o).DataCollectionPropertyChanged(e))); - public static readonly DependencyProperty FillRuleProperty = DependencyProperty.Register( - nameof(FillRule), typeof(FillRule), typeof(MapPolygon), - new FrameworkPropertyMetadata(FillRule.EvenOdd, FrameworkPropertyMetadataOptions.AffectsRender, - (o, e) => ((PathGeometry)((MapPolygon)o).Data).FillRule = (FillRule)e.NewValue)); - - public MapPolygon() - : base(new PathGeometry()) - { - } - /// /// Gets or sets the Locations that define the polygon points. /// @@ -39,26 +28,14 @@ namespace MapControl set { SetValue(LocationsProperty, value); } } - /// - /// Gets or sets the FillRule of the PathGeometry that represents the polyline. - /// - public FillRule FillRule - { - get { return (FillRule)GetValue(FillRuleProperty); } - set { SetValue(FillRuleProperty, value); } - } - protected override void UpdateData() { var figures = ((PathGeometry)Data).Figures; figures.Clear(); - if (ParentMap != null && Locations != null && Locations.Count() >= 2) + if (ParentMap != null) { - var points = Locations.Select(loc => LocationToPoint(loc)); - var polyline = new PolyLineSegment(points.Skip(1), true); - - figures.Add(new PathFigure(points.First(), new PathSegment[] { polyline }, true)); + AddPolylineFigure(figures, Locations, true); } } } diff --git a/MapControl/WPF/MapPolyline.WPF.cs b/MapControl/WPF/MapPolyline.WPF.cs index 3653b980..2a86b58f 100644 --- a/MapControl/WPF/MapPolyline.WPF.cs +++ b/MapControl/WPF/MapPolyline.WPF.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.ComponentModel; -using System.Linq; using System.Windows; using System.Windows.Media; @@ -19,11 +18,6 @@ namespace MapControl nameof(Locations), typeof(IEnumerable), typeof(MapPolyline), new PropertyMetadata(null, (o, e) => ((MapPolyline)o).DataCollectionPropertyChanged(e))); - public MapPolyline() - : base(new PathGeometry()) - { - } - /// /// Gets or sets the Locations that define the polyline points. /// @@ -39,12 +33,9 @@ namespace MapControl var figures = ((PathGeometry)Data).Figures; figures.Clear(); - if (ParentMap != null && Locations != null && Locations.Count() >= 2) + if (ParentMap != null) { - var points = Locations.Select(loc => LocationToPoint(loc)); - var polyline = new PolyLineSegment(points.Skip(1), true); - - figures.Add(new PathFigure(points.First(), new PathSegment[] { polyline }, false)); + AddPolylineFigure(figures, Locations, false); } } } diff --git a/MapControl/WPF/MapShape.WPF.cs b/MapControl/WPF/MapShape.WPF.cs index 8ac781bc..4b90960e 100644 --- a/MapControl/WPF/MapShape.WPF.cs +++ b/MapControl/WPF/MapShape.WPF.cs @@ -3,7 +3,9 @@ // Licensed under the Microsoft Public License (Ms-PL) using System; +using System.Collections.Generic; using System.Collections.Specialized; +using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Shapes; @@ -19,7 +21,7 @@ namespace MapControl get { return Data; } } - private void ParentMapChanged() + partial void SetDataTransform() { if (parentMap != null) { @@ -35,8 +37,6 @@ namespace MapControl { Data.Transform = Transform.Identity; } - - UpdateData(); } private void OnViewportChanged(object sender, ViewportChangedEventArgs e) @@ -61,28 +61,45 @@ namespace MapControl } } - protected void DataCollectionPropertyChanged(DependencyPropertyChangedEventArgs e) - { - INotifyCollectionChanged locations; - - if ((locations = e.OldValue as INotifyCollectionChanged) != null) - { - CollectionChangedEventManager.RemoveListener(locations, this); - } - - if ((locations = e.NewValue as INotifyCollectionChanged) != null) - { - CollectionChangedEventManager.AddListener(locations, this); - } - - UpdateData(); - } - bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) { UpdateData(); return true; } + + protected void DataCollectionPropertyChanged(DependencyPropertyChangedEventArgs e) + { + INotifyCollectionChanged collection; + + if ((collection = e.OldValue as INotifyCollectionChanged) != null) + { + CollectionChangedEventManager.RemoveListener(collection, this); + } + + if ((collection = e.NewValue as INotifyCollectionChanged) != null) + { + CollectionChangedEventManager.AddListener(collection, this); + } + + UpdateData(); + } + + protected void AddPolylineFigure(PathFigureCollection figures, IEnumerable locations, bool closed) + { + if (locations != null && locations.Count() >= 2) + { + var points = locations.Select(loc => LocationToPoint(loc)); + var figure = new PathFigure + { + StartPoint = points.First(), + IsClosed = closed, + IsFilled = closed + }; + + figure.Segments.Add(new PolyLineSegment(points.Skip(1), true)); + figures.Add(figure); + } + } } }