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

History | View | Annotate | Download (30.8 KB)

1
/* 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
import com.vividsolutions.jts.io.geojson.GeoJsonWriter;
28
import com.vividsolutions.jts.operation.buffer.BufferParameters;
29
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
import java.awt.Rectangle;
34
import java.awt.Shape;
35
import java.awt.geom.AffineTransform;
36
import java.awt.geom.Rectangle2D;
37
import org.apache.commons.codec.binary.Hex;
38
import org.apache.commons.lang3.StringUtils;
39
import org.cresques.cts.IProjection;
40
import org.gvsig.fmap.crs.CRSFactory;
41
import org.gvsig.fmap.geom.Geometry;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.GeometryManager;
44
import org.gvsig.fmap.geom.aggregate.Aggregate;
45
import org.gvsig.fmap.geom.complex.Complex;
46
import org.gvsig.fmap.geom.exception.CreateGeometryException;
47
import org.gvsig.fmap.geom.jts.operation.towkb.OGCWKBEncoder;
48
import org.gvsig.fmap.geom.jts.operation.towkb.PostGISEWKBEncoder;
49
import org.gvsig.fmap.geom.jts.operation.towkt.EWKTWriter;
50
import org.gvsig.fmap.geom.jts.primitive.Envelope2D;
51
import org.gvsig.fmap.geom.jts.primitive.Envelope3D;
52
import org.gvsig.fmap.geom.jts.primitive.point.Point3D;
53
import org.gvsig.fmap.geom.jts.util.GMLUtils;
54
import org.gvsig.fmap.geom.jts.util.JTSUtils;
55
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
56
import org.gvsig.fmap.geom.operation.GeometryOperationException;
57
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
58
import org.gvsig.fmap.geom.primitive.Envelope;
59
import org.gvsig.fmap.geom.primitive.OrientableCurve;
60
import org.gvsig.fmap.geom.primitive.OrientableSurface;
61
import org.gvsig.fmap.geom.primitive.Point;
62
import org.gvsig.fmap.geom.type.GeometryType;
63
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65

    
66
/**
67
 * @author gvSIG Team
68
 *
69
 */
70
@SuppressWarnings("UseSpecificCatch")
71
public abstract class AbstractGeometry implements GeometryJTS {
72

    
73
    protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractGeometry.class);
74

    
75
    /**
76
     *
77
     */
78
    private static final long serialVersionUID = 4999326772576222293L;
79

    
80
    private GeometryType geometryType;
81

    
82
    private IProjection projection;
83

    
84
    /**
85
     *
86
     * @param type
87
     * @param subtype
88
     */
89
    public AbstractGeometry(int type, int subtype) {
90
        try {
91
            this.geometryType = GeometryLocator.getGeometryManager().getGeometryType(type, subtype);
92
        } catch (Exception e) {
93
            // TODO: Ver de crear una excepcion para esto o si hay alguna en el API.
94
            throw new RuntimeException(e);
95
        }
96
    }
97
    
98
    public void setGeometryType(GeometryType geometryType) {
99
        this.geometryType = geometryType;
100
    }
101

    
102
    @Override
103
    public GeometryType getGeometryType() {
104
        return geometryType;
105
    }
106

    
107
    protected GeometryManager getManager() {
108
        return GeometryLocator.getGeometryManager();
109
    }
110

    
111
    /*
112
     * (non-Javadoc)
113
     *
114
     * @see org.gvsig.fmap.geom.Geometry#contains(org.gvsig.fmap.geom.Geometry)
115
     */
116
    @Override
117
    public boolean contains(Geometry geometry) throws GeometryOperationNotSupportedException,
118
            GeometryOperationException {
119
        if (!(geometry instanceof GeometryJTS)) {
120
            return false;
121
        }
122
        return getJTS().contains(((GeometryJTS) geometry).getJTS());
123
    }
124

    
125
    /*
126
     * (non-Javadoc)
127
     *
128
     * @see java.lang.Comparable#compareTo(java.lang.Object)
129
     */
130
    @Override
131
    public int compareTo(Object o) {
132
        return getJTS().compareTo(((GeometryJTS) o).getJTS());
133
    }
134

    
135
    /*
136
     * (non-Javadoc)
137
     *
138
     * @see java.awt.Shape#contains(double, double)
139
     */
140
    @Override
141
    public boolean contains(double x, double y) {
142
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
143
        Shape shp = getShape();
144
        return shp.contains(x, y);
145
    }
146

    
147
    /*
148
     * (non-Javadoc)
149
     *
150
     * @see java.awt.Shape#intersects(double, double, double, double)
151
     */
152
    @Override
153
    public boolean intersects(double x, double y, double w, double h) {
154

    
155
        notifyDeprecated("Calling deprecated method of geometry intersects from shape interface");
156
        Shape shp = this.getShape();
157
        return shp.intersects(x, y, w, h);
158
    }
159

    
160
    /*
161
     * (non-Javadoc)
162
     *
163
     * @see java.awt.Shape#contains(double, double, double, double)
164
     */
165
    @Override
166
    public boolean contains(double x, double y, double w, double h) {
167
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
168
        Shape shp = this.getShape();
169
        return shp.contains(x, y, w, h);
170
    }
171

    
172
    /*
173
     * (non-Javadoc)
174
     *
175
     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
176
     */
177
    @Override
178
    public boolean contains(java.awt.geom.Point2D p) {
179
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
180
        Shape shp = this.getShape();
181
        return shp.contains(p);
182
    }
183

    
184
    /*
185
     * (non-Javadoc)
186
     *
187
     * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
188
     */
189
    @Override
190
    public boolean contains(Rectangle2D r) {
191
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
192
        Shape shp = this.getShape();
193
        return shp.contains(r);
194
    }
195

    
196
    /*
197
     * (non-Javadoc)
198
     *
199
     * @see org.gvsig.fmap.geom.Geometry#distance(org.gvsig.fmap.geom.Geometry)
200
     */
201
    @Override
202
    public double distance(org.gvsig.fmap.geom.Geometry other) throws GeometryOperationNotSupportedException,
203
            GeometryOperationException {
204
        return getJTS().distance(((GeometryJTS) other).getJTS());
205
    }
206

    
207
    /*
208
     * (non-Javadoc)
209
     *
210
     * @see
211
     * org.gvsig.fmap.geom.Geometry#isWithinDistance(org.gvsig.fmap.geom.Geometry
212
     * , double)
213
     */
214
    @Override
215
    public boolean isWithinDistance(org.gvsig.fmap.geom.Geometry other, double distance)
216
            throws GeometryOperationNotSupportedException, GeometryOperationException {
217
        return com.vividsolutions.jts.operation.distance.DistanceOp.isWithinDistance(this.getJTS(),
218
                ((GeometryJTS) other).getJTS(), distance);
219
    }
220

    
221
    /*
222
     * (non-Javadoc)
223
     *
224
     * @see org.gvsig.fmap.geom.Geometry#overlaps(org.gvsig.fmap.geom.Geometry)
225
     */
226
    @Override
227
    public boolean overlaps(org.gvsig.fmap.geom.Geometry geometry) throws GeometryOperationNotSupportedException,
228
            GeometryOperationException {
229
        // TODO: this method can be implemented throw invokeOperation
230
        return getJTS().overlaps(((GeometryJTS) geometry).getJTS());
231
    }
232

    
233
    @Override
234
    public boolean coveredBy(Geometry geometry) throws GeometryOperationNotSupportedException,
235
            GeometryOperationException {
236

    
237
        return getJTS().coveredBy(((GeometryJTS) geometry).getJTS());
238
    }
239

    
240
    @Override
241
    public boolean covers(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
242
        // TODO: this method can be implemented throw invokeOperation
243
        return getJTS().covers(((GeometryJTS) geometry).getJTS());
244

    
245
    }
246

    
247
    @Override
248
    public boolean crosses(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
249
        // TODO: this method can be implemented throw invokeOperation
250
        return getJTS().crosses(((GeometryJTS) geometry).getJTS());
251
    }
252

    
253
    @Override
254
    public boolean intersects(Geometry geometry) throws GeometryOperationNotSupportedException,
255
            GeometryOperationException {
256
        return getJTS().intersects(((GeometryJTS) geometry).getJTS());
257
    }
258

    
259
    @Override
260
    public boolean touches(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
261
        // TODO: this method can be implemented throw invokeOperation
262
        return getJTS().touches(((GeometryJTS) geometry).getJTS());
263
    }
264

    
265
    @Override
266
    public boolean disjoint(Geometry geometry) throws GeometryOperationNotSupportedException,
267
            GeometryOperationException {
268
        // TODO: this method can be implemented throw invokeOperation
269
        return getJTS().disjoint(((GeometryJTS) geometry).getJTS());
270
    }
271

    
272
    @Override
273
    public boolean within(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
274
        // TODO: this method can be implemented throw invokeOperation
275
        return getJTS().within(((GeometryJTS) geometry).getJTS());
276
    }
277

    
278
    @Override
279
    public double area() throws GeometryOperationNotSupportedException, GeometryOperationException {
280
        return getJTS().getArea();
281
    }
282

    
283
    @Override
284
    public double perimeter() throws GeometryOperationNotSupportedException, GeometryOperationException {
285
        return getJTS().getLength();
286
    }
287

    
288
    /*
289
     * (non-Javadoc)
290
     *
291
     * @see org.gvsig.fmap.geom.Geometry#intersects(java.awt.geom.Rectangle2D)
292
     */
293
    @Override
294
    public boolean intersects(Rectangle2D r) {
295
        double x = r.getMinX();
296
        double y = r.getMinY();
297
        double w = r.getWidth();
298
        double h = r.getHeight();
299

    
300
        return fastIntersects(x, y, w, h);
301
    }
302

    
303
    /*
304
     * (non-Javadoc)
305
     *
306
     * @see org.gvsig.fmap.geom.Geometry#fastIntersects(double, double, double,
307
     * double)
308
     */
309
    @Override
310
    public boolean fastIntersects(double x, double y, double w, double h) {
311
        com.vividsolutions.jts.geom.Geometry rect; 
312
        com.vividsolutions.jts.geom.Coordinate[] coord = new com.vividsolutions.jts.geom.Coordinate[5];
313
        coord[0] = new com.vividsolutions.jts.geom.Coordinate(x, y);
314
        coord[1] = new com.vividsolutions.jts.geom.Coordinate(x + w, y);
315
        coord[2] = new com.vividsolutions.jts.geom.Coordinate(x + w, y + w);
316
        coord[3] = new com.vividsolutions.jts.geom.Coordinate(x, y + w);
317
        coord[4] = new com.vividsolutions.jts.geom.Coordinate(x, y);
318
        rect = JTSUtils.createJTSPolygon(coord);
319

    
320
        return getJTS().intersects(rect);
321
    }
322

    
323
    /*
324
     * (non-Javadoc)
325
     *
326
     * @see org.gvsig.fmap.geom.Geometry#getEnvelope()
327
     */
328
    @Override
329
    public Envelope getEnvelope() {
330
        if (is3D()) {
331
            Coordinate[] coordinates = getJTS().getCoordinates();
332

    
333
            double minx = Double.POSITIVE_INFINITY;
334
            double miny = Double.POSITIVE_INFINITY;
335
            double minz = Double.POSITIVE_INFINITY;
336

    
337
            double maxx = Double.NEGATIVE_INFINITY;
338
            double maxy = Double.NEGATIVE_INFINITY;
339
            double maxz = Double.NEGATIVE_INFINITY;
340

    
341
            double x;
342
            double y;
343
            double z;
344

    
345
            for (Coordinate coordinate : coordinates) {
346
                x = coordinate.x;
347
                y = coordinate.y;
348
                z = coordinate.z;
349
                minx = Math.min(x, minx);
350
                miny = Math.min(y, miny);
351
                minz = Math.min(z, minz);
352
                maxx = Math.max(x, maxx);
353
                maxy = Math.max(y, maxy);
354
                maxz = Math.max(z, maxz);
355
            }
356

    
357
            if (minx <= maxx && miny <= maxy && minz <= maxz) {
358
                Point min = new Point3D(minx, miny, minz);
359
                Point max = new Point3D(maxx, maxy, maxz);
360
                return new Envelope3D(min, max, this.getProjection());
361
            }
362
            return new Envelope3D(this.getProjection());
363
        } else {
364
            com.vividsolutions.jts.geom.Envelope envelope = getJTS().getEnvelopeInternal();
365
            return new Envelope2D(envelope, this.getProjection());
366
        }
367
    }
368

    
369
    /*
370
     * (non-Javadoc)
371
     *
372
     * @see org.gvsig.fmap.geom.Geometry#isSimple()
373
     */
374
    @Override
375
    public boolean isSimple() {
376
        return this.getJTS().isSimple();
377
    }
378

    
379
    /*
380
     * (non-Javadoc)
381
     *
382
     * @see org.gvsig.fmap.geom.Geometry#isCCW()
383
     */
384
    @Override
385
    public boolean isCCW() throws GeometryOperationNotSupportedException, GeometryOperationException {
386
        return CGAlgorithms.isCCW(this.getJTS().getCoordinates());
387
    }
388

    
389
    /*
390
     * (non-Javadoc)
391
     *
392
     * @see org.gvsig.fmap.geom.Geometry#invokeOperation(int,
393
     * org.gvsig.fmap.geom.operation.GeometryOperationContext)
394
     */
395
    @Override
396
    public Object invokeOperation(int index, GeometryOperationContext ctx)
397
            throws GeometryOperationNotSupportedException, GeometryOperationException {
398
        return getManager().invokeOperation(index, this, ctx);
399

    
400
    }
401

    
402
    /*
403
     * (non-Javadoc)
404
     *
405
     * @see org.gvsig.fmap.geom.Geometry#invokeOperation(java.lang.String,
406
     * org.gvsig.fmap.geom.operation.GeometryOperationContext)
407
     */
408
    @Override
409
    public Object invokeOperation(String opName, GeometryOperationContext ctx)
410
            throws GeometryOperationNotSupportedException, GeometryOperationException {
411
        return getManager().invokeOperation(opName, this, ctx);
412

    
413
    }
414

    
415
    /*
416
     * (non-Javadoc)
417
     *
418
     * @see org.gvsig.fmap.geom.Geometry#getType()
419
     */
420
    @Override
421
    public int getType() {
422
        return this.getGeometryType().getType();
423
    }
424

    
425
    @Override
426
    public Object convertTo(String format) throws GeometryOperationNotSupportedException, GeometryOperationException {
427
        if( StringUtils.isEmpty(format) ) {
428
            throw new IllegalArgumentException("Can't accept null as format name.");
429
        }
430
        format = format.trim().toLowerCase();
431
        switch(format) {
432
            case "jts":
433
                return this.getJTS();
434
            case "wkb":
435
                return this.convertToWKB();
436
            case "hexwkb":
437
                return this.convertToHexWKB();
438
            case "ewkb":
439
                return this.convertToEWKB();
440
            case "wkt":
441
                return this.convertToWKT();
442
            case "gml":
443
                return GMLUtils.geometry2GML(this);
444
            case "json":
445
            case "geojson":
446
                return this.convertToGeoJson();
447
            default:
448
                throw new IllegalArgumentException("Format '"+format+"' not supported");
449
        }
450
        
451
    }
452
    
453
    @Override
454
    public byte[] convertToWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
455
        try {
456
            return new OGCWKBEncoder().encode(this);
457
        } catch (Exception e) {
458
            throw new GeometryOperationException(e);
459
        }
460
    }
461

    
462
    @Override
463
    public String convertToHexWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
464
        try {
465
            byte[] bytes = new OGCWKBEncoder().encode(this);
466
            return Hex.encodeHexString(bytes);
467
        } catch (Exception e) {
468
            throw new GeometryOperationException(e);
469
        }
470
    }
471
    
472
    public String convertToGeoJson() throws GeometryOperationNotSupportedException, GeometryOperationException {
473
        try {
474
            GeoJsonWriter writer = new GeoJsonWriter();
475
            writer.setEncodeCRS(true);
476
            return writer.write(this.getJTS());
477
        } catch (Exception e) {
478
            throw new GeometryOperationException(e);
479
        }
480
    }
481
    
482
    @Override
483
    public String convertToHexEWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
484
        try {
485
            byte[] bytes = new PostGISEWKBEncoder().encode(this);
486
            return Hex.encodeHexString(bytes);
487
        } catch (Exception e) {
488
            throw new GeometryOperationException(e);
489
        }
490
    }
491

    
492
    @Override
493
    public byte[] convertToWKBQuietly() {
494
        try {
495
            return new OGCWKBEncoder().encode(this);
496
        } catch (Exception e) {
497
            return null;
498
        }
499
    }
500
    
501
    @Override
502
    public String convertToHexWKBQuietly() {
503
        try {
504
            byte[] bytes = new OGCWKBEncoder().encode(this);
505
            return Hex.encodeHexString(bytes);
506
        } catch (Exception e) {
507
            return null;
508
        }
509
    }
510
    
511
    @Override
512
    public byte[] convertToWKB(int srs) throws GeometryOperationNotSupportedException, GeometryOperationException {
513
        /*
514
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
515
         */
516

    
517
        try {
518
            return new OGCWKBEncoder().encode(this);
519
        } catch (Exception e) {
520
            throw new GeometryOperationException(e);
521
        }
522
    }
523

    
524
    @Override
525
    public byte[] convertToWKBForcingType(int srs, int type) throws GeometryOperationNotSupportedException,
526
            GeometryOperationException {
527
        /*
528
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
529
         */
530
        Geometry geom = this;
531
        if (this.getType() != type) {
532
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
533
            jts = JTSUtils.convertTypes(jts, this.getType(), type);
534

    
535
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
536
        }
537
        try {
538
            return new OGCWKBEncoder().encode(geom);
539
        } catch (Exception e) {
540
            throw new GeometryOperationException(e);
541
        }
542

    
543
    }
544

    
545
    @Override
546
    public byte[] convertToEWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
547
        try {
548
            return new PostGISEWKBEncoder().encode(this);
549
        } catch (Exception e) {
550
            throw new GeometryOperationException(e);
551
        }
552

    
553
    }
554

    
555
    @Override
556
    public byte[] convertToEWKB(int srs) throws GeometryOperationNotSupportedException, GeometryOperationException {
557
        /*
558
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
559
         */
560

    
561
        try {
562
            return new PostGISEWKBEncoder().encode(this);
563
        } catch (Exception e) {
564
            throw new GeometryOperationException(e);
565
        }
566
    }
567

    
568
    @Override
569
    public byte[] convertToEWKBForcingType(int srs, int type) throws GeometryOperationNotSupportedException,
570
            GeometryOperationException {
571
        /*
572
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
573
         */
574
        Geometry geom = this;
575
        if (this.getType() != type) {
576
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
577
            jts = JTSUtils.convertTypes(jts, this.getType(), type);
578

    
579
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
580
        }
581
        try {
582
            return new PostGISEWKBEncoder().encode(geom);
583
        } catch (Exception e) {
584
            throw new GeometryOperationException(e);
585
        }
586

    
587
    }
588

    
589
    @Override
590
    public String convertToWKT() throws GeometryOperationNotSupportedException, GeometryOperationException {
591
        int subType = getGeometryType().getSubType();
592

    
593
        EWKTWriter writer; // = null;
594

    
595
        switch (subType) {
596
            case Geometry.SUBTYPES.GEOM3D:
597
                writer = new EWKTWriter(3, false);
598
                break;
599
            case Geometry.SUBTYPES.GEOM2DM:
600
                writer = new EWKTWriter(3, true);
601
                break;
602
            case Geometry.SUBTYPES.GEOM3DM:
603
                writer = new EWKTWriter(4, true);
604
                break;
605

    
606
            default:
607
                writer = new EWKTWriter(2, false);
608
                break;
609
        }
610
        com.vividsolutions.jts.geom.Geometry jts = getJTS();
611
        return writer.write(jts);
612
    }
613

    
614
    @Override
615
    public String convertToWKTQuietly() {
616
        try {
617
            return this.convertToWKT();
618
        } catch(Exception ex) {
619
            return null;
620
        }
621
    }
622

    
623
    @Override
624
    public org.gvsig.fmap.geom.Geometry buffer(double distance) throws GeometryOperationNotSupportedException,
625
        GeometryOperationException {
626
        if( distance==0 ) {
627
          return this;
628
        }
629
        return JTSUtils.createGeometry(this.getProjection(), getJTS().buffer(distance));
630
    }
631
    
632
    
633
    @Override
634
    public org.gvsig.fmap.geom.Geometry buffer(double distance, int joinStyle, boolean capButt) throws GeometryOperationNotSupportedException,
635
        GeometryOperationException {
636
        if( distance==0 ) {
637
          return this;
638
        }
639
        
640
        int quadrantSegments = JTSUtils.calculateQuadrantSegments(joinStyle);
641
        
642
        return JTSUtils.createGeometry(this.getProjection(), getJTS().buffer(
643
                distance, 
644
                quadrantSegments, 
645
                capButt ? BufferParameters.CAP_FLAT : BufferParameters.CAP_ROUND
646
        ));
647
    }
648

    
649
    /*
650
     * (non-Javadoc)
651
     *
652
     * @see org.gvsig.fmap.geom.Geometry#snapTo(org.gvsig.fmap.geom.Geometry,
653
     * double)
654
     */
655
    @Override
656
    public org.gvsig.fmap.geom.Geometry snapTo(org.gvsig.fmap.geom.Geometry other, double snapTolerance)
657
            throws GeometryOperationNotSupportedException, GeometryOperationException {
658
        Geometry result; // = null;
659
        GeometrySnapper snapper = new GeometrySnapper(getJTS());
660
        com.vividsolutions.jts.geom.Geometry jts_result = snapper.snapTo(((GeometryJTS) other).getJTS(), snapTolerance);
661
        result = JTSUtils.createGeometry(this.getProjection(), jts_result);
662
        return result;
663
    }
664

    
665
    /*
666
     * (non-Javadoc)
667
     *
668
     * @see org.gvsig.fmap.geom.Geometry#getInteriorPoint()
669
     */
670
    @Override
671
    public Point getInteriorPoint() throws GeometryOperationNotSupportedException, GeometryOperationException {
672

    
673
        com.vividsolutions.jts.geom.Geometry geometry = getJTS();
674
        com.vividsolutions.jts.geom.Point point = geometry.getInteriorPoint();
675
        Geometry result = JTSUtils.createGeometry(this.getProjection(), point);
676
        return (Point) result;
677
    }
678

    
679
    /*
680
     * (non-Javadoc)
681
     *
682
     * @see org.gvsig.fmap.geom.Geometry#isValid()
683
     */
684
    @Override
685
    public boolean isValid() {
686
        return getJTS().isValid();
687
    }
688

    
689
    @Override
690
    public ValidationStatus getValidationStatus() {
691
        DefaultValidationStatus status = new DefaultValidationStatus(ValidationStatus.VALID, null);
692
        com.vividsolutions.jts.geom.Geometry jtsgeom; // = null;
693
        try {
694
            jtsgeom = this.getJTS();
695
            IsValidOp validOp = new IsValidOp(jtsgeom);
696
            if (!validOp.isValid() ) {
697
                status.setValidationError(validOp.getValidationError());
698
            }
699
        } catch (Throwable ex) {
700
            status.setStatusCode(ValidationStatus.CURRUPTED);
701
            status.setMesage("The geometry is corrupted.");
702
            if (this instanceof OrientableSurface) {
703
                int vertices = ((OrientableSurface) this).getNumVertices();
704
                if (vertices < 3) {
705
                    status.setStatusCode(ValidationStatus.TOO_FEW_POINTS);
706
                    status.setMesage(TopologyValidationError.errMsg[TopologyValidationError.TOO_FEW_POINTS]);
707
                }
708
            } else if (this instanceof OrientableCurve) {
709
                int vertices = ((OrientableCurve) this).getNumVertices();
710
                if (vertices < 2) {
711
                    status.setStatusCode(ValidationStatus.TOO_FEW_POINTS);
712
                    status.setMesage(TopologyValidationError.errMsg[TopologyValidationError.TOO_FEW_POINTS]);
713
                }
714
            }
715
        }
716
        return status;
717
    }
718

    
719
    /*
720
     * (non-Javadoc)
721
     *
722
     * @see org.gvsig.fmap.geom.Geometry#makeValid()
723
     */
724
    @Override
725
    public org.gvsig.fmap.geom.Geometry makeValid() {
726
        try {
727
            ValidationStatus vs = this.getValidationStatus();
728
            if (vs.isValid()) {
729
                return this;
730
            }
731
            Geometry g; // = null;
732
            switch (vs.getStatusCode()) {
733
                case Geometry.ValidationStatus.RING_SELF_INTERSECTION:
734
                case Geometry.ValidationStatus.SELF_INTERSECTION:
735
                    g = this.buffer(0);
736
                    if (g.isValid()) {
737
                        return g;
738
                    }
739
                    break;
740

    
741
                case Geometry.ValidationStatus.TOO_FEW_POINTS:
742
                    if (this instanceof OrientableCurve) {
743
                        int vertices = ((OrientableCurve) this).getNumVertices();
744
                        if (vertices < 2) {
745
                            return null; // new
746
                            // DefaultNullGeometry(this.getGeometryType());
747
                        }
748
                    }
749
                    if (this instanceof OrientableSurface) {
750
                        int vertices = ((OrientableSurface) this).getNumVertices();
751
                        if (vertices < 3) {
752
                            return null; // new
753
                            // DefaultNullGeometry(this.getGeometryType());
754
                        }
755
                    }
756
            }
757
        } catch (Exception ex) {
758
            return null;
759
        }
760
        return null;
761
    }
762

    
763
    /*
764
     * (non-Javadoc)
765
     *
766
     * @see org.gvsig.fmap.geom.Geometry#getBounds2D()
767
     */
768
    @Override
769
    public Rectangle2D getBounds2D() {
770
        com.vividsolutions.jts.geom.Envelope envInternal = getJTS().getEnvelopeInternal();
771
        return new Rectangle2D.Double(envInternal.getMinX(), envInternal.getMinY(), envInternal.getWidth(),
772
                envInternal.getHeight());
773
    }
774

    
775
    /*
776
     * (non-Javadoc)
777
     *
778
     * @see java.awt.Shape#getBounds()
779
     */
780
    @Override
781
    public Rectangle getBounds() {
782
        return this.getShape().getBounds();
783
    }
784

    
785
    /*
786
     * (non-Javadoc)
787
     *
788
     * @see org.gvsig.fmap.geom.Geometry#getInternalShape()
789
     */
790
    @Override
791
    public Shape getInternalShape() {
792
        return getShape();
793
    }
794

    
795
    @Override
796
    public void rotate(double radAngle, double basex, double basey) {
797

    
798
        AffineTransform at = new AffineTransform();
799
        at.rotate(radAngle, basex, basey);
800
        this.transform(at);
801
    }
802

    
803
    @Override
804
    public void move(double dx, double dy) {
805

    
806
        AffineTransform at = new AffineTransform();
807
        at.translate(dx, dy);
808
        this.transform(at);
809
    }
810

    
811
    @Override
812
    public void scale(Point basePoint, double sx, double sy) {
813

    
814
        AffineTransform at = new AffineTransform();
815
        at.setToTranslation(basePoint.getX(), basePoint.getY());
816
        at.scale(sx, sy);
817
        at.translate(-basePoint.getX(), -basePoint.getY());
818
        this.transform(at);
819
    }
820

    
821
    @Override
822
    public Geometry[] closestPoints(Geometry other) throws GeometryOperationNotSupportedException,
823
            GeometryOperationException {
824
        Point[] points;
825

    
826
        Coordinate[] jts_points = DistanceOp.nearestPoints(getJTS(), ((GeometryJTS) other).getJTS());
827
        points = new Point[jts_points.length];
828
        for (int i = 0; i < jts_points.length; i++) {
829
            try {
830
                points[i] = JTSUtils.createPoint(this.getGeometryType(), this.getProjection(), jts_points[i]);
831
            } catch (CreateGeometryException e) {
832
                throw new GeometryOperationException(e);
833
            }
834
        }
835

    
836
        return (Geometry[]) points;
837
    }
838

    
839
    @Override
840
    public Geometry convexHull() throws GeometryOperationNotSupportedException, GeometryOperationException {
841
        return JTSUtils.createGeometry(this.getProjection(), getJTS().convexHull(), null);
842
    }
843

    
844
    @Override
845
    public Geometry difference(Geometry other) throws GeometryOperationNotSupportedException,
846
            GeometryOperationException {
847
        return JTSUtils.createGeometry(this.getProjection(), getJTS().difference(((GeometryJTS) other).getJTS()), null);
848
    }
849

    
850
    @Override
851
    public Geometry intersection(Geometry other) throws GeometryOperationNotSupportedException,
852
            GeometryOperationException {
853
        return JTSUtils.createGeometry(this.getProjection(), getJTS().intersection(((GeometryJTS) other).getJTS()), null);
854
    }
855

    
856
    @Override
857
    public Geometry union(Geometry other) throws GeometryOperationNotSupportedException, GeometryOperationException {
858
        return JTSUtils.createGeometry(this.getProjection(), getJTS().union(((GeometryJTS) other).getJTS()), this.getGeometryType());
859
    }
860

    
861
    @Override
862
    public org.gvsig.fmap.geom.primitive.Point centroid() throws GeometryOperationNotSupportedException,
863
            GeometryOperationException {
864
        try {
865
            return JTSUtils.createPoint(this.getGeometryType(), this.getProjection(), getJTS().getCentroid().getCoordinate());
866
        } catch (CreateGeometryException e) {
867
            throw new GeometryOperationException(e);
868
        }
869
    }
870

    
871
    protected void notifyDeprecated(String message) {
872
        LOGGER.info(message);
873

    
874
    }
875

    
876

    
877
    @Override
878
    public boolean ensureOrientation(boolean ccw) throws GeometryOperationNotSupportedException, GeometryOperationException {
879
        if (ccw != isCCW()) {
880
            flip();
881
            return true;
882
        }
883
        return false;
884
    }
885

    
886
    /* (non-Javadoc)
887
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#out(org.gvsig.fmap.geom.Geometry)
888
     */
889
    @Override
890
    public boolean out(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
891
        GeometryJTS otherJtsGeom = (GeometryJTS) geometry;
892
        return (!contains(otherJtsGeom) && !intersects(otherJtsGeom));
893
    }
894

    
895
    /* (non-Javadoc)
896
     * @see java.lang.Object#equals(java.lang.Object)
897
     */
898
    @Override
899
    public boolean equals(Object obj) {
900
        if (obj instanceof GeometryJTS) {
901
            return this.getJTS().equals(((GeometryJTS) obj).getJTS());
902
        }
903
        return false;
904
    }
905

    
906
    @Override
907
    public String toString() {
908
        return this.getGeometryType().getFullName();
909
    }
910

    
911
    @Override
912
    public IProjection getProjection() {
913
        return this.projection;
914
    }
915

    
916
    @Override
917
    public void setProjectionIffNull(IProjection projection) {
918
        if (this.projection == null) {
919
            this.projection = projection;
920
        }
921
    }
922

    
923
    @Override
924
    public void setProjection(IProjection projection) {
925
        this.projection = projection;
926
    }
927

    
928
    @Override
929
    public void setProjection(String projection) {
930
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
931
        this.setProjection(proj);
932
    }
933

    
934
    @Override
935
    @SuppressWarnings("CloneDoesntCallSuperClone")
936
    public Geometry clone() throws CloneNotSupportedException {
937
        return this.cloneGeometry();
938
    }
939

    
940
    @Override
941
    public Geometry boundary() {
942
        return JTSUtils.createGeometry(this.getProjection(), getJTS().getBoundary(), null);
943
    }
944

    
945
    
946
}