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 / DefaultEnvelope.java @ 40596

History | View | Annotate | Download (10.2 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.text.MessageFormat;
28

    
29
import org.slf4j.Logger;
30
import org.slf4j.LoggerFactory;
31

    
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
34
import org.gvsig.fmap.geom.Geometry.TYPES;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.exception.CreateGeometryException;
38
import org.gvsig.fmap.geom.primitive.Envelope;
39
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
40
import org.gvsig.fmap.geom.primitive.Point;
41
import org.gvsig.fmap.geom.primitive.Surface;
42
import org.gvsig.tools.ToolsLocator;
43
import org.gvsig.tools.dynobject.DynStruct;
44
import org.gvsig.tools.persistence.PersistenceManager;
45
import org.gvsig.tools.persistence.PersistentState;
46
import org.gvsig.tools.persistence.exception.PersistenceException;
47

    
48

    
49
/**
50
 * A minimum bounding box or rectangle. Regardless of dimension, an Envelope
51
 * can be represented without ambiguity as two direct positions (coordinate
52
 * points). To encode an Envelope, it is sufficient to encode these two
53
 * points. This is consistent with all of the data types in this
54
 * specification, their state is represented by their publicly accessible
55
 * attributes.
56

57
 * @author Vicente Caballero Navarro
58
 */
59
public abstract class DefaultEnvelope implements Envelope, org.gvsig.tools.lang.Cloneable{
60
    private static final Logger LOG =
61
        LoggerFactory.getLogger(DefaultEnvelope.class);
62

    
63
    public static final String PERSISTENCE_DEFINITION_NAME = "Envelope";
64

    
65
    protected static final String LOWERCORNER_FIELD = "lowerCorner";
66
    protected static final String UPPERCORNER_FIELD = "upperCorner";
67

    
68
    protected Point min;
69
    protected Point max;
70

    
71
    protected boolean isEmpty;
72

    
73
    protected static GeometryManager manager = GeometryLocator.getGeometryManager();
74

    
75
    public DefaultEnvelope(){
76
        super();
77
        isEmpty = true;
78
    }
79

    
80
    public DefaultEnvelope(Point min, Point max){
81
        super();
82
        this.min = min;
83
        this.max = max;
84
        isEmpty = false;
85
    }
86

    
87
    public String toString() {
88
        return MessageFormat.format(
89
            "Envelop(min={0},max={1})", 
90
            new Object[] {
91
                min.toString(),
92
                max.toString()
93
            }
94
        );
95
    }
96

    
97
    /**
98
     * Returns the center ordinate along the specified dimension.
99
     *
100
     * @param dimension DOCUMENT ME!
101
     *
102
     * @return DOCUMENT ME!
103
     */
104
    public double getCenter(int dimension) {
105
        if (isEmpty){
106
            throw new EnvelopeNotInitializedException();
107
        }
108
        return (min.getCoordinateAt(dimension) + max.getCoordinateAt(dimension)) * 0.5;
109
    }
110

    
111
    /**
112
     * Returns the envelope length along the specified dimension.
113
     *
114
     * @param dimension
115
     *
116
     * @return
117
     */
118
    public double getLength(int dimension) {
119
        if (isEmpty){
120
            throw new EnvelopeNotInitializedException();
121
        }
122
        if (max.getCoordinateAt(dimension) > min.getCoordinateAt(dimension)) {
123
            return max.getCoordinateAt(dimension) - min.getCoordinateAt(dimension);
124
        }
125

    
126
        return min.getCoordinateAt(dimension) - max.getCoordinateAt(dimension);
127
    }
128

    
129
    /**
130
     * A coordinate position consisting of all the minimal ordinates for each
131
     * dimension for all points within the Envelope.
132
     *
133
     * @return
134
     */
135
    public Point getLowerCorner() {
136
        return min;
137
    }
138

    
139
    /**
140
     * Returns the maximal ordinate along the specified dimension.
141
     *
142
     * @param dimension
143
     *
144
     * @return
145
     */
146
    public double getMaximum(int dimension) {
147
        if (isEmpty){
148
            throw new EnvelopeNotInitializedException();
149
        }
150
        return max.getCoordinateAt(dimension);
151
    }
152

    
153
    /**
154
     * Returns the minimal ordinate along the specified dimension.
155
     *
156
     * @param dimension
157
     *
158
     * @return
159
     */
160
    public double getMinimum(int dimension) {
161
        if (isEmpty){
162
            throw new EnvelopeNotInitializedException();
163
        }
164
        return min.getCoordinateAt(dimension);
165
    }
166

    
167
    /**
168
     * A coordinate position consisting of all the maximal ordinates for each
169
     * dimension for all points within the Envelope.
170
     *
171
     * @return
172
     */
173
    public Point getUpperCorner() {
174
        return max;
175
    }
176

    
177
    public void add(Envelope envelope) {
178
        if (isEmpty){
179
            setLowerCorner((Point)envelope.getLowerCorner().cloneGeometry());
180
            setUpperCorner((Point)envelope.getUpperCorner().cloneGeometry());          
181
        }else{
182
            int maxDimension = Math.min(getDimension(), envelope.getDimension());
183
            int i;
184
            for (i=0;i<maxDimension;i++){
185
                this.min.setCoordinateAt(i,
186
                    Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
187
                this.max.setCoordinateAt(i,
188
                    Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
189
            }
190
        }
191
    }
192

    
193
    public Geometry getGeometry() {
194
        if (isEmpty){
195
            throw new EnvelopeNotInitializedException();
196
        }
197
        try {
198
            Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
199
            surface.addMoveToVertex((Point)min.cloneGeometry());
200
            surface.addVertex(manager.createPoint(getMaximum(0),getMinimum(1), SUBTYPES.GEOM2D));
201
            surface.addVertex((Point)max.cloneGeometry());
202
            surface.addVertex(manager.createPoint(getMinimum(0),getMaximum(1), SUBTYPES.GEOM2D));
203
            surface.closePrimitive();
204
            return surface;
205
        } catch (CreateGeometryException e) {
206
            LOG.error("Error creting the surface", e);
207
        }          
208
        return null;
209
    }
210

    
211
    public boolean contains(Envelope envelope) {
212
        if (isEmpty){
213
            return false;
214
        }
215
        if((envelope == null) || (envelope.isEmpty())) {
216
            return false;
217
        }
218
        for (int i = 0; i < getDimension(); i++) {
219
            if (getMinimum(i) > envelope.getMinimum(i)
220
                || getMaximum(i) < envelope.getMaximum(i)) {
221
                return false;
222
            }
223
        }
224
        return true;
225
    }
226

    
227
    public boolean intersects(Envelope envelope) {
228
        if (isEmpty){
229
            return false;
230
        }
231
        if((envelope == null) || (envelope.isEmpty())) {
232
            return false;
233
        }
234
        int dimension = getDimension();
235
        for (int i = 0; i < dimension; i++) {
236
            if (getMinimum(i)>envelope.getMaximum(i)){
237
                return false;
238
            } else if (getMaximum(i)<envelope.getMinimum(i)){
239
                return false;
240
            }
241
        }
242
        return true;
243
    }
244

    
245
    public boolean equals(Object other) {
246
        if (!(other == null || other instanceof Envelope)) {
247
            return false;
248
        }
249
        Envelope otherEnv = (Envelope) other;
250
        if (isEmpty && otherEnv.isEmpty()){
251
            return true;
252
        }
253
        if (otherEnv.getDimension() != this.getDimension()) {
254
            return false;
255
        }
256
        for (int i = 0; i < this.getDimension(); i++) {
257
            if (otherEnv.getMinimum(i) != this.getMinimum(i)) {
258
                return false;
259
            }
260
            if (otherEnv.getMaximum(i) != this.getMaximum(i)) {
261
                return false;
262
            }
263
        }
264
        return true;
265
    }
266

    
267
    /* (non-Javadoc)
268
     * @see org.gvsig.fmap.geom.primitive.Envelope#setLowerCorner(org.gvsig.fmap.geom.primitive.Point)
269
     */
270
    public void setLowerCorner(Point lowerCorner) {
271
        this.min = lowerCorner;
272
        if (max != null){
273
            isEmpty = false;
274
        }
275
    }
276

    
277
    /* (non-Javadoc)
278
     * @see org.gvsig.fmap.geom.primitive.Envelope#setUpperCorner(org.gvsig.fmap.geom.primitive.Point)
279
     */
280
    public void setUpperCorner(Point upperCorner) {
281
        this.max = upperCorner;
282
        if (min != null){
283
            isEmpty = false;
284
        }
285
    }
286

    
287
    public static void registerPersistent() {
288
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
289
        if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
290
            DynStruct definition = manager.addDefinition(
291
                DefaultEnvelope.class,
292
                PERSISTENCE_DEFINITION_NAME,
293
                "DefaultEnvelope persistence definition",
294
                null, 
295
                null
296
            ); 
297

    
298
            definition.addDynFieldObject(LOWERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
299
            definition.addDynFieldObject(UPPERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
300
        }
301
    }
302

    
303
    public void loadFromState(PersistentState state)
304
    throws PersistenceException {
305
        setLowerCorner((Point)state.get(LOWERCORNER_FIELD));                
306
        setUpperCorner((Point)state.get(UPPERCORNER_FIELD));                
307
    }
308

    
309
    public void saveToState(PersistentState state) throws PersistenceException {
310
        state.set(LOWERCORNER_FIELD, min);        
311
        state.set(UPPERCORNER_FIELD, max);                
312
    }
313

    
314
    public Object clone() throws CloneNotSupportedException {
315
        DefaultEnvelope other = (DefaultEnvelope) super.clone();
316
        if (!isEmpty){        
317
            other.max = (Point) max.cloneGeometry();
318
            other.min = (Point) min.cloneGeometry();
319
        }
320
        return other;
321
    }
322

    
323
    public boolean isEmpty() {       
324
        return isEmpty;
325
    }        
326
}