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

Last change on this file since 8393 was 8393, checked in by Don-vip, 9 years ago

see #11447 - partial revert of r8384

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