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

History | View | Annotate | Download (13.1 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
/* gvSIG. Geographic Information System of the Valencian Government
26
 *
27
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
28
 * of the Valencian Government (CIT)
29
 *
30
 * This program is free software; you can redistribute it and/or
31
 * modify it under the terms of the GNU General Public License
32
 * as published by the Free Software Foundation; either version 2
33
 * of the License, or (at your option) any later version.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38
 * GNU General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU General Public License
41
 * along with this program; if not, write to the Free Software
42
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
43
 * MA  02110-1301, USA.
44
 *
45
 */
46

    
47
/*
48
 * AUTHORS (In addition to CIT):
49
 * ${year} IVER T.I. S.A.   {{Task}}
50
 */
51

    
52
/* gvSIG. Geographic Information System of the Valencian Government
53
 *
54
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
55
 * of the Valencian Government (CIT)
56
 *
57
 * This program is free software; you can redistribute it and/or
58
 * modify it under the terms of the GNU General Public License
59
 * as published by the Free Software Foundation; either version 2
60
 * of the License, or (at your option) any later version.
61
 *
62
 * This program is distributed in the hope that it will be useful,
63
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
64
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
65
 * GNU General Public License for more details.
66
 *
67
 * You should have received a copy of the GNU General Public License
68
 * along with this program; if not, write to the Free Software
69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
70
 * MA  02110-1301, USA.
71
 *
72
 */
73
/*
74
 * AUTHORS (In addition to CIT):
75
 * ${year} IVER T.I. S.A.   {{Task}}
76
 */
77
/* gvSIG. Geographic Information System of the Valencian Government
78
 *
79
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
80
 * of the Valencian Government (CIT)
81
 *
82
 * This program is free software; you can redistribute it and/or
83
 * modify it under the terms of the GNU General Public License
84
 * as published by the Free Software Foundation; either version 2
85
 * of the License, or (at your option) any later version.
86
 *
87
 * This program is distributed in the hope that it will be useful,
88
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
89
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
90
 * GNU General Public License for more details.
91
 *
92
 * You should have received a copy of the GNU General Public License
93
 * along with this program; if not, write to the Free Software
94
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
95
 * MA  02110-1301, USA.
96
 *
97
 */
98
/*
99
 * AUTHORS (In addition to CIT):
100
 * ${year} IVER T.I. S.A.   {{Task}}
101
 */
102
package org.gvsig.fmap.geom.primitive.impl;
103

    
104
import java.text.MessageFormat;
105

    
106
import org.slf4j.Logger;
107
import org.slf4j.LoggerFactory;
108

    
109
import org.gvsig.fmap.geom.Geometry;
110
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
111
import org.gvsig.fmap.geom.Geometry.TYPES;
112
import org.gvsig.fmap.geom.GeometryLocator;
113
import org.gvsig.fmap.geom.GeometryManager;
114
import org.gvsig.fmap.geom.exception.CreateGeometryException;
115
import org.gvsig.fmap.geom.primitive.Envelope;
116
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
117
import org.gvsig.fmap.geom.primitive.Point;
118
import org.gvsig.fmap.geom.primitive.Surface;
119
import org.gvsig.tools.ToolsLocator;
120
import org.gvsig.tools.dynobject.DynStruct;
121
import org.gvsig.tools.persistence.PersistenceManager;
122
import org.gvsig.tools.persistence.PersistentState;
123
import org.gvsig.tools.persistence.exception.PersistenceException;
124

    
125

    
126
/**
127
 * A minimum bounding box or rectangle. Regardless of dimension, an Envelope
128
 * can be represented without ambiguity as two direct positions (coordinate
129
 * points). To encode an Envelope, it is sufficient to encode these two
130
 * points. This is consistent with all of the data types in this
131
 * specification, their state is represented by their publicly accessible
132
 * attributes.
133

134
 * @author Vicente Caballero Navarro
135
 */
136
public abstract class DefaultEnvelope implements Envelope, org.gvsig.tools.lang.Cloneable{
137
    private static final Logger LOG =
138
        LoggerFactory.getLogger(DefaultEnvelope.class);
139

    
140
    public static final String PERSISTENCE_DEFINITION_NAME = "Envelope";
141

    
142
    protected static final String LOWERCORNER_FIELD = "lowerCorner";
143
    protected static final String UPPERCORNER_FIELD = "upperCorner";
144

    
145
    protected Point min;
146
    protected Point max;
147

    
148
    protected boolean isEmpty;
149

    
150
    protected static GeometryManager manager = GeometryLocator.getGeometryManager();
151

    
152
    public DefaultEnvelope(){
153
        super();
154
        isEmpty = true;
155
    }
156

    
157
    public DefaultEnvelope(Point min, Point max){
158
        super();
159
        this.min = min;
160
        this.max = max;
161
        isEmpty = false;
162
    }
163

    
164
    public String toString() {
165
        return MessageFormat.format(
166
            "Envelop(min={0},max={1})", 
167
            new Object[] {
168
                min.toString(),
169
                max.toString()
170
            }
171
        );
172
    }
173

    
174
    /**
175
     * Returns the center ordinate along the specified dimension.
176
     *
177
     * @param dimension DOCUMENT ME!
178
     *
179
     * @return DOCUMENT ME!
180
     */
181
    public double getCenter(int dimension) {
182
        if (isEmpty){
183
            throw new EnvelopeNotInitializedException();
184
        }
185
        return (min.getCoordinateAt(dimension) + max.getCoordinateAt(dimension)) * 0.5;
186
    }
187

    
188
    /**
189
     * Returns the envelope length along the specified dimension.
190
     *
191
     * @param dimension
192
     *
193
     * @return
194
     */
195
    public double getLength(int dimension) {
196
        if (isEmpty){
197
            throw new EnvelopeNotInitializedException();
198
        }
199
        if (max.getCoordinateAt(dimension) > min.getCoordinateAt(dimension)) {
200
            return max.getCoordinateAt(dimension) - min.getCoordinateAt(dimension);
201
        }
202

    
203
        return min.getCoordinateAt(dimension) - max.getCoordinateAt(dimension);
204
    }
205

    
206
    /**
207
     * A coordinate position consisting of all the minimal ordinates for each
208
     * dimension for all points within the Envelope.
209
     *
210
     * @return
211
     */
212
    public Point getLowerCorner() {
213
        return min;
214
    }
215

    
216
    /**
217
     * Returns the maximal ordinate along the specified dimension.
218
     *
219
     * @param dimension
220
     *
221
     * @return
222
     */
223
    public double getMaximum(int dimension) {
224
        if (isEmpty){
225
            throw new EnvelopeNotInitializedException();
226
        }
227
        return max.getCoordinateAt(dimension);
228
    }
229

    
230
    /**
231
     * Returns the minimal ordinate along the specified dimension.
232
     *
233
     * @param dimension
234
     *
235
     * @return
236
     */
237
    public double getMinimum(int dimension) {
238
        if (isEmpty){
239
            throw new EnvelopeNotInitializedException();
240
        }
241
        return min.getCoordinateAt(dimension);
242
    }
243

    
244
    /**
245
     * A coordinate position consisting of all the maximal ordinates for each
246
     * dimension for all points within the Envelope.
247
     *
248
     * @return
249
     */
250
    public Point getUpperCorner() {
251
        return max;
252
    }
253

    
254
    public void add(Envelope envelope) {
255
        if (isEmpty){
256
            setLowerCorner((Point)envelope.getLowerCorner().cloneGeometry());
257
            setUpperCorner((Point)envelope.getUpperCorner().cloneGeometry());          
258
        }else{
259
            int maxDimension = Math.min(getDimension(), envelope.getDimension());
260
            int i;
261
            for (i=0;i<maxDimension;i++){
262
                this.min.setCoordinateAt(i,
263
                    Math.min(this.min.getCoordinateAt(i), envelope.getMinimum(i)));
264
                this.max.setCoordinateAt(i,
265
                    Math.max(this.max.getCoordinateAt(i), envelope.getMaximum(i)));
266
            }
267
        }
268
    }
269

    
270
    public Geometry getGeometry() {
271
        if (isEmpty){
272
            throw new EnvelopeNotInitializedException();
273
        }
274
        try {
275
            Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
276
            surface.addMoveToVertex((Point)min.cloneGeometry());
277
            surface.addVertex(manager.createPoint(getMaximum(0),getMinimum(1), SUBTYPES.GEOM2D));
278
            surface.addVertex((Point)max.cloneGeometry());
279
            surface.addVertex(manager.createPoint(getMinimum(0),getMaximum(1), SUBTYPES.GEOM2D));
280
            surface.closePrimitive();
281
            return surface;
282
        } catch (CreateGeometryException e) {
283
            LOG.error("Error creting the surface", e);
284
        }          
285
        return null;
286
    }
287

    
288
    public boolean contains(Envelope envelope) {
289
        if (isEmpty){
290
            return false;
291
        }
292
        if((envelope == null) || (envelope.isEmpty())) {
293
            return false;
294
        }
295
        for (int i = 0; i < getDimension(); i++) {
296
            if (getMinimum(i) > envelope.getMinimum(i)
297
                || getMaximum(i) < envelope.getMaximum(i)) {
298
                return false;
299
            }
300
        }
301
        return true;
302
    }
303

    
304
    public boolean intersects(Envelope envelope) {
305
        if (isEmpty){
306
            return false;
307
        }
308
        if((envelope == null) || (envelope.isEmpty())) {
309
            return false;
310
        }
311
        int dimension = getDimension();
312
        for (int i = 0; i < dimension; i++) {
313
            if (getMinimum(i)>envelope.getMaximum(i)){
314
                return false;
315
            } else if (getMaximum(i)<envelope.getMinimum(i)){
316
                return false;
317
            }
318
        }
319
        return true;
320
    }
321

    
322
    public boolean equals(Object other) {
323
        if (!(other == null || other instanceof Envelope)) {
324
            return false;
325
        }
326
        Envelope otherEnv = (Envelope) other;
327
        if (isEmpty && otherEnv.isEmpty()){
328
            return true;
329
        }
330
        if (otherEnv.getDimension() != this.getDimension()) {
331
            return false;
332
        }
333
        for (int i = 0; i < this.getDimension(); i++) {
334
            if (otherEnv.getMinimum(i) != this.getMinimum(i)) {
335
                return false;
336
            }
337
            if (otherEnv.getMaximum(i) != this.getMaximum(i)) {
338
                return false;
339
            }
340
        }
341
        return true;
342
    }
343

    
344
    /* (non-Javadoc)
345
     * @see org.gvsig.fmap.geom.primitive.Envelope#setLowerCorner(org.gvsig.fmap.geom.primitive.Point)
346
     */
347
    public void setLowerCorner(Point lowerCorner) {
348
        this.min = lowerCorner;
349
        if (max != null){
350
            isEmpty = false;
351
        }
352
    }
353

    
354
    /* (non-Javadoc)
355
     * @see org.gvsig.fmap.geom.primitive.Envelope#setUpperCorner(org.gvsig.fmap.geom.primitive.Point)
356
     */
357
    public void setUpperCorner(Point upperCorner) {
358
        this.max = upperCorner;
359
        if (min != null){
360
            isEmpty = false;
361
        }
362
    }
363

    
364
    public static void registerPersistent() {
365
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
366
        if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
367
            DynStruct definition = manager.addDefinition(
368
                DefaultEnvelope.class,
369
                PERSISTENCE_DEFINITION_NAME,
370
                "DefaultEnvelope persistence definition",
371
                null, 
372
                null
373
            ); 
374

    
375
            definition.addDynFieldObject(LOWERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
376
            definition.addDynFieldObject(UPPERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
377
        }
378
    }
379

    
380
    public void loadFromState(PersistentState state)
381
    throws PersistenceException {
382
        setLowerCorner((Point)state.get(LOWERCORNER_FIELD));                
383
        setUpperCorner((Point)state.get(UPPERCORNER_FIELD));                
384
    }
385

    
386
    public void saveToState(PersistentState state) throws PersistenceException {
387
        state.set(LOWERCORNER_FIELD, min);        
388
        state.set(UPPERCORNER_FIELD, max);                
389
    }
390

    
391
    public Object clone() throws CloneNotSupportedException {
392
        DefaultEnvelope other = (DefaultEnvelope) super.clone();
393
        if (!isEmpty){        
394
            other.max = (Point) max.cloneGeometry();
395
            other.min = (Point) min.cloneGeometry();
396
        }
397
        return other;
398
    }
399

    
400
    public boolean isEmpty() {       
401
        return isEmpty;
402
    }        
403
}