Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.impl / src / main / java / org / gvsig / fmap / geom / primitive / impl / AbstractPrimitive.java @ 40435

History | View | Annotate | Download (22.9 KB)

1
package org.gvsig.fmap.geom.primitive.impl;
2

    
3
import java.awt.Shape;
4
import java.awt.geom.AffineTransform;
5
import java.awt.geom.PathIterator;
6
import java.io.Serializable;
7

    
8
import com.vividsolutions.jts.geom.Coordinate;
9
import com.vividsolutions.jts.geom.GeometryFactory;
10
import com.vividsolutions.jts.io.WKBWriter;
11
import com.vividsolutions.jts.operation.distance.DistanceOp;
12
import com.vividsolutions.jts.operation.overlay.snap.GeometrySnapper;
13

    
14
import org.cresques.cts.ICoordTrans;
15
import org.cresques.cts.IProjection;
16
import org.slf4j.Logger;
17
import org.slf4j.LoggerFactory;
18

    
19
import org.gvsig.fmap.geom.Geometry;
20
import org.gvsig.fmap.geom.GeometryLocator;
21
import org.gvsig.fmap.geom.GeometryManager;
22
import org.gvsig.fmap.geom.exception.CreateGeometryException;
23
import org.gvsig.fmap.geom.handler.Handler;
24
import org.gvsig.fmap.geom.operation.GeometryOperation;
25
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
26
import org.gvsig.fmap.geom.operation.GeometryOperationException;
27
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
28
import org.gvsig.fmap.geom.primitive.Envelope;
29
import org.gvsig.fmap.geom.primitive.FShape;
30
import org.gvsig.fmap.geom.primitive.GeneralPathX;
31
import org.gvsig.fmap.geom.primitive.NullGeometry;
32
import org.gvsig.fmap.geom.primitive.Point;
33
import org.gvsig.fmap.geom.primitive.Primitive;
34
import org.gvsig.fmap.geom.type.GeometryType;
35
import org.gvsig.fmap.geom.util.Converter;
36

    
37

    
38
/**
39
 * @author Jorge Piera Llodr� (jorge.piera@iver.es)
40
 */
41
public abstract class AbstractPrimitive implements Primitive, FShape, Shape, Serializable {
42
        
43
        private static final Logger logger = LoggerFactory.getLogger(AbstractPrimitive.class);
44

    
45
        private static final long serialVersionUID = -4334977368955260872L;
46
        protected String id = null;
47
        protected IProjection projection = null;
48
        protected GeometryType geometryType = null;
49
        protected static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
50

    
51
        /**
52
         * The constructor with the GeometryType like and argument 
53
         * is used by the {@link GeometryType}{@link #create()}
54
         * to create the geometry
55
         * @param type
56
         * The geometry type
57
         */
58
        public AbstractPrimitive(GeometryType geometryType) {
59
                this(geometryType, null, null);                
60
        }
61
        
62
        AbstractPrimitive(int type, int subtype) {
63
                try {
64
                        geometryType = geomManager.getGeometryType(type, subtype);
65
                } catch (Exception e) {
66
                        //TODO Not registered geometry
67
                        geometryType = null;
68
                }
69
        }        
70
        
71
        public AbstractPrimitive(GeometryType geometryType, String id, IProjection projection) {
72
                super();
73
                this.id = id;
74
                this.projection = projection;
75
                this.geometryType = geometryType;
76
        }
77

    
78
        public AbstractPrimitive(GeometryType geometryType, IProjection projection) {
79
                this(geometryType, null, projection);
80
        }
81

    
82
        /* (non-Javadoc)
83
         * @see org.gvsig.fmap.geom.Geometry#getGeometryType()
84
         */
85
        public GeometryType getGeometryType() {
86
                return geometryType;
87
        }
88

    
89
        /* (non-Javadoc)
90
         * @see org.gvsig.fmap.geom.Geometry#getType()
91
         */
92
        public int getType() {
93
                return geometryType.getType();
94
        }
95

    
96
        /**
97
         * (non-Javadoc)
98
         * @see com.iver.cit.gvsig.fmap.core.Geometry#getInternalShape()
99
         * @deprecated this Geometry is a Shape.
100
         */
101
        public Shape getInternalShape() {
102
                return this;
103
        }
104

    
105
        /* (non-Javadoc)
106
         * @see org.gvsig.geometries.iso.AbstractGeometry#getId()
107
         */
108
        public String getId() {
109
                return id;
110
        }
111

    
112
        /* (non-Javadoc)
113
         * @see org.gvsig.geometries.iso.AbstractGeometry#getSRS()
114
         */
115
        public IProjection getSRS() {
116
                return projection;
117
        }
118

    
119
        /* (non-Javadoc)
120
         * @see org.gvsig.geometries.iso.AbstractGeometry#transform(org.cresques.cts.IProjection)
121
         */
122
        public AbstractPrimitive transform(IProjection newProjection) {
123
                Geometry newGeom = cloneGeometry();
124
                ICoordTrans coordTrans = projection.getCT(newProjection);
125
                newGeom.reProject(coordTrans);
126
                return (AbstractPrimitive)newGeom;
127
        }
128

    
129

    
130

    
131
        /*
132
         * (non-Javadoc)
133
         * @see org.gvsig.fmap.geom.Geometry#fastIntersects(double, double, double, double)
134
         */
135
        public boolean fastIntersects(double x, double y, double w, double h) {
136

    
137
                boolean resp = true;
138
                
139
                try {
140
                        resp = intersectsRectangle(this, x, y, w, h);
141
                } catch (GeometryOperationException e) {
142
                        logger.error("While doing fastintersects: " + e.getMessage(), e);
143
                }
144
                
145
                return resp;
146
        }
147

    
148
        /*
149
         * (non-Javadoc)
150
         * @see org.gvsig.fmap.geom.Geometry#cloneGeometry()
151
         */
152
        public Geometry cloneGeometry() {
153
                return (Geometry)cloneFShape();
154
        }
155

    
156
        /*
157
         * (non-Javadoc)
158
         * @see org.gvsig.fmap.geom.Geometry#getHandlers(int)
159
         */
160
        public Handler[] getHandlers(int type) {
161
                if (type==STRETCHINGHANDLER){
162
                        return getStretchingHandlers();
163
                }else if (type==SELECTHANDLER){
164
                        return getSelectHandlers();
165
                }
166
                return null;
167
        }
168

    
169
        /*
170
         * (non-Javadoc)
171
         * @see org.gvsig.fmap.geom.Geometry#isSimple()
172
         */
173
        public boolean isSimple() {
174
                return true;
175
        }
176

    
177
        /*
178
         * (non-Javadoc)
179
         * @see org.gvsig.fmap.geom.Geometry#invokeOperation(int, org.gvsig.fmap.geom.operation.GeometryOperationContext)
180
         */
181
        public Object invokeOperation(int index, GeometryOperationContext ctx) throws GeometryOperationNotSupportedException, GeometryOperationException {
182
                return geomManager.invokeOperation(index, this, ctx);
183
        }
184

    
185
        /*
186
         * (non-Javadoc)
187
         * @see org.gvsig.fmap.geom.Geometry#invokeOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperationContext)
188
         */
189
        public Object invokeOperation(String oppName, GeometryOperationContext ctx) throws GeometryOperationNotSupportedException, GeometryOperationException {
190
                return geomManager.invokeOperation(oppName, this, ctx);
191
        }
192

    
193
        /*
194
         * (non-Javadoc)
195
         * @see java.lang.Comparable#compareTo(T)
196
         */
197
        public int compareTo(Object arg0) {
198
                // TODO Auto-generated method stub
199
                return -1;
200
        }
201

    
202
        /*
203
         * (non-Javadoc)
204
         * @see java.lang.Object#toString()
205
         */
206
        public String toString() {
207
                String name=getGeometryType().getName();
208
                return name.substring(name.lastIndexOf(".")+1);
209
        }
210

    
211
        /*
212
         * (non-Javadoc)
213
         * @see java.lang.Object#equals(java.lang.Object)
214
         */
215
        public boolean equals(Object obj) {
216
                if (obj == null) {
217
                        return false;
218
                }
219
                if (this.getClass() != obj.getClass()) {
220
                        return false;
221
                }
222

    
223
                AbstractPrimitive other = (AbstractPrimitive) obj;
224
                if (this.getGeometryType().getType() != other.getGeometryType()
225
                                .getType()) {
226
                        return false;
227

    
228
                }
229
                
230
                if (this.getGeometryType().getSubType() != other.getGeometryType()
231
                                .getSubType()) {
232
                        return false;
233

    
234
                }
235
                
236
                if (this instanceof NullGeometry || obj instanceof NullGeometry) {
237
                    /*
238
                     * If any of them is null geometry, they both have to be
239
                     * null geometry, or else, they are not equal.
240
                     * This prevents null pointer exception in the rest of the
241
                     * method
242
                     */
243
                if (this instanceof NullGeometry && obj instanceof NullGeometry) {
244
                    return true;
245
                } else {
246
                    return false;
247
                }
248
                }
249
                
250
                if (this.projection != other.projection) {
251
                        if (this.projection == null) {
252
                                return false;
253
                        }
254
                        if (this.projection.getAbrev() != other.projection.getAbrev()) { //FIXME this must be false
255
                                return false;
256
                        }
257
                }
258
                if (!this.getBounds().equals(other.getBounds())) {
259
                        return false;
260
                }
261

    
262

    
263
                GeneralPathX myPath = this.getGeneralPath();
264
                GeneralPathX otherPath = other.getGeneralPath();
265
                if (myPath == null) {
266
                        if (otherPath != null) {
267
                                return false;
268
                        } else {
269
                                // TODO checkThis
270
                                return true;
271
                        }
272

    
273
                }
274
                if (myPath.getNumTypes() != otherPath.getNumTypes()) {
275
                        return false;
276
                }
277
                if (Math.abs(myPath.getNumCoords() - otherPath.getNumCoords()) > this
278
                                .getDimension()) {
279
                        return false;
280
                }
281
                PathIterator myIter = myPath.getPathIterator(null);
282
                PathIterator otherIter = otherPath.getPathIterator(null);
283
                int myType,otherType;
284
                // FIXME when 3D, 2DM and 3DM
285
                double[] myData = new double[6];
286
                double[] otherData = new double[6];
287
                double[] myFirst = new double[] { myPath.getPointAt(0).getX(),myPath.getPointAt(0).getY()};
288
                double[] otherFirst = new double[] { otherPath.getPointAt(0).getX(),otherPath.getPointAt(0).getY()};
289

    
290
                while (!myIter.isDone()) {
291
                        if (otherIter.isDone()) {
292
                                return false;
293
                        }
294
                        for (int i = 0; i < myData.length; i++) {
295
                                myData[i] = 0.0;
296
                                otherData[i] = 0.0;
297
                        }
298

    
299
                        myType = myIter.currentSegment(myData);
300
                        otherType = otherIter.currentSegment(otherData);
301

    
302
                        switch (myType) {
303
                        case PathIterator.SEG_LINETO:
304
                                if (otherType != myType) {
305
                                        if (otherType == PathIterator.SEG_CLOSE){
306
                                                if (!comparePathIteratorData(otherFirst, myData)) {
307
                                                        return false;
308
                                                }
309
                                        } else {
310
                                                return false;
311
                                        }
312
                                } else {
313
                                        if (!comparePathIteratorData(myData, otherData)) {
314
                                                return false;
315
                                        }
316
                                }
317
                                break;
318

    
319

    
320
                        case PathIterator.SEG_CLOSE:
321
                                if (otherType != myType) {
322
                                        if (otherType == PathIterator.SEG_LINETO) {
323
                                                if (!comparePathIteratorData(myFirst, otherData)) {
324
                                                        return false;
325
                                                }
326
                                        } else {
327
                                                return false;
328
                                        }
329
                                } else {
330
                                        if (!comparePathIteratorData(myData, otherData)) {
331
                                                return false;
332
                                        }
333
                                }
334
                                break;
335

    
336

    
337

    
338
                        case PathIterator.SEG_MOVETO:
339
                        case PathIterator.SEG_QUADTO:
340
                        case PathIterator.SEG_CUBICTO:
341
                                if (otherType != myType) {
342
                                        return false;
343
                                }
344
                                if (!comparePathIteratorData(myData, otherData)) {
345
                                        return false;
346
                                }
347
                                break;
348

    
349
                        } // end switch
350

    
351

    
352
                        myIter.next();
353
                        otherIter.next();
354
                }
355
                if (!otherIter.isDone()) {
356
                        return false;
357
                }
358
                return true;
359
        }
360

    
361
        private boolean comparePathIteratorData(double[] org, double[] other) {
362
                for (int i = 0; i < org.length; i++) {
363
                        if (Math.abs(org[i] - other[i]) > 0.0000001) {
364
                                return false;
365
                        }
366
                }
367
                return true;
368
        }
369

    
370
        /* (non-Javadoc)
371
         * @see org.gvsig.fmap.geom.primitive.FShape#getShapeType()
372
         */
373
        public int getShapeType() {
374
                return getType();
375
        }
376
        
377
        
378
        
379
        
380
        
381
        
382
        
383
        
384
        /**
385
         * Utility method
386
         * @param geometry
387
         * @param x
388
         * @param y
389
         * @return
390
         * @throws GeometryOperationException
391
         */
392
        protected boolean containsPoint(Geometry geom, double x, double y) throws GeometryOperationException {
393
                
394
                // exclude disjoint 
395
                Envelope env = geom.getEnvelope();
396
                if (x > env.getMaximum(0)) return false; 
397
                if (y > env.getMaximum(1)) return false; 
398
                if (x < env.getMinimum(0)) return false; 
399
                if (y < env.getMinimum(1)) return false; 
400
                
401
                // boxes overlap, need long version
402
                
403
                Geometry geompoint = null;
404
                try {
405
                        geompoint = GeometryLocator.getGeometryManager().createPoint(x, y, SUBTYPES.GEOM2D);
406
                } catch (Exception e1) {
407
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e1);
408
                }
409
                
410
                GeometryOperationContext drgoc = new GeometryOperationContext();
411
                 drgoc.setAttribute("geom",geompoint);
412
                
413
                Object resp = null;
414
                boolean respboolean = true;
415
                try {
416
                        resp = geom.invokeOperation(GeometryOperation.OPERATION_CONTAINS_CODE, drgoc);
417
                        respboolean = ((Boolean) resp).booleanValue();
418
                } catch (Exception e) {
419
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e);
420
                }
421

    
422
                return respboolean;
423
        }
424

    
425
        /**
426
         * 
427
         * @param geometry
428
         * @param x
429
         * @param y
430
         * @param w
431
         * @param h
432
         * @return
433
         */
434
        protected boolean containsRectangle(Geometry geom, double x, double y,
435
                        double w, double h) throws GeometryOperationException {
436
                
437
                
438
                // exclude disjoint boxes
439
                Envelope env = geom.getEnvelope();
440
                if (x > env.getMaximum(0)) return false; 
441
                if ((x+w) < env.getMinimum(0)) return false; 
442
                if (y > env.getMaximum(1)) return false; 
443
                if ((y+h) < env.getMinimum(1)) return false; 
444
                
445
                if (w == 0 && h == 0) {
446
                        return  containsPoint(geom, x, y); 
447
                }
448
                
449
                // boxes overlap, need long version
450
                Geometry rectgeom = null;
451
                GeneralPathX gpx = new GeneralPathX();
452
                gpx.moveTo(x, y);
453
                gpx.lineTo(x+w, y);
454
                gpx.lineTo(x+w, y+h);
455
                gpx.lineTo(x, y+h);
456
                gpx.lineTo(x, y);
457
                
458
                try {
459
                        rectgeom = GeometryLocator.getGeometryManager().createSurface(gpx, SUBTYPES.GEOM2D);
460
                } catch (Exception e1) {
461
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e1);
462
                }
463
                
464
                GeometryOperationContext drgoc = new GeometryOperationContext();
465
                drgoc.setAttribute("geom",rectgeom);
466

    
467
                Object resp = null;
468
                boolean respboolean = true;
469
                try {
470
                        resp = geom.invokeOperation(GeometryOperation.OPERATION_CONTAINS_CODE, drgoc);
471
                        respboolean = ((Boolean) resp).booleanValue();
472
                } catch (Exception e) {
473
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e);
474
                }
475

    
476
                return respboolean;
477
        }
478
        
479

    
480
        /**
481
         * 
482
         * @param geom
483
         * @param x
484
         * @param y
485
         * @param w
486
         * @param h
487
         * @return
488
         */
489
        protected boolean intersectsRectangle(Geometry geom, double x, double y,
490
                        double w, double h) throws GeometryOperationException {
491
                
492
                // exclude disjoint boxes
493
                Envelope env = geom.getEnvelope();
494
                if (x > env.getMaximum(0)) return false; 
495
                if ((x+w) < env.getMinimum(0)) return false; 
496
                if (y > env.getMaximum(1)) return false; 
497
                if ((y+h) < env.getMinimum(1)) return false; 
498
                
499
                // boxes overlap, need long version
500
                Geometry rectgeom = null;
501
                GeneralPathX gpx = new GeneralPathX();
502
                gpx.moveTo(x, y);
503
                gpx.lineTo(x+w, y);
504
                gpx.lineTo(x+w, y+h);
505
                gpx.lineTo(x, y+h);
506
                gpx.lineTo(x, y);
507
                
508
                try {
509
                        rectgeom = GeometryLocator.getGeometryManager().createSurface(gpx, SUBTYPES.GEOM2D);
510
                } catch (Exception e1) {
511
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_INTERSECTS_CODE, e1);
512
                }
513

    
514
                GeometryOperationContext drgoc = new GeometryOperationContext();
515
                drgoc.setAttribute("geom",rectgeom);
516
                
517
                Object resp = null;
518
                boolean respboolean = true;
519
                try {
520
                        resp = geom.invokeOperation(GeometryOperation.OPERATION_INTERSECTS_CODE, drgoc);
521
                        respboolean = ((Boolean) resp).booleanValue();
522
                } catch (Exception e) {
523
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_INTERSECTS_CODE, e);
524
                }
525

    
526
                return respboolean;
527

    
528

    
529
        }
530

    
531
        private com.vividsolutions.jts.geom.Geometry getJTS() {
532
                return Converter.geometryToJts(this);
533
        }
534
        
535
        public byte[] convertToWKB() throws GeometryOperationNotSupportedException,
536
                        GeometryOperationException {
537
                return (byte[]) this.invokeOperation(OPERATIONS.CONVERTTOWKB, null);
538
        }
539

    
540
        public byte[] convertToWKB(int srs) 
541
                throws GeometryOperationNotSupportedException, GeometryOperationException {
542
                int subType = getGeometryType().getSubType();
543
                boolean is3D = subType == 1 || subType == 3;
544
                
545
                WKBWriter write = null;
546
                if(is3D)
547
                        write = new WKBWriter(3);
548
                else
549
                        write = new WKBWriter(2);
550
                return write.write(Converter.geometryToJtsWithSRID(this, srs));
551
        }
552
        
553
        public byte[] convertToWKBForcingType(int srs, int type) 
554
                throws GeometryOperationNotSupportedException, GeometryOperationException {
555
                int subType = getGeometryType().getSubType();
556
                boolean is3D = subType == 1 || subType == 3;
557

    
558
                WKBWriter write = null;
559
                if(is3D)
560
                        write = new WKBWriter(3);
561
                else
562
                        write = new WKBWriter(2);
563
                return write.write(Converter.geometryToJtsWithSRIDForcingType(this, srs, type));
564
        }
565

    
566
        public String convertToWKT() throws GeometryOperationNotSupportedException,
567
                        GeometryOperationException {
568
                return (String) this.invokeOperation(OPERATIONS.CONVERTTOWKT, null);
569
        }
570

    
571
        public Geometry buffer(double distance)
572
                        throws GeometryOperationNotSupportedException,
573
                        GeometryOperationException {
574
                // TODO: this method can be implemented throw invokeOperation 
575
                try {
576
                        return Converter.jtsToGeometry( getJTS().buffer(distance) );
577
                } catch (CreateGeometryException e) {
578
                        throw new GeometryOperationException(e);
579
                }
580
        }
581
        
582
        public boolean contains(Geometry geometry)
583
                        throws GeometryOperationNotSupportedException,
584
                        GeometryOperationException {
585
                // TODO: this method can be implemented throw invokeOperation 
586
                return getJTS().contains(Converter.geometryToJts(geometry));
587
        }
588
        
589
        public double distance(Geometry geometry)
590
                        throws GeometryOperationNotSupportedException,
591
                        GeometryOperationException {
592
                // TODO: this method can be implemented throw invokeOperation 
593
                return getJTS().distance( Converter.geometryToJts(geometry));
594
        }
595
        
596
        public Geometry snapTo(Geometry other, double snapTolerance)
597
                        throws GeometryOperationNotSupportedException,
598
                        GeometryOperationException {
599
                Geometry result = null;
600
                GeometrySnapper snapper = new GeometrySnapper(getJTS());
601
                com.vividsolutions.jts.geom.Geometry jts_result = snapper.snapTo(Converter.geometryToJts(other), snapTolerance);
602
                try {
603
                        result = Converter.jtsToGeometry(jts_result);
604
                } catch (CreateGeometryException e) {
605
                        throw new GeometryOperationException(e);
606
                }
607
                return result;
608
        }
609
        
610
        public boolean isWithinDistance(Geometry other, double distance)
611
                        throws GeometryOperationNotSupportedException,
612
                        GeometryOperationException {
613
                return DistanceOp.isWithinDistance(this.getJTS(), Converter.geometryToJts(other), distance);
614
        }
615
        
616
        
617
        public Geometry[] closestPoints(Geometry other)
618
                        throws GeometryOperationNotSupportedException,
619
                        GeometryOperationException {
620
                Geometry[] points = null;
621

    
622
                Coordinate[] jts_points = DistanceOp.closestPoints(this.getJTS(),
623
                                Converter.geometryToJts(other));
624
                points = new Point[jts_points.length];
625
                GeometryFactory geomFactory = new GeometryFactory();
626
                for (int n = 0; n < jts_points.length; n++) {
627
                        try {
628
                                points[n] = Converter.jtsToGeometry(geomFactory.createPoint(jts_points[n]));
629
                        } catch (CreateGeometryException e) {
630
                                throw new GeometryOperationException(e);
631
                        }
632
                }
633
                return points;
634
        }
635
        
636
        public boolean overlaps(Geometry geometry)
637
                        throws GeometryOperationNotSupportedException,
638
                        GeometryOperationException {
639
                // TODO: this method can be implemented throw invokeOperation 
640
                return getJTS().overlaps(Converter.geometryToJts(geometry));
641
        }
642
        
643
        public Geometry convexHull() throws GeometryOperationNotSupportedException,
644
                        GeometryOperationException {
645
                // TODO: this method can be implemented throw invokeOperation 
646
                try {
647
                        return Converter.jtsToGeometry( getJTS().convexHull() );
648
                } catch (CreateGeometryException e) {
649
                        throw new GeometryOperationException(e);
650
                }
651
        }
652
        
653
        public boolean coveredBy(Geometry geometry)
654
                        throws GeometryOperationNotSupportedException,
655
                        GeometryOperationException {
656
                // TODO: this method can be implemented throw invokeOperation 
657
                return getJTS().coveredBy( Converter.geometryToJts(geometry));
658
        }
659
        
660
        public boolean crosses(Geometry geometry)
661
                        throws GeometryOperationNotSupportedException,
662
                        GeometryOperationException {
663
                // TODO: this method can be implemented throw invokeOperation 
664
                return getJTS().crosses(Converter.geometryToJts(geometry));
665
        }
666
        
667
        public Geometry difference(Geometry other)
668
                        throws GeometryOperationNotSupportedException,
669
                        GeometryOperationException {
670
                // TODO: this method can be implemented throw invokeOperation 
671
                try {
672
                        return Converter.jtsToGeometry( getJTS().difference( Converter.geometryToJts(other)) );
673
                } catch (CreateGeometryException e) {
674
                        throw new GeometryOperationException(e);
675
                }
676
        }
677
        
678
        public Geometry intersection(Geometry other)
679
                        throws GeometryOperationNotSupportedException,
680
                        GeometryOperationException {
681
                // TODO: this method can be implemented throw invokeOperation 
682
                try {
683
                        return Converter.jtsToGeometry( getJTS().intersection(Converter.geometryToJts(other)) );
684
                } catch (CreateGeometryException e) {
685
                        throw new GeometryOperationException(e);
686
                }
687
        }
688
        
689
        public boolean intersects(Geometry geometry)
690
                        throws GeometryOperationNotSupportedException,
691
                        GeometryOperationException {
692
                // TODO: this method can be implemented throw invokeOperation 
693
                return getJTS().intersects(Converter.geometryToJts(geometry));
694
        }
695
        
696
        public boolean touches(Geometry geometry)
697
                        throws GeometryOperationNotSupportedException,
698
                        GeometryOperationException {
699
                // TODO: this method can be implemented throw invokeOperation 
700
                return getJTS().touches(Converter.geometryToJts(geometry));
701
        }
702
        
703
        public Geometry union(Geometry other)
704
                        throws GeometryOperationNotSupportedException,
705
                        GeometryOperationException {
706
                // TODO: this method can be implemented throw invokeOperation 
707
                try {
708
                        return Converter.jtsToGeometry( getJTS().union(Converter.geometryToJts(other)) );
709
                } catch (CreateGeometryException e) {
710
                        throw new GeometryOperationException(e);
711
                }
712
        }
713
        
714
        public boolean disjoint(Geometry geometry)
715
                        throws GeometryOperationNotSupportedException,
716
                        GeometryOperationException {
717
                // TODO: this method can be implemented throw invokeOperation 
718
                return getJTS().disjoint(Converter.geometryToJts(geometry));
719
        }
720
        
721
        public boolean within(Geometry geometry)
722
                        throws GeometryOperationNotSupportedException,
723
                        GeometryOperationException {
724
                // TODO: this method can be implemented throw invokeOperation 
725
                return getJTS().within(Converter.geometryToJts(geometry));
726
        }
727
        
728
        public Point centroid() throws GeometryOperationNotSupportedException, GeometryOperationException {
729
                com.vividsolutions.jts.geom.Geometry geometry = getJTS();
730
                com.vividsolutions.jts.geom.Point point = geometry.getCentroid();
731
                GeometryOperationContext geometryOperationContext = new GeometryOperationContext();
732
                geometryOperationContext.setAttribute("JTSGeometry", point);
733
                return (Point)this.invokeOperation("fromJTS", geometryOperationContext);                
734
        }
735
        
736
           
737
        public Point getInteriorPoint() throws GeometryOperationNotSupportedException, GeometryOperationException {
738
            
739
            try {
740
                com.vividsolutions.jts.geom.Geometry geometry = getJTS();
741
                com.vividsolutions.jts.geom.Point point = geometry.getInteriorPoint();
742
                GeometryOperationContext geometryOperationContext = new GeometryOperationContext();
743
                geometryOperationContext.setAttribute("JTSGeometry", point);
744
                return (Point)this.invokeOperation("fromJTS", geometryOperationContext);
745
        } catch (GeometryOperationNotSupportedException ns_ex) {
746
            throw ns_ex;
747
        } catch (GeometryOperationException op_ex) {
748
            throw op_ex;
749
            } catch (Exception ex) {
750
                /*
751
                 * This is for unexpected null pointer exceptions or other
752
                 */
753
                throw new GeometryOperationException(ex);
754
            }
755
        }   
756

    
757
        
758
        public double area() throws GeometryOperationNotSupportedException, GeometryOperationException
759
    {
760
        //Using get getJTS method instead of use the "toJTS" operation just for performance
761
        return getJTS().getArea();
762
    }
763
    
764
    public double perimeter() throws GeometryOperationNotSupportedException, GeometryOperationException
765
    {
766
      //Using get getJTS method instead of use the "toJTS" operation just for performance
767
        return getJTS().getLength();
768
    }
769

    
770
    public Shape getShape() {
771
        return this;
772
    }  
773
    
774
    public Shape getShape(AffineTransform affineTransform) {
775
        if (affineTransform == null){
776
            return this;
777
        }
778
        return new GeneralPathAdapter(affineTransform, getGeneralPath());
779
    }     
780
    
781
    public void rotate(double radAngle, double basex, double basey) {
782
        
783
        AffineTransform at = new AffineTransform();
784
        at.rotate(radAngle,basex,basey);
785
        this.transform(at);
786
    }
787
    
788
    public void move(double dx, double dy) {
789
        
790
        AffineTransform at = new AffineTransform();
791
        at.translate(dx, dy);
792
        this.transform(at);
793
    }
794
    
795
    public void scale(Point basePoint, double sx, double sy) {
796
        
797
        AffineTransform at = new AffineTransform();
798
        at.setToTranslation(basePoint.getX(),basePoint.getY());
799
        at.scale(sx,sy);
800
        at.translate(-basePoint.getX(),-basePoint.getY());
801
        this.transform(at);
802
    }
803

    
804
}