source: josm/trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java

Last change on this file was 18871, checked in by taylor.smock, 2 years ago

See #23218: Use newer error_prone versions when compiling on Java 11+

error_prone 2.11 dropped support for compiling with Java 8, although it still
supports compiling for Java 8. The "major" new check for us is NotJavadoc since
we used /** in quite a few places which were not javadoc.

Other "new" checks that are of interest:

  • AlreadyChecked: if (foo) { doFoo(); } else if (!foo) { doBar(); }
  • UnnecessaryStringBuilder: Avoid StringBuilder (Java converts + to StringBuilder behind-the-scenes, but may also do something else if it performs better)
  • NonApiType: Avoid specific interface types in function definitions
  • NamedLikeContextualKeyword: Avoid using restricted names for classes and methods
  • UnusedMethod: Unused private methods should be removed

This fixes most of the new error_prone issues and some SonarLint issues.

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.List;
11import java.util.Objects;
12
13import javax.swing.AbstractAction;
14import javax.swing.Action;
15
16import org.apache.commons.jcs3.access.CacheAccess;
17import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
18import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
19import org.openstreetmap.josm.data.coor.LatLon;
20import org.openstreetmap.josm.data.imagery.AbstractWMSTileSource;
21import org.openstreetmap.josm.data.imagery.ImageryInfo;
22import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
23import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
24import org.openstreetmap.josm.data.imagery.TemplatedWMSTileSource;
25import org.openstreetmap.josm.data.imagery.WMSCachedTileLoader;
26import org.openstreetmap.josm.data.imagery.WMSEndpointTileSource;
27import org.openstreetmap.josm.data.preferences.BooleanProperty;
28import org.openstreetmap.josm.data.preferences.IntegerProperty;
29import org.openstreetmap.josm.data.projection.Projection;
30import org.openstreetmap.josm.data.projection.ProjectionRegistry;
31import org.openstreetmap.josm.data.projection.Projections;
32import org.openstreetmap.josm.gui.MainApplication;
33import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings;
34import org.openstreetmap.josm.tools.CheckParameterUtil;
35import org.openstreetmap.josm.tools.Logging;
36
37/**
38 * This is a layer that grabs the current screen from an WMS server. The data
39 * fetched this way is tiled and managed to the disc to reduce server load.
40 *
41 */
42public class WMSLayer extends AbstractCachedTileSourceLayer<AbstractWMSTileSource> {
43 private static final String PREFERENCE_PREFIX = "imagery.wms";
44 /*
45 * Registers all setting properties
46 */
47 static {
48 new TileSourceDisplaySettings(PREFERENCE_PREFIX);
49 }
50
51 /** default tile size for WMS Layer */
52 public static final IntegerProperty PROP_IMAGE_SIZE = new IntegerProperty(PREFERENCE_PREFIX + ".imageSize", 512);
53
54 /** should WMS layer autozoom in default mode */
55 public static final BooleanProperty PROP_DEFAULT_AUTOZOOM = new BooleanProperty(PREFERENCE_PREFIX + ".default_autozoom", true);
56
57 private static final String CACHE_REGION_NAME = "WMS";
58
59 private List<String> serverProjections;
60
61 /**
62 * Constructs a new {@code WMSLayer}.
63 * @param info ImageryInfo description of the layer
64 */
65 public WMSLayer(ImageryInfo info) {
66 super(info);
67 CheckParameterUtil.ensureThat(
68 info.getImageryType() == ImageryType.WMS || info.getImageryType() == ImageryType.WMS_ENDPOINT, "ImageryType is WMS");
69 CheckParameterUtil.ensureParameterNotNull(info.getUrl(), "info.url");
70 if (info.getImageryType() == ImageryType.WMS) {
71 TemplatedWMSTileSource.checkUrl(info.getUrl());
72
73 }
74 this.serverProjections = new ArrayList<>(info.getServerProjections());
75 }
76
77 @Override
78 protected TileSourceDisplaySettings createDisplaySettings() {
79 return new TileSourceDisplaySettings(PREFERENCE_PREFIX);
80 }
81
82 @Override
83 public Action[] getMenuEntries() {
84 List<Action> ret = new ArrayList<>(Arrays.asList(super.getMenuEntries()));
85 ret.add(SeparatorLayerAction.INSTANCE);
86 ret.add(new LayerSaveAction(this));
87 ret.add(new LayerSaveAsAction(this));
88 ret.add(new BookmarkWmsAction());
89 return ret.toArray(new Action[0]);
90 }
91
92 @Override
93 protected AbstractWMSTileSource getTileSource() {
94 AbstractWMSTileSource tileSource;
95 if (info.getImageryType() == ImageryType.WMS) {
96 tileSource = new TemplatedWMSTileSource(info, chooseProjection(ProjectionRegistry.getProjection()));
97 } else {
98 /*
99 * Chicken-and-egg problem. We want to create tile source, but supported projections we can get only
100 * from this tile source. So create tilesource first with dummy ProjectionRegistry.getProjection(), and then update
101 * once we update server projections.
102 *
103 * Thus:
104 * * it is not required to provide projections for wms_endpoint imagery types
105 * * we always use current definitions returned by server
106 */
107 WMSEndpointTileSource endpointTileSource = new WMSEndpointTileSource(info, ProjectionRegistry.getProjection());
108 this.serverProjections = endpointTileSource.getServerProjections();
109 endpointTileSource.setTileProjection(chooseProjection(ProjectionRegistry.getProjection()));
110 tileSource = endpointTileSource;
111 }
112 info.setAttribution(tileSource);
113 return tileSource;
114 }
115
116 /**
117 * This action will add a WMS layer menu entry with the current WMS layer
118 * URL and name extended by the current resolution.
119 * When using the menu entry again, the WMS cache will be used properly.
120 */
121 public class BookmarkWmsAction extends AbstractAction {
122 /**
123 * Constructs a new {@code BookmarkWmsAction}.
124 */
125 public BookmarkWmsAction() {
126 super(tr("Set WMS Bookmark"));
127 }
128
129 @Override
130 public void actionPerformed(ActionEvent ev) {
131 ImageryLayerInfo.addLayer(new ImageryInfo(info));
132 }
133 }
134
135 @Override
136 public Collection<String> getNativeProjections() {
137 return serverProjections;
138 }
139
140 @Override
141 public void projectionChanged(Projection oldValue, Projection newValue) {
142 super.projectionChanged(oldValue, newValue);
143 Projection tileProjection = chooseProjection(newValue);
144 if (!Objects.equals(tileSource.getTileProjection(), tileProjection)) {
145 tileSource.setTileProjection(tileProjection);
146 }
147 }
148
149 private Projection chooseProjection(Projection requested) {
150 if (!serverProjections.contains(requested.toCode())) {
151 LatLon center = MainApplication.isDisplayingMapView() ?
152 requested.eastNorth2latlon(MainApplication.getMap().mapView.getCenter()) : null;
153 Projection firstNonNullproj = null;
154 Projection firstProjInBounds = null;
155 for (String code : serverProjections) {
156 Projection proj = Projections.getProjectionByCode(code);
157 if (proj != null) {
158 if (firstNonNullproj == null) {
159 firstNonNullproj = proj;
160 }
161 if (center != null && proj.getWorldBoundsLatLon().contains(center)) {
162 firstProjInBounds = proj;
163 break;
164 }
165 }
166 }
167 if (firstProjInBounds != null) {
168 return selectProjection(firstProjInBounds);
169 } else if (firstNonNullproj != null) {
170 return selectProjection(firstNonNullproj);
171 }
172 Logging.warn(tr("Unable to find supported projection for layer {0}. Using {1}.", getName(), requested.toCode()));
173 }
174 return requested;
175 }
176
177 private Projection selectProjection(Projection proj) {
178 Logging.info(tr("Reprojecting layer {0} from {1} to {2}. For best image quality and performance,"
179 + " switch to one of the supported projections: {3}",
180 getName(), proj.toCode(), ProjectionRegistry.getProjection().toCode(), String.join(", ", getNativeProjections())));
181 return proj;
182 }
183
184 @Override
185 protected Class<? extends TileLoader> getTileLoaderClass() {
186 return WMSCachedTileLoader.class;
187 }
188
189 @Override
190 protected String getCacheName() {
191 return CACHE_REGION_NAME;
192 }
193
194 /**
195 * Returns cache region for WMS layer.
196 * @return cache region for WMS layer
197 */
198 public static CacheAccess<String, BufferedImageCacheEntry> getCache() {
199 return AbstractCachedTileSourceLayer.getCache(CACHE_REGION_NAME);
200 }
201}
Note: See TracBrowser for help on using the repository browser.