001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io.remotecontrol.handler; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.util.Arrays; 007import java.util.HashMap; 008 009import org.openstreetmap.josm.Main; 010import org.openstreetmap.josm.data.imagery.ImageryInfo; 011import org.openstreetmap.josm.gui.layer.ImageryLayer; 012import org.openstreetmap.josm.gui.util.GuiHelper; 013import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 014import org.openstreetmap.josm.tools.Utils; 015 016/** 017 * Adds an imagery (WMS/TMS) layer. For instance, {@code /imagery?title=...&type=...&url=...}. 018 * @since 3715 019 */ 020public class ImageryHandler extends RequestHandler { 021 022 /** 023 * The remote control command name used to add an imagery layer. 024 */ 025 public static final String command = "imagery"; 026 027 @Override 028 public String getPermissionMessage() { 029 return tr("Remote Control has been asked to load an imagery layer from the following URL:") 030 + "<br>" + args.get("url"); 031 } 032 033 @Override 034 public String[] getMandatoryParams() { 035 return new String[]{"url"}; 036 } 037 038 @Override 039 public String[] getOptionalParams() { 040 return new String[] { "title", "type", "cookies", "min_zoom", "max_zoom"}; 041 } 042 043 @Override 044 public PermissionPrefWithDefault getPermissionPref() { 045 return PermissionPrefWithDefault.LOAD_IMAGERY; 046 } 047 048 @Override 049 protected void handleRequest() throws RequestHandlerErrorException { 050 String url = args.get("url"); 051 String title = args.get("title"); 052 String type = args.get("type"); 053 if ((title == null) || (title.isEmpty())) { 054 title = tr("Remote imagery"); 055 } 056 String cookies = args.get("cookies"); 057 final ImageryInfo imgInfo = new ImageryInfo(title, url, type, null, cookies); 058 String min_zoom = args.get("min_zoom"); 059 if (min_zoom != null && !min_zoom.isEmpty()) { 060 try { 061 imgInfo.setDefaultMinZoom(Integer.parseInt(min_zoom)); 062 } catch (NumberFormatException e) { 063 Main.error(e); 064 } 065 } 066 String max_zoom = args.get("max_zoom"); 067 if (max_zoom != null && !max_zoom.isEmpty()) { 068 try { 069 imgInfo.setDefaultMaxZoom(Integer.parseInt(max_zoom)); 070 } catch (NumberFormatException e) { 071 Main.error(e); 072 } 073 } 074 GuiHelper.runInEDT(new Runnable() { 075 @Override 076 public void run() { 077 try { 078 Main.main.addLayer(ImageryLayer.create(imgInfo)); 079 } catch (IllegalArgumentException e) { 080 Main.error(e, false); 081 } 082 } 083 }); 084 } 085 086 @Override 087 protected void parseArgs() { 088 HashMap<String, String> args = new HashMap<>(); 089 if (request.indexOf('?') != -1) { 090 String query = request.substring(request.indexOf('?') + 1); 091 if (query.indexOf("url=") == 0) { 092 args.put("url", decodeParam(query.substring(4))); 093 } else { 094 int urlIdx = query.indexOf("&url="); 095 if (urlIdx != -1) { 096 args.put("url", decodeParam(query.substring(urlIdx + 5))); 097 query = query.substring(0, urlIdx); 098 } else { 099 if (query.indexOf('#') != -1) { 100 query = query.substring(0, query.indexOf('#')); 101 } 102 } 103 String[] params = query.split("&", -1); 104 for (String param : params) { 105 int eq = param.indexOf('='); 106 if (eq != -1) { 107 args.put(param.substring(0, eq), decodeParam(param.substring(eq + 1))); 108 } 109 } 110 } 111 } 112 this.args = args; 113 } 114 115 @Override 116 protected void validateRequest() throws RequestHandlerBadRequestException { 117 String url = args.get("url"); 118 String type = args.get("type"); 119 try { 120 ImageryLayer.create(new ImageryInfo(null, url, type, null, null)); 121 } catch (IllegalArgumentException e) { 122 throw new RequestHandlerBadRequestException(e.getMessage(), e); 123 } 124 } 125 126 @Override 127 public String getUsage() { 128 return "adds an imagery layer (e.g. WMS, TMS)"; 129 } 130 131 @Override 132 public String[] getUsageExamples() { 133 final String types = Utils.join("|", Utils.transform(Arrays.asList(ImageryInfo.ImageryType.values()), new Utils.Function<ImageryInfo.ImageryType, String>() { 134 @Override 135 public String apply(ImageryInfo.ImageryType x) { 136 return x.getTypeString(); 137 } 138 })); 139 return new String[] { "/imagery?title=osm&type=tms&url=https://a.tile.openstreetmap.org/%7Bzoom%7D/%7Bx%7D/%7By%7D.png", 140 "/imagery?title=landsat&type=wms&url=http://irs.gis-lab.info/?layers=landsat&SRS=%7Bproj%7D&WIDTH=%7Bwidth%7D&HEIGHT=%7Bheight%7D&BBOX=%7Bbbox%7D", 141 "/imagery?title=...&type={"+types+"}&url=....[&cookies=...][&min_zoom=...][&max_zoom=...]"}; 142 } 143}