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 / AbstractGeometry.java @ 47648

History | View | Annotate | Download (35.6 KB)

1 42260 fdiaz
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.geom.jts;
24
25
import com.vividsolutions.jts.algorithm.CGAlgorithms;
26
import com.vividsolutions.jts.geom.Coordinate;
27 46006 jjdelcerro
import com.vividsolutions.jts.io.geojson.GeoJsonWriter;
28 45748 fdiaz
import com.vividsolutions.jts.operation.buffer.BufferParameters;
29 42260 fdiaz
import com.vividsolutions.jts.operation.distance.DistanceOp;
30
import com.vividsolutions.jts.operation.overlay.snap.GeometrySnapper;
31
import com.vividsolutions.jts.operation.valid.IsValidOp;
32
import com.vividsolutions.jts.operation.valid.TopologyValidationError;
33 45748 fdiaz
import java.awt.Rectangle;
34
import java.awt.Shape;
35
import java.awt.geom.AffineTransform;
36
import java.awt.geom.Rectangle2D;
37 45425 jjdelcerro
import org.apache.commons.codec.binary.Hex;
38
import org.apache.commons.lang3.StringUtils;
39 43785 jjdelcerro
import org.cresques.cts.IProjection;
40 44352 jjdelcerro
import org.gvsig.fmap.crs.CRSFactory;
41 42260 fdiaz
import org.gvsig.fmap.geom.Geometry;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.GeometryManager;
44 45939 fdiaz
import org.gvsig.fmap.geom.aggregate.Aggregate;
45 47364 fdiaz
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
46 45939 fdiaz
import org.gvsig.fmap.geom.complex.Complex;
47 42260 fdiaz
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48 42771 jbadia
import org.gvsig.fmap.geom.jts.operation.towkb.OGCWKBEncoder;
49
import org.gvsig.fmap.geom.jts.operation.towkb.PostGISEWKBEncoder;
50 42875 fdiaz
import org.gvsig.fmap.geom.jts.operation.towkt.EWKTWriter;
51 42260 fdiaz
import org.gvsig.fmap.geom.jts.primitive.Envelope2D;
52
import org.gvsig.fmap.geom.jts.primitive.Envelope3D;
53
import org.gvsig.fmap.geom.jts.primitive.point.Point3D;
54 43909 jjdelcerro
import org.gvsig.fmap.geom.jts.util.GMLUtils;
55 42267 fdiaz
import org.gvsig.fmap.geom.jts.util.JTSUtils;
56 42260 fdiaz
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
57
import org.gvsig.fmap.geom.operation.GeometryOperationException;
58
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
59 47605 fdiaz
import org.gvsig.fmap.geom.primitive.Curve;
60 42260 fdiaz
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.fmap.geom.primitive.OrientableCurve;
62 47605 fdiaz
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
63 42260 fdiaz
import org.gvsig.fmap.geom.primitive.OrientableSurface;
64
import org.gvsig.fmap.geom.primitive.Point;
65
import org.gvsig.fmap.geom.type.GeometryType;
66 47605 fdiaz
import org.gvsig.tools.util.IsEmpty;
67 45748 fdiaz
import org.slf4j.Logger;
68
import org.slf4j.LoggerFactory;
69 42260 fdiaz
70
/**
71 45425 jjdelcerro
 * @author gvSIG Team
72 42260 fdiaz
 *
73
 */
74 45425 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
75 42260 fdiaz
public abstract class AbstractGeometry implements GeometryJTS {
76
77 45425 jjdelcerro
    protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractGeometry.class);
78 42260 fdiaz
79
    /**
80
     *
81
     */
82
    private static final long serialVersionUID = 4999326772576222293L;
83
84 45673 jjdelcerro
    private GeometryType geometryType;
85 42260 fdiaz
86 43785 jjdelcerro
    private IProjection projection;
87 43908 jjdelcerro
88 42260 fdiaz
    /**
89
     *
90 45748 fdiaz
     * @param type
91
     * @param subtype
92 42260 fdiaz
     */
93
    public AbstractGeometry(int type, int subtype) {
94
        try {
95
            this.geometryType = GeometryLocator.getGeometryManager().getGeometryType(type, subtype);
96
        } catch (Exception e) {
97
            // TODO: Ver de crear una excepcion para esto o si hay alguna en el API.
98
            throw new RuntimeException(e);
99
        }
100
    }
101 45673 jjdelcerro
102
    public void setGeometryType(GeometryType geometryType) {
103
        this.geometryType = geometryType;
104
    }
105 42260 fdiaz
106 45748 fdiaz
    @Override
107 43908 jjdelcerro
    public GeometryType getGeometryType() {
108 42260 fdiaz
        return geometryType;
109
    }
110
111
    protected GeometryManager getManager() {
112
        return GeometryLocator.getGeometryManager();
113
    }
114
115
    /*
116
     * (non-Javadoc)
117
     *
118
     * @see org.gvsig.fmap.geom.Geometry#contains(org.gvsig.fmap.geom.Geometry)
119
     */
120 45748 fdiaz
    @Override
121 42260 fdiaz
    public boolean contains(Geometry geometry) throws GeometryOperationNotSupportedException,
122 43908 jjdelcerro
            GeometryOperationException {
123 42260 fdiaz
        if (!(geometry instanceof GeometryJTS)) {
124
            return false;
125
        }
126 46671 fdiaz
        com.vividsolutions.jts.geom.Geometry theJTS = this.getJTS();
127
        if(this instanceof Aggregate){
128
            theJTS = theJTS.union();
129
        }
130
131
        com.vividsolutions.jts.geom.Geometry otherJTS = ((GeometryJTS)geometry).getJTS();
132
        if(geometry instanceof Aggregate){
133
            otherJTS = otherJTS.union();
134
        }
135
        return theJTS.contains(otherJTS);
136 42260 fdiaz
    }
137
138
    /*
139
     * (non-Javadoc)
140
     *
141
     * @see java.lang.Comparable#compareTo(java.lang.Object)
142
     */
143 45748 fdiaz
    @Override
144 42260 fdiaz
    public int compareTo(Object o) {
145
        return getJTS().compareTo(((GeometryJTS) o).getJTS());
146
    }
147
148
    /*
149
     * (non-Javadoc)
150
     *
151
     * @see java.awt.Shape#contains(double, double)
152
     */
153 45748 fdiaz
    @Override
154 42260 fdiaz
    public boolean contains(double x, double y) {
155
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
156
        Shape shp = getShape();
157
        return shp.contains(x, y);
158
    }
159
160
    /*
161
     * (non-Javadoc)
162
     *
163
     * @see java.awt.Shape#intersects(double, double, double, double)
164
     */
165 45748 fdiaz
    @Override
166 42260 fdiaz
    public boolean intersects(double x, double y, double w, double h) {
167
168
        notifyDeprecated("Calling deprecated method of geometry intersects from shape interface");
169
        Shape shp = this.getShape();
170
        return shp.intersects(x, y, w, h);
171
    }
172
173
    /*
174
     * (non-Javadoc)
175
     *
176
     * @see java.awt.Shape#contains(double, double, double, double)
177
     */
178 45748 fdiaz
    @Override
179 42260 fdiaz
    public boolean contains(double x, double y, double w, double h) {
180
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
181
        Shape shp = this.getShape();
182
        return shp.contains(x, y, w, h);
183
    }
184
185
    /*
186
     * (non-Javadoc)
187
     *
188
     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
189
     */
190 45748 fdiaz
    @Override
191 42260 fdiaz
    public boolean contains(java.awt.geom.Point2D p) {
192
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
193
        Shape shp = this.getShape();
194
        return shp.contains(p);
195
    }
196
197
    /*
198
     * (non-Javadoc)
199
     *
200
     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
201
     */
202 45748 fdiaz
    @Override
203 42260 fdiaz
    public boolean contains(Rectangle2D r) {
204
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
205
        Shape shp = this.getShape();
206
        return shp.contains(r);
207
    }
208
209
    /*
210
     * (non-Javadoc)
211
     *
212
     * @see org.gvsig.fmap.geom.Geometry#distance(org.gvsig.fmap.geom.Geometry)
213
     */
214 45748 fdiaz
    @Override
215 42260 fdiaz
    public double distance(org.gvsig.fmap.geom.Geometry other) throws GeometryOperationNotSupportedException,
216 43908 jjdelcerro
            GeometryOperationException {
217 42260 fdiaz
        return getJTS().distance(((GeometryJTS) other).getJTS());
218
    }
219
220
    /*
221
     * (non-Javadoc)
222
     *
223
     * @see
224
     * org.gvsig.fmap.geom.Geometry#isWithinDistance(org.gvsig.fmap.geom.Geometry
225
     * , double)
226
     */
227 45748 fdiaz
    @Override
228 42260 fdiaz
    public boolean isWithinDistance(org.gvsig.fmap.geom.Geometry other, double distance)
229 43908 jjdelcerro
            throws GeometryOperationNotSupportedException, GeometryOperationException {
230 42260 fdiaz
        return com.vividsolutions.jts.operation.distance.DistanceOp.isWithinDistance(this.getJTS(),
231 43908 jjdelcerro
                ((GeometryJTS) other).getJTS(), distance);
232 42260 fdiaz
    }
233
234
    /*
235
     * (non-Javadoc)
236
     *
237
     * @see org.gvsig.fmap.geom.Geometry#overlaps(org.gvsig.fmap.geom.Geometry)
238
     */
239 45748 fdiaz
    @Override
240 42260 fdiaz
    public boolean overlaps(org.gvsig.fmap.geom.Geometry geometry) throws GeometryOperationNotSupportedException,
241 43908 jjdelcerro
            GeometryOperationException {
242 42260 fdiaz
        // TODO: this method can be implemented throw invokeOperation
243
        return getJTS().overlaps(((GeometryJTS) geometry).getJTS());
244
    }
245
246 45748 fdiaz
    @Override
247 42260 fdiaz
    public boolean coveredBy(Geometry geometry) throws GeometryOperationNotSupportedException,
248 43908 jjdelcerro
            GeometryOperationException {
249 42260 fdiaz
250
        return getJTS().coveredBy(((GeometryJTS) geometry).getJTS());
251
    }
252
253 45748 fdiaz
    @Override
254 42260 fdiaz
    public boolean covers(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
255
        // TODO: this method can be implemented throw invokeOperation
256
        return getJTS().covers(((GeometryJTS) geometry).getJTS());
257
258
    }
259
260 45748 fdiaz
    @Override
261 42260 fdiaz
    public boolean crosses(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
262
        // TODO: this method can be implemented throw invokeOperation
263
        return getJTS().crosses(((GeometryJTS) geometry).getJTS());
264
    }
265
266 45748 fdiaz
    @Override
267 42260 fdiaz
    public boolean intersects(Geometry geometry) throws GeometryOperationNotSupportedException,
268 43908 jjdelcerro
            GeometryOperationException {
269 42260 fdiaz
        return getJTS().intersects(((GeometryJTS) geometry).getJTS());
270
    }
271
272 45748 fdiaz
    @Override
273 42260 fdiaz
    public boolean touches(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
274
        // TODO: this method can be implemented throw invokeOperation
275
        return getJTS().touches(((GeometryJTS) geometry).getJTS());
276
    }
277
278 45748 fdiaz
    @Override
279 42260 fdiaz
    public boolean disjoint(Geometry geometry) throws GeometryOperationNotSupportedException,
280 43908 jjdelcerro
            GeometryOperationException {
281 42260 fdiaz
        // TODO: this method can be implemented throw invokeOperation
282
        return getJTS().disjoint(((GeometryJTS) geometry).getJTS());
283
    }
284
285 45748 fdiaz
    @Override
286 42260 fdiaz
    public boolean within(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
287
        // TODO: this method can be implemented throw invokeOperation
288
        return getJTS().within(((GeometryJTS) geometry).getJTS());
289
    }
290
291 45748 fdiaz
    @Override
292 42260 fdiaz
    public double area() throws GeometryOperationNotSupportedException, GeometryOperationException {
293
        return getJTS().getArea();
294
    }
295
296 45748 fdiaz
    @Override
297 42260 fdiaz
    public double perimeter() throws GeometryOperationNotSupportedException, GeometryOperationException {
298
        return getJTS().getLength();
299
    }
300
301
    /*
302
     * (non-Javadoc)
303
     *
304
     * @see org.gvsig.fmap.geom.Geometry#intersects(java.awt.geom.Rectangle2D)
305
     */
306 45748 fdiaz
    @Override
307 42260 fdiaz
    public boolean intersects(Rectangle2D r) {
308
        double x = r.getMinX();
309
        double y = r.getMinY();
310
        double w = r.getWidth();
311
        double h = r.getHeight();
312
313
        return fastIntersects(x, y, w, h);
314
    }
315
316
    /*
317
     * (non-Javadoc)
318
     *
319
     * @see org.gvsig.fmap.geom.Geometry#fastIntersects(double, double, double,
320
     * double)
321
     */
322 45748 fdiaz
    @Override
323 42260 fdiaz
    public boolean fastIntersects(double x, double y, double w, double h) {
324 45748 fdiaz
        com.vividsolutions.jts.geom.Geometry rect;
325 42260 fdiaz
        com.vividsolutions.jts.geom.Coordinate[] coord = new com.vividsolutions.jts.geom.Coordinate[5];
326
        coord[0] = new com.vividsolutions.jts.geom.Coordinate(x, y);
327
        coord[1] = new com.vividsolutions.jts.geom.Coordinate(x + w, y);
328
        coord[2] = new com.vividsolutions.jts.geom.Coordinate(x + w, y + w);
329
        coord[3] = new com.vividsolutions.jts.geom.Coordinate(x, y + w);
330
        coord[4] = new com.vividsolutions.jts.geom.Coordinate(x, y);
331 42334 dmartinezizquierdo
        rect = JTSUtils.createJTSPolygon(coord);
332 42260 fdiaz
333
        return getJTS().intersects(rect);
334
    }
335
336
    /*
337
     * (non-Javadoc)
338
     *
339
     * @see org.gvsig.fmap.geom.Geometry#getEnvelope()
340
     */
341 45748 fdiaz
    @Override
342 42260 fdiaz
    public Envelope getEnvelope() {
343
        if (is3D()) {
344 47605 fdiaz
            if(this.isEmpty()){
345
                return new Envelope3D(getProjection());
346
            }
347 42260 fdiaz
            Coordinate[] coordinates = getJTS().getCoordinates();
348
349
            double minx = Double.POSITIVE_INFINITY;
350
            double miny = Double.POSITIVE_INFINITY;
351
            double minz = Double.POSITIVE_INFINITY;
352
353
            double maxx = Double.NEGATIVE_INFINITY;
354
            double maxy = Double.NEGATIVE_INFINITY;
355
            double maxz = Double.NEGATIVE_INFINITY;
356
357
            double x;
358
            double y;
359
            double z;
360
361 45748 fdiaz
            for (Coordinate coordinate : coordinates) {
362
                x = coordinate.x;
363
                y = coordinate.y;
364
                z = coordinate.z;
365 42260 fdiaz
                minx = Math.min(x, minx);
366 42475 fdiaz
                miny = Math.min(y, miny);
367
                minz = Math.min(z, minz);
368 42260 fdiaz
                maxx = Math.max(x, maxx);
369 42475 fdiaz
                maxy = Math.max(y, maxy);
370
                maxz = Math.max(z, maxz);
371 42260 fdiaz
            }
372
373 47605 fdiaz
            if (minx <= maxx && miny <= maxy && (minz <= maxz || (Double.isNaN(minz) && Double.isNaN(maxz)) ) ) {
374 42260 fdiaz
                Point min = new Point3D(minx, miny, minz);
375
                Point max = new Point3D(maxx, maxy, maxz);
376 45943 fdiaz
                return new Envelope3D(min, max, this.getProjection());
377 42260 fdiaz
            }
378 45943 fdiaz
            return new Envelope3D(this.getProjection());
379 42260 fdiaz
        } else {
380 47605 fdiaz
            if(this.isEmpty()){
381
                return new Envelope2D(getProjection());
382
            }
383 42260 fdiaz
            com.vividsolutions.jts.geom.Envelope envelope = getJTS().getEnvelopeInternal();
384 45943 fdiaz
            return new Envelope2D(envelope, this.getProjection());
385 42260 fdiaz
        }
386
    }
387
388
    /*
389
     * (non-Javadoc)
390
     *
391
     * @see org.gvsig.fmap.geom.Geometry#isSimple()
392
     */
393 45748 fdiaz
    @Override
394 42260 fdiaz
    public boolean isSimple() {
395
        return this.getJTS().isSimple();
396
    }
397
398
    /*
399
     * (non-Javadoc)
400
     *
401
     * @see org.gvsig.fmap.geom.Geometry#isCCW()
402
     */
403 45748 fdiaz
    @Override
404 42260 fdiaz
    public boolean isCCW() throws GeometryOperationNotSupportedException, GeometryOperationException {
405
        return CGAlgorithms.isCCW(this.getJTS().getCoordinates());
406
    }
407
408
    /*
409
     * (non-Javadoc)
410
     *
411
     * @see org.gvsig.fmap.geom.Geometry#invokeOperation(int,
412
     * org.gvsig.fmap.geom.operation.GeometryOperationContext)
413
     */
414 45748 fdiaz
    @Override
415 42260 fdiaz
    public Object invokeOperation(int index, GeometryOperationContext ctx)
416 43908 jjdelcerro
            throws GeometryOperationNotSupportedException, GeometryOperationException {
417 42260 fdiaz
        return getManager().invokeOperation(index, this, ctx);
418
419
    }
420
421
    /*
422
     * (non-Javadoc)
423
     *
424
     * @see org.gvsig.fmap.geom.Geometry#invokeOperation(java.lang.String,
425
     * org.gvsig.fmap.geom.operation.GeometryOperationContext)
426
     */
427 45748 fdiaz
    @Override
428 42260 fdiaz
    public Object invokeOperation(String opName, GeometryOperationContext ctx)
429 43908 jjdelcerro
            throws GeometryOperationNotSupportedException, GeometryOperationException {
430 42260 fdiaz
        return getManager().invokeOperation(opName, this, ctx);
431
432
    }
433
434
    /*
435
     * (non-Javadoc)
436
     *
437
     * @see org.gvsig.fmap.geom.Geometry#getType()
438
     */
439 45748 fdiaz
    @Override
440 42260 fdiaz
    public int getType() {
441
        return this.getGeometryType().getType();
442
    }
443
444 43909 jjdelcerro
    @Override
445
    public Object convertTo(String format) throws GeometryOperationNotSupportedException, GeometryOperationException {
446
        if( StringUtils.isEmpty(format) ) {
447
            throw new IllegalArgumentException("Can't accept null as format name.");
448
        }
449
        format = format.trim().toLowerCase();
450
        switch(format) {
451
            case "jts":
452
                return this.getJTS();
453
            case "wkb":
454
                return this.convertToWKB();
455 45425 jjdelcerro
            case "hexwkb":
456
                return this.convertToHexWKB();
457 43909 jjdelcerro
            case "ewkb":
458
                return this.convertToEWKB();
459
            case "wkt":
460
                return this.convertToWKT();
461
            case "gml":
462
                return GMLUtils.geometry2GML(this);
463
            case "json":
464
            case "geojson":
465 46006 jjdelcerro
                return this.convertToGeoJson();
466 43909 jjdelcerro
            default:
467
                throw new IllegalArgumentException("Format '"+format+"' not supported");
468
        }
469
470
    }
471
472 45425 jjdelcerro
    @Override
473 42260 fdiaz
    public byte[] convertToWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
474 43908 jjdelcerro
        try {
475
            return new OGCWKBEncoder().encode(this);
476
        } catch (Exception e) {
477
            throw new GeometryOperationException(e);
478
        }
479 45425 jjdelcerro
    }
480 42260 fdiaz
481 45425 jjdelcerro
    @Override
482
    public String convertToHexWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
483
        try {
484
            byte[] bytes = new OGCWKBEncoder().encode(this);
485
            return Hex.encodeHexString(bytes);
486
        } catch (Exception e) {
487
            throw new GeometryOperationException(e);
488
        }
489 42260 fdiaz
    }
490 45734 omartinez
491 46006 jjdelcerro
    public String convertToGeoJson() throws GeometryOperationNotSupportedException, GeometryOperationException {
492
        try {
493
            GeoJsonWriter writer = new GeoJsonWriter();
494
            writer.setEncodeCRS(true);
495
            return writer.write(this.getJTS());
496
        } catch (Exception e) {
497
            throw new GeometryOperationException(e);
498
        }
499
    }
500
501 45734 omartinez
    @Override
502
    public String convertToHexEWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
503
        try {
504
            byte[] bytes = new PostGISEWKBEncoder().encode(this);
505
            return Hex.encodeHexString(bytes);
506
        } catch (Exception e) {
507
            throw new GeometryOperationException(e);
508
        }
509
    }
510 42260 fdiaz
511 45425 jjdelcerro
    @Override
512
    public byte[] convertToWKBQuietly() {
513
        try {
514
            return new OGCWKBEncoder().encode(this);
515
        } catch (Exception e) {
516
            return null;
517
        }
518
    }
519
520
    @Override
521
    public String convertToHexWKBQuietly() {
522
        try {
523
            byte[] bytes = new OGCWKBEncoder().encode(this);
524
            return Hex.encodeHexString(bytes);
525
        } catch (Exception e) {
526
            return null;
527
        }
528
    }
529
530
    @Override
531 47648 jjdelcerro
    public String convertToHexEWKBQuietly() {
532
        try {
533
            byte[] bytes = new PostGISEWKBEncoder().encode(this);
534
            return Hex.encodeHexString(bytes);
535
        } catch (Exception e) {
536
            return null;
537
        }
538
    }
539
540
    @Override
541 42260 fdiaz
    public byte[] convertToWKB(int srs) throws GeometryOperationNotSupportedException, GeometryOperationException {
542 43908 jjdelcerro
        /*
543 42771 jbadia
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
544 43908 jjdelcerro
         */
545 42813 fdiaz
546 43908 jjdelcerro
        try {
547
            return new OGCWKBEncoder().encode(this);
548
        } catch (Exception e) {
549
            throw new GeometryOperationException(e);
550
        }
551 42260 fdiaz
    }
552
553 43908 jjdelcerro
    @Override
554 42260 fdiaz
    public byte[] convertToWKBForcingType(int srs, int type) throws GeometryOperationNotSupportedException,
555 43908 jjdelcerro
            GeometryOperationException {
556
        /*
557 42771 jbadia
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
558 43908 jjdelcerro
         */
559
        Geometry geom = this;
560
        if (this.getType() != type) {
561 42771 jbadia
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
562
            jts = JTSUtils.convertTypes(jts, this.getType(), type);
563 42813 fdiaz
564 44099 jjdelcerro
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
565 42771 jbadia
        }
566 43908 jjdelcerro
        try {
567
            return new OGCWKBEncoder().encode(geom);
568
        } catch (Exception e) {
569
            throw new GeometryOperationException(e);
570
        }
571 42813 fdiaz
572 42771 jbadia
    }
573 42260 fdiaz
574 45748 fdiaz
    @Override
575 42771 jbadia
    public byte[] convertToEWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
576 43908 jjdelcerro
        try {
577
            return new PostGISEWKBEncoder().encode(this);
578
        } catch (Exception e) {
579
            throw new GeometryOperationException(e);
580
        }
581 42771 jbadia
582 42260 fdiaz
    }
583
584 45748 fdiaz
    @Override
585 42771 jbadia
    public byte[] convertToEWKB(int srs) throws GeometryOperationNotSupportedException, GeometryOperationException {
586 43908 jjdelcerro
        /*
587 42771 jbadia
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
588 43908 jjdelcerro
         */
589 42813 fdiaz
590 43908 jjdelcerro
        try {
591
            return new PostGISEWKBEncoder().encode(this);
592
        } catch (Exception e) {
593
            throw new GeometryOperationException(e);
594
        }
595 42771 jbadia
    }
596
597 45748 fdiaz
    @Override
598 42771 jbadia
    public byte[] convertToEWKBForcingType(int srs, int type) throws GeometryOperationNotSupportedException,
599 43908 jjdelcerro
            GeometryOperationException {
600
        /*
601 42771 jbadia
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
602 43908 jjdelcerro
         */
603
        Geometry geom = this;
604
        if (this.getType() != type) {
605 42771 jbadia
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
606
            jts = JTSUtils.convertTypes(jts, this.getType(), type);
607 42813 fdiaz
608 44099 jjdelcerro
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
609 42771 jbadia
        }
610 43908 jjdelcerro
        try {
611
            return new PostGISEWKBEncoder().encode(geom);
612
        } catch (Exception e) {
613
            throw new GeometryOperationException(e);
614
        }
615 42813 fdiaz
616 42771 jbadia
    }
617
618 45425 jjdelcerro
    @Override
619 42260 fdiaz
    public String convertToWKT() throws GeometryOperationNotSupportedException, GeometryOperationException {
620
        int subType = getGeometryType().getSubType();
621
622 45748 fdiaz
        EWKTWriter writer; // = null;
623 42875 fdiaz
624
        switch (subType) {
625 43908 jjdelcerro
            case Geometry.SUBTYPES.GEOM3D:
626
                writer = new EWKTWriter(3, false);
627
                break;
628
            case Geometry.SUBTYPES.GEOM2DM:
629
                writer = new EWKTWriter(3, true);
630
                break;
631
            case Geometry.SUBTYPES.GEOM3DM:
632
                writer = new EWKTWriter(4, true);
633
                break;
634 42875 fdiaz
635 43908 jjdelcerro
            default:
636
                writer = new EWKTWriter(2, false);
637
                break;
638 42875 fdiaz
        }
639 42260 fdiaz
        com.vividsolutions.jts.geom.Geometry jts = getJTS();
640 42875 fdiaz
        return writer.write(jts);
641 42260 fdiaz
    }
642
643 45425 jjdelcerro
    @Override
644
    public String convertToWKTQuietly() {
645
        try {
646
            return this.convertToWKT();
647
        } catch(Exception ex) {
648
            return null;
649
        }
650
    }
651
652
    @Override
653 42260 fdiaz
    public org.gvsig.fmap.geom.Geometry buffer(double distance) throws GeometryOperationNotSupportedException,
654 45425 jjdelcerro
        GeometryOperationException {
655
        if( distance==0 ) {
656
          return this;
657
        }
658 44099 jjdelcerro
        return JTSUtils.createGeometry(this.getProjection(), getJTS().buffer(distance));
659 42260 fdiaz
    }
660 45748 fdiaz
661
662
    @Override
663
    public org.gvsig.fmap.geom.Geometry buffer(double distance, int joinStyle, boolean capButt) throws GeometryOperationNotSupportedException,
664
        GeometryOperationException {
665
        if( distance==0 ) {
666
          return this;
667
        }
668
669 45762 fdiaz
        int quadrantSegments = JTSUtils.calculateQuadrantSegments(joinStyle);
670 45748 fdiaz
671
        return JTSUtils.createGeometry(this.getProjection(), getJTS().buffer(
672
                distance,
673
                quadrantSegments,
674
                capButt ? BufferParameters.CAP_FLAT : BufferParameters.CAP_ROUND
675
        ));
676
    }
677 42260 fdiaz
678
    /*
679
     * (non-Javadoc)
680
     *
681
     * @see org.gvsig.fmap.geom.Geometry#snapTo(org.gvsig.fmap.geom.Geometry,
682
     * double)
683
     */
684 45748 fdiaz
    @Override
685 42260 fdiaz
    public org.gvsig.fmap.geom.Geometry snapTo(org.gvsig.fmap.geom.Geometry other, double snapTolerance)
686 43908 jjdelcerro
            throws GeometryOperationNotSupportedException, GeometryOperationException {
687 45748 fdiaz
        Geometry result; // = null;
688 42260 fdiaz
        GeometrySnapper snapper = new GeometrySnapper(getJTS());
689
        com.vividsolutions.jts.geom.Geometry jts_result = snapper.snapTo(((GeometryJTS) other).getJTS(), snapTolerance);
690 44099 jjdelcerro
        result = JTSUtils.createGeometry(this.getProjection(), jts_result);
691 42260 fdiaz
        return result;
692
    }
693
694
    /*
695
     * (non-Javadoc)
696
     *
697
     * @see org.gvsig.fmap.geom.Geometry#getInteriorPoint()
698
     */
699 45748 fdiaz
    @Override
700 42260 fdiaz
    public Point getInteriorPoint() throws GeometryOperationNotSupportedException, GeometryOperationException {
701
702
        com.vividsolutions.jts.geom.Geometry geometry = getJTS();
703
        com.vividsolutions.jts.geom.Point point = geometry.getInteriorPoint();
704 44099 jjdelcerro
        Geometry result = JTSUtils.createGeometry(this.getProjection(), point);
705 42260 fdiaz
        return (Point) result;
706
    }
707
708
    /*
709
     * (non-Javadoc)
710
     *
711
     * @see org.gvsig.fmap.geom.Geometry#isValid()
712
     */
713 45748 fdiaz
    @Override
714 42260 fdiaz
    public boolean isValid() {
715
        return getJTS().isValid();
716
    }
717
718 44225 jjdelcerro
    @Override
719 42260 fdiaz
    public ValidationStatus getValidationStatus() {
720
        DefaultValidationStatus status = new DefaultValidationStatus(ValidationStatus.VALID, null);
721 45748 fdiaz
        com.vividsolutions.jts.geom.Geometry jtsgeom; // = null;
722 42260 fdiaz
        try {
723
            jtsgeom = this.getJTS();
724
            IsValidOp validOp = new IsValidOp(jtsgeom);
725 44225 jjdelcerro
            if (!validOp.isValid() ) {
726 42260 fdiaz
                status.setValidationError(validOp.getValidationError());
727
            }
728 46486 jjdelcerro
        } catch (Throwable ex) {
729 42260 fdiaz
            status.setStatusCode(ValidationStatus.CURRUPTED);
730
            status.setMesage("The geometry is corrupted.");
731
            if (this instanceof OrientableSurface) {
732
                int vertices = ((OrientableSurface) this).getNumVertices();
733
                if (vertices < 3) {
734
                    status.setStatusCode(ValidationStatus.TOO_FEW_POINTS);
735
                    status.setMesage(TopologyValidationError.errMsg[TopologyValidationError.TOO_FEW_POINTS]);
736
                }
737
            } else if (this instanceof OrientableCurve) {
738
                int vertices = ((OrientableCurve) this).getNumVertices();
739
                if (vertices < 2) {
740
                    status.setStatusCode(ValidationStatus.TOO_FEW_POINTS);
741
                    status.setMesage(TopologyValidationError.errMsg[TopologyValidationError.TOO_FEW_POINTS]);
742
                }
743
            }
744
        }
745
        return status;
746
    }
747
748
    /*
749
     * (non-Javadoc)
750
     *
751
     * @see org.gvsig.fmap.geom.Geometry#makeValid()
752
     */
753 45748 fdiaz
    @Override
754 42260 fdiaz
    public org.gvsig.fmap.geom.Geometry makeValid() {
755
        try {
756
            ValidationStatus vs = this.getValidationStatus();
757
            if (vs.isValid()) {
758
                return this;
759
            }
760 45748 fdiaz
            Geometry g; // = null;
761 42260 fdiaz
            switch (vs.getStatusCode()) {
762 43908 jjdelcerro
                case Geometry.ValidationStatus.RING_SELF_INTERSECTION:
763
                case Geometry.ValidationStatus.SELF_INTERSECTION:
764
                    g = this.buffer(0);
765
                    if (g.isValid()) {
766
                        return g;
767
                    }
768
                    break;
769 42260 fdiaz
770 43908 jjdelcerro
                case Geometry.ValidationStatus.TOO_FEW_POINTS:
771
                    if (this instanceof OrientableCurve) {
772
                        int vertices = ((OrientableCurve) this).getNumVertices();
773
                        if (vertices < 2) {
774
                            return null; // new
775
                            // DefaultNullGeometry(this.getGeometryType());
776
                        }
777 42260 fdiaz
                    }
778 43908 jjdelcerro
                    if (this instanceof OrientableSurface) {
779
                        int vertices = ((OrientableSurface) this).getNumVertices();
780
                        if (vertices < 3) {
781
                            return null; // new
782
                            // DefaultNullGeometry(this.getGeometryType());
783
                        }
784 42260 fdiaz
                    }
785
            }
786
        } catch (Exception ex) {
787
            return null;
788
        }
789
        return null;
790
    }
791
792
    /*
793
     * (non-Javadoc)
794
     *
795
     * @see org.gvsig.fmap.geom.Geometry#getBounds2D()
796
     */
797 45748 fdiaz
    @Override
798 42260 fdiaz
    public Rectangle2D getBounds2D() {
799
        com.vividsolutions.jts.geom.Envelope envInternal = getJTS().getEnvelopeInternal();
800
        return new Rectangle2D.Double(envInternal.getMinX(), envInternal.getMinY(), envInternal.getWidth(),
801 43908 jjdelcerro
                envInternal.getHeight());
802 42260 fdiaz
    }
803
804
    /*
805
     * (non-Javadoc)
806
     *
807
     * @see java.awt.Shape#getBounds()
808
     */
809 45748 fdiaz
    @Override
810 42260 fdiaz
    public Rectangle getBounds() {
811
        return this.getShape().getBounds();
812
    }
813
814
    /*
815
     * (non-Javadoc)
816
     *
817
     * @see org.gvsig.fmap.geom.Geometry#getInternalShape()
818
     */
819 45748 fdiaz
    @Override
820 42260 fdiaz
    public Shape getInternalShape() {
821
        return getShape();
822
    }
823
824 45748 fdiaz
    @Override
825 42260 fdiaz
    public void rotate(double radAngle, double basex, double basey) {
826
827
        AffineTransform at = new AffineTransform();
828
        at.rotate(radAngle, basex, basey);
829
        this.transform(at);
830
    }
831
832 45748 fdiaz
    @Override
833 42260 fdiaz
    public void move(double dx, double dy) {
834
835
        AffineTransform at = new AffineTransform();
836
        at.translate(dx, dy);
837
        this.transform(at);
838
    }
839
840 45748 fdiaz
    @Override
841 42260 fdiaz
    public void scale(Point basePoint, double sx, double sy) {
842
843
        AffineTransform at = new AffineTransform();
844
        at.setToTranslation(basePoint.getX(), basePoint.getY());
845
        at.scale(sx, sy);
846
        at.translate(-basePoint.getX(), -basePoint.getY());
847
        this.transform(at);
848
    }
849
850 45748 fdiaz
    @Override
851 42260 fdiaz
    public Geometry[] closestPoints(Geometry other) throws GeometryOperationNotSupportedException,
852 43908 jjdelcerro
            GeometryOperationException {
853 45748 fdiaz
        Point[] points;
854 42260 fdiaz
855
        Coordinate[] jts_points = DistanceOp.nearestPoints(getJTS(), ((GeometryJTS) other).getJTS());
856
        points = new Point[jts_points.length];
857
        for (int i = 0; i < jts_points.length; i++) {
858
            try {
859 44099 jjdelcerro
                points[i] = JTSUtils.createPoint(this.getGeometryType(), this.getProjection(), jts_points[i]);
860 42260 fdiaz
            } catch (CreateGeometryException e) {
861
                throw new GeometryOperationException(e);
862
            }
863
        }
864
865
        return (Geometry[]) points;
866
    }
867
868 45748 fdiaz
    @Override
869 42260 fdiaz
    public Geometry convexHull() throws GeometryOperationNotSupportedException, GeometryOperationException {
870 45939 fdiaz
        return JTSUtils.createGeometry(this.getProjection(), getJTS().convexHull(), null);
871 42260 fdiaz
    }
872
873 45748 fdiaz
    @Override
874 42260 fdiaz
    public Geometry difference(Geometry other) throws GeometryOperationNotSupportedException,
875 43908 jjdelcerro
            GeometryOperationException {
876 46671 fdiaz
        com.vividsolutions.jts.geom.Geometry otherJTS = ((GeometryJTS) other).getJTS();
877
        if(other instanceof Aggregate){
878
            otherJTS = otherJTS.union();
879
        }
880 47385 fdiaz
            return JTSUtils.createGeometry(this.getProjection(), getJTS().difference(otherJTS), null);
881
        }
882 42260 fdiaz
883 45748 fdiaz
    @Override
884 42260 fdiaz
    public Geometry intersection(Geometry other) throws GeometryOperationNotSupportedException,
885 43908 jjdelcerro
            GeometryOperationException {
886 46671 fdiaz
        com.vividsolutions.jts.geom.Geometry otherJTS = ((GeometryJTS) other).getJTS();
887
        if(other instanceof Aggregate){
888
            otherJTS = otherJTS.union();
889
        }
890
        return JTSUtils.createGeometry(this.getProjection(), getJTS().intersection(otherJTS), null);
891 42260 fdiaz
    }
892
893 45748 fdiaz
    @Override
894 42260 fdiaz
    public Geometry union(Geometry other) throws GeometryOperationNotSupportedException, GeometryOperationException {
895 47364 fdiaz
        try {
896
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
897
            com.vividsolutions.jts.geom.Geometry otherJts = ((GeometryJTS)other).getJTS();
898
899
            if(jts.isValid() && otherJts.isValid()){
900
                return JTSUtils.createGeometry(this.getProjection(), jts.union(otherJts), this.getGeometryType());
901
            }
902
            MultiPrimitive geom = this.getManager().createMultiPrimitive(geometryType);
903
            geom.addPrimitives(this);
904
            geom.addPrimitives(other);
905
            return geom;
906
        } catch (CreateGeometryException ex) {
907
            throw new GeometryOperationException(
908
                    this.getGeometryType().getType(),
909
                    this.getManager().getGeometryOperationCode(Geometry.OPERATIONS.UNION),
910
                    ex);
911
        }
912 42260 fdiaz
    }
913
914 45748 fdiaz
    @Override
915 42260 fdiaz
    public org.gvsig.fmap.geom.primitive.Point centroid() throws GeometryOperationNotSupportedException,
916 43908 jjdelcerro
            GeometryOperationException {
917 42260 fdiaz
        try {
918 44099 jjdelcerro
            return JTSUtils.createPoint(this.getGeometryType(), this.getProjection(), getJTS().getCentroid().getCoordinate());
919 42260 fdiaz
        } catch (CreateGeometryException e) {
920
            throw new GeometryOperationException(e);
921
        }
922
    }
923
924
    protected void notifyDeprecated(String message) {
925 45425 jjdelcerro
        LOGGER.info(message);
926 42260 fdiaz
927
    }
928 42278 fdiaz
929
930 45748 fdiaz
    @Override
931 42281 fdiaz
    public boolean ensureOrientation(boolean ccw) throws GeometryOperationNotSupportedException, GeometryOperationException {
932 43908 jjdelcerro
        if (ccw != isCCW()) {
933 42281 fdiaz
            flip();
934
            return true;
935
        }
936
        return false;
937
    }
938
939
    /* (non-Javadoc)
940
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#out(org.gvsig.fmap.geom.Geometry)
941
     */
942 45748 fdiaz
    @Override
943 42281 fdiaz
    public boolean out(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
944 43908 jjdelcerro
        GeometryJTS otherJtsGeom = (GeometryJTS) geometry;
945 42281 fdiaz
        return (!contains(otherJtsGeom) && !intersects(otherJtsGeom));
946
    }
947
948 42283 fdiaz
    @Override
949
    public boolean equals(Object obj) {
950
        if (obj instanceof GeometryJTS) {
951
            return this.getJTS().equals(((GeometryJTS) obj).getJTS());
952
        }
953
        return false;
954
    }
955
956 45748 fdiaz
    @Override
957 43908 jjdelcerro
    public String toString() {
958 42813 fdiaz
        return this.getGeometryType().getFullName();
959
    }
960 42334 dmartinezizquierdo
961 43785 jjdelcerro
    @Override
962
    public IProjection getProjection() {
963
        return this.projection;
964
    }
965 42334 dmartinezizquierdo
966 43785 jjdelcerro
    @Override
967
    public void setProjectionIffNull(IProjection projection) {
968 43908 jjdelcerro
        if (this.projection == null) {
969 43785 jjdelcerro
            this.projection = projection;
970
        }
971
    }
972
973
    @Override
974
    public void setProjection(IProjection projection) {
975
        this.projection = projection;
976
    }
977
978 44040 jjdelcerro
    @Override
979 44352 jjdelcerro
    public void setProjection(String projection) {
980
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
981
        this.setProjection(proj);
982
    }
983
984
    @Override
985 44040 jjdelcerro
    @SuppressWarnings("CloneDoesntCallSuperClone")
986
    public Geometry clone() throws CloneNotSupportedException {
987
        return this.cloneGeometry();
988
    }
989
990 45910 fdiaz
    @Override
991
    public Geometry boundary() {
992 45939 fdiaz
        return JTSUtils.createGeometry(this.getProjection(), getJTS().getBoundary(), null);
993 45910 fdiaz
    }
994 47385 fdiaz
995
    @Override
996
    public Geometry fix() {
997
        try {
998
            ValidationStatus status = this.getValidationStatus();
999
            if(status.isValid()) {
1000
                return this.cloneGeometry();
1001
            }
1002
            int statusCode = status.getStatusCode();
1003
            Geometry fixed;
1004
            switch (statusCode) {
1005
                case ValidationStatus.VALID:
1006
                    return this.cloneGeometry();
1007
                case ValidationStatus.SELF_INTERSECTION:
1008
                case ValidationStatus.RING_SELF_INTERSECTION:
1009
                    fixed = this.buffer(Double.MIN_VALUE);
1010
                    break;
1011
                case ValidationStatus.CURRUPTED:
1012
                case ValidationStatus.UNKNOW:
1013
                case ValidationStatus.DISCONNECTED_INTERIOR:
1014
                case ValidationStatus.DUPLICATE_RINGS:
1015
                case ValidationStatus.HOLE_OUTSIDE_SHELL:
1016
                case ValidationStatus.INVALID_COORDINATE:
1017
                case ValidationStatus.NESTED_HOLES:
1018
                case ValidationStatus.NESTED_SHELLS:
1019
                case ValidationStatus.RING_NOT_CLOSED:
1020
                case ValidationStatus.TOO_FEW_POINTS:
1021
                default:
1022
                    return null;
1023
            }
1024
            if(!fixed.isValid()){
1025
                return null;
1026
            }
1027
            if(this.getGeometryType().getType() != fixed.getGeometryType().getType()){
1028
                return null;
1029
            }
1030
            return fixed;
1031
        } catch (Exception ex) {
1032
            return null;
1033
        }
1034
    }
1035 45910 fdiaz
1036 47432 fdiaz
    @Override
1037
    public Geometry forceSubtype(int subtype) throws GeometryOperationNotSupportedException, GeometryOperationException {
1038
        switch(subtype){
1039
            case Geometry.SUBTYPES.GEOM2D:
1040
                return force2D();
1041
            case Geometry.SUBTYPES.GEOM2DM:
1042
                return force2DM();
1043
            case Geometry.SUBTYPES.GEOM3D:
1044
                return force3D();
1045
            case Geometry.SUBTYPES.GEOM3DM:
1046
                return force3DM();
1047
        }
1048
        return this;
1049
    }
1050 45910 fdiaz
1051 47432 fdiaz
    protected abstract Geometry force2DM() throws GeometryOperationNotSupportedException, GeometryOperationException;
1052
1053
    protected abstract Geometry force3D() throws GeometryOperationNotSupportedException, GeometryOperationException;
1054
1055
    protected abstract Geometry force3DM() throws GeometryOperationNotSupportedException, GeometryOperationException;
1056
1057 47605 fdiaz
    @Override
1058
    public boolean isEmpty() {
1059
        if(this instanceof Aggregate) {
1060
            if(((Aggregate)this).getPrimitivesNumber()<1){
1061
                return true;
1062
            }
1063
        } else if(this instanceof Complex) {
1064
            if(((Complex)this).getPrimitivesNumber()<1){
1065
                return true;
1066
            }
1067
        } else if(this instanceof OrientablePrimitive) {
1068
            return ((OrientablePrimitive)this).isEmpty();
1069
        }
1070
        return false;
1071
    }
1072 47432 fdiaz
1073
1074 47605 fdiaz
1075 42260 fdiaz
}