Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / impl / Geometry2D.java @ 34140

History | View | Annotate | Download (17.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 {Iver T.I.}   {Task}
26
*/
27
 
28
package org.gvsig.fmap.geom.impl;
29

    
30
import java.awt.Rectangle;
31
import java.awt.Shape;
32
import java.awt.geom.AffineTransform;
33
import java.awt.geom.PathIterator;
34
import java.awt.geom.Point2D;
35
import java.awt.geom.Rectangle2D;
36

    
37
import org.cresques.cts.ICoordTrans;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
import org.gvsig.fmap.geom.Geometry;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.GeometryManager;
44
import org.gvsig.fmap.geom.exception.CreateGeometryException;
45
import org.gvsig.fmap.geom.handler.Handler;
46
import org.gvsig.fmap.geom.operation.GeometryOperation;
47
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
48
import org.gvsig.fmap.geom.operation.GeometryOperationException;
49
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
50
import org.gvsig.fmap.geom.operation.relationship.DefaultRelationshipGeometryOperationContext;
51
import org.gvsig.fmap.geom.primitive.Envelope;
52
import org.gvsig.fmap.geom.primitive.GeneralPathX;
53
import org.gvsig.fmap.geom.primitive.Point;
54
import org.gvsig.fmap.geom.type.GeometryType;
55
import org.gvsig.fmap.geom.util.Converter;
56

    
57
/**
58
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
59
 */
60
public class Geometry2D implements Geometry{
61
        
62
        private static final Logger logger = LoggerFactory.getLogger(GeometryManager.class);
63
        
64
        private Geometry geometry = null;
65
                
66
        /**
67
         * @param primitive
68
         */
69
        public Geometry2D(Geometry geometry) {
70
                super();
71
                this.geometry = geometry;
72
        }
73

    
74
        /* (non-Javadoc)
75
         * @see org.gvsig.fmap.geom.Geometry#cloneGeometry()
76
         */
77
        public Geometry cloneGeometry() {
78
                return new Geometry2D((Geometry)geometry.cloneGeometry());
79
        }
80

    
81
        /* (non-Javadoc)
82
         * @see org.gvsig.fmap.geom.Geometry#fastIntersects(double, double, double, double)
83
         */
84
        public boolean fastIntersects(double x, double y, double w, double h) {
85
                return geometry.fastIntersects(x, y, w, h);
86
        }
87

    
88
        /* (non-Javadoc)
89
         * @see org.gvsig.fmap.geom.Geometry#getBounds2D()
90
         */
91
        public Rectangle2D getBounds2D() {
92
                return geometry.getBounds2D();
93
        }
94

    
95
        /* (non-Javadoc)
96
         * @see org.gvsig.fmap.geom.Geometry#getDimension()
97
         */
98
        public int getDimension() {
99
                return geometry.getDimension();
100
        }
101

    
102
        /* (non-Javadoc)
103
         * @see org.gvsig.fmap.geom.Geometry#getEnvelope()
104
         */
105
        public Envelope getEnvelope() {
106
                return geometry.getEnvelope();
107
        }
108

    
109
        /* (non-Javadoc)
110
         * @see org.gvsig.fmap.geom.Geometry#getGeneralPath()
111
         */
112
        public GeneralPathX getGeneralPath() {
113
                return geometry.getGeneralPath();
114
        }
115

    
116
        /* (non-Javadoc)
117
         * @see org.gvsig.fmap.geom.Geometry#getGeometryType()
118
         */
119
        public GeometryType getGeometryType() {
120
                return geometry.getGeometryType();
121
        }
122

    
123
        /* (non-Javadoc)
124
         * @see org.gvsig.fmap.geom.Geometry#getHandlers(int)
125
         */
126
        public Handler[] getHandlers(int type) {
127
                return geometry.getHandlers(type);
128
        }
129

    
130
        /* (non-Javadoc)
131
         * @see org.gvsig.fmap.geom.Geometry#getInternalShape()
132
         */
133
        public Shape getInternalShape() {
134
                return geometry.getInternalShape();
135
        }
136

    
137
        /* (non-Javadoc)
138
         * @see org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform)
139
         */
140
        public PathIterator getPathIterator(AffineTransform at) {
141
                return geometry.getPathIterator(at);
142
        }
143

    
144
        /* (non-Javadoc)
145
         * @see org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform, double)
146
         */
147
        public PathIterator getPathIterator(AffineTransform at, double flatness) {
148
                return geometry.getPathIterator(at, flatness);
149
        }
150

    
151
        /* (non-Javadoc)
152
         * @see org.gvsig.fmap.geom.Geometry#getType()
153
         */
154
        public int getType() {
155
                return geometry.getType();
156
        }
157

    
158
        /* (non-Javadoc)
159
         * @see org.gvsig.fmap.geom.Geometry#intersects(java.awt.geom.Rectangle2D)
160
         */
161
        public boolean intersects(Rectangle2D r) {
162
                return geometry.intersects(r);
163
        }
164

    
165
        /* (non-Javadoc)
166
         * @see org.gvsig.fmap.geom.Geometry#invokeOperation(int, org.gvsig.fmap.geom.operation.GeometryOperationContext)
167
         */
168
        public Object invokeOperation(int index, GeometryOperationContext ctx)
169
                        throws GeometryOperationNotSupportedException,
170
                        GeometryOperationException {
171
                return geometry.invokeOperation(index, ctx);
172
        }
173

    
174
        /* (non-Javadoc)
175
         * @see org.gvsig.fmap.geom.Geometry#invokeOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperationContext)
176
         */
177
        public Object invokeOperation(String opName, GeometryOperationContext ctx)
178
                        throws GeometryOperationNotSupportedException,
179
                        GeometryOperationException {
180
                return geometry.invokeOperation(opName, ctx);
181
        }
182

    
183
        /* (non-Javadoc)
184
         * @see org.gvsig.fmap.geom.Geometry#isSimple()
185
         */
186
        public boolean isSimple() {
187
                return geometry.isSimple();
188
        }
189

    
190
        /* (non-Javadoc)
191
         * @see org.gvsig.fmap.geom.Geometry#reProject(org.cresques.cts.ICoordTrans)
192
         */
193
        public void reProject(ICoordTrans ct) {
194
                geometry.reProject(ct);
195
        }
196

    
197
        /* (non-Javadoc)
198
         * @see org.gvsig.fmap.geom.Geometry#transform(java.awt.geom.AffineTransform)
199
         */
200
        public void transform(AffineTransform at) {
201
                geometry.transform(at);
202
        }
203

    
204
        /* (non-Javadoc)
205
         * @see java.awt.Shape#contains(java.awt.geom.Point2D)
206
         */
207
        public boolean contains(Point2D p) {
208
                
209
                
210
                
211
                try {
212
                        return containsPoint(geometry, p.getX(), p.getY());
213
                } catch (GeometryOperationException e) {
214
                        logger.error("While doing contains: " + e.getMessage(), e);
215
                        return true;
216
                }
217
        }
218

    
219
        /* (non-Javadoc)
220
         * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D)
221
         */
222
        public boolean contains(Rectangle2D r) {
223
                try {
224
                        return containsRectangle(geometry,
225
                                        r.getMinX(),
226
                                        r.getMinY(),
227
                                        r.getWidth(),
228
                                        r.getHeight());
229
                } catch (GeometryOperationException e) {
230
                        logger.error("While doing contains: " + e.getMessage(), e);
231
                        return true;
232
                }
233
        }
234

    
235
        /* (non-Javadoc)
236
         * @see java.awt.Shape#contains(double, double)
237
         */
238
        public boolean contains(double x, double y) {
239
                try {
240
                        return containsPoint(geometry, x, y);
241
                } catch (GeometryOperationException e) {
242
                        logger.error("While doing contains: " + e.getMessage(), e);
243
                        return true;
244
                }
245
        }
246

    
247
        /* (non-Javadoc)
248
         * @see java.awt.Shape#contains(double, double, double, double)
249
         */
250
        public boolean contains(double x, double y, double w, double h) {
251
                try {
252
                        return containsRectangle(geometry, x, y, w, h);
253
                } catch (GeometryOperationException e) {
254
                        logger.error("While doing contains: " + e.getMessage(), e);
255
                        return true;
256
                }
257
        }
258

    
259
        /* (non-Javadoc)
260
         * @see java.awt.Shape#getBounds()
261
         */
262
        public Rectangle getBounds() {
263
                return geometry.getBounds();
264
        }
265

    
266
        /* (non-Javadoc)
267
         * @see java.awt.Shape#intersects(double, double, double, double)
268
         */
269
        public boolean intersects(double x, double y, double w, double h) {
270
                try {
271
                        return intersectsRectangle(geometry, x, y, w, h);
272
                } catch (GeometryOperationException e) {
273
                        logger.error("While doing intersects: " + e.getMessage(), e);
274
                        return true;
275
                }
276
        }
277

    
278
        /* (non-Javadoc)
279
         * @see java.lang.Comparable#compareTo(java.lang.Object)
280
         */
281
        public int compareTo(Object arg0) {
282
                return geometry.compareTo(arg0);
283
        }
284
        
285
        
286
        
287
        
288
        
289
        
290
        
291
        
292
        
293
        /**
294
         * Utility method
295
         * @param geometry
296
         * @param x
297
         * @param y
298
         * @return
299
         * @throws GeometryOperationException
300
         */
301
        protected boolean containsPoint(Geometry geom, double x, double y) throws GeometryOperationException {
302
                
303
                // exclude disjoint 
304
                Envelope env = geom.getEnvelope();
305
                if (x > env.getMaximum(0)) return false; 
306
                if (y > env.getMaximum(1)) return false; 
307
                if (x < env.getMinimum(0)) return false; 
308
                if (y < env.getMinimum(1)) return false; 
309
                
310
                // boxes overlap, need long version
311
                
312
                Geometry geompoint = null;
313
                try {
314
                        geompoint = GeometryLocator.getGeometryManager().createPoint(x, y, SUBTYPES.GEOM2D);
315
                } catch (Exception e1) {
316
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e1);
317
                }
318
                
319
                DefaultRelationshipGeometryOperationContext drgoc =
320
                        new DefaultRelationshipGeometryOperationContext(geompoint);
321
                
322
                Object resp = null;
323
                boolean respboolean = true;
324
                try {
325
                        resp = geom.invokeOperation(GeometryOperation.OPERATION_CONTAINS_CODE, drgoc);
326
                        respboolean = ((Boolean) resp).booleanValue();
327
                } catch (Exception e) {
328
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e);
329
                }
330

    
331
                return respboolean;
332
        }
333

    
334
        /**
335
         * 
336
         * @param geometry
337
         * @param x
338
         * @param y
339
         * @param w
340
         * @param h
341
         * @return
342
         */
343
        protected boolean containsRectangle(Geometry geom, double x, double y,
344
                        double w, double h) throws GeometryOperationException {
345
                
346
                
347
                // exclude disjoint boxes
348
                Envelope env = geom.getEnvelope();
349
                if (x > env.getMaximum(0)) return false; 
350
                if ((x+w) < env.getMinimum(0)) return false; 
351
                if (y > env.getMaximum(1)) return false; 
352
                if ((y+h) < env.getMinimum(1)) return false; 
353
                
354
                if (w == 0 && h == 0) {
355
                        return  containsPoint(geom, x, y); 
356
                }
357
                
358
                // boxes overlap, need long version
359
                Geometry rectgeom = null;
360
                GeneralPathX gpx = new GeneralPathX();
361
                gpx.moveTo(x, y);
362
                gpx.lineTo(x+w, y);
363
                gpx.lineTo(x+w, y+h);
364
                gpx.lineTo(x, y+h);
365
                gpx.lineTo(x, y);
366
                
367
                try {
368
                        rectgeom = GeometryLocator.getGeometryManager().createSurface(gpx, SUBTYPES.GEOM2D);
369
                } catch (Exception e1) {
370
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e1);
371
                }
372
                
373
                DefaultRelationshipGeometryOperationContext drgoc =
374
                        new DefaultRelationshipGeometryOperationContext(rectgeom);
375
                
376
                Object resp = null;
377
                boolean respboolean = true;
378
                try {
379
                        resp = geom.invokeOperation(GeometryOperation.OPERATION_CONTAINS_CODE, drgoc);
380
                        respboolean = ((Boolean) resp).booleanValue();
381
                } catch (Exception e) {
382
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_CONTAINS_CODE, e);
383
                }
384

    
385
                return respboolean;
386
        }
387
        
388

    
389
        /**
390
         * 
391
         * @param geom
392
         * @param x
393
         * @param y
394
         * @param w
395
         * @param h
396
         * @return
397
         */
398
        protected boolean intersectsRectangle(Geometry geom, double x, double y,
399
                        double w, double h) throws GeometryOperationException {
400
                
401
                // exclude disjoint boxes
402
                Envelope env = geom.getEnvelope();
403
                if (x > env.getMaximum(0)) return false; 
404
                if ((x+w) < env.getMinimum(0)) return false; 
405
                if (y > env.getMaximum(1)) return false; 
406
                if ((y+h) < env.getMinimum(1)) return false; 
407
                
408
                // boxes overlap, need long version
409
                Geometry rectgeom = null;
410
                GeneralPathX gpx = new GeneralPathX();
411
                gpx.moveTo(x, y);
412
                gpx.lineTo(x+w, y);
413
                gpx.lineTo(x+w, y+h);
414
                gpx.lineTo(x, y+h);
415
                gpx.lineTo(x, y);
416
                
417
                try {
418
                        rectgeom = GeometryLocator.getGeometryManager().createSurface(gpx, SUBTYPES.GEOM2D);
419
                } catch (Exception e1) {
420
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_INTERSECTS_CODE, e1);
421
                }
422
                
423
                DefaultRelationshipGeometryOperationContext drgoc =
424
                        new DefaultRelationshipGeometryOperationContext(rectgeom);
425
                
426
                Object resp = null;
427
                boolean respboolean = true;
428
                try {
429
                        resp = geom.invokeOperation(GeometryOperation.OPERATION_INTERSECTS_CODE, drgoc);
430
                        respboolean = ((Boolean) resp).booleanValue();
431
                } catch (Exception e) {
432
                        throw new GeometryOperationException(geom.getType(), GeometryOperation.OPERATION_INTERSECTS_CODE, e);
433
                }
434

    
435
                return respboolean;
436

    
437

    
438
        }
439

    
440

    
441
        private com.vividsolutions.jts.geom.Geometry getJTS() {
442
                return Converter.geometryToJts(this);
443
        }
444
        
445
        public byte[] convertToWKB() throws GeometryOperationNotSupportedException,
446
                        GeometryOperationException {
447
                return (byte[]) this.invokeOperation(OPERATIONS.CONVERTTOWKB, null);
448
        }
449

    
450
        public String convertToWKT() throws GeometryOperationNotSupportedException,
451
                        GeometryOperationException {
452
                return (String) this.invokeOperation(OPERATIONS.CONVERTTOWKT, null);
453
        }
454

    
455
        public Geometry buffer(double distance)
456
                        throws GeometryOperationNotSupportedException,
457
                        GeometryOperationException {
458
                // TODO: this method can be implemented throw invokeOperation 
459
                try {
460
                        return Converter.jtsToGeometry( getJTS().buffer(distance) );
461
                } catch (CreateGeometryException e) {
462
                        throw new GeometryOperationException(e);
463
                }
464
        }
465
        
466
        public boolean contains(Geometry geometry)
467
                        throws GeometryOperationNotSupportedException,
468
                        GeometryOperationException {
469
                // TODO: this method can be implemented throw invokeOperation 
470
                return getJTS().contains(Converter.geometryToJts(geometry));
471
        }
472
        
473
        public double distance(Geometry geometry)
474
                        throws GeometryOperationNotSupportedException,
475
                        GeometryOperationException {
476
                // TODO: this method can be implemented throw invokeOperation 
477
                return getJTS().distance( Converter.geometryToJts(geometry));
478
        }
479
        
480
        public boolean overlaps(Geometry geometry)
481
                        throws GeometryOperationNotSupportedException,
482
                        GeometryOperationException {
483
                // TODO: this method can be implemented throw invokeOperation 
484
                return getJTS().overlaps(Converter.geometryToJts(geometry));
485
        }
486
        
487
        public Geometry convexHull() throws GeometryOperationNotSupportedException,
488
                        GeometryOperationException {
489
                // TODO: this method can be implemented throw invokeOperation 
490
                try {
491
                        return Converter.jtsToGeometry( getJTS().convexHull() );
492
                } catch (CreateGeometryException e) {
493
                        throw new GeometryOperationException(e);
494
                }
495
        }
496
        
497
        public boolean coveredBy(Geometry geometry)
498
                        throws GeometryOperationNotSupportedException,
499
                        GeometryOperationException {
500
                // TODO: this method can be implemented throw invokeOperation 
501
                return getJTS().coveredBy( Converter.geometryToJts(geometry));
502
        }
503
        
504
        public boolean crosses(Geometry geometry)
505
                        throws GeometryOperationNotSupportedException,
506
                        GeometryOperationException {
507
                // TODO: this method can be implemented throw invokeOperation 
508
                return getJTS().crosses(Converter.geometryToJts(geometry));
509
        }
510
        
511
        public Geometry difference(Geometry other)
512
                        throws GeometryOperationNotSupportedException,
513
                        GeometryOperationException {
514
                // TODO: this method can be implemented throw invokeOperation 
515
                try {
516
                        return Converter.jtsToGeometry( getJTS().difference( Converter.geometryToJts(other)) );
517
                } catch (CreateGeometryException e) {
518
                        throw new GeometryOperationException(e);
519
                }
520
        }
521
        
522
        public Geometry intersection(Geometry other)
523
                        throws GeometryOperationNotSupportedException,
524
                        GeometryOperationException {
525
                // TODO: this method can be implemented throw invokeOperation 
526
                try {
527
                        return Converter.jtsToGeometry( getJTS().intersection(Converter.geometryToJts(other)) );
528
                } catch (CreateGeometryException e) {
529
                        throw new GeometryOperationException(e);
530
                }
531
        }
532
        
533
        public boolean intersects(Geometry geometry)
534
                        throws GeometryOperationNotSupportedException,
535
                        GeometryOperationException {
536
                // TODO: this method can be implemented throw invokeOperation 
537
                return getJTS().intersects(Converter.geometryToJts(geometry));
538
        }
539
        
540
        public boolean touches(Geometry geometry)
541
                        throws GeometryOperationNotSupportedException,
542
                        GeometryOperationException {
543
                // TODO: this method can be implemented throw invokeOperation 
544
                return getJTS().touches(Converter.geometryToJts(geometry));
545
        }
546
        
547
        public Geometry union(Geometry other)
548
                        throws GeometryOperationNotSupportedException,
549
                        GeometryOperationException {
550
                // TODO: this method can be implemented throw invokeOperation 
551
                try {
552
                        return Converter.jtsToGeometry( getJTS().union(Converter.geometryToJts(other)) );
553
                } catch (CreateGeometryException e) {
554
                        throw new GeometryOperationException(e);
555
                }
556
        }
557
        
558
        public boolean disjoint(Geometry geometry)
559
                        throws GeometryOperationNotSupportedException,
560
                        GeometryOperationException {
561
                // TODO: this method can be implemented throw invokeOperation 
562
                return getJTS().disjoint(Converter.geometryToJts(geometry));
563
        }
564
        
565
        public boolean within(Geometry geometry)
566
                        throws GeometryOperationNotSupportedException,
567
                        GeometryOperationException {
568
                // TODO: this method can be implemented throw invokeOperation 
569
                return getJTS().within(Converter.geometryToJts(geometry));
570
        }
571

    
572
        public Point centroid() throws GeometryOperationNotSupportedException, GeometryOperationException {
573
                com.vividsolutions.jts.geom.Geometry geometry = getJTS();
574
                com.vividsolutions.jts.geom.Point point = geometry.getCentroid();
575
                GeometryOperationContext geometryOperationContext = new GeometryOperationContext();
576
                geometryOperationContext.setAttribute("JTSGeometry", point);
577
                return (Point)this.invokeOperation("fromJTS", geometryOperationContext);                
578
        }
579
        
580
        public double area() throws GeometryOperationNotSupportedException, GeometryOperationException
581
        {
582
            //Using get getJTS method instead of use the "toJTS" operation just for performance
583
            return getJTS().getArea();
584
        }
585
    
586
    public double perimeter() throws GeometryOperationNotSupportedException, GeometryOperationException
587
    {
588
      //Using get getJTS method instead of use the "toJTS" operation just for performance
589
        return getJTS().getLength();
590
    }
591
}
592