mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Some cleanup.
This commit is contained in:
parent
65a0d8d51a
commit
be3144af07
|
|
@ -3,6 +3,8 @@
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
@ -41,7 +43,7 @@ namespace MapControl
|
||||||
|
|
||||||
public static readonly DependencyProperty TileLayersProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty TileLayersProperty = DependencyProperty.Register(
|
||||||
"TileLayers", typeof(TileLayerCollection), typeof(Map), new FrameworkPropertyMetadata(
|
"TileLayers", typeof(TileLayerCollection), typeof(Map), new FrameworkPropertyMetadata(
|
||||||
(o, e) => ((Map)o).TileLayersPropertyChanged((TileLayerCollection)e.NewValue),
|
(o, e) => ((Map)o).TileLayersPropertyChanged((TileLayerCollection)e.OldValue, (TileLayerCollection)e.NewValue),
|
||||||
(o, v) => ((Map)o).CoerceTileLayersProperty((TileLayerCollection)v)));
|
(o, v) => ((Map)o).CoerceTileLayersProperty((TileLayerCollection)v)));
|
||||||
|
|
||||||
public static readonly DependencyProperty MainTileLayerProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty MainTileLayerProperty = DependencyProperty.Register(
|
||||||
|
|
@ -122,14 +124,9 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when the ViewTransform property has changed.
|
/// Raised when the current viewport has changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler ViewTransformChanged;
|
public event Action ViewportChanged;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raised when the TileLayers property has changed.
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler TileLayersChanged;
|
|
||||||
|
|
||||||
public double MinZoomLevel { get; set; }
|
public double MinZoomLevel { get; set; }
|
||||||
public double MaxZoomLevel { get; set; }
|
public double MaxZoomLevel { get; set; }
|
||||||
|
|
@ -258,7 +255,7 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the map rotation angle in degrees.
|
/// Gets or sets the map heading, or clockwise rotation angle in degrees.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double Heading
|
public double Heading
|
||||||
{
|
{
|
||||||
|
|
@ -381,7 +378,7 @@ namespace MapControl
|
||||||
if (transformOrigin != null)
|
if (transformOrigin != null)
|
||||||
{
|
{
|
||||||
viewportOrigin += translation;
|
viewportOrigin += translation;
|
||||||
UpdateViewTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -404,7 +401,7 @@ namespace MapControl
|
||||||
Heading = (((Heading + rotation) % 360d) + 360d) % 360d;
|
Heading = (((Heading + rotation) % 360d) + 360d) % 360d;
|
||||||
ZoomLevel += Math.Log(scale, 2d);
|
ZoomLevel += Math.Log(scale, 2d);
|
||||||
updateTransform = true;
|
updateTransform = true;
|
||||||
UpdateViewTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslateMap(translation);
|
TranslateMap(translation);
|
||||||
|
|
@ -448,7 +445,7 @@ namespace MapControl
|
||||||
base.OnRenderSizeChanged(sizeInfo);
|
base.OnRenderSizeChanged(sizeInfo);
|
||||||
|
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
UpdateViewTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRender(DrawingContext drawingContext)
|
protected override void OnRender(DrawingContext drawingContext)
|
||||||
|
|
@ -456,21 +453,89 @@ namespace MapControl
|
||||||
drawingContext.DrawRectangle(Background, null, new Rect(RenderSize));
|
drawingContext.DrawRectangle(Background, null, new Rect(RenderSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnViewTransformChanged(Map map)
|
protected override void OnViewportChanged()
|
||||||
{
|
{
|
||||||
base.OnViewTransformChanged(map);
|
base.OnViewportChanged();
|
||||||
|
|
||||||
if (ViewTransformChanged != null)
|
if (ViewportChanged != null)
|
||||||
{
|
{
|
||||||
ViewTransformChanged(this, EventArgs.Empty);
|
ViewportChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected internal virtual void OnTileLayersChanged()
|
private void TileLayerCollectionChanged(object sender, NotifyCollectionChangedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (tileContainer.TileLayers != null &&
|
switch (eventArgs.Action)
|
||||||
tileContainer.TileLayers.Count > 0 &&
|
{
|
||||||
tileContainer.TileLayers[0].HasDarkBackground)
|
case NotifyCollectionChangedAction.Add:
|
||||||
|
tileContainer.AddTileLayers(eventArgs.NewStartingIndex, eventArgs.NewItems.Cast<TileLayer>());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotifyCollectionChangedAction.Remove:
|
||||||
|
tileContainer.RemoveTileLayers(eventArgs.OldStartingIndex, eventArgs.OldItems.Cast<TileLayer>());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotifyCollectionChangedAction.Move:
|
||||||
|
case NotifyCollectionChangedAction.Replace:
|
||||||
|
tileContainer.RemoveTileLayers(eventArgs.OldStartingIndex, eventArgs.OldItems.Cast<TileLayer>());
|
||||||
|
tileContainer.AddTileLayers(eventArgs.NewStartingIndex, eventArgs.NewItems.Cast<TileLayer>());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotifyCollectionChangedAction.Reset:
|
||||||
|
tileContainer.ClearTileLayers();
|
||||||
|
if (eventArgs.NewItems != null)
|
||||||
|
{
|
||||||
|
tileContainer.AddTileLayers(0, eventArgs.NewItems.Cast<TileLayer>());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateMainTileLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TileLayersPropertyChanged(TileLayerCollection oldTileLayers, TileLayerCollection newTileLayers)
|
||||||
|
{
|
||||||
|
tileContainer.ClearTileLayers();
|
||||||
|
|
||||||
|
if (oldTileLayers != null)
|
||||||
|
{
|
||||||
|
oldTileLayers.CollectionChanged -= TileLayerCollectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTileLayers != null)
|
||||||
|
{
|
||||||
|
newTileLayers.CollectionChanged += TileLayerCollectionChanged;
|
||||||
|
tileContainer.AddTileLayers(0, newTileLayers);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateMainTileLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TileLayerCollection CoerceTileLayersProperty(TileLayerCollection tileLayers)
|
||||||
|
{
|
||||||
|
if (tileLayers == null)
|
||||||
|
{
|
||||||
|
tileLayers = new TileLayerCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tileLayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainTileLayerPropertyChanged(TileLayer mainTileLayer)
|
||||||
|
{
|
||||||
|
if (mainTileLayer != null)
|
||||||
|
{
|
||||||
|
if (TileLayers.Count == 0)
|
||||||
|
{
|
||||||
|
TileLayers.Add(mainTileLayer);
|
||||||
|
}
|
||||||
|
else if (TileLayers[0] != mainTileLayer)
|
||||||
|
{
|
||||||
|
TileLayers[0] = mainTileLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainTileLayer != null && mainTileLayer.HasDarkBackground)
|
||||||
{
|
{
|
||||||
if (DarkForeground != null)
|
if (DarkForeground != null)
|
||||||
{
|
{
|
||||||
|
|
@ -494,63 +559,34 @@ namespace MapControl
|
||||||
Background = LightBackground;
|
Background = LightBackground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TileLayersChanged != null)
|
|
||||||
{
|
|
||||||
TileLayersChanged(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TileLayersPropertyChanged(TileLayerCollection tileLayers)
|
|
||||||
{
|
|
||||||
if (tileLayers != null)
|
|
||||||
{
|
|
||||||
tileContainer.TileLayers = tileLayers;
|
|
||||||
MainTileLayer = tileLayers.Count > 0 ? tileLayers[0] : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TileLayerCollection CoerceTileLayersProperty(TileLayerCollection tileLayers)
|
|
||||||
{
|
|
||||||
if (tileLayers == null)
|
|
||||||
{
|
|
||||||
tileLayers = new TileLayerCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
return tileLayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MainTileLayerPropertyChanged(TileLayer mainTileLayer)
|
|
||||||
{
|
|
||||||
if (mainTileLayer != null)
|
|
||||||
{
|
|
||||||
if (tileContainer.TileLayers.Count == 0)
|
|
||||||
{
|
|
||||||
tileContainer.TileLayers.Add(mainTileLayer);
|
|
||||||
}
|
|
||||||
else if (tileContainer.TileLayers[0] != mainTileLayer)
|
|
||||||
{
|
|
||||||
tileContainer.TileLayers[0] = mainTileLayer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TileLayer CoerceMainTileLayerProperty(TileLayer mainTileLayer)
|
private TileLayer CoerceMainTileLayerProperty(TileLayer mainTileLayer)
|
||||||
{
|
{
|
||||||
if (mainTileLayer == null && tileContainer.TileLayers.Count > 0)
|
if (mainTileLayer == null && TileLayers.Count > 0)
|
||||||
{
|
{
|
||||||
mainTileLayer = tileContainer.TileLayers[0];
|
mainTileLayer = TileLayers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return mainTileLayer;
|
return mainTileLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateMainTileLayer()
|
||||||
|
{
|
||||||
|
TileLayer mainTileLayer = TileLayers.FirstOrDefault();
|
||||||
|
|
||||||
|
if (MainTileLayer != mainTileLayer)
|
||||||
|
{
|
||||||
|
MainTileLayer = mainTileLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CenterPropertyChanged(Location center)
|
private void CenterPropertyChanged(Location center)
|
||||||
{
|
{
|
||||||
if (updateTransform)
|
if (updateTransform)
|
||||||
{
|
{
|
||||||
ResetTransformOrigin();
|
ResetTransformOrigin();
|
||||||
UpdateViewTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (centerAnimation == null)
|
if (centerAnimation == null)
|
||||||
|
|
@ -600,7 +636,7 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
if (updateTransform)
|
if (updateTransform)
|
||||||
{
|
{
|
||||||
UpdateViewTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zoomLevelAnimation == null)
|
if (zoomLevelAnimation == null)
|
||||||
|
|
@ -649,7 +685,7 @@ namespace MapControl
|
||||||
{
|
{
|
||||||
if (updateTransform)
|
if (updateTransform)
|
||||||
{
|
{
|
||||||
UpdateViewTransform();
|
UpdateTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headingAnimation == null)
|
if (headingAnimation == null)
|
||||||
|
|
@ -704,20 +740,20 @@ namespace MapControl
|
||||||
return ((heading % 360d) + 360d) % 360d;
|
return ((heading % 360d) + 360d) % 360d;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateViewTransform()
|
private void UpdateTransform()
|
||||||
{
|
{
|
||||||
double scale;
|
double scale;
|
||||||
|
|
||||||
if (transformOrigin != null)
|
if (transformOrigin != null)
|
||||||
{
|
{
|
||||||
scale = tileContainer.SetTransform(ZoomLevel, Heading, MapTransform.Transform(transformOrigin), viewportOrigin, RenderSize);
|
scale = tileContainer.SetViewportTransform(ZoomLevel, Heading, MapTransform.Transform(transformOrigin), viewportOrigin, RenderSize);
|
||||||
updateTransform = false;
|
updateTransform = false;
|
||||||
Center = ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d));
|
Center = ViewportPointToLocation(new Point(RenderSize.Width / 2d, RenderSize.Height / 2d));
|
||||||
updateTransform = true;
|
updateTransform = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scale = tileContainer.SetTransform(ZoomLevel, Heading, MapTransform.Transform(Center), viewportOrigin, RenderSize);
|
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
|
||||||
|
|
@ -728,7 +764,7 @@ namespace MapControl
|
||||||
rotateTransform.Angle = Heading;
|
rotateTransform.Angle = Heading;
|
||||||
scaleRotateTransform.Matrix = scaleTransform.Value * rotateTransform.Value;
|
scaleRotateTransform.Matrix = scaleTransform.Value * rotateTransform.Value;
|
||||||
|
|
||||||
OnViewTransformChanged(this);
|
OnViewportChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,17 @@ using System.Windows;
|
||||||
|
|
||||||
namespace MapControl
|
namespace MapControl
|
||||||
{
|
{
|
||||||
internal interface INotifyParentMapChanged
|
|
||||||
{
|
|
||||||
void ParentMapChanged(Map oldParentMap, Map newParentMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for child elements of a MapPanel.
|
/// Base class for child elements of a MapPanel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class MapElement : FrameworkElement, INotifyParentMapChanged
|
public abstract class MapElement : FrameworkElement
|
||||||
{
|
{
|
||||||
|
static MapElement()
|
||||||
|
{
|
||||||
|
MapPanel.ParentMapProperty.OverrideMetadata(typeof(MapElement),
|
||||||
|
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, ParentMapPropertyChanged));
|
||||||
|
}
|
||||||
|
|
||||||
protected MapElement()
|
protected MapElement()
|
||||||
{
|
{
|
||||||
HorizontalAlignment = HorizontalAlignment.Stretch;
|
HorizontalAlignment = HorizontalAlignment.Stretch;
|
||||||
|
|
@ -28,23 +29,26 @@ namespace MapControl
|
||||||
get { return MapPanel.GetParentMap(this); }
|
get { return MapPanel.GetParentMap(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void OnViewTransformChanged(Map parentMap);
|
protected abstract void OnViewportChanged();
|
||||||
|
|
||||||
private void OnViewTransformChanged(object sender, EventArgs eventArgs)
|
private static void ParentMapPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
OnViewTransformChanged((Map)sender);
|
MapElement mapElement = obj as MapElement;
|
||||||
}
|
|
||||||
|
|
||||||
void INotifyParentMapChanged.ParentMapChanged(Map oldParentMap, Map newParentMap)
|
if (mapElement != null)
|
||||||
{
|
{
|
||||||
|
Map oldParentMap = eventArgs.OldValue as Map;
|
||||||
|
Map newParentMap = eventArgs.NewValue as Map;
|
||||||
|
|
||||||
if (oldParentMap != null)
|
if (oldParentMap != null)
|
||||||
{
|
{
|
||||||
oldParentMap.ViewTransformChanged -= OnViewTransformChanged;
|
oldParentMap.ViewportChanged -= mapElement.OnViewportChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newParentMap != null)
|
if (newParentMap != null)
|
||||||
{
|
{
|
||||||
newParentMap.ViewTransformChanged += OnViewTransformChanged;
|
newParentMap.ViewportChanged += mapElement.OnViewportChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,9 @@ namespace MapControl
|
||||||
return visual;
|
return visual;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnViewTransformChanged(Map parentMap)
|
protected override void OnViewportChanged()
|
||||||
{
|
{
|
||||||
|
Map parentMap = ParentMap;
|
||||||
Rect bounds = parentMap.ViewportTransform.Inverse.TransformBounds(new Rect(parentMap.RenderSize));
|
Rect bounds = parentMap.ViewportTransform.Inverse.TransformBounds(new Rect(parentMap.RenderSize));
|
||||||
Location loc1 = parentMap.MapTransform.TransformBack(bounds.TopLeft);
|
Location loc1 = parentMap.MapTransform.TransformBack(bounds.TopLeft);
|
||||||
Location loc2 = parentMap.MapTransform.TransformBack(bounds.BottomRight);
|
Location loc2 = parentMap.MapTransform.TransformBack(bounds.BottomRight);
|
||||||
|
|
@ -195,7 +196,7 @@ namespace MapControl
|
||||||
private void UpdateBrush()
|
private void UpdateBrush()
|
||||||
{
|
{
|
||||||
pen.Brush = null;
|
pen.Brush = null;
|
||||||
OnViewTransformChanged(ParentMap);
|
OnViewportChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CoordinateString(double value, string format, string hemispheres)
|
private static string CoordinateString(double value, string format, string hemispheres)
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace MapControl
|
||||||
/// coordinates. IsInsideMapBounds indicates if the viewport coordinates are located
|
/// coordinates. IsInsideMapBounds indicates if the viewport coordinates are located
|
||||||
/// inside the visible part of the map.
|
/// inside the visible part of the map.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MapPanel : Panel, INotifyParentMapChanged
|
public class MapPanel : Panel
|
||||||
{
|
{
|
||||||
public static readonly DependencyProperty ParentMapProperty = DependencyProperty.RegisterAttached(
|
public static readonly DependencyProperty ParentMapProperty = DependencyProperty.RegisterAttached(
|
||||||
"ParentMap", typeof(Map), typeof(MapPanel),
|
"ParentMap", typeof(Map), typeof(MapPanel),
|
||||||
|
|
@ -102,8 +102,10 @@ namespace MapControl
|
||||||
return finalSize;
|
return finalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnViewTransformChanged(Map parentMap)
|
protected virtual void OnViewportChanged()
|
||||||
{
|
{
|
||||||
|
Map parentMap = ParentMap;
|
||||||
|
|
||||||
foreach (UIElement element in InternalChildren)
|
foreach (UIElement element in InternalChildren)
|
||||||
{
|
{
|
||||||
Location location = GetLocation(element);
|
Location location = GetLocation(element);
|
||||||
|
|
@ -115,31 +117,24 @@ namespace MapControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnViewTransformChanged(object sender, EventArgs eventArgs)
|
|
||||||
{
|
|
||||||
OnViewTransformChanged((Map)sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
void INotifyParentMapChanged.ParentMapChanged(Map oldParentMap, Map newParentMap)
|
|
||||||
{
|
|
||||||
if (oldParentMap != null && oldParentMap != this)
|
|
||||||
{
|
|
||||||
oldParentMap.ViewTransformChanged -= OnViewTransformChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newParentMap != null && newParentMap != this)
|
|
||||||
{
|
|
||||||
newParentMap.ViewTransformChanged += OnViewTransformChanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ParentMapPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs)
|
private static void ParentMapPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
INotifyParentMapChanged notifyChanged = obj as INotifyParentMapChanged;
|
MapPanel mapPanel = obj as MapPanel;
|
||||||
|
|
||||||
if (notifyChanged != null)
|
if (mapPanel != null)
|
||||||
{
|
{
|
||||||
notifyChanged.ParentMapChanged(eventArgs.OldValue as Map, eventArgs.NewValue as Map);
|
Map oldParentMap = eventArgs.OldValue as Map;
|
||||||
|
Map newParentMap = eventArgs.NewValue as Map;
|
||||||
|
|
||||||
|
if (oldParentMap != null && oldParentMap != mapPanel)
|
||||||
|
{
|
||||||
|
oldParentMap.ViewportChanged -= mapPanel.OnViewportChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newParentMap != null && newParentMap != mapPanel)
|
||||||
|
{
|
||||||
|
newParentMap.ViewportChanged += mapPanel.OnViewportChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,13 +156,13 @@ namespace MapControl
|
||||||
AddVisualChild(visual);
|
AddVisualChild(visual);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnViewTransformChanged(Map parentMap)
|
protected override void OnViewportChanged()
|
||||||
{
|
{
|
||||||
double scale = 1d;
|
double scale = 1d;
|
||||||
|
|
||||||
if (TransformStroke)
|
if (TransformStroke)
|
||||||
{
|
{
|
||||||
scale = parentMap.CenterScale * Map.MeterPerDegree;
|
scale = ParentMap.CenterScale * Map.MeterPerDegree;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawing.Pen.Thickness = scale * StrokeThickness;
|
drawing.Pen.Thickness = scale * StrokeThickness;
|
||||||
|
|
@ -175,12 +175,10 @@ namespace MapControl
|
||||||
|
|
||||||
protected void UpdateGeometry(bool closed)
|
protected void UpdateGeometry(bool closed)
|
||||||
{
|
{
|
||||||
Map parentMap = MapPanel.GetParentMap(this);
|
if (ParentMap != null && Locations != null && Locations.Count > 0)
|
||||||
|
|
||||||
if (parentMap != null && Locations != null && Locations.Count > 0)
|
|
||||||
{
|
{
|
||||||
drawing.Geometry = CreateGeometry(parentMap, Locations, closed);
|
drawing.Geometry = CreateGeometry(Locations, closed);
|
||||||
OnViewTransformChanged(parentMap);
|
OnViewportChanged();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -190,28 +188,26 @@ namespace MapControl
|
||||||
|
|
||||||
private void UpdatePenThickness()
|
private void UpdatePenThickness()
|
||||||
{
|
{
|
||||||
Map parentMap = MapPanel.GetParentMap(this);
|
if (ParentMap != null)
|
||||||
|
|
||||||
if (parentMap != null)
|
|
||||||
{
|
{
|
||||||
OnViewTransformChanged(parentMap);
|
OnViewportChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Geometry CreateGeometry(Map parentMap, LocationCollection locations, bool closed)
|
private Geometry CreateGeometry(LocationCollection locations, bool closed)
|
||||||
{
|
{
|
||||||
StreamGeometry geometry = new StreamGeometry
|
StreamGeometry geometry = new StreamGeometry
|
||||||
{
|
{
|
||||||
Transform = parentMap.ViewportTransform
|
Transform = ParentMap.ViewportTransform
|
||||||
};
|
};
|
||||||
|
|
||||||
using (StreamGeometryContext sgc = geometry.Open())
|
using (StreamGeometryContext sgc = geometry.Open())
|
||||||
{
|
{
|
||||||
sgc.BeginFigure(parentMap.MapTransform.Transform(locations.First()), closed, closed);
|
sgc.BeginFigure(ParentMap.MapTransform.Transform(locations.First()), closed, closed);
|
||||||
|
|
||||||
if (Locations.Count > 1)
|
if (Locations.Count > 1)
|
||||||
{
|
{
|
||||||
sgc.PolyLineTo(parentMap.MapTransform.Transform(locations.Skip(1)), true, true);
|
sgc.PolyLineTo(ParentMap.MapTransform.Transform(locations.Skip(1)), true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
// Licensed under the Microsoft Public License (Ms-PL)
|
// Licensed under the Microsoft Public License (Ms-PL)
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
@ -23,44 +22,56 @@ namespace MapControl
|
||||||
private double zoomLevel;
|
private double zoomLevel;
|
||||||
private int tileZoomLevel;
|
private int tileZoomLevel;
|
||||||
private Int32Rect tileGrid;
|
private Int32Rect tileGrid;
|
||||||
private TileLayerCollection tileLayers;
|
|
||||||
private readonly DispatcherTimer updateTimer;
|
private readonly DispatcherTimer updateTimer;
|
||||||
private readonly MatrixTransform viewportTransform = new MatrixTransform();
|
|
||||||
|
public readonly MatrixTransform ViewportTransform = new MatrixTransform();
|
||||||
|
|
||||||
public TileContainer()
|
public TileContainer()
|
||||||
{
|
{
|
||||||
updateTimer = new DispatcherTimer(TimeSpan.FromSeconds(0.5), DispatcherPriority.Background, UpdateTiles, Dispatcher);
|
updateTimer = new DispatcherTimer(TimeSpan.FromSeconds(0.5), DispatcherPriority.Background, UpdateTiles, Dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TileLayerCollection TileLayers
|
public void AddTileLayers(int index, IEnumerable<TileLayer> tileLayers)
|
||||||
{
|
{
|
||||||
get { return tileLayers; }
|
Matrix transform = GetVisualTransform();
|
||||||
set
|
|
||||||
|
foreach (TileLayer tileLayer in tileLayers)
|
||||||
{
|
{
|
||||||
if (tileLayers != null)
|
if (string.IsNullOrEmpty(tileLayer.Name))
|
||||||
{
|
{
|
||||||
tileLayers.CollectionChanged -= TileLayersChanged;
|
throw new ArgumentException("TileLayer.Name property must not be null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
tileLayers = value;
|
Children.Insert(index++, tileLayer);
|
||||||
ClearChildren();
|
tileLayer.TransformMatrix = transform;
|
||||||
|
tileLayer.UpdateTiles(tileZoomLevel, tileGrid);
|
||||||
if (tileLayers != null)
|
|
||||||
{
|
|
||||||
tileLayers.CollectionChanged += TileLayersChanged;
|
|
||||||
AddChildren(0, tileLayers);
|
|
||||||
}
|
|
||||||
|
|
||||||
((Map)VisualParent).OnTileLayersChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform ViewportTransform
|
public void RemoveTileLayers(int index, IEnumerable<TileLayer> tileLayers)
|
||||||
{
|
{
|
||||||
get { return viewportTransform; }
|
int count = 0;
|
||||||
|
|
||||||
|
foreach (TileLayer tileLayer in tileLayers)
|
||||||
|
{
|
||||||
|
tileLayer.ClearTiles();
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double SetTransform(double mapZoomLevel, double mapRotation, Point mapOrigin, Point viewportOrigin, Size viewportSize)
|
Children.RemoveRange(index, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearTileLayers()
|
||||||
|
{
|
||||||
|
foreach (TileLayer tileLayer in Children)
|
||||||
|
{
|
||||||
|
tileLayer.ClearTiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
Children.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double SetViewportTransform(double mapZoomLevel, double mapRotation, Point mapOrigin, Point viewportOrigin, Size viewportSize)
|
||||||
{
|
{
|
||||||
zoomLevel = mapZoomLevel;
|
zoomLevel = mapZoomLevel;
|
||||||
rotation = mapRotation;
|
rotation = mapRotation;
|
||||||
|
|
@ -75,17 +86,14 @@ namespace MapControl
|
||||||
transform.Scale(scale, scale);
|
transform.Scale(scale, scale);
|
||||||
transform.Translate(offset.X, offset.Y);
|
transform.Translate(offset.X, offset.Y);
|
||||||
transform.RotateAt(rotation, origin.X, origin.Y);
|
transform.RotateAt(rotation, origin.X, origin.Y);
|
||||||
viewportTransform.Matrix = transform;
|
ViewportTransform.Matrix = transform;
|
||||||
|
|
||||||
transform = GetVisualTransform();
|
transform = GetVisualTransform();
|
||||||
|
|
||||||
if (tileLayers != null)
|
foreach (TileLayer tileLayer in Children)
|
||||||
{
|
|
||||||
foreach (TileLayer tileLayer in tileLayers)
|
|
||||||
{
|
{
|
||||||
tileLayer.TransformMatrix = transform;
|
tileLayer.TransformMatrix = transform;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
updateTimer.IsEnabled = true;
|
updateTimer.IsEnabled = true;
|
||||||
|
|
||||||
|
|
@ -113,7 +121,7 @@ namespace MapControl
|
||||||
int zoom = (int)Math.Floor(zoomLevel + 1d - zoomLevelSwitchOffset);
|
int zoom = (int)Math.Floor(zoomLevel + 1d - zoomLevelSwitchOffset);
|
||||||
int numTiles = 1 << zoom;
|
int numTiles = 1 << zoom;
|
||||||
double mapToTileScale = (double)numTiles / 360d;
|
double mapToTileScale = (double)numTiles / 360d;
|
||||||
Matrix transform = viewportTransform.Matrix;
|
Matrix transform = ViewportTransform.Matrix;
|
||||||
transform.Invert(); // view to map coordinates
|
transform.Invert(); // view to map coordinates
|
||||||
transform.Translate(180d, -180d);
|
transform.Translate(180d, -180d);
|
||||||
transform.Scale(mapToTileScale, -mapToTileScale); // map coordinates to tile indices
|
transform.Scale(mapToTileScale, -mapToTileScale); // map coordinates to tile indices
|
||||||
|
|
@ -142,77 +150,12 @@ namespace MapControl
|
||||||
tileGrid = grid;
|
tileGrid = grid;
|
||||||
transform = GetVisualTransform();
|
transform = GetVisualTransform();
|
||||||
|
|
||||||
if (tileLayers != null)
|
|
||||||
{
|
|
||||||
foreach (TileLayer tileLayer in tileLayers)
|
|
||||||
{
|
|
||||||
tileLayer.TransformMatrix = transform;
|
|
||||||
tileLayer.UpdateTiles(tileZoomLevel, tileGrid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TileLayersChanged(object sender, NotifyCollectionChangedEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
switch (eventArgs.Action)
|
|
||||||
{
|
|
||||||
case NotifyCollectionChangedAction.Add:
|
|
||||||
AddChildren(eventArgs.NewStartingIndex, eventArgs.NewItems);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NotifyCollectionChangedAction.Remove:
|
|
||||||
RemoveChildren(eventArgs.OldStartingIndex, eventArgs.OldItems);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NotifyCollectionChangedAction.Move:
|
|
||||||
case NotifyCollectionChangedAction.Replace:
|
|
||||||
RemoveChildren(eventArgs.OldStartingIndex, eventArgs.OldItems);
|
|
||||||
AddChildren(eventArgs.NewStartingIndex, eventArgs.NewItems);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NotifyCollectionChangedAction.Reset:
|
|
||||||
ClearChildren();
|
|
||||||
if (eventArgs.NewItems != null)
|
|
||||||
{
|
|
||||||
AddChildren(0, eventArgs.NewItems);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
((Map)VisualParent).OnTileLayersChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddChildren(int index, IList layers)
|
|
||||||
{
|
|
||||||
Matrix transform = GetVisualTransform();
|
|
||||||
|
|
||||||
foreach (TileLayer tileLayer in layers)
|
|
||||||
{
|
|
||||||
Children.Insert(index++, tileLayer);
|
|
||||||
tileLayer.TransformMatrix = transform;
|
|
||||||
tileLayer.UpdateTiles(tileZoomLevel, tileGrid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveChildren(int index, IList layers)
|
|
||||||
{
|
|
||||||
foreach (TileLayer tileLayer in layers)
|
|
||||||
{
|
|
||||||
tileLayer.ClearTiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
Children.RemoveRange(index, layers.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearChildren()
|
|
||||||
{
|
|
||||||
foreach (TileLayer tileLayer in Children)
|
foreach (TileLayer tileLayer in Children)
|
||||||
{
|
{
|
||||||
tileLayer.ClearTiles();
|
tileLayer.TransformMatrix = transform;
|
||||||
}
|
tileLayer.UpdateTiles(tileZoomLevel, tileGrid);
|
||||||
|
}
|
||||||
Children.Clear();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ namespace MapControl
|
||||||
tileImageLoader = new TileImageLoader(this);
|
tileImageLoader = new TileImageLoader(this);
|
||||||
VisualEdgeMode = EdgeMode.Aliased;
|
VisualEdgeMode = EdgeMode.Aliased;
|
||||||
VisualTransform = new MatrixTransform();
|
VisualTransform = new MatrixTransform();
|
||||||
Name = string.Empty;
|
|
||||||
MinZoomLevel = 1;
|
MinZoomLevel = 1;
|
||||||
MaxZoomLevel = 18;
|
MaxZoomLevel = 18;
|
||||||
MaxParallelDownloads = 8;
|
MaxParallelDownloads = 8;
|
||||||
|
|
@ -59,7 +58,7 @@ namespace MapControl
|
||||||
|
|
||||||
tileImageLoader.CancelGetTiles();
|
tileImageLoader.CancelGetTiles();
|
||||||
|
|
||||||
if (VisualParent != null && TileSource != null)
|
if (TileSource != null)
|
||||||
{
|
{
|
||||||
SelectTiles();
|
SelectTiles();
|
||||||
RenderTiles();
|
RenderTiles();
|
||||||
|
|
@ -76,11 +75,11 @@ namespace MapControl
|
||||||
|
|
||||||
private void SelectTiles()
|
private void SelectTiles()
|
||||||
{
|
{
|
||||||
TileContainer tileContainer = VisualParent as TileContainer;
|
|
||||||
int maxZoomLevel = Math.Min(zoomLevel, MaxZoomLevel);
|
int maxZoomLevel = Math.Min(zoomLevel, MaxZoomLevel);
|
||||||
int minZoomLevel = maxZoomLevel;
|
int minZoomLevel = maxZoomLevel;
|
||||||
|
ContainerVisual parent = Parent as ContainerVisual;
|
||||||
|
|
||||||
if (tileContainer != null && tileContainer.TileLayers.IndexOf(this) == 0)
|
if (parent != null && parent.Children.IndexOf(this) == 0)
|
||||||
{
|
{
|
||||||
minZoomLevel = MinZoomLevel;
|
minZoomLevel = MinZoomLevel;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
<local:SampleItemCollection x:Key="Polylines"/>
|
<local:SampleItemCollection x:Key="Polylines"/>
|
||||||
<local:SampleItemCollection x:Key="Points"/>
|
<local:SampleItemCollection x:Key="Points"/>
|
||||||
<local:SampleItemCollection x:Key="Pushpins"/>
|
<local:SampleItemCollection x:Key="Pushpins"/>
|
||||||
|
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
<DataTemplate x:Key="PolylineItemTemplate">
|
<DataTemplate x:Key="PolylineItemTemplate">
|
||||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
@ -64,6 +65,7 @@
|
||||||
</Style>
|
</Style>
|
||||||
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
|
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
|
||||||
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
|
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
|
||||||
|
<Setter Property="Visibility" Value="{Binding (map:MapPanel.IsInsideMapBounds), Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
|
|
@ -88,7 +90,7 @@
|
||||||
<map:Map Name="map" IsManipulationEnabled="True" Margin="2" FontSize="10"
|
<map:Map Name="map" IsManipulationEnabled="True" Margin="2" FontSize="10"
|
||||||
LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
|
LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
|
||||||
Center="53.5,8.2" ZoomLevel="11"
|
Center="53.5,8.2" ZoomLevel="11"
|
||||||
MainTileLayer="{Binding ElementName=tileLayerComboBox, Path=SelectedItem}"
|
MainTileLayer="{Binding SelectedItem, ElementName=tileLayerComboBox}"
|
||||||
ManipulationInertiaStarting="MapManipulationInertiaStarting"
|
ManipulationInertiaStarting="MapManipulationInertiaStarting"
|
||||||
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave">
|
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave">
|
||||||
<map:MapGraticule Opacity="0.6"/>
|
<map:MapGraticule Opacity="0.6"/>
|
||||||
|
|
@ -100,9 +102,10 @@
|
||||||
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
|
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
|
||||||
ItemContainerStyle="{StaticResource PushpinItemStyle}"
|
ItemContainerStyle="{StaticResource PushpinItemStyle}"
|
||||||
IsSynchronizedWithCurrentItem="True"/>
|
IsSynchronizedWithCurrentItem="True"/>
|
||||||
<map:Pushpin Location="53.5,8.2" Background="Yellow" Foreground="Blue">N 53° 30' E 8° 12'</map:Pushpin>
|
<map:Pushpin Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"
|
||||||
|
Visibility="{Binding (map:MapPanel.IsInsideMapBounds), Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
|
||||||
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="2,0,0,0" FontSize="10"
|
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="2,0,0,0" FontSize="10"
|
||||||
Text="{Binding ElementName=map, Path=MainTileLayer.Description}"/>
|
Text="{Binding MainTileLayer.Description, ElementName=map}"/>
|
||||||
</map:Map>
|
</map:Map>
|
||||||
<Grid Grid.Row="1" Margin="2">
|
<Grid Grid.Row="1" Margin="2">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|
@ -112,9 +115,9 @@
|
||||||
<TextBlock Name="mouseLocation" Margin="4" VerticalAlignment="Center"/>
|
<TextBlock Name="mouseLocation" Margin="4" VerticalAlignment="Center"/>
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
<Slider Name="zoomSlider" ToolTip="Zoom Level" Margin="4,0,4,0" Width="100" Minimum="1" Maximum="20" SmallChange="0.01"
|
<Slider Name="zoomSlider" ToolTip="Zoom Level" Margin="4,0,4,0" Width="100" Minimum="1" Maximum="20" SmallChange="0.01"
|
||||||
Value="{Binding ElementName=map, Path=TargetZoomLevel}" />
|
Value="{Binding TargetZoomLevel, ElementName=map}" />
|
||||||
<Slider Name="headingSlider" ToolTip="Heading" Margin="4,0,4,0" Width="100" Minimum="0" Maximum="360" SmallChange="10" LargeChange="45"
|
<Slider Name="headingSlider" ToolTip="Heading" Margin="4,0,4,0" Width="100" Minimum="0" Maximum="360" SmallChange="10" LargeChange="45"
|
||||||
Value="{Binding ElementName=map, Path=TargetHeading}"/>
|
Value="{Binding TargetHeading, ElementName=map}"/>
|
||||||
<CheckBox ToolTip="Map Overlay" Margin="4,0,4,0" VerticalAlignment="Center" Content="Seamarks" Click="SeamarksClick"/>
|
<CheckBox ToolTip="Map Overlay" Margin="4,0,4,0" VerticalAlignment="Center" Content="Seamarks" Click="SeamarksClick"/>
|
||||||
<ComboBox Name="tileLayerComboBox" ToolTip="Main Tile Layer" Margin="4,0,4,0" DisplayMemberPath="Name" SelectedIndex="0">
|
<ComboBox Name="tileLayerComboBox" ToolTip="Main Tile Layer" Margin="4,0,4,0" DisplayMemberPath="Name" SelectedIndex="0">
|
||||||
<ComboBox.Items>
|
<ComboBox.Items>
|
||||||
|
|
@ -129,7 +132,11 @@
|
||||||
<map:TileLayer Name="MapQuest OSM" Description="MapQuest OSM - © {y} MapQuest & OpenStreetMap Contributors"
|
<map:TileLayer Name="MapQuest OSM" Description="MapQuest OSM - © {y} MapQuest & OpenStreetMap Contributors"
|
||||||
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"/>
|
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"/>
|
||||||
|
|
||||||
<!--<map:TileLayer Name="Google Maps" Description="Google Maps - © {y} Google"
|
<!-- Note: The providers of the below TileLayers do not allow access to their
|
||||||
|
map content without using their APIs (i.e. Google Maps API or Bing Maps API).
|
||||||
|
Hence the declarations below are for demonstration purpose only. -->
|
||||||
|
|
||||||
|
<map:TileLayer Name="Google Maps" Description="Google Maps - © {y} Google"
|
||||||
TileSource="http://mt{i}.google.com/vt/x={x}&y={y}&z={z}" MaxZoomLevel="20"/>
|
TileSource="http://mt{i}.google.com/vt/x={x}&y={y}&z={z}" MaxZoomLevel="20"/>
|
||||||
<map:TileLayer Name="Google Images" Description="Google Maps - © {y} Google"
|
<map:TileLayer Name="Google Images" Description="Google Maps - © {y} Google"
|
||||||
TileSource="http://khm{i}.google.com/kh/v=113&x={x}&y={y}&z={z}" MaxZoomLevel="20" HasDarkBackground="True"/>
|
TileSource="http://khm{i}.google.com/kh/v=113&x={x}&y={y}&z={z}" MaxZoomLevel="20" HasDarkBackground="True"/>
|
||||||
|
|
@ -138,9 +145,9 @@
|
||||||
<map:TileLayer Name="Bing Images" Description="Bing Maps - © {y} Microsoft Corporation"
|
<map:TileLayer Name="Bing Images" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0" MaxZoomLevel="20" HasDarkBackground="True"/>
|
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=0" MaxZoomLevel="20" HasDarkBackground="True"/>
|
||||||
<map:TileLayer Name="Bing Hybrid" Description="Bing Maps - © {y} Microsoft Corporation"
|
<map:TileLayer Name="Bing Hybrid" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/h{q}.jpeg?g=0&stl=h" MaxZoomLevel="20" HasDarkBackground="True"/>-->
|
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/h{q}.jpeg?g=0&stl=h" MaxZoomLevel="20" HasDarkBackground="True"/>
|
||||||
|
|
||||||
<!-- The TileLayer below uses an ImageTileSource that bypasses caching of map tile images -->
|
<!-- The TileLayer below uses an ImageTileSource, which bypasses caching of map tile images -->
|
||||||
|
|
||||||
<map:TileLayer Name="OSM Uncached" Description="© {y} OpenStreetMap Contributors, CC-BY-SA">
|
<map:TileLayer Name="OSM Uncached" Description="© {y} OpenStreetMap Contributors, CC-BY-SA">
|
||||||
<map:TileLayer.TileSource>
|
<map:TileLayer.TileSource>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue