[3719] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[3715] | 2 | package org.openstreetmap.josm.data.imagery;
|
---|
| 3 |
|
---|
[6968] | 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
[4506] | 6 | import java.awt.Image;
|
---|
[5391] | 7 | import java.util.ArrayList;
|
---|
[4430] | 8 | import java.util.Arrays;
|
---|
[3715] | 9 | import java.util.Collection;
|
---|
[4240] | 10 | import java.util.Collections;
|
---|
| 11 | import java.util.List;
|
---|
[8404] | 12 | import java.util.Locale;
|
---|
[8344] | 13 | import java.util.Map;
|
---|
[7186] | 14 | import java.util.Objects;
|
---|
[9755] | 15 | import java.util.Set;
|
---|
[7203] | 16 | import java.util.TreeSet;
|
---|
[4188] | 17 | import java.util.regex.Matcher;
|
---|
| 18 | import java.util.regex.Pattern;
|
---|
[11216] | 19 | import java.util.stream.Collectors;
|
---|
[3715] | 20 |
|
---|
[4195] | 21 | import javax.swing.ImageIcon;
|
---|
| 22 |
|
---|
[5391] | 23 | import org.openstreetmap.gui.jmapviewer.interfaces.Attributed;
|
---|
[8526] | 24 | import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate;
|
---|
[5391] | 25 | import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTileSource;
|
---|
| 26 | import org.openstreetmap.gui.jmapviewer.tilesources.OsmTileSource.Mapnik;
|
---|
[8344] | 27 | import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
|
---|
[4195] | 28 | import org.openstreetmap.josm.Main;
|
---|
| 29 | import org.openstreetmap.josm.data.Bounds;
|
---|
[4450] | 30 | import org.openstreetmap.josm.data.Preferences.pref;
|
---|
[7476] | 31 | import org.openstreetmap.josm.io.Capabilities;
|
---|
[3934] | 32 | import org.openstreetmap.josm.io.OsmApi;
|
---|
[3974] | 33 | import org.openstreetmap.josm.tools.CheckParameterUtil;
|
---|
[4195] | 34 | import org.openstreetmap.josm.tools.ImageProvider;
|
---|
[8091] | 35 | import org.openstreetmap.josm.tools.LanguageInfo;
|
---|
[12620] | 36 | import org.openstreetmap.josm.tools.Logging;
|
---|
[9755] | 37 | import org.openstreetmap.josm.tools.MultiMap;
|
---|
[11848] | 38 | import org.openstreetmap.josm.tools.Utils;
|
---|
[3934] | 39 |
|
---|
[3715] | 40 | /**
|
---|
[3826] | 41 | * Class that stores info about an image background layer.
|
---|
[3715] | 42 | *
|
---|
[6830] | 43 | * @author Frederik Ramm
|
---|
[3715] | 44 | */
|
---|
[8344] | 45 | public class ImageryInfo extends TileSourceInfo implements Comparable<ImageryInfo>, Attributed {
|
---|
[3826] | 46 |
|
---|
[6690] | 47 | /**
|
---|
| 48 | * Type of imagery entry.
|
---|
| 49 | */
|
---|
[3715] | 50 | public enum ImageryType {
|
---|
[6690] | 51 | /** A WMS (Web Map Service) entry. **/
|
---|
[3715] | 52 | WMS("wms"),
|
---|
[6690] | 53 | /** A TMS (Tile Map Service) entry. **/
|
---|
[3715] | 54 | TMS("tms"),
|
---|
[6690] | 55 | /** TMS entry for Microsoft Bing. */
|
---|
[3878] | 56 | BING("bing"),
|
---|
[6690] | 57 | /** TMS entry for Russian company <a href="https://wiki.openstreetmap.org/wiki/WikiProject_Russia/kosmosnimki">ScanEx</a>. **/
|
---|
[5617] | 58 | SCANEX("scanex"),
|
---|
[6690] | 59 | /** A WMS endpoint entry only stores the WMS server info, without layer, which are chosen later by the user. **/
|
---|
[8568] | 60 | WMS_ENDPOINT("wms_endpoint"),
|
---|
| 61 | /** WMTS stores GetCapabilities URL. Does not store any information about the layer **/
|
---|
| 62 | WMTS("wmts");
|
---|
[3715] | 63 |
|
---|
[8344] | 64 |
|
---|
[6690] | 65 | private final String typeString;
|
---|
[4861] | 66 |
|
---|
[8674] | 67 | ImageryType(String urlString) {
|
---|
[6690] | 68 | this.typeString = urlString;
|
---|
[3715] | 69 | }
|
---|
[4861] | 70 |
|
---|
[6690] | 71 | /**
|
---|
| 72 | * Returns the unique string identifying this type.
|
---|
| 73 | * @return the unique string identifying this type
|
---|
| 74 | * @since 6690
|
---|
| 75 | */
|
---|
| 76 | public final String getTypeString() {
|
---|
| 77 | return typeString;
|
---|
[3715] | 78 | }
|
---|
[6069] | 79 |
|
---|
[6690] | 80 | /**
|
---|
| 81 | * Returns the imagery type from the given type string.
|
---|
| 82 | * @param s The type string
|
---|
| 83 | * @return the imagery type matching the given type string
|
---|
| 84 | */
|
---|
| 85 | public static ImageryType fromString(String s) {
|
---|
[4861] | 86 | for (ImageryType type : ImageryType.values()) {
|
---|
[6690] | 87 | if (type.getTypeString().equals(s)) {
|
---|
[4861] | 88 | return type;
|
---|
| 89 | }
|
---|
| 90 | }
|
---|
| 91 | return null;
|
---|
| 92 | }
|
---|
[3715] | 93 | }
|
---|
[4450] | 94 |
|
---|
[6690] | 95 | /**
|
---|
| 96 | * Multi-polygon bounds for imagery backgrounds.
|
---|
| 97 | * Used to display imagery coverage in preferences and to determine relevant imagery entries based on edit location.
|
---|
| 98 | */
|
---|
[4423] | 99 | public static class ImageryBounds extends Bounds {
|
---|
[6830] | 100 |
|
---|
[6690] | 101 | /**
|
---|
| 102 | * Constructs a new {@code ImageryBounds} from string.
|
---|
| 103 | * @param asString The string containing the list of shapes defining this bounds
|
---|
| 104 | * @param separator The shape separator in the given string, usually a comma
|
---|
| 105 | */
|
---|
[4423] | 106 | public ImageryBounds(String asString, String separator) {
|
---|
| 107 | super(asString, separator);
|
---|
| 108 | }
|
---|
[3715] | 109 |
|
---|
[7005] | 110 | private List<Shape> shapes = new ArrayList<>();
|
---|
[4450] | 111 |
|
---|
[6690] | 112 | /**
|
---|
| 113 | * Adds a new shape to this bounds.
|
---|
| 114 | * @param shape The shape to add
|
---|
| 115 | */
|
---|
| 116 | public final void addShape(Shape shape) {
|
---|
[4423] | 117 | this.shapes.add(shape);
|
---|
| 118 | }
|
---|
| 119 |
|
---|
[6690] | 120 | /**
|
---|
| 121 | * Sets the list of shapes defining this bounds.
|
---|
| 122 | * @param shapes The list of shapes defining this bounds.
|
---|
| 123 | */
|
---|
| 124 | public final void setShapes(List<Shape> shapes) {
|
---|
[4423] | 125 | this.shapes = shapes;
|
---|
| 126 | }
|
---|
| 127 |
|
---|
[6690] | 128 | /**
|
---|
| 129 | * Returns the list of shapes defining this bounds.
|
---|
| 130 | * @return The list of shapes defining this bounds
|
---|
| 131 | */
|
---|
| 132 | public final List<Shape> getShapes() {
|
---|
[4423] | 133 | return shapes;
|
---|
| 134 | }
|
---|
[6289] | 135 |
|
---|
| 136 | @Override
|
---|
| 137 | public int hashCode() {
|
---|
[9371] | 138 | return Objects.hash(super.hashCode(), shapes);
|
---|
[6289] | 139 | }
|
---|
| 140 |
|
---|
| 141 | @Override
|
---|
[9371] | 142 | public boolean equals(Object o) {
|
---|
| 143 | if (this == o) return true;
|
---|
| 144 | if (o == null || getClass() != o.getClass()) return false;
|
---|
| 145 | if (!super.equals(o)) return false;
|
---|
| 146 | ImageryBounds that = (ImageryBounds) o;
|
---|
| 147 | return Objects.equals(shapes, that.shapes);
|
---|
[6289] | 148 | }
|
---|
[4423] | 149 | }
|
---|
[7476] | 150 |
|
---|
[8091] | 151 | /** original name of the imagery entry in case of translation call, for multiple languages English when possible */
|
---|
[6968] | 152 | private String origName;
|
---|
[8091] | 153 | /** (original) language of the translated name entry */
|
---|
| 154 | private String langName;
|
---|
[8092] | 155 | /** whether this is a entry activated by default or not */
|
---|
[8840] | 156 | private boolean defaultEntry;
|
---|
[8092] | 157 | /** Whether this service requires a explicit EULA acceptance before it can be activated */
|
---|
[8840] | 158 | private String eulaAcceptanceRequired;
|
---|
[8092] | 159 | /** type of the imagery servics - WMS, TMS, ... */
|
---|
[4195] | 160 | private ImageryType imageryType = ImageryType.WMS;
|
---|
[8840] | 161 | private double pixelPerDegree;
|
---|
[8092] | 162 | /** maximum zoom level for TMS imagery */
|
---|
[8840] | 163 | private int defaultMaxZoom;
|
---|
[8092] | 164 | /** minimum zoom level for TMS imagery */
|
---|
[8840] | 165 | private int defaultMinZoom;
|
---|
[8092] | 166 | /** display bounds of imagery, displayed in prefs and used for automatic imagery selection */
|
---|
[8840] | 167 | private ImageryBounds bounds;
|
---|
[8092] | 168 | /** projections supported by WMS servers */
|
---|
[10577] | 169 | private List<String> serverProjections = Collections.emptyList();
|
---|
[8091] | 170 | /** description of the imagery entry, should contain notes what type of data it is */
|
---|
[8065] | 171 | private String description;
|
---|
[8092] | 172 | /** language of the description entry */
|
---|
[8091] | 173 | private String langDescription;
|
---|
[8092] | 174 | /** Text of a text attribution displayed when using the imagery */
|
---|
[4195] | 175 | private String attributionText;
|
---|
[11975] | 176 | /** Link to a reference stating the permission for OSM usage */
|
---|
| 177 | private String permissionReferenceURL;
|
---|
| 178 | /** Link behind the text attribution displayed when using the imagery */
|
---|
[4492] | 179 | private String attributionLinkURL;
|
---|
[8092] | 180 | /** Image of a graphical attribution displayed when using the imagery */
|
---|
[4195] | 181 | private String attributionImage;
|
---|
[8092] | 182 | /** Link behind the graphical attribution displayed when using the imagery */
|
---|
[4492] | 183 | private String attributionImageURL;
|
---|
[8092] | 184 | /** Text with usage terms displayed when using the imagery */
|
---|
[4492] | 185 | private String termsOfUseText;
|
---|
[8092] | 186 | /** Link behind the text with usage terms displayed when using the imagery */
|
---|
[4195] | 187 | private String termsOfUseURL;
|
---|
[8092] | 188 | /** country code of the imagery (for country specific imagery) */
|
---|
[4405] | 189 | private String countryCode = "";
|
---|
[11571] | 190 | /**
|
---|
[11570] | 191 | * creation date of the imagery (in the form YYYY-MM-DD;YYYY-MM-DD, where
|
---|
| 192 | * DD and MM as well as a second date are optional)
|
---|
| 193 | * @since 11570
|
---|
| 194 | */
|
---|
| 195 | private String date;
|
---|
[11575] | 196 | /**
|
---|
| 197 | * marked as best in other editors
|
---|
| 198 | * @since 11575
|
---|
| 199 | */
|
---|
[11811] | 200 | private boolean bestMarked;
|
---|
[9658] | 201 | /** mirrors of different type for this entry */
|
---|
[9978] | 202 | private List<ImageryInfo> mirrors;
|
---|
[8092] | 203 | /** icon used in menu */
|
---|
[4713] | 204 | private String icon;
|
---|
[11575] | 205 | /** is the geo reference correct - don't offer offset handling */
|
---|
[9978] | 206 | private boolean isGeoreferenceValid;
|
---|
[11216] | 207 | /** which layers should be activated by default on layer addition. **/
|
---|
[11257] | 208 | private Collection<DefaultLayer> defaultLayers = Collections.emptyList();
|
---|
[9135] | 209 | // when adding a field, also adapt the ImageryInfo(ImageryInfo)
|
---|
| 210 | // and ImageryInfo(ImageryPreferenceEntry) constructor, equals method, and ImageryPreferenceEntry
|
---|
[3715] | 211 |
|
---|
[6690] | 212 | /**
|
---|
| 213 | * Auxiliary class to save an {@link ImageryInfo} object in the preferences.
|
---|
| 214 | */
|
---|
[4450] | 215 | public static class ImageryPreferenceEntry {
|
---|
| 216 | @pref String name;
|
---|
[11570] | 217 | @pref String d;
|
---|
[7186] | 218 | @pref String id;
|
---|
[4450] | 219 | @pref String type;
|
---|
| 220 | @pref String url;
|
---|
[4452] | 221 | @pref double pixel_per_eastnorth;
|
---|
[4450] | 222 | @pref String eula;
|
---|
| 223 | @pref String attribution_text;
|
---|
| 224 | @pref String attribution_url;
|
---|
[11975] | 225 | @pref String permission_reference_url;
|
---|
[4452] | 226 | @pref String logo_image;
|
---|
[4492] | 227 | @pref String logo_url;
|
---|
| 228 | @pref String terms_of_use_text;
|
---|
[4450] | 229 | @pref String terms_of_use_url;
|
---|
| 230 | @pref String country_code = "";
|
---|
[11570] | 231 | @pref String date;
|
---|
[4450] | 232 | @pref int max_zoom;
|
---|
| 233 | @pref int min_zoom;
|
---|
| 234 | @pref String cookies;
|
---|
| 235 | @pref String bounds;
|
---|
| 236 | @pref String shapes;
|
---|
| 237 | @pref String projections;
|
---|
[4713] | 238 | @pref String icon;
|
---|
[8065] | 239 | @pref String description;
|
---|
[9755] | 240 | @pref MultiMap<String, String> noTileHeaders;
|
---|
| 241 | @pref MultiMap<String, String> noTileChecksums;
|
---|
[9619] | 242 | @pref int tileSize = -1;
|
---|
[8418] | 243 | @pref Map<String, String> metadataHeaders;
|
---|
[9134] | 244 | @pref boolean valid_georeference;
|
---|
[11575] | 245 | @pref boolean bestMarked;
|
---|
[11216] | 246 | // TODO: disabled until change of layers is implemented
|
---|
| 247 | // @pref String default_layers;
|
---|
[4450] | 248 |
|
---|
[6364] | 249 | /**
|
---|
[6690] | 250 | * Constructs a new empty WMS {@code ImageryPreferenceEntry}.
|
---|
[6364] | 251 | */
|
---|
[4450] | 252 | public ImageryPreferenceEntry() {
|
---|
[9989] | 253 | // Do nothing
|
---|
[4450] | 254 | }
|
---|
| 255 |
|
---|
[6690] | 256 | /**
|
---|
| 257 | * Constructs a new {@code ImageryPreferenceEntry} from a given {@code ImageryInfo}.
|
---|
| 258 | * @param i The corresponding imagery info
|
---|
| 259 | */
|
---|
[4450] | 260 | public ImageryPreferenceEntry(ImageryInfo i) {
|
---|
| 261 | name = i.name;
|
---|
[7186] | 262 | id = i.id;
|
---|
[6690] | 263 | type = i.imageryType.getTypeString();
|
---|
[4450] | 264 | url = i.url;
|
---|
[4452] | 265 | pixel_per_eastnorth = i.pixelPerDegree;
|
---|
[4450] | 266 | eula = i.eulaAcceptanceRequired;
|
---|
| 267 | attribution_text = i.attributionText;
|
---|
| 268 | attribution_url = i.attributionLinkURL;
|
---|
[11975] | 269 | permission_reference_url = i.permissionReferenceURL;
|
---|
[11570] | 270 | date = i.date;
|
---|
[11575] | 271 | bestMarked = i.bestMarked;
|
---|
[4452] | 272 | logo_image = i.attributionImage;
|
---|
[4492] | 273 | logo_url = i.attributionImageURL;
|
---|
| 274 | terms_of_use_text = i.termsOfUseText;
|
---|
[4450] | 275 | terms_of_use_url = i.termsOfUseURL;
|
---|
| 276 | country_code = i.countryCode;
|
---|
| 277 | max_zoom = i.defaultMaxZoom;
|
---|
| 278 | min_zoom = i.defaultMinZoom;
|
---|
| 279 | cookies = i.cookies;
|
---|
[4713] | 280 | icon = i.icon;
|
---|
[8065] | 281 | description = i.description;
|
---|
[4450] | 282 | if (i.bounds != null) {
|
---|
| 283 | bounds = i.bounds.encodeAsString(",");
|
---|
[6264] | 284 | StringBuilder shapesString = new StringBuilder();
|
---|
[4450] | 285 | for (Shape s : i.bounds.getShapes()) {
|
---|
[6264] | 286 | if (shapesString.length() > 0) {
|
---|
[8390] | 287 | shapesString.append(';');
|
---|
[4450] | 288 | }
|
---|
[6264] | 289 | shapesString.append(s.encodeAsString(","));
|
---|
[4450] | 290 | }
|
---|
[6264] | 291 | if (shapesString.length() > 0) {
|
---|
| 292 | shapes = shapesString.toString();
|
---|
[4450] | 293 | }
|
---|
| 294 | }
|
---|
[11216] | 295 | projections = i.serverProjections.stream().collect(Collectors.joining(","));
|
---|
[8344] | 296 | if (i.noTileHeaders != null && !i.noTileHeaders.isEmpty()) {
|
---|
[9755] | 297 | noTileHeaders = new MultiMap<>(i.noTileHeaders);
|
---|
[8344] | 298 | }
|
---|
[8349] | 299 |
|
---|
[9610] | 300 | if (i.noTileChecksums != null && !i.noTileChecksums.isEmpty()) {
|
---|
[9755] | 301 | noTileChecksums = new MultiMap<>(i.noTileChecksums);
|
---|
[9610] | 302 | }
|
---|
| 303 |
|
---|
[8418] | 304 | if (i.metadataHeaders != null && !i.metadataHeaders.isEmpty()) {
|
---|
| 305 | metadataHeaders = i.metadataHeaders;
|
---|
| 306 | }
|
---|
| 307 |
|
---|
[8349] | 308 | tileSize = i.getTileSize();
|
---|
[9134] | 309 |
|
---|
| 310 | valid_georeference = i.isGeoreferenceValid();
|
---|
[11216] | 311 | // TODO disabled until change of layers is implemented
|
---|
| 312 | // default_layers = i.defaultLayers.stream().collect(Collectors.joining(","));
|
---|
[4450] | 313 | }
|
---|
[6364] | 314 |
|
---|
| 315 | @Override
|
---|
| 316 | public String toString() {
|
---|
[8848] | 317 | StringBuilder s = new StringBuilder("ImageryPreferenceEntry [name=").append(name);
|
---|
[7186] | 318 | if (id != null) {
|
---|
[8848] | 319 | s.append(" id=").append(id);
|
---|
[7186] | 320 | }
|
---|
[8848] | 321 | s.append(']');
|
---|
| 322 | return s.toString();
|
---|
[6364] | 323 | }
|
---|
[4450] | 324 | }
|
---|
| 325 |
|
---|
[6364] | 326 | /**
|
---|
[6690] | 327 | * Constructs a new WMS {@code ImageryInfo}.
|
---|
[6364] | 328 | */
|
---|
[4240] | 329 | public ImageryInfo() {
|
---|
[8344] | 330 | super();
|
---|
[4240] | 331 | }
|
---|
| 332 |
|
---|
[6690] | 333 | /**
|
---|
| 334 | * Constructs a new WMS {@code ImageryInfo} with a given name.
|
---|
| 335 | * @param name The entry name
|
---|
| 336 | */
|
---|
[3715] | 337 | public ImageryInfo(String name) {
|
---|
[8344] | 338 | super(name);
|
---|
[3715] | 339 | }
|
---|
| 340 |
|
---|
[6690] | 341 | /**
|
---|
| 342 | * Constructs a new WMS {@code ImageryInfo} with given name and extended URL.
|
---|
| 343 | * @param name The entry name
|
---|
| 344 | * @param url The entry extended URL
|
---|
| 345 | */
|
---|
[3715] | 346 | public ImageryInfo(String name, String url) {
|
---|
[8344] | 347 | this(name);
|
---|
[4240] | 348 | setExtendedUrl(url);
|
---|
[3715] | 349 | }
|
---|
| 350 |
|
---|
[6690] | 351 | /**
|
---|
| 352 | * Constructs a new WMS {@code ImageryInfo} with given name, extended and EULA URLs.
|
---|
| 353 | * @param name The entry name
|
---|
| 354 | * @param url The entry URL
|
---|
| 355 | * @param eulaAcceptanceRequired The EULA URL
|
---|
| 356 | */
|
---|
[3715] | 357 | public ImageryInfo(String name, String url, String eulaAcceptanceRequired) {
|
---|
[8344] | 358 | this(name);
|
---|
[4240] | 359 | setExtendedUrl(url);
|
---|
[3715] | 360 | this.eulaAcceptanceRequired = eulaAcceptanceRequired;
|
---|
| 361 | }
|
---|
| 362 |
|
---|
[7759] | 363 | /**
|
---|
| 364 | * Constructs a new {@code ImageryInfo} with given name, url, extended and EULA URLs.
|
---|
| 365 | * @param name The entry name
|
---|
| 366 | * @param url The entry URL
|
---|
| 367 | * @param type The entry imagery type. If null, WMS will be used as default
|
---|
| 368 | * @param eulaAcceptanceRequired The EULA URL
|
---|
[8092] | 369 | * @param cookies The data part of HTTP cookies header in case the service requires cookies to work
|
---|
[7759] | 370 | * @throws IllegalArgumentException if type refers to an unknown imagery type
|
---|
| 371 | */
|
---|
[4861] | 372 | public ImageryInfo(String name, String url, String type, String eulaAcceptanceRequired, String cookies) {
|
---|
[8344] | 373 | this(name);
|
---|
[4861] | 374 | setExtendedUrl(url);
|
---|
[6690] | 375 | ImageryType t = ImageryType.fromString(type);
|
---|
[8510] | 376 | this.cookies = cookies;
|
---|
[6361] | 377 | this.eulaAcceptanceRequired = eulaAcceptanceRequired;
|
---|
[4861] | 378 | if (t != null) {
|
---|
| 379 | this.imageryType = t;
|
---|
[11889] | 380 | } else if (type != null && !type.isEmpty()) {
|
---|
[7759] | 381 | throw new IllegalArgumentException("unknown type: "+type);
|
---|
[4861] | 382 | }
|
---|
| 383 | }
|
---|
| 384 |
|
---|
[11889] | 385 | /**
|
---|
| 386 | * Constructs a new {@code ImageryInfo} with given name, url, id, extended and EULA URLs.
|
---|
| 387 | * @param name The entry name
|
---|
| 388 | * @param url The entry URL
|
---|
| 389 | * @param type The entry imagery type. If null, WMS will be used as default
|
---|
| 390 | * @param eulaAcceptanceRequired The EULA URL
|
---|
| 391 | * @param cookies The data part of HTTP cookies header in case the service requires cookies to work
|
---|
| 392 | * @param id tile id
|
---|
| 393 | * @throws IllegalArgumentException if type refers to an unknown imagery type
|
---|
| 394 | */
|
---|
[8344] | 395 | public ImageryInfo(String name, String url, String type, String eulaAcceptanceRequired, String cookies, String id) {
|
---|
| 396 | this(name, url, type, eulaAcceptanceRequired, cookies);
|
---|
| 397 | setId(id);
|
---|
| 398 | }
|
---|
| 399 |
|
---|
[6690] | 400 | /**
|
---|
| 401 | * Constructs a new {@code ImageryInfo} from an imagery preference entry.
|
---|
| 402 | * @param e The imagery preference entry
|
---|
| 403 | */
|
---|
[4450] | 404 | public ImageryInfo(ImageryPreferenceEntry e) {
|
---|
[8634] | 405 | super(e.name, e.url, e.id);
|
---|
[4853] | 406 | CheckParameterUtil.ensureParameterNotNull(e.name, "name");
|
---|
| 407 | CheckParameterUtil.ensureParameterNotNull(e.url, "url");
|
---|
[8065] | 408 | description = e.description;
|
---|
[4452] | 409 | cookies = e.cookies;
|
---|
[4450] | 410 | eulaAcceptanceRequired = e.eula;
|
---|
[6690] | 411 | imageryType = ImageryType.fromString(e.type);
|
---|
[4856] | 412 | if (imageryType == null) throw new IllegalArgumentException("unknown type");
|
---|
[4452] | 413 | pixelPerDegree = e.pixel_per_eastnorth;
|
---|
[4450] | 414 | defaultMaxZoom = e.max_zoom;
|
---|
| 415 | defaultMinZoom = e.min_zoom;
|
---|
| 416 | if (e.bounds != null) {
|
---|
| 417 | bounds = new ImageryBounds(e.bounds, ",");
|
---|
| 418 | if (e.shapes != null) {
|
---|
| 419 | try {
|
---|
| 420 | for (String s : e.shapes.split(";")) {
|
---|
| 421 | bounds.addShape(new Shape(s, ","));
|
---|
| 422 | }
|
---|
| 423 | } catch (IllegalArgumentException ex) {
|
---|
[12620] | 424 | Logging.warn(ex);
|
---|
[4423] | 425 | }
|
---|
| 426 | }
|
---|
| 427 | }
|
---|
[11347] | 428 | if (e.projections != null && !e.projections.isEmpty()) {
|
---|
| 429 | // split generates null element on empty string which gives one element Array[null]
|
---|
[4450] | 430 | serverProjections = Arrays.asList(e.projections.split(","));
|
---|
[4430] | 431 | }
|
---|
[4450] | 432 | attributionText = e.attribution_text;
|
---|
[4492] | 433 | attributionLinkURL = e.attribution_url;
|
---|
[11975] | 434 | permissionReferenceURL = e.permission_reference_url;
|
---|
[4452] | 435 | attributionImage = e.logo_image;
|
---|
[4492] | 436 | attributionImageURL = e.logo_url;
|
---|
[11570] | 437 | date = e.date;
|
---|
[11575] | 438 | bestMarked = e.bestMarked;
|
---|
[4492] | 439 | termsOfUseText = e.terms_of_use_text;
|
---|
[4450] | 440 | termsOfUseURL = e.terms_of_use_url;
|
---|
| 441 | countryCode = e.country_code;
|
---|
[4713] | 442 | icon = e.icon;
|
---|
[8344] | 443 | if (e.noTileHeaders != null) {
|
---|
[9755] | 444 | noTileHeaders = e.noTileHeaders.toMap();
|
---|
[8344] | 445 | }
|
---|
[9610] | 446 | if (e.noTileChecksums != null) {
|
---|
[9755] | 447 | noTileChecksums = e.noTileChecksums.toMap();
|
---|
[9610] | 448 | }
|
---|
[8349] | 449 | setTileSize(e.tileSize);
|
---|
[8418] | 450 | metadataHeaders = e.metadataHeaders;
|
---|
[9134] | 451 | isGeoreferenceValid = e.valid_georeference;
|
---|
[11216] | 452 | // TODO disabled until change of layers is implemented
|
---|
| 453 | // defaultLayers = Arrays.asList(e.default_layers.split(","));
|
---|
[3715] | 454 | }
|
---|
| 455 |
|
---|
[6690] | 456 | /**
|
---|
| 457 | * Constructs a new {@code ImageryInfo} from an existing one.
|
---|
| 458 | * @param i The other imagery info
|
---|
| 459 | */
|
---|
[3715] | 460 | public ImageryInfo(ImageryInfo i) {
|
---|
[8634] | 461 | super(i.name, i.url, i.id);
|
---|
[11572] | 462 | this.origName = i.origName;
|
---|
| 463 | this.langName = i.langName;
|
---|
[11575] | 464 | this.bestMarked = i.bestMarked;
|
---|
[5369] | 465 | this.defaultEntry = i.defaultEntry;
|
---|
| 466 | this.cookies = i.cookies;
|
---|
[3715] | 467 | this.eulaAcceptanceRequired = null;
|
---|
[5369] | 468 | this.imageryType = i.imageryType;
|
---|
| 469 | this.pixelPerDegree = i.pixelPerDegree;
|
---|
| 470 | this.defaultMaxZoom = i.defaultMaxZoom;
|
---|
| 471 | this.defaultMinZoom = i.defaultMinZoom;
|
---|
[4195] | 472 | this.bounds = i.bounds;
|
---|
[5369] | 473 | this.serverProjections = i.serverProjections;
|
---|
[4492] | 474 | this.attributionText = i.attributionText;
|
---|
| 475 | this.attributionLinkURL = i.attributionLinkURL;
|
---|
[11975] | 476 | this.permissionReferenceURL = i.permissionReferenceURL;
|
---|
[4195] | 477 | this.attributionImage = i.attributionImage;
|
---|
[4492] | 478 | this.attributionImageURL = i.attributionImageURL;
|
---|
| 479 | this.termsOfUseText = i.termsOfUseText;
|
---|
[4195] | 480 | this.termsOfUseURL = i.termsOfUseURL;
|
---|
[5369] | 481 | this.countryCode = i.countryCode;
|
---|
[11570] | 482 | this.date = i.date;
|
---|
[4713] | 483 | this.icon = i.icon;
|
---|
[8065] | 484 | this.description = i.description;
|
---|
[8418] | 485 | this.noTileHeaders = i.noTileHeaders;
|
---|
[9610] | 486 | this.noTileChecksums = i.noTileChecksums;
|
---|
[8418] | 487 | this.metadataHeaders = i.metadataHeaders;
|
---|
[9134] | 488 | this.isGeoreferenceValid = i.isGeoreferenceValid;
|
---|
[11216] | 489 | this.defaultLayers = i.defaultLayers;
|
---|
[3715] | 490 | }
|
---|
| 491 |
|
---|
| 492 | @Override
|
---|
[9371] | 493 | public int hashCode() {
|
---|
| 494 | return Objects.hash(url, imageryType);
|
---|
[5369] | 495 | }
|
---|
[7476] | 496 |
|
---|
[7186] | 497 | /**
|
---|
| 498 | * Check if this object equals another ImageryInfo with respect to the properties
|
---|
| 499 | * that get written to the preference file.
|
---|
[7476] | 500 | *
|
---|
[7186] | 501 | * The field {@link #pixelPerDegree} is ignored.
|
---|
[7476] | 502 | *
|
---|
[7186] | 503 | * @param other the ImageryInfo object to compare to
|
---|
| 504 | * @return true if they are equal
|
---|
| 505 | */
|
---|
| 506 | public boolean equalsPref(ImageryInfo other) {
|
---|
| 507 | if (other == null) {
|
---|
| 508 | return false;
|
---|
| 509 | }
|
---|
[8418] | 510 |
|
---|
[11587] | 511 | // CHECKSTYLE.OFF: BooleanExpressionComplexity
|
---|
[8418] | 512 | return
|
---|
| 513 | Objects.equals(this.name, other.name) &&
|
---|
| 514 | Objects.equals(this.id, other.id) &&
|
---|
| 515 | Objects.equals(this.url, other.url) &&
|
---|
[11575] | 516 | Objects.equals(this.bestMarked, other.bestMarked) &&
|
---|
| 517 | Objects.equals(this.isGeoreferenceValid, other.isGeoreferenceValid) &&
|
---|
[8418] | 518 | Objects.equals(this.cookies, other.cookies) &&
|
---|
| 519 | Objects.equals(this.eulaAcceptanceRequired, other.eulaAcceptanceRequired) &&
|
---|
| 520 | Objects.equals(this.imageryType, other.imageryType) &&
|
---|
| 521 | Objects.equals(this.defaultMaxZoom, other.defaultMaxZoom) &&
|
---|
| 522 | Objects.equals(this.defaultMinZoom, other.defaultMinZoom) &&
|
---|
| 523 | Objects.equals(this.bounds, other.bounds) &&
|
---|
| 524 | Objects.equals(this.serverProjections, other.serverProjections) &&
|
---|
| 525 | Objects.equals(this.attributionText, other.attributionText) &&
|
---|
| 526 | Objects.equals(this.attributionLinkURL, other.attributionLinkURL) &&
|
---|
[11975] | 527 | Objects.equals(this.permissionReferenceURL, other.permissionReferenceURL) &&
|
---|
[8418] | 528 | Objects.equals(this.attributionImageURL, other.attributionImageURL) &&
|
---|
| 529 | Objects.equals(this.attributionImage, other.attributionImage) &&
|
---|
| 530 | Objects.equals(this.termsOfUseText, other.termsOfUseText) &&
|
---|
| 531 | Objects.equals(this.termsOfUseURL, other.termsOfUseURL) &&
|
---|
| 532 | Objects.equals(this.countryCode, other.countryCode) &&
|
---|
[11570] | 533 | Objects.equals(this.date, other.date) &&
|
---|
[8418] | 534 | Objects.equals(this.icon, other.icon) &&
|
---|
| 535 | Objects.equals(this.description, other.description) &&
|
---|
| 536 | Objects.equals(this.noTileHeaders, other.noTileHeaders) &&
|
---|
[9610] | 537 | Objects.equals(this.noTileChecksums, other.noTileChecksums) &&
|
---|
[11216] | 538 | Objects.equals(this.metadataHeaders, other.metadataHeaders) &&
|
---|
| 539 | Objects.equals(this.defaultLayers, other.defaultLayers);
|
---|
[11587] | 540 | // CHECKSTYLE.ON: BooleanExpressionComplexity
|
---|
[7186] | 541 | }
|
---|
[5369] | 542 |
|
---|
| 543 | @Override
|
---|
[9371] | 544 | public boolean equals(Object o) {
|
---|
| 545 | if (this == o) return true;
|
---|
| 546 | if (o == null || getClass() != o.getClass()) return false;
|
---|
| 547 | ImageryInfo that = (ImageryInfo) o;
|
---|
| 548 | return imageryType == that.imageryType && Objects.equals(url, that.url);
|
---|
[5369] | 549 | }
|
---|
| 550 |
|
---|
| 551 | @Override
|
---|
| 552 | public String toString() {
|
---|
| 553 | return "ImageryInfo{" +
|
---|
| 554 | "name='" + name + '\'' +
|
---|
| 555 | ", countryCode='" + countryCode + '\'' +
|
---|
| 556 | ", url='" + url + '\'' +
|
---|
| 557 | ", imageryType=" + imageryType +
|
---|
| 558 | '}';
|
---|
| 559 | }
|
---|
| 560 |
|
---|
| 561 | @Override
|
---|
[6690] | 562 | public int compareTo(ImageryInfo in) {
|
---|
[4405] | 563 | int i = countryCode.compareTo(in.countryCode);
|
---|
| 564 | if (i == 0) {
|
---|
[8404] | 565 | i = name.toLowerCase(Locale.ENGLISH).compareTo(in.name.toLowerCase(Locale.ENGLISH));
|
---|
[4405] | 566 | }
|
---|
| 567 | if (i == 0) {
|
---|
[3715] | 568 | i = url.compareTo(in.url);
|
---|
| 569 | }
|
---|
[4405] | 570 | if (i == 0) {
|
---|
[3715] | 571 | i = Double.compare(pixelPerDegree, in.pixelPerDegree);
|
---|
| 572 | }
|
---|
| 573 | return i;
|
---|
| 574 | }
|
---|
| 575 |
|
---|
[11889] | 576 | /**
|
---|
| 577 | * Determines if URL is equal to given imagery info.
|
---|
| 578 | * @param in imagery info
|
---|
| 579 | * @return {@code true} if URL is equal to given imagery info
|
---|
| 580 | */
|
---|
[6690] | 581 | public boolean equalsBaseValues(ImageryInfo in) {
|
---|
[3715] | 582 | return url.equals(in.url);
|
---|
| 583 | }
|
---|
| 584 |
|
---|
[10577] | 585 | /**
|
---|
| 586 | * Sets the pixel per degree value.
|
---|
| 587 | * @param ppd The ppd value
|
---|
| 588 | * @see #getPixelPerDegree()
|
---|
| 589 | */
|
---|
[3715] | 590 | public void setPixelPerDegree(double ppd) {
|
---|
| 591 | this.pixelPerDegree = ppd;
|
---|
| 592 | }
|
---|
| 593 |
|
---|
[6690] | 594 | /**
|
---|
| 595 | * Sets the maximum zoom level.
|
---|
| 596 | * @param defaultMaxZoom The maximum zoom level
|
---|
| 597 | */
|
---|
[4240] | 598 | public void setDefaultMaxZoom(int defaultMaxZoom) {
|
---|
| 599 | this.defaultMaxZoom = defaultMaxZoom;
|
---|
| 600 | }
|
---|
| 601 |
|
---|
[6690] | 602 | /**
|
---|
| 603 | * Sets the minimum zoom level.
|
---|
| 604 | * @param defaultMinZoom The minimum zoom level
|
---|
| 605 | */
|
---|
[4240] | 606 | public void setDefaultMinZoom(int defaultMinZoom) {
|
---|
| 607 | this.defaultMinZoom = defaultMinZoom;
|
---|
| 608 | }
|
---|
[4450] | 609 |
|
---|
[6690] | 610 | /**
|
---|
| 611 | * Sets the imagery polygonial bounds.
|
---|
| 612 | * @param b The imagery bounds (non-rectangular)
|
---|
| 613 | */
|
---|
[4423] | 614 | public void setBounds(ImageryBounds b) {
|
---|
[4195] | 615 | this.bounds = b;
|
---|
| 616 | }
|
---|
| 617 |
|
---|
[6690] | 618 | /**
|
---|
| 619 | * Returns the imagery polygonial bounds.
|
---|
| 620 | * @return The imagery bounds (non-rectangular)
|
---|
| 621 | */
|
---|
[4423] | 622 | public ImageryBounds getBounds() {
|
---|
[4198] | 623 | return bounds;
|
---|
| 624 | }
|
---|
| 625 |
|
---|
[4506] | 626 | @Override
|
---|
| 627 | public boolean requiresAttribution() {
|
---|
[12260] | 628 | return attributionText != null || attributionLinkURL != null || attributionImage != null
|
---|
| 629 | || termsOfUseText != null || termsOfUseURL != null;
|
---|
[4506] | 630 | }
|
---|
| 631 |
|
---|
| 632 | @Override
|
---|
[8526] | 633 | public String getAttributionText(int zoom, ICoordinate topLeft, ICoordinate botRight) {
|
---|
[4464] | 634 | return attributionText;
|
---|
| 635 | }
|
---|
| 636 |
|
---|
[4506] | 637 | @Override
|
---|
| 638 | public String getAttributionLinkURL() {
|
---|
| 639 | return attributionLinkURL;
|
---|
| 640 | }
|
---|
| 641 |
|
---|
[11975] | 642 | /**
|
---|
| 643 | * Return the permission reference URL.
|
---|
[11977] | 644 | * @return The url
|
---|
| 645 | * @see #setPermissionReferenceURL
|
---|
[11975] | 646 | * @since 11975
|
---|
| 647 | */
|
---|
| 648 | public String getPermissionReferenceURL() {
|
---|
| 649 | return permissionReferenceURL;
|
---|
| 650 | }
|
---|
| 651 |
|
---|
[4506] | 652 | @Override
|
---|
| 653 | public Image getAttributionImage() {
|
---|
| 654 | ImageIcon i = ImageProvider.getIfAvailable(attributionImage);
|
---|
| 655 | if (i != null) {
|
---|
| 656 | return i.getImage();
|
---|
| 657 | }
|
---|
| 658 | return null;
|
---|
| 659 | }
|
---|
| 660 |
|
---|
[12258] | 661 | /**
|
---|
| 662 | * Return the raw attribution logo information (an URL to the image).
|
---|
| 663 | * @return The url text
|
---|
| 664 | * @since 12257
|
---|
| 665 | */
|
---|
| 666 | public String getAttributionImageRaw() {
|
---|
| 667 | return attributionImage;
|
---|
| 668 | }
|
---|
| 669 |
|
---|
[4506] | 670 | @Override
|
---|
| 671 | public String getAttributionImageURL() {
|
---|
| 672 | return attributionImageURL;
|
---|
| 673 | }
|
---|
| 674 |
|
---|
| 675 | @Override
|
---|
| 676 | public String getTermsOfUseText() {
|
---|
| 677 | return termsOfUseText;
|
---|
| 678 | }
|
---|
| 679 |
|
---|
| 680 | @Override
|
---|
| 681 | public String getTermsOfUseURL() {
|
---|
| 682 | return termsOfUseURL;
|
---|
| 683 | }
|
---|
| 684 |
|
---|
[10577] | 685 | /**
|
---|
| 686 | * Set the attribution text
|
---|
| 687 | * @param text The text
|
---|
| 688 | * @see #getAttributionText(int, ICoordinate, ICoordinate)
|
---|
| 689 | */
|
---|
[4195] | 690 | public void setAttributionText(String text) {
|
---|
[4423] | 691 | attributionText = text;
|
---|
[4195] | 692 | }
|
---|
| 693 |
|
---|
[10577] | 694 | /**
|
---|
| 695 | * Set the attribution image
|
---|
| 696 | * @param url The url of the image.
|
---|
| 697 | * @see #getAttributionImageURL()
|
---|
| 698 | */
|
---|
| 699 | public void setAttributionImageURL(String url) {
|
---|
| 700 | attributionImageURL = url;
|
---|
[4492] | 701 | }
|
---|
| 702 |
|
---|
[10577] | 703 | /**
|
---|
| 704 | * Set the image for the attribution
|
---|
| 705 | * @param res The image resource
|
---|
| 706 | * @see #getAttributionImage()
|
---|
| 707 | */
|
---|
| 708 | public void setAttributionImage(String res) {
|
---|
| 709 | attributionImage = res;
|
---|
[4464] | 710 | }
|
---|
| 711 |
|
---|
[10577] | 712 | /**
|
---|
| 713 | * Sets the URL the attribution should link to.
|
---|
| 714 | * @param url The url.
|
---|
| 715 | * @see #getAttributionLinkURL()
|
---|
| 716 | */
|
---|
| 717 | public void setAttributionLinkURL(String url) {
|
---|
| 718 | attributionLinkURL = url;
|
---|
[4195] | 719 | }
|
---|
| 720 |
|
---|
[10577] | 721 | /**
|
---|
[11975] | 722 | * Sets the permission reference URL.
|
---|
| 723 | * @param url The url.
|
---|
| 724 | * @see #getPermissionReferenceURL()
|
---|
| 725 | * @since 11975
|
---|
| 726 | */
|
---|
| 727 | public void setPermissionReferenceURL(String url) {
|
---|
| 728 | permissionReferenceURL = url;
|
---|
| 729 | }
|
---|
| 730 |
|
---|
| 731 | /**
|
---|
[10577] | 732 | * Sets the text to display to the user as terms of use.
|
---|
| 733 | * @param text The text
|
---|
| 734 | * @see #getTermsOfUseText()
|
---|
| 735 | */
|
---|
[4492] | 736 | public void setTermsOfUseText(String text) {
|
---|
| 737 | termsOfUseText = text;
|
---|
| 738 | }
|
---|
| 739 |
|
---|
[10577] | 740 | /**
|
---|
| 741 | * Sets a url that links to the terms of use text.
|
---|
| 742 | * @param text The url.
|
---|
| 743 | * @see #getTermsOfUseURL()
|
---|
| 744 | */
|
---|
[4195] | 745 | public void setTermsOfUseURL(String text) {
|
---|
| 746 | termsOfUseURL = text;
|
---|
| 747 | }
|
---|
| 748 |
|
---|
[6690] | 749 | /**
|
---|
| 750 | * Sets the extended URL of this entry.
|
---|
| 751 | * @param url Entry extended URL containing in addition of service URL, its type and min/max zoom info
|
---|
| 752 | */
|
---|
[4240] | 753 | public void setExtendedUrl(String url) {
|
---|
[3974] | 754 | CheckParameterUtil.ensureParameterNotNull(url);
|
---|
[4450] | 755 |
|
---|
[4432] | 756 | // Default imagery type is WMS
|
---|
| 757 | this.url = url;
|
---|
| 758 | this.imageryType = ImageryType.WMS;
|
---|
| 759 |
|
---|
[4194] | 760 | defaultMaxZoom = 0;
|
---|
| 761 | defaultMinZoom = 0;
|
---|
[3715] | 762 | for (ImageryType type : ImageryType.values()) {
|
---|
[10735] | 763 | Matcher m = Pattern.compile(type.getTypeString()+"(?:\\[(?:(\\d+)[,-])?(\\d+)\\])?:(.*)").matcher(url);
|
---|
[6310] | 764 | if (m.matches()) {
|
---|
[4188] | 765 | this.url = m.group(3);
|
---|
[3715] | 766 | this.imageryType = type;
|
---|
[6310] | 767 | if (m.group(2) != null) {
|
---|
[8365] | 768 | defaultMaxZoom = Integer.parseInt(m.group(2));
|
---|
[4188] | 769 | }
|
---|
[6310] | 770 | if (m.group(1) != null) {
|
---|
[8365] | 771 | defaultMinZoom = Integer.parseInt(m.group(1));
|
---|
[4188] | 772 | }
|
---|
[4432] | 773 | break;
|
---|
[3715] | 774 | }
|
---|
| 775 | }
|
---|
| 776 |
|
---|
[10577] | 777 | if (serverProjections.isEmpty()) {
|
---|
[10212] | 778 | serverProjections = new ArrayList<>();
|
---|
| 779 | Matcher m = Pattern.compile(".*\\{PROJ\\(([^)}]+)\\)\\}.*").matcher(url.toUpperCase(Locale.ENGLISH));
|
---|
| 780 | if (m.matches()) {
|
---|
| 781 | for (String p : m.group(1).split(",")) {
|
---|
| 782 | serverProjections.add(p);
|
---|
[4432] | 783 | }
|
---|
| 784 | }
|
---|
| 785 | }
|
---|
[3715] | 786 | }
|
---|
| 787 |
|
---|
[6690] | 788 | /**
|
---|
| 789 | * Returns the entry name.
|
---|
| 790 | * @return The entry name
|
---|
[6968] | 791 | * @since 6968
|
---|
| 792 | */
|
---|
| 793 | public String getOriginalName() {
|
---|
| 794 | return this.origName != null ? this.origName : this.name;
|
---|
| 795 | }
|
---|
| 796 |
|
---|
| 797 | /**
|
---|
[8091] | 798 | * Sets the entry name and handle translation.
|
---|
[8093] | 799 | * @param language The used language
|
---|
[6968] | 800 | * @param name The entry name
|
---|
[8091] | 801 | * @since 8091
|
---|
[6968] | 802 | */
|
---|
[8091] | 803 | public void setName(String language, String name) {
|
---|
| 804 | boolean isdefault = LanguageInfo.getJOSMLocaleCode(null).equals(language);
|
---|
[8510] | 805 | if (LanguageInfo.isBetterLanguage(langName, language)) {
|
---|
[8091] | 806 | this.name = isdefault ? tr(name) : name;
|
---|
| 807 | this.langName = language;
|
---|
| 808 | }
|
---|
[8510] | 809 | if (origName == null || isdefault) {
|
---|
[8091] | 810 | this.origName = name;
|
---|
| 811 | }
|
---|
[6968] | 812 | }
|
---|
| 813 |
|
---|
[10577] | 814 | /**
|
---|
| 815 | * Store the id of this info to the preferences and clear it afterwards.
|
---|
| 816 | */
|
---|
[7203] | 817 | public void clearId() {
|
---|
| 818 | if (this.id != null) {
|
---|
[12841] | 819 | Collection<String> newAddedIds = new TreeSet<>(Main.pref.getList("imagery.layers.addedIds"));
|
---|
[7203] | 820 | newAddedIds.add(this.id);
|
---|
[12841] | 821 | Main.pref.putList("imagery.layers.addedIds", new ArrayList<>(newAddedIds));
|
---|
[7203] | 822 | }
|
---|
[8634] | 823 | setId(null);
|
---|
[7203] | 824 | }
|
---|
[7186] | 825 |
|
---|
| 826 | /**
|
---|
[6690] | 827 | * Determines if this entry is enabled by default.
|
---|
| 828 | * @return {@code true} if this entry is enabled by default, {@code false} otherwise
|
---|
| 829 | */
|
---|
[4240] | 830 | public boolean isDefaultEntry() {
|
---|
| 831 | return defaultEntry;
|
---|
| 832 | }
|
---|
| 833 |
|
---|
[6690] | 834 | /**
|
---|
| 835 | * Sets the default state of this entry.
|
---|
| 836 | * @param defaultEntry {@code true} if this entry has to be enabled by default, {@code false} otherwise
|
---|
| 837 | */
|
---|
[4240] | 838 | public void setDefaultEntry(boolean defaultEntry) {
|
---|
| 839 | this.defaultEntry = defaultEntry;
|
---|
| 840 | }
|
---|
| 841 |
|
---|
[8092] | 842 | /**
|
---|
[10577] | 843 | * Gets the pixel per degree value
|
---|
| 844 | * @return The ppd value.
|
---|
| 845 | */
|
---|
[3715] | 846 | public double getPixelPerDegree() {
|
---|
| 847 | return this.pixelPerDegree;
|
---|
| 848 | }
|
---|
| 849 |
|
---|
[6690] | 850 | /**
|
---|
| 851 | * Returns the maximum zoom level.
|
---|
| 852 | * @return The maximum zoom level
|
---|
| 853 | */
|
---|
[8344] | 854 | @Override
|
---|
[3715] | 855 | public int getMaxZoom() {
|
---|
[4432] | 856 | return this.defaultMaxZoom;
|
---|
[3715] | 857 | }
|
---|
| 858 |
|
---|
[6690] | 859 | /**
|
---|
| 860 | * Returns the minimum zoom level.
|
---|
| 861 | * @return The minimum zoom level
|
---|
| 862 | */
|
---|
[8344] | 863 | @Override
|
---|
[4188] | 864 | public int getMinZoom() {
|
---|
| 865 | return this.defaultMinZoom;
|
---|
| 866 | }
|
---|
| 867 |
|
---|
[6690] | 868 | /**
|
---|
[8065] | 869 | * Returns the description text when existing.
|
---|
| 870 | * @return The description
|
---|
[8067] | 871 | * @since 8065
|
---|
[8065] | 872 | */
|
---|
| 873 | public String getDescription() {
|
---|
| 874 | return this.description;
|
---|
| 875 | }
|
---|
| 876 |
|
---|
| 877 | /**
|
---|
| 878 | * Sets the description text when existing.
|
---|
[8093] | 879 | * @param language The used language
|
---|
[8065] | 880 | * @param description the imagery description text
|
---|
[8091] | 881 | * @since 8091
|
---|
[8065] | 882 | */
|
---|
[8091] | 883 | public void setDescription(String language, String description) {
|
---|
| 884 | boolean isdefault = LanguageInfo.getJOSMLocaleCode(null).equals(language);
|
---|
[8510] | 885 | if (LanguageInfo.isBetterLanguage(langDescription, language)) {
|
---|
[8091] | 886 | this.description = isdefault ? tr(description) : description;
|
---|
| 887 | this.langDescription = language;
|
---|
| 888 | }
|
---|
[8065] | 889 | }
|
---|
| 890 |
|
---|
| 891 | /**
|
---|
| 892 | * Returns a tool tip text for display.
|
---|
| 893 | * @return The text
|
---|
[8067] | 894 | * @since 8065
|
---|
[8065] | 895 | */
|
---|
| 896 | public String getToolTipText() {
|
---|
[11649] | 897 | StringBuilder res = new StringBuilder(getName());
|
---|
[11570] | 898 | boolean html = false;
|
---|
[11649] | 899 | String dateStr = getDate();
|
---|
| 900 | if (dateStr != null && !dateStr.isEmpty()) {
|
---|
| 901 | res.append("<br>").append(tr("Date of imagery: {0}", dateStr));
|
---|
[11570] | 902 | html = true;
|
---|
| 903 | }
|
---|
[11575] | 904 | if (bestMarked) {
|
---|
[11649] | 905 | res.append("<br>").append(tr("This imagery is marked as best in this region in other editors."));
|
---|
[11619] | 906 | html = true;
|
---|
[11575] | 907 | }
|
---|
[8065] | 908 | String desc = getDescription();
|
---|
| 909 | if (desc != null && !desc.isEmpty()) {
|
---|
[11848] | 910 | res.append("<br>").append(Utils.escapeReservedCharactersHTML(desc));
|
---|
[11570] | 911 | html = true;
|
---|
[8065] | 912 | }
|
---|
[11570] | 913 | if (html) {
|
---|
[11649] | 914 | res.insert(0, "<html>").append("</html>");
|
---|
[11570] | 915 | }
|
---|
[11649] | 916 | return res.toString();
|
---|
[8065] | 917 | }
|
---|
| 918 |
|
---|
| 919 | /**
|
---|
[6690] | 920 | * Returns the EULA acceptance URL, if any.
|
---|
| 921 | * @return The URL to an EULA text that has to be accepted before use, or {@code null}
|
---|
| 922 | */
|
---|
[4195] | 923 | public String getEulaAcceptanceRequired() {
|
---|
| 924 | return eulaAcceptanceRequired;
|
---|
| 925 | }
|
---|
| 926 |
|
---|
[6690] | 927 | /**
|
---|
| 928 | * Sets the EULA acceptance URL.
|
---|
| 929 | * @param eulaAcceptanceRequired The URL to an EULA text that has to be accepted before use
|
---|
| 930 | */
|
---|
[4240] | 931 | public void setEulaAcceptanceRequired(String eulaAcceptanceRequired) {
|
---|
| 932 | this.eulaAcceptanceRequired = eulaAcceptanceRequired;
|
---|
| 933 | }
|
---|
| 934 |
|
---|
[6690] | 935 | /**
|
---|
| 936 | * Returns the ISO 3166-1-alpha-2 country code.
|
---|
| 937 | * @return The country code (2 letters)
|
---|
| 938 | */
|
---|
[4405] | 939 | public String getCountryCode() {
|
---|
| 940 | return countryCode;
|
---|
| 941 | }
|
---|
| 942 |
|
---|
[6690] | 943 | /**
|
---|
| 944 | * Sets the ISO 3166-1-alpha-2 country code.
|
---|
| 945 | * @param countryCode The country code (2 letters)
|
---|
| 946 | */
|
---|
[4405] | 947 | public void setCountryCode(String countryCode) {
|
---|
| 948 | this.countryCode = countryCode;
|
---|
| 949 | }
|
---|
| 950 |
|
---|
[6690] | 951 | /**
|
---|
[11570] | 952 | * Returns the date information.
|
---|
| 953 | * @return The date (in the form YYYY-MM-DD;YYYY-MM-DD, where
|
---|
| 954 | * DD and MM as well as a second date are optional)
|
---|
| 955 | * @since 11570
|
---|
| 956 | */
|
---|
| 957 | public String getDate() {
|
---|
| 958 | return date;
|
---|
| 959 | }
|
---|
| 960 |
|
---|
| 961 | /**
|
---|
| 962 | * Sets the date information.
|
---|
| 963 | * @param date The date information
|
---|
| 964 | * @since 11570
|
---|
| 965 | */
|
---|
| 966 | public void setDate(String date) {
|
---|
| 967 | this.date = date;
|
---|
| 968 | }
|
---|
| 969 |
|
---|
| 970 | /**
|
---|
[6690] | 971 | * Returns the entry icon.
|
---|
| 972 | * @return The entry icon
|
---|
| 973 | */
|
---|
[4713] | 974 | public String getIcon() {
|
---|
| 975 | return icon;
|
---|
| 976 | }
|
---|
| 977 |
|
---|
[6690] | 978 | /**
|
---|
| 979 | * Sets the entry icon.
|
---|
| 980 | * @param icon The entry icon
|
---|
| 981 | */
|
---|
[4713] | 982 | public void setIcon(String icon) {
|
---|
| 983 | this.icon = icon;
|
---|
| 984 | }
|
---|
| 985 |
|
---|
[4240] | 986 | /**
|
---|
| 987 | * Get the projections supported by the server. Only relevant for
|
---|
| 988 | * WMS-type ImageryInfo at the moment.
|
---|
| 989 | * @return null, if no projections have been specified; the list
|
---|
| 990 | * of supported projections otherwise.
|
---|
| 991 | */
|
---|
| 992 | public List<String> getServerProjections() {
|
---|
| 993 | return Collections.unmodifiableList(serverProjections);
|
---|
| 994 | }
|
---|
| 995 |
|
---|
[10577] | 996 | /**
|
---|
| 997 | * Sets the list of collections the server supports
|
---|
| 998 | * @param serverProjections The list of supported projections
|
---|
| 999 | */
|
---|
[4240] | 1000 | public void setServerProjections(Collection<String> serverProjections) {
|
---|
[10577] | 1001 | CheckParameterUtil.ensureParameterNotNull(serverProjections, "serverProjections");
|
---|
[7005] | 1002 | this.serverProjections = new ArrayList<>(serverProjections);
|
---|
[4240] | 1003 | }
|
---|
| 1004 |
|
---|
[6690] | 1005 | /**
|
---|
| 1006 | * Returns the extended URL, containing in addition of service URL, its type and min/max zoom info.
|
---|
| 1007 | * @return The extended URL
|
---|
| 1008 | */
|
---|
[4240] | 1009 | public String getExtendedUrl() {
|
---|
[6690] | 1010 | return imageryType.getTypeString() + (defaultMaxZoom != 0
|
---|
[10462] | 1011 | ? ('['+(defaultMinZoom != 0 ? (Integer.toString(defaultMinZoom) + ',') : "")+defaultMaxZoom+']') : "") + ':' + url;
|
---|
[3715] | 1012 | }
|
---|
| 1013 |
|
---|
[10577] | 1014 | /**
|
---|
| 1015 | * Gets a unique toolbar key to store this layer as toolbar item
|
---|
| 1016 | * @return The kay.
|
---|
| 1017 | */
|
---|
[6690] | 1018 | public String getToolbarName() {
|
---|
[3715] | 1019 | String res = name;
|
---|
[8393] | 1020 | if (pixelPerDegree != 0) {
|
---|
[3715] | 1021 | res += "#PPD="+pixelPerDegree;
|
---|
| 1022 | }
|
---|
| 1023 | return res;
|
---|
| 1024 | }
|
---|
| 1025 |
|
---|
[10577] | 1026 | /**
|
---|
| 1027 | * Gets the name that should be displayed in the menu to add this imagery layer.
|
---|
| 1028 | * @return The text.
|
---|
| 1029 | */
|
---|
[6690] | 1030 | public String getMenuName() {
|
---|
[3715] | 1031 | String res = name;
|
---|
[8393] | 1032 | if (pixelPerDegree != 0) {
|
---|
[8846] | 1033 | res += " ("+pixelPerDegree+')';
|
---|
[3715] | 1034 | }
|
---|
| 1035 | return res;
|
---|
| 1036 | }
|
---|
| 1037 |
|
---|
[6690] | 1038 | /**
|
---|
| 1039 | * Determines if this entry requires attribution.
|
---|
| 1040 | * @return {@code true} if some attribution text has to be displayed, {@code false} otherwise
|
---|
| 1041 | */
|
---|
| 1042 | public boolean hasAttribution() {
|
---|
[4198] | 1043 | return attributionText != null;
|
---|
| 1044 | }
|
---|
| 1045 |
|
---|
[6690] | 1046 | /**
|
---|
| 1047 | * Copies attribution from another {@code ImageryInfo}.
|
---|
| 1048 | * @param i The other imagery info to get attribution from
|
---|
| 1049 | */
|
---|
| 1050 | public void copyAttribution(ImageryInfo i) {
|
---|
[4198] | 1051 | this.attributionImage = i.attributionImage;
|
---|
[4492] | 1052 | this.attributionImageURL = i.attributionImageURL;
|
---|
| 1053 | this.attributionText = i.attributionText;
|
---|
[4198] | 1054 | this.attributionLinkURL = i.attributionLinkURL;
|
---|
[4492] | 1055 | this.termsOfUseText = i.termsOfUseText;
|
---|
[4198] | 1056 | this.termsOfUseURL = i.termsOfUseURL;
|
---|
| 1057 | }
|
---|
| 1058 |
|
---|
[4492] | 1059 | /**
|
---|
[6690] | 1060 | * Applies the attribution from this object to a tile source.
|
---|
| 1061 | * @param s The tile source
|
---|
[4492] | 1062 | */
|
---|
[4506] | 1063 | public void setAttribution(AbstractTileSource s) {
|
---|
[4492] | 1064 | if (attributionText != null) {
|
---|
[6990] | 1065 | if ("osm".equals(attributionText)) {
|
---|
[4492] | 1066 | s.setAttributionText(new Mapnik().getAttributionText(0, null, null));
|
---|
| 1067 | } else {
|
---|
| 1068 | s.setAttributionText(attributionText);
|
---|
| 1069 | }
|
---|
| 1070 | }
|
---|
| 1071 | if (attributionLinkURL != null) {
|
---|
[6990] | 1072 | if ("osm".equals(attributionLinkURL)) {
|
---|
[4195] | 1073 | s.setAttributionLinkURL(new Mapnik().getAttributionLinkURL());
|
---|
[4492] | 1074 | } else {
|
---|
[4195] | 1075 | s.setAttributionLinkURL(attributionLinkURL);
|
---|
[4492] | 1076 | }
|
---|
[4195] | 1077 | }
|
---|
[4492] | 1078 | if (attributionImage != null) {
|
---|
[4195] | 1079 | ImageIcon i = ImageProvider.getIfAvailable(null, attributionImage);
|
---|
[4492] | 1080 | if (i != null) {
|
---|
[4195] | 1081 | s.setAttributionImage(i.getImage());
|
---|
[4492] | 1082 | }
|
---|
[4195] | 1083 | }
|
---|
[4492] | 1084 | if (attributionImageURL != null) {
|
---|
| 1085 | s.setAttributionImageURL(attributionImageURL);
|
---|
| 1086 | }
|
---|
| 1087 | if (termsOfUseText != null) {
|
---|
| 1088 | s.setTermsOfUseText(termsOfUseText);
|
---|
| 1089 | }
|
---|
| 1090 | if (termsOfUseURL != null) {
|
---|
[6990] | 1091 | if ("osm".equals(termsOfUseURL)) {
|
---|
[4195] | 1092 | s.setTermsOfUseURL(new Mapnik().getTermsOfUseURL());
|
---|
[4492] | 1093 | } else {
|
---|
[4195] | 1094 | s.setTermsOfUseURL(termsOfUseURL);
|
---|
[4492] | 1095 | }
|
---|
[4195] | 1096 | }
|
---|
| 1097 | }
|
---|
| 1098 |
|
---|
[6690] | 1099 | /**
|
---|
| 1100 | * Returns the imagery type.
|
---|
| 1101 | * @return The imagery type
|
---|
| 1102 | */
|
---|
[3715] | 1103 | public ImageryType getImageryType() {
|
---|
| 1104 | return imageryType;
|
---|
| 1105 | }
|
---|
| 1106 |
|
---|
[6690] | 1107 | /**
|
---|
| 1108 | * Sets the imagery type.
|
---|
| 1109 | * @param imageryType The imagery type
|
---|
| 1110 | */
|
---|
[4240] | 1111 | public void setImageryType(ImageryType imageryType) {
|
---|
| 1112 | this.imageryType = imageryType;
|
---|
| 1113 | }
|
---|
| 1114 |
|
---|
[3934] | 1115 | /**
|
---|
| 1116 | * Returns true if this layer's URL is matched by one of the regular
|
---|
| 1117 | * expressions kept by the current OsmApi instance.
|
---|
[6690] | 1118 | * @return {@code true} is this entry is blacklisted, {@code false} otherwise
|
---|
[3934] | 1119 | */
|
---|
[3826] | 1120 | public boolean isBlacklisted() {
|
---|
[7476] | 1121 | Capabilities capabilities = OsmApi.getOsmApi().getCapabilities();
|
---|
| 1122 | return capabilities != null && capabilities.isOnImageryBlacklist(this.url);
|
---|
[3826] | 1123 | }
|
---|
[8344] | 1124 |
|
---|
[8420] | 1125 | /**
|
---|
[8459] | 1126 | * Sets the map of <header name, header value> that if any of this header
|
---|
[8420] | 1127 | * will be returned, then this tile will be treated as "no tile at this zoom level"
|
---|
| 1128 | *
|
---|
[8459] | 1129 | * @param noTileHeaders Map of <header name, header value> which will be treated as "no tile at this zoom level"
|
---|
[9614] | 1130 | * @since 9613
|
---|
[8420] | 1131 | */
|
---|
[9755] | 1132 | public void setNoTileHeaders(MultiMap<String, String> noTileHeaders) {
|
---|
[11527] | 1133 | if (noTileHeaders == null || noTileHeaders.isEmpty()) {
|
---|
[9755] | 1134 | this.noTileHeaders = null;
|
---|
| 1135 | } else {
|
---|
| 1136 | this.noTileHeaders = noTileHeaders.toMap();
|
---|
| 1137 | }
|
---|
[8344] | 1138 | }
|
---|
| 1139 |
|
---|
| 1140 | @Override
|
---|
[9755] | 1141 | public Map<String, Set<String>> getNoTileHeaders() {
|
---|
[8344] | 1142 | return noTileHeaders;
|
---|
| 1143 | }
|
---|
[8418] | 1144 |
|
---|
[8420] | 1145 | /**
|
---|
[9610] | 1146 | * Sets the map of <checksum type, checksum value> that if any tile with that checksum
|
---|
| 1147 | * will be returned, then this tile will be treated as "no tile at this zoom level"
|
---|
| 1148 | *
|
---|
| 1149 | * @param noTileChecksums Map of <checksum type, checksum value> which will be treated as "no tile at this zoom level"
|
---|
[9614] | 1150 | * @since 9613
|
---|
[9610] | 1151 | */
|
---|
[9755] | 1152 | public void setNoTileChecksums(MultiMap<String, String> noTileChecksums) {
|
---|
[11527] | 1153 | if (noTileChecksums == null || noTileChecksums.isEmpty()) {
|
---|
[9755] | 1154 | this.noTileChecksums = null;
|
---|
| 1155 | } else {
|
---|
| 1156 | this.noTileChecksums = noTileChecksums.toMap();
|
---|
| 1157 | }
|
---|
[9610] | 1158 | }
|
---|
| 1159 |
|
---|
| 1160 | @Override
|
---|
[9755] | 1161 | public Map<String, Set<String>> getNoTileChecksums() {
|
---|
[9610] | 1162 | return noTileChecksums;
|
---|
| 1163 | }
|
---|
| 1164 |
|
---|
| 1165 | /**
|
---|
[8459] | 1166 | * Returns the map of <header name, metadata key> indicating, which HTTP headers should
|
---|
[8420] | 1167 | * be moved to metadata
|
---|
| 1168 | *
|
---|
[8459] | 1169 | * @param metadataHeaders map of <header name, metadata key> indicating, which HTTP headers should be moved to metadata
|
---|
[8420] | 1170 | * @since 8418
|
---|
| 1171 | */
|
---|
[8418] | 1172 | public void setMetadataHeaders(Map<String, String> metadataHeaders) {
|
---|
[11527] | 1173 | if (metadataHeaders == null || metadataHeaders.isEmpty()) {
|
---|
| 1174 | this.metadataHeaders = null;
|
---|
| 1175 | } else {
|
---|
| 1176 | this.metadataHeaders = metadataHeaders;
|
---|
| 1177 | }
|
---|
[8418] | 1178 | }
|
---|
[9134] | 1179 |
|
---|
[10577] | 1180 | /**
|
---|
| 1181 | * Gets the flag if the georeference is valid.
|
---|
| 1182 | * @return <code>true</code> if it is valid.
|
---|
| 1183 | */
|
---|
[9134] | 1184 | public boolean isGeoreferenceValid() {
|
---|
| 1185 | return isGeoreferenceValid;
|
---|
| 1186 | }
|
---|
| 1187 |
|
---|
[10577] | 1188 | /**
|
---|
| 1189 | * Sets an indicator that the georeference is valid
|
---|
| 1190 | * @param isGeoreferenceValid <code>true</code> if it is marked as valid.
|
---|
| 1191 | */
|
---|
[9134] | 1192 | public void setGeoreferenceValid(boolean isGeoreferenceValid) {
|
---|
| 1193 | this.isGeoreferenceValid = isGeoreferenceValid;
|
---|
| 1194 | }
|
---|
| 1195 |
|
---|
[9658] | 1196 | /**
|
---|
[11575] | 1197 | * Returns the status of "best" marked status in other editors.
|
---|
| 1198 | * @return <code>true</code> if it is marked as best.
|
---|
| 1199 | * @since 11575
|
---|
| 1200 | */
|
---|
| 1201 | public boolean isBestMarked() {
|
---|
| 1202 | return bestMarked;
|
---|
| 1203 | }
|
---|
| 1204 |
|
---|
| 1205 | /**
|
---|
| 1206 | * Sets an indicator that in other editors it is marked as best imagery
|
---|
| 1207 | * @param bestMarked <code>true</code> if it is marked as best in other editors.
|
---|
| 1208 | * @since 11575
|
---|
| 1209 | */
|
---|
| 1210 | public void setBestMarked(boolean bestMarked) {
|
---|
| 1211 | this.bestMarked = bestMarked;
|
---|
| 1212 | }
|
---|
| 1213 |
|
---|
| 1214 | /**
|
---|
[9658] | 1215 | * Adds a mirror entry. Mirror entries are completed with the data from the master entry
|
---|
| 1216 | * and only describe another method to access identical data.
|
---|
| 1217 | *
|
---|
| 1218 | * @param entry the mirror to be added
|
---|
| 1219 | * @since 9658
|
---|
| 1220 | */
|
---|
| 1221 | public void addMirror(ImageryInfo entry) {
|
---|
| 1222 | if (mirrors == null) {
|
---|
| 1223 | mirrors = new ArrayList<>();
|
---|
| 1224 | }
|
---|
| 1225 | mirrors.add(entry);
|
---|
| 1226 | }
|
---|
| 1227 |
|
---|
| 1228 | /**
|
---|
| 1229 | * Returns the mirror entries. Entries are completed with master entry data.
|
---|
| 1230 | *
|
---|
| 1231 | * @return the list of mirrors
|
---|
| 1232 | * @since 9658
|
---|
| 1233 | */
|
---|
| 1234 | public List<ImageryInfo> getMirrors() {
|
---|
| 1235 | List<ImageryInfo> l = new ArrayList<>();
|
---|
| 1236 | if (mirrors != null) {
|
---|
[11570] | 1237 | int num = 1;
|
---|
[9658] | 1238 | for (ImageryInfo i : mirrors) {
|
---|
| 1239 | ImageryInfo n = new ImageryInfo(this);
|
---|
| 1240 | if (i.defaultMaxZoom != 0) {
|
---|
| 1241 | n.defaultMaxZoom = i.defaultMaxZoom;
|
---|
| 1242 | }
|
---|
| 1243 | if (i.defaultMinZoom != 0) {
|
---|
| 1244 | n.defaultMinZoom = i.defaultMinZoom;
|
---|
| 1245 | }
|
---|
[10577] | 1246 | n.setServerProjections(i.getServerProjections());
|
---|
[9658] | 1247 | n.url = i.url;
|
---|
| 1248 | n.imageryType = i.imageryType;
|
---|
| 1249 | if (i.getTileSize() != 0) {
|
---|
| 1250 | n.setTileSize(i.getTileSize());
|
---|
| 1251 | }
|
---|
[11571] | 1252 | if (n.id != null) {
|
---|
[11570] | 1253 | n.id = n.id + "_mirror"+num;
|
---|
| 1254 | }
|
---|
[11571] | 1255 | if (num > 1) {
|
---|
[11570] | 1256 | n.name = tr("{0} mirror server {1}", n.name, num);
|
---|
[11577] | 1257 | if (n.origName != null) {
|
---|
[11572] | 1258 | n.origName += " mirror server " + num;
|
---|
| 1259 | }
|
---|
[11570] | 1260 | } else {
|
---|
| 1261 | n.name = tr("{0} mirror server", n.name);
|
---|
[11577] | 1262 | if (n.origName != null) {
|
---|
[11572] | 1263 | n.origName += " mirror server";
|
---|
| 1264 | }
|
---|
[11570] | 1265 | }
|
---|
[9658] | 1266 | l.add(n);
|
---|
[11570] | 1267 | ++num;
|
---|
[9658] | 1268 | }
|
---|
| 1269 | }
|
---|
| 1270 | return l;
|
---|
| 1271 | }
|
---|
[11216] | 1272 |
|
---|
| 1273 | /**
|
---|
| 1274 | * Returns default layers that should be shown for this Imagery (if at all supported by imagery provider)
|
---|
| 1275 | * If no layer is set to default and there is more than one imagery available, then user will be asked to choose the layer
|
---|
| 1276 | * to work on
|
---|
| 1277 | * @return Collection of the layer names
|
---|
| 1278 | */
|
---|
[11257] | 1279 | public Collection<DefaultLayer> getDefaultLayers() {
|
---|
[11216] | 1280 | return defaultLayers;
|
---|
| 1281 | }
|
---|
| 1282 |
|
---|
| 1283 | /**
|
---|
| 1284 | * Sets the default layers that user will work with
|
---|
[11217] | 1285 | * @param layers set the list of default layers
|
---|
[11216] | 1286 | */
|
---|
[11257] | 1287 | public void setDefaultLayers(Collection<DefaultLayer> layers) {
|
---|
| 1288 | if (ImageryType.WMTS.equals(this.imageryType)) {
|
---|
| 1289 | CheckParameterUtil.ensureThat(layers == null ||
|
---|
| 1290 | layers.isEmpty() ||
|
---|
| 1291 | layers.iterator().next() instanceof WMTSDefaultLayer, "Incorrect default layer");
|
---|
| 1292 | }
|
---|
[11216] | 1293 | this.defaultLayers = layers;
|
---|
| 1294 | }
|
---|
[3715] | 1295 | }
|
---|