using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Controls; using System.Windows.Media.Imaging; using Comal.Classes; using Google.Maps; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; using Microsoft.Win32; using PRSDesktop.Forms; using Path = System.IO.Path; namespace PRSDesktop; public class GeoFenceGrid : DynamicDataGrid { private static BitmapImage MAP = PRSDesktop.Resources.map.AsBitmapImage(); protected override void Init() { base.Init(); HiddenColumns.Add(x=>x.LastUpdate); HiddenColumns.Add(x=>x.MinX); HiddenColumns.Add(x=>x.MaxX); HiddenColumns.Add(x=>x.MinY); HiddenColumns.Add(x=>x.MaxY); HiddenColumns.Add(x=>x.Geometry); AddButton("Import", PRSDesktop.Resources.mapmarker.AsBitmapImage(), ImportGeoJSON); ActionColumns.Add(new DynamicImageColumn((r) => MAP, MapClick)); } protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.PageSize = 1000; options.RecordCount = true; } private bool MapClick(CoreRow? row) { if (row == null) return false; var longitude = (row.Get(x=>x.MinX) + row.Get(x=>x.MaxX)) / 2.0; var latitude = (row.Get(x=>x.MinY) + row.Get(x=>x.MaxY)) / 2.0; var timestamp = row.Get(x=>x.LastUpdate); var geometry = row.Get(x=>x.Geometry); var form = new MapForm(latitude, longitude, timestamp, geometry); form.ShowDialog(); return false; } private bool ImportGeoJSON(Button button, CoreRow[] rows) { OpenFileDialog ofd = new(); ofd.Filter = "GeoJSON Files (*.geojson)|*.geojson"; if (ofd.ShowDialog() == true) { Progress.ShowModal("Loading File", progress => { var geojson = GeoJSONFile.Load(ofd.FileName); if (geojson != null) { var queue = geojson.Features?.ToQueue() ?? new Queue(); int fTotal = queue.Count; while (queue.Count > 0) { List updates = new(); var chunk = queue.Dequeue(1000).ToArray(); progress.Report($"Processing {((fTotal - queue.Count)*100.0F/fTotal):F2}% complete)"); var fulladdresses = chunk.Select(x=>x.Properties?.FullAddress() ?? string.Empty).Distinct().ToArray(); var existing = Client.Query(new Filter(x => x.FullAddress).InList(fulladdresses)) .ToObjects().ToList(); foreach (var record in chunk) { if (record.Properties == null || record.Geometry == null) continue; string id = record.Properties.ID(); string fulladdress = record.Properties.FullAddress(); if (string.IsNullOrWhiteSpace(id) || string.IsNullOrWhiteSpace(fulladdress)) continue; var update = existing.FirstOrDefault(x => string.Equals(x.FullAddress, fulladdress)); if (update == null) { update = new GeoFence(); update.FullAddress = fulladdress; existing.Add(update); } update.Street = record.Properties.Street(); update.City = record.Properties.Suburb(); update.State = record.Properties.State(); update.Country = record.Properties.Country(); update.PostCode = record.Properties.Postcode(); var bounds = record.Geometry.Bounds(); update.MinX = bounds.Item1.X; update.MinY = bounds.Item1.Y; update.MaxX = bounds.Item2.X; update.MaxY = bounds.Item2.Y; var geometry = Serialization.Deserialize>>(update.Geometry) ?? new Dictionary>(); geometry[id] = record.Geometry.Points(); update.Geometry = Serialization.Serialize(geometry); if (!updates.Contains(update) && (update.ID == Guid.Empty || update.IsChanged())) updates.Add(update); } if (updates.Any()) Client.Save(updates, $"Loaded from {Path.GetFileName(ofd.FileName)}"); } } }); } return true; } }