diff --git a/Lora-Map/Lora-Map.csproj b/Lora-Map/Lora-Map.csproj index f368f5e..00417d5 100644 --- a/Lora-Map/Lora-Map.csproj +++ b/Lora-Map/Lora-Map.csproj @@ -68,7 +68,6 @@ - PreserveNewest @@ -89,6 +88,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -138,7 +140,9 @@ PreserveNewest - + + PreserveNewest + PreserveNewest diff --git a/Lora-Map/Properties/AssemblyInfo.cs b/Lora-Map/Properties/AssemblyInfo.cs index e4a70a7..36c65b8 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 - 15.04.2019")] +[assembly: AssemblyCopyright("Copyright © 2018 - 21.04.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.0")] -[assembly: AssemblyFileVersion("1.2.0")] +[assembly: AssemblyVersion("1.2.1")] +[assembly: AssemblyFileVersion("1.2.1")] /* * 1.1.1 Add Debian package config @@ -45,4 +45,5 @@ using System.Runtime.InteropServices; * 1.1.6 #5 Create admin area * 1.1.7 #8 Editor for Names * 1.2.0 #4 Possible to Ex and Import Setting +* 1.2.1 #6 Load the map from the Device */ diff --git a/Lora-Map/Server.cs b/Lora-Map/Server.cs index 118d323..f41be46 100644 --- a/Lora-Map/Server.cs +++ b/Lora-Map/Server.cs @@ -12,8 +12,7 @@ using Fraunhofer.Fit.IoT.LoraMap.Model.Admin; using LitJson; namespace Fraunhofer.Fit.IoT.LoraMap { - class Server : Webserver - { + class Server : Webserver { private readonly SortedDictionary positions = new SortedDictionary(); private readonly SortedDictionary alarms = new SortedDictionary(); private JsonData marker; @@ -49,9 +48,9 @@ namespace Fraunhofer.Fit.IoT.LoraMap { protected override void Backend_MessageIncomming(Object sender, BackendEvent e) { try { JsonData d = JsonMapper.ToObject(e.Message); - if (PositionItem.CheckJson(d) && ((String)e.From).Contains("lora/data")) { + if(PositionItem.CheckJson(d) && ((String)e.From).Contains("lora/data")) { String name = PositionItem.GetId(d); - if (this.positions.ContainsKey(name)) { + if(this.positions.ContainsKey(name)) { this.positions[name].Update(d); } else { this.positions.Add(name, new PositionItem(d, this.marker)); @@ -66,20 +65,20 @@ namespace Fraunhofer.Fit.IoT.LoraMap { } Console.WriteLine("PANIC erhalten!"); } - } catch (Exception ex) { + } catch(Exception ex) { Helper.WriteError(ex.Message); } } protected override Boolean SendWebserverResponse(HttpListenerContext cont) { try { - if (cont.Request.Url.PathAndQuery.StartsWith("/loc")) { + 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("?")) { + } 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"; @@ -92,13 +91,52 @@ namespace Fraunhofer.Fit.IoT.LoraMap { return SendJsonResponse(new Dictionary() { { "utc", DateTime.UtcNow } }, cont); } 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/")) { + return SendFileResponse(cont, "resources", false); } - } catch (Exception e) { + } catch(Exception e) { Helper.WriteError("500 - " + e.Message); cont.Response.StatusCode = 500; return false; } return SendFileResponse(cont); } + + private Dictionary> FindMapLayer(HttpListenerRequest request) { + Dictionary> ret = new Dictionary> { + { "online", new Dictionary() { + { "title", "Online Map" }, + { "url", "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" }, + { "attribution", "© OpenStreetMap contributors" }, + { "minZoom", 1 }, + { "maxZoom", 18 } + } } + }; + if(Directory.Exists("resources" + Path.DirectorySeparatorChar + "maps")) { + String[] dirs = Directory.GetDirectories("resources" + Path.DirectorySeparatorChar + "maps"); + foreach(String dir in dirs) { + if(File.Exists(dir + Path.DirectorySeparatorChar + "tiles.json")) { + try { + JsonData map = JsonMapper.ToObject(File.ReadAllText(dir + Path.DirectorySeparatorChar + "tiles.json")); + Dictionary entry = new Dictionary { + { "title", (String)map["name"] }, + { "url", (String)map["tiles"][0] }, + { "attribution", (String)map["attribution"] }, + { "minZoom", (Int32)map["minzoom"] }, + { "maxZoom", (Int32)map["maxzoom"] }, + { "bounds", new Dictionary() { + { "corner1", new Double[] { (Double)map["bounds"][0], (Double)map["bounds"][1] } }, + { "corner2", new Double[] { (Double)map["bounds"][2], (Double)map["bounds"][3] } } + } } + }; + ret.Add(dir.Substring(("resources" + Path.DirectorySeparatorChar + "maps").Length+1), entry); + } catch { } + } + } + } + return ret; + } } } \ No newline at end of file diff --git a/Lora-Map/resources/css/icons/failtile.png b/Lora-Map/resources/css/icons/failtile.png new file mode 100644 index 0000000..4e1fdce Binary files /dev/null and b/Lora-Map/resources/css/icons/failtile.png differ diff --git a/Lora-Map/resources/js/map.js b/Lora-Map/resources/js/map.js index 8744612..bdec935 100644 --- a/Lora-Map/resources/js/map.js +++ b/Lora-Map/resources/js/map.js @@ -1,8 +1,53 @@ var mymap = L.map('bigmap').setView(["{%START_LOCATION%}"], 14); -L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© OpenStreetMap contributors' -}).addTo(mymap); +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++; + } + 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" + }); + } + } + L.control.layers(baseMaps).addTo(mymap); + } + } + }; + layergetter.open("GET", "http://{%REQUEST_URL_HOST%}/getlayer", true); + layergetter.send(); +} mymap.on("click", hidePanel);