mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2025-12-06 07:12:04 +01:00
Simplified caching in TileImageLoader, FileDbCache deletes expired items on creation, TileLayers collection moved to Window resources in SampleApplication.
This commit is contained in:
parent
fbeb01fca3
commit
ae4fb7881a
|
|
@ -56,14 +56,14 @@ namespace Caching
|
|||
|
||||
public FileDbCache(string name, string directory)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentException("The parameter name must not be null or empty.");
|
||||
throw new ArgumentException("The parameter name must not be null or empty or only white-space.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
if (string.IsNullOrWhiteSpace(directory))
|
||||
{
|
||||
throw new ArgumentException("The parameter directory must not be null or empty.");
|
||||
throw new ArgumentException("The parameter directory must not be null or empty or only white-space.");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
|
|
@ -78,6 +78,14 @@ namespace Caching
|
|||
{
|
||||
fileDb.Open(path, false);
|
||||
Trace.TraceInformation("FileDbCache: Opened database with {0} cached items in {1}", fileDb.NumRecords, path);
|
||||
|
||||
fileDb.DeleteRecords(new FilterExpression(expiresField, DateTime.UtcNow, EqualityEnum.LessThan));
|
||||
|
||||
if (fileDb.NumDeleted > 0)
|
||||
{
|
||||
Trace.TraceInformation("FileDbCache: Deleted {0} expired items", fileDb.NumDeleted);
|
||||
fileDb.Clean();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -372,7 +380,10 @@ namespace Caching
|
|||
{
|
||||
try
|
||||
{
|
||||
fileDb.Flush();
|
||||
if (fileDb.IsOpen)
|
||||
{
|
||||
fileDb.Flush();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -384,7 +395,10 @@ namespace Caching
|
|||
{
|
||||
try
|
||||
{
|
||||
fileDb.Clean();
|
||||
if (fileDb.IsOpen)
|
||||
{
|
||||
fileDb.Clean();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -396,16 +410,6 @@ namespace Caching
|
|||
{
|
||||
if (fileDb.IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
fileDb.DeleteRecords(new FilterExpression(expiresField, DateTime.UtcNow, EqualityEnum.LessThanOrEqual));
|
||||
Trace.TraceInformation("FileDbCache: Deleted {0} expired items", fileDb.NumDeleted);
|
||||
fileDb.Clean();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
fileDb.Close();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using System.Windows.Media.Animation;
|
|||
namespace MapControl
|
||||
{
|
||||
/// <summary>
|
||||
/// The main map control. Draws map content provided by the TileLayers or the MainTileLayer property.
|
||||
/// The main map control. Draws map content provided by the TileLayers or the BaseTileLayer property.
|
||||
/// The visible map area is defined by the Center and ZoomLevel properties. The map can be rotated
|
||||
/// by an angle that is given by the Heading property.
|
||||
/// Map is a MapPanel and hence can contain map overlays like other MapPanels or MapItemsControls.
|
||||
|
|
@ -46,10 +46,10 @@ namespace MapControl
|
|||
(o, e) => ((Map)o).TileLayersPropertyChanged((TileLayerCollection)e.OldValue, (TileLayerCollection)e.NewValue),
|
||||
(o, v) => ((Map)o).CoerceTileLayersProperty((TileLayerCollection)v)));
|
||||
|
||||
public static readonly DependencyProperty MainTileLayerProperty = DependencyProperty.Register(
|
||||
"MainTileLayer", typeof(TileLayer), typeof(Map), new FrameworkPropertyMetadata(
|
||||
(o, e) => ((Map)o).MainTileLayerPropertyChanged((TileLayer)e.NewValue),
|
||||
(o, v) => ((Map)o).CoerceMainTileLayerProperty((TileLayer)v)));
|
||||
public static readonly DependencyProperty BaseTileLayerProperty = DependencyProperty.Register(
|
||||
"BaseTileLayer", typeof(TileLayer), typeof(Map), new FrameworkPropertyMetadata(
|
||||
(o, e) => ((Map)o).BaseTileLayerPropertyChanged((TileLayer)e.NewValue),
|
||||
(o, v) => ((Map)o).CoerceBaseTileLayerProperty((TileLayer)v)));
|
||||
|
||||
public static readonly DependencyProperty TileOpacityProperty = DependencyProperty.Register(
|
||||
"TileOpacity", typeof(double), typeof(Map), new FrameworkPropertyMetadata(1d,
|
||||
|
|
@ -112,9 +112,9 @@ namespace MapControl
|
|||
|
||||
Loaded += (o, e) =>
|
||||
{
|
||||
if (MainTileLayer == null)
|
||||
if (BaseTileLayer == null)
|
||||
{
|
||||
MainTileLayer = new TileLayer
|
||||
BaseTileLayer = new TileLayer
|
||||
{
|
||||
Name = "OpenStreetMap",
|
||||
Description = "© {y} OpenStreetMap Contributors, CC-BY-SA",
|
||||
|
|
@ -202,12 +202,12 @@ namespace MapControl
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the main TileLayer used by this Map, i.e. TileLayers[0].
|
||||
/// Gets or sets the base TileLayer used by this Map, i.e. TileLayers[0].
|
||||
/// </summary>
|
||||
public TileLayer MainTileLayer
|
||||
public TileLayer BaseTileLayer
|
||||
{
|
||||
get { return (TileLayer)GetValue(MainTileLayerProperty); }
|
||||
set { SetValue(MainTileLayerProperty, value); }
|
||||
get { return (TileLayer)GetValue(BaseTileLayerProperty); }
|
||||
set { SetValue(BaseTileLayerProperty, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -491,7 +491,7 @@ namespace MapControl
|
|||
break;
|
||||
}
|
||||
|
||||
UpdateMainTileLayer();
|
||||
UpdateBaseTileLayer();
|
||||
}
|
||||
|
||||
private void TileLayersPropertyChanged(TileLayerCollection oldTileLayers, TileLayerCollection newTileLayers)
|
||||
|
|
@ -509,7 +509,7 @@ namespace MapControl
|
|||
tileContainer.AddTileLayers(0, newTileLayers);
|
||||
}
|
||||
|
||||
UpdateMainTileLayer();
|
||||
UpdateBaseTileLayer();
|
||||
}
|
||||
|
||||
private TileLayerCollection CoerceTileLayersProperty(TileLayerCollection tileLayers)
|
||||
|
|
@ -522,21 +522,21 @@ namespace MapControl
|
|||
return tileLayers;
|
||||
}
|
||||
|
||||
private void MainTileLayerPropertyChanged(TileLayer mainTileLayer)
|
||||
private void BaseTileLayerPropertyChanged(TileLayer baseTileLayer)
|
||||
{
|
||||
if (mainTileLayer != null)
|
||||
if (baseTileLayer != null)
|
||||
{
|
||||
if (TileLayers.Count == 0)
|
||||
{
|
||||
TileLayers.Add(mainTileLayer);
|
||||
TileLayers.Add(baseTileLayer);
|
||||
}
|
||||
else if (TileLayers[0] != mainTileLayer)
|
||||
else if (TileLayers[0] != baseTileLayer)
|
||||
{
|
||||
TileLayers[0] = mainTileLayer;
|
||||
TileLayers[0] = baseTileLayer;
|
||||
}
|
||||
}
|
||||
|
||||
if (mainTileLayer != null && mainTileLayer.HasDarkBackground)
|
||||
if (baseTileLayer != null && baseTileLayer.HasDarkBackground)
|
||||
{
|
||||
if (DarkForeground != null)
|
||||
{
|
||||
|
|
@ -562,23 +562,23 @@ namespace MapControl
|
|||
}
|
||||
}
|
||||
|
||||
private TileLayer CoerceMainTileLayerProperty(TileLayer mainTileLayer)
|
||||
private TileLayer CoerceBaseTileLayerProperty(TileLayer baseTileLayer)
|
||||
{
|
||||
if (mainTileLayer == null && TileLayers.Count > 0)
|
||||
if (baseTileLayer == null && TileLayers.Count > 0)
|
||||
{
|
||||
mainTileLayer = TileLayers[0];
|
||||
baseTileLayer = TileLayers[0];
|
||||
}
|
||||
|
||||
return mainTileLayer;
|
||||
return baseTileLayer;
|
||||
}
|
||||
|
||||
private void UpdateMainTileLayer()
|
||||
private void UpdateBaseTileLayer()
|
||||
{
|
||||
TileLayer mainTileLayer = TileLayers.FirstOrDefault();
|
||||
TileLayer baseTileLayer = TileLayers.FirstOrDefault();
|
||||
|
||||
if (MainTileLayer != mainTileLayer)
|
||||
if (BaseTileLayer != baseTileLayer)
|
||||
{
|
||||
MainTileLayer = mainTileLayer;
|
||||
BaseTileLayer = baseTileLayer;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,20 @@ namespace MapControl
|
|||
IsSelected = !IsSelected;
|
||||
}
|
||||
|
||||
private void IsSelectedChanged(bool isSelected)
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
VisualStateManager.GoToState(this, "Selected", true);
|
||||
RaiseEvent(new RoutedEventArgs(SelectedEvent));
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager.GoToState(this, "Unselected", true);
|
||||
RaiseEvent(new RoutedEventArgs(UnselectedEvent));
|
||||
}
|
||||
}
|
||||
|
||||
private void CommonStateChanged()
|
||||
{
|
||||
if (!IsEnabled)
|
||||
|
|
@ -128,19 +142,5 @@ namespace MapControl
|
|||
VisualStateManager.GoToState(this, "Normal", true);
|
||||
}
|
||||
}
|
||||
|
||||
private void IsSelectedChanged(bool isSelected)
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
VisualStateManager.GoToState(this, "Selected", true);
|
||||
RaiseEvent(new RoutedEventArgs(SelectedEvent));
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager.GoToState(this, "Unselected", true);
|
||||
RaiseEvent(new RoutedEventArgs(UnselectedEvent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,18 +23,6 @@ namespace MapControl
|
|||
/// </summary>
|
||||
public class TileImageLoader : DispatcherObject
|
||||
{
|
||||
[Serializable]
|
||||
private class CachedImage
|
||||
{
|
||||
public readonly DateTime CreationTime = DateTime.UtcNow;
|
||||
public readonly byte[] ImageBuffer;
|
||||
|
||||
public CachedImage(byte[] imageBuffer)
|
||||
{
|
||||
ImageBuffer = imageBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly TileLayer tileLayer;
|
||||
private readonly ConcurrentQueue<Tile> pendingTiles = new ConcurrentQueue<Tile>();
|
||||
|
||||
|
|
@ -151,19 +139,19 @@ namespace MapControl
|
|||
newTiles.ForEach(tile =>
|
||||
{
|
||||
string key = CacheKey(tile);
|
||||
CachedImage cachedImage = Cache.Get(key) as CachedImage;
|
||||
byte[] imageBuffer = Cache.Get(key) as byte[];
|
||||
|
||||
if (cachedImage == null)
|
||||
if (imageBuffer == null)
|
||||
{
|
||||
pendingTiles.Enqueue(tile);
|
||||
}
|
||||
else if (!CreateTileImage(tile, cachedImage.ImageBuffer))
|
||||
else if (!CreateTileImage(tile, imageBuffer))
|
||||
{
|
||||
// got corrupted buffer from cache
|
||||
Cache.Remove(key);
|
||||
pendingTiles.Enqueue(tile);
|
||||
}
|
||||
else if (cachedImage.CreationTime + CacheUpdateAge < DateTime.UtcNow)
|
||||
else if (GetCreationTime(imageBuffer) + CacheUpdateAge < DateTime.UtcNow)
|
||||
{
|
||||
// update cached image
|
||||
outdatedTiles.Add(tile);
|
||||
|
|
@ -190,18 +178,16 @@ namespace MapControl
|
|||
tile.Uri = tileLayer.TileSource.GetUri(tile.XIndex, tile.Y, tile.ZoomLevel);
|
||||
byte[] imageBuffer = DownloadImage(tile);
|
||||
|
||||
if (imageBuffer != null &&
|
||||
CreateTileImage(tile, imageBuffer) &&
|
||||
Cache != null)
|
||||
if (imageBuffer != null && CreateTileImage(tile, imageBuffer) && Cache != null)
|
||||
{
|
||||
Cache.Set(CacheKey(tile), new CachedImage(imageBuffer), new CacheItemPolicy { SlidingExpiration = CacheExpiration });
|
||||
Cache.Set(CacheKey(tile), imageBuffer, new CacheItemPolicy { SlidingExpiration = CacheExpiration });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string CacheKey(Tile tile)
|
||||
{
|
||||
return string.Format("{0}-{1}-{2}-{3}", tileLayer.Name, tile.ZoomLevel, tile.XIndex, tile.Y);
|
||||
return string.Format("{0}/{1}/{2}/{3}", tileLayer.Name, tile.ZoomLevel, tile.XIndex, tile.Y);
|
||||
}
|
||||
|
||||
private byte[] DownloadImage(Tile tile)
|
||||
|
|
@ -222,9 +208,9 @@ namespace MapControl
|
|||
{
|
||||
if (response.ContentLength > 0)
|
||||
{
|
||||
using (MemoryStream memoryStream = new MemoryStream((int)response.ContentLength))
|
||||
using (MemoryStream memoryStream = new MemoryStream((int)response.ContentLength + 8))
|
||||
{
|
||||
responseStream.CopyTo(memoryStream);
|
||||
CopyWithCreationTime(responseStream, memoryStream);
|
||||
buffer = memoryStream.GetBuffer();
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +218,7 @@ namespace MapControl
|
|||
{
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
responseStream.CopyTo(memoryStream);
|
||||
CopyWithCreationTime(responseStream, memoryStream);
|
||||
buffer = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +251,7 @@ namespace MapControl
|
|||
|
||||
try
|
||||
{
|
||||
using (Stream stream = new MemoryStream(buffer))
|
||||
using (Stream stream = new MemoryStream(buffer, 0, buffer.Length - 8, false))
|
||||
{
|
||||
bitmap.BeginInit();
|
||||
bitmap.CacheOption = BitmapCacheOption.OnLoad;
|
||||
|
|
@ -284,6 +270,17 @@ namespace MapControl
|
|||
return true;
|
||||
}
|
||||
|
||||
private static DateTime GetCreationTime(byte[] imageBuffer)
|
||||
{
|
||||
return new DateTime(BitConverter.ToInt64(imageBuffer, imageBuffer.Length - 8));
|
||||
}
|
||||
|
||||
private static void CopyWithCreationTime(Stream source, Stream target)
|
||||
{
|
||||
source.CopyTo(target);
|
||||
target.Write(BitConverter.GetBytes(DateTime.UtcNow.Ticks), 0, 8);
|
||||
}
|
||||
|
||||
private static void TraceWarning(string format, params object[] args)
|
||||
{
|
||||
Trace.TraceWarning("[{0:00}] {1}", Thread.CurrentThread.ManagedThreadId, string.Format(format, args));
|
||||
|
|
|
|||
|
|
@ -5,8 +5,43 @@
|
|||
xmlns:local="clr-namespace:SampleApplication"
|
||||
Title="MainWindow" Height="600" Width="800">
|
||||
<Window.Resources>
|
||||
<map:TileLayer x:Key="SeamarksTileLayer"
|
||||
Name="Seamarks" Description="© {y} OpenSeaMap Contributors, CC-BY-SA"
|
||||
<map:TileLayerCollection x:Key="TileLayers">
|
||||
<map:TileLayer Name="OpenStreetMap" Description="© {y} OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
|
||||
<map:TileLayer Name="OpenCycleMap" Description="OpenCycleMap - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png"/>
|
||||
<map:TileLayer Name="OCM Transport" Description="OpenCycleMap Transport - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png"/>
|
||||
<map:TileLayer Name="OCM Landscape" Description="OpenCycleMap Landscape - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png"/>
|
||||
<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"/>
|
||||
|
||||
<!-- 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"/>
|
||||
<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"/>
|
||||
<map:TileLayer Name="Bing Maps" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/r{q}.png?g=0&stl=h" MaxZoomLevel="20"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
|
||||
<!-- 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.TileSource>
|
||||
<map:ImageTileSource UriFormat="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
|
||||
</map:TileLayer.TileSource>
|
||||
</map:TileLayer>
|
||||
</map:TileLayerCollection>
|
||||
<CollectionViewSource x:Key="TileLayersView" Source="{StaticResource TileLayers}"/>
|
||||
<map:TileLayer x:Key="SeamarksTileLayer" Name="Seamarks" Description="© {y} OpenSeaMap Contributors, CC-BY-SA"
|
||||
TileSource="http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png" MinZoomLevel="10" MaxZoomLevel="18"/>
|
||||
<local:SampleItemCollection x:Key="Polylines"/>
|
||||
<local:SampleItemCollection x:Key="Points"/>
|
||||
|
|
@ -90,7 +125,7 @@
|
|||
<map:Map Name="map" IsManipulationEnabled="True" Margin="2" FontSize="10"
|
||||
LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
|
||||
Center="53.5,8.2" ZoomLevel="11"
|
||||
MainTileLayer="{Binding SelectedItem, ElementName=tileLayerComboBox}"
|
||||
BaseTileLayer="{Binding Source={StaticResource TileLayersView}, Path=CurrentItem}"
|
||||
ManipulationInertiaStarting="MapManipulationInertiaStarting"
|
||||
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave">
|
||||
<map:MapGraticule Opacity="0.6"/>
|
||||
|
|
@ -105,7 +140,7 @@
|
|||
<map:Pushpin Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"
|
||||
Visibility="{Binding (map:MapPanel.ViewportPosition).IsInside, Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
|
||||
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="2,0,0,0" FontSize="10"
|
||||
Text="{Binding MainTileLayer.Description, ElementName=map}"/>
|
||||
Text="{Binding BaseTileLayer.Description, ElementName=map}"/>
|
||||
</map:Map>
|
||||
<Grid Grid.Row="1" Margin="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
|
|
@ -119,43 +154,8 @@
|
|||
<Slider Name="headingSlider" ToolTip="Heading" Margin="4,0,4,0" Width="100" Minimum="0" Maximum="360" SmallChange="10" LargeChange="45"
|
||||
Value="{Binding TargetHeading, ElementName=map}"/>
|
||||
<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,0,0" DisplayMemberPath="Name" SelectedIndex="0">
|
||||
<ComboBox.Items>
|
||||
<map:TileLayer Name="OpenStreetMap" Description="© {y} OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
|
||||
<map:TileLayer Name="OpenCycleMap" Description="OpenCycleMap - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png"/>
|
||||
<map:TileLayer Name="OCM Transport" Description="OpenCycleMap Transport - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png"/>
|
||||
<map:TileLayer Name="OCM Landscape" Description="OpenCycleMap Landscape - © {y} Andy Allen & OpenStreetMap Contributors, CC-BY-SA"
|
||||
TileSource="http://{c}.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png"/>
|
||||
<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"/>
|
||||
|
||||
<!-- 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"/>
|
||||
<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"/>
|
||||
<map:TileLayer Name="Bing Maps" Description="Bing Maps - © {y} Microsoft Corporation"
|
||||
TileSource="http://ecn.t{i}.tiles.virtualearth.net/tiles/r{q}.png?g=0&stl=h" MaxZoomLevel="20"/>
|
||||
<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"/>
|
||||
<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"/>-->
|
||||
|
||||
<!-- 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.TileSource>
|
||||
<map:ImageTileSource UriFormat="http://{c}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
|
||||
</map:TileLayer.TileSource>
|
||||
</map:TileLayer>
|
||||
</ComboBox.Items>
|
||||
</ComboBox>
|
||||
<ComboBox ToolTip="Main Tile Layer" Margin="4,0,0,0" DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Source={StaticResource TileLayersView}}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -104,14 +104,14 @@ namespace SampleApplication
|
|||
});
|
||||
|
||||
DispatcherTimer timer = new DispatcherTimer();
|
||||
timer.Interval = TimeSpan.FromSeconds(0.05);
|
||||
timer.Interval = TimeSpan.FromSeconds(0.1);
|
||||
timer.Tick += MovePoint;
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private void MovePoint(object sender, EventArgs e)
|
||||
{
|
||||
movingPoint.Location = new Location(movingPoint.Location.Latitude + 0.0005, movingPoint.Location.Longitude + 0.001);
|
||||
movingPoint.Location = new Location(movingPoint.Location.Latitude + 0.001, movingPoint.Location.Longitude + 0.002);
|
||||
|
||||
if (movingPoint.Location.Latitude > 54d)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using MapControl;
|
||||
|
||||
namespace MapControlTestApp
|
||||
{
|
||||
class MapBackgroundConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
MapBackground mapBackground = (MapBackground)value;
|
||||
|
||||
if (parameter as string == "Foreground")
|
||||
{
|
||||
return mapBackground == MapBackground.Light ? Brushes.Black : Brushes.White;
|
||||
}
|
||||
|
||||
return mapBackground == MapBackground.Light ? Brushes.White : Brushes.Black;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue