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

History | View | Annotate | Download (28.3 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 java.awt.Rectangle;
26
import java.awt.Shape;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.Rectangle2D;
29

    
30
import com.vividsolutions.jts.algorithm.CGAlgorithms;
31
import com.vividsolutions.jts.geom.Coordinate;
32
import com.vividsolutions.jts.operation.distance.DistanceOp;
33
import com.vividsolutions.jts.operation.overlay.snap.GeometrySnapper;
34
import com.vividsolutions.jts.operation.valid.IsValidOp;
35
import com.vividsolutions.jts.operation.valid.TopologyValidationError;
36
import org.apache.commons.codec.binary.Hex;
37
import org.apache.commons.lang3.StringUtils;
38
import org.cresques.cts.IProjection;
39
import org.gvsig.fmap.crs.CRSFactory;
40

    
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44
import org.gvsig.fmap.geom.Geometry;
45
import org.gvsig.fmap.geom.GeometryLocator;
46
import org.gvsig.fmap.geom.GeometryManager;
47
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48
import org.gvsig.fmap.geom.jts.operation.towkb.OGCWKBEncoder;
49
import org.gvsig.fmap.geom.jts.operation.towkb.PostGISEWKBEncoder;
50
import org.gvsig.fmap.geom.jts.operation.towkt.EWKTWriter;
51
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
import org.gvsig.fmap.geom.jts.util.GMLUtils;
55
import org.gvsig.fmap.geom.jts.util.JTSUtils;
56
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
57
import org.gvsig.fmap.geom.operation.GeometryOperationException;
58
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
59
import org.gvsig.fmap.geom.primitive.Envelope;
60
import org.gvsig.fmap.geom.primitive.OrientableCurve;
61
import org.gvsig.fmap.geom.primitive.OrientableSurface;
62
import org.gvsig.fmap.geom.primitive.Point;
63
import org.gvsig.fmap.geom.type.GeometryType;
64

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

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

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

    
79
    private final GeometryType geometryType;
80

    
81
    private IProjection projection;
82

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

    
95
    public GeometryType getGeometryType() {
96
        return geometryType;
97
    }
98

    
99
    protected GeometryManager getManager() {
100
        return GeometryLocator.getGeometryManager();
101
    }
102

    
103
    /*
104
     * (non-Javadoc)
105
     *
106
     * @see org.gvsig.fmap.geom.Geometry#contains(org.gvsig.fmap.geom.Geometry)
107
     */
108
    public boolean contains(Geometry geometry) throws GeometryOperationNotSupportedException,
109
            GeometryOperationException {
110
        if (!(geometry instanceof GeometryJTS)) {
111
            return false;
112
        }
113
        return getJTS().contains(((GeometryJTS) geometry).getJTS());
114
    }
115

    
116
    /*
117
     * (non-Javadoc)
118
     *
119
     * @see java.lang.Comparable#compareTo(java.lang.Object)
120
     */
121
    public int compareTo(Object o) {
122
        return getJTS().compareTo(((GeometryJTS) o).getJTS());
123
    }
124

    
125
    /*
126
     * (non-Javadoc)
127
     *
128
     * @see java.awt.Shape#contains(double, double)
129
     */
130
    public boolean contains(double x, double y) {
131
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
132
        Shape shp = getShape();
133
        return shp.contains(x, y);
134
    }
135

    
136
    /*
137
     * (non-Javadoc)
138
     *
139
     * @see java.awt.Shape#intersects(double, double, double, double)
140
     */
141
    public boolean intersects(double x, double y, double w, double h) {
142

    
143
        notifyDeprecated("Calling deprecated method of geometry intersects from shape interface");
144
        Shape shp = this.getShape();
145
        return shp.intersects(x, y, w, h);
146
    }
147

    
148
    /*
149
     * (non-Javadoc)
150
     *
151
     * @see java.awt.Shape#contains(double, double, double, double)
152
     */
153
    public boolean contains(double x, double y, double w, double h) {
154
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
155
        Shape shp = this.getShape();
156
        return shp.contains(x, y, w, h);
157
    }
158

    
159
    /*
160
     * (non-Javadoc)
161
     *
162
     * @see java.awt.Shape#contains(java.awt.geom.Point2D)
163
     */
164
    public boolean contains(java.awt.geom.Point2D p) {
165
        notifyDeprecated("Calling deprecated method of geometry contains from shape interface");
166
        Shape shp = this.getShape();
167
        return shp.contains(p);
168
    }
169

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

    
181
    /*
182
     * (non-Javadoc)
183
     *
184
     * @see org.gvsig.fmap.geom.Geometry#distance(org.gvsig.fmap.geom.Geometry)
185
     */
186
    public double distance(org.gvsig.fmap.geom.Geometry other) throws GeometryOperationNotSupportedException,
187
            GeometryOperationException {
188
        return getJTS().distance(((GeometryJTS) other).getJTS());
189
    }
190

    
191
    /*
192
     * (non-Javadoc)
193
     *
194
     * @see
195
     * org.gvsig.fmap.geom.Geometry#isWithinDistance(org.gvsig.fmap.geom.Geometry
196
     * , double)
197
     */
198
    public boolean isWithinDistance(org.gvsig.fmap.geom.Geometry other, double distance)
199
            throws GeometryOperationNotSupportedException, GeometryOperationException {
200
        return com.vividsolutions.jts.operation.distance.DistanceOp.isWithinDistance(this.getJTS(),
201
                ((GeometryJTS) other).getJTS(), distance);
202
    }
203

    
204
    /*
205
     * (non-Javadoc)
206
     *
207
     * @see org.gvsig.fmap.geom.Geometry#overlaps(org.gvsig.fmap.geom.Geometry)
208
     */
209
    public boolean overlaps(org.gvsig.fmap.geom.Geometry geometry) throws GeometryOperationNotSupportedException,
210
            GeometryOperationException {
211
        // TODO: this method can be implemented throw invokeOperation
212
        return getJTS().overlaps(((GeometryJTS) geometry).getJTS());
213
    }
214

    
215
    public boolean coveredBy(Geometry geometry) throws GeometryOperationNotSupportedException,
216
            GeometryOperationException {
217

    
218
        return getJTS().coveredBy(((GeometryJTS) geometry).getJTS());
219
    }
220

    
221
    public boolean covers(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
222
        // TODO: this method can be implemented throw invokeOperation
223
        return getJTS().covers(((GeometryJTS) geometry).getJTS());
224

    
225
    }
226

    
227
    public boolean crosses(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
228
        // TODO: this method can be implemented throw invokeOperation
229
        return getJTS().crosses(((GeometryJTS) geometry).getJTS());
230
    }
231

    
232
    public boolean intersects(Geometry geometry) throws GeometryOperationNotSupportedException,
233
            GeometryOperationException {
234
        return getJTS().intersects(((GeometryJTS) geometry).getJTS());
235
    }
236

    
237
    public boolean touches(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
238
        // TODO: this method can be implemented throw invokeOperation
239
        return getJTS().touches(((GeometryJTS) geometry).getJTS());
240
    }
241

    
242
    public boolean disjoint(Geometry geometry) throws GeometryOperationNotSupportedException,
243
            GeometryOperationException {
244
        // TODO: this method can be implemented throw invokeOperation
245
        return getJTS().disjoint(((GeometryJTS) geometry).getJTS());
246
    }
247

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

    
253
    public double area() throws GeometryOperationNotSupportedException, GeometryOperationException {
254
        return getJTS().getArea();
255
    }
256

    
257
    public double perimeter() throws GeometryOperationNotSupportedException, GeometryOperationException {
258
        return getJTS().getLength();
259
    }
260

    
261
    /*
262
     * (non-Javadoc)
263
     *
264
     * @see org.gvsig.fmap.geom.Geometry#intersects(java.awt.geom.Rectangle2D)
265
     */
266
    public boolean intersects(Rectangle2D r) {
267
        double x = r.getMinX();
268
        double y = r.getMinY();
269
        double w = r.getWidth();
270
        double h = r.getHeight();
271

    
272
        return fastIntersects(x, y, w, h);
273
    }
274

    
275
    /*
276
     * (non-Javadoc)
277
     *
278
     * @see org.gvsig.fmap.geom.Geometry#fastIntersects(double, double, double,
279
     * double)
280
     */
281
    public boolean fastIntersects(double x, double y, double w, double h) {
282
        com.vividsolutions.jts.geom.Geometry rect = null;
283
        com.vividsolutions.jts.geom.Coordinate[] coord = new com.vividsolutions.jts.geom.Coordinate[5];
284
        coord[0] = new com.vividsolutions.jts.geom.Coordinate(x, y);
285
        coord[1] = new com.vividsolutions.jts.geom.Coordinate(x + w, y);
286
        coord[2] = new com.vividsolutions.jts.geom.Coordinate(x + w, y + w);
287
        coord[3] = new com.vividsolutions.jts.geom.Coordinate(x, y + w);
288
        coord[4] = new com.vividsolutions.jts.geom.Coordinate(x, y);
289
        rect = JTSUtils.createJTSPolygon(coord);
290

    
291
        return getJTS().intersects(rect);
292
    }
293

    
294
    /*
295
     * (non-Javadoc)
296
     *
297
     * @see org.gvsig.fmap.geom.Geometry#getEnvelope()
298
     */
299
    public Envelope getEnvelope() {
300
        if (is3D()) {
301
            Coordinate[] coordinates = getJTS().getCoordinates();
302

    
303
            double minx = Double.POSITIVE_INFINITY;
304
            double miny = Double.POSITIVE_INFINITY;
305
            double minz = Double.POSITIVE_INFINITY;
306

    
307
            double maxx = Double.NEGATIVE_INFINITY;
308
            double maxy = Double.NEGATIVE_INFINITY;
309
            double maxz = Double.NEGATIVE_INFINITY;
310

    
311
            double x;
312
            double y;
313
            double z;
314

    
315
            for (int i = 0; i < coordinates.length; i++) {
316
                x = coordinates[i].x;
317
                y = coordinates[i].y;
318
                z = coordinates[i].z;
319
                minx = Math.min(x, minx);
320
                miny = Math.min(y, miny);
321
                minz = Math.min(z, minz);
322
                maxx = Math.max(x, maxx);
323
                maxy = Math.max(y, maxy);
324
                maxz = Math.max(z, maxz);
325
            }
326

    
327
            if (minx <= maxx && miny <= maxy && minz <= maxz) {
328
                Point min = new Point3D(minx, miny, minz);
329
                Point max = new Point3D(maxx, maxy, maxz);
330
                return new Envelope3D(min, max);
331
            }
332
            return new Envelope3D();
333
        } else {
334
            com.vividsolutions.jts.geom.Envelope envelope = getJTS().getEnvelopeInternal();
335
            return new Envelope2D(envelope);
336
        }
337
    }
338

    
339
    /*
340
     * (non-Javadoc)
341
     *
342
     * @see org.gvsig.fmap.geom.Geometry#isSimple()
343
     */
344
    public boolean isSimple() {
345
        return this.getJTS().isSimple();
346
    }
347

    
348
    /*
349
     * (non-Javadoc)
350
     *
351
     * @see org.gvsig.fmap.geom.Geometry#isCCW()
352
     */
353
    public boolean isCCW() throws GeometryOperationNotSupportedException, GeometryOperationException {
354
        return CGAlgorithms.isCCW(this.getJTS().getCoordinates());
355
    }
356

    
357
    /*
358
     * (non-Javadoc)
359
     *
360
     * @see org.gvsig.fmap.geom.Geometry#invokeOperation(int,
361
     * org.gvsig.fmap.geom.operation.GeometryOperationContext)
362
     */
363
    public Object invokeOperation(int index, GeometryOperationContext ctx)
364
            throws GeometryOperationNotSupportedException, GeometryOperationException {
365
        return getManager().invokeOperation(index, this, ctx);
366

    
367
    }
368

    
369
    /*
370
     * (non-Javadoc)
371
     *
372
     * @see org.gvsig.fmap.geom.Geometry#invokeOperation(java.lang.String,
373
     * org.gvsig.fmap.geom.operation.GeometryOperationContext)
374
     */
375
    public Object invokeOperation(String opName, GeometryOperationContext ctx)
376
            throws GeometryOperationNotSupportedException, GeometryOperationException {
377
        return getManager().invokeOperation(opName, this, ctx);
378

    
379
    }
380

    
381
    /*
382
     * (non-Javadoc)
383
     *
384
     * @see org.gvsig.fmap.geom.Geometry#getType()
385
     */
386
    public int getType() {
387
        return this.getGeometryType().getType();
388
    }
389

    
390
    @Override
391
    public Object convertTo(String format) throws GeometryOperationNotSupportedException, GeometryOperationException {
392
        if( StringUtils.isEmpty(format) ) {
393
            throw new IllegalArgumentException("Can't accept null as format name.");
394
        }
395
        format = format.trim().toLowerCase();
396
        switch(format) {
397
            case "jts":
398
                return this.getJTS();
399
            case "wkb":
400
                return this.convertToWKB();
401
            case "hexwkb":
402
                return this.convertToHexWKB();
403
            case "ewkb":
404
                return this.convertToEWKB();
405
            case "wkt":
406
                return this.convertToWKT();
407
            case "gml":
408
                return GMLUtils.geometry2GML(this);
409
            case "json":
410
            case "geojson":
411
            default:
412
                throw new IllegalArgumentException("Format '"+format+"' not supported");
413
        }
414
        
415
    }
416
    
417
    @Override
418
    public byte[] convertToWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
419
        try {
420
            return new OGCWKBEncoder().encode(this);
421
        } catch (Exception e) {
422
            throw new GeometryOperationException(e);
423
        }
424
    }
425

    
426
    @Override
427
    public String convertToHexWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
428
        try {
429
            byte[] bytes = new OGCWKBEncoder().encode(this);
430
            return Hex.encodeHexString(bytes);
431
        } catch (Exception e) {
432
            throw new GeometryOperationException(e);
433
        }
434
    }
435

    
436
    @Override
437
    public byte[] convertToWKBQuietly() {
438
        try {
439
            return new OGCWKBEncoder().encode(this);
440
        } catch (Exception e) {
441
            return null;
442
        }
443
    }
444
    
445
    @Override
446
    public String convertToHexWKBQuietly() {
447
        try {
448
            byte[] bytes = new OGCWKBEncoder().encode(this);
449
            return Hex.encodeHexString(bytes);
450
        } catch (Exception e) {
451
            return null;
452
        }
453
    }
454
    
455
    @Override
456
    public byte[] convertToWKB(int srs) throws GeometryOperationNotSupportedException, GeometryOperationException {
457
        /*
458
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
459
         */
460

    
461
        try {
462
            return new OGCWKBEncoder().encode(this);
463
        } catch (Exception e) {
464
            throw new GeometryOperationException(e);
465
        }
466
    }
467

    
468
    @Override
469
    public byte[] convertToWKBForcingType(int srs, int type) throws GeometryOperationNotSupportedException,
470
            GeometryOperationException {
471
        /*
472
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
473
         */
474
        Geometry geom = this;
475
        if (this.getType() != type) {
476
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
477
            jts = JTSUtils.convertTypes(jts, this.getType(), type);
478

    
479
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
480
        }
481
        try {
482
            return new OGCWKBEncoder().encode(geom);
483
        } catch (Exception e) {
484
            throw new GeometryOperationException(e);
485
        }
486

    
487
    }
488

    
489
    public byte[] convertToEWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
490
        try {
491
            return new PostGISEWKBEncoder().encode(this);
492
        } catch (Exception e) {
493
            throw new GeometryOperationException(e);
494
        }
495

    
496
    }
497

    
498
    public byte[] convertToEWKB(int srs) throws GeometryOperationNotSupportedException, GeometryOperationException {
499
        /*
500
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
501
         */
502

    
503
        try {
504
            return new PostGISEWKBEncoder().encode(this);
505
        } catch (Exception e) {
506
            throw new GeometryOperationException(e);
507
        }
508
    }
509

    
510
    public byte[] convertToEWKBForcingType(int srs, int type) throws GeometryOperationNotSupportedException,
511
            GeometryOperationException {
512
        /*
513
             * No se sabe si la especificaci?n de OGC soporta SRS. OGCWKBEncoder no.
514
         */
515
        Geometry geom = this;
516
        if (this.getType() != type) {
517
            com.vividsolutions.jts.geom.Geometry jts = getJTS();
518
            jts = JTSUtils.convertTypes(jts, this.getType(), type);
519

    
520
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
521
        }
522
        try {
523
            return new PostGISEWKBEncoder().encode(geom);
524
        } catch (Exception e) {
525
            throw new GeometryOperationException(e);
526
        }
527

    
528
    }
529

    
530
    @Override
531
    public String convertToWKT() throws GeometryOperationNotSupportedException, GeometryOperationException {
532
        int subType = getGeometryType().getSubType();
533

    
534
        EWKTWriter writer = null;
535

    
536
        switch (subType) {
537
            case Geometry.SUBTYPES.GEOM3D:
538
                writer = new EWKTWriter(3, false);
539
                break;
540
            case Geometry.SUBTYPES.GEOM2DM:
541
                writer = new EWKTWriter(3, true);
542
                break;
543
            case Geometry.SUBTYPES.GEOM3DM:
544
                writer = new EWKTWriter(4, true);
545
                break;
546

    
547
            default:
548
                writer = new EWKTWriter(2, false);
549
                break;
550
        }
551
        com.vividsolutions.jts.geom.Geometry jts = getJTS();
552
        return writer.write(jts);
553
    }
554

    
555
    @Override
556
    public String convertToWKTQuietly() {
557
        try {
558
            return this.convertToWKT();
559
        } catch(Exception ex) {
560
            return null;
561
        }
562
    }
563

    
564
    @Override
565
    public org.gvsig.fmap.geom.Geometry buffer(double distance) throws GeometryOperationNotSupportedException,
566
        GeometryOperationException {
567
        if( distance==0 ) {
568
          return this;
569
        }
570
        return JTSUtils.createGeometry(this.getProjection(), getJTS().buffer(distance));
571
    }
572

    
573
    /*
574
     * (non-Javadoc)
575
     *
576
     * @see org.gvsig.fmap.geom.Geometry#snapTo(org.gvsig.fmap.geom.Geometry,
577
     * double)
578
     */
579
    public org.gvsig.fmap.geom.Geometry snapTo(org.gvsig.fmap.geom.Geometry other, double snapTolerance)
580
            throws GeometryOperationNotSupportedException, GeometryOperationException {
581
        Geometry result = null;
582
        GeometrySnapper snapper = new GeometrySnapper(getJTS());
583
        com.vividsolutions.jts.geom.Geometry jts_result = snapper.snapTo(((GeometryJTS) other).getJTS(), snapTolerance);
584
        result = JTSUtils.createGeometry(this.getProjection(), jts_result);
585
        return result;
586
    }
587

    
588
    /*
589
     * (non-Javadoc)
590
     *
591
     * @see org.gvsig.fmap.geom.Geometry#getInteriorPoint()
592
     */
593
    public Point getInteriorPoint() throws GeometryOperationNotSupportedException, GeometryOperationException {
594

    
595
        com.vividsolutions.jts.geom.Geometry geometry = getJTS();
596
        com.vividsolutions.jts.geom.Point point = geometry.getInteriorPoint();
597
        Geometry result = JTSUtils.createGeometry(this.getProjection(), point);
598
        return (Point) result;
599
    }
600

    
601
    /*
602
     * (non-Javadoc)
603
     *
604
     * @see org.gvsig.fmap.geom.Geometry#isValid()
605
     */
606
    public boolean isValid() {
607
        return getJTS().isValid();
608
    }
609

    
610
    @Override
611
    public ValidationStatus getValidationStatus() {
612
        DefaultValidationStatus status = new DefaultValidationStatus(ValidationStatus.VALID, null);
613
        com.vividsolutions.jts.geom.Geometry jtsgeom = null;
614
        try {
615
            jtsgeom = this.getJTS();
616
            IsValidOp validOp = new IsValidOp(jtsgeom);
617
            if (!validOp.isValid() ) {
618
                status.setValidationError(validOp.getValidationError());
619
            }
620
        } catch (Exception ex) {
621
            status.setStatusCode(ValidationStatus.CURRUPTED);
622
            status.setMesage("The geometry is corrupted.");
623
            if (this instanceof OrientableSurface) {
624
                int vertices = ((OrientableSurface) this).getNumVertices();
625
                if (vertices < 3) {
626
                    status.setStatusCode(ValidationStatus.TOO_FEW_POINTS);
627
                    status.setMesage(TopologyValidationError.errMsg[TopologyValidationError.TOO_FEW_POINTS]);
628
                }
629
            } else if (this instanceof OrientableCurve) {
630
                int vertices = ((OrientableCurve) this).getNumVertices();
631
                if (vertices < 2) {
632
                    status.setStatusCode(ValidationStatus.TOO_FEW_POINTS);
633
                    status.setMesage(TopologyValidationError.errMsg[TopologyValidationError.TOO_FEW_POINTS]);
634
                }
635
            }
636
        }
637
        return status;
638
    }
639

    
640
    /*
641
     * (non-Javadoc)
642
     *
643
     * @see org.gvsig.fmap.geom.Geometry#makeValid()
644
     */
645
    public org.gvsig.fmap.geom.Geometry makeValid() {
646
        try {
647
            ValidationStatus vs = this.getValidationStatus();
648
            if (vs.isValid()) {
649
                return this;
650
            }
651
            Geometry g = null;
652
            switch (vs.getStatusCode()) {
653
                case Geometry.ValidationStatus.RING_SELF_INTERSECTION:
654
                case Geometry.ValidationStatus.SELF_INTERSECTION:
655
                    g = this.buffer(0);
656
                    if (g.isValid()) {
657
                        return g;
658
                    }
659
                    break;
660

    
661
                case Geometry.ValidationStatus.TOO_FEW_POINTS:
662
                    if (this instanceof OrientableCurve) {
663
                        int vertices = ((OrientableCurve) this).getNumVertices();
664
                        if (vertices < 2) {
665
                            return null; // new
666
                            // DefaultNullGeometry(this.getGeometryType());
667
                        }
668
                    }
669
                    if (this instanceof OrientableSurface) {
670
                        int vertices = ((OrientableSurface) this).getNumVertices();
671
                        if (vertices < 3) {
672
                            return null; // new
673
                            // DefaultNullGeometry(this.getGeometryType());
674
                        }
675
                    }
676
            }
677
        } catch (Exception ex) {
678
            return null;
679
        }
680
        return null;
681
    }
682

    
683
    /*
684
     * (non-Javadoc)
685
     *
686
     * @see org.gvsig.fmap.geom.Geometry#getBounds2D()
687
     */
688
    public Rectangle2D getBounds2D() {
689
        com.vividsolutions.jts.geom.Envelope envInternal = getJTS().getEnvelopeInternal();
690
        return new Rectangle2D.Double(envInternal.getMinX(), envInternal.getMinY(), envInternal.getWidth(),
691
                envInternal.getHeight());
692
    }
693

    
694
    /*
695
     * (non-Javadoc)
696
     *
697
     * @see java.awt.Shape#getBounds()
698
     */
699
    public Rectangle getBounds() {
700
        return this.getShape().getBounds();
701
    }
702

    
703
    /*
704
     * (non-Javadoc)
705
     *
706
     * @see org.gvsig.fmap.geom.Geometry#getInternalShape()
707
     */
708
    public Shape getInternalShape() {
709
        return getShape();
710
    }
711

    
712
    public void rotate(double radAngle, double basex, double basey) {
713

    
714
        AffineTransform at = new AffineTransform();
715
        at.rotate(radAngle, basex, basey);
716
        this.transform(at);
717
    }
718

    
719
    public void move(double dx, double dy) {
720

    
721
        AffineTransform at = new AffineTransform();
722
        at.translate(dx, dy);
723
        this.transform(at);
724
    }
725

    
726
    public void scale(Point basePoint, double sx, double sy) {
727

    
728
        AffineTransform at = new AffineTransform();
729
        at.setToTranslation(basePoint.getX(), basePoint.getY());
730
        at.scale(sx, sy);
731
        at.translate(-basePoint.getX(), -basePoint.getY());
732
        this.transform(at);
733
    }
734

    
735
    public Geometry[] closestPoints(Geometry other) throws GeometryOperationNotSupportedException,
736
            GeometryOperationException {
737
        Point[] points = null;
738

    
739
        Coordinate[] jts_points = DistanceOp.nearestPoints(getJTS(), ((GeometryJTS) other).getJTS());
740
        points = new Point[jts_points.length];
741
        for (int i = 0; i < jts_points.length; i++) {
742
            try {
743
                points[i] = JTSUtils.createPoint(this.getGeometryType(), this.getProjection(), jts_points[i]);
744
            } catch (CreateGeometryException e) {
745
                throw new GeometryOperationException(e);
746
            }
747
        }
748

    
749
        return (Geometry[]) points;
750
    }
751

    
752
    public Geometry convexHull() throws GeometryOperationNotSupportedException, GeometryOperationException {
753

    
754
        return JTSUtils.createGeometry(this.getProjection(), getJTS().convexHull());
755
    }
756

    
757
    public Geometry difference(Geometry other) throws GeometryOperationNotSupportedException,
758
            GeometryOperationException {
759
        return JTSUtils.createGeometry(this.getProjection(), getJTS().difference(((GeometryJTS) other).getJTS()));
760
    }
761

    
762
    public Geometry intersection(Geometry other) throws GeometryOperationNotSupportedException,
763
            GeometryOperationException {
764
        return JTSUtils.createGeometry(this.getProjection(), getJTS().intersection(((GeometryJTS) other).getJTS()));
765
    }
766

    
767
    public Geometry union(Geometry other) throws GeometryOperationNotSupportedException, GeometryOperationException {
768
        return JTSUtils.createGeometry(this.getProjection(), getJTS().union(((GeometryJTS) other).getJTS()));
769
    }
770

    
771
    public org.gvsig.fmap.geom.primitive.Point centroid() throws GeometryOperationNotSupportedException,
772
            GeometryOperationException {
773
        try {
774
            return JTSUtils.createPoint(this.getGeometryType(), this.getProjection(), getJTS().getCentroid().getCoordinate());
775
        } catch (CreateGeometryException e) {
776
            throw new GeometryOperationException(e);
777
        }
778
    }
779

    
780
    protected void notifyDeprecated(String message) {
781
        LOGGER.info(message);
782

    
783
    }
784

    
785

    
786
    /* (non-Javadoc)
787
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#ensureOrientation(boolean)
788
     */
789
    public boolean ensureOrientation(boolean ccw) throws GeometryOperationNotSupportedException, GeometryOperationException {
790
        if (ccw != isCCW()) {
791
            flip();
792
            return true;
793
        }
794
        return false;
795
    }
796

    
797
    /* (non-Javadoc)
798
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#out(org.gvsig.fmap.geom.Geometry)
799
     */
800
    public boolean out(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
801
        GeometryJTS otherJtsGeom = (GeometryJTS) geometry;
802
        return (!contains(otherJtsGeom) && !intersects(otherJtsGeom));
803
    }
804

    
805
    /* (non-Javadoc)
806
     * @see java.lang.Object#equals(java.lang.Object)
807
     */
808
    @Override
809
    public boolean equals(Object obj) {
810
        if (obj instanceof GeometryJTS) {
811
            return this.getJTS().equals(((GeometryJTS) obj).getJTS());
812
        }
813
        return false;
814
    }
815

    
816
    public String toString() {
817
        return this.getGeometryType().getFullName();
818
    }
819

    
820
    @Override
821
    public IProjection getProjection() {
822
        return this.projection;
823
    }
824

    
825
    @Override
826
    public void setProjectionIffNull(IProjection projection) {
827
        if (this.projection == null) {
828
            this.projection = projection;
829
        }
830
    }
831

    
832
    @Override
833
    public void setProjection(IProjection projection) {
834
        this.projection = projection;
835
    }
836

    
837
    @Override
838
    public void setProjection(String projection) {
839
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
840
        this.setProjection(proj);
841
    }
842

    
843
    @Override
844
    @SuppressWarnings("CloneDoesntCallSuperClone")
845
    public Geometry clone() throws CloneNotSupportedException {
846
        return this.cloneGeometry();
847
    }
848

    
849
}