Version 2.4.2.:

- added HyperlinkText.InlinesSource attached property
- simplified TileLayerCollection, removed it from MapBase
- simplified MapRectangle and MapImage
This commit is contained in:
ClemensF 2014-12-17 21:38:28 +01:00
parent 1583b10ff3
commit f6a881c674
36 changed files with 456 additions and 372 deletions

View file

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

View file

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

View file

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

View file

@ -49,7 +49,7 @@ namespace MapControl.Caching
var cacheItem = new ImageCacheItem
{
Buffer = await FileIO.ReadBufferAsync(file),
Buffer = await FileIO.ReadBufferAsync(file)
};
try

View file

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

View file

@ -6,8 +6,12 @@ using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
#if WINDOWS_RUNTIME
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
#else
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
#endif
@ -21,7 +25,7 @@ namespace MapControl
/// Converts text containing hyperlinks in markdown syntax [text](url)
/// to a collection of Run and Hyperlink inlines.
/// </summary>
public static List<Inline> ToInlines(this string text)
public static IEnumerable<Inline> TextToInlines(this string text)
{
var inlines = new List<Inline>();
@ -56,5 +60,51 @@ namespace MapControl
return inlines;
}
public static readonly DependencyProperty InlinesSourceProperty = DependencyProperty.RegisterAttached(
"InlinesSource", typeof(string), typeof(HyperlinkText), new PropertyMetadata(null, InlinesSourcePropertyChanged));
public static string GetInlinesSource(UIElement element)
{
return (string)element.GetValue(InlinesSourceProperty);
}
public static void SetInlinesSource(UIElement element, string value)
{
element.SetValue(InlinesSourceProperty, value);
}
private static void InlinesSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
InlineCollection inlines = null;
if (obj is TextBlock)
{
inlines = ((TextBlock)obj).Inlines;
}
else if (obj is Paragraph)
{
inlines = ((Paragraph)obj).Inlines;
}
#if WINDOWS_RUNTIME || SILVERLIGHT
else if (obj is RichTextBlock)
{
var paragraph = new Paragraph();
inlines = paragraph.Inlines;
var richTextBlock = (RichTextBlock)obj;
richTextBlock.Blocks.Clear();
richTextBlock.Blocks.Add(paragraph);
}
#endif
if (inlines != null)
{
inlines.Clear();
foreach (var inline in TextToInlines((string)e.NewValue))
{
inlines.Add(inline);
}
}
}
}
}

View file

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
#if WINDOWS_RUNTIME
@ -39,8 +40,8 @@ namespace MapControl
(o, e) => ((MapBase)o).TileLayerPropertyChanged((TileLayer)e.NewValue)));
public static readonly DependencyProperty TileLayersProperty = DependencyProperty.Register(
"TileLayers", typeof(TileLayerCollection), typeof(MapBase), new PropertyMetadata(null,
(o, e) => ((MapBase)o).TileLayersPropertyChanged((TileLayerCollection)e.OldValue, (TileLayerCollection)e.NewValue)));
"TileLayers", typeof(IList<TileLayer>), typeof(MapBase), new PropertyMetadata(null,
(o, e) => ((MapBase)o).TileLayersPropertyChanged((IList<TileLayer>)e.OldValue, (IList<TileLayer>)e.NewValue)));
public static readonly DependencyProperty MinZoomLevelProperty = DependencyProperty.Register(
"MinZoomLevel", typeof(double), typeof(MapBase), new PropertyMetadata(1d,
@ -74,7 +75,7 @@ namespace MapControl
public MapBase()
{
Children.Add(tileLayerPanel);
TileLayers = new TileLayerCollection();
TileLayers = new ObservableCollection<TileLayer>();
tileUpdateTimer.Tick += UpdateTiles;
Loaded += OnLoaded;
@ -119,9 +120,9 @@ namespace MapControl
/// The additional TileLayers usually have transparent backgrounds and their IsOverlay
/// property is set to true.
/// </summary>
public TileLayerCollection TileLayers
public IList<TileLayer> TileLayers
{
get { return (TileLayerCollection)GetValue(TileLayersProperty); }
get { return (IList<TileLayer>)GetValue(TileLayersProperty); }
set { SetValue(TileLayersProperty, value); }
}
@ -416,7 +417,7 @@ namespace MapControl
{
if (TileLayers == null)
{
TileLayers = new TileLayerCollection(tileLayer);
TileLayers = new ObservableCollection<TileLayer>(new TileLayer[] { tileLayer });
}
else if (TileLayers.Count == 0)
{
@ -429,11 +430,15 @@ namespace MapControl
}
}
private void TileLayersPropertyChanged(TileLayerCollection oldTileLayers, TileLayerCollection newTileLayers)
private void TileLayersPropertyChanged(IList<TileLayer> oldTileLayers, IList<TileLayer> newTileLayers)
{
if (oldTileLayers != null)
{
oldTileLayers.CollectionChanged -= TileLayerCollectionChanged;
var oldCollection = oldTileLayers as INotifyCollectionChanged;
if (oldCollection != null)
{
oldCollection.CollectionChanged -= TileLayerCollectionChanged;
}
TileLayer = null;
RemoveTileLayers(0, oldTileLayers.Count);
@ -444,7 +449,11 @@ namespace MapControl
TileLayer = newTileLayers.FirstOrDefault();
AddTileLayers(0, newTileLayers);
newTileLayers.CollectionChanged += TileLayerCollectionChanged;
var newCollection = newTileLayers as INotifyCollectionChanged;
if (newCollection != null)
{
newCollection.CollectionChanged += TileLayerCollectionChanged;
}
}
}

View file

@ -72,7 +72,6 @@
<Compile Include="MapPolyline.cs" />
<Compile Include="MapPolyline.Silverlight.WinRT.cs" />
<Compile Include="MapRectangle.cs" />
<Compile Include="MapRectangle.Silverlight.WinRT.cs" />
<Compile Include="MapTransform.cs" />
<Compile Include="MatrixEx.cs" />
<Compile Include="MercatorTransform.cs" />

View file

@ -99,7 +99,6 @@
<Compile Include="MapPolyline.cs" />
<Compile Include="MapPolyline.Silverlight.WinRT.cs" />
<Compile Include="MapRectangle.cs" />
<Compile Include="MapRectangle.Silverlight.WinRT.cs" />
<Compile Include="MapTransform.cs" />
<Compile Include="MatrixEx.cs" />
<Compile Include="MercatorTransform.cs" />

View file

@ -19,21 +19,23 @@ namespace MapControl
{
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
"Source", typeof(ImageSource), typeof(MapImage),
new PropertyMetadata(null, (o, e) => ((MapImage)o).SourcePropertyChanged((ImageSource)e.NewValue)));
new PropertyMetadata(null, (o, e) => ((ImageBrush)((MapImage)o).Fill).ImageSource = (ImageSource)e.NewValue));
public MapImage()
{
Fill = new ImageBrush
{
RelativeTransform = new MatrixTransform
{
Matrix = new Matrix(1d, 0d, 0d, -1d, 0d, 1d)
}
};
}
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
private void SourcePropertyChanged(ImageSource image)
{
Fill = new ImageBrush
{
ImageSource = image,
RelativeTransform = FillTransform
};
}
}
}

View file

@ -2,11 +2,9 @@
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
#if WINDOWS_RUNTIME
using Windows.Foundation;
using Windows.UI.Xaml;
#else
using System.Windows;
@ -20,15 +18,8 @@ namespace MapControl
/// </summary>
public partial class MapPolyline : MapPath
{
#if WINDOWS_RUNTIME
// For Windows Runtime, the Locations dependency property type is declared as object
// instead of IEnumerable. See http://stackoverflow.com/q/10544084/1136211
private static readonly Type LocationsPropertyType = typeof(object);
#else
private static readonly Type LocationsPropertyType = typeof(IEnumerable<Location>);
#endif
public static readonly DependencyProperty LocationsProperty = DependencyProperty.Register(
"Locations", LocationsPropertyType, typeof(MapPolyline),
"Locations", typeof(IEnumerable<Location>), typeof(MapPolyline),
new PropertyMetadata(null, LocationsPropertyChanged));
public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register(

View file

@ -1,24 +0,0 @@
// XAML Map Control - http://xamlmapcontrol.codeplex.com/
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
#if WINDOWS_RUNTIME
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
#else
using System.Windows;
using System.Windows.Media;
#endif
namespace MapControl
{
public partial class MapRectangle
{
private void SetRect(Rect rect)
{
((RectangleGeometry)Data).Rect = rect;
RenderTransform = ParentMap.ViewportTransform;
}
}
}

View file

@ -2,7 +2,6 @@
// Copyright © 2014 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Windows;
using System.Windows.Media;
@ -10,31 +9,21 @@ namespace MapControl
{
public partial class MapRectangle
{
static MapRectangle()
static partial void ScaleRect(ref Rect rect, ref Transform transform)
{
FillTransform.Freeze();
}
private void SetRect(Rect rect)
{
// Apply scaling to the RectangleGeometry to compensate for inaccurate hit testing in WPF.
// Scales the RectangleGeometry to compensate inaccurate hit testing in WPF.
// See http://stackoverflow.com/a/19335624/1136211
var scale = 1e6 / Math.Min(rect.Width, rect.Height);
rect.X *= scale;
rect.Y *= scale;
rect.Width *= scale;
rect.Height *= scale;
rect.Scale(1e6, 1e6);
var scaleTransform = new ScaleTransform(1d / scale, 1d / scale);
var scaleTransform = new ScaleTransform(1e-6, 1e-6); // reverts rect scaling
scaleTransform.Freeze();
var transform = new TransformGroup();
transform.Children.Add(scaleTransform); // revert scaling
transform.Children.Add(ParentMap.ViewportTransform);
var transformGroup = new TransformGroup();
transformGroup.Children.Add(scaleTransform);
transformGroup.Children.Add(transform);
((RectangleGeometry)Data).Rect = rect;
RenderTransform = transform;
transform = transformGroup;
}
}
}

View file

@ -18,14 +18,6 @@ namespace MapControl
/// </summary>
public partial class MapRectangle : MapPath
{
/// <summary>
/// Used in derived classes like MapImage.
/// </summary>
protected static readonly MatrixTransform FillTransform = new MatrixTransform
{
Matrix = new Matrix(1d, 0d, 0d, -1d, 0d, 1d)
};
public static readonly DependencyProperty WestProperty = DependencyProperty.Register(
"West", typeof(double), typeof(MapRectangle),
new PropertyMetadata(double.NaN, (o, e) => ((MapRectangle)o).UpdateData()));
@ -81,9 +73,14 @@ namespace MapControl
!double.IsNaN(West) && !double.IsNaN(East) &&
South < North && West < East)
{
SetRect(new Rect(
ParentMap.MapTransform.Transform(new Location(South, West)),
ParentMap.MapTransform.Transform(new Location(North, East))));
var rect = new Rect(ParentMap.MapTransform.Transform(new Location(South, West)),
ParentMap.MapTransform.Transform(new Location(North, East)));
var transform = ParentMap.ViewportTransform;
ScaleRect(ref rect, ref transform);
geometry.Rect = rect;
RenderTransform = transform;
}
else
{
@ -91,5 +88,7 @@ namespace MapControl
ClearValue(RenderTransformProperty);
}
}
static partial void ScaleRect(ref Rect rect, ref Transform transform);
}
}

View file

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

View file

@ -85,7 +85,7 @@ namespace MapControl
}
else
{
var tileList = tiles.ToList();
var tileList = tiles.ToList(); // force immediate evaluation
var sourceName = tileLayer.SourceName;
var maxDownloads = tileLayer.MaxParallelDownloads;
@ -101,7 +101,7 @@ namespace MapControl
while (pendingTiles.TryDequeue(out pendingTile)) ; // no Clear method
}
private void GetTiles(List<Tile> tiles, Dispatcher dispatcher, TileSource tileSource, string sourceName, int maxDownloads)
private void GetTiles(IEnumerable<Tile> tiles, Dispatcher dispatcher, TileSource tileSource, string sourceName, int maxDownloads)
{
if (Cache != null &&
!string.IsNullOrWhiteSpace(sourceName) &&

View file

@ -8,12 +8,10 @@ using System.Linq;
#if WINDOWS_RUNTIME
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
#else
using System.Windows;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Windows.Media;
#endif
@ -158,16 +156,6 @@ namespace MapControl
set { SetValue(BackgroundProperty, value); }
}
/// <summary>
/// In case the Description text contains copyright links in markdown syntax [text](url),
/// the DescriptionInlines property may be used to create a collection of Run and Hyperlink
/// inlines to be displayed in e.g. a TextBlock or a Silverlight RichTextBlock.
/// </summary>
public List<Inline> DescriptionInlines
{
get { return Description.ToInlines(); }
}
public MapBase ParentMap
{
get { return parentMap; }

View file

@ -7,17 +7,12 @@ using System.Linq;
namespace MapControl
{
public class TileLayerCollection : ObservableCollection<TileLayer>
/// <summary>
/// A collection of TileLayers with a string indexer that allows
/// to retrieve individual TileLayers by their SourceName property.
/// </summary>
public class TileLayerCollection : Collection<TileLayer>
{
internal TileLayerCollection(TileLayer tileLayer)
{
Add(tileLayer);
}
public TileLayerCollection()
{
}
public TileLayer this[string sourceName]
{
get { return this.FirstOrDefault(t => t.SourceName == sourceName); }

View file

@ -126,9 +126,6 @@
<Compile Include="..\MapRectangle.cs">
<Link>MapRectangle.cs</Link>
</Compile>
<Compile Include="..\MapRectangle.Silverlight.WinRT.cs">
<Link>MapRectangle.Silverlight.WinRT.cs</Link>
</Compile>
<Compile Include="..\MapTransform.cs">
<Link>MapTransform.cs</Link>
</Compile>

View file

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

View file

@ -11,7 +11,7 @@ using MapControl;
namespace ViewModel
{
public class VmBase : INotifyPropertyChanged
public class Base : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
@ -25,7 +25,7 @@ namespace ViewModel
}
}
public class VmPoint : VmBase
public class Point : Base
{
private string name;
public string Name
@ -50,16 +50,16 @@ namespace ViewModel
}
}
public class VmPolyline
public class Polyline
{
public LocationCollection Locations { get; set; }
}
public class ViewModel : VmBase
public class ViewModel : Base
{
public ObservableCollection<VmPoint> Points { get; set; }
public ObservableCollection<VmPoint> Pushpins { get; set; }
public ObservableCollection<VmPolyline> Polylines { get; set; }
public ObservableCollection<Point> Points { get; set; }
public ObservableCollection<Point> Pushpins { get; set; }
public ObservableCollection<Polyline> Polylines { get; set; }
private Location mapCenter;
public Location MapCenter
@ -76,71 +76,71 @@ namespace ViewModel
{
MapCenter = new Location(53.5, 8.2);
Points = new ObservableCollection<VmPoint>();
Points = new ObservableCollection<Point>();
Points.Add(
new VmPoint
new Point
{
Name = "Steinbake Leitdamm",
Location = new Location(53.51217, 8.16603)
});
Points.Add(
new VmPoint
new Point
{
Name = "Buhne 2",
Location = new Location(53.50926, 8.15815)
});
Points.Add(
new VmPoint
new Point
{
Name = "Buhne 4",
Location = new Location(53.50468, 8.15343)
});
Points.Add(
new VmPoint
new Point
{
Name = "Buhne 6",
Location = new Location(53.50092, 8.15267)
});
Points.Add(
new VmPoint
new Point
{
Name = "Buhne 8",
Location = new Location(53.49871, 8.15321)
});
Points.Add(
new VmPoint
new Point
{
Name = "Buhne 10",
Location = new Location(53.49350, 8.15563)
});
Points.Add(
new VmPoint
new Point
{
Name = "Moving",
Location = new Location(53.5, 8.25)
});
Pushpins = new ObservableCollection<VmPoint>();
Pushpins = new ObservableCollection<Point>();
Pushpins.Add(
new VmPoint
new Point
{
Name = "WHV - Eckwarderhörne",
Location = new Location(53.5495, 8.1877)
});
Pushpins.Add(
new VmPoint
new Point
{
Name = "JadeWeserPort",
Location = new Location(53.5914, 8.14)
});
Pushpins.Add(
new VmPoint
new Point
{
Name = "Kurhaus Dangast",
Location = new Location(53.447, 8.1114)
});
Pushpins.Add(
new VmPoint
new Point
{
Name = "Eckwarderhörne",
Location = new Location(53.5207, 8.2323)
@ -157,14 +157,14 @@ namespace ViewModel
// });
//}
Polylines = new ObservableCollection<VmPolyline>();
Polylines = new ObservableCollection<Polyline>();
Polylines.Add(
new VmPolyline
new Polyline
{
Locations = LocationCollection.Parse("53.5140,8.1451 53.5123,8.1506 53.5156,8.1623 53.5276,8.1757 53.5491,8.1852 53.5495,8.1877 53.5426,8.1993 53.5184,8.2219 53.5182,8.2386 53.5195,8.2387")
});
Polylines.Add(
new VmPolyline
new Polyline
{
Locations = LocationCollection.Parse("53.5978,8.1212 53.6018,8.1494 53.5859,8.1554 53.5852,8.1531 53.5841,8.1539 53.5802,8.1392 53.5826,8.1309 53.5867,8.1317 53.5978,8.1212")
});

View file

@ -65,9 +65,9 @@
</Page.Resources>
<Grid>
<map:MapBase x:Name="map" ZoomLevel="11" MinZoomLevel="2"
TileLayer="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}"
ManipulationMode="Scale,TranslateX,TranslateY,TranslateInertia"
ManipulationStarted="MapManipulationStarted"
ManipulationCompleted="MapManipulationCompleted"
ManipulationDelta="MapManipulationDelta">
<map:MapBase.Center>
<map:Location Latitude="53.5" Longitude="8.2"/>
@ -97,7 +97,7 @@
</map:MapBase>
<Border HorizontalAlignment="Stretch" VerticalAlignment="Top" Background="#7F000000">
<TextBlock x:Name="mapLegend" Margin="2" FontSize="12"/>
<TextBlock Margin="2" FontSize="12" map:HyperlinkText.InlinesSource="{Binding TileLayer.Description, ElementName=map}"/>
</Border>
</Grid>

View file

@ -10,8 +10,7 @@ namespace PhoneApplication
{
public sealed partial class MainPage : Page
{
private TileLayerCollection tileLayers;
private bool manipulationActive;
private bool mapCentered;
public MainPage()
{
@ -19,66 +18,48 @@ namespace PhoneApplication
InitializeComponent();
tileLayers = (TileLayerCollection)Resources["TileLayers"];
SetTileLayer(tileLayers[0].SourceName);
DataContext = new ViewModel(Dispatcher);
NavigationCacheMode = NavigationCacheMode.Required;
}
private void SetTileLayer(string tileLayer)
private void MapMenuItemClick(object sender, RoutedEventArgs e)
{
map.TileLayer = tileLayers[tileLayer];
mapLegend.Inlines.Clear();
foreach (var inline in map.TileLayer.DescriptionInlines)
{
mapLegend.Inlines.Add(inline);
}
var tileLayers = (TileLayerCollection)Resources["TileLayers"];
map.TileLayer = tileLayers[(string)((FrameworkElement)sender).Tag];
}
private void SeamarksChecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Add((TileLayer)tileLayers["Seamarks"]);
var tileLayers = (TileLayerCollection)Resources["TileLayers"];
map.TileLayers.Add(tileLayers["Seamarks"]);
}
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Remove((TileLayer)tileLayers["Seamarks"]);
}
private void MapMenuItemClick(object sender, RoutedEventArgs e)
{
var selectedItem = (MenuFlyoutItem)sender;
SetTileLayer((string)selectedItem.Tag);
var tileLayers = (TileLayerCollection)Resources["TileLayers"];
map.TileLayers.Remove(tileLayers["Seamarks"]);
}
private void CenterButtonClick(object sender, RoutedEventArgs e)
{
manipulationActive = false;
map.TargetCenter = ((ViewModel)DataContext).Location;
mapCentered = true;
}
private void MapManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
manipulationActive = true;
}
private void MapManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
manipulationActive = false;
mapCentered = false;
}
private void MapManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (manipulationActive)
if (mapCentered)
{
map.TransformMap(e.Position, e.Delta.Translation, e.Delta.Rotation, e.Delta.Scale);
e.Complete();
}
else
{
e.Complete();
map.TransformMap(e.Position, e.Delta.Translation, e.Delta.Rotation, e.Delta.Scale);
}
}
}

View file

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

View file

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

View file

@ -57,9 +57,11 @@
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="AerialWithLabels" MaxZoomLevel="19" Foreground="White" Background="Black"/>
</map:TileLayerCollection>
<DataTemplate x:Key="PolylineItemTemplate">
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
</DataTemplate>
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
<Setter Property="Template">
<Setter.Value>
@ -69,6 +71,7 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
<Setter Property="Template">
@ -113,6 +116,7 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
@ -125,18 +129,23 @@
</Setter>
</Style>
</UserControl.Resources>
<UserControl.DataContext>
<vm:ViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<map:Map x:Name="map" Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11"
<map:Map x:Name="map" TileLayer="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}"
Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11"
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave">
<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"/>
<map:MapGraticule Opacity="0.6"/>
<!-- use ItemTemplate or ItemContainerStyle alternatively -->
@ -162,7 +171,7 @@
</map:Map>
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#7FFFFFFF">
<RichTextBlock x:Name="mapLegend" Margin="4,2" FontSize="10"/>
<RichTextBlock Margin="4,2" FontSize="10" map:HyperlinkText.InlinesSource="{Binding TileLayer.Description, ElementName=map}"/>
</Border>
<Grid Grid.Row="1">
@ -191,18 +200,18 @@
</StackPanel>
<CheckBox Margin="5" VerticalAlignment="Bottom" Content="Seamarks"
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
<ComboBox x:Name="tileLayerComboBox" Width="130" Margin="5" VerticalAlignment="Bottom"
SelectionChanged="TileLayerSelectionChanged">
<ComboBoxItem Tag="OpenStreetMap">OpenStreetMap</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest OpenCycleMap">OpenCycleMap</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Landscape">Landscape</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Outdoors">Outdoors</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Transport">Transport</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Transport Dark">Transport Dark</ComboBoxItem>
<ComboBoxItem Tag="MapQuest OpenStreetMap">MapQuest Open</ComboBoxItem>
<!--<ComboBoxItem Tag="Bing Maps Road">Bing Maps Road</ComboBoxItem>
<ComboBoxItem Tag="Bing Maps Aerial">Bing Maps Aerial</ComboBoxItem>
<ComboBoxItem Tag="Bing Maps Hybrid">Bing Maps Hybrid</ComboBoxItem>-->
<ComboBox Width="130" Margin="5" VerticalAlignment="Bottom"
SelectedValuePath="Tag" SelectedValue="{Binding TileLayer, ElementName=map, Mode=TwoWay}">
<ComboBoxItem Tag="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}">OpenStreetMap</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest OpenCycleMap], Source={StaticResource TileLayers}}">OpenCycleMap</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Landscape], Source={StaticResource TileLayers}}">Landscape</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Outdoors], Source={StaticResource TileLayers}}">Outdoors</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Transport], Source={StaticResource TileLayers}}">Transport</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Transport Dark], Source={StaticResource TileLayers}}">Transport Dark</ComboBoxItem>
<ComboBoxItem Tag="{Binding [MapQuest OpenStreetMap], Source={StaticResource TileLayers}}">MapQuest Open</ComboBoxItem>
<!--<ComboBoxItem Tag="{Binding [Bing Maps Road], Source={StaticResource TileLayers}}">Bing Maps Road</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Bing Maps Aerial], Source={StaticResource TileLayers}}">Bing Maps Aerial</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Bing Maps Hybrid], Source={StaticResource TileLayers}}">Bing Maps Hybrid</ComboBoxItem>-->
</ComboBox>
</StackPanel>
</Grid>

View file

@ -2,7 +2,6 @@
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using MapControl;
@ -10,16 +9,11 @@ namespace SilverlightApplication
{
public partial class MainPage : UserControl
{
private TileLayerCollection tileLayers;
public MainPage()
{
//BingMapsTileLayer.ApiKey = "...";
InitializeComponent();
tileLayers = (TileLayerCollection)Resources["TileLayers"];
tileLayerComboBox.SelectedIndex = 0;
}
private void MapMouseMove(object sender, MouseEventArgs e)
@ -53,31 +47,14 @@ namespace SilverlightApplication
mouseLocation.Text = string.Empty;
}
private void TileLayerSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = (ComboBoxItem)tileLayerComboBox.SelectedItem;
map.TileLayer = tileLayers[(string)selectedItem.Tag];
var paragraph = new Paragraph();
foreach (var inline in map.TileLayer.DescriptionInlines)
{
paragraph.Inlines.Add(inline);
}
mapLegend.Blocks.Clear();
mapLegend.Blocks.Add(paragraph);
}
private void SeamarksChecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Add(tileLayers["Seamarks"]);
map.TileLayers.Add(((TileLayerCollection)Resources["TileLayers"])["Seamarks"]);
}
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Remove(tileLayers["Seamarks"]);
map.TileLayers.Remove(((TileLayerCollection)Resources["TileLayers"])["Seamarks"]);
}
}
}

View file

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

View file

@ -61,9 +61,11 @@
Description="Bing Maps - © Microsoft Corporation"
Mode="AerialWithLabels" MaxZoomLevel="19" Foreground="White" Background="Black"/>
</map:TileLayerCollection>
<DataTemplate x:Key="PolylineItemTemplate">
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
</DataTemplate>
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
<Setter Property="Template">
<Setter.Value>
@ -73,6 +75,7 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
<Setter Property="local:BindingHelper.LocationPath" Value="Location"/>
<Setter Property="Foreground" Value="Black"/>
@ -138,6 +141,7 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
<Setter Property="local:BindingHelper.LocationPath" Value="Location"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
@ -151,16 +155,18 @@
</Setter>
</Style>
</Page.Resources>
<Page.DataContext>
<vm:ViewModel/>
</Page.DataContext>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<map:Map x:Name="map" Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11"
Foreground="Black" ManipulationMode="All">
<map:Map x:Name="map" TileLayer="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}"
Center="{Binding MapCenter}" MinZoomLevel="2" MaxZoomLevel="18" ZoomLevel="11" ManipulationMode="All">
<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"/>
<map:MapGraticule Opacity="0.6"/>
@ -194,7 +200,8 @@
</map:Pushpin>
</map:Map>
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#BFFFFFFF">
<TextBlock x:Name="mapLegend" Margin="2" FontSize="10" Foreground="Black"/>
<TextBlock Margin="2" FontSize="10" Foreground="Black"
map:HyperlinkText.InlinesSource="{Binding TileLayer.Description, ElementName=map}"/>
</Border>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
@ -220,18 +227,18 @@
</StackPanel>
<CheckBox Margin="10" VerticalAlignment="Center" Content="Seamarks"
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
<ComboBox x:Name="tileLayerComboBox" Width="200" Margin="10" VerticalAlignment="Center"
SelectionChanged="TileLayerSelectionChanged">
<ComboBoxItem Tag="OpenStreetMap">OpenStreetMap</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest OpenCycleMap">OpenCycleMap</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Landscape">Landscape</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Outdoors">Outdoors</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Transport">Transport</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Transport Dark">Transport Dark</ComboBoxItem>
<ComboBoxItem Tag="MapQuest OpenStreetMap">MapQuest Open</ComboBoxItem>
<!--<ComboBoxItem Tag="Bing Maps Road">Bing Maps Road</ComboBoxItem>
<ComboBoxItem Tag="Bing Maps Aerial">Bing Maps Aerial</ComboBoxItem>
<ComboBoxItem Tag="Bing Maps Hybrid">Bing Maps Hybrid</ComboBoxItem>-->
<ComboBox Width="200" Margin="10" VerticalAlignment="Center"
SelectedValuePath="Tag" SelectedValue="{Binding TileLayer, ElementName=map, Mode=TwoWay}">
<ComboBoxItem Tag="{Binding [OpenStreetMap], Source={StaticResource TileLayers}}">OpenStreetMap</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest OpenCycleMap], Source={StaticResource TileLayers}}">OpenCycleMap</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Landscape], Source={StaticResource TileLayers}}">Landscape</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Outdoors], Source={StaticResource TileLayers}}">Outdoors</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Transport], Source={StaticResource TileLayers}}">Transport</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Thunderforest Transport Dark], Source={StaticResource TileLayers}}">Transport Dark</ComboBoxItem>
<ComboBoxItem Tag="{Binding [MapQuest OpenStreetMap], Source={StaticResource TileLayers}}">MapQuest Open</ComboBoxItem>
<!--<ComboBoxItem Tag="{Binding [Bing Maps Road], Source={StaticResource TileLayers}}">Bing Maps Road</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Bing Maps Aerial], Source={StaticResource TileLayers}}">Bing Maps Aerial</ComboBoxItem>
<ComboBoxItem Tag="{Binding [Bing Maps Hybrid], Source={StaticResource TileLayers}}">Bing Maps Hybrid</ComboBoxItem>-->
</ComboBox>
</StackPanel>
</Grid>

View file

@ -7,8 +7,6 @@ namespace StoreApplication
{
public sealed partial class MainPage : Page
{
private TileLayerCollection tileLayers;
public MainPage()
{
//TileImageLoader.Cache = new MapControl.Caching.ImageFileCache();
@ -16,9 +14,6 @@ namespace StoreApplication
//BingMapsTileLayer.ApiKey = "...";
this.InitializeComponent();
tileLayers = (TileLayerCollection)Resources["TileLayers"];
tileLayerComboBox.SelectedIndex = 0;
}
private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e)
@ -29,28 +24,14 @@ namespace StoreApplication
}
}
private void TileLayerSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = (ComboBoxItem)tileLayerComboBox.SelectedItem;
map.TileLayer = tileLayers[(string)selectedItem.Tag];
mapLegend.Inlines.Clear();
foreach (var inline in map.TileLayer.DescriptionInlines)
{
mapLegend.Inlines.Add(inline);
}
}
private void SeamarksChecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Add(tileLayers["Seamarks"]);
map.TileLayers.Add(((TileLayerCollection)Resources["TileLayers"])["Seamarks"]);
}
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Remove(tileLayers["Seamarks"]);
map.TileLayers.Remove(((TileLayerCollection)Resources["TileLayers"])["Seamarks"]);
}
}
}

View file

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

View file

@ -8,80 +8,81 @@
Title="XAML MapControl - WPF Test Application" Height="600" Width="800"
Stylus.IsPressAndHoldEnabled="False">
<Window.Resources>
<map:TileLayerCollection x:Key="TileLayers">
<!--
TileLayers with OpenStreetMap data.
-->
<map:TileLayer SourceName="OpenStreetMap"
Description="Maps © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
MaxZoomLevel="19"/>
<map:TileLayer SourceName="Thunderforest OpenCycleMap"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png"/>
<map:TileLayer SourceName="Thunderforest Landscape"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png"/>
<map:TileLayer SourceName="Thunderforest Outdoors"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png"/>
<map:TileLayer SourceName="Thunderforest Transport"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/transport/{z}/{x}/{y}.png"/>
<map:TileLayer SourceName="Thunderforest Transport Dark"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png"
Foreground="White" Background="Black"/>
<map:TileLayer SourceName="MapQuest OpenStreetMap"
Description="Maps © [MapQuest](http://www.mapquest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"
MaxZoomLevel="19"/>
<map:TileLayer SourceName="Seamarks"
TileSource="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"
MinZoomLevel="9" MaxZoomLevel="18"/>
<!--
TileLayers with OpenStreetMap data.
-->
<map:TileLayer x:Key="OpenStreetMap" SourceName="OpenStreetMap"
Description="Maps © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
MaxZoomLevel="19"/>
<map:TileLayer x:Key="OpenCycleMap" SourceName="Thunderforest OpenCycleMap"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png"/>
<map:TileLayer x:Key="Landscape" SourceName="Thunderforest Landscape"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png"/>
<map:TileLayer x:Key="Outdoors" SourceName="Thunderforest Outdoors"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png"/>
<map:TileLayer x:Key="Transport" SourceName="Thunderforest Transport"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/transport/{z}/{x}/{y}.png"/>
<map:TileLayer x:Key="TransportDark" SourceName="Thunderforest Transport Dark"
Description="Maps © [Thunderforest](http://www.thunderforest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://{c}.tile.thunderforest.com/transport-dark/{z}/{x}/{y}.png"
Foreground="White" Background="Black"/>
<map:TileLayer x:Key="MapQuest" SourceName="MapQuest OpenStreetMap"
Description="Maps © [MapQuest](http://www.mapquest.com/), Data © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://otile{n}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"
MaxZoomLevel="19"/>
<map:TileLayer x:Key="Seamarks" SourceName="Seamarks"
TileSource="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"
MinZoomLevel="9" MaxZoomLevel="18"/>
<!--
Bing Maps TileLayers with tile URLs retrieved from the Imagery Metadata Service
(see http://msdn.microsoft.com/en-us/library/ff701716.aspx).
A Bing Maps API Key (see http://msdn.microsoft.com/en-us/library/ff428642.aspx) is required
for using these layers and must be assigned to the static BingMapsTileLayer.ApiKey property.
-->
<map:BingMapsTileLayer SourceName="Bing Maps Road"
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="Road" MaxZoomLevel="19"/>
<map:BingMapsTileLayer SourceName="Bing Maps Aerial"
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="Aerial" MaxZoomLevel="19" Foreground="White" Background="Black"/>
<map:BingMapsTileLayer SourceName="Bing Maps Hybrid"
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="AerialWithLabels" MaxZoomLevel="19" Foreground="White" Background="Black"/>
<!--
Bing Maps TileLayers with tile URLs retrieved from the Imagery Metadata Service
(see http://msdn.microsoft.com/en-us/library/ff701716.aspx).
A Bing Maps API Key (see http://msdn.microsoft.com/en-us/library/ff428642.aspx) is required
for using these layers and must be assigned to the static BingMapsTileLayer.ApiKey property.
-->
<map:BingMapsTileLayer x:Key="BingRoad" SourceName="Bing Maps Road"
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="Road" MaxZoomLevel="19"/>
<map:BingMapsTileLayer x:Key="BingAerial" SourceName="Bing Maps Aerial"
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="Aerial" MaxZoomLevel="19" Foreground="White" Background="Black"/>
<map:BingMapsTileLayer x:Key="BingHybrid" SourceName="Bing Maps Hybrid"
Description="© [Microsoft Corporation](http://www.bing.com/maps/)"
Mode="AerialWithLabels" MaxZoomLevel="19" Foreground="White" Background="Black"/>
<!--
A TileLayer for World OSM WMS, a Web Map Service based on OpenStreetMap data.
-->
<!--<map:TileLayer SourceName="World OSM WMS"
Description="[World OSM WMS](http://www.osm-wms.de/) © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://129.206.228.72/cached/osm?SERVICE=WMS&amp;VERSION=1.1.1&amp;REQUEST=GetMap&amp;LAYERS=osm_auto:all&amp;STYLES=&amp;SRS=EPSG:900913&amp;BBOX={W},{S},{E},{N}&amp;WIDTH=256&amp;HEIGHT=256&amp;FORMAT=image/png"/>-->
<!--
A TileLayer for World OSM WMS, a Web Map Service based on OpenStreetMap data.
-->
<!--<map:TileLayer x:Key="WorldOsm" SourceName="World OSM WMS"
Description="[World OSM WMS](http://www.osm-wms.de/) © [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="http://129.206.228.72/cached/osm?SERVICE=WMS&amp;VERSION=1.1.1&amp;REQUEST=GetMap&amp;LAYERS=osm_auto:all&amp;STYLES=&amp;SRS=EPSG:900913&amp;BBOX={W},{S},{E},{N}&amp;WIDTH=256&amp;HEIGHT=256&amp;FORMAT=image/png"/>-->
<!--
A TileLayer that uses an ImageTileSource, which bypasses caching of map tile images
-->
<!--<map:TileLayer SourceName="OpenStreetMap No Cache"
Description="© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)">
<map:ImageTileSource IsAsync="True" UriFormat="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
</map:TileLayer>-->
<!--
A TileLayer that uses an ImageTileSource
-->
<!--<map:TileLayer x:Key="OsmImageTileSource"
Description="© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)">
<map:ImageTileSource IsAsync="True" UriFormat="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
</map:TileLayer>-->
<!--
A TileLayer that demonstrates how to access local tile image files (from ImageFileCache here)
-->
<!--<map:TileLayer x:Key="OsmLocalFiles"
Description="© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="file:///C:/ProgramData/MapControl/TileCache/OpenStreetMap/{z}/{x}/{y}.png"/>-->
<!--
A TileLayer that demonstrates how to access local tile image files (from ImageFileCache here)
-->
<!--<map:TileLayer SourceName="OSM Local Files"
Description="© [OpenStreetMap Contributors](http://www.openstreetmap.org/copyright)"
TileSource="file:///C:/ProgramData/MapControl/TileCache/OpenStreetMap/{z}/{x}/{y}.png"/>-->
</map:TileLayerCollection>
<local:LocationToVisibilityConverter x:Key="LocationToVisibilityConverter"/>
<DataTemplate x:Key="PolylineItemTemplate">
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
</DataTemplate>
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
<Setter Property="Template">
<Setter.Value>
@ -91,6 +92,7 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
<Setter Property="Foreground" Value="Black"/>
@ -104,7 +106,7 @@
<VisualState x:Name="Disabled"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="labelBackground" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="labelBackground" Storyboard.TargetProperty="Opacity" To="0.7" Duration="0:0:0.1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
@ -131,8 +133,8 @@
</Path.Data>
</Path>
<Grid Canvas.Left="15" Canvas.Top="-8">
<Rectangle x:Name="labelBackground" Fill="White" Opacity="0.7"/>
<TextBlock Margin="2,0,2,0" Text="{Binding Name}"/>
<Rectangle x:Name="labelBackground" Fill="White" Opacity="0"/>
<local:OutlinedText Margin="1" OutlineThickness="1.5" Text="{Binding Name}"/>
</Grid>
</Canvas>
</ControlTemplate>
@ -140,6 +142,7 @@
</Setter>
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
</Style>
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
<Setter Property="Visibility">
@ -166,15 +169,18 @@
</Style.Triggers>
</Style>
</Window.Resources>
<Window.DataContext>
<vm:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<map:Map x:Name="map" Center="{Binding MapCenter}" ZoomLevel="11" MaxZoomLevel="20"
<map:Map x:Name="map" ZoomLevel="11" MaxZoomLevel="20" Center="{Binding MapCenter}"
TileLayer="{StaticResource OpenStreetMap}"
MouseLeftButtonDown="MapMouseLeftButtonDown" MouseRightButtonDown="MapMouseRightButtonDown"
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave"
ManipulationInertiaStarting="MapManipulationInertiaStarting">
@ -223,7 +229,7 @@
</map:Map>
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#7FFFFFFF">
<TextBlock x:Name="mapLegend" Margin="2" FontSize="10"/>
<TextBlock Margin="2" FontSize="10" map:HyperlinkText.InlinesSource="{Binding TileLayer.Description, ElementName=map}"/>
</Border>
<Grid Grid.Row="1">
@ -252,18 +258,18 @@
</StackPanel>
<CheckBox ToolTip="Seamarks Overlay" Margin="7" VerticalAlignment="Bottom" Content="Seamarks"
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
<ComboBox x:Name="tileLayerComboBox" ToolTip="Tile Layer" Margin="5" VerticalAlignment="Bottom"
SelectionChanged="TileLayerSelectionChanged">
<ComboBoxItem Tag="OpenStreetMap">OpenStreetMap</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest OpenCycleMap">OpenCycleMap</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Landscape">Landscape</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Outdoors">Outdoors</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Transport">Transport</ComboBoxItem>
<ComboBoxItem Tag="Thunderforest Transport Dark">Transport Dark</ComboBoxItem>
<ComboBoxItem Tag="MapQuest OpenStreetMap">MapQuest Open</ComboBoxItem>
<!--<ComboBoxItem Tag="Bing Maps Road">Bing Maps Road</ComboBoxItem>
<ComboBoxItem Tag="Bing Maps Aerial">Bing Maps Aerial</ComboBoxItem>
<ComboBoxItem Tag="Bing Maps Hybrid">Bing Maps Hybrid</ComboBoxItem>-->
<ComboBox ToolTip="Tile Layer" Margin="5" VerticalAlignment="Bottom"
SelectedValuePath="Tag" SelectedValue="{Binding TileLayer, ElementName=map, Mode=TwoWay}">
<ComboBoxItem Tag="{StaticResource OpenStreetMap}">OpenStreetMap</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource OpenCycleMap}">OpenCycleMap</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource Landscape}">Landscape</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource Outdoors}">Outdoors</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource Transport}">Transport</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource TransportDark}">Transport Dark</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource MapQuest}">MapQuest Open</ComboBoxItem>
<!--<ComboBoxItem Tag="{StaticResource BingRoad}">Bing Maps Road</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource BingAerial}">Bing Maps Aerial</ComboBoxItem>
<ComboBoxItem Tag="{StaticResource BingHybrid}">Bing Maps Hybrid</ComboBoxItem>-->
</ComboBox>
</StackPanel>
</Grid>

View file

@ -1,28 +1,21 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using MapControl;
using MapControl.Caching;
namespace WpfApplication
{
public partial class MainWindow : Window
{
private TileLayerCollection tileLayers;
public MainWindow()
{
//TileImageLoader.Cache = new ImageFileCache(TileImageLoader.DefaultCacheName, TileImageLoader.DefaultCacheFolder);
//TileImageLoader.Cache = new FileDbCache(TileImageLoader.DefaultCacheName, TileImageLoader.DefaultCacheFolder);
//TileImageLoader.Cache = new MapControl.Caching.ImageFileCache(TileImageLoader.DefaultCacheName, TileImageLoader.DefaultCacheFolder);
//TileImageLoader.Cache = new MapControl.Caching.FileDbCache(TileImageLoader.DefaultCacheName, TileImageLoader.DefaultCacheFolder);
//TileImageLoader.HttpUserAgent = "...";
//BingMapsTileLayer.ApiKey = "...";
InitializeComponent();
tileLayers = (TileLayerCollection)Resources["TileLayers"];
tileLayerComboBox.SelectedIndex = 0;
}
private void MapMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
@ -85,24 +78,14 @@ namespace WpfApplication
e.Handled = true;
}
private void TileLayerSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedItem = (ComboBoxItem)tileLayerComboBox.SelectedItem;
map.TileLayer = tileLayers[(string)selectedItem.Tag];
mapLegend.Inlines.Clear();
mapLegend.Inlines.AddRange(map.TileLayer.DescriptionInlines);
}
private void SeamarksChecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Add(tileLayers["Seamarks"]);
map.TileLayers.Add((TileLayer)Resources["Seamarks"]);
}
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
{
map.TileLayers.Remove(tileLayers["Seamarks"]);
map.TileLayers.Remove((TileLayer)Resources["Seamarks"]);
}
}
}

View file

@ -0,0 +1,145 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfApplication
{
public class OutlinedText : FrameworkElement
{
private GlyphRun glyphRun;
private Geometry outline;
public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty FontSizeProperty = TextBlock.FontSizeProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty FontFamilyProperty = TextBlock.FontFamilyProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty FontStyleProperty = TextBlock.FontStyleProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty FontWeightProperty = TextBlock.FontWeightProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty FontStretchProperty = TextBlock.FontStretchProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty ForegroundProperty = TextBlock.ForegroundProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty BackgroundProperty = TextBlock.BackgroundProperty.AddOwner(
typeof(OutlinedText), new FrameworkPropertyMetadata(Brushes.White, (o, e) => ((OutlinedText)o).glyphRun = null));
public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register(
"OutlineThickness", typeof(double), typeof(OutlinedText),
new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsMeasure, (o, e) => ((OutlinedText)o).glyphRun = null));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public double FontSize
{
get { return (double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
public FontFamily FontFamily
{
get { return (FontFamily)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
public FontStyle FontStyle
{
get { return (FontStyle)GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
public FontWeight FontWeight
{
get { return (FontWeight)GetValue(FontWeightProperty); }
set { SetValue(FontWeightProperty, value); }
}
public FontStretch FontStretch
{
get { return (FontStretch)GetValue(FontStretchProperty); }
set { SetValue(FontStretchProperty, value); }
}
public Brush Foreground
{
get { return (Brush)GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); }
}
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
public double OutlineThickness
{
get { return (double)GetValue(OutlineThicknessProperty); }
set { SetValue(OutlineThicknessProperty, value); }
}
protected override Size MeasureOverride(Size availableSize)
{
return CheckGlyphRun() ? outline.Bounds.Size : new Size();
}
protected override void OnRender(DrawingContext drawingContext)
{
if (CheckGlyphRun())
{
var location = outline.Bounds.Location;
drawingContext.PushTransform(new TranslateTransform(-location.X, -location.Y));
drawingContext.DrawGeometry(Background, null, outline);
drawingContext.DrawGlyphRun(Foreground, glyphRun);
}
}
private bool CheckGlyphRun()
{
if (glyphRun == null)
{
if (string.IsNullOrWhiteSpace(Text))
{
return false;
}
var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
GlyphTypeface glyphTypeface;
if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
{
return false;
}
var glyphIndices = new ushort[Text.Length];
var advanceWidths = new double[Text.Length];
for (int i = 0; i < Text.Length; i++)
{
var glyphIndex = glyphTypeface.CharacterToGlyphMap[Text[i]];
glyphIndices[i] = glyphIndex;
advanceWidths[i] = glyphTypeface.AdvanceWidths[glyphIndex] * FontSize;
}
glyphRun = new GlyphRun(glyphTypeface, 0, false, FontSize, glyphIndices, new Point(), advanceWidths, null, null, null, null, null, null);
outline = glyphRun.BuildGeometry().GetWidenedPathGeometry(new Pen(null, OutlineThickness * 2d));
}
return true;
}
}
}

View file

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

View file

@ -69,6 +69,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="OutlinedText.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>