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

Last change on this file since 5391 was 5391, checked in by bastiK, 12 years ago

add session support for imagery layers

  • Property svn:eol-style set to native
File size: 17.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import java.awt.Image;
5import java.util.ArrayList;
6import java.util.Arrays;
7import java.util.Collection;
8import java.util.Collections;
9import java.util.List;
10import java.util.regex.Matcher;
11import java.util.regex.Pattern;
12
13import javax.swing.ImageIcon;
14
15import org.openstreetmap.gui.jmapviewer.Coordinate;
16import org.openstreetmap.gui.jmapviewer.interfaces.Attributed;
17import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTileSource;
18import org.openstreetmap.gui.jmapviewer.tilesources.OsmTileSource.Mapnik;
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.data.Bounds;
21import org.openstreetmap.josm.data.Preferences.pref;
22import org.openstreetmap.josm.io.OsmApi;
23import org.openstreetmap.josm.tools.CheckParameterUtil;
24import org.openstreetmap.josm.tools.ImageProvider;
25
26/**
27 * Class that stores info about an image background layer.
28 *
29 * @author Frederik Ramm <frederik@remote.org>
30 */
31public class ImageryInfo implements Comparable<ImageryInfo>, Attributed {
32
33 public enum ImageryType {
34 WMS("wms"),
35 TMS("tms"),
36 HTML("html"),
37 BING("bing"),
38 SCANEX("scanex");
39
40 private String urlString;
41
42 ImageryType(String urlString) {
43 this.urlString = urlString;
44 }
45
46 public String getUrlString() {
47 return urlString;
48 }
49
50 public static ImageryType fromUrlString(String s) {
51 for (ImageryType type : ImageryType.values()) {
52 if (type.getUrlString().equals(s)) {
53 return type;
54 }
55 }
56 return null;
57 }
58 }
59
60 public static class ImageryBounds extends Bounds {
61 public ImageryBounds(String asString, String separator) {
62 super(asString, separator);
63 }
64
65 private List<Shape> shapes = new ArrayList<Shape>();
66
67 public void addShape(Shape shape) {
68 this.shapes.add(shape);
69 }
70
71 public void setShapes(List<Shape> shapes) {
72 this.shapes = shapes;
73 }
74
75 public List<Shape> getShapes() {
76 return shapes;
77 }
78 }
79
80 private String name;
81 private String url = null;
82 private boolean defaultEntry = false;
83 private String cookies = null;
84 private String eulaAcceptanceRequired= null;
85 private ImageryType imageryType = ImageryType.WMS;
86 private double pixelPerDegree = 0.0;
87 private int defaultMaxZoom = 0;
88 private int defaultMinZoom = 0;
89 private ImageryBounds bounds = null;
90 private List<String> serverProjections;
91 private String attributionText;
92 private String attributionLinkURL;
93 private String attributionImage;
94 private String attributionImageURL;
95 private String termsOfUseText;
96 private String termsOfUseURL;
97 private String countryCode = "";
98 private String icon;
99 // when adding a field, also adapt the ImageryInfo(ImageryInfo) constructor
100
101 /** auxiliary class to save an ImageryInfo object in the preferences */
102 public static class ImageryPreferenceEntry {
103 @pref String name;
104 @pref String type;
105 @pref String url;
106 @pref double pixel_per_eastnorth;
107 @pref String eula;
108 @pref String attribution_text;
109 @pref String attribution_url;
110 @pref String logo_image;
111 @pref String logo_url;
112 @pref String terms_of_use_text;
113 @pref String terms_of_use_url;
114 @pref String country_code = "";
115 @pref int max_zoom;
116 @pref int min_zoom;
117 @pref String cookies;
118 @pref String bounds;
119 @pref String shapes;
120 @pref String projections;
121 @pref String icon;
122
123 public ImageryPreferenceEntry() {
124 }
125
126 public ImageryPreferenceEntry(ImageryInfo i) {
127 name = i.name;
128 type = i.imageryType.getUrlString();
129 url = i.url;
130 pixel_per_eastnorth = i.pixelPerDegree;
131 eula = i.eulaAcceptanceRequired;
132 attribution_text = i.attributionText;
133 attribution_url = i.attributionLinkURL;
134 logo_image = i.attributionImage;
135 logo_url = i.attributionImageURL;
136 terms_of_use_text = i.termsOfUseText;
137 terms_of_use_url = i.termsOfUseURL;
138 country_code = i.countryCode;
139 max_zoom = i.defaultMaxZoom;
140 min_zoom = i.defaultMinZoom;
141 cookies = i.cookies;
142 icon = i.icon;
143 if (i.bounds != null) {
144 bounds = i.bounds.encodeAsString(",");
145 String shapesString = "";
146 for (Shape s : i.bounds.getShapes()) {
147 if (!shapesString.isEmpty()) {
148 shapesString += ";";
149 }
150 shapesString += s.encodeAsString(",");
151 }
152 if (!shapesString.isEmpty()) {
153 shapes = shapesString;
154 }
155 }
156 if (i.serverProjections != null && !i.serverProjections.isEmpty()) {
157 String val = "";
158 for (String p : i.serverProjections) {
159 if (!val.isEmpty())
160 val += ",";
161 val += p;
162 }
163 projections = val;
164 }
165 }
166 }
167
168 public ImageryInfo() {
169 }
170
171 public ImageryInfo(String name) {
172 this.name=name;
173 }
174
175 public ImageryInfo(String name, String url) {
176 this.name=name;
177 setExtendedUrl(url);
178 }
179
180 public ImageryInfo(String name, String url, String eulaAcceptanceRequired) {
181 this.name=name;
182 setExtendedUrl(url);
183 this.eulaAcceptanceRequired = eulaAcceptanceRequired;
184 }
185
186 public ImageryInfo(String name, String url, String eulaAcceptanceRequired, String cookies) {
187 this.name=name;
188 setExtendedUrl(url);
189 this.cookies=cookies;
190 this.eulaAcceptanceRequired = eulaAcceptanceRequired;
191 }
192
193 public ImageryInfo(String name, String url, String type, String eulaAcceptanceRequired, String cookies) {
194 this.name=name;
195 setExtendedUrl(url);
196 ImageryType t = ImageryType.fromUrlString(type);
197 this.cookies=cookies;
198 if (t != null) {
199 this.imageryType = t;
200 }
201 }
202
203 public ImageryInfo(String name, String url, String cookies, double pixelPerDegree) {
204 this.name=name;
205 setExtendedUrl(url);
206 this.cookies=cookies;
207 this.pixelPerDegree=pixelPerDegree;
208 }
209
210 public ImageryInfo(ImageryPreferenceEntry e) {
211 CheckParameterUtil.ensureParameterNotNull(e.name, "name");
212 CheckParameterUtil.ensureParameterNotNull(e.url, "url");
213 name = e.name;
214 url = e.url;
215 cookies = e.cookies;
216 eulaAcceptanceRequired = e.eula;
217 imageryType = ImageryType.fromUrlString(e.type);
218 if (imageryType == null) throw new IllegalArgumentException("unknown type");
219 pixelPerDegree = e.pixel_per_eastnorth;
220 defaultMaxZoom = e.max_zoom;
221 defaultMinZoom = e.min_zoom;
222 if (e.bounds != null) {
223 bounds = new ImageryBounds(e.bounds, ",");
224 if (e.shapes != null) {
225 try {
226 for (String s : e.shapes.split(";")) {
227 bounds.addShape(new Shape(s, ","));
228 }
229 } catch (IllegalArgumentException ex) {
230 Main.warn(ex.toString());
231 }
232 }
233 }
234 if (e.projections != null) {
235 serverProjections = Arrays.asList(e.projections.split(","));
236 }
237 attributionText = e.attribution_text;
238 attributionLinkURL = e.attribution_url;
239 attributionImage = e.logo_image;
240 attributionImageURL = e.logo_url;
241 termsOfUseText = e.terms_of_use_text;
242 termsOfUseURL = e.terms_of_use_url;
243 countryCode = e.country_code;
244 icon = e.icon;
245 }
246
247 public ImageryInfo(ImageryInfo i) {
248 this.name = i.name;
249 this.url = i.url;
250 this.defaultEntry = i.defaultEntry;
251 this.cookies = i.cookies;
252 this.eulaAcceptanceRequired = null;
253 this.imageryType = i.imageryType;
254 this.pixelPerDegree = i.pixelPerDegree;
255 this.defaultMaxZoom = i.defaultMaxZoom;
256 this.defaultMinZoom = i.defaultMinZoom;
257 this.bounds = i.bounds;
258 this.serverProjections = i.serverProjections;
259 this.attributionText = i.attributionText;
260 this.attributionLinkURL = i.attributionLinkURL;
261 this.attributionImage = i.attributionImage;
262 this.attributionImageURL = i.attributionImageURL;
263 this.termsOfUseText = i.termsOfUseText;
264 this.termsOfUseURL = i.termsOfUseURL;
265 this.countryCode = i.countryCode;
266 this.icon = i.icon;
267 }
268
269 @Override
270 public boolean equals(Object o) {
271 if (this == o) return true;
272 if (o == null || getClass() != o.getClass()) return false;
273
274 ImageryInfo that = (ImageryInfo) o;
275
276 if (imageryType != that.imageryType) return false;
277 if (url != null ? !url.equals(that.url) : that.url != null) return false;
278
279 return true;
280 }
281
282 @Override
283 public int hashCode() {
284 int result = url != null ? url.hashCode() : 0;
285 result = 31 * result + (imageryType != null ? imageryType.hashCode() : 0);
286 return result;
287 }
288
289 @Override
290 public String toString() {
291 return "ImageryInfo{" +
292 "name='" + name + '\'' +
293 ", countryCode='" + countryCode + '\'' +
294 ", url='" + url + '\'' +
295 ", imageryType=" + imageryType +
296 '}';
297 }
298
299 @Override
300 public int compareTo(ImageryInfo in)
301 {
302 int i = countryCode.compareTo(in.countryCode);
303 if (i == 0) {
304 i = name.compareTo(in.name);
305 }
306 if (i == 0) {
307 i = url.compareTo(in.url);
308 }
309 if (i == 0) {
310 i = Double.compare(pixelPerDegree, in.pixelPerDegree);
311 }
312 return i;
313 }
314
315 public boolean equalsBaseValues(ImageryInfo in)
316 {
317 return url.equals(in.url);
318 }
319
320 public void setPixelPerDegree(double ppd) {
321 this.pixelPerDegree = ppd;
322 }
323
324 public void setDefaultMaxZoom(int defaultMaxZoom) {
325 this.defaultMaxZoom = defaultMaxZoom;
326 }
327
328 public void setDefaultMinZoom(int defaultMinZoom) {
329 this.defaultMinZoom = defaultMinZoom;
330 }
331
332 public void setBounds(ImageryBounds b) {
333 this.bounds = b;
334 }
335
336 public ImageryBounds getBounds() {
337 return bounds;
338 }
339
340 @Override
341 public boolean requiresAttribution() {
342 return attributionText != null || attributionImage != null || termsOfUseText != null || termsOfUseURL != null;
343 }
344
345 @Override
346 public String getAttributionText(int zoom, Coordinate topLeft, Coordinate botRight) {
347 return attributionText;
348 }
349
350 @Override
351 public String getAttributionLinkURL() {
352 return attributionLinkURL;
353 }
354
355 @Override
356 public Image getAttributionImage() {
357 ImageIcon i = ImageProvider.getIfAvailable(attributionImage);
358 if (i != null) {
359 return i.getImage();
360 }
361 return null;
362 }
363
364 @Override
365 public String getAttributionImageURL() {
366 return attributionImageURL;
367 }
368
369 @Override
370 public String getTermsOfUseText() {
371 return termsOfUseText;
372 }
373
374 @Override
375 public String getTermsOfUseURL() {
376 return termsOfUseURL;
377 }
378
379 public void setAttributionText(String text) {
380 attributionText = text;
381 }
382
383 public void setAttributionImageURL(String text) {
384 attributionImageURL = text;
385 }
386
387 public void setAttributionImage(String text) {
388 attributionImage = text;
389 }
390
391 public void setAttributionLinkURL(String text) {
392 attributionLinkURL = text;
393 }
394
395 public void setTermsOfUseText(String text) {
396 termsOfUseText = text;
397 }
398
399 public void setTermsOfUseURL(String text) {
400 termsOfUseURL = text;
401 }
402
403 public void setExtendedUrl(String url) {
404 CheckParameterUtil.ensureParameterNotNull(url);
405
406 // Default imagery type is WMS
407 this.url = url;
408 this.imageryType = ImageryType.WMS;
409
410 defaultMaxZoom = 0;
411 defaultMinZoom = 0;
412 for (ImageryType type : ImageryType.values()) {
413 Matcher m = Pattern.compile(type.getUrlString()+"(?:\\[(?:(\\d+),)?(\\d+)\\])?:(.*)").matcher(url);
414 if(m.matches()) {
415 this.url = m.group(3);
416 this.imageryType = type;
417 if(m.group(2) != null) {
418 defaultMaxZoom = Integer.valueOf(m.group(2));
419 }
420 if(m.group(1) != null) {
421 defaultMinZoom = Integer.valueOf(m.group(1));
422 }
423 break;
424 }
425 }
426
427 if(serverProjections == null || serverProjections.isEmpty()) {
428 try {
429 serverProjections = new ArrayList<String>();
430 Matcher m = Pattern.compile(".*\\{PROJ\\(([^)}]+)\\)\\}.*").matcher(url.toUpperCase());
431 if(m.matches()) {
432 for(String p : m.group(1).split(","))
433 serverProjections.add(p);
434 }
435 } catch(Exception e) {
436 }
437 }
438 }
439
440 public String getName() {
441 return this.name;
442 }
443
444 public void setName(String name) {
445 this.name = name;
446 }
447
448 public String getUrl() {
449 return this.url;
450 }
451
452 public void setUrl(String url) {
453 this.url = url;
454 }
455
456 public boolean isDefaultEntry() {
457 return defaultEntry;
458 }
459
460 public void setDefaultEntry(boolean defaultEntry) {
461 this.defaultEntry = defaultEntry;
462 }
463
464 public String getCookies() {
465 return this.cookies;
466 }
467
468 public double getPixelPerDegree() {
469 return this.pixelPerDegree;
470 }
471
472 public int getMaxZoom() {
473 return this.defaultMaxZoom;
474 }
475
476 public int getMinZoom() {
477 return this.defaultMinZoom;
478 }
479
480 public String getEulaAcceptanceRequired() {
481 return eulaAcceptanceRequired;
482 }
483
484 public void setEulaAcceptanceRequired(String eulaAcceptanceRequired) {
485 this.eulaAcceptanceRequired = eulaAcceptanceRequired;
486 }
487
488 public String getCountryCode() {
489 return countryCode;
490 }
491
492 public void setCountryCode(String countryCode) {
493 this.countryCode = countryCode;
494 }
495
496 public String getIcon() {
497 return icon;
498 }
499
500 public void setIcon(String icon) {
501 this.icon = icon;
502 }
503
504 /**
505 * Get the projections supported by the server. Only relevant for
506 * WMS-type ImageryInfo at the moment.
507 * @return null, if no projections have been specified; the list
508 * of supported projections otherwise.
509 */
510 public List<String> getServerProjections() {
511 if (serverProjections == null)
512 return Collections.emptyList();
513 return Collections.unmodifiableList(serverProjections);
514 }
515
516 public void setServerProjections(Collection<String> serverProjections) {
517 this.serverProjections = new ArrayList<String>(serverProjections);
518 }
519
520 public String getExtendedUrl() {
521 return imageryType.getUrlString() + (defaultMaxZoom != 0
522 ? "["+(defaultMinZoom != 0 ? defaultMinZoom+",":"")+defaultMaxZoom+"]" : "") + ":" + url;
523 }
524
525 public String getToolbarName()
526 {
527 String res = name;
528 if(pixelPerDegree != 0.0) {
529 res += "#PPD="+pixelPerDegree;
530 }
531 return res;
532 }
533
534 public String getMenuName()
535 {
536 String res = name;
537 if(pixelPerDegree != 0.0) {
538 res += " ("+pixelPerDegree+")";
539 }
540 return res;
541 }
542
543 public boolean hasAttribution()
544 {
545 return attributionText != null;
546 }
547
548 public void copyAttribution(ImageryInfo i)
549 {
550 this.attributionImage = i.attributionImage;
551 this.attributionImageURL = i.attributionImageURL;
552 this.attributionText = i.attributionText;
553 this.attributionLinkURL = i.attributionLinkURL;
554 this.termsOfUseText = i.termsOfUseText;
555 this.termsOfUseURL = i.termsOfUseURL;
556 }
557
558 /**
559 * Applies the attribution from this object to a TMSTileSource.
560 */
561 public void setAttribution(AbstractTileSource s) {
562 if (attributionText != null) {
563 if (attributionText.equals("osm")) {
564 s.setAttributionText(new Mapnik().getAttributionText(0, null, null));
565 } else {
566 s.setAttributionText(attributionText);
567 }
568 }
569 if (attributionLinkURL != null) {
570 if (attributionLinkURL.equals("osm")) {
571 s.setAttributionLinkURL(new Mapnik().getAttributionLinkURL());
572 } else {
573 s.setAttributionLinkURL(attributionLinkURL);
574 }
575 }
576 if (attributionImage != null) {
577 ImageIcon i = ImageProvider.getIfAvailable(null, attributionImage);
578 if (i != null) {
579 s.setAttributionImage(i.getImage());
580 }
581 }
582 if (attributionImageURL != null) {
583 s.setAttributionImageURL(attributionImageURL);
584 }
585 if (termsOfUseText != null) {
586 s.setTermsOfUseText(termsOfUseText);
587 }
588 if (termsOfUseURL != null) {
589 if (termsOfUseURL.equals("osm")) {
590 s.setTermsOfUseURL(new Mapnik().getTermsOfUseURL());
591 } else {
592 s.setTermsOfUseURL(termsOfUseURL);
593 }
594 }
595 }
596
597 public ImageryType getImageryType() {
598 return imageryType;
599 }
600
601 public void setImageryType(ImageryType imageryType) {
602 this.imageryType = imageryType;
603 }
604
605 /**
606 * Returns true if this layer's URL is matched by one of the regular
607 * expressions kept by the current OsmApi instance.
608 */
609 public boolean isBlacklisted() {
610 return OsmApi.getOsmApi().getCapabilities().isOnImageryBlacklist(this.url);
611 }
612}
Note: See TracBrowser for help on using the repository browser.