XAML-Map-Control/MapControl/Shared/MapOverlaysPanel.cs

98 lines
2.8 KiB
C#
Raw Normal View History

2026-04-24 12:19:39 +02:00
using System;
using System.Collections.Generic;
2024-07-22 18:06:41 +02:00
using System.Collections.Specialized;
2024-08-30 16:37:40 +02:00
using System.IO;
2024-07-22 18:06:41 +02:00
using System.Linq;
using System.Threading.Tasks;
2024-07-22 18:06:41 +02:00
#if WPF
using System.Windows;
#elif UWP
using Windows.UI.Xaml;
#elif WINUI
using Microsoft.UI.Xaml;
#endif
2026-04-13 17:14:49 +02:00
namespace MapControl;
/// <summary>
/// A MapPanel with a collection of GroundOverlay or GeoImage children.
/// </summary>
public partial class MapOverlaysPanel : MapPanel
2024-07-22 18:06:41 +02:00
{
2026-04-13 17:14:49 +02:00
public static readonly DependencyProperty SourcePathsProperty =
DependencyPropertyHelper.Register<MapOverlaysPanel, IEnumerable<string>>(nameof(SourcePaths), null,
async (control, oldValue, newValue) => await control.SourcePathsPropertyChanged(oldValue, newValue));
2026-04-24 12:19:39 +02:00
private readonly UpdateTimer updateTimer;
public MapOverlaysPanel()
{
updateTimer = new UpdateTimer { Interval = TimeSpan.FromMilliseconds(100) };
updateTimer.Tick += async (_, _) => await UpdateChildren();
}
2026-04-13 17:14:49 +02:00
public IEnumerable<string> SourcePaths
{
get => (IEnumerable<string>)GetValue(SourcePathsProperty);
set => SetValue(SourcePathsProperty, value);
}
2026-04-24 12:19:39 +02:00
protected virtual async Task<FrameworkElement> CreateOverlayAsync(string sourcePath)
2024-07-22 18:06:41 +02:00
{
2026-04-24 12:19:39 +02:00
var ext = Path.GetExtension(sourcePath).ToLower();
2024-07-22 18:06:41 +02:00
2026-04-24 12:19:39 +02:00
return ext == ".kmz" || ext == ".kml"
? await GroundOverlay.CreateAsync(sourcePath)
: await GeoImage.CreateAsync(sourcePath);
2026-04-13 17:14:49 +02:00
}
2024-07-22 18:06:41 +02:00
2026-04-24 12:19:39 +02:00
private async Task<FrameworkElement> GetOverlay(string sourcePath)
2026-04-13 17:14:49 +02:00
{
2026-04-24 12:19:39 +02:00
var overlay = Children.Cast<FrameworkElement>().FirstOrDefault(child => (string)child.Tag == sourcePath);
2024-07-22 18:06:41 +02:00
2026-04-24 12:19:39 +02:00
if (overlay == null)
2024-07-22 18:06:41 +02:00
{
2026-04-24 12:19:39 +02:00
overlay = await CreateOverlayAsync(sourcePath);
overlay?.Tag = sourcePath;
2024-07-22 18:06:41 +02:00
}
2026-04-24 12:19:39 +02:00
return overlay;
2026-04-13 17:14:49 +02:00
}
2024-07-22 18:06:41 +02:00
2026-04-24 12:19:39 +02:00
private async Task UpdateChildren()
2026-04-13 17:14:49 +02:00
{
2026-04-24 12:19:39 +02:00
updateTimer.Stop();
var overlays = SourcePaths != null
? await Task.WhenAll(SourcePaths.ToList().Select(GetOverlay))
: [];
Children.Clear();
foreach (var overlay in overlays.Where(overlay => overlay != null))
2024-07-22 18:06:41 +02:00
{
2026-04-24 12:19:39 +02:00
Children.Add(overlay);
2024-07-22 18:06:41 +02:00
}
2026-04-13 17:14:49 +02:00
}
2024-07-22 18:06:41 +02:00
2026-04-24 12:19:39 +02:00
private void SourcePathsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
2026-04-13 17:14:49 +02:00
{
2026-04-24 12:19:39 +02:00
updateTimer.Run(true);
2026-04-13 17:14:49 +02:00
}
2024-07-22 18:06:41 +02:00
2026-04-24 12:19:39 +02:00
private async Task SourcePathsPropertyChanged(IEnumerable<string> oldSourcePaths, IEnumerable<string> newSourcePaths)
2026-04-13 17:14:49 +02:00
{
2026-04-24 12:19:39 +02:00
if (oldSourcePaths is INotifyCollectionChanged oldCollection)
2026-04-13 17:14:49 +02:00
{
2026-04-24 12:19:39 +02:00
oldCollection.CollectionChanged -= SourcePathsCollectionChanged;
2026-04-13 17:14:49 +02:00
}
2026-04-24 12:19:39 +02:00
if (newSourcePaths is INotifyCollectionChanged newCollection)
2026-04-13 17:14:49 +02:00
{
2026-04-24 12:19:39 +02:00
newCollection.CollectionChanged += SourcePathsCollectionChanged;
2024-07-22 18:06:41 +02:00
}
2026-04-13 17:14:49 +02:00
2026-04-24 12:19:39 +02:00
await UpdateChildren();
2024-07-22 18:06:41 +02:00
}
}