svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / primitive / Envelope3D.java @ 42281
History | View | Annotate | Download (8.82 KB)
1 | 42260 | fdiaz | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | *
|
||
4 | * Copyright (C) 2007-2013 gvSIG Association.
|
||
5 | *
|
||
6 | * This program is free software; you can redistribute it and/or modify it under
|
||
7 | * the terms of the GNU General Public License as published by the Free Software
|
||
8 | * Foundation; either version 3 of the License, or (at your option) any later
|
||
9 | * version.
|
||
10 | *
|
||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
|
||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||
14 | * details.
|
||
15 | *
|
||
16 | * You should have received a copy of the GNU General Public License along with
|
||
17 | * this program; if not, write to the Free Software Foundation, Inc., 51
|
||
18 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
19 | *
|
||
20 | * For any additional information, do not hesitate to contact us at info AT
|
||
21 | * gvsig.com, or visit our website www.gvsig.com.
|
||
22 | */
|
||
23 | package org.gvsig.fmap.geom.jts.primitive; |
||
24 | |||
25 | import com.vividsolutions.jts.geom.Coordinate; |
||
26 | |||
27 | import org.cresques.cts.ICoordTrans; |
||
28 | |||
29 | import org.gvsig.fmap.geom.jts.primitive.point.Point3D; |
||
30 | import org.gvsig.fmap.geom.primitive.Envelope; |
||
31 | import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException; |
||
32 | import org.gvsig.fmap.geom.primitive.Point; |
||
33 | import org.gvsig.tools.ToolsLocator; |
||
34 | import org.gvsig.tools.dynobject.DynStruct; |
||
35 | import org.gvsig.tools.lang.Cloneable; |
||
36 | import org.gvsig.tools.persistence.PersistenceManager; |
||
37 | |||
38 | /**
|
||
39 | * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
|
||
40 | */
|
||
41 | public class Envelope3D extends DefaultEnvelope implements Cloneable { |
||
42 | |||
43 | public static final String PERSISTENCE_DEFINITION_NAME = "Envelope3Dimensions"; |
||
44 | private static final int DIMENSION = 3; |
||
45 | private boolean isZInitilized = false; |
||
46 | |||
47 | public Envelope3D() {
|
||
48 | super();
|
||
49 | } |
||
50 | |||
51 | public Envelope3D(Point min, Point max) { |
||
52 | super(min, max);
|
||
53 | } |
||
54 | |||
55 | /**
|
||
56 | * @param coordinates
|
||
57 | */
|
||
58 | public Envelope3D(Coordinate[] coordinates) { |
||
59 | double minx = Double.POSITIVE_INFINITY; |
||
60 | double miny = Double.POSITIVE_INFINITY; |
||
61 | double minz = Double.POSITIVE_INFINITY; |
||
62 | |||
63 | double maxx = Double.NEGATIVE_INFINITY; |
||
64 | double maxy = Double.NEGATIVE_INFINITY; |
||
65 | double maxz = Double.NEGATIVE_INFINITY; |
||
66 | |||
67 | double x;
|
||
68 | double y;
|
||
69 | double z;
|
||
70 | |||
71 | for (int i = 0; i < coordinates.length; i++) { |
||
72 | x = coordinates[i].x; |
||
73 | y = coordinates[i].x; |
||
74 | z = coordinates[i].x; |
||
75 | minx = Math.min(x, minx);
|
||
76 | miny = Math.min(y, miny);
|
||
77 | minz = Math.min(z, minz);
|
||
78 | maxx = Math.max(x, maxx);
|
||
79 | maxy = Math.max(y, maxy);
|
||
80 | maxz = Math.max(z, maxz);
|
||
81 | } |
||
82 | |||
83 | if (minx <= maxx && miny <= maxy && minz <= maxz) {
|
||
84 | min = new Point3D(minx, miny, minz);
|
||
85 | max = new Point3D(maxx, maxy, maxz);
|
||
86 | isEmpty = false;
|
||
87 | } else {
|
||
88 | isEmpty = true;
|
||
89 | } |
||
90 | } |
||
91 | |||
92 | /*
|
||
93 | * (non-Javadoc)
|
||
94 | *
|
||
95 | * @see org.gvsig.fmap.geom.primitive.Envelope#getDimension()
|
||
96 | */
|
||
97 | public int getDimension() { |
||
98 | return DIMENSION;
|
||
99 | } |
||
100 | |||
101 | /*
|
||
102 | * (non-Javadoc)
|
||
103 | *
|
||
104 | * @see
|
||
105 | * org.gvsig.fmap.geom.primitive.Envelope#convert(org.cresques.cts.ICoordTrans
|
||
106 | * )
|
||
107 | */
|
||
108 | public Envelope convert(ICoordTrans trans) {
|
||
109 | |||
110 | if (isEmpty) {
|
||
111 | throw new EnvelopeNotInitializedException(); |
||
112 | } |
||
113 | |||
114 | if (trans == null) { |
||
115 | // clone
|
||
116 | return new Envelope2D(this.getLowerCorner(), this.getUpperCorner()); |
||
117 | } |
||
118 | |||
119 | // if (this.getDimension() > 2) {
|
||
120 | // return null;
|
||
121 | // }
|
||
122 | |||
123 | // We'll reproject by taking samples like this:
|
||
124 | //
|
||
125 | // *---*---*---*---*
|
||
126 | // | |
|
||
127 | // * * * * *
|
||
128 | // | |
|
||
129 | // * * * * *
|
||
130 | // | |
|
||
131 | // * * * * *
|
||
132 | // | |
|
||
133 | // *---*---*---*---*
|
||
134 | //
|
||
135 | // This is because:
|
||
136 | //
|
||
137 | // - In some CRS (for example EPSG:4326) the north/south pole is a
|
||
138 | // "line"
|
||
139 | // while in other CRS the north/south pole is a point, so if you
|
||
140 | // reproject the bounding box of the world, the result can be absurd.
|
||
141 | // - Sometimes the top/bottom/right/bottom of one envelope
|
||
142 | // corresponds to a strange point in the the other envelope
|
||
143 | // (not even a point in the perimeter)
|
||
144 | // - More generally, reprojecting usually implies a rotation (the result
|
||
145 | // is a rotated envelope) so it's better to use a few
|
||
146 | // samples along the perimeter.
|
||
147 | double xmin = getMinimum(0); |
||
148 | double ymin = getMinimum(1); |
||
149 | double step_w = 0.25 * (getMaximum(0) - xmin); |
||
150 | double step_h = 0.25 * (getMaximum(1) - ymin); |
||
151 | |||
152 | java.awt.geom.Point2D sample = null;
|
||
153 | java.awt.geom.Point2D sample_trans = null;
|
||
154 | // Init with worst values
|
||
155 | java.awt.geom.Point2D res_min = new java.awt.geom.Point2D.Double(Double.MAX_VALUE, Double.MAX_VALUE); |
||
156 | java.awt.geom.Point2D res_max = new java.awt.geom.Point2D.Double(-Double.MAX_VALUE, -Double.MAX_VALUE); |
||
157 | |||
158 | int added = 0; |
||
159 | for (int i = 0; i < 5; i++) { |
||
160 | for (int j = 0; j < 5; j++) { |
||
161 | sample = new java.awt.geom.Point2D.Double(xmin + i * step_w, ymin + j * step_h);
|
||
162 | sample_trans = new java.awt.geom.Point2D.Double(0, 0); |
||
163 | try {
|
||
164 | sample_trans = trans.convert(sample, sample_trans); |
||
165 | } catch (Exception exc) { |
||
166 | // Unable to convert this one: ignore
|
||
167 | continue;
|
||
168 | } |
||
169 | // Update max/min found
|
||
170 | // X
|
||
171 | if (sample_trans.getX() > res_max.getX()) {
|
||
172 | res_max.setLocation(sample_trans.getX(), res_max.getY()); |
||
173 | } |
||
174 | if (sample_trans.getX() < res_min.getX()) {
|
||
175 | res_min.setLocation(sample_trans.getX(), res_min.getY()); |
||
176 | } |
||
177 | // Y
|
||
178 | if (sample_trans.getY() > res_max.getY()) {
|
||
179 | res_max.setLocation(res_max.getX(), sample_trans.getY()); |
||
180 | } |
||
181 | if (sample_trans.getY() < res_min.getY()) {
|
||
182 | res_min.setLocation(res_min.getX(), sample_trans.getY()); |
||
183 | } |
||
184 | added++; |
||
185 | } |
||
186 | } |
||
187 | |||
188 | if (added == 0) { |
||
189 | // logger.error("Unable to reproject envelope with transf: " +
|
||
190 | // trans.toString());
|
||
191 | return null; |
||
192 | } |
||
193 | |||
194 | return new Envelope3D(new Point3D(res_min.getX(), res_min.getX(), this.min.getCoordinateAt(2)), new Point3D( |
||
195 | res_max.getX(), res_max.getX(), this.max.getCoordinateAt(2))); |
||
196 | |||
197 | } |
||
198 | |||
199 | public static void registerPersistent() { |
||
200 | PersistenceManager manager = ToolsLocator.getPersistenceManager(); |
||
201 | if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) { |
||
202 | DynStruct definition = |
||
203 | manager.addDefinition(Envelope3D.class, PERSISTENCE_DEFINITION_NAME, |
||
204 | "Envelope3D persistence definition", null, null); |
||
205 | |||
206 | definition.extend(manager.getDefinition(DefaultEnvelope.PERSISTENCE_DEFINITION_NAME)); |
||
207 | } |
||
208 | } |
||
209 | |||
210 | public Object clone() throws CloneNotSupportedException { |
||
211 | return super.clone(); |
||
212 | } |
||
213 | |||
214 | private void createPoints() { |
||
215 | this.min = new Point3D(0, 0, 0); |
||
216 | this.max = new Point3D(0, 0, 0); |
||
217 | } |
||
218 | |||
219 | public void add(Envelope envelope) { |
||
220 | int i;
|
||
221 | |||
222 | if (envelope == null || envelope.isEmpty()) { |
||
223 | return;
|
||
224 | } |
||
225 | |||
226 | int maxDimension = DIMENSION;
|
||
227 | |||
228 | if (envelope.getDimension() == 2) { |
||
229 | maxDimension = 2;
|
||
230 | } |
||
231 | |||
232 | if (this.isZInitilized) { |
||
233 | for (i = 0; i < maxDimension; i++) { |
||
234 | this.min.setCoordinateAt(i, Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i))); |
||
235 | this.max.setCoordinateAt(i, Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i))); |
||
236 | } |
||
237 | return;
|
||
238 | } |
||
239 | |||
240 | if (isEmpty) {
|
||
241 | createPoints(); |
||
242 | if (maxDimension == 3) { |
||
243 | this.isZInitilized = true; |
||
244 | } |
||
245 | for (i = 0; i < maxDimension; i++) { |
||
246 | this.min.setCoordinateAt(i, envelope.getMinimum(i));
|
||
247 | this.max.setCoordinateAt(i, envelope.getMaximum(i));
|
||
248 | } |
||
249 | isEmpty = false;
|
||
250 | } else {
|
||
251 | if (maxDimension == DIMENSION) {
|
||
252 | this.min.setCoordinateAt(2, envelope.getMinimum(2)); |
||
253 | this.max.setCoordinateAt(2, envelope.getMaximum(2)); |
||
254 | this.isZInitilized = true; |
||
255 | } |
||
256 | for (i = 0; i < maxDimension; i++) { |
||
257 | this.min.setCoordinateAt(i, Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i))); |
||
258 | this.max.setCoordinateAt(i, Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i))); |
||
259 | } |
||
260 | } |
||
261 | } |
||
262 | } |