122 lines
3.8 KiB
C#
122 lines
3.8 KiB
C#
// Copyright (c) 2022 - schick Informatik
|
|
// bsmd.AIS2Service [MonitorZone.cs]: %UserDisplayName%
|
|
// Description: Represents a geographical area that should be checked against
|
|
// ship positions
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml.Linq;
|
|
|
|
namespace bsmd.AIS2Service
|
|
{
|
|
|
|
#region class MonitorZone
|
|
|
|
public class MonitorZone : DBEntity, IComparable<MonitorZone>
|
|
{
|
|
|
|
#region fields
|
|
|
|
private readonly List<GeoPoint> _vertices = new List<GeoPoint>();
|
|
private readonly List<MonitorAssignment> _assignments = new List<MonitorAssignment>();
|
|
private readonly string _name;
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
public MonitorZone(long id, string name) : base (id)
|
|
{
|
|
_name = name;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public string Name { get { return _name; } }
|
|
|
|
public List<GeoPoint> Vertices { get { return _vertices; } }
|
|
|
|
public List<MonitorAssignment> Assignments { get { return _assignments; } }
|
|
|
|
public bool Active { get; set; }
|
|
|
|
public int Sequence { get; set; }
|
|
|
|
public long MonitorGroupId { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region public static methods
|
|
|
|
public static MonitorZone ImportFromKML(string filename)
|
|
{
|
|
MonitorZone result = null;
|
|
if (File.Exists(filename))
|
|
{
|
|
XDocument kml = XDocument.Load(filename);
|
|
XNamespace ns = "http://www.opengis.net/kml/2.2";
|
|
|
|
string name = kml.Root.Element(ns + "Document").Element(ns + "name").Value;
|
|
if (name.EndsWith(".kml")) name = name.Substring(0, name.Length - 4);
|
|
result = new MonitorZone(-1, name);
|
|
|
|
// now find all vertices
|
|
string[] vertices = kml.Root.Element(ns + "Document").Element(ns + "Placemark").Element(ns + "Polygon").Element(ns + "outerBoundaryIs").Element(ns + "LinearRing").Element(ns + "coordinates").Value.Split(' ');
|
|
for (int i = 0; i < vertices.Length - 1; i++)
|
|
{
|
|
string[] pointElems = vertices[i].Trim().Split(',');
|
|
if (pointElems.Length != 3) continue;
|
|
GeoPoint gp = new GeoPoint(-1);
|
|
gp.Lon = Double.Parse(pointElems[0], System.Globalization.NumberFormatInfo.InvariantInfo);
|
|
gp.Lat = Double.Parse(pointElems[1], System.Globalization.NumberFormatInfo.InvariantInfo);
|
|
result.Vertices.Add(gp);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public methods
|
|
|
|
public bool IsPointInPolygon4(GeoPoint testPoint)
|
|
{
|
|
bool result = false;
|
|
int j = _vertices.Count() - 1;
|
|
for (int i = 0; i < _vertices.Count(); i++)
|
|
{
|
|
if (_vertices[i].Lat < testPoint.Lat && _vertices[j].Lat >= testPoint.Lat || _vertices[j].Lat < testPoint.Lat && _vertices[i].Lat >= testPoint.Lat)
|
|
{
|
|
if (_vertices[i].Lon + (testPoint.Lat - _vertices[i].Lat) / (_vertices[j].Lat - _vertices[i].Lat) * (_vertices[j].Lon - _vertices[i].Lon) < testPoint.Lon)
|
|
{
|
|
result = !result;
|
|
}
|
|
}
|
|
j = i;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public int CompareTo(MonitorZone other)
|
|
{
|
|
return this.Sequence.CompareTo(other.Sequence);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return String.Format("{0} (Seq.:{1} #Vert.:{2}", this.Name, this.Sequence, this.Vertices.Count);
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|