Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / primitive / DefaultEnvelope.java @ 47351

History | View | Annotate | Download (16.2 KB)

1 42260 fdiaz
/**
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.jts.primitive;
26
27 42464 fdiaz
import java.util.ArrayList;
28 42260 fdiaz
29 42464 fdiaz
import com.vividsolutions.jts.geom.Coordinate;
30 44003 jjdelcerro
import org.cresques.cts.IProjection;
31 42464 fdiaz
32 42260 fdiaz
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34
35
import org.gvsig.fmap.geom.Geometry;
36 42772 dmartinezizquierdo
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
37 42260 fdiaz
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
38
import org.gvsig.fmap.geom.Geometry.TYPES;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.GeometryManager;
41
import org.gvsig.fmap.geom.exception.CreateGeometryException;
42 42464 fdiaz
import org.gvsig.fmap.geom.jts.GeometryJTS;
43
import org.gvsig.fmap.geom.jts.util.ArrayListCoordinateSequence;
44
import org.gvsig.fmap.geom.jts.util.JTSUtils;
45 42260 fdiaz
import org.gvsig.fmap.geom.primitive.Envelope;
46
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
47 44040 jjdelcerro
import org.gvsig.fmap.geom.primitive.Line;
48 42260 fdiaz
import org.gvsig.fmap.geom.primitive.Point;
49 44040 jjdelcerro
import org.gvsig.fmap.geom.primitive.Polygon;
50 42260 fdiaz
import org.gvsig.fmap.geom.primitive.Surface;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.dynobject.DynStruct;
53
import org.gvsig.tools.persistence.PersistenceManager;
54
import org.gvsig.tools.persistence.PersistentState;
55
import org.gvsig.tools.persistence.exception.PersistenceException;
56
57
58
/**
59
 * A minimum bounding box or rectangle. Regardless of dimension, an Envelope
60
 * can be represented without ambiguity as two direct positions (coordinate
61
 * points). To encode an Envelope, it is sufficient to encode these two
62
 * points. This is consistent with all of the data types in this
63
 * specification, their state is represented by their publicly accessible
64
 * attributes.
65

66
 * @author Vicente Caballero Navarro
67
 */
68 44040 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
69 42260 fdiaz
public abstract class DefaultEnvelope implements Envelope, org.gvsig.tools.lang.Cloneable{
70
    private static final Logger LOG =
71
        LoggerFactory.getLogger(DefaultEnvelope.class);
72
73
    public static final String PERSISTENCE_DEFINITION_NAME = "Envelope";
74
75
    protected static final String LOWERCORNER_FIELD = "lowerCorner";
76
    protected static final String UPPERCORNER_FIELD = "upperCorner";
77
78
    protected Point min;
79
    protected Point max;
80
81
    protected boolean isEmpty;
82
83 44003 jjdelcerro
    protected IProjection projection;
84
85 42464 fdiaz
    private com.vividsolutions.jts.geom.Polygon jtsGeom = null;
86
87 42260 fdiaz
    protected static GeometryManager manager = GeometryLocator.getGeometryManager();
88
89
    public DefaultEnvelope(){
90
        super();
91
        isEmpty = true;
92
    }
93
94 45943 fdiaz
    public DefaultEnvelope(IProjection projection){
95
        this();
96
        this.projection = projection;
97
    }
98
99
    public DefaultEnvelope(Point min, Point max, IProjection projection){
100 42260 fdiaz
        super();
101
        this.min = min;
102
        this.max = max;
103
        isEmpty = false;
104 45943 fdiaz
        this.projection = projection;
105 42260 fdiaz
    }
106
107
    public String toString() {
108
        if( this.isEmpty ) {
109 42388 jjdelcerro
            return "POLYGON()";
110 42260 fdiaz
        }
111 42388 jjdelcerro
        // Para el 3D estaria mal ya que probablemente habria que devolber un cubo.
112
        StringBuilder builder = new StringBuilder();
113
        builder.append("POLYGON ((");
114
        builder.append(this.min.getX());
115
        builder.append(" ");
116
        builder.append(this.min.getY());
117
        builder.append(", ");
118
        builder.append(this.min.getX());
119
        builder.append(" ");
120
        builder.append(this.max.getY());
121
        builder.append(", ");
122
        builder.append(this.max.getX());
123
        builder.append(" ");
124
        builder.append(this.max.getY());
125
        builder.append(", ");
126
        builder.append(this.max.getX());
127
        builder.append(" ");
128
        builder.append(this.min.getY());
129
        builder.append(", ");
130
        builder.append(this.min.getX());
131
        builder.append(" ");
132
        builder.append(this.min.getY());
133
        builder.append("))");
134
        return builder.toString();
135 42260 fdiaz
    }
136
137
    /**
138
     * Returns the center ordinate along the specified dimension.
139
     *
140
     * @param dimension DOCUMENT ME!
141
     *
142
     * @return DOCUMENT ME!
143
     */
144
    public double getCenter(int dimension) {
145
        if (isEmpty){
146
            throw new EnvelopeNotInitializedException();
147
        }
148
        return (min.getCoordinateAt(dimension) + max.getCoordinateAt(dimension)) * 0.5;
149
    }
150
151
    /**
152
     * Returns the envelope length along the specified dimension.
153
     *
154
     * @param dimension
155
     *
156
     * @return
157
     */
158
    public double getLength(int dimension) {
159
        if (isEmpty){
160
            throw new EnvelopeNotInitializedException();
161
        }
162
        if (max.getCoordinateAt(dimension) > min.getCoordinateAt(dimension)) {
163
            return max.getCoordinateAt(dimension) - min.getCoordinateAt(dimension);
164
        }
165
166
        return min.getCoordinateAt(dimension) - max.getCoordinateAt(dimension);
167
    }
168
169
    /**
170
     * A coordinate position consisting of all the minimal ordinates for each
171
     * dimension for all points within the Envelope.
172
     *
173
     * @return
174
     */
175
    public Point getLowerCorner() {
176
        return min;
177
    }
178
179
    /**
180
     * Returns the maximal ordinate along the specified dimension.
181
     *
182
     * @param dimension
183
     *
184
     * @return
185
     */
186
    public double getMaximum(int dimension) {
187
        if (isEmpty){
188
            throw new EnvelopeNotInitializedException();
189
        }
190
        return max.getCoordinateAt(dimension);
191
    }
192
193
    /**
194
     * Returns the minimal ordinate along the specified dimension.
195
     *
196
     * @param dimension
197
     *
198
     * @return
199
     */
200
    public double getMinimum(int dimension) {
201
        if (isEmpty){
202
            throw new EnvelopeNotInitializedException();
203
        }
204
        return min.getCoordinateAt(dimension);
205
    }
206
207
    /**
208
     * A coordinate position consisting of all the maximal ordinates for each
209
     * dimension for all points within the Envelope.
210
     *
211
     * @return
212
     */
213
    public Point getUpperCorner() {
214
        return max;
215
    }
216
217
218
219
    public Geometry getGeometry() {
220
        if (isEmpty){
221
            throw new EnvelopeNotInitializedException();
222
        }
223
        try {
224 44040 jjdelcerro
            // point?
225
            if (this.min.getX() == this.max.getX() && this.min.getY() == this.max.getY()) {
226
                Point point = this.min.clone();
227
                point.setProjection(projection);
228
                return point;
229
            }
230
            // vertical or horizontal line?
231
            if (this.min.getX() == this.max.getX() ||
232
                this.min.getY() == this.max.getY()) {
233
                Line line = manager.createLine(SUBTYPES.GEOM2D);
234
                line.addVertex(min.clone());
235
                line.addVertex(max.clone());
236
                line.setProjection(projection);
237
                return line;
238
            }
239
            Polygon polygon = manager.createPolygon(SUBTYPES.GEOM2D);
240
            polygon.addVertex(min.clone());
241
            polygon.addVertex(manager.createPoint(getMaximum(0),getMinimum(1), SUBTYPES.GEOM2D));
242
            polygon.addVertex(max.clone());
243
            polygon.addVertex(manager.createPoint(getMinimum(0),getMaximum(1), SUBTYPES.GEOM2D));
244
            polygon.addVertex(min.clone());
245
            polygon.setProjection(projection);
246
            return polygon;
247
        } catch (Exception e) {
248
            LOG.warn("Error creting the geometry from envelope", e);
249 42271 fdiaz
        }
250 42260 fdiaz
        return null;
251
    }
252
253 46142 jjdelcerro
    @Override
254
    public Geometry getBox2D() {
255
        if (isEmpty){
256
            throw new EnvelopeNotInitializedException();
257
        }
258
        try {
259
            Polygon polygon = manager.createPolygon(SUBTYPES.GEOM2D);
260
            polygon.addVertex(min.clone());
261
            polygon.addVertex(manager.createPoint(getMaximum(0),getMinimum(1), SUBTYPES.GEOM2D));
262
            polygon.addVertex(max.clone());
263
            polygon.addVertex(manager.createPoint(getMinimum(0),getMaximum(1), SUBTYPES.GEOM2D));
264
            polygon.addVertex(min.clone());
265
            polygon.setProjection(projection);
266
            return polygon;
267
        } catch (Exception e) {
268
            LOG.warn("Error creting the geometry from envelope", e);
269
        }
270
        return null;
271
    }
272
273
    @Override
274 42260 fdiaz
    public boolean contains(Envelope envelope) {
275
        if (isEmpty){
276
            return false;
277
        }
278
        if((envelope == null) || (envelope.isEmpty())) {
279
            return false;
280
        }
281
        for (int i = 0; i < getDimension(); i++) {
282
            if (getMinimum(i) > envelope.getMinimum(i)
283
                || getMaximum(i) < envelope.getMaximum(i)) {
284
                return false;
285
            }
286
        }
287
        return true;
288
    }
289
290
    public boolean intersects(Envelope envelope) {
291
        if (isEmpty){
292
            return false;
293
        }
294
        if((envelope == null) || (envelope.isEmpty())) {
295
            return false;
296
        }
297
        int dimension = getDimension();
298
        for (int i = 0; i < dimension; i++) {
299
            if (getMinimum(i)>envelope.getMaximum(i)){
300
                return false;
301
            } else if (getMaximum(i)<envelope.getMinimum(i)){
302
                return false;
303
            }
304
        }
305
        return true;
306
    }
307
308
    public boolean equals(Object other) {
309
        if (!(other == null || other instanceof Envelope)) {
310
            return false;
311
        }
312
        Envelope otherEnv = (Envelope) other;
313
        if (isEmpty && otherEnv.isEmpty()){
314
            return true;
315
        }
316
        if (otherEnv.getDimension() != this.getDimension()) {
317
            return false;
318
        }
319
        for (int i = 0; i < this.getDimension(); i++) {
320
            if (otherEnv.getMinimum(i) != this.getMinimum(i)) {
321
                return false;
322
            }
323
            if (otherEnv.getMaximum(i) != this.getMaximum(i)) {
324
                return false;
325
            }
326
        }
327
        return true;
328
    }
329
330
    /* (non-Javadoc)
331
     * @see org.gvsig.fmap.geom.primitive.Envelope#setLowerCorner(org.gvsig.fmap.geom.primitive.Point)
332
     */
333
    public void setLowerCorner(Point lowerCorner) {
334
        this.min = lowerCorner;
335
        if (max != null){
336
            isEmpty = false;
337
        }
338 44003 jjdelcerro
        this.min.setProjectionIffNull(projection);
339 42464 fdiaz
        jtsGeom = null;
340 42260 fdiaz
    }
341
342
    /* (non-Javadoc)
343
     * @see org.gvsig.fmap.geom.primitive.Envelope#setUpperCorner(org.gvsig.fmap.geom.primitive.Point)
344
     */
345
    public void setUpperCorner(Point upperCorner) {
346
        this.max = upperCorner;
347
        if (min != null){
348
            isEmpty = false;
349
        }
350 44003 jjdelcerro
        this.max.setProjectionIffNull(projection);
351 42464 fdiaz
        jtsGeom = null;
352 42260 fdiaz
    }
353
354
    public static void registerPersistent() {
355
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
356
        if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
357
            DynStruct definition = manager.addDefinition(
358
                DefaultEnvelope.class,
359
                PERSISTENCE_DEFINITION_NAME,
360
                "DefaultEnvelope persistence definition",
361 42271 fdiaz
                null,
362 42260 fdiaz
                null
363 42271 fdiaz
            );
364 42260 fdiaz
365
            definition.addDynFieldObject(LOWERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
366
            definition.addDynFieldObject(UPPERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
367
        }
368
    }
369
370
    public void loadFromState(PersistentState state)
371
    throws PersistenceException {
372 42271 fdiaz
        setLowerCorner((Point)state.get(LOWERCORNER_FIELD));
373
        setUpperCorner((Point)state.get(UPPERCORNER_FIELD));
374 42260 fdiaz
    }
375
376
    public void saveToState(PersistentState state) throws PersistenceException {
377 42271 fdiaz
        state.set(LOWERCORNER_FIELD, min);
378
        state.set(UPPERCORNER_FIELD, max);
379 42260 fdiaz
    }
380
381 47351 fdiaz
    @Override
382 42260 fdiaz
    public Object clone() throws CloneNotSupportedException {
383
        DefaultEnvelope other = (DefaultEnvelope) super.clone();
384 47351 fdiaz
        other.setProjection(this.getProjection());
385 42271 fdiaz
        if (!isEmpty){
386 42260 fdiaz
            other.max = (Point) max.cloneGeometry();
387
            other.min = (Point) min.cloneGeometry();
388
        }
389
        return other;
390
    }
391
392 44281 jjdelcerro
    @Override
393 42271 fdiaz
    public boolean isEmpty() {
394 42260 fdiaz
        return isEmpty;
395 42271 fdiaz
    }
396
397 44281 jjdelcerro
    @Override
398 42260 fdiaz
    public void add(Geometry geometry) {
399 44281 jjdelcerro
        if( geometry==null ) {
400
            return;
401
        }
402 42260 fdiaz
        this.add(geometry.getEnvelope());
403
    }
404
405 44281 jjdelcerro
    @Override
406 42260 fdiaz
    public void clear() {
407
        isEmpty = true;
408
    }
409 42271 fdiaz
410 42464 fdiaz
    /* (non-Javadoc)
411
     * @see org.gvsig.fmap.geom.primitive.Envelope#intersects(org.gvsig.fmap.geom.Geometry)
412
     */
413
    @Override
414
    public boolean intersects(Geometry geometry) {
415
        if(geometry instanceof GeometryJTS){
416
            return getJTS().intersects(((GeometryJTS)geometry).getJTS());
417
        }
418
        return false;
419
    }
420
421
422 42772 dmartinezizquierdo
    /* (non-Javadoc)
423
     * @see org.gvsig.fmap.geom.primitive.Envelope#centerTo(org.gvsig.fmap.geom.primitive.Point)
424
     */
425
    @Override
426
    public void centerTo(Point p) {
427
428
        try {
429
            Point loweCorner = manager.createPoint(p.getX() - this.getLength(DIMENSIONS.X)/2,
430
                p.getY() - this.getLength(DIMENSIONS.Y)/2,
431
                    SUBTYPES.GEOM2D);
432
            Point upperCorner = manager.createPoint(p.getX() + this.getLength(DIMENSIONS.X)/2,
433
                p.getY() + this.getLength(DIMENSIONS.Y)/2,
434
                    SUBTYPES.GEOM2D);
435
436
            this.setLowerCorner(loweCorner);
437
            this.setUpperCorner(upperCorner);
438
        } catch (CreateGeometryException e) {
439
            LOG.error("Error creating corners to center the envelope", e);
440
        }
441
    }
442
443 42464 fdiaz
    private com.vividsolutions.jts.geom.Geometry getJTS() {
444
        if (jtsGeom == null) {
445
            ArrayListCoordinateSequence coordinates = new ArrayListCoordinateSequence(new ArrayList<Coordinate>());
446
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(min.getX(), min.getY()));
447
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(getMaximum(0), getMinimum(1)));
448
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(max.getX(), max.getY()));
449
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(getMinimum(0), getMaximum(1)));
450
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(min.getX(), min.getY()));
451
            jtsGeom = JTSUtils.createJTSPolygon(coordinates);
452
        }
453
        return jtsGeom;
454
    }
455 44003 jjdelcerro
456
    @Override
457
    public IProjection getProjection() {
458
        return this.projection;
459
    }
460
461
    @Override
462
    public void setProjectionIffNull(IProjection projection) {
463
        if (this.projection == null) {
464
            this.projection = projection;
465
        }
466
    }
467
468
    @Override
469
    public void setProjection(IProjection projection) {
470
        this.projection = projection;
471
    }
472 45941 jjdelcerro
473
    @Override
474
    public boolean isCollapsed() {
475
        switch(this.getDimension()) {
476
            case 3:
477
                return this.isCollapsed(Geometry.SUBTYPES.GEOM3D);
478
            default:
479
            case 2:
480
                return this.isCollapsed(Geometry.SUBTYPES.GEOM2D);
481
        }
482
    }
483 44003 jjdelcerro
484 45941 jjdelcerro
    @Override
485
    public boolean isCollapsed(int subtype) {
486
        if( this.isEmpty ) {
487
            return true;
488
        }
489
        switch(subtype) {
490
            case Geometry.SUBTYPES.GEOM3DM:
491
                int m = this.getDimension()-1;
492
                if( this.getLength(m)!=0 ) {
493
                    return false;
494
                }
495
            case Geometry.SUBTYPES.GEOM2DM:
496
            case Geometry.SUBTYPES.GEOM3D:
497
                if( this.getLength(DIMENSIONS.Z)!=0 ) {
498
                    return false;
499
                }
500
            default:
501
            case Geometry.SUBTYPES.GEOM2D:
502
                if( this.getLength(DIMENSIONS.X)!=0 ) {
503
                    return false;
504
                }
505
                if( this.getLength(DIMENSIONS.Y)!=0 ) {
506
                    return false;
507
                }
508
                return true;
509
        }
510
    }
511
512 42260 fdiaz
}