From 9b218ef376074a6c258f30dc4357a0856c60b651 Mon Sep 17 00:00:00 2001 From: ClemensF Date: Fri, 12 Apr 2013 19:59:16 +0200 Subject: [PATCH] Version 1.2.0: Added classes MapShape, MapRectangle and MapImage. --- .../FileDbCache/Properties/AssemblyInfo.cs | 4 +- .../ImageFileCache/Properties/AssemblyInfo.cs | 4 +- MapControl/MapBase.Silverlight.WinRT.cs | 2 +- MapControl/MapBase.cs | 2 +- MapControl/MapControl.Silverlight.csproj | 6 +- MapControl/MapControl.WPF.csproj | 5 +- MapControl/MapGraticule.Silverlight.WinRT.cs | 277 +++++++++++++----- MapControl/MapGraticule.WPF.cs | 40 ++- MapControl/MapGraticule.cs | 7 +- MapControl/MapImage.cs | 41 +++ MapControl/MapItem.WPF.cs | 3 +- MapControl/MapOverlay.Silverlight.WinRT.cs | 129 -------- MapControl/MapOverlay.WPF.cs | 151 ---------- MapControl/MapOverlay.cs | 148 +++++++++- MapControl/MapPanel.Silverlight.WinRT.cs | 5 + MapControl/MapPanel.WPF.cs | 9 +- MapControl/MapPanel.cs | 84 +++--- MapControl/MapPolyline.Silverlight.WinRT.cs | 31 +- MapControl/MapPolyline.WPF.cs | 27 +- MapControl/MapPolyline.cs | 17 +- MapControl/MapRectangle.cs | 100 +++++++ MapControl/MapScale.cs | 19 +- MapControl/MapShape.Silverlight.WinRT.cs | 23 ++ MapControl/MapShape.WPF.cs | 22 ++ MapControl/MapShape.cs | 49 ++++ MapControl/Properties/AssemblyInfo.cs | 4 +- MapControl/WinRT/MapControl.WinRT.csproj | 18 +- MapControl/WinRT/Properties/AssemblyInfo.cs | 4 +- .../Properties/AssemblyInfo.cs | 4 +- .../SilverlightApplication/10_535_330.jpg | Bin 0 -> 7174 bytes .../SilverlightApplication/MainPage.xaml | 31 +- .../SilverlightApplication/MainPage.xaml.cs | 20 +- .../Properties/AssemblyInfo.cs | 4 +- .../SilverlightApplication.csproj | 3 + SampleApps/StoreApplication/10_535_330.jpg | Bin 0 -> 7174 bytes SampleApps/StoreApplication/MainPage.xaml | 27 +- SampleApps/StoreApplication/MainPage.xaml.cs | 22 +- .../Properties/AssemblyInfo.cs | 4 +- .../StoreApplication/StoreApplication.csproj | 1 + .../Properties/AssemblyInfo.cs | 4 +- SampleApps/WpfApplication/10_535_330.jpg | Bin 0 -> 7174 bytes SampleApps/WpfApplication/MainWindow.xaml | 33 ++- SampleApps/WpfApplication/MainWindow.xaml.cs | 20 +- .../WpfApplication/Properties/AssemblyInfo.cs | 4 +- .../WpfApplication/WpfApplication.csproj | 3 + 45 files changed, 846 insertions(+), 565 deletions(-) create mode 100644 MapControl/MapImage.cs delete mode 100644 MapControl/MapOverlay.Silverlight.WinRT.cs delete mode 100644 MapControl/MapOverlay.WPF.cs create mode 100644 MapControl/MapRectangle.cs create mode 100644 MapControl/MapShape.Silverlight.WinRT.cs create mode 100644 MapControl/MapShape.WPF.cs create mode 100644 MapControl/MapShape.cs create mode 100644 SampleApps/SilverlightApplication/10_535_330.jpg create mode 100644 SampleApps/StoreApplication/10_535_330.jpg create mode 100644 SampleApps/WpfApplication/10_535_330.jpg diff --git a/Caching/FileDbCache/Properties/AssemblyInfo.cs b/Caching/FileDbCache/Properties/AssemblyInfo.cs index bd589cba..4802386d 100644 --- a/Caching/FileDbCache/Properties/AssemblyInfo.cs +++ b/Caching/FileDbCache/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/Caching/ImageFileCache/Properties/AssemblyInfo.cs b/Caching/ImageFileCache/Properties/AssemblyInfo.cs index 637d6a46..8204a486 100644 --- a/Caching/ImageFileCache/Properties/AssemblyInfo.cs +++ b/Caching/ImageFileCache/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/MapControl/MapBase.Silverlight.WinRT.cs b/MapControl/MapBase.Silverlight.WinRT.cs index 23f0259e..800874af 100644 --- a/MapControl/MapBase.Silverlight.WinRT.cs +++ b/MapControl/MapBase.Silverlight.WinRT.cs @@ -22,7 +22,7 @@ namespace MapControl private const FillBehavior AnimationFillBehavior = FillBehavior.HoldEnd; public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register( - "Foreground", typeof(Brush), typeof(MapBase), null); + "Foreground", typeof(Brush), typeof(MapBase), new PropertyMetadata(new SolidColorBrush(Colors.Black))); partial void Initialize() { diff --git a/MapControl/MapBase.cs b/MapControl/MapBase.cs index 9174dd10..c611b698 100644 --- a/MapControl/MapBase.cs +++ b/MapControl/MapBase.cs @@ -108,7 +108,7 @@ namespace MapControl public MapBase() { - SetValue(MapPanel.ParentMapProperty, this); + SetParentMap(); Background = LightBackground; TileLayers = new TileLayerCollection(); diff --git a/MapControl/MapControl.Silverlight.csproj b/MapControl/MapControl.Silverlight.csproj index 6ba9ed0f..5b5a657f 100644 --- a/MapControl/MapControl.Silverlight.csproj +++ b/MapControl/MapControl.Silverlight.csproj @@ -75,15 +75,17 @@ + - - + + + diff --git a/MapControl/MapControl.WPF.csproj b/MapControl/MapControl.WPF.csproj index 5a9ce143..2aefa025 100644 --- a/MapControl/MapControl.WPF.csproj +++ b/MapControl/MapControl.WPF.csproj @@ -46,7 +46,6 @@ - @@ -60,10 +59,14 @@ + + + + diff --git a/MapControl/MapGraticule.Silverlight.WinRT.cs b/MapControl/MapGraticule.Silverlight.WinRT.cs index 2f28b00b..878db841 100644 --- a/MapControl/MapGraticule.Silverlight.WinRT.cs +++ b/MapControl/MapGraticule.Silverlight.WinRT.cs @@ -6,97 +6,219 @@ using System; using System.Linq; #if NETFX_CORE using Windows.Foundation; +using Windows.UI.Text; +using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Shapes; +using Windows.UI.Xaml.Data; #else using System.Windows; using System.Windows.Controls; using System.Windows.Media; +using System.Windows.Shapes; +using System.Windows.Data; #endif namespace MapControl { - public partial class MapGraticule + public partial class MapGraticule : MapPanel { + public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register( + "FontFamily", typeof(FontFamily), typeof(MapGraticule), + new PropertyMetadata(default(FontFamily), (o, e) => ((MapGraticule)o).OnViewportChanged())); + + public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register( + "FontSize", typeof(double), typeof(MapGraticule), + new PropertyMetadata(10d, (o, e) => ((MapGraticule)o).OnViewportChanged())); + + public static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register( + "FontStyle", typeof(FontStyle), typeof(MapGraticule), + new PropertyMetadata(default(FontStyle), (o, e) => ((MapGraticule)o).OnViewportChanged())); + + public static readonly DependencyProperty FontStretchProperty = DependencyProperty.Register( + "FontStretch", typeof(FontStretch), typeof(MapGraticule), + new PropertyMetadata(default(FontStretch), (o, e) => ((MapGraticule)o).OnViewportChanged())); + + public static readonly DependencyProperty FontWeightProperty = DependencyProperty.Register( + "FontWeight", typeof(FontWeight), typeof(MapGraticule), + new PropertyMetadata(FontWeights.Normal, (o, e) => ((MapGraticule)o).OnViewportChanged())); + + public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register( + "Foreground", typeof(Brush), typeof(MapGraticule), + new PropertyMetadata(null, (o, e) => ((MapGraticule)o).OnViewportChanged())); + + public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register( + "Stroke", typeof(Brush), typeof(MapGraticule), + new PropertyMetadata(null, (o, e) => ((MapGraticule)o).path.Stroke = (Brush)e.NewValue)); + + public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register( + "StrokeThickness", typeof(double), typeof(MapGraticule), + new PropertyMetadata(0.5, (o, e) => ((MapGraticule)o).path.StrokeThickness = (double)e.NewValue)); + + private readonly Path path; private Location graticuleStart; private Location graticuleEnd; + public MapGraticule() + { + IsHitTestVisible = false; + + path = new Path + { + Stroke = Stroke, + StrokeThickness = StrokeThickness + }; + + Children.Add(path); + } + + public FontFamily FontFamily + { + get { return (FontFamily)GetValue(FontFamilyProperty); } + set { SetValue(FontFamilyProperty, value); } + } + + public double FontSize + { + get { return (double)GetValue(FontSizeProperty); } + set { SetValue(FontSizeProperty, value); } + } + + public FontStyle FontStyle + { + get { return (FontStyle)GetValue(FontStyleProperty); } + set { SetValue(FontStyleProperty, value); } + } + + public FontStretch FontStretch + { + get { return (FontStretch)GetValue(FontStretchProperty); } + set { SetValue(FontStretchProperty, value); } + } + + public FontWeight FontWeight + { + get { return (FontWeight)GetValue(FontWeightProperty); } + set { SetValue(FontWeightProperty, value); } + } + + public Brush Foreground + { + get { return (Brush)GetValue(ForegroundProperty); } + set { SetValue(ForegroundProperty, value); } + } + + public Brush Stroke + { + get { return (Brush)GetValue(StrokeProperty); } + set { SetValue(StrokeProperty, value); } + } + + public double StrokeThickness + { + get { return (double)GetValue(StrokeThicknessProperty); } + set { SetValue(StrokeThicknessProperty, value); } + } + protected override void OnViewportChanged() { - var parentMap = MapPanel.GetParentMap(this); - var bounds = parentMap.ViewportTransform.Inverse.TransformBounds(new Rect(0d, 0d, parentMap.RenderSize.Width, parentMap.RenderSize.Height)); - var start = parentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); - var end = parentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); - var minSpacing = MinLineSpacing * 360d / (Math.Pow(2d, parentMap.ZoomLevel) * 256d); - var spacing = LineSpacings[LineSpacings.Length - 1]; - - if (spacing >= minSpacing) + if (ParentMap != null) { - spacing = LineSpacings.FirstOrDefault(s => s >= minSpacing); - } - - var labelsStart = new Location( - Math.Ceiling(start.Latitude / spacing) * spacing, - Math.Ceiling(start.Longitude / spacing) * spacing); - - var labelsEnd = new Location( - Math.Floor(end.Latitude / spacing) * spacing, - Math.Floor(end.Longitude / spacing) * spacing); - - var linesStart = new Location( - Math.Min(Math.Max(labelsStart.Latitude - spacing, -parentMap.MapTransform.MaxLatitude), parentMap.MapTransform.MaxLatitude), - labelsStart.Longitude - spacing); - - var linesEnd = new Location( - Math.Min(Math.Max(labelsEnd.Latitude + spacing, -parentMap.MapTransform.MaxLatitude), parentMap.MapTransform.MaxLatitude), - labelsEnd.Longitude + spacing); - - if (!linesStart.Equals(graticuleStart) || !linesEnd.Equals(graticuleEnd)) - { - graticuleStart = linesStart; - graticuleEnd = linesEnd; - - Geometry.Figures.Clear(); - Geometry.Transform = parentMap.ViewportTransform; - - for (var lat = labelsStart.Latitude; lat <= end.Latitude; lat += spacing) + if (path.Data == null) { - var figure = new PathFigure - { - StartPoint = parentMap.MapTransform.Transform(new Location(lat, linesStart.Longitude)), - IsClosed = false, - IsFilled = false - }; + path.Data = new PathGeometry(); - figure.Segments.Add(new LineSegment + if (Foreground == null) { - Point = parentMap.MapTransform.Transform(new Location(lat, linesEnd.Longitude)), - }); + SetBinding(ForegroundProperty, new Binding() + { + Source = ParentMap, + Path = new PropertyPath("Foreground") + }); + } - Geometry.Figures.Add(figure); + if (Stroke == null) + { + SetBinding(StrokeProperty, new Binding() + { + Source = ParentMap, + Path = new PropertyPath("Foreground") + }); + } } - for (var lon = labelsStart.Longitude; lon <= end.Longitude; lon += spacing) + var geometry = (PathGeometry)path.Data; + var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(0d, 0d, ParentMap.RenderSize.Width, ParentMap.RenderSize.Height)); + var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); + var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); + var minSpacing = MinLineSpacing * 360d / (Math.Pow(2d, ParentMap.ZoomLevel) * 256d); + var spacing = LineSpacings[LineSpacings.Length - 1]; + + if (spacing >= minSpacing) { - var figure = new PathFigure - { - StartPoint = parentMap.MapTransform.Transform(new Location(linesStart.Latitude, lon)), - IsClosed = false, - IsFilled = false - }; - - figure.Segments.Add(new LineSegment - { - Point = parentMap.MapTransform.Transform(new Location(linesEnd.Latitude, lon)), - }); - - Geometry.Figures.Add(figure); + spacing = LineSpacings.FirstOrDefault(s => s >= minSpacing); } - var childIndex = 1; // 0 for Path + var labelsStart = new Location( + Math.Ceiling(start.Latitude / spacing) * spacing, + Math.Ceiling(start.Longitude / spacing) * spacing); - if (Foreground != null) + var labelsEnd = new Location( + Math.Floor(end.Latitude / spacing) * spacing, + Math.Floor(end.Longitude / spacing) * spacing); + + var linesStart = new Location( + Math.Min(Math.Max(labelsStart.Latitude - spacing, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude), + labelsStart.Longitude - spacing); + + var linesEnd = new Location( + Math.Min(Math.Max(labelsEnd.Latitude + spacing, -ParentMap.MapTransform.MaxLatitude), ParentMap.MapTransform.MaxLatitude), + labelsEnd.Longitude + spacing); + + if (!linesStart.Equals(graticuleStart) || !linesEnd.Equals(graticuleEnd)) { + graticuleStart = linesStart; + graticuleEnd = linesEnd; + + geometry.Figures.Clear(); + geometry.Transform = ParentMap.ViewportTransform; + + for (var lat = labelsStart.Latitude; lat <= end.Latitude; lat += spacing) + { + var figure = new PathFigure + { + StartPoint = ParentMap.MapTransform.Transform(new Location(lat, linesStart.Longitude)), + IsClosed = false, + IsFilled = false + }; + + figure.Segments.Add(new LineSegment + { + Point = ParentMap.MapTransform.Transform(new Location(lat, linesEnd.Longitude)), + }); + + geometry.Figures.Add(figure); + } + + for (var lon = labelsStart.Longitude; lon <= end.Longitude; lon += spacing) + { + var figure = new PathFigure + { + StartPoint = ParentMap.MapTransform.Transform(new Location(linesStart.Latitude, lon)), + IsClosed = false, + IsFilled = false + }; + + figure.Segments.Add(new LineSegment + { + Point = ParentMap.MapTransform.Transform(new Location(linesEnd.Latitude, lon)), + }); + + geometry.Figures.Add(figure); + } + + var childIndex = 1; // 0 for Path var format = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°"; var measureSize = new Size(double.PositiveInfinity, double.PositiveInfinity); @@ -113,7 +235,17 @@ namespace MapControl } else { - label = new TextBlock { RenderTransform = new TransformGroup() }; + label = new TextBlock + { + RenderTransform = new TransformGroup() + }; + + label.SetBinding(TextBlock.ForegroundProperty, new Binding + { + Source = this, + Path = new PropertyPath("Foreground") + }); + Children.Add(label); } @@ -126,9 +258,8 @@ namespace MapControl label.FontSize = FontSize; label.FontStyle = FontStyle; - label.FontWeight = FontWeight; label.FontStretch = FontStretch; - label.Foreground = Foreground; + label.FontWeight = FontWeight; label.Text = string.Format("{0}\n{1}", CoordinateString(lat, format, "NS"), @@ -141,7 +272,7 @@ namespace MapControl if (transformGroup.Children.Count == 0) { transformGroup.Children.Add(new TranslateTransform()); - transformGroup.Children.Add(parentMap.RotateTransform); + transformGroup.Children.Add(ParentMap.RotateTransform); } var translateTransform = (TranslateTransform)transformGroup.Children[0]; @@ -151,13 +282,17 @@ namespace MapControl MapPanel.SetLocation(label, location); } } - } - while (Children.Count > childIndex) - { - Children.RemoveAt(Children.Count - 1); + while (Children.Count > childIndex) + { + Children.RemoveAt(Children.Count - 1); + } } } + else + { + path.Data = null; + } base.OnViewportChanged(); } diff --git a/MapControl/MapGraticule.WPF.cs b/MapControl/MapGraticule.WPF.cs index 0da78ecd..e876bc8f 100644 --- a/MapControl/MapGraticule.WPF.cs +++ b/MapControl/MapGraticule.WPF.cs @@ -9,18 +9,30 @@ using System.Windows.Media; namespace MapControl { - public partial class MapGraticule + public partial class MapGraticule : MapOverlay { + static MapGraticule() + { + UIElement.IsHitTestVisibleProperty.OverrideMetadata( + typeof(MapGraticule), new FrameworkPropertyMetadata(false)); + + MapOverlay.StrokeThicknessProperty.OverrideMetadata( + typeof(MapGraticule), new FrameworkPropertyMetadata(0.5)); + } + + protected override void OnViewportChanged() + { + InvalidateVisual(); + } + protected override void OnRender(DrawingContext drawingContext) { - var parentMap = MapPanel.GetParentMap(this); - - if (parentMap != null) + if (ParentMap != null) { - var bounds = parentMap.ViewportTransform.Inverse.TransformBounds(new Rect(parentMap.RenderSize)); - var start = parentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); - var end = parentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); - var minSpacing = MinLineSpacing * 360d / (Math.Pow(2d, parentMap.ZoomLevel) * 256d); + var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(ParentMap.RenderSize)); + var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); + var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); + var minSpacing = MinLineSpacing * 360d / (Math.Pow(2d, ParentMap.ZoomLevel) * 256d); var spacing = LineSpacings[LineSpacings.Length - 1]; if (spacing >= minSpacing) @@ -35,15 +47,15 @@ namespace MapControl for (var lat = labelsStart.Latitude; lat <= end.Latitude; lat += spacing) { drawingContext.DrawLine(Pen, - parentMap.LocationToViewportPoint(new Location(lat, start.Longitude)), - parentMap.LocationToViewportPoint(new Location(lat, end.Longitude))); + ParentMap.LocationToViewportPoint(new Location(lat, start.Longitude)), + ParentMap.LocationToViewportPoint(new Location(lat, end.Longitude))); } for (var lon = labelsStart.Longitude; lon <= end.Longitude; lon += spacing) { drawingContext.DrawLine(Pen, - parentMap.LocationToViewportPoint(new Location(start.Latitude, lon)), - parentMap.LocationToViewportPoint(new Location(end.Latitude, lon))); + ParentMap.LocationToViewportPoint(new Location(start.Latitude, lon)), + ParentMap.LocationToViewportPoint(new Location(end.Latitude, lon))); } if (Foreground != null && Foreground != Brushes.Transparent) @@ -55,13 +67,13 @@ namespace MapControl for (var lon = labelsStart.Longitude; lon <= end.Longitude; lon += spacing) { var t = StrokeThickness / 2d; - var p = parentMap.LocationToViewportPoint(new Location(lat, lon)); + var p = ParentMap.LocationToViewportPoint(new Location(lat, lon)); var latPos = new Point(p.X + t + 2d, p.Y - t - FontSize / 4d); var lonPos = new Point(p.X + t + 2d, p.Y + t + FontSize); var latLabel = CoordinateString(lat, format, "NS"); var lonLabel = CoordinateString(Location.NormalizeLongitude(lon), format, "EW"); - drawingContext.PushTransform(new RotateTransform(parentMap.Heading, p.X, p.Y)); + drawingContext.PushTransform(new RotateTransform(ParentMap.Heading, p.X, p.Y)); drawingContext.DrawGlyphRun(Foreground, GlyphRunText.Create(latLabel, Typeface, FontSize, latPos)); drawingContext.DrawGlyphRun(Foreground, GlyphRunText.Create(lonLabel, Typeface, FontSize, lonPos)); drawingContext.Pop(); diff --git a/MapControl/MapGraticule.cs b/MapControl/MapGraticule.cs index aa2a7c66..dd4e8953 100644 --- a/MapControl/MapGraticule.cs +++ b/MapControl/MapGraticule.cs @@ -13,7 +13,7 @@ namespace MapControl /// /// Draws a graticule overlay. /// - public partial class MapGraticule : MapOverlay + public partial class MapGraticule { /// /// Graticule line spacings in degrees. @@ -24,11 +24,6 @@ namespace MapControl public static readonly DependencyProperty MinLineSpacingProperty = DependencyProperty.Register( "MinLineSpacing", typeof(double), typeof(MapGraticule), new PropertyMetadata(150d)); - public MapGraticule() - { - StrokeThickness = 0.5; - } - /// /// Minimum spacing in pixels between adjacent graticule lines. /// diff --git a/MapControl/MapImage.cs b/MapControl/MapImage.cs new file mode 100644 index 00000000..f8a4792d --- /dev/null +++ b/MapControl/MapImage.cs @@ -0,0 +1,41 @@ +// XAML Map Control - http://xamlmapcontrol.codeplex.com/ +// Copyright © 2013 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +#if NETFX_CORE +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; +#else +using System.Windows; +using System.Windows.Media; +#endif + +namespace MapControl +{ + public class MapImage : MapRectangle + { + private static readonly Transform imageTransform = new MatrixTransform + { + Matrix = new Matrix(1, 0, 0, -1, 0, 1) + }; + + public static readonly DependencyProperty SourceProperty = DependencyProperty.Register( + "Source", typeof(ImageSource), typeof(MapImage), + new PropertyMetadata(null, (o, e) => ((MapImage)o).SourceChanged((ImageSource)e.NewValue))); + + public ImageSource Source + { + get { return (ImageSource)GetValue(SourceProperty); } + set { SetValue(SourceProperty, value); } + } + + private void SourceChanged(ImageSource source) + { + Fill = new ImageBrush + { + ImageSource = source, + RelativeTransform = imageTransform + }; + } + } +} diff --git a/MapControl/MapItem.WPF.cs b/MapControl/MapItem.WPF.cs index c6037d2b..c40dd05e 100644 --- a/MapControl/MapItem.WPF.cs +++ b/MapControl/MapItem.WPF.cs @@ -15,8 +15,7 @@ namespace MapControl public class MapItem : ListBoxItem { public static readonly DependencyProperty IsCurrentProperty = MapItemsControl.IsCurrentProperty.AddOwner( - typeof(MapItem), - new PropertyMetadata((o, e) => ((MapItem)o).IsCurrentPropertyChanged((bool)e.NewValue))); + typeof(MapItem), new PropertyMetadata((o, e) => ((MapItem)o).IsCurrentPropertyChanged((bool)e.NewValue))); static MapItem() { diff --git a/MapControl/MapOverlay.Silverlight.WinRT.cs b/MapControl/MapOverlay.Silverlight.WinRT.cs deleted file mode 100644 index c0f47747..00000000 --- a/MapControl/MapOverlay.Silverlight.WinRT.cs +++ /dev/null @@ -1,129 +0,0 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// Copyright © 2013 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -#if NETFX_CORE -using Windows.UI; -using Windows.UI.Text; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Shapes; -#else -using System.Windows; -using System.Windows.Media; -using System.Windows.Shapes; -#endif - -namespace MapControl -{ - public partial class MapOverlay : MapPanel - { - public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register( - "FontFamily", typeof(FontFamily), typeof(MapOverlay), - new PropertyMetadata(default(FontFamily), (o, e) => ((MapOverlay)o).FontSizePropertyChanged())); - - public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register( - "FontSize", typeof(double), typeof(MapOverlay), - new PropertyMetadata(10d, (o, e) => ((MapOverlay)o).FontSizePropertyChanged())); - - public static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register( - "FontStyle", typeof(FontStyle), typeof(MapOverlay), - new PropertyMetadata(default(FontStyle), (o, e) => ((MapOverlay)o).FontSizePropertyChanged())); - - public static readonly DependencyProperty FontStretchProperty = DependencyProperty.Register( - "FontStretch", typeof(FontStretch), typeof(MapOverlay), - new PropertyMetadata(default(FontStretch), (o, e) => ((MapOverlay)o).FontSizePropertyChanged())); - - public static readonly DependencyProperty FontWeightProperty = DependencyProperty.Register( - "FontWeight", typeof(FontWeight), typeof(MapOverlay), - new PropertyMetadata(FontWeights.Normal, (o, e) => ((MapOverlay)o).FontSizePropertyChanged())); - - public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register( - "Foreground", typeof(Brush), typeof(MapOverlay), - new PropertyMetadata(new SolidColorBrush(Colors.Black), (o, e) => ((MapOverlay)o).ForegroundPropertyChanged())); - - public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register( - "Stroke", typeof(Brush), typeof(MapOverlay), - new PropertyMetadata(new SolidColorBrush(Colors.Black), (o, e) => ((MapOverlay)o).Path.Stroke = (Brush)e.NewValue)); - - public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register( - "StrokeThickness", typeof(double), typeof(MapOverlay), - new PropertyMetadata(1d, (o, e) => ((MapOverlay)o).StrokeThicknessPropertyChanged((double)e.NewValue))); - - public static readonly DependencyProperty StrokeDashArrayProperty = DependencyProperty.Register( - "StrokeDashArray", typeof(DoubleCollection), typeof(MapOverlay), - new PropertyMetadata(null, (o, e) => ((MapOverlay)o).Path.StrokeDashArray = (DoubleCollection)e.NewValue)); - - public static readonly DependencyProperty StrokeDashOffsetProperty = DependencyProperty.Register( - "StrokeDashOffset", typeof(double), typeof(MapOverlay), - new PropertyMetadata(0d, (o, e) => ((MapOverlay)o).Path.StrokeDashOffset = (double)e.NewValue)); - - public static readonly DependencyProperty StrokeDashCapProperty = DependencyProperty.Register( - "StrokeDashCap", typeof(PenLineCap), typeof(MapOverlay), - new PropertyMetadata(default(PenLineCap), (o, e) => ((MapOverlay)o).Path.StrokeDashCap = (PenLineCap)e.NewValue)); - - public static readonly DependencyProperty StrokeStartLineCapProperty = DependencyProperty.Register( - "StrokeStartLineCap", typeof(PenLineCap), typeof(MapOverlay), - new PropertyMetadata(default(PenLineCap), (o, e) => ((MapOverlay)o).Path.StrokeStartLineCap = (PenLineCap)e.NewValue)); - - public static readonly DependencyProperty StrokeEndLineCapProperty = DependencyProperty.Register( - "StrokeEndLineCap", typeof(PenLineCap), typeof(MapOverlay), - new PropertyMetadata(default(PenLineCap), (o, e) => ((MapOverlay)o).Path.StrokeEndLineCap = (PenLineCap)e.NewValue)); - - public static readonly DependencyProperty StrokeLineJoinProperty = DependencyProperty.Register( - "StrokeLineJoin", typeof(PenLineJoin), typeof(MapOverlay), - new PropertyMetadata(default(PenLineJoin), (o, e) => ((MapOverlay)o).Path.StrokeLineJoin = (PenLineJoin)e.NewValue)); - - public static readonly DependencyProperty StrokeMiterLimitProperty = DependencyProperty.Register( - "StrokeMiterLimit", typeof(double), typeof(MapOverlay), - new PropertyMetadata(1d, (o, e) => ((MapOverlay)o).Path.StrokeMiterLimit = (double)e.NewValue)); - - protected readonly Path Path = new Path(); - protected readonly PathGeometry Geometry = new PathGeometry(); - - public MapOverlay() - { - IsHitTestVisible = false; - Path.Stroke = Stroke; - Path.StrokeThickness = StrokeThickness; - Path.StrokeDashArray = StrokeDashArray; - Path.StrokeDashOffset = StrokeDashOffset; - Path.StrokeDashCap = StrokeDashCap; - Path.StrokeStartLineCap = StrokeStartLineCap; - Path.StrokeEndLineCap = StrokeEndLineCap; - Path.StrokeLineJoin = StrokeLineJoin; - Path.StrokeMiterLimit = StrokeMiterLimit; - Path.Data = Geometry; - Children.Add(Path); - } - - private void FontSizePropertyChanged() - { - if (GetParentMap(this) != null) - { - // FontSize may affect layout - OnViewportChanged(); - } - } - - private void ForegroundPropertyChanged() - { - if (GetParentMap(this) != null) - { - // Foreground may affect rendering - OnViewportChanged(); - } - } - - private void StrokeThicknessPropertyChanged(double thickness) - { - Path.StrokeThickness = thickness; - - if (GetParentMap(this) != null) - { - // StrokeThickness may affect layout - OnViewportChanged(); - } - } - } -} diff --git a/MapControl/MapOverlay.WPF.cs b/MapControl/MapOverlay.WPF.cs deleted file mode 100644 index 4ff41f9f..00000000 --- a/MapControl/MapOverlay.WPF.cs +++ /dev/null @@ -1,151 +0,0 @@ -// XAML Map Control - http://xamlmapcontrol.codeplex.com/ -// Copyright © 2013 Clemens Fischer -// Licensed under the Microsoft Public License (Ms-PL) - -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Shapes; - -namespace MapControl -{ - public partial class MapOverlay : FrameworkElement, IMapElement - { - public static readonly DependencyProperty BackgroundProperty = Control.BackgroundProperty.AddOwner( - typeof(MapOverlay)); - - public static readonly DependencyProperty FontSizeProperty = Control.FontSizeProperty.AddOwner( - typeof(MapOverlay)); - - public static readonly DependencyProperty FontFamilyProperty = Control.FontFamilyProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); - - public static readonly DependencyProperty FontStyleProperty = Control.FontStyleProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); - - public static readonly DependencyProperty FontStretchProperty = Control.FontStretchProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); - - public static readonly DependencyProperty FontWeightProperty = Control.FontWeightProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); - - public static readonly DependencyProperty ForegroundProperty = Control.ForegroundProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).ForegroundChanged((Brush)e.NewValue))); - - public static readonly DependencyProperty StrokeProperty = Shape.StrokeProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.Brush = (Brush)e.NewValue)); - - public static readonly DependencyProperty StrokeThicknessProperty = Shape.StrokeThicknessProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsMeasure, (o, e) => ((MapOverlay)o).pen.Thickness = (double)e.NewValue)); - - public static readonly DependencyProperty StrokeDashArrayProperty = Shape.StrokeDashArrayProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.DashStyle = new DashStyle((DoubleCollection)e.NewValue, ((MapOverlay)o).StrokeDashOffset))); - - public static readonly DependencyProperty StrokeDashOffsetProperty = Shape.StrokeDashOffsetProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.DashStyle = new DashStyle(((MapOverlay)o).StrokeDashArray, (double)e.NewValue))); - - public static readonly DependencyProperty StrokeDashCapProperty = Shape.StrokeDashCapProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.DashCap = (PenLineCap)e.NewValue)); - - public static readonly DependencyProperty StrokeStartLineCapProperty = Shape.StrokeStartLineCapProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.StartLineCap = (PenLineCap)e.NewValue)); - - public static readonly DependencyProperty StrokeEndLineCapProperty = Shape.StrokeEndLineCapProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.EndLineCap = (PenLineCap)e.NewValue)); - - public static readonly DependencyProperty StrokeLineJoinProperty = Shape.StrokeLineJoinProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.LineJoin = (PenLineJoin)e.NewValue)); - - public static readonly DependencyProperty StrokeMiterLimitProperty = Shape.StrokeMiterLimitProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).pen.MiterLimit = (double)e.NewValue)); - - private Pen pen; - private Typeface typeface; - - static MapOverlay() - { - UIElement.IsHitTestVisibleProperty.OverrideMetadata( - typeof(MapOverlay), new FrameworkPropertyMetadata(false)); - } - - public MapOverlay() - { - pen = new Pen - { - Brush = Stroke, - Thickness = StrokeThickness, - DashStyle = new DashStyle(StrokeDashArray, StrokeDashOffset), - DashCap = StrokeDashCap, - StartLineCap = StrokeStartLineCap, - EndLineCap = StrokeEndLineCap, - LineJoin = StrokeLineJoin, - MiterLimit = StrokeMiterLimit - }; - } - - public Brush Background - { - get { return (Brush)GetValue(BackgroundProperty); } - set { SetValue(BackgroundProperty, value); } - } - - protected Pen Pen - { - get - { - if (pen.Brush == null) - { - pen.Brush = Foreground; - } - - return pen; - } - } - - protected Typeface Typeface - { - get - { - if (typeface == null) - { - typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch); - } - - return typeface; - } - } - - protected virtual void OnViewportChanged() - { - InvalidateVisual(); - } - - private void OnViewportChanged(object sender, EventArgs e) - { - OnViewportChanged(); - } - - void IMapElement.ParentMapChanged(MapBase oldParentMap, MapBase newParentMap) - { - if (oldParentMap != null) - { - oldParentMap.ViewportChanged -= OnViewportChanged; - } - - if (newParentMap != null) - { - newParentMap.ViewportChanged += OnViewportChanged; - OnViewportChanged(); - } - } - - private void ForegroundChanged(Brush foreground) - { - if (Stroke == null) - { - pen.Brush = foreground; - } - } - } -} diff --git a/MapControl/MapOverlay.cs b/MapControl/MapOverlay.cs index e236d4e8..a3c37c9a 100644 --- a/MapControl/MapOverlay.cs +++ b/MapControl/MapOverlay.cs @@ -2,26 +2,70 @@ // Copyright © 2013 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) -#if NETFX_CORE -using Windows.UI.Text; -using Windows.UI.Xaml.Media; -#else using System.Windows; +using System.Windows.Controls; using System.Windows.Media; -#endif +using System.Windows.Shapes; namespace MapControl { /// /// Base class for map overlays with font, background, foreground and stroke properties. + /// Rendering is typically done by overriding OnRender in derived classes. /// - public partial class MapOverlay + public class MapOverlay : FrameworkElement, IMapElement { - public FontFamily FontFamily - { - get { return (FontFamily)GetValue(FontFamilyProperty); } - set { SetValue(FontFamilyProperty, value); } - } + public static readonly DependencyProperty FontSizeProperty = Control.FontSizeProperty.AddOwner( + typeof(MapOverlay)); + + public static readonly DependencyProperty FontFamilyProperty = Control.FontFamilyProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); + + public static readonly DependencyProperty FontStyleProperty = Control.FontStyleProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); + + public static readonly DependencyProperty FontStretchProperty = Control.FontStretchProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); + + public static readonly DependencyProperty FontWeightProperty = Control.FontWeightProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).typeface = null)); + + public static readonly DependencyProperty BackgroundProperty = Control.BackgroundProperty.AddOwner( + typeof(MapOverlay)); + + public static readonly DependencyProperty ForegroundProperty = Control.ForegroundProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata((o, e) => ((MapOverlay)o).ForegroundChanged())); + + public static readonly DependencyProperty StrokeProperty = Shape.StrokeProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeThicknessProperty = Shape.StrokeThicknessProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeDashArrayProperty = Shape.StrokeDashArrayProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeDashOffsetProperty = Shape.StrokeDashOffsetProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeDashCapProperty = Shape.StrokeDashCapProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(default(PenLineCap), FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeStartLineCapProperty = Shape.StrokeStartLineCapProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(default(PenLineCap), FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeEndLineCapProperty = Shape.StrokeEndLineCapProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(default(PenLineCap), FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeLineJoinProperty = Shape.StrokeLineJoinProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(default(PenLineJoin), FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + public static readonly DependencyProperty StrokeMiterLimitProperty = Shape.StrokeMiterLimitProperty.AddOwner( + typeof(MapOverlay), new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsRender, (o, e) => ((MapOverlay)o).pen = null)); + + private MapBase parentMap; + private Typeface typeface; + private Pen pen; public double FontSize { @@ -29,6 +73,12 @@ namespace MapControl set { SetValue(FontSizeProperty, value); } } + public FontFamily FontFamily + { + get { return (FontFamily)GetValue(FontFamilyProperty); } + set { SetValue(FontFamilyProperty, value); } + } + public FontStyle FontStyle { get { return (FontStyle)GetValue(FontStyleProperty); } @@ -47,6 +97,12 @@ namespace MapControl set { SetValue(FontWeightProperty, value); } } + public Brush Background + { + get { return (Brush)GetValue(BackgroundProperty); } + set { SetValue(BackgroundProperty, value); } + } + public Brush Foreground { get { return (Brush)GetValue(ForegroundProperty); } @@ -106,5 +162,75 @@ namespace MapControl get { return (double)GetValue(StrokeMiterLimitProperty); } set { SetValue(StrokeMiterLimitProperty, value); } } + + public MapBase ParentMap + { + get { return parentMap; } + set + { + if (parentMap != null) + { + parentMap.ViewportChanged -= (o, e) => OnViewportChanged(); + } + + parentMap = value; + + if (parentMap != null) + { + parentMap.ViewportChanged += (o, e) => OnViewportChanged(); + OnViewportChanged(); + } + } + } + + protected Typeface Typeface + { + get + { + if (typeface == null) + { + typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch); + } + + return typeface; + } + } + + protected Pen Pen + { + get + { + if (pen == null) + { + pen = new Pen + { + Brush = Stroke != null ? Stroke : Foreground, + Thickness = StrokeThickness, + DashStyle = new DashStyle(StrokeDashArray, StrokeDashOffset), + DashCap = StrokeDashCap, + StartLineCap = StrokeStartLineCap, + EndLineCap = StrokeEndLineCap, + LineJoin = StrokeLineJoin, + MiterLimit = StrokeMiterLimit + }; + + pen.Freeze(); + } + + return pen; + } + } + + protected virtual void OnViewportChanged() + { + } + + private void ForegroundChanged() + { + if (Stroke == null) + { + pen = null; + } + } } } diff --git a/MapControl/MapPanel.Silverlight.WinRT.cs b/MapControl/MapPanel.Silverlight.WinRT.cs index 9870243b..40dc0f46 100644 --- a/MapControl/MapPanel.Silverlight.WinRT.cs +++ b/MapControl/MapPanel.Silverlight.WinRT.cs @@ -72,5 +72,10 @@ namespace MapControl return parentMap; } + + internal void SetParentMap() + { + SetValue(ParentMapProperty, this); + } } } diff --git a/MapControl/MapPanel.WPF.cs b/MapControl/MapPanel.WPF.cs index 2fa6bc0d..8de26358 100644 --- a/MapControl/MapPanel.WPF.cs +++ b/MapControl/MapPanel.WPF.cs @@ -8,13 +8,20 @@ namespace MapControl { public partial class MapPanel { - public static readonly DependencyProperty ParentMapProperty = DependencyProperty.RegisterAttached( + private static readonly DependencyPropertyKey ParentMapPropertyKey = DependencyProperty.RegisterAttachedReadOnly( "ParentMap", typeof(MapBase), typeof(MapPanel), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, ParentMapPropertyChanged)); + public static readonly DependencyProperty ParentMapProperty = ParentMapPropertyKey.DependencyProperty; + public static MapBase GetParentMap(UIElement element) { return (MapBase)element.GetValue(ParentMapProperty); } + + internal void SetParentMap() + { + SetValue(ParentMapPropertyKey, this); + } } } diff --git a/MapControl/MapPanel.cs b/MapControl/MapPanel.cs index ddec9b19..3d32536e 100644 --- a/MapControl/MapPanel.cs +++ b/MapControl/MapPanel.cs @@ -18,7 +18,7 @@ namespace MapControl { internal interface IMapElement { - void ParentMapChanged(MapBase oldParentMap, MapBase newParentMap); + MapBase ParentMap { get; set; } } /// @@ -49,6 +49,41 @@ namespace MapControl return (Point?)element.GetValue(ViewportPositionProperty); } + private MapBase parentMap; + + public MapBase ParentMap + { + get { return parentMap; } + set + { + if (parentMap != null && parentMap != this) + { + parentMap.ViewportChanged -= (o, e) => OnViewportChanged(); + } + + parentMap = value; + + if (parentMap != null && parentMap != this) + { + parentMap.ViewportChanged += (o, e) => OnViewportChanged(); + OnViewportChanged(); + } + } + } + + protected virtual void OnViewportChanged() + { + foreach (UIElement element in InternalChildren) + { + var location = GetLocation(element); + + if (location != null) + { + SetViewportPosition(element, parentMap, location); + } + } + } + protected override Size MeasureOverride(Size availableSize) { foreach (UIElement element in InternalChildren) @@ -61,8 +96,6 @@ namespace MapControl protected override Size ArrangeOverride(Size finalSize) { - var parentMap = GetParentMap(this); - foreach (UIElement element in InternalChildren) { var rect = new Rect(0d, 0d, element.DesiredSize.Width, element.DesiredSize.Height); @@ -92,47 +125,13 @@ namespace MapControl return finalSize; } - protected virtual void OnViewportChanged() - { - var parentMap = GetParentMap(this); - - foreach (UIElement element in InternalChildren) - { - var location = GetLocation(element); - - if (location != null) - { - SetViewportPosition(element, parentMap, location); - } - } - } - - private void OnViewportChanged(object sender, EventArgs e) - { - OnViewportChanged(); - } - - void IMapElement.ParentMapChanged(MapBase oldParentMap, MapBase newParentMap) - { - if (oldParentMap != null && oldParentMap != this) - { - oldParentMap.ViewportChanged -= OnViewportChanged; - } - - if (newParentMap != null && newParentMap != this) - { - newParentMap.ViewportChanged += OnViewportChanged; - OnViewportChanged(); - } - } - private static void ParentMapPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { - var element = obj as IMapElement; + var mapElement = obj as IMapElement; - if (element != null) + if (mapElement != null) { - element.ParentMapChanged(e.OldValue as MapBase, e.NewValue as MapBase); + mapElement.ParentMap = e.NewValue as MapBase; } } @@ -142,7 +141,10 @@ namespace MapControl if (element != null) { - SetViewportPosition(element, GetParentMap(element), (Location)e.NewValue); + var mapElement = element as IMapElement; + var parentMap = mapElement != null ? mapElement.ParentMap : GetParentMap(element); + + SetViewportPosition(element, parentMap, (Location)e.NewValue); } } diff --git a/MapControl/MapPolyline.Silverlight.WinRT.cs b/MapControl/MapPolyline.Silverlight.WinRT.cs index 704bf6d2..9be7b8dd 100644 --- a/MapControl/MapPolyline.Silverlight.WinRT.cs +++ b/MapControl/MapPolyline.Silverlight.WinRT.cs @@ -5,38 +5,31 @@ using System.Linq; #if NETFX_CORE using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Shapes; #else -using System.Windows; using System.Windows.Media; -using System.Windows.Shapes; + #endif namespace MapControl { - public partial class MapPolyline : Path + public partial class MapPolyline { - protected readonly PathGeometry Geometry = new PathGeometry(); - public MapPolyline() + : base(new PathGeometry()) { - Data = Geometry; - MapPanel.AddParentMapHandlers(this); } - private void UpdateGeometry() + protected override void UpdateGeometry() { - var parentMap = MapPanel.GetParentMap(this); + var geometry = (PathGeometry)Geometry; var locations = Locations; Location first; - Geometry.Figures.Clear(); - - if (parentMap != null && locations != null && (first = locations.FirstOrDefault()) != null) + if (ParentMap != null && locations != null && (first = locations.FirstOrDefault()) != null) { var figure = new PathFigure { - StartPoint = parentMap.MapTransform.Transform(first), + StartPoint = ParentMap.MapTransform.Transform(first), IsClosed = IsClosed, IsFilled = IsClosed }; @@ -45,7 +38,7 @@ namespace MapControl foreach (var location in locations.Skip(1)) { - segment.Points.Add(parentMap.MapTransform.Transform(location)); + segment.Points.Add(ParentMap.MapTransform.Transform(location)); } if (segment.Points.Count > 0) @@ -53,12 +46,14 @@ namespace MapControl figure.Segments.Add(segment); } - Geometry.Figures.Add(figure); - Geometry.Transform = parentMap.ViewportTransform; + geometry.Figures.Clear(); + geometry.Figures.Add(figure); + geometry.Transform = ParentMap.ViewportTransform; } else { - Geometry.Transform = null; + geometry.Figures.Clear(); + geometry.ClearValue(Geometry.TransformProperty); } } } diff --git a/MapControl/MapPolyline.WPF.cs b/MapControl/MapPolyline.WPF.cs index 81c92246..ac53db55 100644 --- a/MapControl/MapPolyline.WPF.cs +++ b/MapControl/MapPolyline.WPF.cs @@ -4,42 +4,39 @@ using System.Linq; using System.Windows.Media; -using System.Windows.Shapes; namespace MapControl { - public partial class MapPolyline : Shape + public partial class MapPolyline { - protected readonly StreamGeometry Geometry = new StreamGeometry(); - - protected override Geometry DefiningGeometry + public MapPolyline() + : base(new StreamGeometry()) { - get { return Geometry; } } - private void UpdateGeometry() + protected override void UpdateGeometry() { - var parentMap = MapPanel.GetParentMap(this); + var geometry = (StreamGeometry)Geometry; var locations = Locations; Location first; - if (parentMap != null && locations != null && (first = locations.FirstOrDefault()) != null) + if (ParentMap != null && locations != null && (first = locations.FirstOrDefault()) != null) { - using (var context = Geometry.Open()) + using (var context = geometry.Open()) { - var startPoint = parentMap.MapTransform.Transform(first); - var points = locations.Skip(1).Select(l => parentMap.MapTransform.Transform(l)).ToList(); + var startPoint = ParentMap.MapTransform.Transform(first); + var points = locations.Skip(1).Select(l => ParentMap.MapTransform.Transform(l)).ToList(); context.BeginFigure(startPoint, IsClosed, IsClosed); context.PolyLineTo(points, true, false); } - Geometry.Transform = parentMap.ViewportTransform; + geometry.Transform = ParentMap.ViewportTransform; } else { - Geometry.Clear(); - Geometry.Transform = null; + geometry.Clear(); + geometry.ClearValue(Geometry.TransformProperty); } } } diff --git a/MapControl/MapPolyline.cs b/MapControl/MapPolyline.cs index d0e51a8b..99673c26 100644 --- a/MapControl/MapPolyline.cs +++ b/MapControl/MapPolyline.cs @@ -14,7 +14,7 @@ using System.Windows; namespace MapControl { - public partial class MapPolyline : IMapElement + public partial class MapPolyline : MapShape { #if NETFX_CORE // For WinRT, the Locations dependency property type is declared as object @@ -49,21 +49,6 @@ namespace MapControl set { SetValue(IsClosedProperty, value); } } - protected override Size MeasureOverride(Size constraint) - { - // Shape.MeasureOverride in WPF and WinRT sometimes return a Size with zero - // width or height, whereas Shape.MeasureOverride in Silverlight occasionally - // throws an ArgumentException, as it tries to create a Size from a negative - // width or height, apparently resulting from a transformed geometry in Path.Data. - // In either case it seems to be sufficient to simply return a non-zero size. - return new Size(1, 1); - } - - void IMapElement.ParentMapChanged(MapBase oldParentMap, MapBase newParentMap) - { - UpdateGeometry(); - } - private void LocationCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { UpdateGeometry(); diff --git a/MapControl/MapRectangle.cs b/MapControl/MapRectangle.cs new file mode 100644 index 00000000..4833aa96 --- /dev/null +++ b/MapControl/MapRectangle.cs @@ -0,0 +1,100 @@ +// XAML Map Control - http://xamlmapcontrol.codeplex.com/ +// Copyright © 2013 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +#if NETFX_CORE +using Windows.Foundation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; +#else +using System.Windows; +using System.Windows.Media; +#endif + +namespace MapControl +{ + public partial class MapRectangle : MapShape + { + private static Transform DefaultFillRelativeTransform = + Brush.RelativeTransformProperty.GetMetadata(typeof(Brush)).DefaultValue as Transform; + + public static readonly DependencyProperty SouthProperty = DependencyProperty.Register( + "South", typeof(double), typeof(MapRectangle), + new PropertyMetadata(double.NaN, (o, e) => ((MapRectangle)o).UpdateGeometry())); + + public static readonly DependencyProperty NorthProperty = DependencyProperty.Register( + "North", typeof(double), typeof(MapRectangle), + new PropertyMetadata(double.NaN, (o, e) => ((MapRectangle)o).UpdateGeometry())); + + public static readonly DependencyProperty WestProperty = DependencyProperty.Register( + "West", typeof(double), typeof(MapRectangle), + new PropertyMetadata(double.NaN, (o, e) => ((MapRectangle)o).UpdateGeometry())); + + public static readonly DependencyProperty EastProperty = DependencyProperty.Register( + "East", typeof(double), typeof(MapRectangle), + new PropertyMetadata(double.NaN, (o, e) => ((MapRectangle)o).UpdateGeometry())); + + public MapRectangle() + : base(new RectangleGeometry()) + { + } + + public double South + { + get { return (double)GetValue(SouthProperty); } + set { SetValue(SouthProperty, value); } + } + + public double North + { + get { return (double)GetValue(NorthProperty); } + set { SetValue(NorthProperty, value); } + } + + public double West + { + get { return (double)GetValue(WestProperty); } + set { SetValue(WestProperty, value); } + } + + public double East + { + get { return (double)GetValue(EastProperty); } + set { SetValue(EastProperty, value); } + } + + protected override void UpdateGeometry() + { + var geometry = (RectangleGeometry)Geometry; + + if (ParentMap != null && + !double.IsNaN(South) && !double.IsNaN(North) && + !double.IsNaN(West) && !double.IsNaN(East) && + South < North && West < East) + { + var p1 = ParentMap.MapTransform.Transform(new Location(South, West)); + var p2 = ParentMap.MapTransform.Transform(new Location(North, East)); + + geometry.Rect = new Rect(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y); + RenderTransform = ParentMap.ViewportTransform; + } + else + { + geometry.Rect = Rect.Empty; + ClearValue(RenderTransformProperty); + } + } + +//#if !NETFX_CORE && !SILVERLIGHT +// protected override void OnRender(DrawingContext drawingContext) +// { +// if (ParentMap != null) +// { +// drawingContext.PushTransform(ParentMap.ViewportTransform); +// drawingContext.DrawRectangle(Fill, null, ((RectangleGeometry)Geometry).Rect); +// drawingContext.Pop(); +// } +// } +//#endif + } +} diff --git a/MapControl/MapScale.cs b/MapControl/MapScale.cs index b952dc8e..bf7a10cb 100644 --- a/MapControl/MapScale.cs +++ b/MapControl/MapScale.cs @@ -15,13 +15,16 @@ namespace MapControl public class MapScale : MapOverlay { public static readonly DependencyProperty PaddingProperty = Control.PaddingProperty.AddOwner( - typeof(MapOverlay), new FrameworkPropertyMetadata(new Thickness(2d))); + typeof(MapScale), new FrameworkPropertyMetadata(new Thickness(2d))); private double length; private Size size; static MapScale() { + UIElement.IsHitTestVisibleProperty.OverrideMetadata( + typeof(MapScale), new FrameworkPropertyMetadata(false)); + FrameworkElement.MinWidthProperty.OverrideMetadata( typeof(MapScale), new FrameworkPropertyMetadata(100d)); @@ -46,11 +49,9 @@ namespace MapControl protected override Size MeasureOverride(Size availableSize) { - var parentMap = MapPanel.GetParentMap(this); - - if (parentMap != null && parentMap.CenterScale > 0d) + if (ParentMap != null && ParentMap.CenterScale > 0d) { - length = MinWidth / parentMap.CenterScale; + length = MinWidth / ParentMap.CenterScale; var magnitude = Math.Pow(10d, Math.Floor(Math.Log10(length))); if (length / magnitude < 2d) @@ -66,7 +67,7 @@ namespace MapControl length = 10d * magnitude; } - size.Width = length * parentMap.CenterScale + StrokeThickness + Padding.Left + Padding.Right; + size.Width = length * ParentMap.CenterScale + StrokeThickness + Padding.Left + Padding.Right; size.Height = FontSize + 2d * StrokeThickness + Padding.Top + Padding.Bottom; } else @@ -79,9 +80,7 @@ namespace MapControl protected override void OnRender(DrawingContext drawingContext) { - var parentMap = MapPanel.GetParentMap(this); - - if (parentMap != null) + if (ParentMap != null) { var x1 = Padding.Left + StrokeThickness / 2d; var x2 = size.Width - Padding.Right - StrokeThickness / 2d; @@ -89,7 +88,7 @@ namespace MapControl var y2 = size.Height - Padding.Bottom - StrokeThickness / 2d; var text = length >= 1000d ? string.Format("{0:0} km", length / 1000d) : string.Format("{0:0} m", length); - drawingContext.DrawRectangle(Background ?? parentMap.Background, null, new Rect(size)); + drawingContext.DrawRectangle(Background ?? ParentMap.Background, null, new Rect(size)); drawingContext.DrawLine(Pen, new Point(x1, y1), new Point(x1, y2)); drawingContext.DrawLine(Pen, new Point(x2, y1), new Point(x2, y2)); drawingContext.DrawLine(Pen, new Point(x1, y2), new Point(x2, y2)); diff --git a/MapControl/MapShape.Silverlight.WinRT.cs b/MapControl/MapShape.Silverlight.WinRT.cs new file mode 100644 index 00000000..fc4c4d65 --- /dev/null +++ b/MapControl/MapShape.Silverlight.WinRT.cs @@ -0,0 +1,23 @@ +// XAML Map Control - http://xamlmapcontrol.codeplex.com/ +// Copyright © 2013 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +#if NETFX_CORE +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Shapes; +#else +using System.Windows.Media; +using System.Windows.Shapes; +#endif + +namespace MapControl +{ + public partial class MapShape : Path + { + public MapShape(Geometry geometry) + { + Data = Geometry = geometry; + MapPanel.AddParentMapHandlers(this); + } + } +} diff --git a/MapControl/MapShape.WPF.cs b/MapControl/MapShape.WPF.cs new file mode 100644 index 00000000..e9421707 --- /dev/null +++ b/MapControl/MapShape.WPF.cs @@ -0,0 +1,22 @@ +// XAML Map Control - http://xamlmapcontrol.codeplex.com/ +// Copyright © 2013 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +using System.Windows.Media; +using System.Windows.Shapes; + +namespace MapControl +{ + public partial class MapShape : Shape + { + public MapShape(Geometry geometry) + { + Geometry = geometry; + } + + protected override Geometry DefiningGeometry + { + get { return Geometry; } + } + } +} diff --git a/MapControl/MapShape.cs b/MapControl/MapShape.cs new file mode 100644 index 00000000..e643d5d4 --- /dev/null +++ b/MapControl/MapShape.cs @@ -0,0 +1,49 @@ +// XAML Map Control - http://xamlmapcontrol.codeplex.com/ +// Copyright © 2013 Clemens Fischer +// Licensed under the Microsoft Public License (Ms-PL) + +#if NETFX_CORE +using Windows.Foundation; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Shapes; +#else +using System.Windows; +using System.Windows.Media; +#endif + +namespace MapControl +{ + /// + /// Base class for map shapes. + /// + public partial class MapShape : IMapElement + { + private MapBase parentMap; + + public MapBase ParentMap + { + get { return parentMap; } + set + { + parentMap = value; + UpdateGeometry(); + } + } + + protected readonly Geometry Geometry; + + protected virtual void UpdateGeometry() + { + } + + protected override Size MeasureOverride(Size constraint) + { + // Shape.MeasureOverride in WPF and WinRT sometimes return a Size with zero + // width or height, whereas Shape.MeasureOverride in Silverlight occasionally + // throws an ArgumentException, as it tries to create a Size from a negative + // width or height, apparently resulting from a transformed Geometry. + // In either case it seems to be sufficient to simply return a non-zero size. + return new Size(1, 1); + } + } +} diff --git a/MapControl/Properties/AssemblyInfo.cs b/MapControl/Properties/AssemblyInfo.cs index 040b4ae2..e410fb07 100644 --- a/MapControl/Properties/AssemblyInfo.cs +++ b/MapControl/Properties/AssemblyInfo.cs @@ -16,6 +16,6 @@ using System.Windows; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/MapControl/WinRT/MapControl.WinRT.csproj b/MapControl/WinRT/MapControl.WinRT.csproj index 392c8d1a..0b21109f 100644 --- a/MapControl/WinRT/MapControl.WinRT.csproj +++ b/MapControl/WinRT/MapControl.WinRT.csproj @@ -63,6 +63,9 @@ MapGraticule.Silverlight.WinRT.cs + + MapImage.cs + MapItem.Silverlight.WinRT.cs @@ -72,12 +75,6 @@ MapItemsControl.Silverlight.WinRT.cs - - MapOverlay.cs - - - MapOverlay.Silverlight.WinRT.cs - MapPanel.cs @@ -90,6 +87,15 @@ MapPolyline.Silverlight.WinRT.cs + + MapRectangle.cs + + + MapShape.cs + + + MapShape.Silverlight.WinRT.cs + MapTransform.cs diff --git a/MapControl/WinRT/Properties/AssemblyInfo.cs b/MapControl/WinRT/Properties/AssemblyInfo.cs index 34cf1ead..00ecaa45 100644 --- a/MapControl/WinRT/Properties/AssemblyInfo.cs +++ b/MapControl/WinRT/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs index 789da4d6..cdd1b20b 100644 --- a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs +++ b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication/10_535_330.jpg b/SampleApps/SilverlightApplication/10_535_330.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7eb2f5a71746b01a70dbdae4509923f8674552af GIT binary patch literal 7174 zcmbW5cTiK&m&X%YfCP{#p-7iNqz9xIApt@Uy@*H$0qNC3FOlAa2uKMKNrC@3~8i@&lvyMOKOd2{B@n|J5D@8{fe-n(=E%>P*hTtcICQ2-zi003TGfIo`> zO#n3&6^M$G8UzB-&`{GtSm+>NFa*lP%)r9U!E=S1gNut-P+XXo|C#_77wo#oHAyK1 z0>LA!pdv4=EG~nP{u=~HLqh`rL)hu)*roZn_@w{O_NNQLNc~q6IglSf#t0;51pes- z@LcGm1pdPS|1uyMIRzyZh?<5Ld@-T<5`YXyPEJNaPDx2YaWVV;#d81!BPA1`lm->E z$!!q7AB%KUMhUgRjfQSk%;ZNw8AtzU8d|o?>`)G&tHLl5QG~4Ab$JCvO)Vr!TSpgd zYG!U>X=QEWCErX9TDLdJzkL6>mHIDEZ2Z$wmMl zG=pa&^Sf#+a*cv@c|=q7I4DV5fS6HFTTwwJX_h*hokG+XzENRkxAD6am_$bIMX2jI z7)LmH;oY3T-+EP@M50#8X8y2HmV>z+P3dCjzp}dH=IV&GpA{RS13N>~Y!aG-`qAiJ z{4o_4Rv|^l(qv3Vi;V~@^hFvV=|yTJ=ZkS(o?YuCL7fA8t1hhOR-=Uv}YtW7Z! zmW~Brf+UNir4(ZUU^r|v)hSs_^vSR=Ja7iXVKS9`5v$=2)I&oc$~aOFpop7m(Nb4+ zQLU6s@xa#(c^@Xx7PjwFB0L^Xi;g+LneQ(zTZKp2z`T!$xcz;(Q1b>3V2lid(HHFi z^SZmoce9~Sz%g;$fJ68jV&ZO!$VB6FYB6xXiEB!s5iNJfeZcshIiAwZIS{7JF2HIq z?U@6QR!o<#^1i#R)}E`@j4~w4)PsHTDf@1LIKe!cbvN5X+2b>#__Gi8thKxy;iXRv zPlbeT-3x`(GB{Z=M_%;`9A`b4#AS8t2lUCeuxmd#_w?nH?9NY84}{ zKF3K&4KI=;YnH-sJ4e_R!#e0>3yBHxm$|5vz7|;_*|X}kyG2@F*XtN$h|gJfqjKKp?-tqvIpKe%e{}uCGa76h`(u^KPCU69* z!{;~ZWFY(mF3HXkGDj?|m>kiR-4v-miGvkiR7C|4$%47a2aJqGq0gX5w8^d9kRAz(;kKE( zKD3p%_<_M@kR>i6CdPUeUlA8FvDaG_jpho+vdM1=rTYvBbJvh@p66wk-G2KX8#*II zkuJB>9H6MGRVg&{HrFgoLB7w~emURP(^th4Dja5e?H%F3-Q+=J*?lWOM8VVqjFi|X zggf@7ZqPj7Im>SbpNc{zZ&ru8jb(uj*+w?9x$?GgRUCUC3EU0<+i9% zEvp4#szRItV$Fh2qZkJ$#yT>k&a{=W0BB*QQE@CLe_P<+uJbQwV<1jO#~n{Lsa_g+ zF)flU3t^&9jxa$29JPLl9(r5*wxT4+Qa%B9)C5GCj;e?Uxonu5CL9%mol@bOfMwRiu|o|;N$f| zi2G$p7`tw(_fM(cvYA<;QCT+`diC~>7Y#iMu9j&-X#RkS~; zf|PO|k?jcZoJ?vX$J^XviUObymJqKJ`Fz6e~;d{3R=nLh*gnSxlHEZp+R_U+C7Ts zRU?$KL>H>lq{7Pa7qn6u>yfgRQ^cSr-j8+L>O{Lv8Jaaf3D*K^I3KrKNF%(is|osH zc2Dc+crazfME~NHN_qYlp}GdQstS=X^c$x>=eUe`s(@X%lWss$)i~?&KDgY2?Z{8% zg|)D#Tynz~5)-%_x9{DP*`uf&#t;{h=i88tJH+VbVg zD`E_*FI}Xx3sw%!&|pUZvN2IbGNa-v1*c&Za>*|kb+;EP0@&jzP&Am$$CMS6xsHVN(!b?QD?uMH~C zB#B2%;Hj{!to)rA?NR+S8xf$FoJZFT?JP`IH!%xA>yB8{r#v!1RHRQ(%)JF-Q1NnU z@=#&I87XtY4kLRQ2_vI2cjYDP1;A00o6V1%lWT$fTgr?Fw-nGm($D8t zh^nFA^HyZ1eLkp;%XY|=M%UJi(U4H5Jv(}*u^V@Eo=1P>u{rA;uC?Ud!EN5VRetl< z&BY;aXb`w*qhT}{ecf(wyZk!den6$tE?0?$7#rR#XQ>!8CDg-mO`0kkJD-x^lyNiE zqm@%Np0o_Ep84oW;hD{Gs2`0MDV~Z^XP|JRN-y{&0;?d80{TibJb*39t911taJLcE zeh!zp&PFBMz)=NX*Ky;qL*^n%$xi7(U%4Vpw6fn=Ws5GWl>37ymJ$|rU~QX)zM zNH+J;z?y<9m9i+?vaF^v1p*+T#H z{9}r9Jin99D~)o0L|sZW4KpkJleeRai~7}vYP5gL`pzRM%DIS{BsCRJ1I^cpEk((v zwlci?Z$8luT5}sx^QPG}n-hn1RZ<4Gzt)(%nQCw-C~6K?=&;msyRYj$r#)(zmSNp6 z+GmrBUXW&eR6HHEUaUP>r9m{k^pB1Of3Y~JD>#LPF=|32yLQeFjGT?3Huv-*yYs{U z0J47W^ZEFY_j9_UbnT_a0(M1%T`09eUDbl}9tx?Ar1iY?@qrzMD_t%XDoOdM!F35G zt;G1VdWe@~%NhR3IyWk3(;}mwetcvxQQ;5Z%t9hXR^-Sbdf~FD&`>b94tGsOoT2*< zF7w+T_GZRURFk2I>fW`I>|)ze_6?c{0l$&SKa0t`ruK)wD02UX|g_|kKu2m_=YG$9gWbZo};Fg&GX3NN?SgM=BYzlxjBN> z!%IAK_=tBru?y{oqAboDP4$~W2RL$|2+)5qU=O>I6ZW!2)~qy%$+kk6q3h75s5Jzp zD~^|-;4=5~-G6}Oxo-DKN8i(O)W4Q90K&z*P-6BJrKUIXk%$J-mC` zY0+cAV}YCe)NH%u^iywsTHtYc$OENGgQLV(Q32P;cL4sDe*i@L0Pqf!^bNg0qf~=y z(6e-WT<+XI>o437uaIVTZMtj0S|g{R!0IhXN*qMi2cYTH>-v;sZ5-?^=7)g`Itrk4 zBceR_fUw|?AjBXvQUOKx_F6cu<>XP^Xk+7Wn0o?W!_vdJdo_>33)60DwPxfx)B=_y zE7`}C%y~Gh#QL+i7a)0t4_B|^L3gMq$f#9+T6FMxa(K=8J8fe?6Mq0vq-2?A?)|la z27$^gG}4r|+SQL+GWS}iZ1t&O^FPvTG~`X}liggZa!7Yj-{q@vHLMwzBfFTfZH;6= z5OzV9dESFVPe|tqK`>^n!jhOBRXXnpp1uD$Uc)F)YwH_9@G(_cSm=Qn$&EIl$WsWB z)1SfJd!+mZ;_ytWi@d!K`LRFcSB}#s$hbIkys|l9g>E7_RaPl`|6w4*@3@;TzuuH~ zc0S{ggvbC3OJ58(i-k41gsE!j22>A#*-Lse>GA$-&mb?o=EeJ-2zBowwY}cET-8#t zJ9Skjh7EaZ{M`JJgaP-rSUd5%Zlt2X4{lb~g?`FPmy87j zr;iS(hhv6sy*VAGN|)Q>l=)0>_KyMQrk}ov$x%6XZ2bhUs5s6Em+;0x(fKU?fK{Te zs>p<;&P(PS35U~MQNQMn;Z-edI_0UC4j3(#M#_?Z@c1+nYpp9qlU9#<+DRbgun)?>-E~+d$WU2 zONaveBzO4q>sjOjk?uZEJjV4K(`zPtM!gq#;fn~zBKBkYw3yd$dMV?s!$xOTM^HfW z1MYooGZd$~xp19bc&f@D0Q&ppQJE4+^(Yo^M`^r6yBfk9R3#?ipvT%9A;F)W&C9bQ z!WHw~?3#{AOmab{|3f08k4ajgP)~B#iu+ZL8&rOHGw7Mb!S5@LCln_7tzgKS21Hws zaRNKk_>ntW`$^&RuXw!ex?jKMPOuDh4xfL0XJ%gVo9v<$r=XWJpmYmfIW7S6vHD#hQMOC0_J(WSvVcs^$aP~!<;F|WsyUnMqV^WH{ClY355bZRsdPKr0+l7z zCuO=a!_@4X1g>@bHNOc~0bHXH14j+A>9kbmH|BmCF`&XDA_HEwnrTVSK90^1#J(Lh zNP;VF@TIbqoZf4X6s+S+U7J2Ix|ZlmD6#t3lXGZDz{E`O~eWi$XV8 z)}c8X3m|)s2|-K97T$eM^;hD>&u2RIizuutxUoH=bkXd#F`;Xm@U=oiX?29e`VJj` z>}lJ6>zdAOmCq6y1bCKs(`0_-- zAAoDU_MqijMBN{N)to`|h6Xf=A7U6P!2guILkd&FL9!($e|pQ*#*{FV)mDBb$f@we z5Q}?&e=AA8Ii}~t6Z9P0C4l{W(B}9yFi8w=+_)jS5*tz{fm>Oh+Sdy+t101)hEG)@ z<`O72U_(p(1?GhJQRcv(`({2lP1cts;4U8B{i1DNsZCU0iQ;C?fgj=CV$ZiR{tV?- zLG%>2^MjLj*ayeIaS-pug@r^9n{F)_YK+^N?~3hMP!r1YeS3d)Rh`w*>zPhDRZ5~8 zwJAKYgj!1lW%~Z=dfF`%z0wA*O`H~>oMZCUka};55a)VhQ&OW#{$LT?Q~La>P6L}G zGFv;6UDD@y0*Z&|L*6x@Y4_1Z-@#k(itY|o^XJ91Chbk8myRU!5HfU{PxDKT;9!LV zr=^E^oLX2 znHrt;v)3(2lUN_MG}+DCcN?;Y9ij|}i!MBYT4kSWw~t4v4>R;kr4d_~e8_VZ`qj|U z;1(CDH;nExg`J6CK~uE|s#RTISLd5s?aD!21VKNzHdiV|@lO&bmt_XV#6MVZZb;Hn z+nRgb@x|?gk242AZ7kcTOT=r>U6MJIM4zi!zq z3y0Z+rjbdWj`=maGx!I?R<<{uj+vIOYSJxBl)}wYvlbK?hO51#>7RnZ<(QP_D0(ZG zRBG@M`golq6~bx5=DI}x^ULRoC6?10InLUfk)d83IyXmB$+zVc%()`9{Y-1i*R0-| zM8|vOY;MOMc1xF_jQ0VIg#P31CzNJ^v(PVw_-Y~K=NY& zpNRs9Rxw?%q186I)Bd#~9rI z=5RWE*_>TDglDJO1N}TX*|Xd1OrcY=r}c}dUBzc^>#%_}tLN-Y@Hzfj;=&~#Uuj=- z74Lnd_UMU47jNLSQ6zkh{1!`ZDdk45>&r?gT0 zo=BB#k29?Hawf|u+(mY&&_GX6C`MDkZtp29Fdm0`E<)7m(o)7$eyPo3 z4N4iekts7Ib_nE3d9_3R7=U^T{SMN#=C{vqYtSq+td7M)@X2k{42ZVl&TM^%)J_ct zU!@7WGo|zqe{^cCHbvFor~zH(Fccb4RK}WBDH*+&C2#RF++zA>UcNnB;n18=8i0!8i9HABj?ve+h`6J!EG?_Go3#^h z-pdT=vAfG&NvKnuE~_cdn@4F2UXeUUj2!OOL%>XIWR0N zs3so-HN*J?6R*%vz(q;BZ3;_3&_vW+(welOj1NTPwdv8v@*Yaz%;BYz&*frYB7@@~ zk}7KG$~*K6OhTmym!+89i1YOtLAJwcymZb`|KVo1Yb~m_7Mx@5aqYDEE0CmAOKdG4k9Akl%8Z>&U#8TYKP9=h!s%2V(5uC z8MdQdHoL!EO$EAAflnQC_SN6_56F~h`bDik$Sxce*WZyUQgu-HfWeP7!qeF!y%6?SE) z%}Jd1bQWPy*|7nq5})h18skV3#j#}8%a%MT5!|QW6@A8vy^Z0DqzT6roslSeIgg&F z*(XIewhN&F@XNs-?8kfwXq|VZ-Xz1hec<4p;byufq-f_=bC_7+b&#DDMZD^a)a|V{ z0A$1GSo@{OjEK}eEvF{;zDHNnuXK*_fmm}T$q#xj(csjN4u zyIR)Siyl-|v|n*qei4mI%xY4D{&0IWSC-1pDz2`}Cd6BbF>3qip0nB>Pf5Kylq32+ z5OOwNw_#R<%Wh#`)gVybZ#?p + @@ -136,16 +138,27 @@ - + - - - - + + + + + + + + + + + + + + OpenStreetMap OpenCycleMap OCM Transport diff --git a/SampleApps/SilverlightApplication/MainPage.xaml.cs b/SampleApps/SilverlightApplication/MainPage.xaml.cs index 56e59501..f52de91f 100644 --- a/SampleApps/SilverlightApplication/MainPage.xaml.cs +++ b/SampleApps/SilverlightApplication/MainPage.xaml.cs @@ -1,6 +1,7 @@ using MapControl; using System; using System.Collections.Generic; +using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -20,7 +21,7 @@ namespace SilverlightApplication { InitializeComponent(); - ICollection polylines = (ICollection)Resources["Polylines"]; + var polylines = (ICollection)Resources["Polylines"]; polylines.Add( new SamplePolyline { @@ -32,7 +33,7 @@ namespace SilverlightApplication Locations = LocationCollection.Parse("53.5978,8.1212 53.6018,8.1494 53.5859,8.1554 53.5852,8.1531 53.5841,8.1539 53.5802,8.1392 53.5826,8.1309 53.5867,8.1317 53.5978,8.1212") }); - ICollection points = (ICollection)Resources["Points"]; + var points = (ICollection)Resources["Points"]; points.Add( new SamplePoint { @@ -71,7 +72,7 @@ namespace SilverlightApplication }); points.Add(movingPoint); - ICollection pushpins = (ICollection)Resources["Pushpins"]; + var pushpins = (ICollection)Resources["Pushpins"]; pushpins.Add( new SamplePoint { @@ -97,8 +98,7 @@ namespace SilverlightApplication Location = new Location(53.5207, 8.2323) }); - DispatcherTimer timer = new DispatcherTimer(); - timer.Interval = TimeSpan.FromSeconds(0.1); + var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) }; timer.Tick += MovePoint; timer.Start(); } @@ -121,7 +121,15 @@ namespace SilverlightApplication private void MapMouseMove(object sender, MouseEventArgs e) { - mouseLocation.Text = map.ViewportPointToLocation(e.GetPosition(map)).ToString(); + var location = map.ViewportPointToLocation(e.GetPosition(map)); + var longitude = Location.NormalizeLongitude(location.Longitude); + var latString = location.Latitude < 0 ? + string.Format(CultureInfo.InvariantCulture, "S {0:00.00000}", -location.Latitude) : + string.Format(CultureInfo.InvariantCulture, "N {0:00.00000}", location.Latitude); + var lonString = longitude < 0 ? + string.Format(CultureInfo.InvariantCulture, "W {0:000.00000}", -longitude) : + string.Format(CultureInfo.InvariantCulture, "E {0:000.00000}", longitude); + mouseLocation.Text = latString + "\n" + lonString; } private void TileLayerSelectionChanged(object sender, SelectionChangedEventArgs e) diff --git a/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs index 7a5c0583..abf046e3 100644 --- a/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/SilverlightApplication/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication/SilverlightApplication.csproj b/SampleApps/SilverlightApplication/SilverlightApplication.csproj index 8265ae75..c6af4cfe 100644 --- a/SampleApps/SilverlightApplication/SilverlightApplication.csproj +++ b/SampleApps/SilverlightApplication/SilverlightApplication.csproj @@ -107,6 +107,9 @@ MapControl.Silverlight + + + @@ -145,16 +147,25 @@ - - - + + + + + + + + + + + + - + OpenStreetMap OpenCycleMap OCM Transport diff --git a/SampleApps/StoreApplication/MainPage.xaml.cs b/SampleApps/StoreApplication/MainPage.xaml.cs index 098b5929..0d968f54 100644 --- a/SampleApps/StoreApplication/MainPage.xaml.cs +++ b/SampleApps/StoreApplication/MainPage.xaml.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Navigation; +using Windows.UI.Xaml.Controls.Primitives; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 @@ -24,7 +24,7 @@ namespace StoreApplication { this.InitializeComponent(); - ICollection polylines = (ICollection)Resources["Polylines"]; + var polylines = (ICollection)Resources["Polylines"]; polylines.Add( new SamplePolyline { @@ -36,7 +36,7 @@ namespace StoreApplication Locations = LocationCollection.Parse("53.5978,8.1212 53.6018,8.1494 53.5859,8.1554 53.5852,8.1531 53.5841,8.1539 53.5802,8.1392 53.5826,8.1309 53.5867,8.1317 53.5978,8.1212") }); - ICollection points = (ICollection)Resources["Points"]; + var points = (ICollection)Resources["Points"]; points.Add( new SamplePoint { @@ -75,7 +75,7 @@ namespace StoreApplication }); points.Add(movingPoint); - ICollection pushpins = (ICollection)Resources["Pushpins"]; + var pushpins = (ICollection)Resources["Pushpins"]; pushpins.Add( new SamplePoint { @@ -101,8 +101,7 @@ namespace StoreApplication Location = new Location(53.5207, 8.2323) }); - DispatcherTimer timer = new DispatcherTimer(); - timer.Interval = TimeSpan.FromSeconds(0.1); + var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) }; timer.Tick += MovePoint; timer.Start(); } @@ -118,13 +117,12 @@ namespace StoreApplication } } - /// - /// Invoked when this page is about to be displayed in a Frame. - /// - /// Event data that describes how this page was reached. The Parameter - /// property is typically used to configure the page. - protected override void OnNavigatedTo(NavigationEventArgs e) + private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e) { + if (mapImage != null) + { + mapImage.Opacity = e.NewValue / 100; + } } private void SeamarksClick(object sender, RoutedEventArgs e) diff --git a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs index 4a5f02eb..fe37a253 100644 --- a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.InteropServices; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] diff --git a/SampleApps/StoreApplication/StoreApplication.csproj b/SampleApps/StoreApplication/StoreApplication.csproj index ca2617c1..993e6857 100644 --- a/SampleApps/StoreApplication/StoreApplication.csproj +++ b/SampleApps/StoreApplication/StoreApplication.csproj @@ -50,6 +50,7 @@ + diff --git a/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs b/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs index 455d9077..90794e39 100644 --- a/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Windows; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] diff --git a/SampleApps/WpfApplication/10_535_330.jpg b/SampleApps/WpfApplication/10_535_330.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7eb2f5a71746b01a70dbdae4509923f8674552af GIT binary patch literal 7174 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 + @@ -196,17 +198,28 @@ - + - - - - + + + + + + + + + + + + + + diff --git a/SampleApps/WpfApplication/MainWindow.xaml.cs b/SampleApps/WpfApplication/MainWindow.xaml.cs index e36a6ffc..c4be346c 100644 --- a/SampleApps/WpfApplication/MainWindow.xaml.cs +++ b/SampleApps/WpfApplication/MainWindow.xaml.cs @@ -2,6 +2,7 @@ using MapControl; using System; using System.Collections.Generic; +using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -33,7 +34,7 @@ namespace WpfApplication InitializeComponent(); - ICollection polylines = (ICollection)Resources["Polylines"]; + var polylines = (ICollection)Resources["Polylines"]; polylines.Add( new SamplePolyline { @@ -45,7 +46,7 @@ namespace WpfApplication Locations = LocationCollection.Parse("53.5978,8.1212 53.6018,8.1494 53.5859,8.1554 53.5852,8.1531 53.5841,8.1539 53.5802,8.1392 53.5826,8.1309 53.5867,8.1317 53.5978,8.1212") }); - ICollection points = (ICollection)Resources["Points"]; + var points = (ICollection)Resources["Points"]; points.Add( new SamplePoint { @@ -84,7 +85,7 @@ namespace WpfApplication }); points.Add(movingPoint); - ICollection pushpins = (ICollection)Resources["Pushpins"]; + var pushpins = (ICollection)Resources["Pushpins"]; pushpins.Add( new SamplePoint { @@ -110,8 +111,7 @@ namespace WpfApplication Location = new Location(53.5207, 8.2323) }); - DispatcherTimer timer = new DispatcherTimer(); - timer.Interval = TimeSpan.FromSeconds(0.1); + var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) }; timer.Tick += MovePoint; timer.Start(); } @@ -151,7 +151,15 @@ namespace WpfApplication private void MapMouseMove(object sender, MouseEventArgs e) { - mouseLocation.Text = map.ViewportPointToLocation(e.GetPosition(map)).ToString(); + var location = map.ViewportPointToLocation(e.GetPosition(map)); + var longitude = Location.NormalizeLongitude(location.Longitude); + var latString = location.Latitude < 0 ? + string.Format(CultureInfo.InvariantCulture, "S {0:00.00000}", -location.Latitude) : + string.Format(CultureInfo.InvariantCulture, "N {0:00.00000}", location.Latitude); + var lonString = longitude < 0 ? + string.Format(CultureInfo.InvariantCulture, "W {0:000.00000}", -longitude) : + string.Format(CultureInfo.InvariantCulture, "E {0:000.00000}", longitude); + mouseLocation.Text = latString + "\n" + lonString; } private void MapManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e) diff --git a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs index 7137c03b..11e284e3 100644 --- a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs +++ b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Windows; [assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("1.1.10")] -[assembly: AssemblyFileVersion("1.1.10")] +[assembly: AssemblyVersion("1.2.0")] +[assembly: AssemblyFileVersion("1.2.0")] [assembly: ComVisible(false)] [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] diff --git a/SampleApps/WpfApplication/WpfApplication.csproj b/SampleApps/WpfApplication/WpfApplication.csproj index 3dbf53f1..78ba97a8 100644 --- a/SampleApps/WpfApplication/WpfApplication.csproj +++ b/SampleApps/WpfApplication/WpfApplication.csproj @@ -96,6 +96,9 @@ MapControl.WPF + + +