Revision 41423

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.impl/src/main/java/org/gvsig/fmap/geom/primitive/impl/Envelope3D.java
3 3
 *
4 4
 * Copyright (C) 2007-2013 gvSIG Association.
5 5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
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 10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
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 15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
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.
20 19
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
23 22
 */
24
 
25 23
package org.gvsig.fmap.geom.primitive.impl;
26 24

  
27 25
import org.cresques.cts.ICoordTrans;
28 26
import org.gvsig.fmap.geom.primitive.Envelope;
27
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
29 28
import org.gvsig.fmap.geom.primitive.Point;
30 29
import org.gvsig.tools.ToolsLocator;
31 30
import org.gvsig.tools.dynobject.DynStruct;
......
35 34
/**
36 35
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
37 36
 */
38
public class Envelope3D extends DefaultEnvelope implements Cloneable{
39
	public static final String PERSISTENCE_DEFINITION_NAME = "Envelope3Dimensions";
40
        private static final int DIMENSION = 3;
41
        private boolean isZInitilized =false;
42
        
43
	public Envelope3D() {
44
		super();		
45
	}
37
public class Envelope3D extends DefaultEnvelope implements Cloneable {
46 38

  
47
	public Envelope3D(Point min, Point max) {
48
		super(min, max);
49
	}
50
	
51
	/* (non-Javadoc)
52
	 * @see org.gvsig.fmap.geom.primitive.Envelope#getDimension()
53
	 */
54
	public int getDimension() {
55
		return DIMENSION;
56
	}
57
	
58
	/*
59
	 * (non-Javadoc)
60
	 * @see org.gvsig.fmap.geom.primitive.Envelope#convert(org.cresques.cts.ICoordTrans)
61
	 */
62
	public Envelope convert(ICoordTrans trans) {
63
		return null;
64
	}
65
	
66
	public static void registerPersistent() {
67
		PersistenceManager manager = ToolsLocator.getPersistenceManager();
68
		if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
69
			DynStruct definition = manager.addDefinition(
70
					Envelope3D.class,
71
					PERSISTENCE_DEFINITION_NAME,
72
					"Envelope3D persistence definition",
73
					null, 
74
					null
75
			); 
76
			
77
			definition.extend(manager.getDefinition(DefaultEnvelope.PERSISTENCE_DEFINITION_NAME));	
78
		}
79
	}
39
    public static final String PERSISTENCE_DEFINITION_NAME = "Envelope3Dimensions";
40
    private static final int DIMENSION = 3;
41
    private boolean isZInitilized = false;
80 42

  
81
	public Object clone() throws CloneNotSupportedException {
82
	    return super.clone();
83
	}
84
        
85
        
43
    public Envelope3D() {
44
        super();
45
    }
46

  
47
    public Envelope3D(Point min, Point max) {
48
        super(min, max);
49
    }
50

  
51
    /* (non-Javadoc)
52
     * @see org.gvsig.fmap.geom.primitive.Envelope#getDimension()
53
     */
54
    public int getDimension() {
55
        return DIMENSION;
56
    }
57

  
58
    /*
59
     * (non-Javadoc)
60
     * @see org.gvsig.fmap.geom.primitive.Envelope#convert(org.cresques.cts.ICoordTrans)
61
     */
62
    public Envelope convert(ICoordTrans trans) {
63

  
64
        if (isEmpty) {
65
            throw new EnvelopeNotInitializedException();
66
        }
67

  
68
        if (trans == null) {
69
            // clone
70
            return new Envelope2D(this.getLowerCorner(), this.getUpperCorner());
71
        }
72

  
73
//        if (this.getDimension() > 2) {
74
//            return null;
75
//        }
76

  
77
	    // We'll reproject by taking samples like this:
78
        // 
79
        //  *---*---*---*---*
80
        //  |               |
81
        //  *   *   *   *   *
82
        //  |               |
83
        //  *   *   *   *   *
84
        //  |               |
85
        //  *   *   *   *   *
86
        //  |               |
87
        //  *---*---*---*---*
88
        // 
89
        // This is because:
90
        // 
91
        // - In some CRS (for example EPSG:4326) the north/south pole is a "line"
92
        //   while in other CRS the north/south pole is a point, so if you
93
        //   reproject the bounding box of the world, the result can be absurd.
94
        // - Sometimes the top/bottom/right/bottom of one envelope
95
        //   corresponds to a strange point in the the other envelope
96
        //   (not even a point in the perimeter)
97
        // - More generally, reprojecting usually implies a rotation (the result
98
        //   is a rotated envelope) so it's better to use a few
99
        //   samples along the perimeter.
100
        double xmin = getMinimum(0);
101
        double ymin = getMinimum(1);
102
        double step_w = 0.25 * (getMaximum(0) - xmin);
103
        double step_h = 0.25 * (getMaximum(1) - ymin);
104

  
105
        java.awt.geom.Point2D sample = null;
106
        java.awt.geom.Point2D sample_trans = null;
107
        // Init with worst values
108
        java.awt.geom.Point2D res_min = new java.awt.geom.Point2D.Double(
109
                Double.MAX_VALUE, Double.MAX_VALUE);
110
        java.awt.geom.Point2D res_max = new java.awt.geom.Point2D.Double(
111
                -Double.MAX_VALUE, -Double.MAX_VALUE);
112

  
113
        int added = 0;
114
        for (int i = 0; i < 5; i++) {
115
            for (int j = 0; j < 5; j++) {
116
                sample = new java.awt.geom.Point2D.Double(
117
                        xmin + i * step_w,
118
                        ymin + j * step_h);
119
                sample_trans = new java.awt.geom.Point2D.Double(0, 0);
120
                try {
121
                    sample_trans = trans.convert(sample, sample_trans);
122
                } catch (Exception exc) {
123
                    // Unable to convert this one: ignore
124
                    continue;
125
                }
126
	                // Update max/min found
127
                // X
128
                if (sample_trans.getX() > res_max.getX()) {
129
                    res_max.setLocation(sample_trans.getX(), res_max.getY());
130
                }
131
                if (sample_trans.getX() < res_min.getX()) {
132
                    res_min.setLocation(sample_trans.getX(), res_min.getY());
133
                }
134
                // Y
135
                if (sample_trans.getY() > res_max.getY()) {
136
                    res_max.setLocation(res_max.getX(), sample_trans.getY());
137
                }
138
                if (sample_trans.getY() < res_min.getY()) {
139
                    res_min.setLocation(res_min.getX(), sample_trans.getY());
140
                }
141
                added++;
142
            }
143
        }
144

  
145
        if (added == 0) {
146
            //logger.error("Unable to reproject envelope with transf: " + trans.toString());
147
            return null;
148
        }
149

  
150
        return new Envelope3D(
151
                new Point2DZ(res_min.getX(), res_min.getX(), this.min.getCoordinateAt(2)),
152
                new Point2DZ(res_max.getX(), res_max.getX(), this.max.getCoordinateAt(2))
153
        );
154

  
155
    }
156

  
157
    public static void registerPersistent() {
158
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
159
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
160
            DynStruct definition = manager.addDefinition(
161
                    Envelope3D.class,
162
                    PERSISTENCE_DEFINITION_NAME,
163
                    "Envelope3D persistence definition",
164
                    null,
165
                    null
166
            );
167

  
168
            definition.extend(manager.getDefinition(DefaultEnvelope.PERSISTENCE_DEFINITION_NAME));
169
        }
170
    }
171

  
172
    public Object clone() throws CloneNotSupportedException {
173
        return super.clone();
174
    }
175

  
86 176
    private void createPoints() {
87 177
        this.min = new Point2DZ(0, 0, 0);
88 178
        this.max = new Point2DZ(0, 0, 0);
89 179
    }
90
    
180

  
91 181
    public void add(Envelope envelope) {
92 182
        int i;
93
        
94
        if( envelope==null || envelope.isEmpty() ) {
183

  
184
        if (envelope == null || envelope.isEmpty()) {
95 185
            return;
96 186
        }
97
       
98
        int maxDimension = DIMENSION; 
99 187

  
100
        if( envelope.getDimension()==2 ) {
188
        int maxDimension = DIMENSION;
189

  
190
        if (envelope.getDimension() == 2) {
101 191
            maxDimension = 2;
102 192
        }
103
        
104
        if( this.isZInitilized ) {
105
            for (i=0;i<maxDimension;i++){
193

  
194
        if (this.isZInitilized) {
195
            for (i = 0; i < maxDimension; i++) {
106 196
                this.min.setCoordinateAt(i,
107
                    Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
197
                        Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
108 198
                this.max.setCoordinateAt(i,
109
                    Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
199
                        Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
110 200
            }
111 201
            return;
112 202
        }
113
        
114
        
115
        if (isEmpty){
203

  
204
        if (isEmpty) {
116 205
            createPoints();
117
            if( maxDimension == 3 ) {
206
            if (maxDimension == 3) {
118 207
                this.isZInitilized = true;
119 208
            }
120
            for (i=0;i<maxDimension;i++){
209
            for (i = 0; i < maxDimension; i++) {
121 210
                this.min.setCoordinateAt(i, envelope.getMinimum(i));
122 211
                this.max.setCoordinateAt(i, envelope.getMaximum(i));
123 212
            }
124 213
            isEmpty = false;
125 214
        } else {
126
            if( maxDimension==DIMENSION ) {
215
            if (maxDimension == DIMENSION) {
127 216
                this.min.setCoordinateAt(2, envelope.getMinimum(2));
128 217
                this.max.setCoordinateAt(2, envelope.getMaximum(2));
129 218
                this.isZInitilized = true;
130 219
            }
131
            for (i=0;i<maxDimension;i++){
220
            for (i = 0; i < maxDimension; i++) {
132 221
                this.min.setCoordinateAt(i,
133
                    Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
222
                        Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
134 223
                this.max.setCoordinateAt(i,
135
                    Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
224
                        Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
136 225
            }
137 226
        }
138 227
    }
139 228
}
140

  

Also available in: Unified diff