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

History | View | Annotate | Download (28.4 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 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 void setGeometryType(GeometryType geometryType) {
96
        this.geometryType = geometryType;
97
    }
98

    
99
    public GeometryType getGeometryType() {
100
        return geometryType;
101
    }
102

    
103
    protected GeometryManager getManager() {
104
        return GeometryLocator.getGeometryManager();
105
    }
106

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

    
120
    /*
121
     * (non-Javadoc)
122
     *
123
     * @see java.lang.Comparable#compareTo(java.lang.Object)
124
     */
125
    public int compareTo(Object o) {
126
        return getJTS().compareTo(((GeometryJTS) o).getJTS());
127
    }
128

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

    
140
    /*
141
     * (non-Javadoc)
142
     *
143
     * @see java.awt.Shape#intersects(double, double, double, double)
144
     */
145
    public boolean intersects(double x, double y, double w, double h) {
146

    
147
        notifyDeprecated("Calling deprecated method of geometry intersects from shape interface");
148
        Shape shp = this.getShape();
149
        return shp.intersects(x, y, w, h);
150
    }
151

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

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

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

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

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

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

    
219
    public boolean coveredBy(Geometry geometry) throws GeometryOperationNotSupportedException,
220
            GeometryOperationException {
221

    
222
        return getJTS().coveredBy(((GeometryJTS) geometry).getJTS());
223
    }
224

    
225
    public boolean covers(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
226
        // TODO: this method can be implemented throw invokeOperation
227
        return getJTS().covers(((GeometryJTS) geometry).getJTS());
228

    
229
    }
230

    
231
    public boolean crosses(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
232
        // TODO: this method can be implemented throw invokeOperation
233
        return getJTS().crosses(((GeometryJTS) geometry).getJTS());
234
    }
235

    
236
    public boolean intersects(Geometry geometry) throws GeometryOperationNotSupportedException,
237
            GeometryOperationException {
238
        return getJTS().intersects(((GeometryJTS) geometry).getJTS());
239
    }
240

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

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

    
252
    public boolean within(Geometry geometry) throws GeometryOperationNotSupportedException, GeometryOperationException {
253
        // TODO: this method can be implemented throw invokeOperation
254
        return getJTS().within(((GeometryJTS) geometry).getJTS());
255
    }
256

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

    
261
    public double perimeter() throws GeometryOperationNotSupportedException, GeometryOperationException {
262
        return getJTS().getLength();
263
    }
264

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

    
276
        return fastIntersects(x, y, w, h);
277
    }
278

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

    
295
        return getJTS().intersects(rect);
296
    }
297

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

    
307
            double minx = Double.POSITIVE_INFINITY;
308
            double miny = Double.POSITIVE_INFINITY;
309
            double minz = Double.POSITIVE_INFINITY;
310

    
311
            double maxx = Double.NEGATIVE_INFINITY;
312
            double maxy = Double.NEGATIVE_INFINITY;
313
            double maxz = Double.NEGATIVE_INFINITY;
314

    
315
            double x;
316
            double y;
317
            double z;
318

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

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

    
343
    /*
344
     * (non-Javadoc)
345
     *
346
     * @see org.gvsig.fmap.geom.Geometry#isSimple()
347
     */
348
    public boolean isSimple() {
349
        return this.getJTS().isSimple();
350
    }
351

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

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

    
371
    }
372

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

    
383
    }
384

    
385
    /*
386
     * (non-Javadoc)
387
     *
388
     * @see org.gvsig.fmap.geom.Geometry#getType()
389
     */
390
    public int getType() {
391
        return this.getGeometryType().getType();
392
    }
393

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

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

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

    
465
        try {
466
            return new OGCWKBEncoder().encode(this);
467
        } catch (Exception e) {
468
            throw new GeometryOperationException(e);
469
        }
470
    }
471

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

    
483
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
484
        }
485
        try {
486
            return new OGCWKBEncoder().encode(geom);
487
        } catch (Exception e) {
488
            throw new GeometryOperationException(e);
489
        }
490

    
491
    }
492

    
493
    public byte[] convertToEWKB() throws GeometryOperationNotSupportedException, GeometryOperationException {
494
        try {
495
            return new PostGISEWKBEncoder().encode(this);
496
        } catch (Exception e) {
497
            throw new GeometryOperationException(e);
498
        }
499

    
500
    }
501

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

    
507
        try {
508
            return new PostGISEWKBEncoder().encode(this);
509
        } catch (Exception e) {
510
            throw new GeometryOperationException(e);
511
        }
512
    }
513

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

    
524
            geom = JTSUtils.createGeometry(this.getProjection(), jts);
525
        }
526
        try {
527
            return new PostGISEWKBEncoder().encode(geom);
528
        } catch (Exception e) {
529
            throw new GeometryOperationException(e);
530
        }
531

    
532
    }
533

    
534
    @Override
535
    public String convertToWKT() throws GeometryOperationNotSupportedException, GeometryOperationException {
536
        int subType = getGeometryType().getSubType();
537

    
538
        EWKTWriter writer = null;
539

    
540
        switch (subType) {
541
            case Geometry.SUBTYPES.GEOM3D:
542
                writer = new EWKTWriter(3, false);
543
                break;
544
            case Geometry.SUBTYPES.GEOM2DM:
545
                writer = new EWKTWriter(3, true);
546
                break;
547
            case Geometry.SUBTYPES.GEOM3DM:
548
                writer = new EWKTWriter(4, true);
549
                break;
550

    
551
            default:
552
                writer = new EWKTWriter(2, false);
553
                break;
554
        }
555
        com.vividsolutions.jts.geom.Geometry jts = getJTS();
556
        return writer.write(jts);
557
    }
558

    
559
    @Override
560
    public String convertToWKTQuietly() {
561
        try {
562
            return this.convertToWKT();
563
        } catch(Exception ex) {
564
            return null;
565
        }
566
    }
567

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

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

    
592
    /*
593
     * (non-Javadoc)
594
     *
595
     * @see org.gvsig.fmap.geom.Geometry#getInteriorPoint()
596
     */
597
    public Point getInteriorPoint() throws GeometryOperationNotSupportedException, GeometryOperationException {
598

    
599
        com.vividsolutions.jts.geom.Geometry geometry = getJTS();
600
        com.vividsolutions.jts.geom.Point point = geometry.getInteriorPoint();
601
        Geometry result = JTSUtils.createGeometry(this.getProjection(), point);
602
        return (Point) result;
603
    }
604

    
605
    /*
606
     * (non-Javadoc)
607
     *
608
     * @see org.gvsig.fmap.geom.Geometry#isValid()
609
     */
610
    public boolean isValid() {
611
        return getJTS().isValid();
612
    }
613

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

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

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

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

    
698
    /*
699
     * (non-Javadoc)
700
     *
701
     * @see java.awt.Shape#getBounds()
702
     */
703
    public Rectangle getBounds() {
704
        return this.getShape().getBounds();
705
    }
706

    
707
    /*
708
     * (non-Javadoc)
709
     *
710
     * @see org.gvsig.fmap.geom.Geometry#getInternalShape()
711
     */
712
    public Shape getInternalShape() {
713
        return getShape();
714
    }
715

    
716
    public void rotate(double radAngle, double basex, double basey) {
717

    
718
        AffineTransform at = new AffineTransform();
719
        at.rotate(radAngle, basex, basey);
720
        this.transform(at);
721
    }
722

    
723
    public void move(double dx, double dy) {
724

    
725
        AffineTransform at = new AffineTransform();
726
        at.translate(dx, dy);
727
        this.transform(at);
728
    }
729

    
730
    public void scale(Point basePoint, double sx, double sy) {
731

    
732
        AffineTransform at = new AffineTransform();
733
        at.setToTranslation(basePoint.getX(), basePoint.getY());
734
        at.scale(sx, sy);
735
        at.translate(-basePoint.getX(), -basePoint.getY());
736
        this.transform(at);
737
    }
738

    
739
    public Geometry[] closestPoints(Geometry other) throws GeometryOperationNotSupportedException,
740
            GeometryOperationException {
741
        Point[] points = null;
742

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

    
753
        return (Geometry[]) points;
754
    }
755

    
756
    public Geometry convexHull() throws GeometryOperationNotSupportedException, GeometryOperationException {
757

    
758
        return JTSUtils.createGeometry(this.getProjection(), getJTS().convexHull());
759
    }
760

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

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

    
771
    public Geometry union(Geometry other) throws GeometryOperationNotSupportedException, GeometryOperationException {
772
        return JTSUtils.createGeometry(this.getProjection(), getJTS().union(((GeometryJTS) other).getJTS()));
773
    }
774

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

    
784
    protected void notifyDeprecated(String message) {
785
        LOGGER.info(message);
786

    
787
    }
788

    
789

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

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

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

    
820
    public String toString() {
821
        return this.getGeometryType().getFullName();
822
    }
823

    
824
    @Override
825
    public IProjection getProjection() {
826
        return this.projection;
827
    }
828

    
829
    @Override
830
    public void setProjectionIffNull(IProjection projection) {
831
        if (this.projection == null) {
832
            this.projection = projection;
833
        }
834
    }
835

    
836
    @Override
837
    public void setProjection(IProjection projection) {
838
        this.projection = projection;
839
    }
840

    
841
    @Override
842
    public void setProjection(String projection) {
843
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
844
        this.setProjection(proj);
845
    }
846

    
847
    @Override
848
    @SuppressWarnings("CloneDoesntCallSuperClone")
849
    public Geometry clone() throws CloneNotSupportedException {
850
        return this.cloneGeometry();
851
    }
852

    
853
}