source: josm/trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java@ 8344

Last change on this file since 8344 was 8344, checked in by bastiK, 9 years ago

applied #10454 - Mapbox "empty" tile (imagery with zoom level > 17) (patch by wiktorn)

  • Property svn:eol-style set to native
File size: 32.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Image;
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.Collections;
11import java.util.List;
12import java.util.Map;
13import java.util.Objects;
14import java.util.TreeSet;
15import java.util.regex.Matcher;
16import java.util.regex.Pattern;
17
18import javax.swing.ImageIcon;
19
20import org.openstreetmap.gui.jmapviewer.Coordinate;
21import org.openstreetmap.gui.jmapviewer.interfaces.Attributed;
22import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTileSource;
23import org.openstreetmap.gui.jmapviewer.tilesources.OsmTileSource.Mapnik;
24import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.data.Bounds;
27import org.openstreetmap.josm.data.Preferences.pref;
28import org.openstreetmap.josm.io.Capabilities;
29import org.openstreetmap.josm.io.OsmApi;
30import org.openstreetmap.josm.tools.CheckParameterUtil;
31import org.openstreetmap.josm.tools.ImageProvider;
32import org.openstreetmap.josm.tools.LanguageInfo;
33
34/**
35 * Class that stores info about an image background layer.
36 *
37 * @author Frederik Ramm
38 */
39public class ImageryInfo extends TileSourceInfo implements Comparable<ImageryInfo>, Attributed {
40
41 /**
42 * Type of imagery entry.
43 */
44 public enum ImageryType {
45 /** A WMS (Web Map Service) entry. **/
46 WMS("wms"),
47 /** A TMS (Tile Map Service) entry. **/
48 TMS("tms"),
49 /** An HTML proxy (previously used for Yahoo imagery) entry. **/
50 HTML("html"),
51 /** TMS entry for Microsoft Bing. */
52 BING("bing"),
53 /** TMS entry for Russian company <a href="https://wiki.openstreetmap.org/wiki/WikiProject_Russia/kosmosnimki">ScanEx</a>. **/
54 SCANEX("scanex"),
55 /** A WMS endpoint entry only stores the WMS server info, without layer, which are chosen later by the user. **/
56 WMS_ENDPOINT("wms_endpoint");
57
58
59 private final String typeString;
60
61 private ImageryType(String urlString) {
62 this.typeString = urlString;
63 }
64
65 /**
66 * Returns the unique string identifying this type.
67 * @return the unique string identifying this type
68 * @since 6690
69 */
70 public final String getTypeString() {
71 return typeString;
72 }
73
74 /**
75 * Returns the imagery type from the given type string.
76 * @param s The type string
77 * @return the imagery type matching the given type string
78 */
79 public static ImageryType fromString(String s) {
80 for (ImageryType type : ImageryType.values()) {
81 if (type.getTypeString().equals(s)) {
82 return type;
83 }
84 }
85 return null;
86 }
87 }
88
89 /**
90 * Multi-polygon bounds for imagery backgrounds.
91 * Used to display imagery coverage in preferences and to determine relevant imagery entries based on edit location.
92 */
93 public static class ImageryBounds extends Bounds {
94
95 /**
96 * Constructs a new {@code ImageryBounds} from string.
97 * @param asString The string containing the list of shapes defining this bounds
98 * @param separator The shape separator in the given string, usually a comma
99 */
100 public ImageryBounds(String asString, String separator) {
101 super(asString, separator);
102 }
103
104 private List<Shape> shapes = new ArrayList<>();
105
106 /**
107 * Adds a new shape to this bounds.
108 * @param shape The shape to add
109 */
110 public final void addShape(Shape shape) {
111 this.shapes.add(shape);
112 }
113
114 /**
115 * Sets the list of shapes defining this bounds.
116 * @param shapes The list of shapes defining this bounds.
117 */
118 public final void setShapes(List<Shape> shapes) {
119 this.shapes = shapes;
120 }
121
122 /**
123 * Returns the list of shapes defining this bounds.
124 * @return The list of shapes defining this bounds
125 */
126 public final List<Shape> getShapes() {
127 return shapes;
128 }
129
130 @Override
131 public int hashCode() {
132 final int prime = 31;
133 int result = super.hashCode();
134 result = prime * result + ((shapes == null) ? 0 : shapes.hashCode());
135 return result;
136 }
137
138 @Override
139 public boolean equals(Object obj) {
140 if (this == obj)
141 return true;
142 if (!super.equals(obj))
143 return false;
144 if (getClass() != obj.getClass())
145 return false;
146 ImageryBounds other = (ImageryBounds) obj;
147 if (shapes == null) {
148 if (other.shapes != null)
149 return false;
150 } else if (!shapes.equals(other.shapes))
151 return false;
152 return true;
153 }
154 }
155
156
157 /** original name of the imagery entry in case of translation call, for multiple languages English when possible */
158 private String origName;
159 /** (original) language of the translated name entry */
160 private String langName;
161 /** whether this is a entry activated by default or not */
162 private boolean defaultEntry = false;
163 /** The data part of HTTP cookies header in case the service requires cookies to work */
164 private String cookies = null;
165 /** Whether this service requires a explicit EULA acceptance before it can be activated */
166 private String eulaAcceptanceRequired = null;
167 /** type of the imagery servics - WMS, TMS, ... */
168 private ImageryType imageryType = ImageryType.WMS;
169 private double pixelPerDegree = 0.0;
170 /** maximum zoom level for TMS imagery */
171 private int defaultMaxZoom = 0;
172 /** minimum zoom level for TMS imagery */
173 private int defaultMinZoom = 0;
174 /** display bounds of imagery, displayed in prefs and used for automatic imagery selection */
175 private ImageryBounds bounds = null;
176 /** projections supported by WMS servers */
177 private List<String> serverProjections;
178 /** description of the imagery entry, should contain notes what type of data it is */
179 private String description;
180 /** language of the description entry */
181 private String langDescription;
182 /** Text of a text attribution displayed when using the imagery */
183 private String attributionText;
184 /** Link behing the text attribution displayed when using the imagery */
185 private String attributionLinkURL;
186 /** Image of a graphical attribution displayed when using the imagery */
187 private String attributionImage;
188 /** Link behind the graphical attribution displayed when using the imagery */
189 private String attributionImageURL;
190 /** Text with usage terms displayed when using the imagery */
191 private String termsOfUseText;
192 /** Link behind the text with usage terms displayed when using the imagery */
193 private String termsOfUseURL;
194 /** country code of the imagery (for country specific imagery) */
195 private String countryCode = "";
196 /** icon used in menu */
197 private String icon;
198 // when adding a field, also adapt the ImageryInfo(ImageryInfo) constructor
199 private Map<String, String> noTileHeaders;
200
201 /**
202 * Auxiliary class to save an {@link ImageryInfo} object in the preferences.
203 */
204 public static class ImageryPreferenceEntry {
205 @pref String name;
206 @pref String id;
207 @pref String type;
208 @pref String url;
209 @pref double pixel_per_eastnorth;
210 @pref String eula;
211 @pref String attribution_text;
212 @pref String attribution_url;
213 @pref String logo_image;
214 @pref String logo_url;
215 @pref String terms_of_use_text;
216 @pref String terms_of_use_url;
217 @pref String country_code = "";
218 @pref int max_zoom;
219 @pref int min_zoom;
220 @pref String cookies;
221 @pref String bounds;
222 @pref String shapes;
223 @pref String projections;
224 @pref String icon;
225 @pref String description;
226 @pref Map<String, String> noTileHeaders;
227
228 /**
229 * Constructs a new empty WMS {@code ImageryPreferenceEntry}.
230 */
231 public ImageryPreferenceEntry() {
232 }
233
234 /**
235 * Constructs a new {@code ImageryPreferenceEntry} from a given {@code ImageryInfo}.
236 * @param i The corresponding imagery info
237 */
238 public ImageryPreferenceEntry(ImageryInfo i) {
239 name = i.name;
240 id = i.id;
241 type = i.imageryType.getTypeString();
242 url = i.url;
243 pixel_per_eastnorth = i.pixelPerDegree;
244 eula = i.eulaAcceptanceRequired;
245 attribution_text = i.attributionText;
246 attribution_url = i.attributionLinkURL;
247 logo_image = i.attributionImage;
248 logo_url = i.attributionImageURL;
249 terms_of_use_text = i.termsOfUseText;
250 terms_of_use_url = i.termsOfUseURL;
251 country_code = i.countryCode;
252 max_zoom = i.defaultMaxZoom;
253 min_zoom = i.defaultMinZoom;
254 cookies = i.cookies;
255 icon = i.icon;
256 description = i.description;
257 if (i.bounds != null) {
258 bounds = i.bounds.encodeAsString(",");
259 StringBuilder shapesString = new StringBuilder();
260 for (Shape s : i.bounds.getShapes()) {
261 if (shapesString.length() > 0) {
262 shapesString.append(";");
263 }
264 shapesString.append(s.encodeAsString(","));
265 }
266 if (shapesString.length() > 0) {
267 shapes = shapesString.toString();
268 }
269 }
270 if (i.serverProjections != null && !i.serverProjections.isEmpty()) {
271 StringBuilder val = new StringBuilder();
272 for (String p : i.serverProjections) {
273 if (val.length() > 0) {
274 val.append(",");
275 }
276 val.append(p);
277 }
278 projections = val.toString();
279 }
280 if (i.noTileHeaders != null && !i.noTileHeaders.isEmpty()) {
281 noTileHeaders = i.noTileHeaders;
282 }
283 }
284
285 @Override
286 public String toString() {
287 String s = "ImageryPreferenceEntry [name=" + name;
288 if (id != null) {
289 s += " id=" + id;
290 }
291 s += "]";
292 return s;
293 }
294 }
295
296 /**
297 * Constructs a new WMS {@code ImageryInfo}.
298 */
299 public ImageryInfo() {
300 super();
301 }
302
303 /**
304 * Constructs a new WMS {@code ImageryInfo} with a given name.
305 * @param name The entry name
306 */
307 public ImageryInfo(String name) {
308 super(name);
309 }
310
311 /**
312 * Constructs a new WMS {@code ImageryInfo} with given name and extended URL.
313 * @param name The entry name
314 * @param url The entry extended URL
315 */
316 public ImageryInfo(String name, String url) {
317 this(name);
318 setExtendedUrl(url);
319 }
320
321 /**
322 * Constructs a new WMS {@code ImageryInfo} with given name, extended and EULA URLs.
323 * @param name The entry name
324 * @param url The entry URL
325 * @param eulaAcceptanceRequired The EULA URL
326 */
327 public ImageryInfo(String name, String url, String eulaAcceptanceRequired) {
328 this(name);
329 setExtendedUrl(url);
330 this.eulaAcceptanceRequired = eulaAcceptanceRequired;
331 }
332
333 /**
334 * Constructs a new {@code ImageryInfo} with given name, url, extended and EULA URLs.
335 * @param name The entry name
336 * @param url The entry URL
337 * @param type The entry imagery type. If null, WMS will be used as default
338 * @param eulaAcceptanceRequired The EULA URL
339 * @param cookies The data part of HTTP cookies header in case the service requires cookies to work
340 * @throws IllegalArgumentException if type refers to an unknown imagery type
341 */
342 public ImageryInfo(String name, String url, String type, String eulaAcceptanceRequired, String cookies) {
343 this(name);
344 setExtendedUrl(url);
345 ImageryType t = ImageryType.fromString(type);
346 this.cookies=cookies;
347 this.eulaAcceptanceRequired = eulaAcceptanceRequired;
348 if (t != null) {
349 this.imageryType = t;
350 } else if (type != null && !type.trim().isEmpty()) {
351 throw new IllegalArgumentException("unknown type: "+type);
352 }
353 }
354
355 public ImageryInfo(String name, String url, String type, String eulaAcceptanceRequired, String cookies, String id) {
356 this(name, url, type, eulaAcceptanceRequired, cookies);
357 setId(id);
358 }
359
360 /**
361 * Constructs a new {@code ImageryInfo} from an imagery preference entry.
362 * @param e The imagery preference entry
363 */
364 public ImageryInfo(ImageryPreferenceEntry e) {
365 CheckParameterUtil.ensureParameterNotNull(e.name, "name");
366 CheckParameterUtil.ensureParameterNotNull(e.url, "url");
367 name = e.name;
368 id = e.id;
369 url = e.url;
370 description = e.description;
371 cookies = e.cookies;
372 eulaAcceptanceRequired = e.eula;
373 imageryType = ImageryType.fromString(e.type);
374 if (imageryType == null) throw new IllegalArgumentException("unknown type");
375 pixelPerDegree = e.pixel_per_eastnorth;
376 defaultMaxZoom = e.max_zoom;
377 defaultMinZoom = e.min_zoom;
378 if (e.bounds != null) {
379 bounds = new ImageryBounds(e.bounds, ",");
380 if (e.shapes != null) {
381 try {
382 for (String s : e.shapes.split(";")) {
383 bounds.addShape(new Shape(s, ","));
384 }
385 } catch (IllegalArgumentException ex) {
386 Main.warn(ex);
387 }
388 }
389 }
390 if (e.projections != null) {
391 serverProjections = Arrays.asList(e.projections.split(","));
392 }
393 attributionText = e.attribution_text;
394 attributionLinkURL = e.attribution_url;
395 attributionImage = e.logo_image;
396 attributionImageURL = e.logo_url;
397 termsOfUseText = e.terms_of_use_text;
398 termsOfUseURL = e.terms_of_use_url;
399 countryCode = e.country_code;
400 icon = e.icon;
401 if (e.noTileHeaders != null) {
402 noTileHeaders = e.noTileHeaders;
403 }
404 }
405
406 /**
407 * Constructs a new {@code ImageryInfo} from an existing one.
408 * @param i The other imagery info
409 */
410 public ImageryInfo(ImageryInfo i) {
411 this.name = i.name;
412 this.id = i.id;
413 this.url = i.url;
414 this.defaultEntry = i.defaultEntry;
415 this.cookies = i.cookies;
416 this.eulaAcceptanceRequired = null;
417 this.imageryType = i.imageryType;
418 this.pixelPerDegree = i.pixelPerDegree;
419 this.defaultMaxZoom = i.defaultMaxZoom;
420 this.defaultMinZoom = i.defaultMinZoom;
421 this.bounds = i.bounds;
422 this.serverProjections = i.serverProjections;
423 this.attributionText = i.attributionText;
424 this.attributionLinkURL = i.attributionLinkURL;
425 this.attributionImage = i.attributionImage;
426 this.attributionImageURL = i.attributionImageURL;
427 this.termsOfUseText = i.termsOfUseText;
428 this.termsOfUseURL = i.termsOfUseURL;
429 this.countryCode = i.countryCode;
430 this.icon = i.icon;
431 this.description = i.description;
432 }
433
434 @Override
435 public boolean equals(Object o) {
436 if (this == o) return true;
437 if (o == null || getClass() != o.getClass()) return false;
438
439 ImageryInfo that = (ImageryInfo) o;
440
441 if (imageryType != that.imageryType) return false;
442 if (url != null ? !url.equals(that.url) : that.url != null) return false;
443 if (name != null ? !name.equals(that.name) : that.name != null) return false;
444
445 return true;
446 }
447
448 /**
449 * Check if this object equals another ImageryInfo with respect to the properties
450 * that get written to the preference file.
451 *
452 * The field {@link #pixelPerDegree} is ignored.
453 *
454 * @param other the ImageryInfo object to compare to
455 * @return true if they are equal
456 */
457 public boolean equalsPref(ImageryInfo other) {
458 if (other == null) {
459 return false;
460 }
461 if (!Objects.equals(this.name, other.name)) {
462 return false;
463 }
464 if (!Objects.equals(this.id, other.id)) {
465 return false;
466 }
467 if (!Objects.equals(this.url, other.url)) {
468 return false;
469 }
470 if (!Objects.equals(this.cookies, other.cookies)) {
471 return false;
472 }
473 if (!Objects.equals(this.eulaAcceptanceRequired, other.eulaAcceptanceRequired)) {
474 return false;
475 }
476 if (this.imageryType != other.imageryType) {
477 return false;
478 }
479 if (this.defaultMaxZoom != other.defaultMaxZoom) {
480 return false;
481 }
482 if (this.defaultMinZoom != other.defaultMinZoom) {
483 return false;
484 }
485 if (!Objects.equals(this.bounds, other.bounds)) {
486 return false;
487 }
488 if (!Objects.equals(this.serverProjections, other.serverProjections)) {
489 return false;
490 }
491 if (!Objects.equals(this.attributionText, other.attributionText)) {
492 return false;
493 }
494 if (!Objects.equals(this.attributionLinkURL, other.attributionLinkURL)) {
495 return false;
496 }
497 if (!Objects.equals(this.attributionImage, other.attributionImage)) {
498 return false;
499 }
500 if (!Objects.equals(this.attributionImageURL, other.attributionImageURL)) {
501 return false;
502 }
503 if (!Objects.equals(this.termsOfUseText, other.termsOfUseText)) {
504 return false;
505 }
506 if (!Objects.equals(this.termsOfUseURL, other.termsOfUseURL)) {
507 return false;
508 }
509 if (!Objects.equals(this.countryCode, other.countryCode)) {
510 return false;
511 }
512 if (!Objects.equals(this.icon, other.icon)) {
513 return false;
514 }
515 if (!Objects.equals(this.description, other.description)) {
516 return false;
517 }
518 return true;
519 }
520
521 @Override
522 public int hashCode() {
523 int result = url != null ? url.hashCode() : 0;
524 result = 31 * result + (imageryType != null ? imageryType.hashCode() : 0);
525 return result;
526 }
527
528 @Override
529 public String toString() {
530 return "ImageryInfo{" +
531 "name='" + name + '\'' +
532 ", countryCode='" + countryCode + '\'' +
533 ", url='" + url + '\'' +
534 ", imageryType=" + imageryType +
535 '}';
536 }
537
538 @Override
539 public int compareTo(ImageryInfo in) {
540 int i = countryCode.compareTo(in.countryCode);
541 if (i == 0) {
542 i = name.toLowerCase().compareTo(in.name.toLowerCase());
543 }
544 if (i == 0) {
545 i = url.compareTo(in.url);
546 }
547 if (i == 0) {
548 i = Double.compare(pixelPerDegree, in.pixelPerDegree);
549 }
550 return i;
551 }
552
553 public boolean equalsBaseValues(ImageryInfo in) {
554 return url.equals(in.url);
555 }
556
557 public void setPixelPerDegree(double ppd) {
558 this.pixelPerDegree = ppd;
559 }
560
561 /**
562 * Sets the maximum zoom level.
563 * @param defaultMaxZoom The maximum zoom level
564 */
565 public void setDefaultMaxZoom(int defaultMaxZoom) {
566 this.defaultMaxZoom = defaultMaxZoom;
567 }
568
569 /**
570 * Sets the minimum zoom level.
571 * @param defaultMinZoom The minimum zoom level
572 */
573 public void setDefaultMinZoom(int defaultMinZoom) {
574 this.defaultMinZoom = defaultMinZoom;
575 }
576
577 /**
578 * Sets the imagery polygonial bounds.
579 * @param b The imagery bounds (non-rectangular)
580 */
581 public void setBounds(ImageryBounds b) {
582 this.bounds = b;
583 }
584
585 /**
586 * Returns the imagery polygonial bounds.
587 * @return The imagery bounds (non-rectangular)
588 */
589 public ImageryBounds getBounds() {
590 return bounds;
591 }
592
593 @Override
594 public boolean requiresAttribution() {
595 return attributionText != null || attributionImage != null || termsOfUseText != null || termsOfUseURL != null;
596 }
597
598 @Override
599 public String getAttributionText(int zoom, Coordinate topLeft, Coordinate botRight) {
600 return attributionText;
601 }
602
603 @Override
604 public String getAttributionLinkURL() {
605 return attributionLinkURL;
606 }
607
608 @Override
609 public Image getAttributionImage() {
610 ImageIcon i = ImageProvider.getIfAvailable(attributionImage);
611 if (i != null) {
612 return i.getImage();
613 }
614 return null;
615 }
616
617 @Override
618 public String getAttributionImageURL() {
619 return attributionImageURL;
620 }
621
622 @Override
623 public String getTermsOfUseText() {
624 return termsOfUseText;
625 }
626
627 @Override
628 public String getTermsOfUseURL() {
629 return termsOfUseURL;
630 }
631
632 public void setAttributionText(String text) {
633 attributionText = text;
634 }
635
636 public void setAttributionImageURL(String text) {
637 attributionImageURL = text;
638 }
639
640 public void setAttributionImage(String text) {
641 attributionImage = text;
642 }
643
644 public void setAttributionLinkURL(String text) {
645 attributionLinkURL = text;
646 }
647
648 public void setTermsOfUseText(String text) {
649 termsOfUseText = text;
650 }
651
652 public void setTermsOfUseURL(String text) {
653 termsOfUseURL = text;
654 }
655
656 /**
657 * Sets the extended URL of this entry.
658 * @param url Entry extended URL containing in addition of service URL, its type and min/max zoom info
659 */
660 public void setExtendedUrl(String url) {
661 CheckParameterUtil.ensureParameterNotNull(url);
662
663 // Default imagery type is WMS
664 this.url = url;
665 this.imageryType = ImageryType.WMS;
666
667 defaultMaxZoom = 0;
668 defaultMinZoom = 0;
669 for (ImageryType type : ImageryType.values()) {
670 Matcher m = Pattern.compile(type.getTypeString()+"(?:\\[(?:(\\d+),)?(\\d+)\\])?:(.*)").matcher(url);
671 if (m.matches()) {
672 this.url = m.group(3);
673 this.imageryType = type;
674 if (m.group(2) != null) {
675 defaultMaxZoom = Integer.valueOf(m.group(2));
676 }
677 if (m.group(1) != null) {
678 defaultMinZoom = Integer.valueOf(m.group(1));
679 }
680 break;
681 }
682 }
683
684 if (serverProjections == null || serverProjections.isEmpty()) {
685 try {
686 serverProjections = new ArrayList<>();
687 Matcher m = Pattern.compile(".*\\{PROJ\\(([^)}]+)\\)\\}.*").matcher(url.toUpperCase());
688 if(m.matches()) {
689 for(String p : m.group(1).split(","))
690 serverProjections.add(p);
691 }
692 } catch (Exception e) {
693 Main.warn(e);
694 }
695 }
696 }
697
698 /**
699 * Returns the entry name.
700 * @return The entry name
701 */
702 @Override
703 public String getName() {
704 return this.name;
705 }
706
707 /**
708 * Returns the entry name.
709 * @return The entry name
710 * @since 6968
711 */
712 public String getOriginalName() {
713 return this.origName != null ? this.origName : this.name;
714 }
715
716 /**
717 * Sets the entry name.
718 * @param name The entry name
719 */
720 public void setName(String name) {
721 this.name = name;
722 }
723
724 /**
725 * Sets the entry name and handle translation.
726 * @param language The used language
727 * @param name The entry name
728 * @since 8091
729 */
730 public void setName(String language, String name) {
731 boolean isdefault = LanguageInfo.getJOSMLocaleCode(null).equals(language);
732 if(LanguageInfo.isBetterLanguage(langName, language)) {
733 this.name = isdefault ? tr(name) : name;
734 this.langName = language;
735 }
736 if(origName == null || isdefault) {
737 this.origName = name;
738 }
739 }
740
741 /**
742 * Gets the entry id.
743 *
744 * Id can be null. This gets the configured id as is. Due to a user error,
745 * this may not be unique. Use {@link ImageryLayerInfo#getUniqueId} to ensure
746 * a unique value.
747 * @return the id
748 */
749 public String getId() {
750 return this.id;
751 }
752
753 /**
754 * Sets the entry id.
755 * @param id the entry id
756 */
757 public void setId(String id) {
758 this.id = id;
759 }
760
761 public void clearId() {
762 if (this.id != null) {
763 Collection<String> newAddedIds = new TreeSet<>(Main.pref.getCollection("imagery.layers.addedIds"));
764 newAddedIds.add(this.id);
765 Main.pref.putCollection("imagery.layers.addedIds", newAddedIds);
766 }
767 this.id = null;
768 }
769
770 /**
771 * Returns the entry URL.
772 * @return The entry URL
773 */
774 @Override
775 public String getUrl() {
776 return this.url;
777 }
778
779 /**
780 * Sets the entry URL.
781 * @param url The entry URL
782 */
783 public void setUrl(String url) {
784 this.url = url;
785 }
786
787 /**
788 * Determines if this entry is enabled by default.
789 * @return {@code true} if this entry is enabled by default, {@code false} otherwise
790 */
791 public boolean isDefaultEntry() {
792 return defaultEntry;
793 }
794
795 /**
796 * Sets the default state of this entry.
797 * @param defaultEntry {@code true} if this entry has to be enabled by default, {@code false} otherwise
798 */
799 public void setDefaultEntry(boolean defaultEntry) {
800 this.defaultEntry = defaultEntry;
801 }
802
803 /**
804 * Return the data part of HTTP cookies header in case the service requires cookies to work
805 * @return the cookie data part
806 */
807 @Override
808 public String getCookies() {
809 return this.cookies;
810 }
811
812 public double getPixelPerDegree() {
813 return this.pixelPerDegree;
814 }
815
816 /**
817 * Returns the maximum zoom level.
818 * @return The maximum zoom level
819 */
820 @Override
821 public int getMaxZoom() {
822 return this.defaultMaxZoom;
823 }
824
825 /**
826 * Returns the minimum zoom level.
827 * @return The minimum zoom level
828 */
829 @Override
830 public int getMinZoom() {
831 return this.defaultMinZoom;
832 }
833
834 /**
835 * Returns the description text when existing.
836 * @return The description
837 * @since 8065
838 */
839 public String getDescription() {
840 return this.description;
841 }
842
843 /**
844 * Sets the description text when existing.
845 * @param language The used language
846 * @param description the imagery description text
847 * @since 8091
848 */
849 public void setDescription(String language, String description) {
850 boolean isdefault = LanguageInfo.getJOSMLocaleCode(null).equals(language);
851 if(LanguageInfo.isBetterLanguage(langDescription, language)) {
852 this.description = isdefault ? tr(description) : description;
853 this.langDescription = language;
854 }
855 }
856
857 /**
858 * Returns a tool tip text for display.
859 * @return The text
860 * @since 8065
861 */
862 public String getToolTipText() {
863 String desc = getDescription();
864 if (desc != null && !desc.isEmpty()) {
865 return "<html>" + getName() + "<br>" + desc + "</html>";
866 }
867 return getName();
868 }
869
870 /**
871 * Returns the EULA acceptance URL, if any.
872 * @return The URL to an EULA text that has to be accepted before use, or {@code null}
873 */
874 public String getEulaAcceptanceRequired() {
875 return eulaAcceptanceRequired;
876 }
877
878 /**
879 * Sets the EULA acceptance URL.
880 * @param eulaAcceptanceRequired The URL to an EULA text that has to be accepted before use
881 */
882 public void setEulaAcceptanceRequired(String eulaAcceptanceRequired) {
883 this.eulaAcceptanceRequired = eulaAcceptanceRequired;
884 }
885
886 /**
887 * Returns the ISO 3166-1-alpha-2 country code.
888 * @return The country code (2 letters)
889 */
890 public String getCountryCode() {
891 return countryCode;
892 }
893
894 /**
895 * Sets the ISO 3166-1-alpha-2 country code.
896 * @param countryCode The country code (2 letters)
897 */
898 public void setCountryCode(String countryCode) {
899 this.countryCode = countryCode;
900 }
901
902 /**
903 * Returns the entry icon.
904 * @return The entry icon
905 */
906 public String getIcon() {
907 return icon;
908 }
909
910 /**
911 * Sets the entry icon.
912 * @param icon The entry icon
913 */
914 public void setIcon(String icon) {
915 this.icon = icon;
916 }
917
918 /**
919 * Get the projections supported by the server. Only relevant for
920 * WMS-type ImageryInfo at the moment.
921 * @return null, if no projections have been specified; the list
922 * of supported projections otherwise.
923 */
924 public List<String> getServerProjections() {
925 if (serverProjections == null)
926 return Collections.emptyList();
927 return Collections.unmodifiableList(serverProjections);
928 }
929
930 public void setServerProjections(Collection<String> serverProjections) {
931 this.serverProjections = new ArrayList<>(serverProjections);
932 }
933
934 /**
935 * Returns the extended URL, containing in addition of service URL, its type and min/max zoom info.
936 * @return The extended URL
937 */
938 public String getExtendedUrl() {
939 return imageryType.getTypeString() + (defaultMaxZoom != 0
940 ? "["+(defaultMinZoom != 0 ? defaultMinZoom+",":"")+defaultMaxZoom+"]" : "") + ":" + url;
941 }
942
943 public String getToolbarName() {
944 String res = name;
945 if(pixelPerDegree != 0.0) {
946 res += "#PPD="+pixelPerDegree;
947 }
948 return res;
949 }
950
951 public String getMenuName() {
952 String res = name;
953 if(pixelPerDegree != 0.0) {
954 res += " ("+pixelPerDegree+")";
955 }
956 return res;
957 }
958
959 /**
960 * Determines if this entry requires attribution.
961 * @return {@code true} if some attribution text has to be displayed, {@code false} otherwise
962 */
963 public boolean hasAttribution() {
964 return attributionText != null;
965 }
966
967 /**
968 * Copies attribution from another {@code ImageryInfo}.
969 * @param i The other imagery info to get attribution from
970 */
971 public void copyAttribution(ImageryInfo i) {
972 this.attributionImage = i.attributionImage;
973 this.attributionImageURL = i.attributionImageURL;
974 this.attributionText = i.attributionText;
975 this.attributionLinkURL = i.attributionLinkURL;
976 this.termsOfUseText = i.termsOfUseText;
977 this.termsOfUseURL = i.termsOfUseURL;
978 }
979
980 /**
981 * Applies the attribution from this object to a tile source.
982 * @param s The tile source
983 */
984 public void setAttribution(AbstractTileSource s) {
985 if (attributionText != null) {
986 if ("osm".equals(attributionText)) {
987 s.setAttributionText(new Mapnik().getAttributionText(0, null, null));
988 } else {
989 s.setAttributionText(attributionText);
990 }
991 }
992 if (attributionLinkURL != null) {
993 if ("osm".equals(attributionLinkURL)) {
994 s.setAttributionLinkURL(new Mapnik().getAttributionLinkURL());
995 } else {
996 s.setAttributionLinkURL(attributionLinkURL);
997 }
998 }
999 if (attributionImage != null) {
1000 ImageIcon i = ImageProvider.getIfAvailable(null, attributionImage);
1001 if (i != null) {
1002 s.setAttributionImage(i.getImage());
1003 }
1004 }
1005 if (attributionImageURL != null) {
1006 s.setAttributionImageURL(attributionImageURL);
1007 }
1008 if (termsOfUseText != null) {
1009 s.setTermsOfUseText(termsOfUseText);
1010 }
1011 if (termsOfUseURL != null) {
1012 if ("osm".equals(termsOfUseURL)) {
1013 s.setTermsOfUseURL(new Mapnik().getTermsOfUseURL());
1014 } else {
1015 s.setTermsOfUseURL(termsOfUseURL);
1016 }
1017 }
1018 }
1019
1020 /**
1021 * Returns the imagery type.
1022 * @return The imagery type
1023 */
1024 public ImageryType getImageryType() {
1025 return imageryType;
1026 }
1027
1028 /**
1029 * Sets the imagery type.
1030 * @param imageryType The imagery type
1031 */
1032 public void setImageryType(ImageryType imageryType) {
1033 this.imageryType = imageryType;
1034 }
1035
1036 /**
1037 * Returns true if this layer's URL is matched by one of the regular
1038 * expressions kept by the current OsmApi instance.
1039 * @return {@code true} is this entry is blacklisted, {@code false} otherwise
1040 */
1041 public boolean isBlacklisted() {
1042 Capabilities capabilities = OsmApi.getOsmApi().getCapabilities();
1043 return capabilities != null && capabilities.isOnImageryBlacklist(this.url);
1044 }
1045
1046 public void setNoTileHeaders(Map<String, String> noTileHeaders) {
1047 this.noTileHeaders = noTileHeaders;
1048 }
1049
1050 @Override
1051 public Map<String, String> getNoTileHeaders() {
1052 return noTileHeaders;
1053 }
1054}
Note: See TracBrowser for help on using the repository browser.