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 = "<html><body>" + exception.getMessage() + "</body></html>";
|
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 = "<html><body>Hello world</body></html>";
|
|
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
|
|
|
*/
|
|
|
|
|
|
}
|