using System; using System.Text; using System.Threading; using System.Net; using System.IO; using System.Drawing; namespace tileserver { public class ControllerHTTP { private Thread thread = null; private MetaReader metaReader = new MetaReader(); private HttpListener weblistener = null; public ControllerHTTP(int port) { try { weblistener = new HttpListener(); weblistener.Prefixes.Add("http://*:" + port + "/"); // netsh http add urlacl url = "http://*:8080/" user = todos weblistener.Prefixes.Add("https://*:" + (port + 1) + "/"); // netsh http add urlacl url = "http://*:8080/" user = todos // Console.WriteLine("http://*:" + port + "/"); weblistener.Start(); thread = new Thread(work); thread.Start(); } catch (Exception e) { Console.WriteLine(e.Message); } } public void work() { HttpListenerContext context = null; HttpListenerRequest request = null; HttpListenerResponse response = null; while (true) { try { context = weblistener.GetContext(); // Block until a connection comes in request = context.Request; response = context.Response; String path = request.Url.LocalPath; String function = getString(request, "request"); if (function.Equals("GetMap", StringComparison.InvariantCultureIgnoreCase)) { byte[] data = GetMap(request, path); response.StatusCode = 200; response.SendChunked = true; var output = response.OutputStream; output.Write(data, 0, data.Length); output.Close(); } else { throw new Exception("501, Request not supported. Available requests (GetMap)"); } } catch (ControllerHTTPException e) { sendError(response, e); } catch (Exception e) { sendError(response, new ControllerHTTPException(400, e.Message)); } } } private void sendError(HttpListenerResponse response, ControllerHTTPException exception) { try { string responseString = "" + exception.getMessage() + ""; var buffer = System.Text.Encoding.UTF8.GetBytes(responseString); response.ContentLength64 = buffer.Length; var output = response.OutputStream; output.Write(buffer, 0, buffer.Length); output.Close(); } catch (Exception) { } } private byte[] GetMap(HttpListenerRequest request, String path) { String service = getString(request, "service"); { if (service.Equals("WMS", StringComparison.InvariantCultureIgnoreCase) == false) { throw new Exception("501, Service not supported, WMS required"); } } String version = getString(request, "version"); { if (version.Equals("1.1.1") == false) { throw new Exception("501, Version not supported, 1.1.1 required"); } } String format = getString(request, "format"); { if (format.Equals("image/png", StringComparison.InvariantCultureIgnoreCase) == false) { throw new Exception("501, Image type not supported, image/png required"); } } String srs = getString(request, "srs"); if (srs.Equals("OSGEO", StringComparison.InvariantCultureIgnoreCase) == true) { String[] layers = getStrings(request, "layers"); String[] bbox = getStrings(request, "bbox"); int x1 = Int32.Parse(bbox[0].Trim()); int y1 = Int32.Parse(bbox[1].Trim()); int zoom = Int32.Parse(bbox[2].Trim()); int width = getInteger(request, "width"); int height = getInteger(request, "height"); int x2 = x1 + (int)Math.Ceiling((double)width / Program.TILE_SIZE) - 1; int y2 = y1 + (int)Math.Ceiling((double)height / Program.TILE_SIZE) - 1; return ImageFactory.getImageData(x1, y1, x2, y2, zoom, layers, width, height, path); } else if ((srs.Equals("EPSG:4326", StringComparison.InvariantCultureIgnoreCase) == true) || (srs.Equals("WGS84", StringComparison.InvariantCultureIgnoreCase) == true)) { // http://127.0.0.1:8080/gis_mataro?service=WMS&request=GetMap&layers=lands,motorway&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A4326&width=256&height=256&bbox=2.4169921875,41.5414776667903,2.43896484375,41.5579215778042 // http://127.0.0.1:8080/gis_mataro?service=WMS&request=GetMap&layers=lands,motorway&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A4326&width=256&height=256&bbox=2.4169921875,41.5579215778042,2.43896484375,41.5743613059891 String[] layers = getStrings(request, "layers"); String[] bbox = getStrings(request, "bbox"); double lon1 = Double.Parse(bbox[0].Trim().Replace(".", ",")); double lat1 = Double.Parse(bbox[1].Trim().Replace(".", ",")); double lon2 = Double.Parse(bbox[2].Trim().Replace(".", ",")); double lat2 = Double.Parse(bbox[3].Trim().Replace(".", ",")); int width = getInteger(request, "width"); int height = getInteger(request, "height"); int zoom = getInteger(request, "zoom"); if (zoom == 0) { for (int i = 1; i < 32; i++) { int x1 = (int)Math.Round(Mercator.longitudeToX(lon1, i)); int y1 = (int)Math.Round(Mercator.latitudeToY(lat1, i)); int x2 = (int)Math.Round(Mercator.longitudeToX(lon2, i)); int y2 = (int)Math.Round(Mercator.latitudeToY(lat2, i)); int pixelsx = Math.Abs(x2 - x1); int pixelsy = Math.Abs(y1 - y2); if ((pixelsx >= width) && (pixelsy >= height)) { zoom = i; break; } } } if (zoom > 0) { if (lon1 > lon2) { double lon3 = lon2; lon2 = lon1; lon1 = lon3; }; if (lat1 > lat2) { double lat3 = lat2; lat2 = lat1; lat1 = lat3; }; int x1 = (int)Math.Round(Mercator.longitudeToX(lon1, zoom)); int y1 = (int)Math.Round(Mercator.latitudeToY(lat1, zoom)); int x2 = (int)Math.Round(Mercator.longitudeToX(lon2, zoom)); int y2 = (int)Math.Round(Mercator.latitudeToY(lat2, zoom)); int modulox = x1 % (int)Program.TILE_SIZE; int moduloy = y2 % (int)Program.TILE_SIZE; if ((modulox > 0) || (moduloy > 0)) { int X1 = (int)(x1 / (int)Program.TILE_SIZE); int Y1 = (int)(y2 / (int)Program.TILE_SIZE); int X2 = (int)(x2 / (int)Program.TILE_SIZE) + 1; int Y2 = (int)(y1 / (int)Program.TILE_SIZE) + 1; if (modulox > 0) X2 = X2 + 1; if (moduloy > 0) Y2 = Y2 + 1; byte[] image = ImageFactory.getImageData(X1, Y1, X2, Y2, zoom, layers, (X2 - X1) * (int)Program.TILE_SIZE, (Y2 - Y1) * (int)Program.TILE_SIZE, path); return ImageFactory.crop(image, modulox, moduloy, width, height); } else { int X1 = (int)(x1 / (int)Program.TILE_SIZE); int Y1 = (int)(y2 / (int)Program.TILE_SIZE); int X2 = (int)(x2 / (int)Program.TILE_SIZE); int Y2 = (int)(y1 / (int)Program.TILE_SIZE); return ImageFactory.getImageData(X1, Y1, X2, Y2, zoom, layers, width, height, path); } } throw new ControllerHTTPException(501, "Bad coordinates with given size"); // Mercator, UTM } else if (srs.Equals("EPSG:3857", StringComparison.InvariantCultureIgnoreCase) == true) { //https://gis.stackexchange.com/questions/48949/epsg-3857-or-4326-for-googlemaps-openstreetmap-and-leaflet throw new ControllerHTTPException(501, "SRS not supported"); // Mercator, UTM } else { throw new ControllerHTTPException(501, "SRS not supported"); } throw new ControllerHTTPException(400, "Bad request"); /* bool transparent = getBoolean(request, "format"); String bgcolor = getString(request, "bgcolor"); String exceptions = getString(request, "exceptions"); String elevation = getString(request, "elevation"); String sld = getString(request, "sld"); String wms = getString(request, "wms"); String[] styles = getStrings(request, "styles"); */ } private String getString(HttpListenerRequest request, String field) { try { String result = request.QueryString[field]; if (result != null) return result; } catch (Exception) { } return ""; } private int getInteger(HttpListenerRequest request, String field) { try { return Int32.Parse(getString(request, field)); } catch (Exception e) { } return 0; } private String[] getStrings(HttpListenerRequest request, String field) { return getString(request, field).Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); } private bool getBoolean(HttpListenerRequest request, String field) { return (getString(request, field).Equals("true", StringComparison.InvariantCultureIgnoreCase)); } } public class ControllerHTTPException : Exception { private int code; private String message; public ControllerHTTPException(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } } /* static void Main() { var web = new HttpListener(); web.Prefixes.Add("http://localhost:8080/"); Console.WriteLine("Listening.."); * web.Start(); Console.WriteLine(web.GetContext()); var context = web.GetContext(); var response = context.Response; const string responseString = "Hello world"; var buffer = System.Text.Encoding.UTF8.GetBytes(responseString); response.ContentLength64 = buffer.Length; var output = response.OutputStream; output.Write(buffer, 0, buffer.Length); Console.WriteLine(output); output.Close(); web.Stop(); Console.ReadKey(); } http://172.16.11.187:9090/geoserver/SCT/wms?tiled=false&service=WMS&request=GetMap&layers=land,border_district,border_municipio,border_voivodato,railways,bridges,street&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=OSGEO&width=256&height=256&bbox=66422,48879,17 http://127.0.0.1:8080/gis_mataro?service=WMS&request=GetMap&layers=land,border_district,border_municipio,border_voivodato,railways,bridges,street&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A4326&width=256&height=256&bbox=2.4169921875,41.52502957323801,2.427978515625,41.53325414281322 http://172.16.11.187:9090/geoserver/SCT/wms?tiled=false&service=WMS&request=GetMap&layers=land,border_district,border_municipio,border_voivodato,railways,bridges,street&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A3857&width=256&height=256&x=66422&y=48879&zoom=17 http://localhost:8080/geoserver/SCT/wms?tiled=false&service=WMS&request=GetMap&layers=land,border_district,border_municipio,border_voivodato,railways,bridges,street&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A3857&width=256&height=256&x=66422&y=48879&zoom=17 http://localhost:8080/geoserver/SCT/wms?tiled=false&service=WMS&request=GetMap&layers=land,border_district,border_municipio,border_voivodato,railways,bridges,street&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A3857&width=256&height=256&x=66422&y=48879&zoom=17 http://172.16.11.187:9090/geoserver/SCT/wms?tiled=false&service=WMS&request=GetMap&layers=land,border_district,border_municipio,border_voivodato,railways,bridges,street&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=OSGEO&width=256&height=256&bbox=66422,48879,17 http://localhost:8080/geoserver/SCT/wms?tiled=false&service=WMS&request=GetMap&layers=layer1,layer2,layer3&styles=&format=image%2Fpng&transparent=true&version=1.1.1&srs=EPSG%3A3857&width=256&height=256&bbox=264166.3697535692,5094986.557376712,266612.35465869476,5097432.542281834 http://cite.opengeospatial.org/OGCTestData/wms/1.1.1/spec/wms1.1.1.html#wmsops.getmap 7.2.2 GetMap */ }