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 00000000..7eb2f5a7 Binary files /dev/null and b/SampleApps/SilverlightApplication/10_535_330.jpg differ diff --git a/SampleApps/SilverlightApplication/MainPage.xaml b/SampleApps/SilverlightApplication/MainPage.xaml index f58dae34..7a00141a 100644 --- a/SampleApps/SilverlightApplication/MainPage.xaml +++ b/SampleApps/SilverlightApplication/MainPage.xaml @@ -105,6 +105,8 @@ + @@ -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 00000000..7eb2f5a7 Binary files /dev/null and b/SampleApps/WpfApplication/10_535_330.jpg differ diff --git a/SampleApps/WpfApplication/MainWindow.xaml b/SampleApps/WpfApplication/MainWindow.xaml index 73b2a8a2..d4e48c6e 100644 --- a/SampleApps/WpfApplication/MainWindow.xaml +++ b/SampleApps/WpfApplication/MainWindow.xaml @@ -155,6 +155,8 @@ MouseLeftButtonDown="MapMouseLeftButtonDown" MouseRightButtonDown="MapMouseRightButtonDown" MouseMove="MapMouseMove" MouseLeave="MapMouseLeave" ManipulationInertiaStarting="MapManipulationInertiaStarting"> + @@ -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 + + +