Ticket #19336: 19336-poc.patch
File 19336-poc.patch, 12.2 KB (added by , 4 years ago) |
---|
-
new file resources/data/GetCapabilities.xml
commit 013e837825607bb8bde748d83df4bbe028ae0c64 Author: Simon Legner <Simon.Legner@gmail.com> Date: 2021-03-20 08:44:43 +0100 WIP #19336 - Implement WMS server diff --git a/resources/data/GetCapabilities.xml b/resources/data/GetCapabilities.xml new file mode 100644 index 000000000..bc7a9ccab
- + 1 <?xml version="1.0" encoding="UTF-8"?> 2 <WMS_Capabilities 3 version="1.3.0" 4 xmlns="http://www.opengis.net/wms" 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6 xmlns:xlink="http://www.w3.org/1999/xlink" 7 xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"> 8 <Service> 9 <Name>WMS</Name> 10 <Title>JOSM</Title> 11 <Abstract>...</Abstract> 12 <OnlineResource xlink:href="http://localhost:8111/wms?"/> 13 <Fees>none</Fees> 14 <AccessConstraints>ODbL</AccessConstraints> 15 </Service> 16 <Capability> 17 <Request> 18 <GetCapabilities> 19 <Format>application/vnd.ogc.wms_xml</Format> 20 <Format>text/xml</Format> 21 <DCPType> 22 <HTTP> 23 <Get> 24 <OnlineResource xlink:href="http://localhost:8111/wms?"/> 25 </Get> 26 </HTTP> 27 </DCPType> 28 </GetCapabilities> 29 <GetMap> 30 <Format>image/png</Format> 31 <DCPType> 32 <HTTP> 33 <Get> 34 <OnlineResource xlink:href="http://localhost:8111/wms?"/> 35 </Get> 36 </HTTP> 37 </DCPType> 38 </GetMap> 39 </Request> 40 <Exception> 41 <Format>application/vnd.ogc.se_xml</Format> 42 <Format>application/vnd.ogc.se_inimage</Format> 43 <Format>application/vnd.ogc.se_blank</Format> 44 <Format>text/xml</Format> 45 <Format>XML</Format> 46 </Exception> 47 <Layer> 48 <Title>JOSM Root</Title> 49 <CRS>EPSG:3857</CRS> 50 <Layer> 51 <Title>JOSM Layer</Title> 52 <Style> 53 <Name>JOSM Style</Name> 54 <Title>JOSM Style</Title> 55 </Style> 56 </Layer> 57 </Layer> 58 </Capability> 59 </WMS_Capabilities> -
src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java b/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java index e03bfb4ce..c45d06b4d 100644
a b import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHan 44 44 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerForbiddenException; 45 45 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerOsmApiException; 46 46 import org.openstreetmap.josm.io.remotecontrol.handler.VersionHandler; 47 import org.openstreetmap.josm.io.remotecontrol.handler.WmsHandler; 47 48 import org.openstreetmap.josm.tools.Logging; 48 49 import org.openstreetmap.josm.tools.Utils; 49 50 … … public class RequestProcessor extends Thread { 171 172 addRequestHandlerClass(VersionHandler.command, VersionHandler.class, true); 172 173 addRequestHandlerClass(FeaturesHandler.command, FeaturesHandler.class, true); 173 174 addRequestHandlerClass(OpenApiHandler.command, OpenApiHandler.class, true); 175 addRequestHandlerClass(WmsHandler.command, WmsHandler.class, true); 174 176 } 175 177 } 176 178 … … public class RequestProcessor extends Thread { 181 183 public void run() { 182 184 Writer out = null; // NOPMD 183 185 try { // NOPMD 184 out = new OutputStreamWriter(new BufferedOutputStream(request.getOutputStream()), RESPONSE_CHARSET); 186 BufferedOutputStream raw = new BufferedOutputStream(request.getOutputStream()); 187 out = new OutputStreamWriter(raw, RESPONSE_CHARSET); 185 188 BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.US_ASCII)); // NOPMD 186 189 187 190 String get = in.readLine(); … … public class RequestProcessor extends Thread { 262 265 handler.setUrl(url); 263 266 handler.setSender(sender); 264 267 handler.handle(); 265 sendHeader(out, "200 OK", handler.getContentType(), false); 266 out.write("Content-length: " + handler.getContent().length() 267 + "\r\n"); 268 out.write("\r\n"); 269 out.write(handler.getContent()); 270 out.flush(); 268 if (handler instanceof WmsHandler) { 269 sendHeader(out, "200 OK", handler.getContentType(), null, -1); 270 out.flush(); 271 ((WmsHandler) handler).handleRequest(raw); 272 raw.flush(); 273 } else { 274 sendHeader(out, "200 OK", handler.getContentType(), RESPONSE_CHARSET, handler.getContent().length()); 275 out.write(handler.getContent()); 276 out.flush(); 277 } 271 278 } catch (RequestHandlerOsmApiException ex) { 272 279 Logging.debug(ex); 273 280 sendBadGateway(out, ex.getMessage()); … … public class RequestProcessor extends Thread { 305 312 } 306 313 307 314 private static void sendErrorHtml(Writer out, int errorCode, String errorName, String helpHtml) throws IOException { 308 sendHeader(out, errorCode + " " + errorName, "text/html", true);315 sendHeader(out, errorCode + " " + errorName, "text/html", RESPONSE_CHARSET, -1); 309 316 out.write(String.format( 310 317 RESPONSE_TEMPLATE, 311 318 "<title>" + errorName + "</title>", … … public class RequestProcessor extends Thread { 389 396 * The status string ("200 OK", "500", etc) 390 397 * @param contentType 391 398 * The content type of the data sent 392 * @param endHeaders 393 * If true, adds a new line, ending the headers. 399 * @param charset The content charset 400 * @param length The content length 401 * 394 402 * @throws IOException 395 403 * When error 396 404 */ 397 private static void sendHeader(Writer out, String status, String contentType, 398 boolean endHeaders) throws IOException { 399 out.write("HTTP/1.1 " + status + "\r\n"); 400 out.write("Date: " + new Date() + "\r\n"); 401 out.write("Server: " + JOSM_REMOTE_CONTROL + "\r\n"); 402 out.write("Content-type: " + contentType + "; charset=" + RESPONSE_CHARSET.name().toLowerCase(Locale.ENGLISH) + "\r\n"); 403 out.write("Access-Control-Allow-Origin: *\r\n"); 404 if (endHeaders) 405 out.write("\r\n"); 405 private static void sendHeader(Appendable out, String status, String contentType, Charset charset, long length) throws IOException { 406 out.append("HTTP/1.1 ").append(status).append("\r\n"); 407 out.append("Date: ").append(String.valueOf(new Date())).append("\r\n"); 408 out.append("Server: " + JOSM_REMOTE_CONTROL + "\r\n"); 409 410 out.append("Content-type: ").append(contentType); 411 if (charset != null) { 412 out.append("; charset=").append(charset.name().toLowerCase(Locale.ENGLISH)); 413 } 414 out.append("\r\n"); 415 416 if (length > 0) { 417 out.append("Content-length: ").append(String.valueOf(length)).append("\r\n"); 418 } 419 420 out.append("Access-Control-Allow-Origin: *\r\n"); 421 422 // end header 423 out.append("\r\n"); 406 424 } 407 425 408 426 /** -
new file src/org/openstreetmap/josm/io/remotecontrol/handler/WmsHandler.java
diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/WmsHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/WmsHandler.java new file mode 100644 index 000000000..a504778e0
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.io.remotecontrol.handler; 3 4 import org.openstreetmap.josm.gui.MainApplication; 5 import org.openstreetmap.josm.gui.mappaint.RenderingHelper; 6 import org.openstreetmap.josm.gui.mappaint.RenderingHelper.StyleData; 7 import org.openstreetmap.josm.io.CachedFile; 8 import org.openstreetmap.josm.io.IllegalDataException; 9 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 10 import org.openstreetmap.josm.tools.CheckParameterUtil; 11 12 import javax.imageio.ImageIO; 13 import java.awt.image.BufferedImage; 14 import java.io.IOException; 15 import java.io.OutputStream; 16 import java.net.URISyntaxException; 17 import java.util.Collections; 18 import java.util.Locale; 19 import java.util.Map; 20 import java.util.stream.Collectors; 21 22 public class WmsHandler extends RequestHandler { 23 24 /** 25 * The remote control command name. 26 */ 27 public static final String command = "wms"; 28 29 @Override 30 protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException { 31 if (args.get("request").equalsIgnoreCase("GetCapabilities")) { 32 contentType = "text/xml"; 33 } else if (args.get("request").equalsIgnoreCase("GetMap")) { 34 contentType = args.getOrDefault("format", "image/png"); 35 } 36 } 37 38 public void handleRequest(OutputStream out) throws IOException { 39 if (args.get("request").equalsIgnoreCase("GetCapabilities")) { 40 byte[] bytes = new CachedFile("resource://data/GetCapabilities.xml").getByteContent(); 41 out.write(bytes); 42 } else if (args.get("request").equalsIgnoreCase("GetMap")) { 43 getMap(out); 44 } 45 } 46 47 private void getMap(OutputStream out) throws IOException { 48 // double[] bbox = Pattern.compile(",").splitAsStream(args.get("bbox")).mapToDouble(Double::parseDouble).toArray(); 49 // ProjectionBounds projectionBounds = new ProjectionBounds(); 50 // projectionBounds.extend(new EastNorth(bbox[0], bbox[1])); 51 // projectionBounds.extend(new EastNorth(bbox[2], bbox[3])); 52 // System.out.println(projectionBounds); 53 // Bounds bounds = ProjectionRegistry.getProjection().getLatLonBoundsBox(projectionBounds); 54 // System.out.println(bounds); 55 StyleData styleData = new StyleData(); 56 styleData.styleUrl = "resource://styles/standard/elemstyles.mapcss"; 57 58 RenderingHelper renderingHelper = new RenderingHelper( 59 MainApplication.getLayerManager().getActiveDataSet(), 60 MainApplication.getMap().mapView.getRealBounds(), 61 MainApplication.getMap().mapView.getScale(), 62 Collections.singleton(styleData)); 63 try { 64 BufferedImage image = renderingHelper.render(); 65 ImageIO.write(image, "png", out); 66 } catch (IllegalDataException e) { 67 throw new RuntimeException(e); 68 } 69 } 70 71 @Override 72 protected void parseArgs() throws URISyntaxException { 73 super.parseArgs(); 74 this.args = this.args.entrySet().stream().collect(Collectors.toMap(s -> s.getKey().toLowerCase(Locale.ROOT), Map.Entry::getValue)); 75 this.args.computeIfAbsent("service", k -> "WMS"); 76 this.args.computeIfAbsent("request", k -> "GetCapabilities"); 77 } 78 79 @Override 80 public String[] getMandatoryParams() { 81 return new String[]{}; 82 } 83 84 @Override 85 public String[] getOptionalParams() { 86 return new String[]{"service", "request", "version", "bbox", "layer"}; 87 } 88 89 @Override 90 protected void validateRequest() throws RequestHandlerBadRequestException { 91 CheckParameterUtil.ensureThat("WMS".equalsIgnoreCase(args.get("service")), "service=WMS"); 92 CheckParameterUtil.ensureParameterNotNull("WMS".equalsIgnoreCase(args.get("request")), "request"); 93 } 94 95 @Override 96 public String getPermissionMessage() { 97 return null; 98 } 99 100 @Override 101 public PermissionPrefWithDefault getPermissionPref() { 102 return null; 103 } 104 }