// Copyright (c) 2022 - schick Informatik // bsmd.AIS2Service [AISZoneMonitor.cs]: %UserDisplayName% // Description: Background Thread Controller class for comparing AIS Targets // to monitor zones // using log4net; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Security.Policy; using System.Text; using System.Threading; using System.Threading.Tasks; namespace bsmd.AIS2Service { internal class AISZoneMonitor : IAISThread { #region Fields ConcurrentDictionary _sitRepDict; AIS_SQLiteStorage _storage; private Thread _thread; private bool _stopFlag = false; private static readonly ILog _log = LogManager.GetLogger(typeof(AISZoneMonitor)); #endregion #region Construction public AISZoneMonitor(ConcurrentDictionary sitRepDict, AIS_SQLiteStorage sqliteStorage) { _sitRepDict = sitRepDict; _storage = sqliteStorage; } #endregion #region private methods private void Monitor() { // load zones from storage List allZones = _storage.LoadMonitorZones(); Dictionary> testZones = new Dictionary>(); foreach(MonitorZone zone in allZones) { // load up Zone list for all assignment mmsi's (to check) foreach(MonitorAssignment ma in zone.Assignments) { if(!testZones.ContainsKey(ma.MMSI)) testZones[ma.MMSI] = new List(); testZones[ma.MMSI].Add(zone); } } // loop while(!_stopFlag) { // check all "current" AIS Targets against the zones foreach(int mmsi in _sitRepDict.Keys) { if(testZones.ContainsKey(mmsi)) { AIS_Target target = _sitRepDict[mmsi]; foreach(MonitorZone zone in testZones[mmsi]) { if(zone.IsPointInPolygon4(target.Position)) { _log.InfoFormat("{0} is in zone {1}", target.ToString(), zone.Name); } } } } int currentSaturationSecs = 0; // (DateTime.Now - alarm.FirstDetected).TotalSeconds; if(currentSaturationSecs > Properties.Settings.Default.MonitorTargetSaturationSecs) { // trigger alarm, this thing was "hot" long enough } Thread.Sleep(Properties.Settings.Default.MonitorTestIntervalSecs * 1000); } } #endregion #region IAISThread implementation public string Name { get { return "Zone monitor"; } } public event EventHandler FatalErrorOccurred; public void Start() { if (_thread != null) return; // may not run twice ThreadStart runReader = new ThreadStart(this.Monitor); _thread = new Thread(runReader); _thread.Start(); } public void Stop() { if (_thread == null) return; _stopFlag = true; _thread.Join(); _thread = null; } #endregion } }