Version 1.3.3: Fixed MapImageLayer.

This commit is contained in:
ClemensF 2013-05-15 15:58:07 +02:00
parent 5d6becbb50
commit 9264cf819a
12 changed files with 120 additions and 113 deletions

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -416,7 +416,7 @@ namespace MapControl
{ {
Loaded -= OnLoaded; Loaded -= OnLoaded;
if (TileLayer == null) if (TileLayer == null && TileLayers == null)
{ {
TileLayer = TileLayer.Default; TileLayer = TileLayer.Default;
} }

View file

@ -27,10 +27,12 @@ namespace MapControl
/// </summary> /// </summary>
public class MapImageLayer : MapPanel public class MapImageLayer : MapPanel
{ {
private static readonly DependencyProperty RelativeImageSizeProperty = DependencyProperty.Register(
"RelativeImageSize", typeof(double), typeof(MapImageLayer), new PropertyMetadata(1d));
private readonly DispatcherTimer updateTimer; private readonly DispatcherTimer updateTimer;
private string uriFormat; private string uriFormat;
private bool latLonBoundingBox; private bool latLonBoundingBox;
private bool imageIsValid;
private bool updateInProgress; private bool updateInProgress;
private int currentImageIndex; private int currentImageIndex;
@ -43,6 +45,12 @@ namespace MapControl
updateTimer.Tick += UpdateImage; updateTimer.Tick += UpdateImage;
} }
public double RelativeImageSize
{
get { return (double)GetValue(RelativeImageSizeProperty); }
set { SetValue(RelativeImageSizeProperty, value); }
}
public string UriFormat public string UriFormat
{ {
get { return uriFormat; } get { return uriFormat; }
@ -78,7 +86,6 @@ namespace MapControl
{ {
base.OnViewportChanged(); base.OnViewportChanged();
imageIsValid = false;
updateTimer.Stop(); updateTimer.Stop();
updateTimer.Start(); updateTimer.Start();
} }
@ -86,53 +93,57 @@ namespace MapControl
protected virtual ImageSource GetImage(double west, double east, double south, double north, int width, int height) protected virtual ImageSource GetImage(double west, double east, double south, double north, int width, int height)
{ {
ImageSource image = null; ImageSource image = null;
var uri = uriFormat.Replace("{X}", width.ToString()).Replace("{Y}", height.ToString());
if (latLonBoundingBox) if (uriFormat != null)
{ {
uri = uri. var uri = uriFormat.Replace("{X}", width.ToString()).Replace("{Y}", height.ToString());
Replace("{w}", west.ToString(CultureInfo.InvariantCulture)).
Replace("{s}", south.ToString(CultureInfo.InvariantCulture)).
Replace("{e}", east.ToString(CultureInfo.InvariantCulture)).
Replace("{n}", north.ToString(CultureInfo.InvariantCulture));
}
else
{
var p1 = ParentMap.MapTransform.Transform(new Location(south, west));
var p2 = ParentMap.MapTransform.Transform(new Location(north, east));
var arc = TileSource.EarthRadius * Math.PI / 180d;
uri = uri. if (latLonBoundingBox)
Replace("{W}", (arc * p1.X).ToString(CultureInfo.InvariantCulture)).
Replace("{S}", (arc * p1.Y).ToString(CultureInfo.InvariantCulture)).
Replace("{E}", (arc * p2.X).ToString(CultureInfo.InvariantCulture)).
Replace("{N}", (arc * p2.Y).ToString(CultureInfo.InvariantCulture));
}
try
{
var bitmap = new BitmapImage();
var request = (HttpWebRequest)WebRequest.Create(uri);
request.UserAgent = "XAML Map Control";
using (var response = (HttpWebResponse)request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{ {
responseStream.CopyTo(memoryStream); uri = uri.
Replace("{w}", west.ToString(CultureInfo.InvariantCulture)).
Replace("{s}", south.ToString(CultureInfo.InvariantCulture)).
Replace("{e}", east.ToString(CultureInfo.InvariantCulture)).
Replace("{n}", north.ToString(CultureInfo.InvariantCulture));
}
else
{
var p1 = ParentMap.MapTransform.Transform(new Location(south, west));
var p2 = ParentMap.MapTransform.Transform(new Location(north, east));
var arc = TileSource.EarthRadius * Math.PI / 180d;
bitmap.BeginInit(); uri = uri.
bitmap.CacheOption = BitmapCacheOption.OnLoad; Replace("{W}", (arc * p1.X).ToString(CultureInfo.InvariantCulture)).
bitmap.StreamSource = memoryStream; Replace("{S}", (arc * p1.Y).ToString(CultureInfo.InvariantCulture)).
bitmap.EndInit(); Replace("{E}", (arc * p2.X).ToString(CultureInfo.InvariantCulture)).
bitmap.Freeze(); Replace("{N}", (arc * p2.Y).ToString(CultureInfo.InvariantCulture));
} }
image = bitmap; try
} {
catch (Exception ex) var bitmap = new BitmapImage();
{ var request = (HttpWebRequest)WebRequest.Create(uri);
Trace.TraceWarning("{0}: {1}", uri, ex.Message); request.UserAgent = "XAML Map Control";
using (var response = (HttpWebResponse)request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
responseStream.CopyTo(memoryStream);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
bitmap.Freeze();
}
image = bitmap;
}
catch (Exception ex)
{
Trace.TraceWarning("{0}: {1}", uri, ex.Message);
}
} }
return image; return image;
@ -140,64 +151,60 @@ namespace MapControl
private void UpdateImage(object sender, EventArgs e) private void UpdateImage(object sender, EventArgs e)
{ {
updateTimer.Stop(); if (!updateInProgress)
if (updateInProgress || string.IsNullOrWhiteSpace(uriFormat))
{ {
return; updateTimer.Stop();
} updateInProgress = true;
imageIsValid = true; var relativeSize = Math.Max(RelativeImageSize, 1d);
updateInProgress = true; var width = ActualWidth * relativeSize;
var height = ActualHeight * relativeSize;
var dx = (ActualWidth - width) / 2d;
var dy = (ActualHeight - height) / 2d;
var loc1 = ParentMap.ViewportPointToLocation(new Point(dx, dy));
var loc2 = ParentMap.ViewportPointToLocation(new Point(width, dy));
var loc3 = ParentMap.ViewportPointToLocation(new Point(dx, height));
var loc4 = ParentMap.ViewportPointToLocation(new Point(width, height));
var loc1 = ParentMap.ViewportPointToLocation(new Point(0d, 0d)); ThreadPool.QueueUserWorkItem(o =>
var loc2 = ParentMap.ViewportPointToLocation(new Point(ActualWidth, 0d));
var loc3 = ParentMap.ViewportPointToLocation(new Point(0d, ActualHeight));
var loc4 = ParentMap.ViewportPointToLocation(new Point(ActualWidth, ActualHeight));
var width = (int)ActualWidth;
var height = (int)ActualHeight;
ThreadPool.QueueUserWorkItem(o =>
{
var west = Math.Min(loc1.Longitude, Math.Min(loc2.Longitude, Math.Min(loc3.Longitude, loc4.Longitude)));
var east = Math.Max(loc1.Longitude, Math.Max(loc2.Longitude, Math.Max(loc3.Longitude, loc4.Longitude)));
var south = Math.Min(loc1.Latitude, Math.Min(loc2.Latitude, Math.Min(loc3.Latitude, loc4.Latitude)));
var north = Math.Max(loc1.Latitude, Math.Max(loc2.Latitude, Math.Max(loc3.Latitude, loc4.Latitude)));
var image = GetImage(west, east, south, north, width, height);
if (image != null)
{ {
Dispatcher.BeginInvoke((Action)(() => var west = Math.Min(loc1.Longitude, Math.Min(loc2.Longitude, Math.Min(loc3.Longitude, loc4.Longitude)));
var east = Math.Max(loc1.Longitude, Math.Max(loc2.Longitude, Math.Max(loc3.Longitude, loc4.Longitude)));
var south = Math.Min(loc1.Latitude, Math.Min(loc2.Latitude, Math.Min(loc3.Latitude, loc4.Latitude)));
var north = Math.Max(loc1.Latitude, Math.Max(loc2.Latitude, Math.Max(loc3.Latitude, loc4.Latitude)));
var image = GetImage(west, east, south, north, (int)width, (int)height);
if (image != null)
{ {
var mapImage = (MapImage)Children[currentImageIndex]; Dispatcher.BeginInvoke((Action)(() => UpdateImage(west, east, south, north, image)));
mapImage.BeginAnimation(Image.OpacityProperty, }
new DoubleAnimation
{
To = 0,
Duration = Tile.AnimationDuration,
BeginTime = Tile.AnimationDuration
});
currentImageIndex = (currentImageIndex + 1) % 2; updateInProgress = false;
mapImage = (MapImage)Children[currentImageIndex]; });
mapImage.Source = null; }
mapImage.North = double.NaN; // avoid frequent MapRectangle.UpdateGeometry() calls }
mapImage.West = west;
mapImage.East = east;
mapImage.South = south;
mapImage.North = north;
mapImage.Source = image;
mapImage.BeginAnimation(Image.OpacityProperty, new DoubleAnimation(1d, Tile.AnimationDuration));
if (!imageIsValid) private void UpdateImage(double west, double east, double south, double north, ImageSource image)
{ {
UpdateImage(this, EventArgs.Empty); var mapImage = (MapImage)Children[currentImageIndex];
} mapImage.BeginAnimation(Image.OpacityProperty,
})); new DoubleAnimation
} {
To = 0d,
Duration = Tile.AnimationDuration,
BeginTime = Tile.AnimationDuration
});
updateInProgress = false; currentImageIndex = (currentImageIndex + 1) % 2;
}); mapImage = (MapImage)Children[currentImageIndex];
mapImage.Source = null;
mapImage.North = double.NaN; // avoid frequent MapRectangle.UpdateGeometry() calls
mapImage.West = west;
mapImage.East = east;
mapImage.South = south;
mapImage.North = north;
mapImage.Source = image;
mapImage.BeginAnimation(Image.OpacityProperty, new DoubleAnimation(1d, Tile.AnimationDuration));
} }
} }
} }

View file

@ -15,8 +15,8 @@ using System.Windows;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -19,7 +19,7 @@ namespace MapControl
internal partial class TileContainer internal partial class TileContainer
{ {
private const double maxScaledTileSize = 400d; // scaled tile size 200..400 units private const double maxScaledTileSize = 400d; // scaled tile size 200..400 units
private static double zoomLevelSwitchOffset = Math.Log(maxScaledTileSize / TileSource.TileSize, 2d); private static double zoomLevelSwitchDelta = Math.Log(maxScaledTileSize / TileSource.TileSize, 2d);
internal static TimeSpan UpdateInterval = TimeSpan.FromSeconds(0.5); internal static TimeSpan UpdateInterval = TimeSpan.FromSeconds(0.5);
@ -127,7 +127,7 @@ namespace MapControl
{ {
updateTimer.Stop(); updateTimer.Stop();
var zoom = (int)Math.Floor(zoomLevel + 1d - zoomLevelSwitchOffset); var zoom = (int)Math.Floor(zoomLevel + 1d - zoomLevelSwitchDelta);
var numTiles = 1 << zoom; var numTiles = 1 << zoom;
var transform = GetTileIndexMatrix(numTiles); var transform = GetTileIndexMatrix(numTiles);

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")] [assembly: AssemblyCopyright("Copyright © Clemens Fischer 2012-2013")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.3.2")] [assembly: AssemblyVersion("1.3.3")]
[assembly: AssemblyFileVersion("1.3.2")] [assembly: AssemblyFileVersion("1.3.3")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]