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

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

fix NPE seen in continuous integration, reproducible in offline mode

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