Version 2.1.0:

- TileImageLoader with local file caching in WinRT
- Location implements IEquatable
- Removed Surface sample application
This commit is contained in:
ClemensF 2014-07-09 21:27:28 +02:00
parent 10527c3f0d
commit 4e0253aa70
38 changed files with 493 additions and 393 deletions

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -38,16 +38,15 @@ namespace MapControl
public static void DrawGlyphRun(this DrawingContext drawingContext, Brush foreground, GlyphRun glyphRun, public static void DrawGlyphRun(this DrawingContext drawingContext, Brush foreground, GlyphRun glyphRun,
Point position, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) Point position, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment)
{ {
var bbox = glyphRun.ComputeInkBoundingBox(); var boundingBox = glyphRun.ComputeInkBoundingBox();
var transform = new TranslateTransform(position.X - bbox.X, position.Y - bbox.Y);
switch (horizontalAlignment) switch (horizontalAlignment)
{ {
case HorizontalAlignment.Center: case HorizontalAlignment.Center:
transform.X -= bbox.Width / 2d; position.X -= boundingBox.Width / 2d;
break; break;
case HorizontalAlignment.Right: case HorizontalAlignment.Right:
transform.X -= bbox.Width; position.X -= boundingBox.Width;
break; break;
default: default:
break; break;
@ -56,16 +55,16 @@ namespace MapControl
switch (verticalAlignment) switch (verticalAlignment)
{ {
case VerticalAlignment.Center: case VerticalAlignment.Center:
transform.Y -= bbox.Height / 2d; position.Y -= boundingBox.Height / 2d;
break; break;
case VerticalAlignment.Bottom: case VerticalAlignment.Bottom:
transform.Y -= bbox.Height; position.Y -= boundingBox.Height;
break; break;
default: default:
break; break;
} }
drawingContext.PushTransform(transform); drawingContext.PushTransform(new TranslateTransform(position.X - boundingBox.X, position.Y - boundingBox.Y));
drawingContext.DrawGlyphRun(foreground, glyphRun); drawingContext.DrawGlyphRun(foreground, glyphRun);
drawingContext.Pop(); drawingContext.Pop();
} }

View file

@ -0,0 +1,14 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System.Threading.Tasks;
namespace MapControl
{
public interface IObjectCache
{
Task<object> GetAsync(string key);
Task SetAsync(string key, object value);
}
}

View file

@ -0,0 +1,62 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
namespace MapControl
{
public class ImageFileCache : IObjectCache
{
private readonly IStorageFolder rootFolder;
public ImageFileCache()
{
rootFolder = ApplicationData.Current.TemporaryFolder;
}
public ImageFileCache(IStorageFolder folder)
{
rootFolder = folder;
}
public async Task<object> GetAsync(string key)
{
try
{
return await PathIO.ReadBufferAsync(Path.Combine(rootFolder.Path, key));
}
catch
{
return null;
}
}
public async Task SetAsync(string key, object value)
{
try
{
var buffer = (IBuffer)value;
var names = key.Split('\\');
var folder = rootFolder;
for (int i = 0; i < names.Length - 1; i++)
{
folder = await folder.CreateFolderAsync(names[i], CreationCollisionOption.OpenIfExists);
}
var file = await folder.CreateFileAsync(names[names.Length - 1], CreationCollisionOption.ReplaceExisting);
await FileIO.WriteBufferAsync(file, buffer);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
}

View file

@ -10,7 +10,7 @@ namespace MapControl
/// <summary> /// <summary>
/// A geographic location with latitude and longitude values in degrees. /// A geographic location with latitude and longitude values in degrees.
/// </summary> /// </summary>
public partial class Location public partial class Location : IEquatable<Location>
{ {
private double latitude; private double latitude;
private double longitude; private double longitude;
@ -37,6 +37,23 @@ namespace MapControl
set { longitude = value; } set { longitude = value; }
} }
public bool Equals(Location location)
{
return location != null
&& location.latitude == latitude
&& location.longitude == longitude;
}
public override bool Equals(object obj)
{
return Equals(obj as Location);
}
public override int GetHashCode()
{
return latitude.GetHashCode() ^ longitude.GetHashCode();
}
public override string ToString() public override string ToString()
{ {
return string.Format(CultureInfo.InvariantCulture, "{0:F5},{1:F5}", latitude, longitude); return string.Format(CultureInfo.InvariantCulture, "{0:F5},{1:F5}", latitude, longitude);

View file

@ -579,7 +579,7 @@ namespace MapControl
{ {
AdjustCenterProperty(TargetCenterProperty, ref targetCenter); AdjustCenterProperty(TargetCenterProperty, ref targetCenter);
if (targetCenter.Latitude != Center.Latitude || targetCenter.Longitude != Center.Longitude) if (!targetCenter.Equals(Center))
{ {
if (centerAnimation != null) if (centerAnimation != null)
{ {

View file

@ -106,7 +106,7 @@
<Compile Include="Tile.Silverlight.WinRT.cs" /> <Compile Include="Tile.Silverlight.WinRT.cs" />
<Compile Include="TileContainer.cs" /> <Compile Include="TileContainer.cs" />
<Compile Include="TileContainer.Silverlight.WinRT.cs" /> <Compile Include="TileContainer.Silverlight.WinRT.cs" />
<Compile Include="TileImageLoader.Silverlight.WinRT.cs" /> <Compile Include="TileImageLoader.Silverlight.cs" />
<Compile Include="TileLayer.cs" /> <Compile Include="TileLayer.cs" />
<Compile Include="TileLayerCollection.cs" /> <Compile Include="TileLayerCollection.cs" />
<Compile Include="TileSource.cs" /> <Compile Include="TileSource.cs" />

View file

@ -3,10 +3,10 @@
// Licensed under the Microsoft Public License (Ms-PL) // Licensed under the Microsoft Public License (Ms-PL)
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
#if WINDOWS_RUNTIME #if WINDOWS_RUNTIME
using Windows.Foundation; using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media;
@ -31,7 +31,7 @@ namespace MapControl
public MapGraticule() public MapGraticule()
{ {
IsHitTestVisible = false; IsHitTestVisible = false;
StrokeThickness = 0.5; Stroke = new SolidColorBrush(Color.FromArgb(127, 0, 0, 0));
path = new Path path = new Path
{ {
@ -55,7 +55,6 @@ namespace MapControl
protected override void OnViewportChanged() protected override void OnViewportChanged()
{ {
var geometry = (PathGeometry)path.Data;
var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), ParentMap.RenderSize)); var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), ParentMap.RenderSize));
var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); 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 end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height));
@ -88,28 +87,22 @@ namespace MapControl
graticuleStart = lineStart; graticuleStart = lineStart;
graticuleEnd = lineEnd; graticuleEnd = lineEnd;
var geometry = (PathGeometry)path.Data;
geometry.Figures.Clear(); geometry.Figures.Clear();
geometry.Transform = ParentMap.ViewportTransform; geometry.Transform = ParentMap.ViewportTransform;
var latLocations = new List<Location>((int)((end.Latitude - labelStart.Latitude) / spacing) + 1);
for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing) for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing)
{ {
var location = new Location(lat, lineStart.Longitude);
latLocations.Add(location);
var figure = new PathFigure var figure = new PathFigure
{ {
StartPoint = ParentMap.MapTransform.Transform(location), StartPoint = ParentMap.MapTransform.Transform(new Location(lat, lineStart.Longitude)),
IsClosed = false, IsClosed = false,
IsFilled = false IsFilled = false
}; };
location.Longitude = lineEnd.Longitude;
figure.Segments.Add(new LineSegment figure.Segments.Add(new LineSegment
{ {
Point = ParentMap.MapTransform.Transform(location), Point = ParentMap.MapTransform.Transform(new Location(lat, lineEnd.Longitude)),
}); });
geometry.Figures.Add(figure); geometry.Figures.Add(figure);
@ -134,14 +127,11 @@ namespace MapControl
var childIndex = 1; // 0 for Path var childIndex = 1; // 0 for Path
var format = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°"; var format = spacing < 1d ? "{0} {1}°{2:00}'" : "{0} {1}°";
var measureSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
foreach (var location in latLocations) for (var lat = labelStart.Latitude; lat <= end.Latitude; lat += spacing)
{ {
for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing) for (var lon = labelStart.Longitude; lon <= end.Longitude; lon += spacing)
{ {
location.Longitude = lon;
TextBlock label; TextBlock label;
if (childIndex < Children.Count) if (childIndex < Children.Count)
@ -150,9 +140,14 @@ namespace MapControl
} }
else else
{ {
var renderTransform = new TransformGroup();
renderTransform.Children.Add(new TranslateTransform());
renderTransform.Children.Add(ParentMap.RotateTransform);
renderTransform.Children.Add(new TranslateTransform());
label = new TextBlock label = new TextBlock
{ {
RenderTransform = new TransformGroup() RenderTransform = renderTransform
}; };
label.SetBinding(TextBlock.ForegroundProperty, new Binding label.SetBinding(TextBlock.ForegroundProperty, new Binding
@ -175,30 +170,13 @@ namespace MapControl
label.FontStyle = FontStyle; label.FontStyle = FontStyle;
label.FontStretch = FontStretch; label.FontStretch = FontStretch;
label.FontWeight = FontWeight; label.FontWeight = FontWeight;
label.Text = string.Format("{0}\n{1}", CoordinateString(lat, format, "NS"), CoordinateString(Location.NormalizeLongitude(lon), format, "EW"));
label.Tag = new Location(lat, lon);
label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
label.Text = string.Format("{0}\n{1}", var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0];
CoordinateString(location.Latitude, format, "NS"),
CoordinateString(Location.NormalizeLongitude(location.Longitude), format, "EW"));
label.Measure(measureSize);
var transformGroup = (TransformGroup)label.RenderTransform;
if (transformGroup.Children.Count == 0)
{
transformGroup.Children.Add(new TranslateTransform());
transformGroup.Children.Add(ParentMap.RotateTransform);
transformGroup.Children.Add(new TranslateTransform());
}
var translateTransform = (TranslateTransform)transformGroup.Children[0];
translateTransform.X = StrokeThickness / 2d + 2d; translateTransform.X = StrokeThickness / 2d + 2d;
translateTransform.Y = -label.DesiredSize.Height / 2d; translateTransform.Y = -label.DesiredSize.Height / 2d;
var viewportPosition = ParentMap.LocationToViewportPoint(location);
translateTransform = (TranslateTransform)transformGroup.Children[2];
translateTransform.X = viewportPosition.X;
translateTransform.Y = viewportPosition.Y;
} }
} }
@ -208,6 +186,18 @@ namespace MapControl
} }
} }
// don't use MapPanel.Location because labels may be at more than 180° distance from map center
for (int i = 1; i < Children.Count; i++)
{
var label = (TextBlock)Children[i];
var location = (Location)label.Tag;
var viewportTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[2];
var viewportPosition = ParentMap.LocationToViewportPoint(location);
viewportTransform.X = viewportPosition.X;
viewportTransform.Y = viewportPosition.Y;
}
base.OnViewportChanged(); base.OnViewportChanged();
} }
} }

View file

@ -2,6 +2,7 @@
// Copyright © 2014 Clemens Fischer // Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL) // Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_RUNTIME #if WINDOWS_RUNTIME
using Windows.UI.Xaml; using Windows.UI.Xaml;
#else #else
@ -43,7 +44,7 @@ namespace MapControl
hemisphere = hemispheres[1]; hemisphere = hemispheres[1];
} }
var minutes = (int)(value * 60d + 0.5); var minutes = (int)Math.Round(value * 60d);
return string.Format(format, hemisphere, minutes / 60, (double)(minutes % 60)); return string.Format(format, hemisphere, minutes / 60, (double)(minutes % 60));
} }

View file

@ -14,8 +14,8 @@ using System.Windows;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -13,12 +13,6 @@ namespace MapControl
{ {
internal partial class TileContainer internal partial class TileContainer
{ {
private Matrix GetViewportTransformMatrix(double scale, double offsetX, double offsetY)
{
return new Matrix(scale, 0d, 0d, -scale, offsetX, offsetY)
.RotateAt(rotation, viewportOrigin.X, viewportOrigin.Y);
}
private Matrix GetTileIndexMatrix(int numTiles) private Matrix GetTileIndexMatrix(int numTiles)
{ {
var scale = (double)numTiles / 360d; var scale = (double)numTiles / 360d;
@ -29,6 +23,13 @@ namespace MapControl
.Scale(scale, -scale); // map coordinates to tile indices .Scale(scale, -scale); // map coordinates to tile indices
} }
private void UpdateViewportTransform(double scale, double offsetX, double offsetY)
{
ViewportTransform.Matrix =
new Matrix(scale, 0d, 0d, -scale, offsetX, offsetY)
.RotateAt(rotation, viewportOrigin.X, viewportOrigin.Y);
}
/// <summary> /// <summary>
/// Sets a RenderTransform with origin at tileGrid.X and tileGrid.Y to minimize rounding errors. /// Sets a RenderTransform with origin at tileGrid.X and tileGrid.Y to minimize rounding errors.
/// </summary> /// </summary>

View file

@ -9,14 +9,6 @@ namespace MapControl
{ {
internal partial class TileContainer internal partial class TileContainer
{ {
private Matrix GetViewportTransformMatrix(double scale, double offsetX, double offsetY)
{
var transform = new Matrix(scale, 0d, 0d, -scale, offsetX, offsetY);
transform.RotateAt(rotation, viewportOrigin.X, viewportOrigin.Y);
return transform;
}
private Matrix GetTileIndexMatrix(int numTiles) private Matrix GetTileIndexMatrix(int numTiles)
{ {
var scale = (double)numTiles / 360d; var scale = (double)numTiles / 360d;
@ -28,6 +20,14 @@ namespace MapControl
return transform; return transform;
} }
private void UpdateViewportTransform(double scale, double offsetX, double offsetY)
{
var transform = new Matrix(scale, 0d, 0d, -scale, offsetX, offsetY);
transform.RotateAt(rotation, viewportOrigin.X, viewportOrigin.Y);
ViewportTransform.Matrix = transform;
}
/// <summary> /// <summary>
/// Sets a RenderTransform with origin at tileGrid.X and tileGrid.Y to minimize rounding errors. /// Sets a RenderTransform with origin at tileGrid.X and tileGrid.Y to minimize rounding errors.
/// </summary> /// </summary>

View file

@ -22,7 +22,7 @@ namespace MapControl
// relative scaled tile size ranges from 0.75 to 1.5 (192 to 384 pixels) // relative scaled tile size ranges from 0.75 to 1.5 (192 to 384 pixels)
private static double zoomLevelSwitchDelta = -Math.Log(0.75, 2d); private static double zoomLevelSwitchDelta = -Math.Log(0.75, 2d);
internal static TimeSpan UpdateInterval = TimeSpan.FromSeconds(0.5); public static TimeSpan UpdateInterval = TimeSpan.FromSeconds(0.5);
private readonly DispatcherTimer updateTimer; private readonly DispatcherTimer updateTimer;
private Size viewportSize; private Size viewportSize;
@ -102,7 +102,7 @@ namespace MapControl
var transformOffsetX = viewportOrigin.X - mapOrigin.X * scale; var transformOffsetX = viewportOrigin.X - mapOrigin.X * scale;
var transformOffsetY = viewportOrigin.Y + mapOrigin.Y * scale; var transformOffsetY = viewportOrigin.Y + mapOrigin.Y * scale;
ViewportTransform.Matrix = GetViewportTransformMatrix(scale, transformOffsetX, transformOffsetY); UpdateViewportTransform(scale, transformOffsetX, transformOffsetY);
tileLayerOffset.X = transformOffsetX - 180d * scale; tileLayerOffset.X = transformOffsetX - 180d * scale;
tileLayerOffset.Y = transformOffsetY - 180d * scale; tileLayerOffset.Y = transformOffsetY - 180d * scale;

View file

@ -1,64 +0,0 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Diagnostics;
#if WINDOWS_RUNTIME
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
#else
using System.Windows.Media;
using System.Windows.Media.Imaging;
#endif
namespace MapControl
{
/// <summary>
/// Loads map tile images.
/// </summary>
internal class TileImageLoader
{
internal void BeginGetTiles(TileLayer tileLayer, IEnumerable<Tile> tiles)
{
var imageTileSource = tileLayer.TileSource as ImageTileSource;
if (imageTileSource != null)
{
foreach (var tile in tiles)
{
try
{
var image = imageTileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
tile.SetImageSource(image, tileLayer.AnimateTileOpacity);
}
catch (Exception ex)
{
Debug.WriteLine("Loading tile image failed: {0}", ex.Message);
}
}
}
else
{
foreach (var tile in tiles)
{
try
{
var uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
var image = uri != null ? new BitmapImage(uri) : null;
tile.SetImageSource(image, tileLayer.AnimateTileOpacity);
}
catch (Exception ex)
{
Debug.WriteLine("Creating tile image failed: {0}", ex.Message);
}
}
}
}
public void CancelGetTiles()
{
}
}
}

View file

@ -0,0 +1,55 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace MapControl
{
/// <summary>
/// Loads map tile images.
/// </summary>
internal class TileImageLoader
{
internal void BeginGetTiles(TileLayer tileLayer, IEnumerable<Tile> tiles)
{
var imageTileSource = tileLayer.TileSource as ImageTileSource;
foreach (var tile in tiles)
{
try
{
ImageSource image = null;
if (imageTileSource != null)
{
image = imageTileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
}
else
{
var uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
if (uri != null)
{
image = new BitmapImage(uri);
}
}
tile.SetImageSource(image, tileLayer.AnimateTileOpacity);
}
catch (Exception ex)
{
Debug.WriteLine("Loading tile image failed: {0}", ex.Message);
}
}
}
internal void CancelGetTiles()
{
}
}
}

View file

@ -0,0 +1,196 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Web.Http;
using Windows.Web.Http.Filters;
namespace MapControl
{
/// <summary>
/// Loads map tile images.
/// </summary>
public class TileImageLoader
{
public static IObjectCache Cache { get; set; }
private HttpClient httpClient;
internal void BeginGetTiles(TileLayer tileLayer, IEnumerable<Tile> tiles)
{
var imageTileSource = tileLayer.TileSource as ImageTileSource;
foreach (var tile in tiles)
{
try
{
ImageSource image = null;
if (imageTileSource != null)
{
image = imageTileSource.LoadImage(tile.XIndex, tile.Y, tile.ZoomLevel);
}
else
{
var uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
if (uri != null)
{
if (Cache == null || string.IsNullOrEmpty(tileLayer.SourceName))
{
image = new BitmapImage(uri);
}
else
{
var bitmap = new BitmapImage();
image = bitmap;
Task.Run(async () => await LoadCachedImage(tileLayer, tile, uri, bitmap));
}
}
}
tile.SetImageSource(image, tileLayer.AnimateTileOpacity);
}
catch (Exception ex)
{
Debug.WriteLine("Loading tile image failed: {0}", ex.Message);
}
}
}
internal void CancelGetTiles()
{
}
private async Task LoadCachedImage(TileLayer tileLayer, Tile tile, Uri uri, BitmapImage bitmap)
{
var cacheKey = string.Format(@"{0}\{1}\{2}\{3}{4}",
tileLayer.SourceName, tile.ZoomLevel, tile.XIndex, tile.Y, Path.GetExtension(uri.LocalPath));
var buffer = await Cache.GetAsync(cacheKey) as IBuffer;
if (buffer != null)
{
await LoadImageFromBuffer(buffer, bitmap);
//Debug.WriteLine("Loaded cached image {0}", cacheKey);
}
else
{
DownloadAndCacheImage(uri, bitmap, cacheKey);
}
}
private async Task LoadImageFromBuffer(IBuffer buffer, BitmapImage bitmap)
{
using (var stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(buffer);
await stream.FlushAsync();
stream.Seek(0);
await bitmap.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
{
try
{
await bitmap.SetSourceAsync(stream);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
});
}
}
private void DownloadAndCacheImage(Uri uri, BitmapImage bitmap, string cacheKey)
{
try
{
if (httpClient == null)
{
var filter = new HttpBaseProtocolFilter();
filter.AllowAutoRedirect = false;
filter.CacheControl.ReadBehavior = HttpCacheReadBehavior.Default;
filter.CacheControl.WriteBehavior = HttpCacheWriteBehavior.NoCache;
httpClient = new HttpClient(filter);
}
httpClient.GetAsync(uri).Completed = async (request, status) =>
{
if (status == AsyncStatus.Completed)
{
using (var response = request.GetResults())
{
await LoadImageFromHttpResponse(response, bitmap, cacheKey);
}
}
else
{
Debug.WriteLine("{0}: {1}", uri, request.ErrorCode != null ? request.ErrorCode.Message : status.ToString());
}
};
}
catch (Exception ex)
{
Debug.WriteLine("{0}: {1}", uri, ex.Message);
}
}
private async Task LoadImageFromHttpResponse(HttpResponseMessage response, BitmapImage bitmap, string cacheKey)
{
if (response.IsSuccessStatusCode)
{
var stream = new InMemoryRandomAccessStream();
using (var content = response.Content)
{
await content.WriteToStreamAsync(stream);
}
await stream.FlushAsync();
stream.Seek(0);
await bitmap.Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
{
try
{
await bitmap.SetSourceAsync(stream);
// cache image asynchronously, after successful decoding
var task = Task.Run(async () =>
{
var buffer = new Windows.Storage.Streams.Buffer((uint)stream.Size);
stream.Seek(0);
await stream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None);
stream.Dispose();
await Cache.SetAsync(cacheKey, buffer);
});
}
catch (Exception ex)
{
Debug.WriteLine("{0}: {1}", response.RequestMessage.RequestUri, ex.Message);
stream.Dispose();
}
});
}
else
{
Debug.WriteLine("{0}: {1}", response.RequestMessage.RequestUri, response.StatusCode);
}
}
}
}

View file

@ -42,6 +42,9 @@
<Compile Include="..\Extensions.WinRT.cs"> <Compile Include="..\Extensions.WinRT.cs">
<Link>Extensions.WinRT.cs</Link> <Link>Extensions.WinRT.cs</Link>
</Compile> </Compile>
<Compile Include="..\ImageFileCache.WinRT.cs">
<Link>ImageFileCache.WinRT.cs</Link>
</Compile>
<Compile Include="..\ImageTileSource.Silverlight.WinRT.cs"> <Compile Include="..\ImageTileSource.Silverlight.WinRT.cs">
<Link>ImageTileSource.Silverlight.WinRT.cs</Link> <Link>ImageTileSource.Silverlight.WinRT.cs</Link>
</Compile> </Compile>
@ -51,6 +54,9 @@
<Compile Include="..\Int32Rect.cs"> <Compile Include="..\Int32Rect.cs">
<Link>Int32Rect.cs</Link> <Link>Int32Rect.cs</Link>
</Compile> </Compile>
<Compile Include="..\IObjectCache.WinRT.cs">
<Link>IObjectCache.WinRT.cs</Link>
</Compile>
<Compile Include="..\Location.cs"> <Compile Include="..\Location.cs">
<Link>Location.cs</Link> <Link>Location.cs</Link>
</Compile> </Compile>
@ -138,8 +144,8 @@
<Compile Include="..\TileContainer.Silverlight.WinRT.cs"> <Compile Include="..\TileContainer.Silverlight.WinRT.cs">
<Link>TileContainer.Silverlight.WinRT.cs</Link> <Link>TileContainer.Silverlight.WinRT.cs</Link>
</Compile> </Compile>
<Compile Include="..\TileImageLoader.Silverlight.WinRT.cs"> <Compile Include="..\TileImageLoader.WinRT.cs">
<Link>TileImageLoader.Silverlight.WinRT.cs</Link> <Link>TileImageLoader.WinRT.cs</Link>
</Compile> </Compile>
<Compile Include="..\TileLayer.cs"> <Compile Include="..\TileLayer.cs">
<Link>TileLayer.cs</Link> <Link>TileLayer.cs</Link>

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -35,7 +35,7 @@
<local:ObjectReferenceConverter x:Key="ObjectReferenceConverter"/> <local:ObjectReferenceConverter x:Key="ObjectReferenceConverter"/>
</Page.Resources> </Page.Resources>
<Grid> <Grid>
<map:MapBase x:Name="map" ZoomLevel="11" <map:MapBase x:Name="map" ZoomLevel="11" MinZoomLevel="2"
ManipulationMode="Scale,TranslateX,TranslateY,TranslateInertia" ManipulationMode="Scale,TranslateX,TranslateY,TranslateInertia"
ManipulationStarted="MapManipulationStarted" ManipulationStarted="MapManipulationStarted"
ManipulationCompleted="MapManipulationCompleted" ManipulationCompleted="MapManipulationCompleted"

View file

@ -14,7 +14,13 @@ namespace PhoneApplication
public MainPage() public MainPage()
{ {
TileImageLoader.Cache = new ImageFileCache();
InitializeComponent(); InitializeComponent();
var tileLayers = (TileLayerCollection)Resources["TileLayers"];
map.TileLayer = tileLayers[0];
DataContext = new ViewModel(Dispatcher); DataContext = new ViewModel(Dispatcher);
NavigationCacheMode = NavigationCacheMode.Required; NavigationCacheMode = NavigationCacheMode.Required;
} }

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -1,4 +1,5 @@
using System.Globalization; using System;
using System.Globalization;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
@ -22,14 +23,27 @@ namespace SilverlightApplication
private void MapMouseMove(object sender, MouseEventArgs e) private void MapMouseMove(object sender, MouseEventArgs e)
{ {
var location = map.ViewportPointToLocation(e.GetPosition(map)); var location = map.ViewportPointToLocation(e.GetPosition(map));
var longitude = Location.NormalizeLongitude(location.Longitude); var latitude = (int)Math.Round(location.Latitude * 60000d);
var latString = location.Latitude < 0 ? var longitude = (int)Math.Round(Location.NormalizeLongitude(location.Longitude) * 60000d);
string.Format(CultureInfo.InvariantCulture, "S {0:00.00000}", -location.Latitude) : var latHemisphere = 'N';
string.Format(CultureInfo.InvariantCulture, "N {0:00.00000}", location.Latitude); var lonHemisphere = 'E';
var lonString = longitude < 0 ?
string.Format(CultureInfo.InvariantCulture, "W {0:000.00000}", -longitude) : if (latitude < 0)
string.Format(CultureInfo.InvariantCulture, "E {0:000.00000}", longitude); {
mouseLocation.Text = latString + "\n" + lonString; latitude = -latitude;
latHemisphere = 'S';
}
if (longitude < 0)
{
longitude = -longitude;
lonHemisphere = 'W';
}
mouseLocation.Text = string.Format(CultureInfo.InvariantCulture,
"{0} {1:00} {2:00.000}\n{3} {4:000} {5:00.000}",
latHemisphere, latitude / 60000, (double)(latitude % 60000) / 1000d,
lonHemisphere, longitude / 60000, (double)(longitude % 60000) / 1000d);
} }
private void TileLayerSelectionChanged(object sender, SelectionChangedEventArgs e) private void TileLayerSelectionChanged(object sender, SelectionChangedEventArgs e)

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -22,6 +22,12 @@
<map:TileLayer SourceName="MapQuest OSM" Description="MapQuest OSM - © {y} MapQuest &amp; OpenStreetMap Contributors"> <map:TileLayer SourceName="MapQuest OSM" Description="MapQuest OSM - © {y} MapQuest &amp; OpenStreetMap Contributors">
<map:TileSource UriFormat="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"/> <map:TileSource UriFormat="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"/>
</map:TileLayer> </map:TileLayer>
<map:TileLayer SourceName="Bing Maps" Description="Bing Maps - © {y} Microsoft Corporation" MinZoomLevel="1" MaxZoomLevel="19">
<map:TileSource UriFormat="http://ecn.t{i}.tiles.virtualearth.net/tiles/r{q}.png?g=0&amp;stl=h"/>
</map:TileLayer>
<map:TileLayer SourceName="Bing Images" Description="Bing Maps - © {y} Microsoft Corporation" MinZoomLevel="1" MaxZoomLevel="19" Background="#FF3F3F3F" Foreground="White">
<map:TileSource UriFormat="http://ecn.t{i}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0"/>
</map:TileLayer>
<map:TileLayer SourceName="Seamarks" Description="© {y} OpenSeaMap Contributors, CC-BY-SA" MinZoomLevel="10" MaxZoomLevel="18"> <map:TileLayer SourceName="Seamarks" Description="© {y} OpenSeaMap Contributors, CC-BY-SA" MinZoomLevel="10" MaxZoomLevel="18">
<map:TileSource UriFormat="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"/> <map:TileSource UriFormat="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"/>
</map:TileLayer> </map:TileLayer>
@ -124,7 +130,7 @@
<RowDefinition/> <RowDefinition/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<map:Map x:Name="map" MinZoomLevel="2" Center="{Binding MapCenter}" MaxZoomLevel="18" ZoomLevel="11" Foreground="Black"> <map:Map x:Name="map" Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11" Foreground="Black">
<map:MapImage x:Name="mapImage" South="53.54031" North="53.74871" West="8.08594" East="8.43750" <map:MapImage x:Name="mapImage" South="53.54031" North="53.74871" West="8.08594" East="8.43750"
Source="10_535_330.jpg" Opacity="0.5"/> Source="10_535_330.jpg" Opacity="0.5"/>
<map:MapGraticule Opacity="0.6"/> <map:MapGraticule Opacity="0.6"/>
@ -190,6 +196,8 @@
<ComboBoxItem>OCM Transport</ComboBoxItem> <ComboBoxItem>OCM Transport</ComboBoxItem>
<ComboBoxItem>OCM Landscape</ComboBoxItem> <ComboBoxItem>OCM Landscape</ComboBoxItem>
<ComboBoxItem>MapQuest OSM</ComboBoxItem> <ComboBoxItem>MapQuest OSM</ComboBoxItem>
<ComboBoxItem>Bing Maps</ComboBoxItem>
<ComboBoxItem>Bing Images</ComboBoxItem>
</ComboBox> </ComboBox>
</StackPanel> </StackPanel>
</Grid> </Grid>

View file

@ -1,4 +1,5 @@
using MapControl; using MapControl;
using Windows.Storage;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Controls.Primitives;
@ -9,7 +10,12 @@ namespace StoreApplication
{ {
public MainPage() public MainPage()
{ {
TileImageLoader.Cache = new ImageFileCache();
this.InitializeComponent(); this.InitializeComponent();
var tileLayers = (TileLayerCollection)Resources["TileLayers"];
map.TileLayer = tileLayers[0];
} }
private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e) private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e)

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -1,3 +0,0 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>

View file

@ -1,12 +0,0 @@
<Application x:Class="SurfaceApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Microsoft.Surface.Presentation.Generic;v2.0.0.0;31bf3856ad364e35;component/themes\styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View file

@ -1,8 +0,0 @@
using System.Windows;
namespace SurfaceApplication
{
public partial class App : Application
{
}
}

View file

@ -1,12 +0,0 @@
<s:SurfaceWindow x:Class="SurfaceApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
xmlns:m="clr-namespace:MapControl;assembly=MapControl.WPF"
Title="SurfaceApplication" WindowStyle="None" WindowState="Maximized">
<Grid>
<m:Map Center="53.5,8.2" ZoomLevel="11" TouchDown="MapTouchDown">
<m:MapGraticule Opacity="0.5" MinLineSpacing="200"/>
</m:Map>
</Grid>
</s:SurfaceWindow>

View file

@ -1,28 +0,0 @@
using System.Windows.Input;
using Microsoft.Surface;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Surface.Presentation.Input;
namespace SurfaceApplication
{
public partial class MainWindow : SurfaceWindow
{
public MainWindow()
{
InitializeComponent();
}
private void MapTouchDown(object sender, TouchEventArgs e)
{
if (SurfaceEnvironment.IsSurfaceEnvironmentAvailable &&
!e.Device.GetIsFingerRecognized())
{
// If touch event is from a blob or tag, prevent touch capture by setting
// TouchEventArgs.Handled = true. Hence no manipulation will be started.
// See http://msdn.microsoft.com/en-us/library/ms754010#touch_and_manipulation
e.Handled = true;
}
}
}
}

View file

@ -1,15 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Surface Sample Application")]
[assembly: AssemblyDescription("XAML Map Control Sample Application for PixelSense (Surface 2)")]
[assembly: AssemblyProduct("XAML Map Control")]
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -1,97 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{6285FB9D-B7EA-469A-B464-224077967167}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SurfaceApplication</RootNamespace>
<AssemblyName>SurfaceApplication</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Microsoft.Surface" />
<Reference Include="Microsoft.Surface.Presentation" />
<Reference Include="Microsoft.Surface.Presentation.Generic" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<None Include="App.config" />
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<Content Include="SurfaceApplication.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\..\MapControl\MapControl.WPF.csproj">
<Project>{226f3575-b683-446d-a2f0-181291dc8787}</Project>
<Name>MapControl.WPF</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains the information needed to install your application
with the Surface Shell. Please refer to the documentation for deployment
instructions.
-->
<ss:ApplicationInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ss="http://schemas.microsoft.com/Surface/2007/ApplicationMetadata">
<Application>
<Title>SurfaceApplication</Title>
<Description>SurfaceApplication</Description>
<ExecutableFile>SurfaceApplication.exe</ExecutableFile>
<Arguments>
</Arguments>
<IconImageFile>Resources\icon.png</IconImageFile>
<Tags>
<!--
If your application uses tagged objects, please uncomment this section to register the tags with the Shell.
You can register Tags by using the appropriate instructions below.
-->
<!--
To register a specific value Tag:
1. Please uncomment the Tag Element below.
2. Replace "C0" below with the value of your Tag (in hexadecimal format). Repeat this section (this element and its children) for other Tags
3. Please remove the Launch element if you do not want to register the tag with Object Routing.
-->
<!--
<Tag Value="0xC0">
<Actions>
<Launch />
</Actions>
</Tag>
-->
<!--
To register all Tags in a series:
1. Please uncomment the Tag Element below.
2. Replace "0000000000000000" below with the series of your Tag (in hexadecimal format). Repeat this section (this element and its children) for other Tags
3. Please remove the Launch element if you do not want to register the tag with Object Routing.
-->
<!--
<Tag Series="0x0000000000000000">
<Actions>
<Launch />
</Actions>
</Tag>
-->
</Tags>
</Application>
</ss:ApplicationInfo>

View file

@ -2,7 +2,6 @@
using System.Globalization; using System.Globalization;
using System.Runtime.Caching; using System.Runtime.Caching;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Caching; using Caching;
using MapControl; using MapControl;
@ -56,14 +55,27 @@ namespace WpfApplication
private void MapMouseMove(object sender, MouseEventArgs e) private void MapMouseMove(object sender, MouseEventArgs e)
{ {
var location = map.ViewportPointToLocation(e.GetPosition(map)); var location = map.ViewportPointToLocation(e.GetPosition(map));
var longitude = Location.NormalizeLongitude(location.Longitude); var latitude = (int)Math.Round(location.Latitude * 60000d);
var latString = location.Latitude < 0 ? var longitude = (int)Math.Round(Location.NormalizeLongitude(location.Longitude) * 60000d);
string.Format(CultureInfo.InvariantCulture, "S {0:00.00000}", -location.Latitude) : var latHemisphere = 'N';
string.Format(CultureInfo.InvariantCulture, "N {0:00.00000}", location.Latitude); var lonHemisphere = 'E';
var lonString = longitude < 0 ?
string.Format(CultureInfo.InvariantCulture, "W {0:000.00000}", -longitude) : if (latitude < 0)
string.Format(CultureInfo.InvariantCulture, "E {0:000.00000}", longitude); {
mouseLocation.Text = latString + "\n" + lonString; latitude = -latitude;
latHemisphere = 'S';
}
if (longitude < 0)
{
longitude = -longitude;
lonHemisphere = 'W';
}
mouseLocation.Text = string.Format(CultureInfo.InvariantCulture,
"{0} {1:00} {2:00.000}\n{3} {4:000} {5:00.000}",
latHemisphere, latitude / 60000, (double)(latitude % 60000) / 1000d,
lonHemisphere, longitude / 60000, (double)(longitude % 60000) / 1000d);
} }
private void MapManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e) private void MapManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")] [assembly: AssemblyCopyright("Copyright © 2014 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.0.0")] [assembly: AssemblyVersion("2.1.0")]
[assembly: AssemblyFileVersion("2.0.0")] [assembly: AssemblyFileVersion("2.1.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]