// 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.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; namespace bsmd.AIS2Service { #region DBEntity public class DBEntity { protected int _id; // PK from database public DBEntity(int id) { _id = id; } public int Id { get { return _id; } set { _id = value; } } } #endregion #region class MonitorGroup public class MonitorGroup : DBEntity { #region fields private readonly string _name; private readonly List _zones = new List(); #endregion #region Construction public MonitorGroup(int id, string name) : base( id ) { _name = name; } #endregion #region Properties public List Zones { get { return _zones; } } public string Name { get { return _name; } } #endregion } #endregion #region class MonitorZone public class MonitorZone : DBEntity { #region fields private readonly List _vertices = new List(); private readonly List _assignments = new List(); private readonly string _name; #endregion #region Construction public MonitorZone(int id, string name) : base (id) { _name = name; } #endregion #region Properties public string Name { get { return _name; } } public List Vertices { get { return _vertices; } } public List Assignments { get { return _assignments; } } public bool Active { get; set; } public int Sequence { get; set; } public int MonitorGroupId { get; set; } #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; } #endregion } #endregion #region class GeoPoint public class GeoPoint : DBEntity { public GeoPoint(int id) : base (id) {} public double Lat { get; set; } public double Lon { get; set; } public int MonitorZoneId { get; set; } } #endregion #region class MonitorAssignment public class MonitorAssignment : DBEntity { public MonitorAssignment(int id) : base(id) {} [Flags] public enum ZoneMonitorType { INACTIVE = 0, ENTER = 1, EXIT = 2, PASSTHROUGH = 4, // outside - enter - inside - exit - outside LEAVE_AND_RETURN = 8 // inside - exit - outside - enter - inside } public int Id { get { return _id; } } public int MMSI { get; set; } public ZoneMonitorType MonitorType { get; set; } = ZoneMonitorType.INACTIVE; } #endregion #region class Alarm public class Alarm : DBEntity { private readonly MonitorAssignment _assignment; public Alarm(int id, MonitorAssignment assignment) : base(id) { _assignment = assignment; } public MonitorAssignment Assignment { get { return _assignment; } } public DateTime Timestamp { get; set; } public DateTime? Acknowledged { get; set; } public MonitorAssignment.ZoneMonitorType ZoneMonitorType { get; set; } } #endregion }