source: josm/trunk/src/org/openstreetmap/josm/gui/layer/geoimage/viewers/projections/Equirectangular.java

Last change on this file was 18877, checked in by taylor.smock, 11 months ago

See #23220: Use jakarta.annotation instead of javax.annotation (JSR305)

jsr305 should be removed in June 2024 to give plugins time to migrate.

Some lint issues were also fixed.

  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer.geoimage.viewers.projections;
3
4import java.awt.Component;
5import java.awt.Graphics;
6import java.awt.Image;
7import java.awt.Point;
8import java.awt.Rectangle;
9import java.awt.event.ComponentAdapter;
10import java.awt.event.ComponentEvent;
11import java.awt.image.BufferedImage;
12import java.util.Collections;
13import java.util.Set;
14
15import org.openstreetmap.josm.data.imagery.street_level.Projections;
16import org.openstreetmap.josm.gui.layer.geoimage.ImageDisplay;
17import org.openstreetmap.josm.gui.util.GuiHelper;
18import org.openstreetmap.josm.gui.util.imagery.CameraPlane;
19import org.openstreetmap.josm.gui.util.imagery.Vector3D;
20
21import jakarta.annotation.Nonnull;
22import jakarta.annotation.Nullable;
23
24/**
25 * A class for showing 360 images that use the equirectangular projection
26 * @author Taylor Smock
27 * @since 18246
28 */
29public class Equirectangular extends ComponentAdapter implements IImageViewer {
30 @Nullable
31 private volatile CameraPlane cameraPlane;
32 private volatile BufferedImage offscreenImage;
33
34 @Override
35 public Set<Projections> getSupportedProjections() {
36 return Collections.singleton(Projections.EQUIRECTANGULAR);
37 }
38
39 @Override
40 public void paintImage(Graphics g, BufferedImage image, Rectangle target, Rectangle visibleRect) {
41 final CameraPlane currentCameraPlane;
42 final BufferedImage currentOffscreenImage;
43 synchronized (this) {
44 final CameraPlane currentPlane = this.cameraPlane;
45 currentCameraPlane = currentPlane != null ? currentPlane : this.updateCameraPlane(target.width, target.height);
46 currentOffscreenImage = this.offscreenImage;
47 }
48 currentCameraPlane.mapping(image, currentOffscreenImage, visibleRect);
49 if (target == null) {
50 target = new Rectangle(0, 0, currentOffscreenImage.getWidth(null), currentOffscreenImage.getHeight(null));
51 }
52 g.drawImage(currentOffscreenImage, target.x, target.y, target.x + target.width, target.y + target.height,
53 visibleRect.x, visibleRect.y, visibleRect.x + visibleRect.width, visibleRect.y + visibleRect.height,
54 null);
55 }
56
57 @Override
58 public ImageDisplay.VisRect getDefaultVisibleRectangle(Component component, Image image) {
59 return new ImageDisplay.VisRect(0, 0, component.getSize().width, component.getSize().height);
60 }
61
62 @Override
63 public Vector3D getRotation() {
64 final CameraPlane currentPlane = this.cameraPlane;
65 if (currentPlane != null) {
66 return currentPlane.getRotation();
67 }
68 return IImageViewer.super.getRotation();
69 }
70
71 @Override
72 public void componentResized(ComponentEvent e) {
73 final Component imgDisplay = e.getComponent();
74 if (e.getComponent().getWidth() > 0
75 && e.getComponent().getHeight() > 0) {
76 updateCameraPlane(imgDisplay.getWidth(), imgDisplay.getHeight());
77 if (imgDisplay instanceof ImageDisplay) {
78 ((ImageDisplay) imgDisplay).updateVisibleRectangle();
79 }
80 GuiHelper.runInEDT(imgDisplay::revalidate);
81 }
82 }
83
84 /**
85 * Update the current camera plane
86 * @param width The width to use
87 * @param height The height to use
88 */
89 @Nonnull
90 private CameraPlane updateCameraPlane(int width, int height) {
91 // FIXME: Do something so that the types of the images are the same between the offscreenImage and
92 // the image entry
93 final CameraPlane currentCameraPlane;
94 synchronized (this) {
95 currentCameraPlane = this.cameraPlane;
96 }
97 final BufferedImage temporaryOffscreenImage = new BufferedImage(width, height,
98 BufferedImage.TYPE_4BYTE_ABGR);
99
100 Vector3D currentRotation = null;
101 if (currentCameraPlane != null) {
102 currentRotation = currentCameraPlane.getRotation();
103 }
104 final CameraPlane temporaryCameraPlane = new CameraPlane(width, height);
105 if (currentRotation != null) {
106 temporaryCameraPlane.setRotation(currentRotation);
107 }
108 synchronized (this) {
109 this.cameraPlane = temporaryCameraPlane;
110 this.offscreenImage = temporaryOffscreenImage;
111 }
112 return temporaryCameraPlane;
113 }
114
115 @Override
116 public void mouseDragged(final Point from, final Point to, ImageDisplay.VisRect currentVisibleRect) {
117 final CameraPlane currentPlane = this.cameraPlane;
118 if (from != null && to != null && currentPlane != null) {
119 currentPlane.setRotationFromDelta(from, to);
120 }
121 }
122
123 @Override
124 public void checkAndModifyVisibleRectSize(Image image, ImageDisplay.VisRect visibleRect) {
125 IImageViewer.super.checkAndModifyVisibleRectSize(this.offscreenImage, visibleRect);
126 }
127
128 @Override
129 public Image getMaxImageSize(ImageDisplay imageDisplay, Image image) {
130 return this.offscreenImage;
131 }
132}
Note: See TracBrowser for help on using the repository browser.