mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Version 1.1.10: Fixed Center property coercion in MapBase.
This commit is contained in:
parent
35fc959034
commit
ec27d16119
|
|
@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
50
Caching/ImageFileCache/ImageFileCache4.csproj
Normal file
50
Caching/ImageFileCache/ImageFileCache4.csproj
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?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>{275B9FAB-C9F8-447B-8C66-53C5E09E7F79}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>ImageFileCache</RootNamespace>
|
||||||
|
<AssemblyName>ImageFileCache4</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
</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>
|
||||||
|
</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>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Runtime.Caching" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="ImageFileCache.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</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>
|
||||||
|
|
@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,11 @@ namespace MapControl
|
||||||
partial void Initialize()
|
partial void Initialize()
|
||||||
{
|
{
|
||||||
AddVisualChild(tileContainer);
|
AddVisualChild(tileContainer);
|
||||||
|
|
||||||
SizeChanged += OnRenderSizeChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRenderSizeChanged(object sender, SizeChangedEventArgs e)
|
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
|
||||||
{
|
{
|
||||||
|
base.OnRenderSizeChanged(sizeInfo);
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
viewportOrigin.X = Math.Min(Math.Max(origin.X, 0d), RenderSize.Width);
|
viewportOrigin.X = Math.Min(Math.Max(origin.X, 0d), RenderSize.Width);
|
||||||
viewportOrigin.Y = Math.Min(Math.Max(origin.Y, 0d), RenderSize.Height);
|
viewportOrigin.Y = Math.Min(Math.Max(origin.Y, 0d), RenderSize.Height);
|
||||||
transformOrigin = CoerceLocation(ViewportPointToLocation(viewportOrigin));
|
transformOrigin = ViewportPointToLocation(viewportOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -404,17 +404,28 @@ namespace MapControl
|
||||||
/// is performed relative to the specified origin point in viewport coordinates.
|
/// is performed relative to the specified origin point in viewport coordinates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void TransformMap(Point origin, Point translation, double rotation, double scale)
|
public void TransformMap(Point origin, Point translation, double rotation, double scale)
|
||||||
{
|
|
||||||
if (rotation != 0d || scale != 1d)
|
|
||||||
{
|
{
|
||||||
SetTransformOrigin(origin);
|
SetTransformOrigin(origin);
|
||||||
SetProperty(HeadingProperty, CoerceHeading(Heading + rotation));
|
|
||||||
SetProperty(ZoomLevelProperty, CoerceZoomLevel(ZoomLevel + Math.Log(scale, 2d)));
|
viewportOrigin.X += translation.X;
|
||||||
UpdateTransform();
|
viewportOrigin.Y += translation.Y;
|
||||||
|
|
||||||
|
if (rotation != 0d)
|
||||||
|
{
|
||||||
|
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();
|
ResetTransformOrigin();
|
||||||
TranslateMap(translation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -423,10 +434,10 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ZoomMap(Point origin, double zoomLevel)
|
public void ZoomMap(Point origin, double zoomLevel)
|
||||||
{
|
{
|
||||||
var targetZoomLebel = TargetZoomLevel;
|
var targetZoomLevel = TargetZoomLevel;
|
||||||
TargetZoomLevel = zoomLevel;
|
TargetZoomLevel = zoomLevel;
|
||||||
|
|
||||||
if (TargetZoomLevel != targetZoomLebel) // TargetZoomLevel might be coerced
|
if (TargetZoomLevel != targetZoomLevel) // TargetZoomLevel might be coerced
|
||||||
{
|
{
|
||||||
SetTransformOrigin(origin);
|
SetTransformOrigin(origin);
|
||||||
}
|
}
|
||||||
|
|
@ -561,27 +572,34 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetProperty(DependencyProperty property, object value)
|
private void InternalSetValue(DependencyProperty property, object value)
|
||||||
{
|
{
|
||||||
internalPropertyChange = true;
|
internalPropertyChange = true;
|
||||||
SetValue(property, value);
|
SetValue(property, value);
|
||||||
internalPropertyChange = false;
|
internalPropertyChange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Location CoerceLocation(Location location)
|
private bool CoerceLocation(Location location, double latitudeEpsilon = 0d)
|
||||||
{
|
{
|
||||||
return new Location(
|
var maxLatitude = mapTransform.MaxLatitude + latitudeEpsilon;
|
||||||
Math.Min(Math.Max(location.Latitude, -mapTransform.MaxLatitude), mapTransform.MaxLatitude),
|
var latitude = Math.Min(Math.Max(location.Latitude, -maxLatitude), maxLatitude);
|
||||||
Location.NormalizeLongitude(location.Longitude));
|
var longitude = Location.NormalizeLongitude(location.Longitude);
|
||||||
|
|
||||||
|
if (location.Latitude != latitude || location.Longitude != longitude)
|
||||||
|
{
|
||||||
|
location.Latitude = latitude;
|
||||||
|
location.Longitude = longitude;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CoerceCenterProperty(DependencyProperty property, ref Location center)
|
return false;
|
||||||
{
|
}
|
||||||
Location coercedValue = CoerceLocation(center);
|
|
||||||
|
|
||||||
if (!coercedValue.Equals(center))
|
private void CoerceCenterProperty(DependencyProperty property, Location center)
|
||||||
{
|
{
|
||||||
SetProperty(property, coercedValue);
|
if (CoerceLocation(center))
|
||||||
|
{
|
||||||
|
InternalSetValue(property, center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -589,14 +607,14 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
if (!internalPropertyChange)
|
if (!internalPropertyChange)
|
||||||
{
|
{
|
||||||
CoerceCenterProperty(CenterProperty, ref center);
|
CoerceCenterProperty(CenterProperty, center);
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
|
|
||||||
if (centerAnimation == null)
|
if (centerAnimation == null)
|
||||||
{
|
{
|
||||||
SetProperty(TargetCenterProperty, center);
|
InternalSetValue(TargetCenterProperty, center);
|
||||||
SetProperty(CenterPointProperty, new Point(center.Longitude, center.Latitude));
|
InternalSetValue(CenterPointProperty, new Point(center.Longitude, center.Latitude));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -605,9 +623,9 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
if (!internalPropertyChange)
|
if (!internalPropertyChange)
|
||||||
{
|
{
|
||||||
CoerceCenterProperty(TargetCenterProperty, ref targetCenter);
|
CoerceCenterProperty(TargetCenterProperty, targetCenter);
|
||||||
|
|
||||||
if (targetCenter != Center)
|
if (!targetCenter.Equals(Center))
|
||||||
{
|
{
|
||||||
if (centerAnimation != null)
|
if (centerAnimation != null)
|
||||||
{
|
{
|
||||||
|
|
@ -637,8 +655,8 @@ namespace MapControl
|
||||||
centerAnimation.Completed -= CenterAnimationCompleted;
|
centerAnimation.Completed -= CenterAnimationCompleted;
|
||||||
centerAnimation = null;
|
centerAnimation = null;
|
||||||
|
|
||||||
SetProperty(CenterProperty, TargetCenter);
|
InternalSetValue(CenterProperty, TargetCenter);
|
||||||
SetProperty(CenterPointProperty, new Point(TargetCenter.Longitude, TargetCenter.Latitude));
|
InternalSetValue(CenterPointProperty, new Point(TargetCenter.Longitude, TargetCenter.Latitude));
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
@ -648,7 +666,7 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
if (!internalPropertyChange)
|
if (!internalPropertyChange)
|
||||||
{
|
{
|
||||||
SetProperty(CenterProperty, new Location(centerPoint.Y, centerPoint.X));
|
InternalSetValue(CenterProperty, new Location(centerPoint.Y, centerPoint.X));
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
@ -660,7 +678,7 @@ namespace MapControl
|
||||||
|
|
||||||
if (coercedValue != minZoomLevel)
|
if (coercedValue != minZoomLevel)
|
||||||
{
|
{
|
||||||
SetProperty(MinZoomLevelProperty, coercedValue);
|
InternalSetValue(MinZoomLevelProperty, coercedValue);
|
||||||
}
|
}
|
||||||
else if (ZoomLevel < minZoomLevel)
|
else if (ZoomLevel < minZoomLevel)
|
||||||
{
|
{
|
||||||
|
|
@ -674,7 +692,7 @@ namespace MapControl
|
||||||
|
|
||||||
if (coercedValue != maxZoomLevel)
|
if (coercedValue != maxZoomLevel)
|
||||||
{
|
{
|
||||||
SetProperty(MaxZoomLevelProperty, coercedValue);
|
InternalSetValue(MaxZoomLevelProperty, coercedValue);
|
||||||
}
|
}
|
||||||
else if (ZoomLevel > maxZoomLevel)
|
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)
|
private bool CoerceZoomLevelProperty(DependencyProperty property, ref double zoomLevel)
|
||||||
{
|
{
|
||||||
var coercedValue = CoerceZoomLevel(zoomLevel);
|
var coercedValue = Math.Min(Math.Max(zoomLevel, MinZoomLevel), MaxZoomLevel);
|
||||||
|
|
||||||
if (coercedValue != zoomLevel)
|
if (coercedValue != zoomLevel)
|
||||||
{
|
{
|
||||||
SetProperty(property, coercedValue);
|
InternalSetValue(property, coercedValue);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return coercedValue != zoomLevel;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ZoomLevelPropertyChanged(double zoomLevel)
|
private void ZoomLevelPropertyChanged(double zoomLevel)
|
||||||
|
|
@ -708,7 +722,7 @@ namespace MapControl
|
||||||
|
|
||||||
if (zoomLevelAnimation == null)
|
if (zoomLevelAnimation == null)
|
||||||
{
|
{
|
||||||
SetProperty(TargetZoomLevelProperty, zoomLevel);
|
InternalSetValue(TargetZoomLevelProperty, zoomLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -744,24 +758,19 @@ namespace MapControl
|
||||||
zoomLevelAnimation.Completed -= ZoomLevelAnimationCompleted;
|
zoomLevelAnimation.Completed -= ZoomLevelAnimationCompleted;
|
||||||
zoomLevelAnimation = null;
|
zoomLevelAnimation = null;
|
||||||
|
|
||||||
SetProperty(ZoomLevelProperty, TargetZoomLevel);
|
InternalSetValue(ZoomLevelProperty, TargetZoomLevel);
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double CoerceHeading(double heading)
|
|
||||||
{
|
|
||||||
return (heading >= -180d && heading <= 360d) ? heading : ((heading + 360d) % 360d);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CoerceHeadingProperty(DependencyProperty property, ref double heading)
|
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)
|
if (coercedValue != heading)
|
||||||
{
|
{
|
||||||
SetProperty(property, coercedValue);
|
InternalSetValue(property, coercedValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -774,7 +783,7 @@ namespace MapControl
|
||||||
|
|
||||||
if (headingAnimation == null)
|
if (headingAnimation == null)
|
||||||
{
|
{
|
||||||
SetProperty(TargetHeadingProperty, heading);
|
InternalSetValue(TargetHeadingProperty, heading);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -824,26 +833,32 @@ namespace MapControl
|
||||||
headingAnimation.Completed -= HeadingAnimationCompleted;
|
headingAnimation.Completed -= HeadingAnimationCompleted;
|
||||||
headingAnimation = null;
|
headingAnimation = null;
|
||||||
|
|
||||||
SetProperty(HeadingProperty, TargetHeading);
|
InternalSetValue(HeadingProperty, TargetHeading);
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void 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)
|
if (transformOrigin != null)
|
||||||
{
|
{
|
||||||
scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, mapTransform.Transform(transformOrigin), viewportOrigin, RenderSize);
|
center = ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d));
|
||||||
SetProperty(CenterProperty, ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d)));
|
var coerced = CoerceLocation(center, 1e-3);
|
||||||
}
|
|
||||||
else
|
InternalSetValue(CenterProperty, center);
|
||||||
|
|
||||||
|
if (coerced)
|
||||||
{
|
{
|
||||||
scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, mapTransform.Transform(Center), viewportOrigin, RenderSize);
|
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;
|
CenterScale = scale;
|
||||||
SetTransformMatrixes(scale);
|
SetTransformMatrixes(scale);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,11 @@ namespace MapControl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MercatorTransform : MapTransform
|
public class MercatorTransform : MapTransform
|
||||||
{
|
{
|
||||||
|
private static readonly double maxLatitude = Math.Atan(Math.Sinh(Math.PI)) / Math.PI * 180d;
|
||||||
|
|
||||||
public override double MaxLatitude
|
public override double MaxLatitude
|
||||||
{
|
{
|
||||||
get { return 85.0511287798066; }
|
get { return maxLatitude; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override double RelativeScale(Location location)
|
public override double RelativeScale(Location location)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,6 @@ using System.Windows;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
// Copyright © 2013 Clemens Fischer
|
// Copyright © 2013 Clemens Fischer
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
|
|
||||||
#if NETFX_CORE
|
#if NETFX_CORE
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
|
@ -19,7 +18,7 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
public partial class Tile
|
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
|
public ImageSource ImageSource
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -147,19 +147,20 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
Interlocked.Increment(ref downloadThreadCount);
|
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;
|
Tile tile;
|
||||||
|
|
||||||
while (pendingTiles.TryDequeue(out tile))
|
while (pendingTiles.TryDequeue(out tile))
|
||||||
{
|
{
|
||||||
byte[] buffer = null;
|
byte[] buffer = null;
|
||||||
ImageSource image = null;
|
ImageSource image = null;
|
||||||
var imageTileSource = tileLayer.TileSource as ImageTileSource;
|
|
||||||
|
|
||||||
if (imageTileSource != null)
|
if (imageTileSource != null)
|
||||||
{
|
{
|
||||||
|
|
@ -176,15 +177,18 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
var uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
var uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||||
|
|
||||||
if (uri.Scheme != "http")
|
if (uri != null)
|
||||||
{
|
{
|
||||||
image = CreateImage(uri);
|
if (uri.Scheme == "http")
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
buffer = DownloadImage(uri);
|
buffer = DownloadImage(uri);
|
||||||
image = CreateImage(buffer);
|
image = CreateImage(buffer);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = CreateImage(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image != null)
|
if (image != null)
|
||||||
|
|
@ -203,7 +207,7 @@ namespace MapControl
|
||||||
Interlocked.Decrement(ref downloadThreadCount);
|
Interlocked.Decrement(ref downloadThreadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageSource CreateImage(Uri uri)
|
private static ImageSource CreateImage(Uri uri)
|
||||||
{
|
{
|
||||||
var image = new BitmapImage();
|
var image = new BitmapImage();
|
||||||
|
|
||||||
|
|
@ -224,15 +228,15 @@ namespace MapControl
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImageSource CreateImage(byte[] buffer)
|
private static ImageSource CreateImage(byte[] buffer)
|
||||||
{
|
{
|
||||||
BitmapImage image = null;
|
BitmapImage image = null;
|
||||||
|
|
||||||
if (buffer != null && buffer.Length > 8)
|
if (buffer != null && buffer.Length > sizeof(long))
|
||||||
{
|
{
|
||||||
try
|
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 = new BitmapImage();
|
||||||
image.BeginInit();
|
image.BeginInit();
|
||||||
|
|
@ -264,12 +268,12 @@ namespace MapControl
|
||||||
using (var response = (HttpWebResponse)request.GetResponse())
|
using (var response = (HttpWebResponse)request.GetResponse())
|
||||||
using (var responseStream = response.GetResponseStream())
|
using (var responseStream = response.GetResponseStream())
|
||||||
{
|
{
|
||||||
var length = response.ContentLength;
|
|
||||||
var creationTime = DateTime.UtcNow.ToBinary();
|
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);
|
responseStream.CopyTo(memoryStream);
|
||||||
|
|
||||||
buffer = length > 0 ? memoryStream.GetBuffer() : memoryStream.ToArray();
|
buffer = length > 0 ? memoryStream.GetBuffer() : memoryStream.ToArray();
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,12 @@
|
||||||
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
|
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
|
||||||
ItemContainerStyle="{StaticResource PushpinItemStyle}"/>
|
ItemContainerStyle="{StaticResource PushpinItemStyle}"/>
|
||||||
|
|
||||||
|
<Path map:MapPanel.Location="53.5,8.2" Stroke="Blue" StrokeThickness="3" Fill="#1F007F00">
|
||||||
|
<Path.Data>
|
||||||
|
<EllipseGeometry RadiusX="500" RadiusY="500" Transform="{Binding ScaleTransform, ElementName=map}"/>
|
||||||
|
</Path.Data>
|
||||||
|
</Path>
|
||||||
|
|
||||||
<map:Pushpin map:MapPanel.Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"/>
|
<map:Pushpin map:MapPanel.Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"/>
|
||||||
|
|
||||||
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4" FontSize="10"
|
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4" FontSize="10"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,20 @@
|
||||||
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
|
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
|
||||||
ItemContainerStyle="{StaticResource PushpinItemStyle}"/>
|
ItemContainerStyle="{StaticResource PushpinItemStyle}"/>
|
||||||
|
|
||||||
<!-- No TypeConverter (yet?) for string to Location
|
<Path Stroke="Blue" StrokeThickness="3">
|
||||||
<map:Pushpin map:MapPanel.Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"/>-->
|
<map:MapPanel.Location>
|
||||||
|
<map:Location Latitude="53.5" Longitude="8.2"/>
|
||||||
|
</map:MapPanel.Location>
|
||||||
|
<Path.Data>
|
||||||
|
<EllipseGeometry RadiusX="1000" RadiusY="1000" Transform="{Binding ScaleTransform, ElementName=map}"/>
|
||||||
|
</Path.Data>
|
||||||
|
</Path>
|
||||||
|
|
||||||
|
<map:Pushpin Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'">
|
||||||
|
<map:MapPanel.Location>
|
||||||
|
<map:Location Latitude="53.5" Longitude="8.2"/>
|
||||||
|
</map:MapPanel.Location>
|
||||||
|
</map:Pushpin>
|
||||||
|
|
||||||
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4" FontSize="10"
|
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4" FontSize="10"
|
||||||
Text="{Binding TileLayer.Description, ElementName=map}"/>
|
Text="{Binding TileLayer.Description, ElementName=map}"/>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using System.Windows;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<!-- The TileLayer below demonstrates how to access local tile image files (from ImageFileCache here) -->
|
<!-- The TileLayer below demonstrates how to access local tile image files (from ImageFileCache here) -->
|
||||||
<!--<map:TileLayer SourceName="OSM Local Files" Description="© {y} OpenStreetMap Contributors, CC-BY-SA"
|
<!--<map:TileLayer SourceName="OSM Local Files" Description="© {y} OpenStreetMap Contributors, CC-BY-SA"
|
||||||
TileSource="file://C:/ProgramData/MapControl/TileCache/OpenStreetMap/{z}/{x}/{y}.png"/>-->
|
TileSource="file:///C:/ProgramData/MapControl/TileCache/OpenStreetMap/{z}/{x}/{y}.png"/>-->
|
||||||
</map:TileLayerCollection>
|
</map:TileLayerCollection>
|
||||||
<CollectionViewSource x:Key="TileLayersView" Source="{StaticResource TileLayers}"/>
|
<CollectionViewSource x:Key="TileLayersView" Source="{StaticResource TileLayers}"/>
|
||||||
<local:LocationToVisibilityConverter x:Key="LocationToVisibilityConverter"/>
|
<local:LocationToVisibilityConverter x:Key="LocationToVisibilityConverter"/>
|
||||||
|
|
@ -182,6 +182,12 @@
|
||||||
</map:Pushpin.Visibility>
|
</map:Pushpin.Visibility>
|
||||||
</map:Pushpin>
|
</map:Pushpin>
|
||||||
|
|
||||||
|
<Path map:MapPanel.Location="53.5,8.2" Stroke="Blue" StrokeThickness="3" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||||
|
<Path.Data>
|
||||||
|
<EllipseGeometry RadiusX="1852" RadiusY="1852" Transform="{Binding ScaleTransform, ElementName=map}"/>
|
||||||
|
</Path.Data>
|
||||||
|
</Path>
|
||||||
|
|
||||||
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4" FontSize="10"
|
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="4" FontSize="10"
|
||||||
Text="{Binding TileLayer.Description, ElementName=map}"/>
|
Text="{Binding TileLayer.Description, ElementName=map}"/>
|
||||||
</map:Map>
|
</map:Map>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using System.Windows;
|
||||||
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
[assembly: AssemblyCopyright("Copyright © 2013 Clemens Fischer")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: AssemblyVersion("1.1.9")]
|
[assembly: AssemblyVersion("1.1.10")]
|
||||||
[assembly: AssemblyFileVersion("1.1.9")]
|
[assembly: AssemblyFileVersion("1.1.10")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue