source: osm/applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/GeorefImage.java@ 17089

Last change on this file since 17089 was 17089, checked in by pieren, 15 years ago

raster image feature implementation

  • Property svn:eol-style set to native
File size: 8.6 KB
Line 
1package cadastre_fr;
2
3import java.awt.AlphaComposite;
4import java.awt.Color;
5import java.awt.Graphics;
6import java.awt.Graphics2D;
7import java.awt.GraphicsConfiguration;
8import java.awt.GraphicsDevice;
9import java.awt.GraphicsEnvironment;
10import java.awt.Point;
11import java.awt.Transparency;
12import java.awt.image.BufferedImage;
13import java.io.IOException;
14import java.io.ObjectInputStream;
15import java.io.ObjectOutputStream;
16import java.io.Serializable;
17
18import javax.imageio.ImageIO;
19
20import org.openstreetmap.josm.data.coor.EastNorth;
21import org.openstreetmap.josm.gui.NavigatableComponent;
22
23public class GeorefImage implements Serializable {
24 private static final long serialVersionUID = 1L;
25
26 public EastNorth min;
27 public EastNorth max;
28 public BufferedImage image;
29
30 private double pixelPerEast;
31 private double pixelPerNorth;
32
33 public GeorefImage(BufferedImage img, EastNorth min, EastNorth max) {
34 image = img;
35 this.min = min;
36 this.max = max;
37 updatePixelPer();
38 }
39
40 public static GraphicsConfiguration getDefaultConfiguration() {
41 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
42 GraphicsDevice gd = ge.getDefaultScreenDevice();
43 return gd.getDefaultConfiguration();
44 }
45
46 private void getNewBounding(EastNorth min, EastNorth max, EastNorth c, EastNorth d) {
47 EastNorth pt[] = new EastNorth[4];
48 pt[0] = min;
49 pt[1] = max;
50 pt[2] = c;
51 pt[3] = d;
52 double smallestEast = Double.MAX_VALUE;
53 double smallestNorth = Double.MAX_VALUE;
54 double highestEast = Double.MIN_VALUE;
55 double highestNorth = Double.MIN_VALUE;
56 for(int i=0; i<=3; i++) {
57 smallestEast = Math.min(pt[i].east(), smallestEast);
58 smallestNorth = Math.min(pt[i].north(), smallestNorth);
59 highestEast = Math.max(pt[i].east(), highestEast);
60 highestNorth = Math.max(pt[i].north(), highestNorth);
61 }
62 min.setLocation(smallestEast, smallestNorth);
63 max.setLocation(highestEast, highestNorth);
64 }
65
66 public boolean contains(EastNorth en) {
67 return min.east() <= en.east() && en.east() <= max.east() && min.north() <= en.north()
68 && en.north() <= max.north();
69 }
70
71 public void paint(Graphics2D g, NavigatableComponent nc, boolean backgroundTransparent, float transparency,
72 boolean drawBoundaries) {
73 if (image == null || min == null || max == null)
74 return;
75
76 Point minPt = nc.getPoint(min), maxPt = nc.getPoint(max);
77
78 if (!g.hitClip(minPt.x, maxPt.y, maxPt.x - minPt.x, minPt.y - maxPt.y))
79 return;
80
81 if (backgroundTransparent && transparency < 1.0f)
82 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transparency));
83 if (drawBoundaries) {
84 g.setColor(Color.green);
85 g.drawRect(minPt.x, maxPt.y, maxPt.x - minPt.x, minPt.y - maxPt.y);
86 }
87 g.drawImage(image, minPt.x, maxPt.y, maxPt.x, minPt.y, // dest
88 0, 0, image.getWidth(), image.getHeight(), // src
89 null);
90 if (backgroundTransparent && transparency < 1.0f)
91 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
92 }
93
94 /**
95 * Is the given bbox overlapping this image ?
96 */
97 public boolean overlap(GeorefImage georefImage) {
98 if (this.contains(georefImage.min) || this.contains(georefImage.max))
99 return true;
100 if (this.contains(new EastNorth(georefImage.min.east(), georefImage.max.north()))
101 || this.contains(new EastNorth(georefImage.max.east(), georefImage.min.north())))
102 return true;
103 return false;
104 }
105
106 /**
107 * Make all pixels masked by the given georefImage transparent in this image
108 *
109 * @param georefImage
110 */
111 public void withdraw(GeorefImage georefImage) {
112 double minMaskEast = (georefImage.min.east() > this.min.east()) ? georefImage.min.east() : this.min.east();
113 double maxMaskEast = (georefImage.max.east() < this.max.east()) ? georefImage.max.east() : this.max.east();
114 double minMaskNorth = (georefImage.min.north() > this.min.north()) ? georefImage.min.north() : this.min.north();
115 double maxMaskNorth = (georefImage.max.north() < this.max.north()) ? georefImage.max.north() : this.max.north();
116 if ((maxMaskNorth - minMaskNorth) > 0 && (maxMaskEast - minMaskEast) > 0) {
117 double pixelPerEast = (max.east() - min.east()) / image.getWidth();
118 double pixelPerNorth = (max.north() - min.north()) / image.getHeight();
119 int minXMaskPixel = (int) ((minMaskEast - min.east()) / pixelPerEast);
120 int minYMaskPixel = (int) ((max.north() - maxMaskNorth) / pixelPerNorth);
121 int widthXMaskPixel = Math.abs((int) ((maxMaskEast - minMaskEast) / pixelPerEast));
122 int heightYMaskPixel = Math.abs((int) ((maxMaskNorth - minMaskNorth) / pixelPerNorth));
123 Graphics g = image.getGraphics();
124 for (int x = minXMaskPixel; x < minXMaskPixel + widthXMaskPixel; x++)
125 for (int y = minYMaskPixel; y < minYMaskPixel + heightYMaskPixel; y++)
126 image.setRGB(x, y, VectorImageModifier.cadastreBackgroundTransp);
127 g.dispose();
128 }
129 }
130
131 /*
132 * Method required by BufferedImage serialization
133 */
134 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
135 max = (EastNorth) in.readObject();
136 min = (EastNorth) in.readObject();
137 image = (BufferedImage) ImageIO.read(ImageIO.createImageInputStream(in));
138 updatePixelPer();
139 }
140
141 /*
142 * Method required by BufferedImage serialization
143 */
144 private void writeObject(ObjectOutputStream out) throws IOException {
145 out.writeObject(max);
146 out.writeObject(min);
147 ImageIO.write(image, "png", ImageIO.createImageOutputStream(out));
148 }
149
150 private void updatePixelPer() {
151 pixelPerEast = image.getWidth()/(max.east()-min.east());
152 pixelPerNorth = image.getHeight()/(max.north()-min.north());
153 }
154
155 public double getPixelPerEast() {
156 return pixelPerEast;
157 }
158
159 public double getPixelPerNorth() {
160 return pixelPerNorth;
161 }
162
163 @Override
164 public String toString() {
165 return "GeorefImage[min=" + min + ", max=" + max + ", image" + image + "]";
166 }
167
168 /*
169 * Following methods are used for affine transformation of two points p1 and p2
170 */
171 /**
172 * Add a translation (dx, dy) to this image min,max coordinates
173 * @param dx delta added to X image coordinate
174 * @param dy delta added to Y image coordinate
175 */
176 public void shear(double dx, double dy) {
177 min = new EastNorth(min.east() + dx, min.north() + dy);
178 max = new EastNorth(max.east() + dx, max.north() + dy);
179 }
180
181 /**
182 * Change this image scale by moving the min,max coordinates around an anchor
183 * @param anchor
184 * @param proportion
185 */
186 public void scale(EastNorth anchor, double proportion) {
187 min = anchor.interpolate(min, proportion);
188 max = anchor.interpolate(max, proportion);
189 updatePixelPer();
190 }
191
192 /**
193 * Rotate this image and its min/max coordinates around anchor point
194 * @param anchor anchor of rotation
195 * @param angle angle of rotation (in radians)
196 */
197 public void rotate(EastNorth anchor, double angle) {
198 EastNorth min2 = new EastNorth(min.east(), max.north());
199 EastNorth max2 = new EastNorth(max.east(), min.north());
200 min = min.rotate(anchor, angle);
201 max = max.rotate(anchor, angle);
202 min2 = min2.rotate(anchor, angle);
203 max2 = max2.rotate(anchor, angle);
204 getNewBounding(min, max, min2, max2);
205 image = tilt(image, angle);
206 }
207
208 /**
209 * Rotate by copying original buffered image into a new one with new dimensions
210 * @param image
211 * @param angle
212 * @return
213 */
214 public static BufferedImage tilt(BufferedImage image, double angle) {
215 double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
216 int w = image.getWidth(), h = image.getHeight();
217 int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
218 GraphicsConfiguration gc = getDefaultConfiguration();
219 BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
220 Graphics2D g = result.createGraphics();
221 g.translate((neww-w)/2, (newh-h)/2);
222 g.rotate(angle, w/2, h/2);
223 g.drawRenderedImage(image, null);
224 g.dispose();
225 return result;
226 }
227
228}
Note: See TracBrowser for help on using the repository browser.