From ff1a036124a724107f5dc35faa52d8a02d83f35a Mon Sep 17 00:00:00 2001 From: Daniel Schick Date: Tue, 3 Jan 2023 16:30:03 +0100 Subject: [PATCH] =?UTF-8?q?Richtungspfeile=20f=C3=BCr=20die=20Web=C3=BCber?= =?UTF-8?q?sicht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AIS/bsmd.AIS2Service/AISZoneMonitor.cs | 1 + AIS/bsmd.AIS2Service/AIS_SQLiteStorage.cs | 2 +- AIS/bsmd.AIS2Service/App.config | 3 ++ .../Properties/Settings.Designer.cs | 11 +++- .../Properties/Settings.settings | 3 ++ AIS/bsmd.AIS2Service/img/arrow_down_red.png | Bin 0 -> 933 bytes AIS/bsmd.AIS2Service/img/arrow_up_green.png | Bin 0 -> 950 bytes .../img/bullet_square_yellow.png | Bin 0 -> 446 bytes AIS/bsmd.AIS2Service/img/clock.png | Bin 0 -> 1662 bytes .../webservice/SLRController.cs | 51 +++++++++++++++++- .../webservice/ShipLocationReport.cs | 1 + AIS/bsmd.AIS2Service/zonen.js | 5 +- 12 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 AIS/bsmd.AIS2Service/img/arrow_down_red.png create mode 100644 AIS/bsmd.AIS2Service/img/arrow_up_green.png create mode 100644 AIS/bsmd.AIS2Service/img/bullet_square_yellow.png create mode 100644 AIS/bsmd.AIS2Service/img/clock.png diff --git a/AIS/bsmd.AIS2Service/AISZoneMonitor.cs b/AIS/bsmd.AIS2Service/AISZoneMonitor.cs index d9e2a0d8..9cd113eb 100644 --- a/AIS/bsmd.AIS2Service/AISZoneMonitor.cs +++ b/AIS/bsmd.AIS2Service/AISZoneMonitor.cs @@ -72,6 +72,7 @@ namespace bsmd.AIS2Service { if(testDict.ContainsKey(mmsi)) { + if (!_sitRepDict.ContainsKey(mmsi)) continue; AIS_Target target = _sitRepDict[mmsi]; foreach(AlarmAssignmentZone aazone in testDict[mmsi]) { if(aazone.Zone.IsPointInPolygon4(target.Position)) diff --git a/AIS/bsmd.AIS2Service/AIS_SQLiteStorage.cs b/AIS/bsmd.AIS2Service/AIS_SQLiteStorage.cs index 4065abbe..0efb605a 100644 --- a/AIS/bsmd.AIS2Service/AIS_SQLiteStorage.cs +++ b/AIS/bsmd.AIS2Service/AIS_SQLiteStorage.cs @@ -400,7 +400,7 @@ namespace bsmd.AIS2Service string loadSLRString = "SELECT a.timestamp_first, a.timestamp_last, za.mmsi, mz.id FROM alarm a " + "INNER JOIN zone_assignment za ON a.zone_assignment_id = za.id " + "INNER JOIN monitor_zone mz ON za.monitor_zone_id = mz.id " + - $"WHERE mz.monitor_group_id = {groupId}"; + $"WHERE mz.monitor_group_id = {groupId} ORDER BY mz.sequence"; SQLiteCommand laCmd = new SQLiteCommand(loadSLRString, _connection); SQLiteDataReader reader = laCmd.ExecuteReader(); diff --git a/AIS/bsmd.AIS2Service/App.config b/AIS/bsmd.AIS2Service/App.config index 01211684..da7c04e3 100644 --- a/AIS/bsmd.AIS2Service/App.config +++ b/AIS/bsmd.AIS2Service/App.config @@ -70,6 +70,9 @@ 60 + + 24 + diff --git a/AIS/bsmd.AIS2Service/Properties/Settings.Designer.cs b/AIS/bsmd.AIS2Service/Properties/Settings.Designer.cs index 8ea7f200..a5128f39 100644 --- a/AIS/bsmd.AIS2Service/Properties/Settings.Designer.cs +++ b/AIS/bsmd.AIS2Service/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace bsmd.AIS2Service.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.2.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -130,5 +130,14 @@ namespace bsmd.AIS2Service.Properties { return ((int)(this["MinAlarmIntervalMins"])); } } + + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("24")] + public int AutoAlarmExpiryHours { + get { + return ((int)(this["AutoAlarmExpiryHours"])); + } + } } } diff --git a/AIS/bsmd.AIS2Service/Properties/Settings.settings b/AIS/bsmd.AIS2Service/Properties/Settings.settings index 33f3e9aa..3f43ac8f 100644 --- a/AIS/bsmd.AIS2Service/Properties/Settings.settings +++ b/AIS/bsmd.AIS2Service/Properties/Settings.settings @@ -38,5 +38,8 @@ 60 + + 24 + \ No newline at end of file diff --git a/AIS/bsmd.AIS2Service/img/arrow_down_red.png b/AIS/bsmd.AIS2Service/img/arrow_down_red.png new file mode 100644 index 0000000000000000000000000000000000000000..a76e2f2a86ba7fa00e75553e4817e1ea3a0f05ad GIT binary patch literal 933 zcmV;W16urvP)8#(+DFEdGX; z7t!m#KwN-0!nue_=_qK}Kfp#Y7|><|O}3GpD%d)pAOTZ6g0*J<0F7fnk>FA15HW3Y zK-FN<7Ll|22jCotM}3B15e;|!u?Qw@;Ccc?5sDze14>We3brc)w~B18kCvKuCC^wwk>yS7>8G5H)~EXcjJGg*_U`w{;o z1D8WZ5J?GHipE7mbvI1f!1h$4T#RalWEqmR(87HH6lYv7V;Z3v5TAi6CSN2351q-$ zMG$rOzXy2tSmDRMk+G6=R$roMbYtUBw9^A5p#4LL2y`0jEVQz~h0|kmlFM&{Vyz>o zR2Dy(9m56hW+w7O#i?iTho?XSzLDUoHBbQzVQU>R>HqYnfCe0H+9IrDh_K(2Iv<|E@ES=(F{qly|sx;%#l z-?^}aW;3OldM>Y-%Ipn2*ma7|U)>r0X1TSIZC5GQE2zsM-V-v9_ZcBeF~f(D5D*(7 z#!*+p+PxfgZ*m6CpVyl;X3 zQWvKOmT$c=roX>7q8~lmf1UqBAD<{LesH{h{$c+43x0&GCqTM9C;$KeD|AIzbVF}& zd2(rIXmkKWZ*X~XX=iA3AgLfSFfceRGB7bQAW2R`Pf}ALM{QzA5RM^F00000NkvXX Hu0mjf0V$}! literal 0 HcmV?d00001 diff --git a/AIS/bsmd.AIS2Service/img/arrow_up_green.png b/AIS/bsmd.AIS2Service/img/arrow_up_green.png new file mode 100644 index 0000000000000000000000000000000000000000..a053206733272ea385b9d42e84e2bfb0aa05c1d5 GIT binary patch literal 950 zcmV;n14;aeP))^ytBZC;xyZCIw84 z|AFz~#l(23c(NCp#snK{)l{JJqm&h7+1>Y<84p`8)U?3P`I-65_xsF@XB#ngsqfF8 zi=8*Ole1;OdlUV$=gyC{9U5po@XEy}Z*4U%-pZr*#|Lf?jr6x=aRjr+4&p z!-dZVmmdgtb>c|&;9ygIOJzIF`Z&KAr%6*q(1Z{IK?3Vx6;ne+iNh}Hd^0z*)A*F9 zf2^e^E4_W{29=$Dr^``7tJmlfF{h+r7bgdhPk1w77s zoK|r8nfXCrcRZI;Kyfa)mry`J0Bu}CV&LW&es3>NJVR#?oeVMnY zAUT2rJf*HpKus}&iYSeH2;rd$Hgp3~K}>PxQI(QS231i7&byrh45gs!1WCX=&Ok*` zGt89AiYk100Aa&61FSTrChUsRI9G;6VnROTNJMZZICGdPswEZasH!}R)G0a35hTHx z1A}mHiqwS4R3)yQDH0Plk~KsU%v`Ck2x^8%C|OjN0))g0cuNtxn8?S3xQU1umvZb* z*Om9lK@x5(U8h*c6A|NGjKhI5BA4RI%;o>i&&~jA3pwV#{;O2<-dt^tbSnKoz`r#> zwkxUJ-&+6x04sDwSad^gaCvfRXJ~W)LvL_-a%pF1bRel9GB7YWEiy1MF(64!Lr+pu YAV+OtNDz)8PXGV_07*qoM6N<$f-M`vc>n+a literal 0 HcmV?d00001 diff --git a/AIS/bsmd.AIS2Service/img/bullet_square_yellow.png b/AIS/bsmd.AIS2Service/img/bullet_square_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..19623882cd140e98aaa5875c1c405c3039da51dd GIT binary patch literal 446 zcmV;v0YUzWP)kZ^b0Ouz=yZIo$URy85F~<1`L})5E3Bm0joju(p%|L|f!{fa%QUKEh zHD(aa#>MH)C6ERf7L4gySl<4WoMj;b1aOax3bvBB$a{tG40y=%Ie-k}6!eAQHGNH0 z187TZACUPYAc`PML%fC_0PoTI9aBwaSO3joH1??X>44xpoq1#ORwn?2fheI5z}bMQ z8k*Vwivh)|;9QRuS*Mh>#ag#0Jpzv{k>r!-B6wSi1# zH%Y$EP@>Sez6Q0W^V6h%qhZ?5psMt}ti$HYvLG?eHHadVb)YQuH5m|N+`qjySHoex zmGbP2(N~dpz<>PB_y8%VykAMl$k_k@04sDwSad^gaCvfRXJ~W)LvL_-a%pF1bRel9 oGB7YWEiy1MF(64!Lr+puAV+OtNDz)8PXGV_07*qoM6N<$f;W=HB>(^b literal 0 HcmV?d00001 diff --git a/AIS/bsmd.AIS2Service/img/clock.png b/AIS/bsmd.AIS2Service/img/clock.png new file mode 100644 index 0000000000000000000000000000000000000000..84f277fd590cfef77b398e214d30409ffa8566b6 GIT binary patch literal 1662 zcmV-^27&pBP)3$w6g_X5eJzD)0jV9jLV?t!NK#usVoY36jLM?X1dTv6nz&%}mnKHjMj?RIw2){b zktIZ;QvIVLMuRD65L${9ER?p|O6j!I&hqAMp6?CdioE2TOkTcs&%NiId#{B5d77J> z=cLo=HI`*9QB}3t<#H7ohK^J!J(5bLPMfCr6|e1XX=&-XR*e4y*t&IVm9FdWGT_~Y zVMtj`gQn$RS~ds<+csfaCSU^-6BE|>`1pZrHv8)S{rk^c7l7HU&*gHPB}wuo#*&ym zs{|DlRS1WI(6Sk*svD4Hj3&l$>Qpx_^!7m4G8h^fN)zPS_V)G<{u)pDNATBWS#C}y zCtOov#b{_;jGGqJ!0&a#rOMEAStyDO{)N}AqAXsDS+mQLGi+p1Nmn9~SRRYT^#1<- zZ~s-n_U+r(D~i%`ab!fg<+gfMSCk=>PNAS60$Fi67s)y40WAKILZs4Z3=R$;94*9e zBME%-Ksupvy11RUp38z-o$Bc(kZc`B2q!lWv4jIEsx{S(N1_siR=VdDfpj2;;wk-Ctc+gl?Vs?D4AW2 zg>`kZ$KzS0G&VNAVOeI$ZS_m2qE6%}KT;VWpE0S!jniZJ?pPP%Gm9LMd_UMsf>kK0 zb08^BQgk3(fiR#=ptG|}VwGx*X-fzN0*t^rlWA`Gz0>H zLRB{m+maN?9|%I?2w-dmm3Y*=n50Yie(l<|=sSNN%O89M8((MY~55cSIpaziX*@T|UIqK(h%W;P4a_6}fV?oMS(A4w}9$vW$Pp^9hzg`?eMl+Gl z7__*-;HIOA%)88*jaR^AEm8f5a8b9IC6g?fD&;RKdGUmpA~WHqx0~L=z4zVE5uqSL zJ(!DA8Lv3qZHsF392Aip^-GS83O&1J4z@!wJF)v@C!$jdnN{|(1~e7&PC4-DLCjxJ zi>YiV-7xbmVuscg5Sk-H;W;842Hc8;vuA%1l^>GX10T~`)`=fFpmAvZ+Phrh$BHII=(9j0wxwdvIgM5P24-%g~`2zwNCc6FI-wmtIBojZT#JU^IBjNt5< z)0kCO$x%Eea_2};v3JitELnOdbW_lU%fNZ?d?j#n8XX-)Y{m_kSsX*>v7?xroIF5F z_d4xL&%ZQ0Je)c7#V5!K!5DmCU;tx@B)(_%jmwtNE&AUB^E-zYPSkh5< z>ALA`xvt|s5!`^Aqhe-Q!HylRHXCfimMvS({cEE&G&H=%?tQbNu~AyS@^M&_8$q9& z8%uLKbZBT0p-2HIXn=sW)4784Su={6c?PX*Z8oWSb3twYC0- zS3io9s(J8-q7W;1czBSLHi!VJ5aN4yqCN%3e>{TE54NW`5I1bvy!oT+E`6~q*dNW| zaOi>h`rGA&3+qr>H5XIZ{w{W_ZRtoRMscR62gi>6WKo9$*~|N<}v^P04sDwSad^g zaCvfRXJ~W)LvL_-a%pF1bRel9GB7YWEiy1MF(64!Lr+puAV+OtNDz)8PXGV_07*qo IM6N<$f@85BumAu6 literal 0 HcmV?d00001 diff --git a/AIS/bsmd.AIS2Service/webservice/SLRController.cs b/AIS/bsmd.AIS2Service/webservice/SLRController.cs index 7c26b1ab..30d339a3 100644 --- a/AIS/bsmd.AIS2Service/webservice/SLRController.cs +++ b/AIS/bsmd.AIS2Service/webservice/SLRController.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Web.Http; namespace bsmd.AIS2Service @@ -11,7 +12,10 @@ namespace bsmd.AIS2Service if (!id.HasValue) return null; List result = AISManager.SQLiteStorage.GetShipLocationReports(id.Value); + Dictionary> mmsiDict = new Dictionary>(); foreach(ShipLocationReport report in result) { + if (!mmsiDict.ContainsKey(report.MMSI)) mmsiDict[report.MMSI] = new List(); + mmsiDict[report.MMSI].Add(report); if (AISManager.SitRep.ContainsKey(report.MMSI)) { report.Destination = AISManager.SitRep[report.MMSI].Destination; @@ -21,6 +25,51 @@ namespace bsmd.AIS2Service } } + // determine "state" of vessel through alarm comparison. Possible values are: + // 0 = stationary (= equals) + // 1 = incoming + // 2 = outgoing + // 3 = expired + + foreach(int key in mmsiDict.Keys) + { + bool expired = true; + DateTime? lastDate= null; + bool? incoming = null; + + // first run through alarm list to determine state + foreach(ShipLocationReport slr in mmsiDict[key]) + { + if((DateTime.Now - slr.Timestamp_Last).TotalHours < Properties.Settings.Default.AutoAlarmExpiryHours) expired = false; + if (lastDate == null) + { + lastDate = slr.Timestamp_Last; + } + else + { + incoming = slr.Timestamp_Last < lastDate; + } + } + + // second run through alarm list to set state flag in all entries + foreach (ShipLocationReport slr in mmsiDict[key]) + { + if (expired) + { + slr.VoyageDirection = 3; + } + else if (incoming.HasValue) + { + if (incoming.Value) { slr.VoyageDirection = 1; } + else { slr.VoyageDirection = 2; } + } + else + { + slr.VoyageDirection = 0; // stationary / no comparison value + } + } + } + return result; } } diff --git a/AIS/bsmd.AIS2Service/webservice/ShipLocationReport.cs b/AIS/bsmd.AIS2Service/webservice/ShipLocationReport.cs index 25d813f6..ac33e176 100644 --- a/AIS/bsmd.AIS2Service/webservice/ShipLocationReport.cs +++ b/AIS/bsmd.AIS2Service/webservice/ShipLocationReport.cs @@ -23,5 +23,6 @@ namespace bsmd.AIS2Service public string NavStatus { get; set; } + public int VoyageDirection { get; set; } } } diff --git a/AIS/bsmd.AIS2Service/zonen.js b/AIS/bsmd.AIS2Service/zonen.js index af32799e..9d3cb0b3 100644 --- a/AIS/bsmd.AIS2Service/zonen.js +++ b/AIS/bsmd.AIS2Service/zonen.js @@ -62,7 +62,10 @@ function updateData(data, groupId) { const colCount = row.childNodes.length; row.childNodes[0].innerHTML = data[i].Name; - // TODO: incoming/outgoing symbol + if(data[i].VoyageDirection == 0) row.childNodes[1].innerHTML = ''; + if(data[i].VoyageDirection == 1) row.childNodes[1].innerHTML = ''; + if(data[i].VoyageDirection == 2) row.childNodes[1].innerHTML = ''; + if(data[i].VoyageDirection == 3) row.childNodes[1].innerHTML = ''; row.childNodes[2].innerHTML = data[i].IMO; // find alarm cell and set value