[3719] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[3715] | 2 | package org.openstreetmap.josm.data.imagery;
|
---|
| 3 |
|
---|
| 4 | import java.io.IOException;
|
---|
| 5 | import java.util.ArrayList;
|
---|
| 6 | import java.util.Arrays;
|
---|
| 7 | import java.util.Collection;
|
---|
| 8 | import java.util.Collections;
|
---|
| 9 | import java.util.List;
|
---|
| 10 |
|
---|
| 11 | import org.openstreetmap.josm.Main;
|
---|
[4450] | 12 | import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryPreferenceEntry;
|
---|
[5729] | 13 | import org.openstreetmap.josm.io.MirroredInputStream;
|
---|
[4240] | 14 | import org.openstreetmap.josm.io.imagery.ImageryReader;
|
---|
| 15 | import org.openstreetmap.josm.tools.Utils;
|
---|
[6248] | 16 | import org.xml.sax.SAXException;
|
---|
[3715] | 17 |
|
---|
[4450] | 18 | /**
|
---|
| 19 | * Manages the list of imagery entries that are shown in the imagery menu.
|
---|
| 20 | */
|
---|
[3715] | 21 | public class ImageryLayerInfo {
|
---|
[3826] | 22 |
|
---|
[3715] | 23 | public static final ImageryLayerInfo instance = new ImageryLayerInfo();
|
---|
[7005] | 24 | List<ImageryInfo> layers = new ArrayList<>();
|
---|
| 25 | static List<ImageryInfo> defaultLayers = new ArrayList<>();
|
---|
[3715] | 26 |
|
---|
[6883] | 27 | private static final String[] DEFAULT_LAYER_SITES = {
|
---|
[6897] | 28 | Main.getJOSMWebsite()+"/maps"
|
---|
[3826] | 29 | };
|
---|
| 30 |
|
---|
[4016] | 31 | private ImageryLayerInfo() {
|
---|
| 32 | }
|
---|
| 33 |
|
---|
| 34 | public ImageryLayerInfo(ImageryLayerInfo info) {
|
---|
| 35 | layers.addAll(info.layers);
|
---|
| 36 | }
|
---|
| 37 |
|
---|
[4216] | 38 | public void clear() {
|
---|
| 39 | layers.clear();
|
---|
| 40 | }
|
---|
| 41 |
|
---|
[4016] | 42 | public void load() {
|
---|
[6093] | 43 | boolean addedDefault = !layers.isEmpty();
|
---|
[4450] | 44 | List<ImageryPreferenceEntry> entries = Main.pref.getListOfStructs("imagery.entries", null, ImageryPreferenceEntry.class);
|
---|
[4881] | 45 | if (entries != null) {
|
---|
[4450] | 46 | for (ImageryPreferenceEntry prefEntry : entries) {
|
---|
[4853] | 47 | try {
|
---|
| 48 | ImageryInfo i = new ImageryInfo(prefEntry);
|
---|
| 49 | add(i);
|
---|
| 50 | } catch (IllegalArgumentException e) {
|
---|
[6248] | 51 | Main.warn("Unable to load imagery preference entry:"+e);
|
---|
[4853] | 52 | }
|
---|
[4450] | 53 | }
|
---|
| 54 | Collections.sort(layers);
|
---|
| 55 | }
|
---|
| 56 | if (addedDefault) {
|
---|
| 57 | save();
|
---|
| 58 | }
|
---|
| 59 | }
|
---|
| 60 |
|
---|
[5729] | 61 | /**
|
---|
| 62 | * Loads the available imagery entries.
|
---|
| 63 | *
|
---|
| 64 | * The data is downloaded from the JOSM website (or loaded from cache).
|
---|
| 65 | * Entries marked as "default" are added to the user selection, if not
|
---|
| 66 | * already present.
|
---|
| 67 | *
|
---|
| 68 | * @param clearCache if true, clear the cache and start a fresh download.
|
---|
| 69 | */
|
---|
[4016] | 70 | public void loadDefaults(boolean clearCache) {
|
---|
| 71 | defaultLayers.clear();
|
---|
[4240] | 72 | for (String source : Main.pref.getCollection("imagery.layers.sites", Arrays.asList(DEFAULT_LAYER_SITES))) {
|
---|
| 73 | if (clearCache) {
|
---|
| 74 | MirroredInputStream.cleanup(source);
|
---|
| 75 | }
|
---|
| 76 | MirroredInputStream stream = null;
|
---|
| 77 | try {
|
---|
| 78 | ImageryReader reader = new ImageryReader(source);
|
---|
| 79 | Collection<ImageryInfo> result = reader.parse();
|
---|
| 80 | defaultLayers.addAll(result);
|
---|
| 81 | } catch (IOException ex) {
|
---|
| 82 | Utils.close(stream);
|
---|
[6642] | 83 | Main.error(ex, false);
|
---|
[4240] | 84 | continue;
|
---|
[6642] | 85 | } catch (SAXException ex) {
|
---|
[4240] | 86 | Utils.close(stream);
|
---|
[6642] | 87 | Main.error(ex);
|
---|
[4240] | 88 | continue;
|
---|
| 89 | }
|
---|
| 90 | }
|
---|
[6310] | 91 | while (defaultLayers.remove(null));
|
---|
[4428] | 92 |
|
---|
[4240] | 93 | Collection<String> defaults = Main.pref.getCollection("imagery.layers.default");
|
---|
[7005] | 94 | List<String> defaultsSave = new ArrayList<>();
|
---|
[4240] | 95 | for (ImageryInfo def : defaultLayers) {
|
---|
| 96 | if (def.isDefaultEntry()) {
|
---|
| 97 | defaultsSave.add(def.getUrl());
|
---|
[4428] | 98 |
|
---|
[4240] | 99 | boolean isKnownDefault = false;
|
---|
| 100 | for (String url : defaults) {
|
---|
| 101 | if (isSimilar(url, def.getUrl())) {
|
---|
| 102 | isKnownDefault = true;
|
---|
| 103 | break;
|
---|
| 104 | }
|
---|
[3978] | 105 | }
|
---|
[4240] | 106 | boolean isInUserList = false;
|
---|
| 107 | if (!isKnownDefault) {
|
---|
| 108 | for (ImageryInfo i : layers) {
|
---|
| 109 | if (isSimilar(def.getUrl(), i.getUrl())) {
|
---|
| 110 | isInUserList = true;
|
---|
| 111 | break;
|
---|
[3715] | 112 | }
|
---|
| 113 | }
|
---|
| 114 | }
|
---|
[4240] | 115 | if (!isKnownDefault && !isInUserList) {
|
---|
| 116 | add(new ImageryInfo(def));
|
---|
| 117 | }
|
---|
[3715] | 118 | }
|
---|
| 119 | }
|
---|
| 120 |
|
---|
[4016] | 121 | Collections.sort(defaultLayers);
|
---|
[6093] | 122 | Main.pref.putCollection("imagery.layers.default", defaultsSave.isEmpty() ? defaults : defaultsSave);
|
---|
[3715] | 123 | }
|
---|
[4428] | 124 |
|
---|
[4240] | 125 | // some additional checks to respect extended URLs in preferences (legacy workaround)
|
---|
| 126 | private boolean isSimilar(String a, String b) {
|
---|
[6087] | 127 | return Utils.equal(a, b) || (a != null && b != null && !a.isEmpty() && !b.isEmpty() && (a.contains(b) || b.contains(a)));
|
---|
[4240] | 128 | }
|
---|
[3715] | 129 |
|
---|
| 130 | public void add(ImageryInfo info) {
|
---|
| 131 | layers.add(info);
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | public void remove(ImageryInfo info) {
|
---|
| 135 | layers.remove(info);
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | public void save() {
|
---|
[7005] | 139 | List<ImageryPreferenceEntry> entries = new ArrayList<>();
|
---|
[3715] | 140 | for (ImageryInfo info : layers) {
|
---|
[4450] | 141 | entries.add(new ImageryPreferenceEntry(info));
|
---|
[3715] | 142 | }
|
---|
[4450] | 143 | Main.pref.putListOfStructs("imagery.entries", entries, ImageryPreferenceEntry.class);
|
---|
[3715] | 144 | }
|
---|
| 145 |
|
---|
| 146 | public List<ImageryInfo> getLayers() {
|
---|
| 147 | return Collections.unmodifiableList(layers);
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | public List<ImageryInfo> getDefaultLayers() {
|
---|
| 151 | return Collections.unmodifiableList(defaultLayers);
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | public static void addLayer(ImageryInfo info) {
|
---|
| 155 | instance.add(info);
|
---|
| 156 | instance.save();
|
---|
| 157 | }
|
---|
[5369] | 158 |
|
---|
| 159 | public static void addLayers(Collection<ImageryInfo> infos) {
|
---|
| 160 | for (ImageryInfo i : infos) {
|
---|
| 161 | instance.add(i);
|
---|
| 162 | }
|
---|
| 163 | instance.save();
|
---|
| 164 | Collections.sort(instance.layers);
|
---|
| 165 | }
|
---|
[3715] | 166 | }
|
---|