diff --git a/CHANGELOG b/CHANGELOG index 8d82863..4cc8a11 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,23 @@ # Changelogs +## 1.2.9 +### New Features +* Add setting model to code +* #19 grid automatisch generieren +* #24 Add information about weather/warning +* #28 Fightdedection Plygon on Map +* #27 Draw Camera-Desity bock on map +* #16 filter nach kategorien/tracker einbauen +* #15 suche nach ständen einbauen +### Bugfixes +* Add Correct Dispose Handling +* TimeCalculation now handle negative values correct +### Changes +* Refactoring of all JS +* Make only one request per second instead of four per AJAX +* Refactoring adminpannel and add settings.json +* New function in TimeCalculation, so you can not have negative Timespans + ## 1.2.8 ### New Features * Implement #12 Make icon transparent if there is no data update diff --git a/Lora-Map/Lib/WebRequests.cs b/Lora-Map/Lib/WebRequests.cs new file mode 100644 index 0000000..8a4e98a --- /dev/null +++ b/Lora-Map/Lib/WebRequests.cs @@ -0,0 +1,62 @@ +using System; +using System.IO; +using System.Net; + +using BlubbFish.Utils; + +using LitJson; + +namespace Fraunhofer.Fit.IoT.LoraMap.Lib { + public class WebRequests { + private static readonly Object getLock = new Object(); + public JsonData GetJson(String url) { + String text = null; + for(Int32 i = 0; i < 3; i++) { + try { + text = this.GetString(url); + break; + } catch(Exception e) { + Helper.WriteError(e.Message); + if(i == 2) { + throw; + } + System.Threading.Thread.Sleep(30000); + } + } + if(text == null) { + return new JsonData(); + } + try { + return JsonMapper.ToObject(text); + } catch(Exception) { + return new JsonData(); + } + } + + private String GetString(String url, Boolean withoutput = true) { + String ret = null; + lock(getLock) { + HttpWebRequest request = WebRequest.CreateHttp(url); + request.Timeout = 10000; + //request.Headers.Add(HttpRequestHeader.Authorization, this.auth); + try { + using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { + if(response.StatusCode == HttpStatusCode.Unauthorized) { + Console.Error.WriteLine("Benutzer oder Passwort falsch!"); + throw new Exception("Benutzer oder Passwort falsch!"); + } + if(withoutput) { + StreamReader reader = new StreamReader(response.GetResponseStream()); + ret = reader.ReadToEnd(); + } + } + } catch(Exception e) { + //Helper.WriteError("Konnte keine Verbindung zum Razzbery Server herstellen. Resource: \"" + this.server + v + "\" Fehler: " + e.Message); + //return null; + throw new Exception("Konnte keine Verbindung zum Server herstellen: " + e.Message); + } + } + return ret; + } + } +} diff --git a/Lora-Map/Lora-Map.csproj b/Lora-Map/Lora-Map.csproj index 8f6e897..216558a 100644 --- a/Lora-Map/Lora-Map.csproj +++ b/Lora-Map/Lora-Map.csproj @@ -45,13 +45,17 @@ + + + + @@ -98,12 +102,24 @@ PreserveNewest + + PreserveNewest + PreserveNewest PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -236,8 +252,6 @@ PreserveNewest - - - + \ No newline at end of file diff --git a/Lora-Map/Model/Admin/AdminModel.cs b/Lora-Map/Model/Admin/AdminModel.cs index 3374f33..3546f7a 100644 --- a/Lora-Map/Model/Admin/AdminModel.cs +++ b/Lora-Map/Model/Admin/AdminModel.cs @@ -1,157 +1,131 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Text; -using BlubbFish.Utils; -using BlubbFish.Utils.IoT.Bots; -using LitJson; - -namespace Fraunhofer.Fit.IoT.LoraMap.Model.Admin { - class AdminModel { - public delegate void AdminEvent(Object sender, EventArgs e); - public event AdminEvent NamesUpdate; - - private readonly Dictionary session = new Dictionary(); - private readonly Dictionary settings; - - public AdminModel(Dictionary settings) { - this.settings = settings; - if(!settings.ContainsKey("admin_user") || !settings.ContainsKey("admin_pass")) { - Helper.WriteError("Kann die Einstellungen [webserver] admin_user und admin_pass nicht laden!"); - throw new FileNotFoundException("Kann die Einstellungen [webserver] admin_user und admin_pass nicht laden!"); - } - } - - public Boolean ParseReuqest(HttpListenerContext cont) { - if(cont.Request.Url.PathAndQuery == "/admin/login") { - return this.Login(cont); - } - if(!this.CheckAuth(cont)) { - return false; - } - if(cont.Request.Url.PathAndQuery.StartsWith("/admin/get_json_")) { - return this.SendJson(cont); - } - if(cont.Request.Url.PathAndQuery.StartsWith("/admin/set_json_")) { - return this.GetJson(cont); - } - return Webserver.SendFileResponse(cont); - } - - private Boolean GetJson(HttpListenerContext cont) { - if(cont.Request.Url.PathAndQuery == "/admin/set_json_names") { - StreamReader reader = new StreamReader(cont.Request.InputStream, cont.Request.ContentEncoding); - String rawData = reader.ReadToEnd(); - cont.Request.InputStream.Close(); - reader.Close(); - try { - JsonMapper.ToObject(rawData); - } catch(Exception) { - Helper.WriteError("501 - Error recieving names.json " + cont.Request.Url.PathAndQuery); - cont.Response.StatusCode = 501; - return false; - } - File.WriteAllText("json/names.json", rawData); - Console.WriteLine("200 - Post names.json " + cont.Request.Url.PathAndQuery); - this.NamesUpdate?.Invoke(this, new EventArgs()); - return true; - } else if(cont.Request.Url.PathAndQuery == "/admin/set_json_geo") { - StreamReader reader = new StreamReader(cont.Request.InputStream, cont.Request.ContentEncoding); - String rawData = reader.ReadToEnd(); - cont.Request.InputStream.Close(); - reader.Close(); - try { - JsonMapper.ToObject(rawData); - } catch(Exception) { - Helper.WriteError("501 - Error recieving geo.json " + cont.Request.Url.PathAndQuery); - cont.Response.StatusCode = 501; - return false; - } - File.WriteAllText("json/geo.json", rawData); - Console.WriteLine("200 - Post geo.json " + cont.Request.Url.PathAndQuery); - this.NamesUpdate?.Invoke(this, new EventArgs()); - return true; - } - return false; - } - - private Boolean SendJson(HttpListenerContext cont) { - if(cont.Request.Url.PathAndQuery == "/admin/get_json_names") { - String file = File.ReadAllText("json/names.json"); - Byte[] buf = Encoding.UTF8.GetBytes(file); - cont.Response.ContentLength64 = buf.Length; - cont.Response.OutputStream.Write(buf, 0, buf.Length); - Console.WriteLine("200 - Send names.json " + cont.Request.Url.PathAndQuery); - return true; - } else if(cont.Request.Url.PathAndQuery == "/admin/get_json_geo") { - String file = File.ReadAllText("json/geo.json"); - Byte[] buf = Encoding.UTF8.GetBytes(file); - cont.Response.ContentLength64 = buf.Length; - cont.Response.OutputStream.Write(buf, 0, buf.Length); - Console.WriteLine("200 - Send geo.json " + cont.Request.Url.PathAndQuery); - return true; - } - Helper.WriteError("404 - Section in get_json not found " + cont.Request.Url.PathAndQuery + "!"); - cont.Response.StatusCode = 404; - return false; - } - - private Boolean Login(HttpListenerContext cont) { - Dictionary POST = Webserver.GetPostParams(cont.Request); - if(POST.ContainsKey("user") && POST["user"] == this.settings["admin_user"] && POST.ContainsKey("pass") && POST["pass"] == this.settings["admin_pass"]) { - Int64 sessionid = 0; - while(true) { - sessionid = AdminSession.GetRandomSessionid(); - if(!this.session.ContainsKey(sessionid)) { - break; - } - } - if(cont.Request.Cookies["loramapsession"] != null) { - if(Int64.TryParse(cont.Request.Cookies["loramapsession"].Value, out Int64 cookiesessionid)) { - if(this.session.ContainsKey(cookiesessionid)) { - if(!this.session[sessionid].IsLoggedin) { - sessionid = cookiesessionid; - } - } - } - } - if(!this.session.ContainsKey(sessionid)) { - this.session.Add(sessionid, new AdminSession()); - } - this.session[sessionid].IsLoggedin = true; - cont.Response.AppendCookie(new Cookie("loramapsession", sessionid.ToString()) { - Expires = DateTime.Now.AddYears(1) - }); - cont.Response.AddHeader("Location", "/admin"); - cont.Response.StatusCode = 307; - Console.WriteLine("200 - Login OK! " + cont.Request.Url.PathAndQuery); - return true; - } - cont.Response.AddHeader("Location", "/admin/login.html"); - cont.Response.StatusCode = 307; - Helper.WriteError("307 - Login WRONG! " + cont.Request.Url.PathAndQuery); - return false; - } - - private Boolean CheckAuth(HttpListenerContext cont) { - #if DEBUG - return true; - #endif - if(cont.Request.Url.PathAndQuery.StartsWith("/admin/login.html")) { - return true; - } else { - if(cont.Request.Cookies["loramapsession"] != null) { - if(Int64.TryParse(cont.Request.Cookies["loramapsession"].Value, out Int64 sessionid)) { - if(this.session.ContainsKey(sessionid)) { - return this.session[sessionid].IsLoggedin; - } - } - } - cont.Response.StatusCode = 403; - Helper.WriteError("403 - " + cont.Request.Url.PathAndQuery); - } - return false; - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using BlubbFish.Utils; +using BlubbFish.Utils.IoT.Bots; +using LitJson; + +namespace Fraunhofer.Fit.IoT.LoraMap.Model.Admin { + class AdminModel { + public delegate void AdminEvent(Object sender, EventArgs e); + public event AdminEvent NamesUpdate; + public event AdminEvent GeoUpdate; + public event AdminEvent SettingsUpdate; + + private readonly Dictionary session = new Dictionary(); + private readonly Dictionary settings; + + public AdminModel(Dictionary settings) { + this.settings = settings; + if(!settings.ContainsKey("admin_user") || !settings.ContainsKey("admin_pass")) { + Helper.WriteError("Kann die Einstellungen [webserver] admin_user und admin_pass nicht laden!"); + throw new FileNotFoundException("Kann die Einstellungen [webserver] admin_user und admin_pass nicht laden!"); + } + } + + public Boolean ParseReuqest(HttpListenerContext cont) => + cont.Request.Url.PathAndQuery == "/admin/login" ? this.Login(cont) : + !this.CheckAuth(cont) ? false : + cont.Request.Url.PathAndQuery.StartsWith("/admin/get_json_") ? this.GetJsonFiles(cont) : + cont.Request.Url.PathAndQuery.StartsWith("/admin/set_json_") ? this.SetJsonFiles(cont) : + Webserver.SendFileResponse(cont); + + private Boolean SetJsonFiles(HttpListenerContext cont) => + cont.Request.Url.PathAndQuery == "/admin/set_json_names" ? this.SetJsonFile(cont, "names.json", this.NamesUpdate) : + cont.Request.Url.PathAndQuery == "/admin/set_json_geo" ? this.SetJsonFile(cont, "geo.json", this.GeoUpdate) : + cont.Request.Url.PathAndQuery == "/admin/set_json_settings" ? this.SetJsonFile(cont, "settings.json", this.SettingsUpdate) : + false; + + private Boolean SetJsonFile(HttpListenerContext cont, String filename, AdminEvent updatenotifier) { + StreamReader reader = new StreamReader(cont.Request.InputStream, cont.Request.ContentEncoding); + String rawData = reader.ReadToEnd(); + cont.Request.InputStream.Close(); + reader.Close(); + try { + JsonMapper.ToObject(rawData); + } catch (Exception) { + Helper.WriteError("501 - Error recieving " + filename + ", no valid json " + cont.Request.Url.PathAndQuery); + cont.Response.StatusCode = 501; + return false; + } + File.WriteAllText("json/"+ filename, rawData); + Console.WriteLine("200 - Post " + filename + " " + cont.Request.Url.PathAndQuery); + updatenotifier?.Invoke(this, new EventArgs()); + return true; + } + + private Boolean GetJsonFiles(HttpListenerContext cont) => + cont.Request.Url.PathAndQuery == "/admin/get_json_names" ? this.GetJsonFile(cont, "names.json") : + cont.Request.Url.PathAndQuery == "/admin/get_json_geo" ? this.GetJsonFile(cont, "geo.json") : + cont.Request.Url.PathAndQuery == "/admin/get_json_settings" ? this.GetJsonFile(cont, "settings.json") : + false; + + private Boolean GetJsonFile(HttpListenerContext cont, String filename) { + String file = File.ReadAllText("json/" + filename); + Byte[] buf = Encoding.UTF8.GetBytes(file); + cont.Response.ContentLength64 = buf.Length; + cont.Response.OutputStream.Write(buf, 0, buf.Length); + Console.WriteLine("200 - Send names.json " + cont.Request.Url.PathAndQuery); + return true; + } + + private Boolean Login(HttpListenerContext cont) { + Dictionary POST = Webserver.GetPostParams(cont.Request); + if(POST.ContainsKey("user") && POST["user"] == this.settings["admin_user"] && POST.ContainsKey("pass") && POST["pass"] == this.settings["admin_pass"]) { + Int64 sessionid = 0; + while(true) { + sessionid = AdminSession.GetRandomSessionid(); + if(!this.session.ContainsKey(sessionid)) { + break; + } + } + if(cont.Request.Cookies["loramapsession"] != null) { + if(Int64.TryParse(cont.Request.Cookies["loramapsession"].Value, out Int64 cookiesessionid)) { + if(this.session.ContainsKey(cookiesessionid)) { + if(!this.session[sessionid].IsLoggedin) { + sessionid = cookiesessionid; + } + } + } + } + if(!this.session.ContainsKey(sessionid)) { + this.session.Add(sessionid, new AdminSession()); + } + this.session[sessionid].IsLoggedin = true; + cont.Response.AppendCookie(new Cookie("loramapsession", sessionid.ToString()) { + Expires = DateTime.Now.AddYears(1) + }); + cont.Response.AddHeader("Location", "/admin"); + cont.Response.StatusCode = 307; + Console.WriteLine("200 - Login OK! " + cont.Request.Url.PathAndQuery); + return true; + } + cont.Response.AddHeader("Location", "/admin/login.html"); + cont.Response.StatusCode = 307; + Helper.WriteError("307 - Login WRONG! " + cont.Request.Url.PathAndQuery); + return false; + } + + private Boolean CheckAuth(HttpListenerContext cont) { + #if DEBUG + return true; + #endif + if(cont.Request.Url.PathAndQuery.StartsWith("/admin/login.html")) { + return true; + } else { + if(cont.Request.Cookies["loramapsession"] != null) { + if(Int64.TryParse(cont.Request.Cookies["loramapsession"].Value, out Int64 sessionid)) { + if(this.session.ContainsKey(sessionid)) { + return this.session[sessionid].IsLoggedin; + } + } + } + cont.Response.StatusCode = 403; + Helper.WriteError("403 - " + cont.Request.Url.PathAndQuery); + } + return false; + } + } +} diff --git a/Lora-Map/Model/Crowd.cs b/Lora-Map/Model/Crowd.cs index fcf8a19..2d22ed6 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("timestamp_1") && json["timestamp_1"].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["timestamp_1"], 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/Marker.cs b/Lora-Map/Model/Marker.cs index fedef22..e6b1510 100644 --- a/Lora-Map/Model/Marker.cs +++ b/Lora-Map/Model/Marker.cs @@ -37,7 +37,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model } } } - ret += (ret.Contains("?")) ? "&name=" + name : "?name=" + name; + ret += ret.Contains("?") ? "&name=" + name : "?name=" + name; return ret; } diff --git a/Lora-Map/Model/PositionItem.cs b/Lora-Map/Model/PositionItem.cs index d081bf7..9149ba6 100644 --- a/Lora-Map/Model/PositionItem.cs +++ b/Lora-Map/Model/PositionItem.cs @@ -19,8 +19,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model { public Double Height { get; private set; } public String Name { get; private set; } public String Icon { get; private set; } - - + public String Group { get; private set; } public PositionItem(JsonData json, JsonData marker) { this.Update(json); @@ -29,21 +28,13 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model { public void UpdateMarker(JsonData marker, String id) { if(marker.ContainsKey(id)) { - if(marker[id].ContainsKey("name") && marker[id]["name"].IsString) { - this.Name = (String)marker[id]["name"]; - } else { - this.Name = id; - } - if(marker[id].ContainsKey("marker.svg") && marker[id]["marker.svg"].IsObject) { - this.Icon = Marker.ParseMarkerConfig(marker[id]["marker.svg"], this.Name); - } else if(marker[id].ContainsKey("icon") && marker[id]["icon"].IsString) { - this.Icon = (String)marker[id]["icon"]; - } else { - this.Icon = null; - } + this.Name = marker[id].ContainsKey("name") && marker[id]["name"].IsString ? (String)marker[id]["name"] : id; + this.Icon = marker[id].ContainsKey("marker.svg") && marker[id]["marker.svg"].IsObject ? Marker.ParseMarkerConfig(marker[id]["marker.svg"], this.Name) : marker[id].ContainsKey("icon") && marker[id]["icon"].IsString ? (String)marker[id]["icon"] : null; + this.Group = marker[id].ContainsKey("Group") && marker[id]["Group"].IsString ? (String)marker[id]["Group"] : "no"; } else { this.Name = id; this.Icon = null; + this.Group = null; } } public static Boolean CheckJson(JsonData json) => json.ContainsKey("Rssi") && json["Rssi"].IsDouble @@ -71,17 +62,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model { } this.Recievedtime = DateTime.UtcNow; this.Battery = Math.Round((Double)json["BatteryLevel"], 2); - if(this.Battery < 3.44) { - this.Batterysimple = 0; - } else if(this.Battery < 3.53) { - this.Batterysimple = 1; - } else if(this.Battery < 3.6525) { - this.Batterysimple = 2; - } else if(this.Battery < 3.8825) { - this.Batterysimple = 3; - } else { - this.Batterysimple = 4; - } + this.Batterysimple = this.Battery < 3.44 ? 0 : this.Battery < 3.53 ? 1 : this.Battery < 3.6525 ? 2 : this.Battery < 3.8825 ? 3 : 4; this.Latitude = (Double)json["Gps"]["Latitude"]; this.Longitude = (Double)json["Gps"]["Longitude"]; this.Fix = (Boolean)json["Gps"]["Fix"]; diff --git a/Lora-Map/Model/Settings.cs b/Lora-Map/Model/Settings.cs new file mode 100644 index 0000000..ed88be4 --- /dev/null +++ b/Lora-Map/Model/Settings.cs @@ -0,0 +1,170 @@ +using CoordinateSharp; +using LitJson; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Fraunhofer.Fit.IoT.LoraMap.Model { + public class Settings { + private readonly List weatherCellIDs = new List(); + private Int32 gridradius; + + 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 Dictionary DensityArea { get; private set; } + + public Settings() => this.ParseJson(); + + public void AdminModelUpdateSettings(Object sender, EventArgs e) => this.ParseJson(); + + private void ParseJson() { + JsonData json = JsonMapper.ToObject(File.ReadAllText("json/settings.json")); + if(json.ContainsKey("StartPos") && json["StartPos"].IsObject && + json["StartPos"].ContainsKey("lat") && json["StartPos"]["lat"].IsDouble && + json["StartPos"].ContainsKey("lon") && json["StartPos"]["lon"].IsDouble) { + this.Startloclat = (Double)json["StartPos"]["lat"]; + this.Startloclon = (Double)json["StartPos"]["lon"]; + } else { + this.Startloclat = 0; + this.Startloclon = 0; + } + this.weatherCellIDs.Clear(); + if (json.ContainsKey("CellIds") && json["CellIds"].IsArray && json["CellIds"].Count > 0) { + foreach (JsonData item in json["CellIds"]) { + if(Int32.TryParse(item.ToString(), out Int32 cellid)) { + this.weatherCellIDs.Add(cellid); + } + } + } + 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; + } + if (json.ContainsKey("CrwodDensity") && json["CrwodDensity"].IsObject) { + Dictionary densitys = new Dictionary(); + foreach (KeyValuePair entry in json["CrwodDensity"]) { + Density density = new Density(); + density.Polygon = 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"]); + } + density.Polygon.Add(coords); + } + } + if(entry.Value.ContainsKey("Count") && (entry.Value["Count"].IsInt || entry.Value["Count"].IsDouble)) { + density.Maximum = (Int32)entry.Value["Count"]; + } + densitys.Add(entry.Key, density); + } + this.DensityArea = densitys; + } + this.gridradius = json.ContainsKey("GridRadius") && json["GridRadius"].IsInt && this.Startloclat != 0 && this.Startloclon != 0 ? (Int32)json["GridRadius"] : 0; + this.GenerateGrid(); + } + + private void GenerateGrid() { + if(this.Startloclat == 0 || this.Startloclon == 0 || this.gridradius == 0) { + return; + } + MilitaryGridReferenceSystem start = new Coordinate(this.Startloclat, this.Startloclon).MGRS; + + Double left = start.Easting - this.gridradius - (start.Easting - this.gridradius) % 100; + Double bottom = start.Northing - this.gridradius - (start.Northing - this.gridradius) % 100; + Double right = start.Easting + this.gridradius + (100 - (start.Easting + this.gridradius) % 100); + Double top = start.Northing + this.gridradius + (100 - (start.Northing + this.gridradius) % 100); + this.Grid = new Dictionary>>> { + { "Major", new List>>() }, + { "Minor", new List>>() } + }; + for (Double i = left; i <= right; i += 50) { + Coordinate TopLeft = MilitaryGridReferenceSystem.MGRStoLatLong(new MilitaryGridReferenceSystem(start.LatZone, start.LongZone, start.Digraph, i, top)); + Coordinate BottomLeft = MilitaryGridReferenceSystem.MGRStoLatLong(new MilitaryGridReferenceSystem(start.LatZone, start.LongZone, start.Digraph, i, bottom)); + if(i%100 == 0) { + this.Grid["Major"].Add(new Dictionary> { + { "from", new List { + TopLeft.Latitude.DecimalDegree, + TopLeft.Longitude.DecimalDegree + } + }, + { "to", new List { + BottomLeft.Latitude.DecimalDegree, + BottomLeft.Longitude.DecimalDegree + } + } + }); + } else { + this.Grid["Minor"].Add(new Dictionary> { + { "from", new List { + TopLeft.Latitude.DecimalDegree, + TopLeft.Longitude.DecimalDegree + } + }, + { "to", new List { + BottomLeft.Latitude.DecimalDegree, + BottomLeft.Longitude.DecimalDegree + } + } + }); + } + } + for (Double i = bottom; i <= top; i += 50) { + Coordinate BottomLeft = MilitaryGridReferenceSystem.MGRStoLatLong(new MilitaryGridReferenceSystem(start.LatZone, start.LongZone, start.Digraph, left, i)); + Coordinate BottomRight = MilitaryGridReferenceSystem.MGRStoLatLong(new MilitaryGridReferenceSystem(start.LatZone, start.LongZone, start.Digraph, right, i)); + if (i % 100 == 0) { + this.Grid["Major"].Add(new Dictionary> { + { "from", new List { + BottomLeft.Latitude.DecimalDegree, + BottomLeft.Longitude.DecimalDegree + } + }, + { "to", new List { + BottomRight.Latitude.DecimalDegree, + BottomRight.Longitude.DecimalDegree + } + } + }); + } else { + this.Grid["Minor"].Add(new Dictionary> { + { "from", new List { + BottomLeft.Latitude.DecimalDegree, + BottomLeft.Longitude.DecimalDegree + } + }, + { "to", new List { + BottomRight.Latitude.DecimalDegree, + BottomRight.Longitude.DecimalDegree + } + } + }); + } + } + } + + public List GetWeatherCellIds() => this.weatherCellIDs; + + public struct Density { + public List> Polygon { get; set; } + public Int32 Maximum { get; set; } + } + } +} diff --git a/Lora-Map/Model/WeatherWarnings.cs b/Lora-Map/Model/WeatherWarnings.cs new file mode 100644 index 0000000..7620277 --- /dev/null +++ b/Lora-Map/Model/WeatherWarnings.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Threading; + +using Fraunhofer.Fit.IoT.LoraMap.Lib; + +using LitJson; + +namespace Fraunhofer.Fit.IoT.LoraMap.Model { + public class WeatherWarnings { + private readonly Settings settings; + private Thread bgthread; + private readonly WebRequests webrequests = new WebRequests(); + + public List Warnungen { get; private set; } + + public WeatherWarnings(Settings settings) { + this.settings = settings; + this.StartBackgroundThread(); + } + + private void StartBackgroundThread() { + this.bgthread = new Thread(this.BackGroundRunner); + this.bgthread.Start(); + } + + private void BackGroundRunner() { + while(true) { + List ret = new List(); + foreach(Int32 item in this.settings.GetWeatherCellIds()) { + try { + JsonData json = this.webrequests.GetJson("https://maps.dwd.de/geoserver/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&typeName=dwd:Warnungen_Gemeinden&outputFormat=application/json&cql_filter=WARNCELLID=" + item); + if (json.ContainsKey("features") && json["features"].IsArray && json["features"].Count > 0) { + foreach (JsonData warning in json["features"]) { + try { + ret.Add(new Warning(warning)); + } catch { } + } + } + } catch { } + } + this.Warnungen = ret; + Thread.Sleep(60 * 1000); + } + } + + internal void Dispose() => this.bgthread.Abort(); + + public class Warning { + public Warning(JsonData warning) { + this.Id = warning["id"].ToString(); + this.From = warning["properties"]["SENT"].ToString(); + this.To = warning["properties"]["EXPIRES"].ToString(); + this.Location = warning["properties"]["NAME"].ToString(); + this.Type = warning["properties"]["EVENT"].ToString().ToLower(); + this.Level = warning["properties"]["SEVERITY"].ToString().ToLower(); + this.Headline = warning["properties"]["HEADLINE"].ToString(); + this.Body = warning["properties"]["DESCRIPTION"].ToString(); + this.Instructions = warning["properties"]["INSTRUCTION"] != null ? warning["properties"]["INSTRUCTION"].ToString() : ""; + } + + public String Id { get; } + public String From { get; } + public String To { get; } + public String Location { get; } + public String Type { get; } + public String Level { get; } + public String Headline { get; } + public String Body { get; } + public String Instructions { get; } + } + } + + +} + +/* https://maps.dwd.de/geoserver/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&typeName=dwd:Warnungen_Gemeinden&outputFormat=application/json&cql_filter=WARNCELLID=805314000 + * { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": "Warnungen_Gemeinden.805314000.2.49.0.1.276.0.DWD.PVW.1565627520000.4edfa973-5fef-4b97-8990-7489828dbe5b.DEU", + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ 7.2072, 50.7395 ], + [ 7.1534, 50.7599 ], + [ 7.1255, 50.7744 ], + [ 7.105, 50.7622 ], + [ 7.0768, 50.7679 ], + [ 7.0666, 50.7705 ], + [ 7.0378, 50.7558 ], + [ 7.0256, 50.7054 ], + [ 7.0385, 50.6886 ], + [ 7.0255, 50.665 ], + [ 7.0473, 50.6391 ], + [ 7.0639, 50.6309 ], + [ 7.1054, 50.6595 ], + [ 7.1278, 50.6472 ], + [ 7.1564, 50.6547 ], + [ 7.1954, 50.6434 ], + [ 7.2119, 50.649 ], + [ 7.1972, 50.6648 ], + [ 7.1679, 50.7035 ], + [ 7.1969, 50.7138 ], + [ 7.2072, 50.7395 ] + ] + ] + ] + }, + "geometry_name": "THE_GEOM", + "properties": { + "AREADESC": "Bonn", + "NAME": "Stadt Bonn", + "WARNCELLID": 805314000, + "IDENTIFIER": "2.49.0.1.276.0.DWD.PVW.1565627520000.4edfa973-5fef-4b97-8990-7489828dbe5b.DEU", + "SENDER": "CAP@dwd.de", + "SENT": "2019-08-12T16:32:00Z", + "STATUS": "Actual", + "MSGTYPE": "Update", + "SOURCE": "PVW", + "SCOPE": "Public", + "CODE": "id:2.49.0.1.276.0.DWD.PVW.1565627520000.4edfa973-5fef-4b97-8990-7489828dbe5b", + "LANGUAGE": "de-DE", + "CATEGORY": "Met", + "EVENT": "GEWITTER", + "RESPONSETYPE": "Prepare", + "URGENCY": "Immediate", + "SEVERITY": "Minor", + "CERTAINTY": "Likely", + "EC_PROFILE": "2.1", + "EC_LICENSE": "Geobasisdaten: Copyright Bundesamt für Kartographie und Geodäsie, Frankfurt am Main, 2017", + "EC_II": "31", + "EC_GROUP": "THUNDERSTORM;WIND", + "EC_AREA_COLOR": "255 255 0", + "EFFECTIVE": "2019-08-12T16:32:00Z", + "ONSET": "2019-08-12T16:32:00Z", + "EXPIRES": "2019-08-12T17:00:00Z", + "SENDERNAME": "DWD / Nationales Warnzentrum Offenbach", + "HEADLINE": "Amtliche WARNUNG vor GEWITTER", + "DESCRIPTION": "Von Südwesten ziehen einzelne Gewitter auf. Dabei gibt es Windböen mit Geschwindigkeiten um 60 km/h (17m/s, 33kn, Bft 7).", + "INSTRUCTION": "ACHTUNG! Hinweis auf mögliche Gefahren: Örtlich kann es Blitzschlag geben. Bei Blitzschlag besteht Lebensgefahr!", + "WEB": "http://www.wettergefahren.de", + "CONTACT": "Deutscher Wetterdienst", + "PARAMETERNAME": "Böen;Gewitter;Gewitteraufzugsrichtung", + "PARAMETERVALUE": "~60 [km/h];einzelne;SW", + "ALTITUDE": 0, + "CEILING": 9842.5197, + "bbox": [ 7.0255, 50.6309, 7.2119, 50.7744 ] + } + } + ], + "totalFeatures": 1, + "numberMatched": 1, + "numberReturned": 1, + "timeStamp": "2019-08-12T16:42:20.743Z", + "crs": { + "type": "name", + "properties": { "name": "urn:ogc:def:crs:EPSG::4326" } + }, + "bbox": [ 50.6309, 7.0255, 50.7744, 7.2119 ] +} +*/ diff --git a/Lora-Map/Program.cs b/Lora-Map/Program.cs index 648a4c6..80f7cb6 100644 --- a/Lora-Map/Program.cs +++ b/Lora-Map/Program.cs @@ -9,22 +9,19 @@ namespace Fraunhofer.Fit.IoT.LoraMap { InIReader.SetSearchPath(new List() { "/etc/loramap", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\loramap" }); if (!InIReader.ConfigExist("settings")) { Helper.WriteError("settings.ini not found!"); - Console.ReadLine(); + _ = Console.ReadLine(); return; } if(!InIReader.ConfigExist("requests")) { Helper.WriteError("requests.ini not found!"); - Console.ReadLine(); + _ = Console.ReadLine(); return; } InIReader ini = InIReader.GetInstance("settings"); Dictionary backenddata = ini.GetSection("mqtt"); - backenddata.Add("topic", "lora/#;camera/#"); + backenddata.Add("topic", "lora/#;camera/#;sfn/#"); ADataBackend b = (ADataBackend)ABackend.GetInstance(backenddata, ABackend.BackendType.Data); - new Server(b, ini.GetSection("webserver"), InIReader.GetInstance("requests")); - while(true) { - System.Threading.Thread.Sleep(1000); - } + _ = new Server(b, ini.GetSection("webserver"), InIReader.GetInstance("requests")); } } } diff --git a/Lora-Map/Properties/AssemblyInfo.cs b/Lora-Map/Properties/AssemblyInfo.cs index dee9186..01d1089 100644 --- a/Lora-Map/Properties/AssemblyInfo.cs +++ b/Lora-Map/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Fraunhofer FIT")] [assembly: AssemblyProduct("Lora-Map")] -[assembly: AssemblyCopyright("Copyright © 2018 - 10.07.2019")] +[assembly: AssemblyCopyright("Copyright © 2018 - 30.08.2019")] [assembly: AssemblyTrademark("Fraunhofer FIT, BlubbFish")] [assembly: AssemblyCulture("")] [assembly: NeutralResourcesLanguage("de-DE")] @@ -33,8 +33,8 @@ using System.Runtime.InteropServices; // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, // übernehmen, indem Sie "*" eingeben: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.8")] -[assembly: AssemblyFileVersion("1.2.8")] +[assembly: AssemblyVersion("1.2.9")] +[assembly: AssemblyFileVersion("1.2.9")] /* * 1.1.1 Add Debian package config @@ -53,4 +53,5 @@ using System.Runtime.InteropServices; * 1.2.6 New Types of marker for person * 1.2.7 Reorganise a lot of things, add Support for Cameradata * 1.2.8 Improving the UI +* 1.2.9 The PüMa Release */ diff --git a/Lora-Map/Server.cs b/Lora-Map/Server.cs index a24cef5..f23f307 100644 --- a/Lora-Map/Server.cs +++ b/Lora-Map/Server.cs @@ -15,13 +15,19 @@ namespace Fraunhofer.Fit.IoT.LoraMap { class Server : Webserver { private readonly SortedDictionary positions = new SortedDictionary(); private readonly SortedDictionary alarms = new SortedDictionary(); - private readonly SortedDictionary cameras = new SortedDictionary(); - private readonly SortedDictionary crowds = new SortedDictionary(); + private readonly SortedDictionary counter = new SortedDictionary(); + private readonly SortedDictionary density = new SortedDictionary(); + private readonly SortedDictionary fights = new SortedDictionary(); private JsonData marker; + private readonly Settings settings; + private readonly WeatherWarnings weather; private readonly Dictionary markertable = new Dictionary(); private readonly AdminModel admin; private readonly Object lockData = new Object(); private readonly Object lockPanic = new Object(); + private readonly Object lockFight = new Object(); + private readonly Object lockCount = new Object(); + private readonly Object lockDensy = new Object(); public Server(ADataBackend backend, Dictionary settings, InIReader requests) : base(backend, settings, requests) { this.logger.SetPath(settings["loggingpath"]); @@ -29,7 +35,12 @@ namespace Fraunhofer.Fit.IoT.LoraMap { this.admin = new AdminModel(settings); this.marker = JsonMapper.ToObject(File.ReadAllText("json/names.json")); this.admin.NamesUpdate += this.AdminModelUpdateNames; + this.settings = new Settings(); + this.weather = new WeatherWarnings(this.settings); + this.admin.SettingsUpdate += this.settings.AdminModelUpdateSettings; this.StartListen(); + this.WaitForShutdown(); + this.Dispose(); } private void AdminModelUpdateNames(Object sender, EventArgs e) { @@ -42,7 +53,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap { private void CheckJsonFiles() { if(!Directory.Exists("json")) { - Directory.CreateDirectory("json"); + _ = Directory.CreateDirectory("json"); } if(!File.Exists("json/names.json")) { File.WriteAllText("json/names.json", "{}"); @@ -50,6 +61,9 @@ namespace Fraunhofer.Fit.IoT.LoraMap { if(!File.Exists("json/geo.json")) { File.WriteAllText("json/geo.json", "{}"); } + if (!File.Exists("json/settings.json")) { + File.WriteAllText("json/settings.json", "{}"); + } } protected override void Backend_MessageIncomming(Object sender, BackendEvent mqtt) { @@ -84,19 +98,31 @@ namespace Fraunhofer.Fit.IoT.LoraMap { Console.WriteLine("PANIC erhalten!"); } else if(Camera.CheckJson(d) && ((String)mqtt.From).Contains("camera/count")) { String cameraid = Camera.GetId(d); - if(this.cameras.ContainsKey(cameraid)) { - this.cameras[cameraid].Update(d); - } else { - this.cameras.Add(cameraid, new Camera(d)); + lock (this.lockCount) { + if (this.counter.ContainsKey(cameraid)) { + this.counter[cameraid].Update(d); + } else { + this.counter.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)) || + } else if(((((String)mqtt.From).Contains("sfn/crowd_density_local") || ((String)mqtt.From).Contains("camera/crowd")) && Crowd.CheckJsonCrowdDensityLocal(d)) || (((String)mqtt.From).Contains("sfn/flow") && Crowd.CheckJsonFlow(d))) { String cameraid = Crowd.GetId(d); - if(this.crowds.ContainsKey(cameraid)) { - this.crowds[cameraid].Update(d); - } else { - this.crowds.Add(cameraid, new Crowd(d)); + lock (this.lockDensy) { + if (this.density.ContainsKey(cameraid)) { + this.density[cameraid].Update(d); + } else { + this.density.Add(cameraid, new Crowd(d)); + } + } + } else if((((String)mqtt.From).Contains("camera/fighting_detection") || ((String)mqtt.From).Contains("sfn/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) { @@ -106,13 +132,28 @@ namespace Fraunhofer.Fit.IoT.LoraMap { protected override Boolean SendWebserverResponse(HttpListenerContext cont) { try { - if(cont.Request.Url.PathAndQuery.StartsWith("/loc")) { - return SendJsonResponse(this.positions, cont); - } else if(cont.Request.Url.PathAndQuery.StartsWith("/panic")) { - return SendJsonResponse(this.alarms, cont); - } else if(cont.Request.Url.PathAndQuery.StartsWith("/icons/marker/Marker.svg") && cont.Request.Url.PathAndQuery.Contains("?")) { + if (cont.Request.Url.PathAndQuery.StartsWith("/get1000")) { + return SendJsonResponse(new Dictionary() { + { "loc", this.positions }, + { "panic", this.alarms }, + { "cameracount", this.counter }, + { "crowdcount", this.density }, + { "fightdedect", this.fights }, + { "weatherwarnings", this.weather.Warnungen } + }, cont); + } else if (cont.Request.Url.PathAndQuery.StartsWith("/get60000")) { + return SendJsonResponse(new Dictionary() { + { "currenttime", new Dictionary() { { "utc", DateTime.UtcNow } } } + }, cont); + } else if (cont.Request.Url.PathAndQuery.StartsWith("/getonce")) { + return SendJsonResponse(new Dictionary() { + { "getlayer", this.FindMapLayer(cont.Request) }, + { "getgeo", JsonMapper.ToObject(File.ReadAllText("json/geo.json")) }, + { "startup", this.settings } + }, cont); + } else if (cont.Request.Url.PathAndQuery.StartsWith("/icons/marker/Marker.svg") && cont.Request.Url.PathAndQuery.Contains("?")) { String hash = cont.Request.Url.PathAndQuery.Substring(cont.Request.Url.PathAndQuery.IndexOf('?') + 1); - if(!this.markertable.ContainsKey(hash)) { + if (!this.markertable.ContainsKey(hash)) { this.markertable.Add(hash, new Marker(hash)); } cont.Response.ContentType = "image/svg+xml"; @@ -121,25 +162,11 @@ namespace Fraunhofer.Fit.IoT.LoraMap { cont.Response.OutputStream.Write(buf, 0, buf.Length); Console.WriteLine("200 - " + cont.Request.Url.PathAndQuery); return true; - } else if(cont.Request.Url.PathAndQuery.StartsWith("/currenttime")) { - return SendJsonResponse(new Dictionary() { { "utc", DateTime.UtcNow } }, cont); - } else if(cont.Request.Url.PathAndQuery.StartsWith("/admin")) { + } else if (cont.Request.Url.PathAndQuery.StartsWith("/admin")) { return this.admin.ParseReuqest(cont); - } else if(cont.Request.Url.PathAndQuery.StartsWith("/getlayer")) { - return SendJsonResponse(this.FindMapLayer(cont.Request), cont); - } else if(cont.Request.Url.PathAndQuery.StartsWith("/maps/")) { + } else if (cont.Request.Url.PathAndQuery.StartsWith("/maps/")) { return SendFileResponse(cont, "resources", false); - } else if(cont.Request.Url.PathAndQuery.StartsWith("/getgeo")) { - Byte[] buf = Encoding.UTF8.GetBytes(File.ReadAllText("json/geo.json")); - cont.Response.ContentLength64 = buf.Length; - cont.Response.OutputStream.Write(buf, 0, buf.Length); - Console.WriteLine("200 - " + cont.Request.Url.PathAndQuery); - return true; - } else if(cont.Request.Url.PathAndQuery.StartsWith("/cameracount")) { - return SendJsonResponse(this.cameras, cont); - } else if (cont.Request.Url.PathAndQuery.StartsWith("/crowdcount")) { - return SendJsonResponse(this.crowds, cont); - } + } } catch(Exception e) { Helper.WriteError("SendWebserverResponse(): 500 - " + e.Message + "\n\n" + e.StackTrace); cont.Response.StatusCode = 500; @@ -182,5 +209,10 @@ namespace Fraunhofer.Fit.IoT.LoraMap { } return ret; } + + public override void Dispose() { + this.weather.Dispose(); + base.Dispose(); + } } } \ No newline at end of file diff --git a/Lora-Map/resources/admin/css/global.css b/Lora-Map/resources/admin/css/global.css index 2c0a105..1a8cdd1 100644 --- a/Lora-Map/resources/admin/css/global.css +++ b/Lora-Map/resources/admin/css/global.css @@ -30,54 +30,42 @@ margin-left: 210px; border-left: 1px solid black; } -#content #nameeditor .title { - margin-bottom: 20px; - font-weight: bold; -} -#content #nameeditor #nametable { + +#content .settingstable { margin-left: 15px; - border-collapse: collapse; + border-collapse: separate; } -#content #nameeditor #nametable thead { +#content .settingstable thead { background-color: #CCCCCC; background-color: rgba(0,0,0,0.2); } -#content #nameeditor #nametable thead th { +#content .settingstable thead th { text-align: left; } -#content #nameeditor #nametable thead .rowid { - width: 60px; -} -#content #nameeditor #nametable thead .rowicon { - width: 65px; -} -#content #nameeditor #nametable thead .rowedit { - width: 50px; -} -#content #nameeditor #nametable thead .rowname { - width: 250px; -} -#content #nameeditor #nametable tbody tr:nth-child(odd) { +#content .settingstable tbody tr:nth-child(odd) { background-color: #f39d9d; background-color: rgba(20,0,250,0.1); } -#content #nameeditor #nametable tbody tr:nth-child(even) { +#content .settingstable tbody tr:nth-child(even) { background-color: #9c9eee; background-color: rgba(250,59,0,0.1); } -#content #nameeditor #nametable tbody tr:hover { +#content .settingstable tbody tr:hover { background-color: #e4e1e1; background-color: rgba(0,0,0,0.1); } -#content #nameeditor #nametable tfoot { +#content .settingstable tfoot { background-color: #e4e1e1; background-color: rgba(0,0,0,0.1); } -#content #nameeditor .pointer { + +#content .pointer { cursor: pointer; } -#content #nameeditor #nametable tbody .name { - width: 55px; + +#content #nameeditor .title { + margin-bottom: 20px; + font-weight: bold; } #iconeditor { @@ -113,4 +101,22 @@ #content #eximport .names textarea { height: 120px; width: 90%; +} + +#content #settingseditor .title { + margin-bottom: 20px; + font-weight: bold; +} + +#content #settingseditor .startloc, +#content #settingseditor .wetterwarnings, +#content #settingseditor .savesettings, +#content #settingseditor .gridradius { + margin-left: 15px; +} + +#content #settingseditor .fightdedection, +#content #settingseditor .crowddensity { + margin-left: 15px; + margin-top: 20px; } \ No newline at end of file diff --git a/Lora-Map/resources/admin/index.html b/Lora-Map/resources/admin/index.html index 5b876b5..1632311 100644 --- a/Lora-Map/resources/admin/index.html +++ b/Lora-Map/resources/admin/index.html @@ -11,9 +11,10 @@
Wilkommen im Adminbereich
diff --git a/Lora-Map/resources/admin/js/menu.js b/Lora-Map/resources/admin/js/menu.js index c94175d..1a61b29 100644 --- a/Lora-Map/resources/admin/js/menu.js +++ b/Lora-Map/resources/admin/js/menu.js @@ -1,44 +1,65 @@ -function menu_names() { - var ajaxnames = new XMLHttpRequest(); - ajaxnames.onreadystatechange = function() { - if(ajaxnames.readyState === 4 && ajaxnames.status === 200) { - NamesEditor.ParseJson(ajaxnames.responseText); - } - }; - ajaxnames.open("GET", "/admin/get_json_names", true); - ajaxnames.send(); -} - -function menu_overlay() { - -} - -function menu_eximport() { - var ajaxnames = new XMLHttpRequest(); - ajaxnames.onreadystatechange = function () { - if (ajaxnames.readyState === 4 && ajaxnames.status === 200) { - var ajaxgeo = new XMLHttpRequest(); - ajaxgeo.onreadystatechange = function () { - if (ajaxgeo.readyState === 4 && ajaxgeo.status === 200) { - ExImport.ParseJson(ajaxnames.responseText, ajaxgeo.responseText); - } - }; - ajaxgeo.open("GET", "/admin/get_json_geo", true); - ajaxgeo.send(); - } - }; - ajaxnames.open("GET", "/admin/get_json_names", true); - ajaxnames.send(); -} +var AdminMenu = { + Names: function () { + var ajaxnames = new XMLHttpRequest(); + ajaxnames.onreadystatechange = function () { + if (ajaxnames.readyState === 4 && ajaxnames.status === 200) { + NamesEditor.ParseJson(ajaxnames.responseText); + } + }; + ajaxnames.open("GET", "/admin/get_json_names", true); + ajaxnames.send(); + return false; + }, + Overlay: function () { + return false; + }, + Settings: function () { + var ajaxsettings = new XMLHttpRequest(); + ajaxsettings.onreadystatechange = function () { + if (ajaxsettings.readyState === 4 && ajaxsettings.status === 200) { + Settings.ParseJson(JSON.parse(ajaxsettings.responseText)); + } + }; + ajaxsettings.open("GET", "/admin/get_json_settings", true); + ajaxsettings.send(); + return false; + }, + ExImport: function () { + var ajaxnames = new XMLHttpRequest(); + ajaxnames.onreadystatechange = function () { + if (ajaxnames.readyState === 4 && ajaxnames.status === 200) { + var ajaxgeo = new XMLHttpRequest(); + ajaxgeo.onreadystatechange = function () { + if (ajaxgeo.readyState === 4 && ajaxgeo.status === 200) { + var ajaxsettings = new XMLHttpRequest(); + ajaxsettings.onreadystatechange = function () { + if (ajaxsettings.readyState === 4 && ajaxsettings.status === 200) { + ExImport.ParseJson(ajaxnames.responseText, ajaxgeo.responseText, ajaxsettings.responseText); + } + }; + ajaxsettings.open("GET", "/admin/get_json_settings", true); + ajaxsettings.send(); + } + }; + ajaxgeo.open("GET", "/admin/get_json_geo", true); + ajaxgeo.send(); + } + }; + ajaxnames.open("GET", "/admin/get_json_names", true); + ajaxnames.send(); + return false; + } +}; var NamesEditor = { iconeditorcounter: 0, + filterGropus: { no: "immer Sichtbar", fw: "Feuerwehr", sani: "Sanitäter", pol: "Polizei", oa: "Ordnungsamt", si: "Sicherheitsdienst", thw: "Technisches Hilfswerk", crew: "Veranstalter", dev: "Entwickler" }, ParseJson: function (jsontext) { document.getElementById("content").innerHTML = ""; var namesconfig = JSON.parse(jsontext); var html = "
Namenseinträge in den Einstellungen
"; - html += ""; - html += ""; + html += "
IDNameIcon
"; + html += ""; html += ""; for (var id in namesconfig) { if (namesconfig.hasOwnProperty(id)) { @@ -53,12 +74,14 @@ var NamesEditor = { } else { html += ""; } + var gfilter = typeof nameentry.Group === "undefined" ? "no" : nameentry.Group; + html += ""; html += "" + ""; } } html += ""; - html += ""; + html += ""; html += "
IDNameIconFilter Gruppe
" + this.filterGropus[gfilter] + "
"; document.getElementById("content").innerHTML = html + "
"; }, @@ -119,9 +142,10 @@ var NamesEditor = { }, Add: function () { var newrow = document.createElement("tr"); - newrow.innerHTML = ""; - newrow.innerHTML += ""; + newrow.innerHTML = ""; + newrow.innerHTML += ""; newrow.innerHTML += " wähle Icon"; + newrow.innerHTML += "" + this.CreateSelectBox("", "item", { item: "" }, this.filterGropus, null, null, true); newrow.innerHTML += " "; document.getElementById("nametable").children[1].appendChild(newrow); }, @@ -135,7 +159,7 @@ var NamesEditor = { } var id = rows[i].children[0].innerText; var name = rows[i].children[1].innerText; - namejson[id] = { "name": name }; + namejson[id] = { "name": name, "Group": rows[i].children[3].attributes.rel.nodeValue }; if (rows[i].children[2].children[0].hasAttribute("data")) { namejson[id]["marker.svg"] = this.BuildIconJson(rows[i].children[2].children[0].data); } @@ -164,16 +188,18 @@ var NamesEditor = { var id = el.children[0].innerText; var name = el.children[1].innerText; var url = null; + var gfilter = el.children[3].attributes.rel.nodeValue; if (el.children[2].children[0].hasAttribute("data")) { url = el.children[2].children[0].data; } - el.innerHTML = ""; - el.innerHTML += ""; + el.innerHTML = ""; + el.innerHTML += ""; if (url === null) { el.innerHTML += " wähle Icon"; } else { el.innerHTML += " "; } + el.innerHTML += "" + this.CreateSelectBox("", "item", { item: gfilter }, this.filterGropus, null, null, true); el.innerHTML += " "; }, Abort: function (el) { @@ -183,6 +209,10 @@ var NamesEditor = { var id = el.children[0].children[0].value; var name = el.children[1].children[0].value; var url = null; + var gfilter = el.children[3].children[0].selectedOptions[0].value; + if (gfilter === "---") { + gfilter = "no"; + } if (el.children[2].children.length === 2) { url = el.children[2].children[1].data; } @@ -193,6 +223,7 @@ var NamesEditor = { } else { el.innerHTML += ""; } + el.innerHTML += "" + this.filterGropus[gfilter] + ""; el.innerHTML += " "; }, IconEditor: function (el) { @@ -220,13 +251,17 @@ var NamesEditor = { ""; document.getElementsByTagName("body")[0].appendChild(ie); }, - CreateSelectBox: function (title, key, query, options, muliple, group) { - var html = title + ": "; - var eventtext = "NamesEditor.ChangeLinkPreview(\"" + key + "\",this.selectedOptions);"; - if (typeof group !== "undefined") { - eventtext += " document.getElementById(\"" + group + "\"+this.value).style.display = \"block\";'"; + CreateSelectBox: function (title, key, query, options, muliple, group, noonchange) { + var html = title !== "" ? title + ": " : ""; + var onchange = ""; + if (!(typeof noonchange !== "undefined" && noonchange === true)) { + var eventtext = "NamesEditor.ChangeLinkPreview(\"" + key + "\",this.selectedOptions);"; + if (typeof group !== "undefined" && group !== null) { + eventtext += " document.getElementById(\"" + group + "\"+this.value).style.display = \"block\";'"; + } + onchange = " onchange='" + eventtext + "'"; } - html += " Lat, Lon"; + html += "
CellId's für DWD-Wetterwarnungen: (Trennen durch \";\", cap_warncellids_csv)
"; + html += "
Radius für das Grid um den Startpunkt: m
"; + html += "
Fight Dedection Kameras:
" + this._renderFightDedection(jsonsettings.FightDedection) + "
"; + html += "
Crowd Density Kameras:
" + this._renderCrowdDensity(jsonsettings.CrwodDensity) + "
"; + html += "
"; + document.getElementById("content").innerHTML = html + ""; + }, + Save: function () { + var ret = {}; + ret.StartPos = {}; + ret.StartPos.lat = parseFloat(document.getElementById("startlat").value.replace(",", ".")); + ret.StartPos.lon = parseFloat(document.getElementById("startlon").value.replace(",", ".")); + ret.CellIds = document.getElementById("wetterids").value.split(";"); + ret.GridRadius = parseInt(document.getElementById("gridrad").value); + + var rowsf = document.getElementById("fighttable").children[1].children; + var fightjson = {}; + for (var i = 0; i < rowsf.length; i++) { + if (rowsf[i].children[0].children.length === 1) { + alert("Bitte zuerst alle Zeilen speichern oder Löschen!"); + return; + } + var id = rowsf[i].children[0].innerText; + var coords = rowsf[i].children[1].innerHTML.split("
"); + var polyjson = []; + for (var j = 0; j < coords.length; j++) { + var coord = coords[j].split(";"); + polyjson[j] = { "Lat": this._filterFloat(coord[0]), "Lon": this._filterFloat(coord[1]) }; + } + fightjson[id] = { "Poly": polyjson }; + } + ret.FightDedection = fightjson; + + var rowsc = document.getElementById("crowdtable").children[1].children; + var crowdjson = {}; + for (i = 0; i < rowsc.length; i++) { + if (rowsc[i].children[0].children.length === 1) { + alert("Bitte zuerst alle Zeilen speichern oder Löschen!"); + return; + } + id = rowsc[i].children[0].innerText; + var num = this._filterFloat(rowsc[i].children[1].innerText); + coords = rowsc[i].children[2].innerHTML.split("
"); + + polyjson = []; + for (j = 0; j < coords.length; j++) { + coord = coords[j].split(";"); + polyjson[j] = { "Lat": this._filterFloat(coord[0]), "Lon": this._filterFloat(coord[1]) }; + } + crowdjson[id] = { + "Poly": polyjson, + "Count": num + }; + } + ret.CrwodDensity = crowdjson; + + var savesettings = new XMLHttpRequest(); + savesettings.onreadystatechange = function () { + if (savesettings.readyState === 4) { + if (savesettings.status === 200) { + alert("Änderungen gespeichert!"); + } else if (savesettings.status === 501) { + alert("Ein Fehler ist aufgetreten (invalid JSON)!"); + } + } + }; + savesettings.open("POST", "/admin/set_json_settings", true); + savesettings.send(JSON.stringify(ret)); + }, + _renderFightDedection: function (json) { + var ret = ""; + ret += ""; + ret += ""; + ret += ""; + for (var id in json) { + var coords = []; + for (var i = 0; i < json[id].Poly.length; i++) { + coords[i] = json[id].Poly[i].Lat + ";" + json[id].Poly[i].Lon; + } + ret += "" + + "" + + "" + + "" + + ""; + } + ret += ""; + ret += ""; + ret += "
IDKoordinaten
" + id + "" + coords.join("
") + "
"; + return ret; + }, + _renderCrowdDensity: function (json) { + var ret = ""; + ret += ""; + ret += ""; + ret += ""; + for (var id in json) { + var coords = []; + for (var i = 0; i < json[id].Poly.length; i++) { + coords[i] = json[id].Poly[i].Lat + ";" + json[id].Poly[i].Lon; + } + ret += "" + + "" + + "" + + "" + + "" + + ""; + } + ret += ""; + ret += ""; + ret += "
IDPersonenanzahlKoordinaten
" + id + "" + json[id].Count + "" + coords.join("
") + "
"; + return ret; + }, + AddFight: function () { + var newrow = document.createElement("tr"); + newrow.innerHTML = ""; + newrow.innerHTML += ""; + newrow.innerHTML += " "; + document.getElementById("fighttable").children[1].appendChild(newrow); + }, + AddDensity: function () { + var newrow = document.createElement("tr"); + newrow.innerHTML = ""; + newrow.innerHTML += ""; + newrow.innerHTML += ""; + newrow.innerHTML += " "; + document.getElementById("crowdtable").children[1].appendChild(newrow); + }, + Abort: function (el) { + el.parentNode.removeChild(el); + }, + SaveRowfight: function (el) { + var coords = el.children[1].children[0].value.replace(/\n/gi, "
"); + var coordscheck = coords.split("
"); + var fail = false; + for (var i = 0; i < coordscheck.length; i++) { + var coord = coordscheck[i].split(";"); + if (coord.length !== 2) { + fail = true; + break; + } + if (isNaN(this._filterFloat(coord[0])) || isNaN(this._filterFloat(coord[1]))) { + fail = true; + break; + } + } + if (fail) { + alert("Die Eingabe der Koordinaten ist nicht Korrekt!\n\nBeispiel:\n50.7;7.8\n50.6;7.9"); + return; + } + el.innerHTML = "" + el.children[0].children[0].value + "" + + "" + coords + "" + + " "; + }, + SaveRowdensity: function (el) { + var coords = el.children[2].children[0].value.replace(/\n/gi, "
"); + var coordscheck = coords.split("
"); + var fail = false; + for (var i = 0; i < coordscheck.length; i++) { + var coord = coordscheck[i].split(";"); + if (coord.length !== 2) { + fail = true; + break; + } + if (isNaN(this._filterFloat(coord[0])) || isNaN(this._filterFloat(coord[1]))) { + fail = true; + break; + } + } + if (fail) { + alert("Die Eingabe der Koordinaten ist nicht Korrekt!\n\nBeispiel:\n50.7;7.8\n50.6;7.9"); + return; + } + if (isNaN(this._filterFloat(el.children[1].children[0].value))) { + alert("Die Eingabe der Maximalen Anzahl der Personen ist nicht Korrekt, erwarte eine Zahl."); + return; + } + el.innerHTML = "" + el.children[0].children[0].value + "" + + "" + el.children[1].children[0].value + "" + + "" + coords + "" + + " "; + }, + Delete: function (el) { + var answ = window.prompt("Wollen sie den Eintrag für \"" + el.firstChild.innerHTML + "\" wirklich löschen?", ""); + if (answ !== null) { + el.parentNode.removeChild(el); + } + }, + EditFight: function (el) { + el.innerHTML = "" + + "" + + " "; + }, + EditDensity: function (el) { + el.innerHTML = "" + + "" + + "" + + " "; + }, + _filterFloat: function (value) { + if (/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/.test(value)) { + return Number(value); + } + return NaN; + } +}; + var ExImport = { - ParseJson: function (jsonnames, jsongeo) { + ParseJson: function (jsonnames, jsongeo, jsonsettings) { html = "
Ex- und Import der Einstellungen
"; html += "
names.json (Namen und Icons)
"; html += "
geo.json (Layer on the MAP) Kml Konverter
"; + html += "
settings.json (Settings of the Map)
"; + html += "
"; document.getElementById("content").innerHTML = html; document.getElementById("ex_names").value = jsonnames; document.getElementById("ex_geo").value = jsongeo; + document.getElementById("ex_settings").value = jsonsettings; }, SaveNames: function () { var savenames = new XMLHttpRequest(); @@ -357,5 +620,19 @@ var ExImport = { }; savegeo.open("POST", "/admin/set_json_geo", true); savegeo.send(document.getElementById("ex_geo").value); + }, + SaveSettings: function () { + var savesettings = new XMLHttpRequest(); + savesettings.onreadystatechange = function () { + if (savesettings.readyState === 4) { + if (savesettings.status === 200) { + alert("Änderungen an settings.json gespeichert!"); + } else if (savesettings.status === 501) { + alert("Ein Fehler ist aufgetreten (invalid JSON)!"); + } + } + }; + savesettings.open("POST", "/admin/set_json_settings", true); + savesettings.send(document.getElementById("ex_settings").value); } }; \ No newline at end of file diff --git a/Lora-Map/resources/css/global.css b/Lora-Map/resources/css/global.css index 889abbb..57a9bff 100644 --- a/Lora-Map/resources/css/global.css +++ b/Lora-Map/resources/css/global.css @@ -59,12 +59,24 @@ object { #menucollumn .pos { background-image: url("icons/placeholder.png"); } +#menucollumn .filter { + background-image: url("icons/filter.png"); +} #menucollumn .admin { background-image: url("icons/admin-with-cogwheels.png"); } #menucollumn .info { background-image: url("icons/information.png"); } +#menucollumn .weather { + background-image: url("icons/storm-in.png"); +} +#menucollumn .weather.ac { + background-image: url("icons/storm-ac.png"); +} +#menucollumn .suche { + background-image: url("icons/search.png"); +} #pannels { position: absolute; @@ -89,6 +101,10 @@ object { #pannels #pannels_pos .item { margin: 4px; } +#pannels #pannels_pos .item.filter { + opacity: 0.4; + background-color: rgba(1,1,1,0.2); +} #pannels #pannels_pos .item .color { float: left; width: 2px; @@ -101,10 +117,10 @@ object { margin-right: 5px; } #pannels #pannels_pos .item .icon img { - height: 40px; - width: 40px; - margin-left: 3px; -} + height: 40px; + width: 40px; + margin-left: 3px; + } #pannels #pannels_pos .item .line1 .name { font-weight: bold; } @@ -203,6 +219,103 @@ object { margin-left: 70px; } +#pannels #pannels_weather { + margin: 5px; + display: none; +} +#pannels #pannels_weather h1 { + margin: 0; + font-size: 20px; + text-align: center; +} +#pannels #pannels_weather .alertitem { + padding: 5px; + margin-bottom: 10px; +} +#pannels #pannels_weather .alertitem.minor { + background-color: #ffeb3b; +} +#pannels #pannels_weather .alertitem.moderate { + background-color: #fb8c00; +} +#pannels #pannels_weather .alertitem.severe { + background-color: #e53935; +} +#pannels #pannels_weather .alertitem.extreme { + background-color: #880e4f; +} +#pannels #pannels_weather .alertitem.hitze { + background-color: #c9f; +} +#pannels #pannels_weather .alertitem .head { + font-weight: bold; + display: block; + font-size: 14px; +} +#pannels #pannels_weather .alertitem .ort { + display: block; + text-align: right; + margin-bottom: 10px; +} +#pannels #pannels_weather .alertitem .text { + display: block; + margin-bottom: 10px; +} + +#pannels #pannels_filter { + margin: 5px; + display: none; +} +#pannels #pannels_filter h1 { + font-size: 16px; +} +#pannels #pannels_filter select { + height: 140px; + width: 235px; +} + +#pannels #pannels_suche { + display: none; + padding: 5px; +} +#pannels #pannels_suche .searchtitle { + font-weight: bold; + font-size: 13px; +} +#pannels #pannels_suche input { + width: 220px; + margin-top: 5px; +} +#pannels #pannels_suche #search_results { + border-top: 1px solid black; + margin-top: 10px; + padding-top: 10px; +} +#pannels #pannels_suche #search_results .result { + background-color: rgba(0,0,0,0.2); + margin-bottom: 5px; + cursor: pointer; +} +#pannels #pannels_suche #search_results .result .text { + display: inline-block; + width: 200px; +} +#pannels #pannels_suche #search_results .result .text .title { + font-weight: bold; + display: block; +} +#pannels #pannels_suche #search_results .result .text .desc { + display: block; +} +#pannels #pannels_suche #search_results .result .box { + display: inline-block; + height: 25px; + width: 15px; + border-style: solid; + border-width: 2px; + vertical-align: top; +} + #overlays #cameracount { position: absolute; top: 10px; diff --git a/Lora-Map/resources/css/icons/filter.png b/Lora-Map/resources/css/icons/filter.png new file mode 100644 index 0000000..1884276 Binary files /dev/null and b/Lora-Map/resources/css/icons/filter.png differ diff --git a/Lora-Map/resources/css/icons/search.png b/Lora-Map/resources/css/icons/search.png new file mode 100644 index 0000000..2c622d0 Binary files /dev/null and b/Lora-Map/resources/css/icons/search.png differ diff --git a/Lora-Map/resources/css/icons/storm-ac.png b/Lora-Map/resources/css/icons/storm-ac.png new file mode 100644 index 0000000..4cbbae6 Binary files /dev/null and b/Lora-Map/resources/css/icons/storm-ac.png differ diff --git a/Lora-Map/resources/css/icons/storm-in.png b/Lora-Map/resources/css/icons/storm-in.png new file mode 100644 index 0000000..ff8a59f Binary files /dev/null and b/Lora-Map/resources/css/icons/storm-in.png differ diff --git a/Lora-Map/resources/index.html b/Lora-Map/resources/index.html index b5c2aad..90f4854 100644 --- a/Lora-Map/resources/index.html +++ b/Lora-Map/resources/index.html @@ -10,15 +10,36 @@
+
+

Angezeigte Gruppen

+
+ (Klicken Sie mit STRG in das Formular um mehrere Gruppen auszuwählen)

+ Sind keine Gruppen ausgewählt, werden alle Icons angezeigt, egal welcher Gruppe sie angehören. +
+
+

Keine Gefahren

+
Teste Login...
@@ -34,9 +55,16 @@
  • Freepik licensed CC 3.0 BY
  • Silk Iconset licensed CC 2.5 BY
  • Those Icons licensed by CC 3.0 BY
  • +
  • Freepik licensed by CC 3.0 BY
  • +
  • Dimitry Miroliubov from flaticon.com
  • +
    + Standnummer:
    + +
    +
    diff --git a/Lora-Map/resources/js/functions.js b/Lora-Map/resources/js/functions.js index 8873c70..a43bc1a 100644 --- a/Lora-Map/resources/js/functions.js +++ b/Lora-Map/resources/js/functions.js @@ -1,43 +1,87 @@ -setInterval(timecorrectionrunner, 60000); -timecorrectionrunner(); - -function timecorrectionrunner() { - var timecorrection = new XMLHttpRequest(); - timecorrection.onreadystatechange = parseAjaxTimecorrection; - timecorrection.open("GET", "/currenttime", true); - timecorrection.send(); -} - -var timeOffset = 0; - -function parseAjaxTimecorrection() { - if (this.readyState === 4 && this.status === 200) { - utcobject = JSON.parse(this.responseText); +var FunctionsObject = { + _internalTimeOffset: 0, + Start: function () { + setInterval(this._Runner60000, 60000); + setInterval(this._Runner1000, 1000); + this._Runner60000(); + this._Runner1000(); + this._RunnerOnce(); + return this; + }, + _Runner60000: function () { + var get60000 = new XMLHttpRequest(); + get60000.onreadystatechange = function () { + if (get60000.readyState === 4 && get60000.status === 200) { + var json = JSON.parse(get60000.responseText); + FunctionsObject._ParseAJAX(json["currenttime"]); + } + }; + get60000.open("GET", "/get60000", true); + get60000.send(); + }, + _Runner1000: function () { + var get1000 = new XMLHttpRequest(); + get1000.onreadystatechange = function () { + if (get1000.readyState === 4 && get1000.status === 200) { + var json = JSON.parse(get1000.responseText); + MarkerObject._ParseAJAXLoc(json["loc"]); + MarkerObject._ParseAJAXPanic(json["panic"]); + OverlayObject._ParseAJAXCount(json["cameracount"]); + OverlayObject._ParseAJAXDensity(json["crowdcount"]); + MenuObject._ParseAJAXWeatherAlerts(json["weatherwarnings"]); + MapObject._ParseAJAXFightDedection(json["fightdedect"]); + MapObject._ParseAJAXDensity(json["crowdcount"]); + } + }; + get1000.open("GET", "/get1000", true); + get1000.send(); + }, + _RunnerOnce: function () { + var getonce = new XMLHttpRequest(); + getonce.onreadystatechange = function () { + if (getonce.readyState === 4 && getonce.status === 200) { + var json = JSON.parse(getonce.responseText); + MapObject._ParseAJAXLayers(json["getlayer"]); + MapObject._ParseAJAXGeo(json["getgeo"]); + MapObject._ParseAJAXSettings(json["startup"]); + } + }; + getonce.open("GET", "/getonce", true); + getonce.send(); + }, + _ParseAJAX: function (utcobject) { if (utcobject.hasOwnProperty("utc")) { - timeOffset = Date.now() - Date.parse(utcobject["utc"]); + this._internalTimeOffset = Date.now() - Date.parse(utcobject["utc"]); + } + }, + TimeCalculation: function (timestr, type) { + if (type === "diffraw" || type === "difftext" || type === "difftextn") { + var diff = Math.round((Date.now() - Date.parse(timestr) - this._internalTimeOffset) / 1000); + if (type === "diffraw") { + return diff; + } + if (type === "difftextn" && diff < 0) { + diff = diff * -1; + } + var isneg = false; + if (diff < 0) { + isneg = true; + diff = diff * -1; + } + if (diff < 60) { + return (isneg ? "-" : "") + diff + " s"; + } + if (diff < 60 * 60) { + return (isneg ? "-" : "") + Math.floor(diff / 60) + " m"; + } + if (diff < 60 * 60 * 24) { + return (isneg ? "-" : "") + Math.floor(diff / (60 * 60)) + " h"; + } + return (isneg ? "-" : "") + Math.floor(diff / (60 * 60 * 24)) + " d"; + } else if (type === "str") { + var date = new Date(Date.parse(timestr) + this._internalTimeOffset); + var str = date.toLocaleString(); + return str; } } -} - -function timeCalculation(timestr, type) { - if (type === "diffraw" || type === "difftext") { - var diff = Math.round((Date.now() - Date.parse(timestr) - timeOffset) / 1000); - if (type === "diffraw") { - return diff; - } - if (diff < 60) { - return diff + " s"; - } - if (diff < 60 * 60) { - return Math.floor(diff / 60) + " m"; - } - if (diff < 60 * 60 * 24) { - return Math.floor(diff / (60 * 60)) + " h"; - } - return Math.floor(diff / (60 * 60 * 24)) + " d"; - } else if (type === "str") { - var date = new Date(Date.parse(timestr) + timeOffset); - var str = date.toLocaleString(); - return str; - } -} \ No newline at end of file +}.Start(); \ No newline at end of file diff --git a/Lora-Map/resources/js/map.js b/Lora-Map/resources/js/map.js index 747797c..cb821fd 100644 --- a/Lora-Map/resources/js/map.js +++ b/Lora-Map/resources/js/map.js @@ -1,197 +1,263 @@ -var mymap = L.map('bigmap').setView(["{%START_LOCATION%}"], 16); - -GetMapLayers(); -function GetMapLayers() { - var layergetter = new XMLHttpRequest(); - layergetter.onreadystatechange = function () { - if (layergetter.readyState === 4 && layergetter.status === 200) { - var maps = JSON.parse(layergetter.responseText); - var i = 0; - for (var key in maps) { - i++; +var MapObject = { + Map: {}, + GeoJson: {}, + _FightDedection: {}, + _DensityAreas: {}, + _SpecialMarkers: new Array(), + Start: function () { + this.Map = L.map('bigmap').setView([0, 0], 16); + this._SetupMapZoomFontsize(); + this._SetupClickHandler(); + return this; + }, + _ParseAJAXSettings: function (settings) { + this.Map.panTo([settings.Startloclat, settings.Startloclon]); + this._GenerateGrid(settings.Grid); + this._GenerateFightBoxes(settings.FightDedection); + this._GenerateDensityBoxes(settings.DensityArea); + }, + _ParseAJAXLayers: function (maps) { + var i = 0; + for (var key in maps) { + i++; + } + if (i === 1) { + L.tileLayer(maps["online"]["url"], { + attribution: maps["online"]["attribution"], + minZoom: maps["online"]["minZoom"], + maxZoom: maps["online"]["maxZoom"] + }).addTo(this.Map); + } else { + var baseMaps = {}; + for (key in maps) { + if (key !== "online") { + var basemap = L.tileLayer(maps[key]["url"], { + attribution: maps[key]["attribution"], + minZoom: maps[key]["minZoom"], + maxZoom: maps[key]["maxZoom"], + errorTileUrl: "css/icons/failtile.png" + }); + basemap.addTo(this.Map); + baseMaps[maps[key]["title"]] = basemap; + break; + } } - if (i === 1) { - L.tileLayer(maps["online"]["url"], { - attribution: maps["online"]["attribution"], - minZoom: maps["online"]["minZoom"], - maxZoom: maps["online"]["maxZoom"] - }).addTo(mymap); - } else { - var baseMaps = {}; - for (key in maps) { - if (key !== "online") { - var basemap = L.tileLayer(maps[key]["url"], { - attribution: maps[key]["attribution"], - minZoom: maps[key]["minZoom"], - maxZoom: maps[key]["maxZoom"], - errorTileUrl: "css/icons/failtile.png" - }); - basemap.addTo(mymap); - baseMaps[maps[key]["title"]] = basemap; - break; - } + for (key in maps) { + if (!baseMaps.hasOwnProperty(maps[key]["title"])) { + baseMaps[maps[key]["title"]] = L.tileLayer(maps[key]["url"], { + attribution: maps[key]["attribution"], + minZoom: maps[key]["minZoom"], + maxZoom: maps[key]["maxZoom"], + errorTileUrl: "css/icons/failtile.png" + }); } - for (key in maps) { - if (!baseMaps.hasOwnProperty(maps[key]["title"])) { - baseMaps[maps[key]["title"]] = L.tileLayer(maps[key]["url"], { - attribution: maps[key]["attribution"], - minZoom: maps[key]["minZoom"], - maxZoom: maps[key]["maxZoom"], - errorTileUrl: "css/icons/failtile.png" - }); + } + L.control.layers(baseMaps).addTo(this.Map); + } + }, + _GenerateGrid: function (grid) { + for (var i = 0; i < grid.Major.length; i++) { + var linemajor = grid.Major[i]; + L.polyline([[linemajor.from[0], linemajor.from[1]], [linemajor.to[0], linemajor.to[1]]], { color: "red", weight: 1 }).addTo(this.Map); + } + for (var j = 0; j < grid.Minor.length; j++) { + var lineminor = grid.Minor[j]; + 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' }); } - L.control.layers(baseMaps).addTo(mymap); } } - }; - layergetter.open("GET", "/getlayer", true); - layergetter.send(); -} - -var SpecialMarkers = new Array(); -GetGeoLayer(); -function GetGeoLayer() { - var geogetter = new XMLHttpRequest(); - geogetter.onreadystatechange = function () { - if (geogetter.readyState === 4 && geogetter.status === 200) { - var geo = JSON.parse(geogetter.responseText); - if (!(Object.keys(geo).length === 0 && geo.constructor === Object)) { - L.geoJSON(geo, { - style: function (features) { - return { - color: typeof features.properties["stroke"] === "undefined" ? '#000000' : features.properties["stroke"], - weight: typeof features.properties["stroke-width"] === "undefined" ? 1 : features.properties["stroke-width"], - opacity: typeof features.properties["stroke-opacity"] === "undefined" ? 1 : features.properties["stroke-opacity"], - fillColor: typeof features.properties["fill"] === "undefined" ? '#ffffff' : features.properties["fill"], - fillOpacity: typeof features.properties["fill-opacity"] === "undefined" ? 1 : features.properties["fill-opacity"] - }; - }, - onEachFeature: function (feature, layer) { - if (feature.geometry.type === "Polygon" || feature.geometry.type === "Point" && feature.properties.hasOwnProperty("icon")) { - var text = ""+feature.properties.name+""; - if (feature.properties.hasOwnProperty("description")) { - text = text + "
    " + feature.properties.description; - } - layer.bindPopup(text); - } - }, - pointToLayer: function (geoJsonPoint, latlng) { - if (geoJsonPoint.properties.hasOwnProperty("description") && geoJsonPoint.properties["description"] === "snumber" && !geoJsonPoint.properties.hasOwnProperty("icon")) { - var snumbericon = L.marker(latlng, { - icon: new L.DivIcon({ - className: "snumber-icon", - html: geoJsonPoint.properties["name"], - iconSize: [8, 8] - }) - }); - SpecialMarkers.push(snumbericon); - return snumbericon; - } else if (geoJsonPoint.properties.hasOwnProperty("description") && geoJsonPoint.properties["description"] === "coord" && !geoJsonPoint.properties.hasOwnProperty("icon")) { - var coordicon = L.marker(latlng, { - icon: new L.DivIcon({ - className: "coord-icon", - html: geoJsonPoint.properties["name"] - }) - }); - SpecialMarkers.push(coordicon); - return coordicon; - } else if (geoJsonPoint.properties.hasOwnProperty("icon")) { - return L.marker(latlng, { icon: L.icon({ iconUrl: "css/icons/cctv.png", iconSize: [32, 32] }) }); - } - } - }).addTo(mymap); + }, + _GenerateDensityBoxes: function (densityareas) { + for (var cameraid in densityareas) { + this._DensityAreas[cameraid] = { 'Poly': L.polygon(densityareas[cameraid].Polygon, { color: 'hsl(120,100%,50%)', weight: 1 }).addTo(this.Map), 'Maximum': densityareas[cameraid].Maximum }; + this._DensityAreas[cameraid].Poly.bindPopup("Besuchermenge:
    " + + "Besucher (0/" + this._DensityAreas[cameraid].Maximum + ") Personen
    " + + ""); + } + }, + _ParseAJAXDensity: function (json) { + for (var cameraid in json) { + if (this._DensityAreas.hasOwnProperty(cameraid)) { + var crowd = json[cameraid]; + var box = this._DensityAreas[cameraid].Poly; + var max = this._DensityAreas[cameraid].Maximum; + var cur = crowd.DensityCount; + if (cur > max) { + cur = max; + } + box.setStyle({ color: this._createRGB(cur, max) }); + var p = box.getPopup().setContent("Besuchermenge:
    " + + "Besucher (" + crowd.DensityCount + "/" + max + ") Personen
    " + + "").update(); } } - }; - geogetter.open("GET", "/getgeo", true); - geogetter.send(); -} - -mymap.on('zoomend', function () { - var currentZoom = mymap.getZoom(); - if (currentZoom < 14) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "0px"; - elem._icon.style.marginLeft = "0px"; - elem._icon.style.marginTop = "0px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "0px"; - } - }); - } else if (currentZoom === 14) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "0px"; - elem._icon.style.marginLeft = "0px"; - elem._icon.style.marginTop = "0px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "6px"; - } - }); - } else if (currentZoom === 15) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "0px"; - elem._icon.style.marginLeft = "0px"; - elem._icon.style.marginTop = "0px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "9px"; - } - }); - } else if (currentZoom === 16) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "5px"; - elem._icon.style.marginLeft = "-4px"; - elem._icon.style.marginTop = "-4px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "13px"; - } - }); - } else if (currentZoom === 17) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "5px"; - elem._icon.style.marginLeft = "-4px"; - elem._icon.style.marginTop = "-4px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "16px"; - } - }); - } else if (currentZoom === 18) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "8px"; - elem._icon.style.marginLeft = "-5px"; - elem._icon.style.marginTop = "-6px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "25px"; - } - }); - } else if (currentZoom === 19) { - SpecialMarkers.forEach(function (elem, index) { - if (elem.feature.properties["description"] === "snumber") { - elem._icon.style.fontSize = "14px"; - elem._icon.style.marginLeft = "-8px"; - elem._icon.style.marginTop = "-11px"; - } - if (elem.feature.properties["description"] === "coord") { - elem._icon.style.fontSize = "45px"; + }, + _createRGB: function (current, max) { + return "hsl(" + 120 * (1 - current / max) + ",100%,50%)"; + }, + _ParseAJAXGeo: function (geo) { + if (!(Object.keys(geo).length === 0 && geo.constructor === Object)) { + this.GeoJson = geo; + L.geoJSON(geo, { + style: function (features) { + return { + color: typeof features.properties["stroke"] === "undefined" ? '#000000' : features.properties["stroke"], + weight: typeof features.properties["stroke-width"] === "undefined" ? 1 : features.properties["stroke-width"], + opacity: typeof features.properties["stroke-opacity"] === "undefined" ? 1 : features.properties["stroke-opacity"], + fillColor: typeof features.properties["fill"] === "undefined" ? '#ffffff' : features.properties["fill"], + fillOpacity: typeof features.properties["fill-opacity"] === "undefined" ? 1 : features.properties["fill-opacity"] + }; + }, + onEachFeature: function (feature, layer) { + if (feature.geometry.type === "Polygon" || feature.geometry.type === "Point" && feature.properties.hasOwnProperty("icon")) { + var text = "" + feature.properties.name + ""; + if (feature.properties.hasOwnProperty("description")) { + text = text + "
    " + feature.properties.description; + } + layer.bindPopup(text); + } + }, + pointToLayer: function (geoJsonPoint, latlng) { + if (geoJsonPoint.properties.hasOwnProperty("description") && geoJsonPoint.properties["description"] === "snumber" && !geoJsonPoint.properties.hasOwnProperty("icon")) { + var snumbericon = L.marker(latlng, { + icon: new L.DivIcon({ + className: "snumber-icon", + html: geoJsonPoint.properties["name"], + iconSize: [8, 8] + }) + }); + MapObject._SpecialMarkers.push(snumbericon); + return snumbericon; + } else if (geoJsonPoint.properties.hasOwnProperty("description") && geoJsonPoint.properties["description"] === "coord" && !geoJsonPoint.properties.hasOwnProperty("icon")) { + var coordicon = L.marker(latlng, { + icon: new L.DivIcon({ + className: "coord-icon", + html: geoJsonPoint.properties["name"] + }) + }); + MapObject._SpecialMarkers.push(coordicon); + return coordicon; + } else if (geoJsonPoint.properties.hasOwnProperty("icon")) { + return L.marker(latlng, { icon: L.icon({ iconUrl: "css/icons/cctv.png", iconSize: [32, 32] }) }); + } + } + }).addTo(this.Map); + } + }, + _SetupMapZoomFontsize: function () { + this.Map.on('zoomend', function () { + var currentZoom = MapObject.Map.getZoom(); + if (currentZoom < 14) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "0px"; + elem._icon.style.marginLeft = "0px"; + elem._icon.style.marginTop = "0px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "0px"; + } + }); + } else if (currentZoom === 14) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "0px"; + elem._icon.style.marginLeft = "0px"; + elem._icon.style.marginTop = "0px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "6px"; + } + }); + } else if (currentZoom === 15) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "0px"; + elem._icon.style.marginLeft = "0px"; + elem._icon.style.marginTop = "0px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "9px"; + } + }); + } else if (currentZoom === 16) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "5px"; + elem._icon.style.marginLeft = "-4px"; + elem._icon.style.marginTop = "-4px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "13px"; + } + }); + } else if (currentZoom === 17) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "5px"; + elem._icon.style.marginLeft = "-4px"; + elem._icon.style.marginTop = "-4px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "16px"; + } + }); + } else if (currentZoom === 18) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "8px"; + elem._icon.style.marginLeft = "-5px"; + elem._icon.style.marginTop = "-6px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "25px"; + } + }); + } else if (currentZoom === 19) { + MapObject._SpecialMarkers.forEach(function (elem, index) { + if (elem.feature.properties["description"] === "snumber") { + elem._icon.style.fontSize = "14px"; + elem._icon.style.marginLeft = "-8px"; + elem._icon.style.marginTop = "-11px"; + } + if (elem.feature.properties["description"] === "coord") { + elem._icon.style.fontSize = "45px"; + } + }); } }); + }, + _SetupClickHandler: function () { + this.Map.on("click", this._HidePanel); + }, + _HidePanel: function (e) { + MenuObject.ShowHidePanel(null); + }, + JumpTo: function (lat, lon) { + this.Map.flyTo([lat, lon], 19); } -}); - -mymap.on("click", hidePanel); - -function hidePanel(e) { - showHidePanel(null); -} \ No newline at end of file +}.Start(); \ No newline at end of file diff --git a/Lora-Map/resources/js/marker.js b/Lora-Map/resources/js/marker.js index dea8915..44dd496 100644 --- a/Lora-Map/resources/js/marker.js +++ b/Lora-Map/resources/js/marker.js @@ -1,27 +1,18 @@ -setInterval(datarunner, 1000); -function datarunner() { - var loc = new XMLHttpRequest(); - loc.onreadystatechange = parseAjaxLoc; - loc.open("GET", "/loc", true); - loc.send(); - - var panic = new XMLHttpRequest(); - panic.onreadystatechange = parseAjaxPanic; - panic.open("GET", "/panic", true); - panic.send(); -} - -var markers = {}; -var serverLocation = {}; -//https://leafletjs.com/reference-1.4.0.html#marker -function parseAjaxLoc() { - if (this.readyState === 4 && this.status === 200) { - serverLocation = JSON.parse(this.responseText); - for (var key in serverLocation) { - if (serverLocation.hasOwnProperty(key)) { - var positionItem = serverLocation[key]; +var MarkerObject = { + _Markers: {}, + PanicData: {}, + LocationData: {}, + VisibleMarkers: {}, + Start: function () { + return this; + }, + _ParseAJAXLoc: function (serverLocation) { + this.LocationData = serverLocation; + for (var key in this.LocationData) { + if (this.LocationData.hasOwnProperty(key)) { + var positionItem = this.LocationData[key]; if (positionItem['Latitude'] !== 0 || positionItem['Longitude'] !== 0) { - if (!markers.hasOwnProperty(key)) { + if (!this._Markers.hasOwnProperty(key)) { var marker = null; if (positionItem['Icon'] === null) { marker = L.marker([positionItem['Latitude'], positionItem['Longitude']], { 'title': positionItem['Name'] }); @@ -34,67 +25,80 @@ function parseAjaxLoc() { }); marker = L.marker([positionItem['Latitude'], positionItem['Longitude']], { 'title': positionItem['Name'], 'icon': myIcon }); } - markers[key] = marker.addTo(mymap).on("click", showMarkerInfo, key); + this._Markers[key] = marker.addTo(MapObject.Map).on("click", function () { MenuObject.statusToDevice = this; MenuObject.ShowHidePanel("pannels_info"); }, key); } else { - markers[key].setLatLng([positionItem['Latitude'], positionItem['Longitude']]); + this._Markers[key].setLatLng([positionItem['Latitude'], positionItem['Longitude']]); if (positionItem['Icon'] !== null) { - if (markers[key]._icon.children.length === 0) { - markers[key].setIcon(L.divIcon({ + if (this._Markers[key]._icon.children.length === 0) { + this._Markers[key].setIcon(L.divIcon({ className: 'pos-marker', iconSize: [56, 80], iconAnchor: [0, 80], html: '' })); - } else if (markers[key]._icon.children[0].hasAttribute("src")) { - var old = markers[key]._icon.children[0]["src"].substring(markers[key]._icon.children[0]["src"].indexOf("/", 7) + 1); + } else if (this._Markers[key]._icon.children[0].hasAttribute("src")) { + var old = this._Markers[key]._icon.children[0]["src"].substring(this._Markers[key]._icon.children[0]["src"].indexOf("/", 7) + 1); if (old !== positionItem['Icon']) { - markers[key]._icon.children[0]["src"] = positionItem['Icon']; + this._Markers[key]._icon.children[0]["src"] = positionItem['Icon']; } } } else { - if (markers[key]._icon.children.length === 1 && markers[key]._icon.children[0].hasAttribute("src")) { - markers[key].removeFrom(mymap); - markers[key] = L.marker([positionItem['Latitude'], positionItem['Longitude']], { 'title': positionItem['Name'] }).addTo(mymap).on("click", showMarkerInfo, key); + if (this._Markers[key]._icon.children.length === 1 && this._Markers[key]._icon.children[0].hasAttribute("src")) { + this._Markers[key].removeFrom(MapObject.Map); + this._Markers[key] = L.marker([positionItem['Latitude'], positionItem['Longitude']], { 'title': positionItem['Name'] }).addTo(MapObject.Map).on("click", function () { MenuObject.statusToDevice = this; MenuObject.ShowHidePanel("pannels_info"); }, key); } } } - var lasttime = timeCalculation(positionItem['Recievedtime'], "diffraw"); - if (lasttime <= 5 * 60) { - markers[key]._icon.style.opacity = 1; - } else if (lasttime > 5 * 60 && lasttime <= 15 * 60) { - markers[key]._icon.style.opacity = 0.9 - (lasttime - 5 * 60) / (15 * 60 - 5 * 60) * (0.9 - 0.7); - } else if (lasttime > 15 * 60 && lasttime <= 30 * 60) { - markers[key]._icon.style.opacity = 0.7 - (lasttime - 15 * 60) / (30 * 60 - 15 * 60) * (0.7 - 0.5); - } else if (lasttime > 30 * 60 && lasttime <= 60 * 60) { - markers[key]._icon.style.opacity = 0.5 - (lasttime - 30 * 60) / (30 * 60 - 30 * 60) * (0.5 - 0.25); - } else if (lasttime > 60 * 60) { - markers[key]._icon.style.opacity = 0.25; + if (positionItem.Group !== null && this.VisibleMarkers.hasOwnProperty("___isset") && !this.VisibleMarkers.hasOwnProperty(positionItem.Group)) { + this._Markers[key]._icon.style.opacity = 0; + } else { + var lasttime = FunctionsObject.TimeCalculation(positionItem['Recievedtime'], "diffraw"); + if (lasttime <= 5 * 60) { + this._Markers[key]._icon.style.opacity = 1; + } else if (lasttime > 5 * 60 && lasttime <= 15 * 60) { + this._Markers[key]._icon.style.opacity = 0.9 - (lasttime - 5 * 60) / (15 * 60 - 5 * 60) * (0.9 - 0.7); + } else if (lasttime > 15 * 60 && lasttime <= 30 * 60) { + this._Markers[key]._icon.style.opacity = 0.7 - (lasttime - 15 * 60) / (30 * 60 - 15 * 60) * (0.7 - 0.5); + } else if (lasttime > 30 * 60 && lasttime <= 60 * 60) { + this._Markers[key]._icon.style.opacity = 0.5 - (lasttime - 30 * 60) / (30 * 60 - 30 * 60) * (0.5 - 0.25); + } else if (lasttime > 60 * 60) { + this._Markers[key]._icon.style.opacity = 0.25; + } } } } } - updateStatus(); - update_pannels_info(); - } -} - -var serverPanic = {}; -function parseAjaxPanic() { - if (this.readyState === 4 && this.status === 200) { - serverPanic = JSON.parse(this.responseText); - for (var id in serverPanic) { - if (serverPanic.hasOwnProperty(id)) { - var alertItem = serverPanic[id]; - if (markers.hasOwnProperty(id)) { - var marker = markers[id]; - if (timeCalculation(alertItem["Recievedtime"], "diffraw") <= 10 && marker._icon.className.indexOf(" marker-alert") === -1) { - marker._icon.className += " marker-alert"; - showMarkerInfoPerId(id); - } else if (timeCalculation(alertItem["Recievedtime"], "diffraw") > 10 && marker._icon.className.indexOf(" marker-alert") !== -1) { - marker._icon.className = marker._icon.className.replace(" marker-alert", ""); + MenuObject.UpdateStatus(); + MenuObject._Update_pannels_info(); + }, + _ParseAJAXPanic: function (serverPanic) { + this.PanicData = serverPanic; + for (var id in this.PanicData) { + if (this.PanicData.hasOwnProperty(id)) { + var alertItem = this.PanicData[id]; + if (this._Markers.hasOwnProperty(id)) { + var marker = this._Markers[id]; + if (!(this.LocationData[id].Group !== null && this.VisibleMarkers.hasOwnProperty("___isset") && !this.VisibleMarkers.hasOwnProperty(this.LocationData[id].Group))) { + if (FunctionsObject.TimeCalculation(alertItem["Recievedtime"], "diffraw") <= 10 && marker._icon.className.indexOf(" marker-alert") === -1) { + marker._icon.className += " marker-alert"; + MenuObject.ShowMarkerInfoPerId(id); + } else if (FunctionsObject.TimeCalculation(alertItem["Recievedtime"], "diffraw") > 10 && marker._icon.className.indexOf(" marker-alert") !== -1) { + marker._icon.className = marker._icon.className.replace(" marker-alert", ""); + } } } } } + }, + ChangeFilter: function (select) { + this.VisibleMarkers = {}; + if (select.selectedOptions.length > 0) { + for (var i = 0; i < select.selectedOptions.length; i++) { + this.VisibleMarkers[select.selectedOptions[i].value] = true; + } + this.VisibleMarkers["no"] = true; + this.VisibleMarkers["___isset"] = true; + } + this._ParseAJAXLoc(this.LocationData); } -} \ No newline at end of file +}.Start(); \ No newline at end of file diff --git a/Lora-Map/resources/js/menu.js b/Lora-Map/resources/js/menu.js index 871124d..62a2249 100644 --- a/Lora-Map/resources/js/menu.js +++ b/Lora-Map/resources/js/menu.js @@ -1,175 +1,219 @@ -var visiblePanel = null; -function showHidePanel(name) { - if (visiblePanel === null && name !== null) { - document.getElementById("pannels").style.display = "block"; - document.getElementById(name).style.display = "block"; - visiblePanel = name; - if (typeof window["update_" + name] === "function") { - window["update_" + name](); - } - } else if (visiblePanel === name && name !== "pannels_info" || name === null) { - document.getElementById("pannels").style.display = "none"; - if (visiblePanel !== null) { - document.getElementById(visiblePanel).style.display = "none"; - } - visiblePanel = null; - } else { - document.getElementById(visiblePanel).style.display = "none"; - document.getElementById(name).style.display = "block"; - visiblePanel = name; - if (typeof window["update_" + name] === "function") { - window["update_" + name](); - } - } -} - -var statusToDevice = null; -function showMarkerInfo(e) { - statusToDevice = this; - showHidePanel("pannels_info"); -} - -function showMarkerInfoPerId(id) { - statusToDevice = id; - showHidePanel("pannels_info"); -} - -function showMarkerInfoMenu() { - statusToDevice = this.getAttribute("rel"); - showHidePanel("pannels_info"); -} - -function update_pannels_info() { - document.getElementById("pannels_info").innerHTML = ""; - if (serverLocation.hasOwnProperty(statusToDevice)) { - var positionItem = serverLocation[statusToDevice]; - var html = "
    Name: " + positionItem["Name"] + "
    "; - html += "
    Batterie: " + positionItem["Battery"] + "V
    "; - if (positionItem["Fix"]) { - html += "
    GPS-Empfang
    "; +var MenuObject = { + statusToDevice: null, + _visiblePanel: null, + _overviewStatus: new Array(), + Start: function () { + return this; + }, + ShowHidePanel: function (name) { + if (this._visiblePanel === null && name !== null) { + document.getElementById("pannels").style.display = "block"; + document.getElementById(name).style.display = "block"; + this._visiblePanel = name; + if (typeof MenuObject["_Update_" + name] === "function") { + MenuObject["_Update_" + name](); + } + } else if (this._visiblePanel === name && name !== "pannels_info" || name === null) { + document.getElementById("pannels").style.display = "none"; + if (this._visiblePanel !== null) { + document.getElementById(this._visiblePanel).style.display = "none"; + } + this._visiblePanel = null; } else { - html += "
    kein GPS-Empfang
    "; + document.getElementById(this._visiblePanel).style.display = "none"; + document.getElementById(name).style.display = "block"; + this._visiblePanel = name; + if (typeof MenuObject["_Update_" + name] === "function") { + MenuObject["_Update_" + name](); + } } - html += "
    " + positionItem["UTM"]["Base"] + " " + positionItem["UTM"]["FieldWidth"] + "" + positionItem["UTM"]["Width"] + " " + positionItem["UTM"]["FieldHeight"] + "" + positionItem["UTM"]["Height"] + "
    "; - html += "
    Höhe: " + positionItem["Height"].toFixed(1) + " m
    "; - html += "
    HDOP: " + positionItem["Hdop"].toFixed(1) + "
    "; - html += "
    Dezimal: " + positionItem["Latitude"].toFixed(5) + ", " + positionItem["Longitude"].toFixed(5) + "
    "; - html += "
    Letzter Wert: Vor: " + timeCalculation(positionItem["Lastgpspostime"], "difftext") + "
    "; - html += "
    Update: " + timeCalculation(positionItem["Recievedtime"], "str") + "
    Vor: " + timeCalculation(positionItem["Recievedtime"], "difftext") + "
    "; - html += "
    RSSI: " + positionItem["Rssi"] + ", SNR: " + positionItem["Snr"] + "
    "; - if (serverPanic.hasOwnProperty(statusToDevice)) { - var panicData = serverPanic[statusToDevice]; - if (panicData["ButtonPressed"].length > 0) { - html += "
    Alerts:"; - for (var i = 0; i < panicData["ButtonPressed"].length; i++) { - html += "" + timeCalculation(panicData["ButtonPressed"][i], "str")+" (vor " + timeCalculation(panicData["ButtonPressed"][i],"difftext")+")"; + }, + ShowMarkerInfoPerId: function (id) { + this.statusToDevice = id; + this.ShowHidePanel("pannels_info"); + }, + UpdateStatus: function () { + for (var id in MarkerObject.LocationData) { + if (MarkerObject.LocationData.hasOwnProperty(id)) { + var positionItem = MarkerObject.LocationData[id]; + if (typeof this._overviewStatus[id] === "undefined") { + this._overviewStatus[id] = this._CreateOverviewElement(positionItem, id); + document.getElementById("pannels_pos").appendChild(this._overviewStatus[id]); } - html += "
    "; + if (positionItem.Group !== null && MarkerObject.VisibleMarkers.hasOwnProperty("___isset") && !MarkerObject.VisibleMarkers.hasOwnProperty(positionItem.Group)) { + if (this._overviewStatus[id].className.indexOf("filter") === -1) { + this._overviewStatus[id].className = "item filter"; + } + } else { + if (this._overviewStatus[id].className.indexOf("filter") !== -1) { + this._overviewStatus[id].className = "item"; + } + } + this._UpdateOverviewElement(positionItem, id); } } - document.getElementById("pannels_info").innerHTML = html; - } -} - -var overviewStatus = new Array(); - -function updateStatus() { - for (var id in serverLocation) { - if (serverLocation.hasOwnProperty(id)) { - var positionItem = serverLocation[id]; - if (typeof overviewStatus[id] === "undefined") { - overviewStatus[id] = createOverviewElement(positionItem, id); - document.getElementById("pannels_pos").appendChild(overviewStatus[id]); - } - updateOverviewElement(positionItem, id); + }, + _UpdateOverviewElement: function (positionItem, id) { + if (positionItem["Batterysimple"] === 0) { + document.getElementById("overview-color-id-" + id).style.backgroundColor = "red"; + } else if (positionItem["Batterysimple"] === 1 || positionItem["Batterysimple"] === 2) { + document.getElementById("overview-color-id-" + id).style.backgroundColor = "yellow"; + } else if (positionItem["Batterysimple"] === 3 || positionItem["Batterysimple"] === 4) { + document.getElementById("overview-color-id-" + id).style.backgroundColor = "green"; } - } -} - -function updateOverviewElement(positionItem, id) { - if (positionItem["Batterysimple"] === 0) { - document.getElementById("overview-color-id-" + id).style.backgroundColor = "red"; - } else if (positionItem["Batterysimple"] === 1 || positionItem["Batterysimple"] === 2) { - document.getElementById("overview-color-id-" + id).style.backgroundColor = "yellow"; - } else if (positionItem["Batterysimple"] === 3 || positionItem["Batterysimple"] === 4) { - document.getElementById("overview-color-id-" + id).style.backgroundColor = "green"; - } - document.getElementById("overview-name-id-" + id).innerText = positionItem["Name"]; - document.getElementById("overview-akkuimg-id-" + id).src = "icons/akku/" + positionItem["Batterysimple"] + "-4.png"; - if (positionItem["Fix"]) { - document.getElementById("overview-gps-id-" + id).innerText = "GPS-Empfang"; - document.getElementById("overview-gps-id-" + id).style.color = "green"; - } else { - document.getElementById("overview-gps-id-" + id).innerText = "kein GPS-Empfang"; - document.getElementById("overview-gps-id-" + id).style.color = "red"; - } - document.getElementById("overview-update-id-" + id).innerText = "Letzte Werte: vor " + timeCalculation(positionItem["Recievedtime"], "difftext"); - if (positionItem['Icon'] === null) { - var icon = document.getElementById("overview-icon-id-" + id); - if (icon.children[0].hasAttribute("rel")) { - document.getElementById("overview-icon-id-" + id).innerHTML = ""; + document.getElementById("overview-name-id-" + id).innerText = positionItem["Name"]; + document.getElementById("overview-akkuimg-id-" + id).src = "icons/akku/" + positionItem["Batterysimple"] + "-4.png"; + if (positionItem["Fix"]) { + document.getElementById("overview-gps-id-" + id).innerText = "GPS-Empfang"; + document.getElementById("overview-gps-id-" + id).style.color = "green"; + } else { + document.getElementById("overview-gps-id-" + id).innerText = "kein GPS-Empfang"; + document.getElementById("overview-gps-id-" + id).style.color = "red"; } - } else { - if (document.getElementById("overview-icon-id-" + id).children[0].hasAttribute("src")) { - if (document.getElementById("overview-icon-id-" + id).children[0]["src"].substring(document.getElementById("overview-icon-id-" + id).children[0]["src"].indexOf("/", 7) + 1) !== positionItem['Icon'] + "&marker-bg=hidden") { - document.getElementById("overview-icon-id-" + id).children[0]["src"] = positionItem['Icon'] + "&marker-bg=hidden"; + document.getElementById("overview-update-id-" + id).innerText = "Letzte Werte: vor " + FunctionsObject.TimeCalculation(positionItem["Recievedtime"], "difftext"); + if (positionItem['Icon'] === null) { + var icon = document.getElementById("overview-icon-id-" + id); + if (icon.children[0].hasAttribute("rel")) { + document.getElementById("overview-icon-id-" + id).innerHTML = ""; } } else { - document.getElementById("overview-icon-id-" + id).innerHTML = ""; + if (document.getElementById("overview-icon-id-" + id).children[0].hasAttribute("src")) { + if (document.getElementById("overview-icon-id-" + id).children[0]["src"].substring(document.getElementById("overview-icon-id-" + id).children[0]["src"].indexOf("/", 7) + 1) !== positionItem['Icon'] + "&marker-bg=hidden") { + document.getElementById("overview-icon-id-" + id).children[0]["src"] = positionItem['Icon'] + "&marker-bg=hidden"; + } + } else { + document.getElementById("overview-icon-id-" + id).innerHTML = ""; + } } + }, + _CreateOverviewElement: function (positionItem, id) { + var divItem = document.createElement("div"); + divItem.className = "item"; + divItem.onclick = function showMarkerInfoMenu() { + MenuObject.statusToDevice = this.getAttribute("rel"); + MenuObject.ShowHidePanel("pannels_info"); + }; + divItem.setAttribute("rel", id); + divItem.innerHTML = ""; + if (positionItem['Icon'] !== null) { + divItem.innerHTML += ""; + } else { + divItem.innerHTML += ""; + } + divItem.innerHTML += "
    " + + "" + + "" + + "
    "; + divItem.innerHTML += "
    kein GPS-Empfang
    "; + divItem.innerHTML += "
    Letzte Werte: vor " + FunctionsObject.TimeCalculation(positionItem["Recievedtime"], "difftext") + "
    "; + return divItem; + }, + _ParseAJAXPannelAdmin: function (loggedin) { + if (!loggedin) { + var html = "

    Login to Adminpannel

    "; + html += "
    Username:
    "; + html += "
    Passwort:
    "; + html += "
    "; + document.getElementById("pannels_admin").innerHTML = html; + } else { + document.getElementById("pannels_admin").innerHTML = "Adminpannel"; + } + }, + SubmitLoginForm: function () { + var adminlogin = new XMLHttpRequest(); + adminlogin.onreadystatechange = function () { + if (adminlogin.readyState === 4 && adminlogin.status === 200) { + MenuObject._Update_pannels_admin(); + } + }; + adminlogin.open("POST", "/admin/login", true); + adminlogin.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + adminlogin.send("user=" + encodeURI(document.getElementById("pannels_admin_name").value) + "&pass=" + encodeURI(document.getElementById("pannels_admin_pass").value)); + }, + _Update_pannels_info: function () { + document.getElementById("pannels_info").innerHTML = ""; + if (MarkerObject.LocationData.hasOwnProperty(this.statusToDevice)) { + var positionItem = MarkerObject.LocationData[this.statusToDevice]; + var html = "
    Name: " + positionItem["Name"] + "
    "; + html += "
    Batterie: " + positionItem["Battery"] + "V
    "; + if (positionItem["Fix"]) { + html += "
    GPS-Empfang
    "; + } else { + html += "
    kein GPS-Empfang
    "; + } + html += "
    " + positionItem["UTM"]["Base"] + " " + positionItem["UTM"]["FieldWidth"] + "" + positionItem["UTM"]["Width"] + " " + positionItem["UTM"]["FieldHeight"] + "" + positionItem["UTM"]["Height"] + "
    "; + html += "
    Höhe: " + positionItem["Height"].toFixed(1) + " m
    "; + html += "
    HDOP: " + positionItem["Hdop"].toFixed(1) + "
    "; + html += "
    Dezimal: " + positionItem["Latitude"].toFixed(5) + ", " + positionItem["Longitude"].toFixed(5) + "
    "; + html += "
    Letzter Wert: Vor: " + FunctionsObject.TimeCalculation(positionItem["Lastgpspostime"], "difftext") + "
    "; + html += "
    Update: " + FunctionsObject.TimeCalculation(positionItem["Recievedtime"], "str") + "
    Vor: " + FunctionsObject.TimeCalculation(positionItem["Recievedtime"], "difftext") + "
    "; + html += "
    RSSI: " + positionItem["Rssi"] + ", SNR: " + positionItem["Snr"] + "
    "; + if (MarkerObject.PanicData.hasOwnProperty(this.statusToDevice)) { + var panicData = MarkerObject.PanicData[this.statusToDevice]; + if (panicData["ButtonPressed"].length > 0) { + html += "
    Alerts:"; + for (var i = 0; i < panicData["ButtonPressed"].length; i++) { + html += "" + FunctionsObject.TimeCalculation(panicData["ButtonPressed"][i], "str") + " (vor " + FunctionsObject.TimeCalculation(panicData["ButtonPressed"][i], "difftext") + ")"; + } + html += "
    "; + } + } + document.getElementById("pannels_info").innerHTML = html; + } + }, + _Update_pannels_admin: function () { + var testadmin = new XMLHttpRequest(); + testadmin.onreadystatechange = function () { + if (testadmin.readyState === 4 && testadmin.status === 403) { + MenuObject._ParseAJAXPannelAdmin(false); + } else if (testadmin.readyState === 4 && testadmin.status === 200) { + MenuObject._ParseAJAXPannelAdmin(true); + } + }; + testadmin.open("GET", "/admin", true); + testadmin.send(); + }, + _ParseAJAXWeatherAlerts: function (json) { + if (json.length > 0) { + var html = ""; + for (var i = 0; i < json.length; i++) { + var walert = json[i]; + html += "
    " + + "" + walert.Headline + "" + + "" + walert.Location + "" + + "" + walert.Body + (walert.Instructions !== "" ? "

    " + walert.Instructions : "") + "
    " + + "Von: "; + if (FunctionsObject.TimeCalculation(walert.From, "diffraw") < 0) { + html += "in " + FunctionsObject.TimeCalculation(walert.From, "difftextn"); + } else { + html += "vor " + FunctionsObject.TimeCalculation(walert.From, "difftext"); + } + html += " Bis: in " + FunctionsObject.TimeCalculation(walert.To, "difftextn") + "" + + "
    "; + } + document.getElementById("pannels_weather").innerHTML = html; + document.getElementById("menucol_weather_icon").className = "weather ac"; + } else { + document.getElementById("pannels_weather").innerHTML = "

    Keine Gefahren

    "; + document.getElementById("menucol_weather_icon").className = "weather"; + } + }, + SearchInGeoJson: function (searchtext) { + var html = ""; + if (MapObject.GeoJson.features.length > 0) { + for (var i = 0; i < MapObject.GeoJson.features.length; i++) { + var feature = MapObject.GeoJson.features[i]; + if (feature.properties.name.indexOf(searchtext) !== -1 && feature.geometry.type === "Polygon") { + if (feature.geometry.coordinates.length > 0 && feature.geometry.coordinates[0].length > 0 && feature.geometry.coordinates[0][0].length > 0) { + html += "
    " + + "" + feature.properties.name + "" + + "" + (typeof feature.properties.description !== "undefined" ? feature.properties.description : "") + "" + + "" + + "
    "; + } + } + } + } + document.getElementById("search_results").innerHTML = html; } -} - -function createOverviewElement(positionItem, id) { - var divItem = document.createElement("div"); - divItem.className = "item"; - divItem.onclick = showMarkerInfoMenu; - divItem.setAttribute("rel", id); - divItem.innerHTML = ""; - if (positionItem['Icon'] !== null) { - divItem.innerHTML += ""; - } else { - divItem.innerHTML += ""; - } - divItem.innerHTML += "
    " + - "" + - "" + - "
    "; - divItem.innerHTML += "
    kein GPS-Empfang
    "; - divItem.innerHTML += "
    Letzte Werte: vor " + timeCalculation(positionItem["Recievedtime"], "difftext") + "
    "; - return divItem; -} - - -function update_pannels_admin() { - var testadmin = new XMLHttpRequest(); - testadmin.onreadystatechange = parseAjaxPannelAdmin; - testadmin.open("GET", "/admin", true); - testadmin.send(); -} - -function parseAjaxPannelAdmin() { - if (this.readyState === 4 && this.status === 403) { - var html = "

    Login to Adminpannel

    "; - html += "
    Username:
    "; - html += "
    Passwort:
    "; - html += "
    "; - document.getElementById("pannels_admin").innerHTML = html; - } else if (this.readyState === 4 && this.status === 200) { - document.getElementById("pannels_admin").innerHTML = "Adminpannel"; - } -} - -function submitloginform() { - var adminlogin = new XMLHttpRequest(); - adminlogin.onreadystatechange = parseAjaxLogin; - adminlogin.open("POST", "/admin/login", true); - adminlogin.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - adminlogin.send("user=" + encodeURI(document.getElementById("pannels_admin_name").value) + "&pass=" + encodeURI(document.getElementById("pannels_admin_pass").value)); -} - -function parseAjaxLogin() { - if (this.readyState === 4 && this.status === 200) { - update_pannels_admin(); - } -} \ No newline at end of file +}.Start(); \ No newline at end of file diff --git a/Lora-Map/resources/js/overlays.js b/Lora-Map/resources/js/overlays.js index 9aed95c..f3eceae 100644 --- a/Lora-Map/resources/js/overlays.js +++ b/Lora-Map/resources/js/overlays.js @@ -1,18 +1,8 @@ -setInterval(overlayrunner, 1000); -function overlayrunner() { - var ccount = new XMLHttpRequest(); - ccount.onreadystatechange = parseAjaxCount; - ccount.open("GET", "/cameracount", true); - ccount.send(); - var cdensity = new XMLHttpRequest(); - cdensity.onreadystatechange = parseAjaxDensity; - cdensity.open("GET", "/crowdcount", true); - cdensity.send(); -} - -function parseAjaxCount() { - if (this.readyState === 4 && this.status === 200) { - var cameracounts = JSON.parse(this.responseText); +var OverlayObject = { + Start: function () { + return this; + }, + _ParseAJAXCount: function (cameracounts) { var camerastext = ""; for (var cameraid in cameracounts) { if (cameracounts.hasOwnProperty(cameraid)) { @@ -27,12 +17,8 @@ function parseAjaxCount() { } } document.getElementById("cameracount").innerHTML = camerastext; - } -} - -function parseAjaxDensity() { - if (this.readyState === 4 && this.status === 200) { - var cameradensy = JSON.parse(this.responseText); + }, + _ParseAJAXDensity: function (cameradensy) { var densystext = ""; for (var densyid in cameradensy) { if (cameradensy.hasOwnProperty(densyid)) { @@ -46,4 +32,4 @@ function parseAjaxDensity() { } document.getElementById("crwoddensy").innerHTML = densystext; } -} \ No newline at end of file +}.Start(); \ No newline at end of file