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 @ 40435

History | View | Annotate | Download (12.1 KB)

1

    
2
/* gvSIG. Geographic Information System of the Valencian Government
3
 *
4
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
5
 * of the Valencian Government (CIT)
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
 * MA  02110-1301, USA.
21
 *
22
 */
23

    
24
/*
25
 * AUTHORS (In addition to CIT):
26
 * ${year} IVER T.I. S.A.   {{Task}}
27
 */
28

    
29
/* gvSIG. Geographic Information System of the Valencian Government
30
 *
31
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
32
 * of the Valencian Government (CIT)
33
 *
34
 * This program is free software; you can redistribute it and/or
35
 * modify it under the terms of the GNU General Public License
36
 * as published by the Free Software Foundation; either version 2
37
 * of the License, or (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
47
 * MA  02110-1301, USA.
48
 *
49
 */
50
/*
51
 * AUTHORS (In addition to CIT):
52
 * ${year} IVER T.I. S.A.   {{Task}}
53
 */
54
/* gvSIG. Geographic Information System of the Valencian Government
55
 *
56
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
57
 * of the Valencian Government (CIT)
58
 *
59
 * This program is free software; you can redistribute it and/or
60
 * modify it under the terms of the GNU General Public License
61
 * as published by the Free Software Foundation; either version 2
62
 * of the License, or (at your option) any later version.
63
 *
64
 * This program is distributed in the hope that it will be useful,
65
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
66
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
67
 * GNU General Public License for more details.
68
 *
69
 * You should have received a copy of the GNU General Public License
70
 * along with this program; if not, write to the Free Software
71
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
72
 * MA  02110-1301, USA.
73
 *
74
 */
75
/*
76
 * AUTHORS (In addition to CIT):
77
 * ${year} IVER T.I. S.A.   {{Task}}
78
 */
79
package org.gvsig.fmap.geom.primitive.impl;
80

    
81
import java.text.MessageFormat;
82

    
83
import org.slf4j.Logger;
84
import org.slf4j.LoggerFactory;
85

    
86
import org.gvsig.fmap.geom.Geometry;
87
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
88
import org.gvsig.fmap.geom.Geometry.TYPES;
89
import org.gvsig.fmap.geom.GeometryLocator;
90
import org.gvsig.fmap.geom.GeometryManager;
91
import org.gvsig.fmap.geom.exception.CreateGeometryException;
92
import org.gvsig.fmap.geom.primitive.Envelope;
93
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
94
import org.gvsig.fmap.geom.primitive.Point;
95
import org.gvsig.fmap.geom.primitive.Surface;
96
import org.gvsig.tools.ToolsLocator;
97
import org.gvsig.tools.dynobject.DynStruct;
98
import org.gvsig.tools.persistence.PersistenceManager;
99
import org.gvsig.tools.persistence.PersistentState;
100
import org.gvsig.tools.persistence.exception.PersistenceException;
101

    
102

    
103
/**
104
 * A minimum bounding box or rectangle. Regardless of dimension, an Envelope
105
 * can be represented without ambiguity as two direct positions (coordinate
106
 * points). To encode an Envelope, it is sufficient to encode these two
107
 * points. This is consistent with all of the data types in this
108
 * specification, their state is represented by their publicly accessible
109
 * attributes.
110

111
 * @author Vicente Caballero Navarro
112
 */
113
public abstract class DefaultEnvelope implements Envelope, org.gvsig.tools.lang.Cloneable{
114
    private static final Logger LOG =
115
        LoggerFactory.getLogger(DefaultEnvelope.class);
116

    
117
    public static final String PERSISTENCE_DEFINITION_NAME = "Envelope";
118

    
119
    protected static final String LOWERCORNER_FIELD = "lowerCorner";
120
    protected static final String UPPERCORNER_FIELD = "upperCorner";
121

    
122
    protected Point min;
123
    protected Point max;
124

    
125
    protected boolean isEmpty;
126

    
127
    protected static GeometryManager manager = GeometryLocator.getGeometryManager();
128

    
129
    public DefaultEnvelope(){
130
        super();
131
        isEmpty = true;
132
    }
133

    
134
    public DefaultEnvelope(Point min, Point max){
135
        super();
136
        this.min = min;
137
        this.max = max;
138
        isEmpty = false;
139
    }
140

    
141
    public String toString() {
142
        return MessageFormat.format(
143
            "Envelop(min={0},max={1})", 
144
            new Object[] {
145
                min.toString(),
146
                max.toString()
147
            }
148
        );
149
    }
150

    
151
    /**
152
     * Returns the center ordinate along the specified dimension.
153
     *
154
     * @param dimension DOCUMENT ME!
155
     *
156
     * @return DOCUMENT ME!
157
     */
158
    public double getCenter(int dimension) {
159
        if (isEmpty){
160
            throw new EnvelopeNotInitializedException();
161
        }
162
        return (min.getCoordinateAt(dimension) + max.getCoordinateAt(dimension)) * 0.5;
163
    }
164

    
165
    /**
166
     * Returns the envelope length along the specified dimension.
167
     *
168
     * @param dimension
169
     *
170
     * @return
171
     */
172
    public double getLength(int dimension) {
173
        if (isEmpty){
174
            throw new EnvelopeNotInitializedException();
175
        }
176
        if (max.getCoordinateAt(dimension) > min.getCoordinateAt(dimension)) {
177
            return max.getCoordinateAt(dimension) - min.getCoordinateAt(dimension);
178
        }
179

    
180
        return min.getCoordinateAt(dimension) - max.getCoordinateAt(dimension);
181
    }
182

    
183
    /**
184
     * A coordinate position consisting of all the minimal ordinates for each
185
     * dimension for all points within the Envelope.
186
     *
187
     * @return
188
     */
189
    public Point getLowerCorner() {
190
        return min;
191
    }
192

    
193
    /**
194
     * Returns the maximal ordinate along the specified dimension.
195
     *
196
     * @param dimension
197
     *
198
     * @return
199
     */
200
    public double getMaximum(int dimension) {
201
        if (isEmpty){
202
            throw new EnvelopeNotInitializedException();
203
        }
204
        return max.getCoordinateAt(dimension);
205
    }
206

    
207
    /**
208
     * Returns the minimal ordinate along the specified dimension.
209
     *
210
     * @param dimension
211
     *
212
     * @return
213
     */
214
    public double getMinimum(int dimension) {
215
        if (isEmpty){
216
            throw new EnvelopeNotInitializedException();
217
        }
218
        return min.getCoordinateAt(dimension);
219
    }
220

    
221
    /**
222
     * A coordinate position consisting of all the maximal ordinates for each
223
     * dimension for all points within the Envelope.
224
     *
225
     * @return
226
     */
227
    public Point getUpperCorner() {
228
        return max;
229
    }
230

    
231
    public void add(Envelope envelope) {
232
        if (isEmpty){
233
            setLowerCorner((Point)envelope.getLowerCorner().cloneGeometry());
234
            setUpperCorner((Point)envelope.getUpperCorner().cloneGeometry());          
235
        }else{
236
            int maxDimension = Math.min(getDimension(), envelope.getDimension());
237
            int i;
238
            for (i=0;i<maxDimension;i++){
239
                this.min.setCoordinateAt(i,
240
                    Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
241
                this.max.setCoordinateAt(i,
242
                    Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
243
            }
244
        }
245
    }
246

    
247
    public Geometry getGeometry() {
248
        if (isEmpty){
249
            throw new EnvelopeNotInitializedException();
250
        }
251
        try {
252
            Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
253
            surface.addMoveToVertex((Point)min.cloneGeometry());
254
            surface.addVertex(manager.createPoint(getMaximum(0),getMinimum(1), SUBTYPES.GEOM2D));
255
            surface.addVertex((Point)max.cloneGeometry());
256
            surface.addVertex(manager.createPoint(getMinimum(0),getMaximum(1), SUBTYPES.GEOM2D));
257
            surface.closePrimitive();
258
            return surface;
259
        } catch (CreateGeometryException e) {
260
            LOG.error("Error creting the surface", e);
261
        }          
262
        return null;
263
    }
264

    
265
    public boolean contains(Envelope envelope) {
266
        if (isEmpty){
267
            return false;
268
        }
269
        if((envelope == null) || (envelope.isEmpty())) {
270
            return false;
271
        }
272
        for (int i = 0; i < getDimension(); i++) {
273
            if (getMinimum(i) > envelope.getMinimum(i)
274
                || getMaximum(i) < envelope.getMaximum(i)) {
275
                return false;
276
            }
277
        }
278
        return true;
279
    }
280

    
281
    public boolean intersects(Envelope envelope) {
282
        if (isEmpty){
283
            return false;
284
        }
285
        if((envelope == null) || (envelope.isEmpty())) {
286
            return false;
287
        }
288
        int dimension = getDimension();
289
        for (int i = 0; i < dimension; i++) {
290
            if (getMinimum(i)>envelope.getMaximum(i)){
291
                return false;
292
            } else if (getMaximum(i)<envelope.getMinimum(i)){
293
                return false;
294
            }
295
        }
296
        return true;
297
    }
298

    
299
    public boolean equals(Object other) {
300
        if (!(other == null || other instanceof Envelope)) {
301
            return false;
302
        }
303
        Envelope otherEnv = (Envelope) other;
304
        if (isEmpty && otherEnv.isEmpty()){
305
            return true;
306
        }
307
        if (otherEnv.getDimension() != this.getDimension()) {
308
            return false;
309
        }
310
        for (int i = 0; i < this.getDimension(); i++) {
311
            if (otherEnv.getMinimum(i) != this.getMinimum(i)) {
312
                return false;
313
            }
314
            if (otherEnv.getMaximum(i) != this.getMaximum(i)) {
315
                return false;
316
            }
317
        }
318
        return true;
319
    }
320

    
321
    /* (non-Javadoc)
322
     * @see org.gvsig.fmap.geom.primitive.Envelope#setLowerCorner(org.gvsig.fmap.geom.primitive.Point)
323
     */
324
    public void setLowerCorner(Point lowerCorner) {
325
        this.min = lowerCorner;
326
        if (max != null){
327
            isEmpty = false;
328
        }
329
    }
330

    
331
    /* (non-Javadoc)
332
     * @see org.gvsig.fmap.geom.primitive.Envelope#setUpperCorner(org.gvsig.fmap.geom.primitive.Point)
333
     */
334
    public void setUpperCorner(Point upperCorner) {
335
        this.max = upperCorner;
336
        if (min != null){
337
            isEmpty = false;
338
        }
339
    }
340

    
341
    public static void registerPersistent() {
342
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
343
        if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
344
            DynStruct definition = manager.addDefinition(
345
                DefaultEnvelope.class,
346
                PERSISTENCE_DEFINITION_NAME,
347
                "DefaultEnvelope persistence definition",
348
                null, 
349
                null
350
            ); 
351

    
352
            definition.addDynFieldObject(LOWERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
353
            definition.addDynFieldObject(UPPERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
354
        }
355
    }
356

    
357
    public void loadFromState(PersistentState state)
358
    throws PersistenceException {
359
        setLowerCorner((Point)state.get(LOWERCORNER_FIELD));                
360
        setUpperCorner((Point)state.get(UPPERCORNER_FIELD));                
361
    }
362

    
363
    public void saveToState(PersistentState state) throws PersistenceException {
364
        state.set(LOWERCORNER_FIELD, min);        
365
        state.set(UPPERCORNER_FIELD, max);                
366
    }
367

    
368
    public Object clone() throws CloneNotSupportedException {
369
        DefaultEnvelope other = (DefaultEnvelope) super.clone();
370
        if (!isEmpty){        
371
            other.max = (Point) max.cloneGeometry();
372
            other.min = (Point) min.cloneGeometry();
373
        }
374
        return other;
375
    }
376

    
377
    public boolean isEmpty() {       
378
        return isEmpty;
379
    }        
380
}