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

History | View | Annotate | Download (11.9 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.jts.primitive;
26

    
27
import java.util.ArrayList;
28

    
29
import com.vividsolutions.jts.geom.Coordinate;
30

    
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
36
import org.gvsig.fmap.geom.Geometry.TYPES;
37
import org.gvsig.fmap.geom.GeometryLocator;
38
import org.gvsig.fmap.geom.GeometryManager;
39
import org.gvsig.fmap.geom.exception.CreateGeometryException;
40
import org.gvsig.fmap.geom.jts.GeometryJTS;
41
import org.gvsig.fmap.geom.jts.util.ArrayListCoordinateSequence;
42
import org.gvsig.fmap.geom.jts.util.JTSUtils;
43
import org.gvsig.fmap.geom.primitive.Envelope;
44
import org.gvsig.fmap.geom.primitive.EnvelopeNotInitializedException;
45
import org.gvsig.fmap.geom.primitive.Point;
46
import org.gvsig.fmap.geom.primitive.Surface;
47
import org.gvsig.tools.ToolsLocator;
48
import org.gvsig.tools.dynobject.DynStruct;
49
import org.gvsig.tools.persistence.PersistenceManager;
50
import org.gvsig.tools.persistence.PersistentState;
51
import org.gvsig.tools.persistence.exception.PersistenceException;
52

    
53

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

62
 * @author Vicente Caballero Navarro
63
 */
64
public abstract class DefaultEnvelope implements Envelope, org.gvsig.tools.lang.Cloneable{
65
    private static final Logger LOG =
66
        LoggerFactory.getLogger(DefaultEnvelope.class);
67

    
68
    public static final String PERSISTENCE_DEFINITION_NAME = "Envelope";
69

    
70
    protected static final String LOWERCORNER_FIELD = "lowerCorner";
71
    protected static final String UPPERCORNER_FIELD = "upperCorner";
72

    
73
    protected Point min;
74
    protected Point max;
75

    
76
    protected boolean isEmpty;
77

    
78
    private com.vividsolutions.jts.geom.Polygon jtsGeom = null;
79

    
80
    protected static GeometryManager manager = GeometryLocator.getGeometryManager();
81

    
82
    public DefaultEnvelope(){
83
        super();
84
        isEmpty = true;
85
    }
86

    
87
    public DefaultEnvelope(Point min, Point max){
88
        super();
89
        this.min = min;
90
        this.max = max;
91
        isEmpty = false;
92
    }
93

    
94
    public String toString() {
95
        if( this.isEmpty ) {
96
            return "POLYGON()";
97
        }
98
        // Para el 3D estaria mal ya que probablemente habria que devolber un cubo.
99
        StringBuilder builder = new StringBuilder();
100
        builder.append("POLYGON ((");
101
        builder.append(this.min.getX());
102
        builder.append(" ");
103
        builder.append(this.min.getY());
104
        builder.append(", ");
105
        builder.append(this.min.getX());
106
        builder.append(" ");
107
        builder.append(this.max.getY());
108
        builder.append(", ");
109
        builder.append(this.max.getX());
110
        builder.append(" ");
111
        builder.append(this.max.getY());
112
        builder.append(", ");
113
        builder.append(this.max.getX());
114
        builder.append(" ");
115
        builder.append(this.min.getY());
116
        builder.append(", ");
117
        builder.append(this.min.getX());
118
        builder.append(" ");
119
        builder.append(this.min.getY());
120
        builder.append("))");
121
        return builder.toString();
122
    }
123

    
124
    /**
125
     * Returns the center ordinate along the specified dimension.
126
     *
127
     * @param dimension DOCUMENT ME!
128
     *
129
     * @return DOCUMENT ME!
130
     */
131
    public double getCenter(int dimension) {
132
        if (isEmpty){
133
            throw new EnvelopeNotInitializedException();
134
        }
135
        return (min.getCoordinateAt(dimension) + max.getCoordinateAt(dimension)) * 0.5;
136
    }
137

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

    
153
        return min.getCoordinateAt(dimension) - max.getCoordinateAt(dimension);
154
    }
155

    
156
    /**
157
     * A coordinate position consisting of all the minimal ordinates for each
158
     * dimension for all points within the Envelope.
159
     *
160
     * @return
161
     */
162
    public Point getLowerCorner() {
163
        return min;
164
    }
165

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

    
180
    /**
181
     * Returns the minimal ordinate along the specified dimension.
182
     *
183
     * @param dimension
184
     *
185
     * @return
186
     */
187
    public double getMinimum(int dimension) {
188
        if (isEmpty){
189
            throw new EnvelopeNotInitializedException();
190
        }
191
        return min.getCoordinateAt(dimension);
192
    }
193

    
194
    /**
195
     * A coordinate position consisting of all the maximal ordinates for each
196
     * dimension for all points within the Envelope.
197
     *
198
     * @return
199
     */
200
    public Point getUpperCorner() {
201
        return max;
202
    }
203

    
204

    
205

    
206
    public Geometry getGeometry() {
207
        if (isEmpty){
208
            throw new EnvelopeNotInitializedException();
209
        }
210
        try {
211
            Surface surface = (Surface)manager.create(TYPES.SURFACE, SUBTYPES.GEOM2D);
212
            surface.addVertex((Point)min.cloneGeometry());
213
            surface.addVertex(manager.createPoint(getMaximum(0),getMinimum(1), SUBTYPES.GEOM2D));
214
            surface.addVertex((Point)max.cloneGeometry());
215
            surface.addVertex(manager.createPoint(getMinimum(0),getMaximum(1), SUBTYPES.GEOM2D));
216
            surface.addVertex((Point)min.cloneGeometry());
217
            return surface;
218
        } catch (CreateGeometryException e) {
219
            LOG.error("Error creting the surface", e);
220
        }
221
        return null;
222
    }
223

    
224
    public boolean contains(Envelope envelope) {
225
        if (isEmpty){
226
            return false;
227
        }
228
        if((envelope == null) || (envelope.isEmpty())) {
229
            return false;
230
        }
231
        for (int i = 0; i < getDimension(); i++) {
232
            if (getMinimum(i) > envelope.getMinimum(i)
233
                || getMaximum(i) < envelope.getMaximum(i)) {
234
                return false;
235
            }
236
        }
237
        return true;
238
    }
239

    
240
    public boolean intersects(Envelope envelope) {
241
        if (isEmpty){
242
            return false;
243
        }
244
        if((envelope == null) || (envelope.isEmpty())) {
245
            return false;
246
        }
247
        int dimension = getDimension();
248
        for (int i = 0; i < dimension; i++) {
249
            if (getMinimum(i)>envelope.getMaximum(i)){
250
                return false;
251
            } else if (getMaximum(i)<envelope.getMinimum(i)){
252
                return false;
253
            }
254
        }
255
        return true;
256
    }
257

    
258
    public boolean equals(Object other) {
259
        if (!(other == null || other instanceof Envelope)) {
260
            return false;
261
        }
262
        Envelope otherEnv = (Envelope) other;
263
        if (isEmpty && otherEnv.isEmpty()){
264
            return true;
265
        }
266
        if (otherEnv.getDimension() != this.getDimension()) {
267
            return false;
268
        }
269
        for (int i = 0; i < this.getDimension(); i++) {
270
            if (otherEnv.getMinimum(i) != this.getMinimum(i)) {
271
                return false;
272
            }
273
            if (otherEnv.getMaximum(i) != this.getMaximum(i)) {
274
                return false;
275
            }
276
        }
277
        return true;
278
    }
279

    
280
    /* (non-Javadoc)
281
     * @see org.gvsig.fmap.geom.primitive.Envelope#setLowerCorner(org.gvsig.fmap.geom.primitive.Point)
282
     */
283
    public void setLowerCorner(Point lowerCorner) {
284
        this.min = lowerCorner;
285
        if (max != null){
286
            isEmpty = false;
287
        }
288
        jtsGeom = null;
289
    }
290

    
291
    /* (non-Javadoc)
292
     * @see org.gvsig.fmap.geom.primitive.Envelope#setUpperCorner(org.gvsig.fmap.geom.primitive.Point)
293
     */
294
    public void setUpperCorner(Point upperCorner) {
295
        this.max = upperCorner;
296
        if (min != null){
297
            isEmpty = false;
298
        }
299
        jtsGeom = null;
300
    }
301

    
302
    public static void registerPersistent() {
303
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
304
        if( manager.getDefinition(PERSISTENCE_DEFINITION_NAME)==null ) {
305
            DynStruct definition = manager.addDefinition(
306
                DefaultEnvelope.class,
307
                PERSISTENCE_DEFINITION_NAME,
308
                "DefaultEnvelope persistence definition",
309
                null,
310
                null
311
            );
312

    
313
            definition.addDynFieldObject(LOWERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
314
            definition.addDynFieldObject(UPPERCORNER_FIELD).setClassOfValue(Point.class).setMandatory(true);
315
        }
316
    }
317

    
318
    public void loadFromState(PersistentState state)
319
    throws PersistenceException {
320
        setLowerCorner((Point)state.get(LOWERCORNER_FIELD));
321
        setUpperCorner((Point)state.get(UPPERCORNER_FIELD));
322
    }
323

    
324
    public void saveToState(PersistentState state) throws PersistenceException {
325
        state.set(LOWERCORNER_FIELD, min);
326
        state.set(UPPERCORNER_FIELD, max);
327
    }
328

    
329
    public Object clone() throws CloneNotSupportedException {
330
        DefaultEnvelope other = (DefaultEnvelope) super.clone();
331
        if (!isEmpty){
332
            other.max = (Point) max.cloneGeometry();
333
            other.min = (Point) min.cloneGeometry();
334
        }
335
        return other;
336
    }
337

    
338
    public boolean isEmpty() {
339
        return isEmpty;
340
    }
341

    
342
    public void add(Geometry geometry) {
343
        this.add(geometry.getEnvelope());
344
    }
345

    
346
    public void clear() {
347
        isEmpty = true;
348
    }
349

    
350
    /* (non-Javadoc)
351
     * @see org.gvsig.fmap.geom.primitive.Envelope#intersects(org.gvsig.fmap.geom.Geometry)
352
     */
353
    @Override
354
    public boolean intersects(Geometry geometry) {
355
        if(geometry instanceof GeometryJTS){
356
            return getJTS().intersects(((GeometryJTS)geometry).getJTS());
357
        }
358
        return false;
359
    }
360

    
361

    
362
    private com.vividsolutions.jts.geom.Geometry getJTS() {
363
        if (jtsGeom == null) {
364
            ArrayListCoordinateSequence coordinates = new ArrayListCoordinateSequence(new ArrayList<Coordinate>());
365
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(min.getX(), min.getY()));
366
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(getMaximum(0), getMinimum(1)));
367
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(max.getX(), max.getY()));
368
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(getMinimum(0), getMaximum(1)));
369
            coordinates.add(new com.vividsolutions.jts.geom.Coordinate(min.getX(), min.getY()));
370
            jtsGeom = JTSUtils.createJTSPolygon(coordinates);
371
        }
372
        return jtsGeom;
373
    }
374
}