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