diff --git a/CHANGELOG b/CHANGELOG index f11818b..1811fcf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ * Add setting model to code * #19 grid automatisch generieren * #24 Add information about weather/warning +* #28 Fightdedection Plygon on Map ### Bugfixes * Add Correct Dispose Handling * TimeCalculation now handle negative values correct diff --git a/Lora-Map/Lora-Map.csproj b/Lora-Map/Lora-Map.csproj index 80367c7..956e965 100644 --- a/Lora-Map/Lora-Map.csproj +++ b/Lora-Map/Lora-Map.csproj @@ -50,6 +50,7 @@ + diff --git a/Lora-Map/Model/Crowd.cs b/Lora-Map/Model/Crowd.cs index fcf8a19..c66dd9c 100644 --- a/Lora-Map/Model/Crowd.cs +++ b/Lora-Map/Model/Crowd.cs @@ -1,63 +1,51 @@ -using LitJson; -using System; -using System.Globalization; - -namespace Fraunhofer.Fit.IoT.LoraMap.Model -{ - public class Crowd - { - public Int32 DensityCount { get; private set; } - public DateTime LastUpdate { get; private set; } - public Double AverageFlowMagnitude { get; private set; } - public Double AverageFlowDirection { get; private set; } - public Double Cofidence { get; private set; } - public String Situation { get; private set; } - - public Crowd(JsonData json) => this.Update(json); - - public static Boolean CheckJsonCrowdDensityLocal(JsonData json) => json.ContainsKey("camera_ids") && json["camera_ids"].IsArray && json["camera_ids"].Count == 1 && - json.ContainsKey("density_map") && json["density_map"].IsArray && - json.ContainsKey("type_module") && json["type_module"].IsString && json["type_module"].ToString() == "crowd_density_local" && - json.ContainsKey("density_count") && json["density_count"].IsInt && - json.ContainsKey("timestamp1") && json["timestamp1"].IsString; - - public static Boolean CheckJsonFlow(JsonData json) => json.ContainsKey("camera_ids") && json["camera_ids"].IsArray && json["camera_ids"].Count == 1 && - json.ContainsKey("average_flow_magnitude") && json["average_flow_magnitude"].IsArray && - json.ContainsKey("type_module") && json["type_module"].IsString && json["type_module"].ToString() == "flow" && - json.ContainsKey("average_flow_direction") && json["average_flow_direction"].IsArray && - json.ContainsKey("timestamp") && json["timestamp"].IsString; - - public static Boolean CheckJsonFightingDetection(JsonData json) => json.ContainsKey("camera_ids") && json["camera_ids"].IsArray && json["camera_ids"].Count == 1 && - json.ContainsKey("confidence") && json["confidence"].IsDouble && - json.ContainsKey("type_module") && json["type_module"].IsString && json["type_module"].ToString() == "fighting_detection" && - json.ContainsKey("situation") && json["situation"].IsString && - json.ContainsKey("timestamp") && json["timestamp"].IsString; - - public static String GetId(JsonData json) => (String)json["camera_ids"][0]; - - public void Update(JsonData json) { - if(CheckJsonCrowdDensityLocal(json)) { - this.DensityCount = (Int32)json["density_count"]; - if (DateTime.TryParse((String)json["timestamp1"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { - this.LastUpdate = updatetime.ToUniversalTime(); - } - } else if(CheckJsonFlow(json)) { - if (json["average_flow_magnitude"].Count == 1) { - this.AverageFlowMagnitude = (Double)json["average_flow_magnitude"][0]; - } - if (json["average_flow_direction"].Count == 1) { - this.AverageFlowDirection = (Double)json["average_flow_direction"][0]; - } - if (DateTime.TryParse((String)json["timestamp"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { - this.LastUpdate = updatetime.ToUniversalTime(); - } - } else if(CheckJsonFightingDetection(json)) { - this.Cofidence = (Double)json["confidence"]; - this.Situation = (String)json["situation"]; - if (DateTime.TryParse((String)json["timestamp"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { - this.LastUpdate = updatetime.ToUniversalTime(); - } - } - } - } -} +using LitJson; +using System; +using System.Globalization; + +namespace Fraunhofer.Fit.IoT.LoraMap.Model +{ + public class Crowd + { + public Int32 DensityCount { get; private set; } + public DateTime TimeStamp { get; private set; } + public Double AverageFlowMagnitude { get; private set; } + public Double AverageFlowDirection { get; private set; } + public DateTime LastUpdate { get; private set; } + + public Crowd(JsonData json) => this.Update(json); + + public static Boolean CheckJsonCrowdDensityLocal(JsonData json) => json.ContainsKey("camera_ids") && json["camera_ids"].IsArray && json["camera_ids"].Count == 1 && + json.ContainsKey("density_map") && json["density_map"].IsArray && + json.ContainsKey("type_module") && json["type_module"].IsString && json["type_module"].ToString() == "crowd_density_local" && + json.ContainsKey("density_count") && json["density_count"].IsInt && + json.ContainsKey("timestamp1") && json["timestamp1"].IsString; + + public static Boolean CheckJsonFlow(JsonData json) => json.ContainsKey("camera_ids") && json["camera_ids"].IsArray && json["camera_ids"].Count == 1 && + json.ContainsKey("average_flow_magnitude") && json["average_flow_magnitude"].IsArray && + json.ContainsKey("type_module") && json["type_module"].IsString && json["type_module"].ToString() == "flow" && + json.ContainsKey("average_flow_direction") && json["average_flow_direction"].IsArray && + json.ContainsKey("timestamp") && json["timestamp"].IsString; + + public static String GetId(JsonData json) => (String)json["camera_ids"][0]; + + public void Update(JsonData json) { + if(CheckJsonCrowdDensityLocal(json)) { + this.DensityCount = (Int32)json["density_count"]; + if (DateTime.TryParse((String)json["timestamp1"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { + this.TimeStamp = updatetime.ToUniversalTime(); + } + } else if(CheckJsonFlow(json)) { + if (json["average_flow_magnitude"].Count == 1) { + this.AverageFlowMagnitude = (Double)json["average_flow_magnitude"][0]; + } + if (json["average_flow_direction"].Count == 1) { + this.AverageFlowDirection = (Double)json["average_flow_direction"][0]; + } + if (DateTime.TryParse((String)json["timestamp"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { + this.TimeStamp = updatetime.ToUniversalTime(); + } + } + this.LastUpdate = DateTime.UtcNow; + } + } +} diff --git a/Lora-Map/Model/Fight.cs b/Lora-Map/Model/Fight.cs new file mode 100644 index 0000000..d937cdb --- /dev/null +++ b/Lora-Map/Model/Fight.cs @@ -0,0 +1,35 @@ +using LitJson; +using System; +using System.Globalization; + +namespace Fraunhofer.Fit.IoT.LoraMap.Model { + public class Fight { + public Fight(JsonData json) => this.Update(json); + + public DateTime LastUpdate { get; private set; } + public DateTime TimeStamp { get; private set; } + public String Situation { get; private set; } + public Double FightProbability { get; private set; } + + public static Boolean CheckJsonFightingDetection(JsonData json) => json.ContainsKey("camera_ids") && json["camera_ids"].IsArray && json["camera_ids"].Count == 1 && + json.ContainsKey("confidence") && json["confidence"].IsString && + json.ContainsKey("type_module") && json["type_module"].IsString && json["type_module"].ToString() == "fighting_detection" && + json.ContainsKey("situation") && json["situation"].IsString && + json.ContainsKey("timestamp") && json["timestamp"].IsString; + + public static String GetId(JsonData json) => (String)json["camera_ids"][0]; + + public void Update(JsonData json) { + if (CheckJsonFightingDetection(json)) { + if (Double.TryParse((String)json["confidence"], NumberStyles.Float, CultureInfo.InvariantCulture, out Double cofidence)) { + this.FightProbability = cofidence; + } + this.Situation = (String)json["situation"]; + if (DateTime.TryParse((String)json["timestamp"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime)) { + this.TimeStamp = updatetime.ToUniversalTime(); + } + this.LastUpdate = DateTime.UtcNow; + } + } + } +} diff --git a/Lora-Map/Model/Settings.cs b/Lora-Map/Model/Settings.cs index 748666a..85c7768 100644 --- a/Lora-Map/Model/Settings.cs +++ b/Lora-Map/Model/Settings.cs @@ -12,6 +12,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model { public Double Startloclat { get; private set; } public Double Startloclon { get; private set; } public Dictionary>>> Grid { get; private set; } + public Dictionary>> FightDedection { get; private set; } public Settings() => this.ParseJson(); @@ -36,6 +37,24 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model { } } } + if(json.ContainsKey("FightDedection") && json["FightDedection"].IsObject) { + Dictionary>> fight = new Dictionary>>(); + foreach (KeyValuePair entry in json["FightDedection"]) { + List> poly = new List>(); + if(entry.Value.ContainsKey("Poly") && entry.Value["Poly"].IsArray) { + foreach (JsonData coord in entry.Value["Poly"]) { + List coords = new List(); + if (coord.ContainsKey("Lat") && coord["Lat"].IsDouble && coord.ContainsKey("Lon") && coord["Lon"].IsDouble) { + coords.Add((Double)coord["Lat"]); + coords.Add((Double)coord["Lon"]); + } + poly.Add(coords); + } + } + fight.Add(entry.Key, poly); + } + this.FightDedection = fight; + } this.gridradius = json.ContainsKey("GridRadius") && json["GridRadius"].IsInt && this.Startloclat != 0 && this.Startloclon != 0 ? (Int32)json["GridRadius"] : 0; this.GenerateGrid(); } diff --git a/Lora-Map/Server.cs b/Lora-Map/Server.cs index 33be813..1374279 100644 --- a/Lora-Map/Server.cs +++ b/Lora-Map/Server.cs @@ -17,6 +17,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap { private readonly SortedDictionary alarms = new SortedDictionary(); private readonly SortedDictionary cameras = new SortedDictionary(); private readonly SortedDictionary crowds = new SortedDictionary(); + private readonly SortedDictionary fights = new SortedDictionary(); private JsonData marker; private readonly Settings settings; private readonly WeatherWarnings weather; @@ -24,6 +25,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap { private readonly AdminModel admin; private readonly Object lockData = new Object(); private readonly Object lockPanic = new Object(); + private readonly Object lockFight = new Object(); public Server(ADataBackend backend, Dictionary settings, InIReader requests) : base(backend, settings, requests) { this.logger.SetPath(settings["loggingpath"]); @@ -100,7 +102,6 @@ namespace Fraunhofer.Fit.IoT.LoraMap { this.cameras.Add(cameraid, new Camera(d)); } } else if((((String)mqtt.From).Contains("sfn/crowd_density_local") && Crowd.CheckJsonCrowdDensityLocal(d)) || - (((String)mqtt.From).Contains("sfn/fighting_detection") && Crowd.CheckJsonFightingDetection(d)) || (((String)mqtt.From).Contains("sfn/flow") && Crowd.CheckJsonFlow(d))) { String cameraid = Crowd.GetId(d); if(this.crowds.ContainsKey(cameraid)) { @@ -108,6 +109,15 @@ namespace Fraunhofer.Fit.IoT.LoraMap { } else { this.crowds.Add(cameraid, new Crowd(d)); } + } else if(((String)mqtt.From).Contains("camera/fighting_detection") && Fight.CheckJsonFightingDetection(d)) { + String cameraid = Fight.GetId(d); + lock (this.lockFight) { + if (this.fights.ContainsKey(cameraid)) { + this.fights[cameraid].Update(d); + } else { + this.fights.Add(cameraid, new Fight(d)); + } + } } } catch(Exception e) { Helper.WriteError("Backend_MessageIncomming(): "+e.Message + "\n\n" + e.StackTrace); @@ -122,6 +132,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap { { "panic", this.alarms }, { "cameracount", this.cameras }, { "crowdcount", this.crowds }, + { "fightdedect", this.fights }, { "weatherwarnings", this.weather.Warnungen } }, cont); } else if (cont.Request.Url.PathAndQuery.StartsWith("/get60000")) { diff --git a/Lora-Map/resources/js/functions.js b/Lora-Map/resources/js/functions.js index f4b2652..73d4c5b 100644 --- a/Lora-Map/resources/js/functions.js +++ b/Lora-Map/resources/js/functions.js @@ -29,6 +29,7 @@ OverlayObject._ParseAJAXCount(json["cameracount"]); OverlayObject._ParseAJAXDensity(json["crowdcount"]); MenuObject._ParseAJAXWeatherAlerts(json["weatherwarnings"]); + MapObject._ParseAJAXFightDedection(json["fightdedect"]); } }; get1000.open("GET", "/get1000", true); diff --git a/Lora-Map/resources/js/map.js b/Lora-Map/resources/js/map.js index 1e73f06..d4d9da9 100644 --- a/Lora-Map/resources/js/map.js +++ b/Lora-Map/resources/js/map.js @@ -1,5 +1,6 @@ var MapObject = { Map: {}, + _FightDedection: {}, _SpecialMarkers: new Array(), Start: function () { this.Map = L.map('bigmap').setView([0, 0], 16); @@ -10,6 +11,7 @@ _ParseAJAXSettings: function (settings) { this.Map.panTo([settings.Startloclat, settings.Startloclon]); this._GenerateGrid(settings.Grid); + this._GenerateFightBoxes(settings.FightDedection); }, _ParseAJAXLayers: function (maps) { var i = 0; @@ -60,6 +62,32 @@ L.polyline([[lineminor.from[0], lineminor.from[1]], [lineminor.to[0], lineminor.to[1]]], { color: "red", weight: 0.7, opacity: 0.5 }).addTo(this.Map); } }, + _GenerateFightBoxes: function (fightdedection) { + for (var cameraid in fightdedection) { + this._FightDedection[cameraid] = L.polygon(fightdedection[cameraid], { color: 'black', weight: 1 }).addTo(this.Map); + this._FightDedection[cameraid].bindPopup("Fightdedection für Kamera: " + cameraid); + } + }, + _ParseAJAXFightDedection: function (json) { + for (var cameraid in json) { + if (this._FightDedection.hasOwnProperty(cameraid)) { + var fight = json[cameraid]; + var box = this._FightDedection[cameraid]; + var diff = FunctionsObject.TimeCalculation(fight["LastUpdate"], "diffraw"); + if (diff <= 10 && box.options.color === "black") { + box.setStyle({ color: 'rgb(' + (fight["FightProbability"]*255)+',0,0)' }); + } else if (diff <= 10 && box.options.color !== "black") { + if (diff % 2 == 0) { + box.setStyle({ color: 'rgb(' + (fight["FightProbability"] * 255) + ',0,0)' }); + } else { + box.setStyle({ color: 'green' }); + } + } else if (diff > 10 && box.options.color !== "black") { + box.setStyle({ color: 'black' }); + } + } + } + }, _ParseAJAXGeo: function (geo) { if (!(Object.keys(geo).length === 0 && geo.constructor === Object)) { L.geoJSON(geo, {