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; 007 008import org.openstreetmap.josm.data.imagery.ImageryInfo; 009import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType; 010import org.openstreetmap.josm.data.imagery.ImageryLayerInfo; 011import org.openstreetmap.josm.gui.MainApplication; 012import org.openstreetmap.josm.gui.layer.ImageryLayer; 013import org.openstreetmap.josm.gui.util.GuiHelper; 014import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 015import org.openstreetmap.josm.tools.Logging; 016import org.openstreetmap.josm.tools.Utils; 017 018/** 019 * Adds an imagery (WMS/TMS) layer. For instance, {@code /imagery?title=...&type=...&url=...}. 020 * @since 3715 021 */ 022public class ImageryHandler extends RequestHandler.RawURLParseRequestHandler { 023 024 /** 025 * The remote control command name used to add an imagery layer. 026 */ 027 public static final String command = "imagery"; 028 029 @Override 030 public String getPermissionMessage() { 031 return tr("Remote Control has been asked to load an imagery layer from the following URL:") 032 + "<br>" + args.get("url"); 033 } 034 035 @Override 036 public String[] getMandatoryParams() { 037 return new String[]{"url"}; 038 } 039 040 @Override 041 public String[] getOptionalParams() { 042 return new String[] {"title", "type", "cookies", "min_zoom", "max_zoom"}; 043 } 044 045 @Override 046 public PermissionPrefWithDefault getPermissionPref() { 047 return PermissionPrefWithDefault.LOAD_IMAGERY; 048 } 049 050 protected static ImageryInfo findBingEntry() { 051 for (ImageryInfo i : ImageryLayerInfo.instance.getDefaultLayers()) { 052 if (ImageryType.BING == i.getImageryType()) { 053 return i; 054 } 055 } 056 return null; 057 } 058 059 protected ImageryInfo buildImageryInfo() { 060 String url = args.get("url"); 061 String title = args.get("title"); 062 String type = args.get("type"); 063 final ImageryInfo bing = ImageryType.BING.getTypeString().equals(type) ? findBingEntry() : null; 064 if ((title == null || title.isEmpty()) && bing != null) { 065 title = bing.getName(); 066 } 067 if (title == null || title.isEmpty()) { 068 title = tr("Remote imagery"); 069 } 070 String cookies = args.get("cookies"); 071 final ImageryInfo imgInfo = new ImageryInfo(title, url, type, null, cookies); 072 if (bing != null) { 073 imgInfo.setIcon(bing.getIcon()); 074 } 075 String minZoom = args.get("min_zoom"); 076 if (minZoom != null && !minZoom.isEmpty()) { 077 try { 078 imgInfo.setDefaultMinZoom(Integer.parseInt(minZoom)); 079 } catch (NumberFormatException e) { 080 Logging.error(e); 081 } 082 } 083 String maxZoom = args.get("max_zoom"); 084 if (maxZoom != null && !maxZoom.isEmpty()) { 085 try { 086 imgInfo.setDefaultMaxZoom(Integer.parseInt(maxZoom)); 087 } catch (NumberFormatException e) { 088 Logging.error(e); 089 } 090 } 091 return imgInfo; 092 } 093 094 @Override 095 protected void handleRequest() throws RequestHandlerErrorException { 096 final ImageryInfo imgInfo = buildImageryInfo(); 097 if (MainApplication.isDisplayingMapView()) { 098 for (ImageryLayer layer : MainApplication.getLayerManager().getLayersOfType(ImageryLayer.class)) { 099 if (layer.getInfo().equals(imgInfo)) { 100 Logging.info("Imagery layer already exists: "+imgInfo); 101 return; 102 } 103 } 104 } 105 GuiHelper.runInEDT(() -> { 106 try { 107 MainApplication.getLayerManager().addLayer(ImageryLayer.create(imgInfo)); 108 } catch (IllegalArgumentException e) { 109 Logging.log(Logging.LEVEL_ERROR, e); 110 } 111 }); 112 } 113 114 @Override 115 protected void validateRequest() throws RequestHandlerBadRequestException { 116 String url = args != null ? args.get("url") : null; 117 String type = args != null ? args.get("type") : null; 118 String cookies = args != null ? args.get("cookies") : null; 119 try { 120 ImageryLayer.create(new ImageryInfo(null, url, type, null, cookies)); 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()), 134 ImageryType::getTypeString)); 135 return new String[] { 136 "/imagery?title=osm&type=tms&url=https://a.tile.openstreetmap.org/%7Bzoom%7D/%7Bx%7D/%7By%7D.png", 137 "/imagery?title=landsat&type=wms&url=http://irs.gis-lab.info/?" + 138 "layers=landsat&SRS=%7Bproj%7D&WIDTH=%7Bwidth%7D&HEIGHT=%7Bheight%7D&BBOX=%7Bbbox%7D", 139 "/imagery?title=...&type={"+types+"}&url=....[&cookies=...][&min_zoom=...][&max_zoom=...]" 140 }; 141 } 142}