source: josm/trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java@ 11451

Last change on this file since 11451 was 10934, checked in by Don-vip, 8 years ago

see #13503 - add more debug info

  • Property svn:eol-style set to native
File size: 10.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trc;
7
8import java.awt.Color;
9import java.awt.Component;
10import java.awt.GridBagLayout;
11import java.awt.event.ActionEvent;
12import java.awt.image.BufferedImage;
13import java.awt.image.BufferedImageOp;
14import java.util.ArrayList;
15import java.util.List;
16
17import javax.swing.AbstractAction;
18import javax.swing.Action;
19import javax.swing.Icon;
20import javax.swing.JCheckBoxMenuItem;
21import javax.swing.JComponent;
22import javax.swing.JLabel;
23import javax.swing.JMenu;
24import javax.swing.JMenuItem;
25import javax.swing.JPanel;
26import javax.swing.JPopupMenu;
27import javax.swing.JSeparator;
28
29import org.openstreetmap.josm.Main;
30import org.openstreetmap.josm.data.ProjectionBounds;
31import org.openstreetmap.josm.data.imagery.ImageryInfo;
32import org.openstreetmap.josm.data.imagery.OffsetBookmark;
33import org.openstreetmap.josm.data.preferences.ColorProperty;
34import org.openstreetmap.josm.data.preferences.IntegerProperty;
35import org.openstreetmap.josm.gui.MenuScroller;
36import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings;
37import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings;
38import org.openstreetmap.josm.gui.widgets.UrlLabel;
39import org.openstreetmap.josm.tools.GBC;
40import org.openstreetmap.josm.tools.ImageProvider;
41import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
42import org.openstreetmap.josm.tools.Utils;
43
44public abstract class ImageryLayer extends Layer {
45
46 public static final ColorProperty PROP_FADE_COLOR = new ColorProperty(marktr("Imagery fade"), Color.white);
47 public static final IntegerProperty PROP_FADE_AMOUNT = new IntegerProperty("imagery.fade_amount", 0);
48 public static final IntegerProperty PROP_SHARPEN_LEVEL = new IntegerProperty("imagery.sharpen_level", 0);
49
50 private final List<ImageProcessor> imageProcessors = new ArrayList<>();
51
52 public static Color getFadeColor() {
53 return PROP_FADE_COLOR.get();
54 }
55
56 public static Color getFadeColorWithAlpha() {
57 Color c = PROP_FADE_COLOR.get();
58 return new Color(c.getRed(), c.getGreen(), c.getBlue(), PROP_FADE_AMOUNT.get()*255/100);
59 }
60
61 protected final ImageryInfo info;
62
63 protected Icon icon;
64
65 private final ImageryFilterSettings filterSettings = new ImageryFilterSettings();
66
67 /**
68 * Constructs a new {@code ImageryLayer}.
69 * @param info imagery info
70 */
71 public ImageryLayer(ImageryInfo info) {
72 super(info.getName());
73 this.info = info;
74 if (info.getIcon() != null) {
75 icon = new ImageProvider(info.getIcon()).setOptional(true).
76 setMaxSize(ImageSizes.LAYER).get();
77 }
78 if (icon == null) {
79 icon = ImageProvider.get("imagery_small");
80 }
81 for (ImageProcessor processor : filterSettings.getProcessors()) {
82 addImageProcessor(processor);
83 }
84 filterSettings.setSharpenLevel(1 + PROP_SHARPEN_LEVEL.get() / 2f);
85 }
86
87 public double getPPD() {
88 if (!Main.isDisplayingMapView())
89 return Main.getProjection().getDefaultZoomInPPD();
90 ProjectionBounds bounds = Main.map.mapView.getProjectionBounds();
91 return Main.map.mapView.getWidth() / (bounds.maxEast - bounds.minEast);
92 }
93
94 /**
95 * Gets the x displacement of this layer.
96 * To be removed end of 2016
97 * @return The x displacement.
98 * @deprecated Use {@link TileSourceDisplaySettings#getDx()}
99 */
100 @Deprecated
101 public double getDx() {
102 // moved to AbstractTileSourceLayer/TileSourceDisplaySettings. Remains until all actions migrate.
103 return 0;
104 }
105
106 /**
107 * Gets the y displacement of this layer.
108 * To be removed end of 2016
109 * @return The y displacement.
110 * @deprecated Use {@link TileSourceDisplaySettings#getDy()}
111 */
112 @Deprecated
113 public double getDy() {
114 // moved to AbstractTileSourceLayer/TileSourceDisplaySettings. Remains until all actions migrate.
115 return 0;
116 }
117
118 /**
119 * Sets the displacement offset of this layer. The layer is automatically invalidated.
120 * To be removed end of 2016
121 * @param dx The x offset
122 * @param dy The y offset
123 * @deprecated Use {@link TileSourceDisplaySettings}
124 */
125 @Deprecated
126 public void setOffset(double dx, double dy) {
127 // moved to AbstractTileSourceLayer/TileSourceDisplaySettings. Remains until all actions migrate.
128 }
129
130 /**
131 * To be removed end of 2016
132 * @param dx deprecated
133 * @param dy deprecated
134 * @deprecated Use {@link TileSourceDisplaySettings}
135 */
136 @Deprecated
137 public void displace(double dx, double dy) {
138 // moved to AbstractTileSourceLayer/TileSourceDisplaySettings. Remains until all actions migrate.
139 }
140
141 /**
142 * Returns imagery info.
143 * @return imagery info
144 */
145 public ImageryInfo getInfo() {
146 return info;
147 }
148
149 @Override
150 public Icon getIcon() {
151 return icon;
152 }
153
154 @Override
155 public boolean isMergable(Layer other) {
156 return false;
157 }
158
159 @Override
160 public void mergeFrom(Layer from) {
161 }
162
163 @Override
164 public Object getInfoComponent() {
165 JPanel panel = new JPanel(new GridBagLayout());
166 panel.add(new JLabel(getToolTipText()), GBC.eol());
167 if (info != null) {
168 String url = info.getUrl();
169 if (url != null) {
170 panel.add(new JLabel(tr("URL: ")), GBC.std().insets(0, 5, 2, 0));
171 panel.add(new UrlLabel(url), GBC.eol().insets(2, 5, 10, 0));
172 }
173 }
174 return panel;
175 }
176
177 public static ImageryLayer create(ImageryInfo info) {
178 switch(info.getImageryType()) {
179 case WMS:
180 case HTML:
181 return new WMSLayer(info);
182 case WMTS:
183 return new WMTSLayer(info);
184 case TMS:
185 case BING:
186 case SCANEX:
187 return new TMSLayer(info);
188 default:
189 throw new AssertionError(tr("Unsupported imagery type: {0}", info.getImageryType()));
190 }
191 }
192
193 class ApplyOffsetAction extends AbstractAction {
194 private final transient OffsetBookmark b;
195
196 ApplyOffsetAction(OffsetBookmark b) {
197 super(b.name);
198 this.b = b;
199 }
200
201 @Override
202 public void actionPerformed(ActionEvent ev) {
203 setOffset(b.dx, b.dy);
204 Main.main.menu.imageryMenu.refreshOffsetMenu();
205 Main.map.repaint();
206 }
207 }
208
209 public class OffsetAction extends AbstractAction implements LayerAction {
210 @Override
211 public void actionPerformed(ActionEvent e) {
212 // Do nothing
213 }
214
215 @Override
216 public Component createMenuComponent() {
217 return getOffsetMenuItem();
218 }
219
220 @Override
221 public boolean supportLayers(List<Layer> layers) {
222 return false;
223 }
224 }
225
226 public JMenuItem getOffsetMenuItem() {
227 JMenu subMenu = new JMenu(trc("layer", "Offset"));
228 subMenu.setIcon(ImageProvider.get("mapmode", "adjustimg"));
229 return (JMenuItem) getOffsetMenuItem(subMenu);
230 }
231
232 public JComponent getOffsetMenuItem(JComponent subMenu) {
233 JMenuItem adjustMenuItem = new JMenuItem(getAdjustAction());
234 if (OffsetBookmark.allBookmarks.isEmpty()) return adjustMenuItem;
235
236 subMenu.add(adjustMenuItem);
237 subMenu.add(new JSeparator());
238 boolean hasBookmarks = false;
239 int menuItemHeight = 0;
240 for (OffsetBookmark b : OffsetBookmark.allBookmarks) {
241 if (!b.isUsable(this)) {
242 continue;
243 }
244 JCheckBoxMenuItem item = new JCheckBoxMenuItem(new ApplyOffsetAction(b));
245 if (Utils.equalsEpsilon(b.dx, getDx()) && Utils.equalsEpsilon(b.dy, getDy())) {
246 item.setSelected(true);
247 }
248 subMenu.add(item);
249 menuItemHeight = item.getPreferredSize().height;
250 hasBookmarks = true;
251 }
252 if (menuItemHeight > 0) {
253 if (subMenu instanceof JMenu) {
254 MenuScroller.setScrollerFor((JMenu) subMenu);
255 } else if (subMenu instanceof JPopupMenu) {
256 MenuScroller.setScrollerFor((JPopupMenu) subMenu);
257 }
258 }
259 return hasBookmarks ? subMenu : adjustMenuItem;
260 }
261
262 protected abstract Action getAdjustAction();
263
264 /**
265 * Gets the settings for the filter that is applied to this layer.
266 * @return The filter settings.
267 * @since 10547
268 */
269 public ImageryFilterSettings getFilterSettings() {
270 return filterSettings;
271 }
272
273 /**
274 * This method adds the {@link ImageProcessor} to this Layer if it is not {@code null}.
275 *
276 * @param processor that processes the image
277 *
278 * @return true if processor was added, false otherwise
279 */
280 public boolean addImageProcessor(ImageProcessor processor) {
281 return processor != null && imageProcessors.add(processor);
282 }
283
284 /**
285 * This method removes given {@link ImageProcessor} from this layer
286 *
287 * @param processor which is needed to be removed
288 *
289 * @return true if processor was removed
290 */
291 public boolean removeImageProcessor(ImageProcessor processor) {
292 return imageProcessors.remove(processor);
293 }
294
295 /**
296 * Wraps a {@link BufferedImageOp} to be used as {@link ImageProcessor}.
297 * @param op the {@link BufferedImageOp}
298 * @param inPlace true to apply filter in place, i.e., not create a new {@link BufferedImage} for the result
299 * (the {@code op} needs to support this!)
300 * @return the {@link ImageProcessor} wrapper
301 */
302 public static ImageProcessor createImageProcessor(final BufferedImageOp op, final boolean inPlace) {
303 return image -> op.filter(image, inPlace ? image : null);
304 }
305
306 /**
307 * This method gets all {@link ImageProcessor}s of the layer
308 *
309 * @return list of image processors without removed one
310 */
311 public List<ImageProcessor> getImageProcessors() {
312 return imageProcessors;
313 }
314
315 /**
316 * Applies all the chosen {@link ImageProcessor}s to the image
317 *
318 * @param img - image which should be changed
319 *
320 * @return the new changed image
321 */
322 public BufferedImage applyImageProcessors(BufferedImage img) {
323 for (ImageProcessor processor : imageProcessors) {
324 img = processor.process(img);
325 }
326 return img;
327 }
328
329 @Override
330 public String toString() {
331 return getClass().getSimpleName() + " [info=" + info + ']';
332 }
333}
Note: See TracBrowser for help on using the repository browser.