Statistics
| Revision:

svn-gvsig-desktop / 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 / Envelope2D.java @ 41209

History | View | Annotate | Download (6.39 KB)

1
/**
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
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.
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.
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.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.fmap.geom.primitive.impl;
26

    
27
import java.awt.geom.Rectangle2D;
28

    
29
import org.cresques.cts.ICoordTrans;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.fmap.geom.Geometry;
34
import org.gvsig.fmap.geom.GeometryLocator;
35
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
36
import org.gvsig.fmap.geom.primitive.Envelope;
37
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
38
import org.gvsig.fmap.geom.primitive.Point;
39
import org.gvsig.tools.ToolsLocator;
40
import org.gvsig.tools.dynobject.DynStruct;
41
import org.gvsig.tools.lang.Cloneable;
42
import org.gvsig.tools.locator.LocatorException;
43
import org.gvsig.tools.persistence.PersistenceManager;
44

    
45
/**
46
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
47
 */
48
public class Envelope2D extends DefaultEnvelope implements Cloneable{
49
    
50
    private static final Logger logger = LoggerFactory.getLogger(Envelope2D.class);
51
    
52
        public static final String PERSISTENCE_DEFINITION_NAME = "Envelope2Dimensions";
53
        
54
        public Envelope2D() {
55
                super();        
56
        }
57

    
58
        public Envelope2D(Point min, Point max) {
59
                super(min, max);
60
        }
61

    
62
        public Envelope2D(double minX,double minY,double maxX, double maxY){
63
                this(new Point2D(minX, minY), new Point2D(maxX, maxY));
64
        }
65

    
66
        /* (non-Javadoc)
67
         * @see org.gvsig.fmap.geom.primitive.Envelope#getDimension()
68
         */
69
        public int getDimension() {
70
                return 2;
71
        }
72

    
73
        /*
74
         * (non-Javadoc)
75
         * @see org.gvsig.fmap.geom.primitive.Envelope#convert(org.cresques.cts.ICoordTrans)
76
         */
77
        public Envelope convert(ICoordTrans trans) {
78
            
79
            if (isEmpty){
80
            throw new EnvelopeNotInitializedException();
81
        }
82
            
83
            if (trans == null) {
84
                // clone
85
                return new Envelope2D(this.getLowerCorner(), this.getUpperCorner());
86
            }
87
            
88
            if (this.getDimension() > 2) {
89
                        return null;
90
                }
91
            
92
            // We'll reproject by taking samples like this:
93
            // 
94
            //  *---*---*---*---*
95
        //  |               |
96
        //  *   *   *   *   *
97
        //  |               |
98
        //  *   *   *   *   *
99
        //  |               |
100
        //  *   *   *   *   *
101
        //  |               |
102
        //  *---*---*---*---*
103
            // 
104
            // This is because:
105
            // 
106
            // - In some CRS (for example EPSG:4326) the north/south pole is a "line"
107
            //   while in other CRS the north/south pole is a point, so if you
108
            //   reproject the bounding box of the world, the result can be absurd.
109
            // - Sometimes the top/bottom/right/bottom of one envelope
110
            //   corresponds to a strange point in the the other envelope
111
            //   (not even a point in the perimeter)
112
            // - More generally, reprojecting usually implies a rotation (the result
113
            //   is a rotated envelope) so it's better to use a few
114
            //   samples along the perimeter.
115
            
116
            double xmin = getMinimum(0);
117
            double ymin = getMinimum(1);
118
            double step_w = 0.25 * (getMaximum(0) - xmin);
119
            double step_h = 0.25 * (getMaximum(1) - ymin);
120

    
121
            java.awt.geom.Point2D sample = null;
122
            java.awt.geom.Point2D sample_trans = null;
123
            // Init with worst values
124
        java.awt.geom.Point2D res_min = new java.awt.geom.Point2D.Double(
125
            Double.MAX_VALUE, Double.MAX_VALUE);
126
        java.awt.geom.Point2D res_max = new java.awt.geom.Point2D.Double(
127
            -Double.MAX_VALUE, -Double.MAX_VALUE);
128
           
129
        int added = 0;
130
            for (int i=0; i<5; i++) {
131
                for (int j=0; j<5; j++) {
132
                        sample = new java.awt.geom.Point2D.Double(
133
                            xmin + i * step_w,
134
                            ymin + j * step_h);
135
                        sample_trans = new java.awt.geom.Point2D.Double(0,0);
136
                        try {
137
                            trans.convert(sample, sample_trans);
138
                        } catch (Exception exc) {
139
                            // Unable to convert this one: ignore
140
                            continue;
141
                        }
142
                        // Update max/min found
143
                        // X
144
                        if (sample_trans.getX() > res_max.getX()) {
145
                            res_max.setLocation(sample_trans.getX(), res_max.getY());
146
                        } else {
147
                            if (sample_trans.getX() < res_min.getX()) {
148
                                res_min.setLocation(sample_trans.getX(), res_min.getY());
149
                            }
150
                        }
151
                        // Y
152
                    if (sample_trans.getY() > res_max.getY()) {
153
                        res_max.setLocation(res_max.getX(), sample_trans.getY());
154
                    } else {
155
                        if (sample_trans.getY() < res_min.getY()) {
156
                            res_min.setLocation(res_min.getX(), sample_trans.getY());
157
                        }
158
                    }
159
                    added++;
160
                }
161
            }
162
            
163
            if (added == 0) {
164
                logger.error("Unable to reproject envelope with transf: " + trans.toString());
165
                return null;
166
            }
167
            
168
                return new Envelope2D(
169
                    res_min.getX(),
170
                    res_min.getY(),
171
                    res_max.getX(),
172
                    res_max.getY());
173
        }
174

    
175
        public static void registerPersistent() {
176
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
177
                if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
178
                        DynStruct definition = manager.addDefinition(
179
                                        Envelope2D.class,
180
                                        PERSISTENCE_DEFINITION_NAME,
181
                                        "Envelope2D persistence definition",
182
                                        null, 
183
                                        null
184
                        ); 
185
                        
186
                        definition.extend(manager.getDefinition(DefaultEnvelope.PERSISTENCE_DEFINITION_NAME));        
187
                }
188
        }
189
        
190
    public Object clone() throws CloneNotSupportedException {
191
        return super.clone();
192
    }
193
}
194