diff --git a/Caching/FileDbCache/Properties/AssemblyInfo.cs b/Caching/FileDbCache/Properties/AssemblyInfo.cs index f0d18cdf..bd589cba 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] diff --git a/Caching/ImageFileCache/ImageFileCache4.csproj b/Caching/ImageFileCache/ImageFileCache4.csproj new file mode 100644 index 00000000..871982db --- /dev/null +++ b/Caching/ImageFileCache/ImageFileCache4.csproj @@ -0,0 +1,50 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {275B9FAB-C9F8-447B-8C66-53C5E09E7F79} + Library + Properties + ImageFileCache + ImageFileCache4 + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + none + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + \ No newline at end of file diff --git a/Caching/ImageFileCache/Properties/AssemblyInfo.cs b/Caching/ImageFileCache/Properties/AssemblyInfo.cs index 28262461..637d6a46 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] diff --git a/MapControl/MapBase.WPF.cs b/MapControl/MapBase.WPF.cs index f786c9a7..85321e58 100644 --- a/MapControl/MapBase.WPF.cs +++ b/MapControl/MapBase.WPF.cs @@ -29,12 +29,11 @@ namespace MapControl partial void Initialize() { AddVisualChild(tileContainer); - - SizeChanged += OnRenderSizeChanged; } - private void OnRenderSizeChanged(object sender, SizeChangedEventArgs e) + protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { + base.OnRenderSizeChanged(sizeInfo); ResetTransformOrigin(); UpdateTransform(); } diff --git a/MapControl/MapBase.cs b/MapControl/MapBase.cs index 91eda0a3..9174dd10 100644 --- a/MapControl/MapBase.cs +++ b/MapControl/MapBase.cs @@ -366,7 +366,7 @@ namespace MapControl { viewportOrigin.X = Math.Min(Math.Max(origin.X, 0d), RenderSize.Width); viewportOrigin.Y = Math.Min(Math.Max(origin.Y, 0d), RenderSize.Height); - transformOrigin = CoerceLocation(ViewportPointToLocation(viewportOrigin)); + transformOrigin = ViewportPointToLocation(viewportOrigin); } /// @@ -405,16 +405,27 @@ namespace MapControl /// public void TransformMap(Point origin, Point translation, double rotation, double scale) { - if (rotation != 0d || scale != 1d) + SetTransformOrigin(origin); + + viewportOrigin.X += translation.X; + viewportOrigin.Y += translation.Y; + + if (rotation != 0d) { - SetTransformOrigin(origin); - SetProperty(HeadingProperty, CoerceHeading(Heading + rotation)); - SetProperty(ZoomLevelProperty, CoerceZoomLevel(ZoomLevel + Math.Log(scale, 2d))); - UpdateTransform(); + var heading = (((Heading + rotation) % 360d) + 360d) % 360d; + InternalSetValue(HeadingProperty, heading); + InternalSetValue(TargetHeadingProperty, heading); } + if (scale != 1d) + { + var zoomLevel = Math.Min(Math.Max(ZoomLevel + Math.Log(scale, 2d), MinZoomLevel), MaxZoomLevel); + InternalSetValue(ZoomLevelProperty, zoomLevel); + InternalSetValue(TargetZoomLevelProperty, zoomLevel); + } + + UpdateTransform(); ResetTransformOrigin(); - TranslateMap(translation); } /// @@ -423,10 +434,10 @@ namespace MapControl /// public void ZoomMap(Point origin, double zoomLevel) { - var targetZoomLebel = TargetZoomLevel; + var targetZoomLevel = TargetZoomLevel; TargetZoomLevel = zoomLevel; - if (TargetZoomLevel != targetZoomLebel) // TargetZoomLevel might be coerced + if (TargetZoomLevel != targetZoomLevel) // TargetZoomLevel might be coerced { SetTransformOrigin(origin); } @@ -561,27 +572,34 @@ namespace MapControl } } - private void SetProperty(DependencyProperty property, object value) + private void InternalSetValue(DependencyProperty property, object value) { internalPropertyChange = true; SetValue(property, value); internalPropertyChange = false; } - private Location CoerceLocation(Location location) + private bool CoerceLocation(Location location, double latitudeEpsilon = 0d) { - return new Location( - Math.Min(Math.Max(location.Latitude, -mapTransform.MaxLatitude), mapTransform.MaxLatitude), - Location.NormalizeLongitude(location.Longitude)); + var maxLatitude = mapTransform.MaxLatitude + latitudeEpsilon; + var latitude = Math.Min(Math.Max(location.Latitude, -maxLatitude), maxLatitude); + var longitude = Location.NormalizeLongitude(location.Longitude); + + if (location.Latitude != latitude || location.Longitude != longitude) + { + location.Latitude = latitude; + location.Longitude = longitude; + return true; + } + + return false; } - private void CoerceCenterProperty(DependencyProperty property, ref Location center) + private void CoerceCenterProperty(DependencyProperty property, Location center) { - Location coercedValue = CoerceLocation(center); - - if (!coercedValue.Equals(center)) + if (CoerceLocation(center)) { - SetProperty(property, coercedValue); + InternalSetValue(property, center); } } @@ -589,14 +607,14 @@ namespace MapControl { if (!internalPropertyChange) { - CoerceCenterProperty(CenterProperty, ref center); + CoerceCenterProperty(CenterProperty, center); ResetTransformOrigin(); UpdateTransform(); if (centerAnimation == null) { - SetProperty(TargetCenterProperty, center); - SetProperty(CenterPointProperty, new Point(center.Longitude, center.Latitude)); + InternalSetValue(TargetCenterProperty, center); + InternalSetValue(CenterPointProperty, new Point(center.Longitude, center.Latitude)); } } } @@ -605,9 +623,9 @@ namespace MapControl { if (!internalPropertyChange) { - CoerceCenterProperty(TargetCenterProperty, ref targetCenter); + CoerceCenterProperty(TargetCenterProperty, targetCenter); - if (targetCenter != Center) + if (!targetCenter.Equals(Center)) { if (centerAnimation != null) { @@ -637,8 +655,8 @@ namespace MapControl centerAnimation.Completed -= CenterAnimationCompleted; centerAnimation = null; - SetProperty(CenterProperty, TargetCenter); - SetProperty(CenterPointProperty, new Point(TargetCenter.Longitude, TargetCenter.Latitude)); + InternalSetValue(CenterProperty, TargetCenter); + InternalSetValue(CenterPointProperty, new Point(TargetCenter.Longitude, TargetCenter.Latitude)); ResetTransformOrigin(); UpdateTransform(); } @@ -648,7 +666,7 @@ namespace MapControl { if (!internalPropertyChange) { - SetProperty(CenterProperty, new Location(centerPoint.Y, centerPoint.X)); + InternalSetValue(CenterProperty, new Location(centerPoint.Y, centerPoint.X)); ResetTransformOrigin(); UpdateTransform(); } @@ -660,7 +678,7 @@ namespace MapControl if (coercedValue != minZoomLevel) { - SetProperty(MinZoomLevelProperty, coercedValue); + InternalSetValue(MinZoomLevelProperty, coercedValue); } else if (ZoomLevel < minZoomLevel) { @@ -674,7 +692,7 @@ namespace MapControl if (coercedValue != maxZoomLevel) { - SetProperty(MaxZoomLevelProperty, coercedValue); + InternalSetValue(MaxZoomLevelProperty, coercedValue); } else if (ZoomLevel > maxZoomLevel) { @@ -682,21 +700,17 @@ namespace MapControl } } - private double CoerceZoomLevel(double zoomLevel) - { - return Math.Min(Math.Max(zoomLevel, MinZoomLevel), MaxZoomLevel); - } - private bool CoerceZoomLevelProperty(DependencyProperty property, ref double zoomLevel) { - var coercedValue = CoerceZoomLevel(zoomLevel); + var coercedValue = Math.Min(Math.Max(zoomLevel, MinZoomLevel), MaxZoomLevel); if (coercedValue != zoomLevel) { - SetProperty(property, coercedValue); + InternalSetValue(property, coercedValue); + return true; } - return coercedValue != zoomLevel; + return false; } private void ZoomLevelPropertyChanged(double zoomLevel) @@ -708,7 +722,7 @@ namespace MapControl if (zoomLevelAnimation == null) { - SetProperty(TargetZoomLevelProperty, zoomLevel); + InternalSetValue(TargetZoomLevelProperty, zoomLevel); } } } @@ -744,24 +758,19 @@ namespace MapControl zoomLevelAnimation.Completed -= ZoomLevelAnimationCompleted; zoomLevelAnimation = null; - SetProperty(ZoomLevelProperty, TargetZoomLevel); + InternalSetValue(ZoomLevelProperty, TargetZoomLevel); UpdateTransform(); ResetTransformOrigin(); } } - private double CoerceHeading(double heading) - { - return (heading >= -180d && heading <= 360d) ? heading : ((heading + 360d) % 360d); - } - private void CoerceHeadingProperty(DependencyProperty property, ref double heading) { - var coercedValue = CoerceHeading(heading); + var coercedValue = (heading >= -180d && heading <= 360d) ? heading : (((heading % 360d) + 360d) % 360d); if (coercedValue != heading) { - SetProperty(property, coercedValue); + InternalSetValue(property, coercedValue); } } @@ -774,7 +783,7 @@ namespace MapControl if (headingAnimation == null) { - SetProperty(TargetHeadingProperty, heading); + InternalSetValue(TargetHeadingProperty, heading); } } } @@ -824,26 +833,32 @@ namespace MapControl headingAnimation.Completed -= HeadingAnimationCompleted; headingAnimation = null; - SetProperty(HeadingProperty, TargetHeading); + InternalSetValue(HeadingProperty, TargetHeading); UpdateTransform(); } } private void UpdateTransform() { - double scale; + var center = Center; + var origin = transformOrigin != null ? transformOrigin : center; + var scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, mapTransform.Transform(origin), viewportOrigin, RenderSize); if (transformOrigin != null) { - scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, mapTransform.Transform(transformOrigin), viewportOrigin, RenderSize); - SetProperty(CenterProperty, ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d))); - } - else - { - scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, mapTransform.Transform(Center), viewportOrigin, RenderSize); + center = ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d)); + var coerced = CoerceLocation(center, 1e-3); + + InternalSetValue(CenterProperty, center); + + if (coerced) + { + ResetTransformOrigin(); + scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, mapTransform.Transform(center), viewportOrigin, RenderSize); + } } - scale *= mapTransform.RelativeScale(Center) / MeterPerDegree; // Pixels per meter at center latitude + scale *= mapTransform.RelativeScale(center) / MeterPerDegree; // Pixels per meter at center latitude CenterScale = scale; SetTransformMatrixes(scale); diff --git a/MapControl/MercatorTransform.cs b/MapControl/MercatorTransform.cs index c33b7f12..f92d6f04 100644 --- a/MapControl/MercatorTransform.cs +++ b/MapControl/MercatorTransform.cs @@ -17,9 +17,11 @@ namespace MapControl /// public class MercatorTransform : MapTransform { + private static readonly double maxLatitude = Math.Atan(Math.Sinh(Math.PI)) / Math.PI * 180d; + public override double MaxLatitude { - get { return 85.0511287798066; } + get { return maxLatitude; } } public override double RelativeScale(Location location) diff --git a/MapControl/Properties/AssemblyInfo.cs b/MapControl/Properties/AssemblyInfo.cs index 462d9640..040b4ae2 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] diff --git a/MapControl/Tile.Silverlight.WinRT.cs b/MapControl/Tile.Silverlight.WinRT.cs index 2ceabe55..dbb32006 100644 --- a/MapControl/Tile.Silverlight.WinRT.cs +++ b/MapControl/Tile.Silverlight.WinRT.cs @@ -2,7 +2,6 @@ // Copyright © 2013 Clemens Fischer // Licensed under the Microsoft Public License (Ms-PL) - #if NETFX_CORE using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -19,7 +18,7 @@ namespace MapControl { public partial class Tile { - public readonly Image Image = new Image { Stretch = Stretch.Uniform, Opacity = 0d }; + public readonly Image Image = new Image { IsHitTestVisible = false, Opacity = 0d }; public ImageSource ImageSource { diff --git a/MapControl/TileImageLoader.WPF.cs b/MapControl/TileImageLoader.WPF.cs index eb4f6b87..1f910dff 100644 --- a/MapControl/TileImageLoader.WPF.cs +++ b/MapControl/TileImageLoader.WPF.cs @@ -147,19 +147,20 @@ namespace MapControl { Interlocked.Increment(ref downloadThreadCount); - ThreadPool.QueueUserWorkItem(LoadTiles); + ThreadPool.QueueUserWorkItem(LoadTiles, imageTileSource); } } } - private void LoadTiles(object o) + private void LoadTiles(object tileSource) { + var imageTileSource = (ImageTileSource)tileSource; Tile tile; + while (pendingTiles.TryDequeue(out tile)) { byte[] buffer = null; ImageSource image = null; - var imageTileSource = tileLayer.TileSource as ImageTileSource; if (imageTileSource != null) { @@ -176,14 +177,17 @@ namespace MapControl { var uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel); - if (uri.Scheme != "http") + if (uri != null) { - image = CreateImage(uri); - } - else - { - buffer = DownloadImage(uri); - image = CreateImage(buffer); + if (uri.Scheme == "http") + { + buffer = DownloadImage(uri); + image = CreateImage(buffer); + } + else + { + image = CreateImage(uri); + } } } @@ -203,7 +207,7 @@ namespace MapControl Interlocked.Decrement(ref downloadThreadCount); } - private ImageSource CreateImage(Uri uri) + private static ImageSource CreateImage(Uri uri) { var image = new BitmapImage(); @@ -224,15 +228,15 @@ namespace MapControl return image; } - private ImageSource CreateImage(byte[] buffer) + private static ImageSource CreateImage(byte[] buffer) { BitmapImage image = null; - if (buffer != null && buffer.Length > 8) + if (buffer != null && buffer.Length > sizeof(long)) { try { - using (var stream = new MemoryStream(buffer, 8, buffer.Length - 8, false)) + using (var stream = new MemoryStream(buffer, sizeof(long), buffer.Length - sizeof(long), false)) { image = new BitmapImage(); image.BeginInit(); @@ -264,12 +268,12 @@ namespace MapControl using (var response = (HttpWebResponse)request.GetResponse()) using (var responseStream = response.GetResponseStream()) { - var length = response.ContentLength; var creationTime = DateTime.UtcNow.ToBinary(); + var length = (int)response.ContentLength; - using (var memoryStream = length > 0 ? new MemoryStream((int)length + 8) : new MemoryStream()) + using (var memoryStream = length > 0 ? new MemoryStream(length + sizeof(long)) : new MemoryStream()) { - memoryStream.Write(BitConverter.GetBytes(creationTime), 0, 8); + memoryStream.Write(BitConverter.GetBytes(creationTime), 0, sizeof(long)); responseStream.CopyTo(memoryStream); buffer = length > 0 ? memoryStream.GetBuffer() : memoryStream.ToArray(); diff --git a/MapControl/WinRT/Properties/AssemblyInfo.cs b/MapControl/WinRT/Properties/AssemblyInfo.cs index 3a46758e..34cf1ead 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs b/SampleApps/SilverlightApplication.Web/Properties/AssemblyInfo.cs index 9b7df7e6..789da4d6 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] diff --git a/SampleApps/SilverlightApplication/MainPage.xaml b/SampleApps/SilverlightApplication/MainPage.xaml index c14e619e..f58dae34 100644 --- a/SampleApps/SilverlightApplication/MainPage.xaml +++ b/SampleApps/SilverlightApplication/MainPage.xaml @@ -120,6 +120,12 @@ + + + + + + - + + + + + + + + + + + + + + diff --git a/SampleApps/StoreApplication/Properties/AssemblyInfo.cs b/SampleApps/StoreApplication/Properties/AssemblyInfo.cs index 41736ac1..4a5f02eb 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] diff --git a/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs b/SampleApps/SurfaceApplication/Properties/AssemblyInfo.cs index ecd2e635..455d9077 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] diff --git a/SampleApps/WpfApplication/MainWindow.xaml b/SampleApps/WpfApplication/MainWindow.xaml index 02887449..73b2a8a2 100644 --- a/SampleApps/WpfApplication/MainWindow.xaml +++ b/SampleApps/WpfApplication/MainWindow.xaml @@ -39,7 +39,7 @@ + TileSource="file:///C:/ProgramData/MapControl/TileCache/OpenStreetMap/{z}/{x}/{y}.png"/>--> @@ -181,6 +181,12 @@ + + + + + + diff --git a/SampleApps/WpfApplication/Properties/AssemblyInfo.cs b/SampleApps/WpfApplication/Properties/AssemblyInfo.cs index 3193fc37..7137c03b 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.9")] -[assembly: AssemblyFileVersion("1.1.9")] +[assembly: AssemblyVersion("1.1.10")] +[assembly: AssemblyFileVersion("1.1.10")] [assembly: ComVisible(false)] [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]