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 / util / JTSUtils.java @ 42360

History | View | Annotate | Download (20.9 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.util;
24

    
25
import java.util.List;
26

    
27
import com.vividsolutions.jts.geom.Coordinate;
28
import com.vividsolutions.jts.geom.CoordinateSequence;
29
import com.vividsolutions.jts.geom.GeometryCollection;
30
import com.vividsolutions.jts.geom.LineSegment;
31
import com.vividsolutions.jts.geom.LineString;
32
import com.vividsolutions.jts.geom.LinearRing;
33
import com.vividsolutions.jts.geom.MultiLineString;
34
import com.vividsolutions.jts.geom.MultiPoint;
35
import com.vividsolutions.jts.geom.MultiPolygon;
36
import com.vividsolutions.jts.geom.Triangle;
37
import com.vividsolutions.jts.util.GeometricShapeFactory;
38

    
39
import org.hibernate.spatial.jts.mgeom.MCoordinateSequence;
40
import org.hibernate.spatial.jts.mgeom.MGeometryFactory;
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44
import org.gvsig.fmap.geom.Geometry;
45
import org.gvsig.fmap.geom.GeometryException;
46
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
47
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48
import org.gvsig.fmap.geom.jts.GeometryJTS;
49
import org.gvsig.fmap.geom.jts.MCoordinate;
50
import org.gvsig.fmap.geom.jts.aggregate.MultiLine2D;
51
import org.gvsig.fmap.geom.jts.aggregate.MultiLine2DM;
52
import org.gvsig.fmap.geom.jts.aggregate.MultiLine3D;
53
import org.gvsig.fmap.geom.jts.aggregate.MultiLine3DM;
54
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint2D;
55
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint2DM;
56
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint3D;
57
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint3DM;
58
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon2D;
59
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon2DM;
60
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon3D;
61
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon3DM;
62
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line2D;
63
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line2DM;
64
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line3D;
65
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line3DM;
66
import org.gvsig.fmap.geom.jts.primitive.point.Point2D;
67
import org.gvsig.fmap.geom.jts.primitive.point.Point2DM;
68
import org.gvsig.fmap.geom.jts.primitive.point.Point3D;
69
import org.gvsig.fmap.geom.jts.primitive.point.Point3DM;
70
import org.gvsig.fmap.geom.jts.primitive.point.PointJTS;
71
import org.gvsig.fmap.geom.jts.primitive.ring.Ring2D;
72
import org.gvsig.fmap.geom.jts.primitive.ring.Ring2DM;
73
import org.gvsig.fmap.geom.jts.primitive.ring.Ring3D;
74
import org.gvsig.fmap.geom.jts.primitive.ring.Ring3DM;
75
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon2D;
76
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon2DM;
77
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon3D;
78
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon3DM;
79
import org.gvsig.fmap.geom.primitive.Point;
80
import org.gvsig.fmap.geom.primitive.Polygon;
81
import org.gvsig.fmap.geom.primitive.Primitive;
82
import org.gvsig.fmap.geom.primitive.Ring;
83
import org.gvsig.fmap.geom.type.GeometryType;
84

    
85
/**
86
 * @author fdiaz
87
 *
88
 */
89
public class JTSUtils {
90

    
91
    public static final Logger logger = LoggerFactory.getLogger(JTSUtils.class);
92

    
93
    private static class MyMGeometryFactory extends org.hibernate.spatial.jts.mgeom.MGeometryFactory {
94

    
95
        /**
96
         *
97
         */
98
        private static final long serialVersionUID = -8174926092714691479L;
99

    
100
        public com.vividsolutions.jts.geom.Point createPoint(CoordinateSequence coordinates) {
101
            if(!(coordinates instanceof MCoordinateSequence)){
102
                if (coordinates != null) {
103
                    coordinates = new MCoordinateSequence(coordinates);
104
                }
105
            }
106
            return super.createPoint(coordinates);
107
        }
108

    
109
        public LinearRing createLinearRing(CoordinateSequence coordinates) {
110
            if(!(coordinates instanceof MCoordinateSequence)){
111
                if (coordinates != null) {
112
                    coordinates = new MCoordinateSequence(coordinates);
113
                }
114
            }
115
            return super.createLinearRing(coordinates);
116
        }
117

    
118
        @Override
119
        public LineString createLineString(CoordinateSequence coordinates) {
120
            if(!(coordinates instanceof MCoordinateSequence)){
121
                if (coordinates != null) {
122
                    coordinates = new MCoordinateSequence(coordinates);
123
                }
124
            }
125
            return super.createLineString(coordinates);
126
        }
127

    
128
    }
129

    
130

    
131
    private static final com.vividsolutions.jts.geom.GeometryFactory factory =
132
        new com.vividsolutions.jts.geom.GeometryFactory();
133

    
134
    private static final com.vividsolutions.jts.geom.GeometryFactory mfactory = new MyMGeometryFactory();
135

    
136
    public static Point createPoint(GeometryType type, Coordinate coordinate) throws CreateGeometryException {
137

    
138
        switch (type.getSubType()) {
139
        case Geometry.SUBTYPES.GEOM2D:
140
            return new Point2D(coordinate);
141
        case Geometry.SUBTYPES.GEOM2DM:
142
            return new Point2DM(coordinate);
143
        case Geometry.SUBTYPES.GEOM3D:
144
            return new Point3D(coordinate);
145
        case Geometry.SUBTYPES.GEOM3DM:
146
            return new Point3DM(coordinate);
147
        default:
148
            Point p = null;
149
            p = (Point) type.create();
150
            for (int i = 0; i < p.getDimension(); i++) {
151
                p.setCoordinateAt(i, coordinate.getOrdinate(i));
152
            }
153
            break;
154
        }
155

    
156
        return null;
157
    }
158

    
159
    private static com.vividsolutions.jts.geom.GeometryFactory getFactory(CoordinateSequence coordinates){
160
        com.vividsolutions.jts.geom.GeometryFactory factory = JTSUtils.factory;
161
        if(coordinates.size()>0 && coordinates.getCoordinate(0) instanceof org.hibernate.spatial.jts.mgeom.MCoordinate){
162
            factory = mfactory;
163
        }
164
        return factory;
165
    }
166

    
167
    public static com.vividsolutions.jts.geom.GeometryFactory getFactory(Coordinate coordinate) {
168
        com.vividsolutions.jts.geom.GeometryFactory factory = JTSUtils.factory;
169
        if(coordinate instanceof org.hibernate.spatial.jts.mgeom.MCoordinate){
170
            factory = mfactory;
171
        }
172
        return factory;
173
    }
174

    
175
    public static com.vividsolutions.jts.geom.GeometryFactory getFactory(Coordinate[] coordinates) {
176
        com.vividsolutions.jts.geom.GeometryFactory factory = JTSUtils.factory;
177
        if(coordinates.length>0 && coordinates[0] instanceof org.hibernate.spatial.jts.mgeom.MCoordinate){
178
                factory = mfactory;
179
        }
180
        return factory;
181
    }
182

    
183
    public static LineString createJTSLineString(CoordinateSequence coordinates) {
184
        return getFactory(coordinates).createLineString(coordinates);
185
    }
186

    
187
    public static LinearRing createJTSLinearRing(CoordinateSequence coordinates) {
188
        return getFactory(coordinates).createLinearRing(coordinates);
189
    }
190

    
191
    public static MultiPoint createJTSMultiPoint(CoordinateSequence coordinates) {
192
        return getFactory(coordinates).createMultiPoint(coordinates);
193
    }
194

    
195
    public static Geometry createGeometry(com.vividsolutions.jts.geom.Geometry jtsGeom) {
196
        if (jtsGeom instanceof com.vividsolutions.jts.geom.Point) {
197
            Coordinate coordinate = jtsGeom.getCoordinate();
198
            if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
199
                if (Double.isNaN(coordinate.z)) {
200
                    return new Point2DM(coordinate);
201
                } else {
202
                    return new Point3DM(coordinate);
203
                }
204
            } else {
205
                if (Double.isNaN(coordinate.z)) {
206
                    return new Point2D(coordinate);
207
                } else {
208
                    return new Point3D(coordinate);
209
                }
210
            }
211
        }
212

    
213
        if (jtsGeom instanceof com.vividsolutions.jts.geom.LineString) {
214
            Coordinate[] coordinates = jtsGeom.getCoordinates();
215
            Coordinate coordinate = jtsGeom.getCoordinate();
216
            com.vividsolutions.jts.geom.LineString lineString = (com.vividsolutions.jts.geom.LineString) jtsGeom;
217
            if (!lineString.isEmpty()) {
218
                if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
219
                    if (coordinate!=null && Double.isNaN(coordinate.z)) {
220
                        return new Line2DM(coordinates);
221
                    } else {
222
                        return new Line3DM(coordinates);
223
                    }
224
                } else {
225
                    if (coordinate!=null && Double.isNaN(coordinate.z)) {
226
                        return new Line2D(coordinates);
227
                    } else {
228
                        return new Line3D(coordinates);
229
                    }
230
                }
231
            }
232
        }
233

    
234
        if (jtsGeom instanceof com.vividsolutions.jts.geom.Polygon) {
235
            Polygon polygon;
236
            com.vividsolutions.jts.geom.Polygon polygonJTS = (com.vividsolutions.jts.geom.Polygon)jtsGeom;
237
            Coordinate[] coordinates = polygonJTS.getExteriorRing().getCoordinates();
238
            Coordinate coordinate = jtsGeom.getCoordinate();
239
            if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
240
                if (Double.isNaN(coordinate.z)) {
241
                    polygon = new Polygon2DM(coordinates);
242
                } else {
243
                    polygon = new Polygon3DM(coordinates);
244
                }
245
            } else {
246
                if (Double.isNaN(coordinate.z)) {
247
                    polygon = new Polygon2D(coordinates);
248
                } else {
249
                    polygon = new Polygon3D(coordinates);
250
                }
251
            }
252
            for(int i = 0; i<polygonJTS.getNumInteriorRing(); i++){
253
                LineString ringJTS = polygonJTS.getInteriorRingN(i);
254
                coordinates = ringJTS.getCoordinates();
255
                coordinate = ringJTS.getCoordinate();
256
                Ring ring;
257
                if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
258
                    if (Double.isNaN(coordinate.z)) {
259
                        ring = new Ring2DM(coordinates);
260
                    } else {
261
                        ring = new Ring3DM(coordinates);
262
                    }
263
                } else {
264
                    if (Double.isNaN(coordinate.z)) {
265
                        ring = new Ring2D(coordinates);
266
                    } else {
267
                        ring = new Ring3D(coordinates);
268
                    }
269
                }
270
                polygon.addInteriorRing(ring);
271
            }
272
            return polygon;
273
        }
274

    
275
        if (jtsGeom instanceof com.vividsolutions.jts.geom.GeometryCollection) {
276
            GeometryCollection collection = (com.vividsolutions.jts.geom.GeometryCollection)jtsGeom;
277
            Coordinate coordinate = collection.getCoordinate();
278
            MultiPrimitive multiprimitive = null;
279
            if (jtsGeom instanceof MultiLineString) {
280
                if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
281
                    if (Double.isNaN(coordinate.z)) {
282
                        multiprimitive = new MultiLine2DM();
283
                    } else {
284
                        multiprimitive = new MultiLine3DM();
285
                    }
286
                } else {
287
                    if (Double.isNaN(coordinate.z)) {
288
                        multiprimitive = new MultiLine2D();
289
                    } else {
290
                        multiprimitive = new MultiLine3D();
291
                    }
292
                }
293
            }
294
            if (jtsGeom instanceof MultiPolygon) {
295
                if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
296
                    if (Double.isNaN(coordinate.z)) {
297
                        multiprimitive = new MultiPolygon2DM();
298
                    } else {
299
                        multiprimitive = new MultiPolygon3DM();
300
                    }
301
                } else {
302
                    if (Double.isNaN(coordinate.z)) {
303
                        multiprimitive = new MultiPolygon2D();
304
                    } else {
305
                        multiprimitive = new MultiPolygon3D();
306
                    }
307
                }
308
            }
309

    
310
            if (jtsGeom instanceof MultiPoint) {
311
                if (jtsGeom.getFactory() instanceof MyMGeometryFactory) {
312
                    if (Double.isNaN(coordinate.z)) {
313
                        multiprimitive = new MultiPoint2DM();
314
                    } else {
315
                        multiprimitive = new MultiPoint3DM();
316
                    }
317
                } else {
318
                    if (Double.isNaN(coordinate.z)) {
319
                        multiprimitive = new MultiPoint2D();
320
                    } else {
321
                        multiprimitive = new MultiPoint3D();
322
                    }
323
                }
324
            }
325

    
326
            if (multiprimitive != null) {
327
                for (int i = 0; i < collection.getNumGeometries(); i++) {
328
                    com.vividsolutions.jts.geom.Geometry geometry = collection.getGeometryN(i);
329
                    multiprimitive.addPrimitive((Primitive) createGeometry(geometry));
330
                }
331
            }
332
            return multiprimitive;
333
        }
334

    
335
        return null;
336
    }
337

    
338
    /**
339
     * This function is called when the we need force types, that is the
340
     * destination
341
     * type does not match with the input geometry type
342
     *
343
     * @param g
344
     * @param sourceType
345
     * @param destinationType
346
     * @return
347
     */
348
    public static com.vividsolutions.jts.geom.Geometry convertTypes(com.vividsolutions.jts.geom.Geometry g,
349
        int sourceType, int destinationType) {
350

    
351
        com.vividsolutions.jts.geom.GeometryFactory factory = g.getFactory();
352

    
353
        if ((sourceType == Geometry.TYPES.CURVE || sourceType == Geometry.TYPES.SPLINE
354
            || sourceType == Geometry.TYPES.ARC || sourceType == Geometry.TYPES.ELLIPTICARC
355
            || sourceType == Geometry.TYPES.CIRCUMFERENCE || sourceType == Geometry.TYPES.PERIELLIPSE)
356
            && destinationType == Geometry.TYPES.MULTISURFACE) {
357
            if (g instanceof MultiLineString) {
358
                com.vividsolutions.jts.geom.Polygon[] poly = new com.vividsolutions.jts.geom.Polygon[((MultiLineString) g).getNumGeometries()];
359
                for (int i = 0; i < ((MultiLineString) g).getNumGeometries(); i++) {
360
                    com.vividsolutions.jts.geom.Geometry lineString = ((MultiLineString) g).getGeometryN(i);
361
                    poly[i] = convertLineStringToPolygon((LineString) lineString);
362
                }
363
                return factory.createMultiPolygon(poly);
364
            } else {
365
                return convertLineStringToPolygon((LineString) g);
366
            }
367
        }
368

    
369
        if ((sourceType == Geometry.TYPES.CIRCLE || sourceType == Geometry.TYPES.ELLIPSE
370
            || sourceType == Geometry.TYPES.ELLIPTICARC || sourceType == Geometry.TYPES.FILLEDSPLINE)
371
            && destinationType == Geometry.TYPES.MULTICURVE) {
372
            if (g instanceof com.vividsolutions.jts.geom.Polygon) {
373
                com.vividsolutions.jts.geom.Polygon poly = (com.vividsolutions.jts.geom.Polygon) g;
374
                LineString lineString = factory.createLinearRing(poly.getCoordinates());
375
                return factory.createMultiLineString(new LineString[] { lineString });
376
            }
377
        }
378
        return g;
379
    }
380

    
381
    private static com.vividsolutions.jts.geom.Polygon convertLineStringToPolygon(LineString line) {
382
        Coordinate[] coordinates = line.getCoordinates();
383
        com.vividsolutions.jts.geom.GeometryFactory factory = line.getFactory();
384
        LinearRing shell = factory.createLinearRing(coordinates);
385
        com.vividsolutions.jts.geom.Polygon pol = factory.createPolygon(shell, null);
386
        return pol;
387
    }
388

    
389
    public static MCoordinate createMCoordinate(double x, double y, double m) {
390
        return MCoordinate.create2dWithMeasure(x, y, m);
391
    }
392

    
393
    public static MCoordinate createMCoordinate(double x, double y, double z, double m) {
394
        return MCoordinate.create3dWithMeasure(x, y, z, m);
395
    }
396

    
397
    /**
398
     * @param init
399
     * @param middle
400
     * @param end
401
     * @return
402
     */
403
    public static Coordinate getCircumcentre(Point init, Point middle, Point end) {
404
        Triangle triangle =
405
            new Triangle(((PointJTS) init).getJTSCoordinate(),
406
                ((PointJTS) middle).getJTSCoordinate(),
407
                ((PointJTS) end).getJTSCoordinate());
408
        return triangle.circumcentre();
409
    }
410

    
411
    public static LineString createJTSLineStringFromArcPoints(Point centre, double radius, double startAngle, double endAngle){
412
        GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
413
        shapeFactory.setCentre(((PointJTS)centre).getJTSCoordinate());
414
        shapeFactory.setSize(radius*2);
415
        return shapeFactory.createArc(startAngle, endAngle);
416
    }
417

    
418
    public static MultiLineString createJTSMultiLineString(LineString[] lineStrings) {
419
        com.vividsolutions.jts.geom.GeometryFactory factory = JTSUtils.factory;
420
        if(lineStrings.length>0){
421
            factory = lineStrings[0].getFactory();
422
        }
423
        return factory.createMultiLineString(lineStrings);
424
    }
425

    
426
    /**
427
     * @param coordinates
428
     * @param interiorRings
429
     * @return
430
     * @throws GeometryException
431
     */
432
    public static com.vividsolutions.jts.geom.Polygon createJTSPolygon(ArrayListCoordinateSequence coordinates,
433
        List<Ring> interiorRings) {
434
        com.vividsolutions.jts.geom.GeometryFactory factory = getFactory(coordinates);
435

    
436
        LinearRing shell = factory.createLinearRing(coordinates);
437
        LinearRing[] holes = new LinearRing[interiorRings.size()];
438
        for(int i=0; i<interiorRings.size(); i++){
439
            Ring ring = interiorRings.get(i);
440
            holes[i] = (LinearRing) ((GeometryJTS) ring).getJTS();
441
        }
442
        return factory.createPolygon(shell, holes);
443
    }
444

    
445

    
446
    /**
447
     * @param coordinates
448
     * @return
449
     * @throws GeometryException
450
     */
451
    public static com.vividsolutions.jts.geom.Polygon createJTSPolygon(ArrayListCoordinateSequence coordinates) {
452
        com.vividsolutions.jts.geom.GeometryFactory factory = getFactory(coordinates);
453

    
454
        LinearRing shell = factory.createLinearRing(coordinates);
455
        return factory.createPolygon(shell);
456
    }
457

    
458
    public static com.vividsolutions.jts.geom.MultiPolygon createJTSMultiPolygon(com.vividsolutions.jts.geom.Polygon[] polygons){
459
        com.vividsolutions.jts.geom.GeometryFactory factory = JTSUtils.factory;
460
        if(polygons.length>0){
461
            factory = polygons[0].getFactory();
462
        }
463
        return factory.createMultiPolygon(polygons);
464
    }
465

    
466
    /**
467
     * Returns the intersection point between an ellipse and her minor axis.
468
     *
469
     * @param init
470
     * @param middle
471
     * @param end
472
     * @return
473
     */
474
    public static Coordinate getPointAtYAxisInEllipse(Point init, Point end, Double ydist) {
475

    
476
        LineSegment segment = new LineSegment(((PointJTS) init).getJTSCoordinate(),
477
            ((PointJTS) end).getJTSCoordinate());
478
        Coordinate middle = segment.midPoint();
479

    
480
        LineSegment midSegment = new LineSegment(middle, ((PointJTS) end).getJTSCoordinate());
481
        double modulus = midSegment.getLength();
482

    
483
        //Mayor semi-axis unitary vector
484
        Coordinate uni = new Coordinate((end.getX()-middle.x)/modulus, (end.getY()-middle.y)/modulus);
485

    
486
        //Minor axis unitary vector
487
        Coordinate perpUni = new Coordinate(-uni.y,uni.x);
488

    
489
        Coordinate point = new Coordinate(middle.x+(perpUni.x*ydist), middle.y+(perpUni.y*ydist));
490

    
491
        return point;
492
    }
493

    
494
    /**
495
     * Returns the middle point between two points.
496
     *
497
     * @param init
498
     * @param middle
499
     * @param end
500
     * @return
501
     */
502
    public static Coordinate getMidPoint(Point init, Point end) {
503

    
504
        LineSegment segment = new LineSegment(((PointJTS) init).getJTSCoordinate(),
505
            ((PointJTS) end).getJTSCoordinate());
506
        Coordinate middle = segment.midPoint();
507
        return middle;
508
    }
509

    
510
    /**
511
     * @param coordinate
512
     * @return
513
     */
514
    public static com.vividsolutions.jts.geom.Geometry createJTSPoint(Coordinate coordinate) {
515
        return getFactory(coordinate).createPoint(coordinate);
516
    }
517

    
518
    /**
519
     * @param coord
520
     * @return
521
     */
522
    public static com.vividsolutions.jts.geom.Geometry createJTSPolygon(Coordinate[] coordinates) {
523
        return getFactory(coordinates).createPolygon(coordinates);
524
    }
525

    
526

    
527
}