| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- using System;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Net.Http;
- using System.Runtime.InteropServices;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Input;
- using System.Windows.Media;
- using Geocoding;
- using Geocoding.Google;
- using InABox.Clients;
- using InABox.Core;
- using InABox.WPF;
- using Nominatim.API.Geocoders;
- using Nominatim.API.Models;
- using Nominatim.API.Web;
- using Syncfusion.UI.Xaml.Maps;
- using Address = InABox.Core.Address;
- using OnAfterLoad = InABox.DynamicGrid.OnAfterLoad;
- using Point = System.Windows.Point;
- namespace InABox.Wpf.DynamicGrid;
- public partial class GeofenceEditor : Window
- {
- public Address Address { get; private set; }
-
- GeoFenceDefinition _definition = null;
- //private ImageryLayer ImageryLayer;
- //private MapPolygon Polygon;
- //private SubShapeFileLayer ShapeLayer;
- private bool _canEdit = false;
-
- public GeofenceEditor(Address address, bool canEdit)
- {
- _canEdit = canEdit;
- Address = address;
- _definition = Serialization.Deserialize<GeoFenceDefinition>(address.Geofence) ?? new GeoFenceDefinition();
-
- InitializeComponent();
-
- // ImageryLayer = string.IsNullOrWhiteSpace(CoreUtils.GoogleAPIKey)
- // ? new ImageryLayer()
- // : new GoogleImageryLayer() { Type = GoogleImageryLayerType.Satellite };
- // ImageryLayer.Radius = 10;
- //
- // Map.Layers.Add(ImageryLayer);
- //
- // Polygon = new MapPolygon()
- // {
- // Fill = new SolidColorBrush(Colors.LightSalmon) { Opacity = 0.5 },
- // Stroke = new SolidColorBrush(Colors.Firebrick),
- // StrokeThickness = 0.75,
- // Points = new CoreObservableCollection<Point>()
- // };
- // ShapeLayer = new SubShapeFileLayer() { MapElements = new ObservableCollection<MapElement>([Polygon]) };
- //
- // ImageryLayer.SubShapeFileLayers = new ObservableCollection<SubShapeFileLayer>([ShapeLayer]);
-
- SetGeometry.Visibility = canEdit ? Visibility.Visible : Visibility.Collapsed;
- SetRadius.Visibility = canEdit ? Visibility.Visible : Visibility.Collapsed;
- SearchBar.Visibility = canEdit ? Visibility.Visible : Visibility.Collapsed;
-
- Street.Text = address.Street;
- City.Text = address.City;
- State.Text = address.State;
- PostCode.Text = Address.PostCode;
- Title = $"Geofence Editor ({(string.IsNullOrWhiteSpace(CoreUtils.GoogleAPIKey) ? "OSM" : "Google")})";
-
-
- }
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- if (_canEdit && string.IsNullOrWhiteSpace(Address.Geofence))
- Task.Run(CheckAddress);
- else
- SetupMap();
- }
- private class HttpClientFactory : IHttpClientFactory
- {
- private static HttpClient? _client;
- public HttpClient CreateClient(string name)
- {
-
- _client ??= new HttpClient();
- return _client;
- }
- }
-
- private static HttpClientFactory? _httpClientFactory = null;
- private async Task CheckAddress()
- {
- if (!string.IsNullOrWhiteSpace(CoreUtils.GoogleAPIKey))
- {
-
- IGeocoder geocoder = new GoogleGeocoder(CoreUtils.GoogleAPIKey);
- try
- {
- var matches =
- await geocoder.GeocodeAsync(
- $"{Address.Street}, {Address.City} {Address.State} {Address.PostCode} Australia");
- var match = matches.FirstOrDefault();
- if (match != null)
- {
- Address.Location.Longitude = match.Coordinates.Longitude;
- Address.Location.Latitude = match.Coordinates.Latitude;
-
- if (match is GoogleAddress gAdd)
- {
- _definition.Coordinates.Clear();
- _definition.Coordinates.Add(new GeoPoint(gAdd.Bounds.NorthEast.Latitude,
- gAdd.Bounds.NorthEast.Longitude));
- _definition.Coordinates.Add(new GeoPoint(gAdd.Bounds.NorthEast.Latitude,
- gAdd.Bounds.SouthWest.Longitude));
- _definition.Coordinates.Add(new GeoPoint(gAdd.Bounds.SouthWest.Latitude,
- gAdd.Bounds.SouthWest.Longitude));
- _definition.Coordinates.Add(new GeoPoint(gAdd.Bounds.SouthWest.Latitude,
- gAdd.Bounds.NorthEast.Longitude));
- _definition.Coordinates.Add(new GeoPoint(gAdd.Bounds.NorthEast.Latitude,
- gAdd.Bounds.NorthEast.Longitude));
- }
- else
- SquareFence(20.0);
-
- Address.Geofence = Serialization.Serialize(_definition);
- }
- else
- {
- Address.Location.Longitude = 0.0;
- Address.Location.Latitude = 0.0;
- Address.Geofence = string.Empty;
- }
- }
- catch (Exception e)
- {
- Logger.Send(LogType.Error, ClientFactory.UserID, $"{e.Message}\n{e.StackTrace}");
- }
- }
- else
- {
- _httpClientFactory ??= new HttpClientFactory();
- NominatimWebInterface intf = new NominatimWebInterface(_httpClientFactory);
-
- var searcher = new ForwardGeocoder(intf);
- var request = new ForwardGeocodeRequest()
- {
- StreetAddress = Address.Street,
- City = Address.City,
- // County="",
- State = Address.State,
- PostalCode = Address.PostCode,
- Country = "AU",
- //queryString = $"{Address.Street}, {Address.City}, {Address.State}, {Address.PostCode} Australia",
- //BreakdownAddressElements = true,
- ShowExtraTags = true,
- ShowAlternativeNames = true,
- ShowGeoJSON = true,
- };
- try
- {
- var matches = await searcher.Geocode(request);
- var match = matches.FirstOrDefault();
- if (match != null)
- {
- Address.Location.Longitude = match.Longitude;
- Address.Location.Latitude = match.Latitude;
- if (match.BoundingBox.HasValue)
- {
- var bbox = match.BoundingBox.Value;
- _definition.Coordinates.Clear();
- _definition.Coordinates.Add(new GeoPoint(bbox.minLatitude, bbox.minLongitude));
- _definition.Coordinates.Add(new GeoPoint(bbox.minLatitude, bbox.maxLongitude));
- _definition.Coordinates.Add(new GeoPoint(bbox.maxLatitude, bbox.maxLongitude));
- _definition.Coordinates.Add(new GeoPoint(bbox.maxLatitude, bbox.minLongitude));
- _definition.Coordinates.Add(new GeoPoint(bbox.minLatitude, bbox.minLongitude));
- }
- else
- SquareFence(20.0);
- Address.Geofence = Serialization.Serialize(_definition);
- }
- else
- {
- Address.Location.Longitude = 0.0;
- Address.Location.Latitude = 0.0;
- Address.Geofence = string.Empty;
- }
- }
-
- catch (Exception e)
- {
- Logger.Send(LogType.Error, ClientFactory.UserID, $"{e.Message}\n{e.StackTrace}");
- }
-
- }
- Dispatcher.BeginInvoke(SetupMap);
- }
- private void SquareFence(double side)
- {
-
- _definition.Coordinates.Clear();
- _definition.Coordinates.Add(new GeoPoint(Address.Location.Latitude, Address.Location.Longitude).Move(0-(side/2.0),0-(side/2.0)));
- _definition.Coordinates.Add(new GeoPoint(Address.Location.Latitude, Address.Location.Longitude).Move(0-(side/2.0),side/2.0));
- _definition.Coordinates.Add(new GeoPoint(Address.Location.Latitude, Address.Location.Longitude).Move(side/2.0,side/2.0));
- _definition.Coordinates.Add(new GeoPoint(Address.Location.Latitude, Address.Location.Longitude).Move(side/2.0,0-(side/2.0)));
- _definition.Coordinates.Add(new GeoPoint(Address.Location.Latitude, Address.Location.Longitude).Move(0-(side/2.0),0-(side/2.0)));
- }
- private void SetupMap()
- {
- CenterMap();
- RadiusSlider.ValueChanged -= RadiusSliderChanged;
- RadiusSlider.Value = 20.0;
- if (_definition.Coordinates.Count < 4)
- SquareFence(20.0);
- RadiusSlider.ValueChanged += RadiusSliderChanged;
- UpdateMap();
- }
- private void CenterMap()
- {
- ImageryLayer.Center = new Point(Address.Location.Latitude, Address.Location.Longitude);
- ImageryLayer.Markers = new CoreObservableCollection<MapMarker>([new MapMarker()
- {
- Latitude = $"{Address.Location.Latitude:F15}",
- Longitude = $"{Address.Location.Longitude:F15}"
- }]);
- }
- private void RadiusSliderChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
- {
- RecalculateSquareFence();
- UpdateMap();
- }
- private void RecalculateSquareFence()
- {
- SquareFence(RadiusSlider.Value);
- Address.Geofence = Serialization.Serialize(_definition);
- }
- private void UpdateMap()
- {
- // if (Polygon.Points is CoreObservableCollection<Point> _pts)
- // _pts.ReplaceRange(_definition.Coordinates.Select(p => new Point(p.Latitude, p.Longitude)));
- Polygon.Points.Clear();
- foreach (var p in _definition.Coordinates)
- Polygon.Points.Add(new Point(p.Latitude, p.Longitude));
- ShapeLayer.Refresh();
-
- }
-
- private void ZoomIn_OnClick(object sender, RoutedEventArgs e)
- {
- Map.MaxZoom = Math.Min(20, Map.ZoomLevel + 1);
- Map.ZoomLevel = Math.Min(20, Map.ZoomLevel + 1);
- UpdateMap();
- }
- private void ZoomOut_OnClick(object sender, RoutedEventArgs e)
- {
- Map.MinZoom= Math.Max(5, Map.ZoomLevel - 1);
- Map.ZoomLevel = Math.Max(5, Map.ZoomLevel - 1);
- UpdateMap();
- }
- private enum GeoFenceAction
- {
- None,
- Polygon,
- Square,
- Coordinates
- }
- private GeoFenceAction _action = GeoFenceAction.None;
- private void UpdateButtons(GeoFenceAction action)
- {
- _action = action;
-
- CloseEditor.Visibility = action == GeoFenceAction.None
- ? Visibility.Collapsed
- : Visibility.Visible;
-
- SetGeometry.Visibility = action == GeoFenceAction.None || action == GeoFenceAction.Polygon
- ? Visibility.Visible
- : Visibility.Collapsed;
- SetGeometry.IsEnabled = action == GeoFenceAction.None;
- SetGeometry.Background = action == GeoFenceAction.Polygon
- ? Brushes.Yellow
- : Brushes.Silver;
-
- SetRadius.Visibility = action == GeoFenceAction.None || action == GeoFenceAction.Square
- ? Visibility.Visible
- : Visibility.Collapsed;
- SetRadius.IsEnabled = action == GeoFenceAction.None;
- SetRadius.Background = action == GeoFenceAction.Square
- ? Brushes.Yellow
- : Brushes.Silver;
- RadiusSlider.Visibility = action == GeoFenceAction.Square
- ? Visibility.Visible
- : Visibility.Collapsed;
-
- SetCoordinates.Visibility = action == GeoFenceAction.None || action == GeoFenceAction.Coordinates
- ? Visibility.Visible
- : Visibility.Collapsed;
- SetCoordinates.IsEnabled = action == GeoFenceAction.None;
- SetCoordinates.Background = action == GeoFenceAction.Coordinates
- ? Brushes.Yellow
- : Brushes.Silver;
- }
-
- private void SetGeometry_OnClick(object sender, RoutedEventArgs e)
- {
- //if (_action == GeoFenceAction.Polygon)
- // UpdateButtons(GeoFenceAction.None);
- //else
- //{
- UpdateButtons(GeoFenceAction.Polygon);
- _definition.Coordinates.Clear();
- UpdateMap();
- //}
- }
-
- private void SetRadius_OnClick(object sender, RoutedEventArgs e)
- {
- //if (_action == GeoFenceAction.Square)
- // UpdateButtons(GeoFenceAction.None);
- //else
- //{
- UpdateButtons(GeoFenceAction.Square);
- RadiusSlider.ValueChanged -= RadiusSliderChanged;
- RadiusSlider.Value = 20.0;
- SquareFence(20.0);
- RadiusSlider.ValueChanged += RadiusSliderChanged;
- RecalculateSquareFence();
- UpdateMap();
- //}
- }
- private void SearchAddress_Click(object sender, RoutedEventArgs e)
- {
- Task.Run(CheckAddress);
- }
- private void SetCoordinates_OnClick(object sender, RoutedEventArgs e)
- {
- //if (_action == GeoFenceAction.Coordinates)
- // UpdateButtons(GeoFenceAction.None);
- //else
- {
- UpdateButtons(GeoFenceAction.Coordinates);
- _definition.Coordinates.Clear();
- UpdateMap();
- }
- }
- private void CloseEditor_OnClick(object sender, RoutedEventArgs e)
- {
- UpdateButtons(GeoFenceAction.None);
- }
- private void Map_OnPreviewMouseUp(object sender, MouseButtonEventArgs e)
- {
- var point = Mouse.GetPosition(Map);
- System.Console.WriteLine($@"Preview: {point.X}, {point.Y}");
- Dispatcher.BeginInvoke(() =>
- {
- var latlon = ImageryLayer.GetLatLonFromPoint(point);
- var geopoint = new GeoPoint(latlon.Y, latlon.X);
-
- if (_action == GeoFenceAction.Polygon)
- {
- if (!_definition.Coordinates.Any())
- _definition.Coordinates.Add(geopoint.Copy());
- _definition.Coordinates.Insert(_definition.Coordinates.Count - 1, geopoint.Copy());
- Address.Geofence = Serialization.Serialize(_definition);
- UpdateMap();
- e.Handled = true;
- }
- else if (_action == GeoFenceAction.Coordinates)
- {
- Address.Location.Latitude = geopoint.Latitude;
- Address.Location.Longitude = geopoint.Longitude;
- CenterMap();
- UpdateMap();
- e.Handled = true;
- }
- });
-
- }
- }
|