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

History | View | Annotate | Download (16.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.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

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

    
83
/**
84
 * @author fdiaz
85
 *
86
 */
87
public class JTSUtils {
88

    
89
    public static final Logger logger = LoggerFactory.getLogger(JTSUtils.class);
90

    
91
    public static final com.vividsolutions.jts.geom.GeometryFactory factory =
92
        new com.vividsolutions.jts.geom.GeometryFactory();
93

    
94
    public static Point createPoint(GeometryType type, Coordinate coordinate) throws CreateGeometryException {
95

    
96
        switch (type.getSubType()) {
97
        case Geometry.SUBTYPES.GEOM2D:
98
            return new Point2D(coordinate);
99
        case Geometry.SUBTYPES.GEOM2DM:
100
            return new Point2DM(coordinate);
101
        case Geometry.SUBTYPES.GEOM3D:
102
            return new Point3D(coordinate);
103
        case Geometry.SUBTYPES.GEOM3DM:
104
            return new Point3DM(coordinate);
105
        default:
106
            Point p = null;
107
            p = (Point) type.create();
108
            for (int i = 0; i < p.getDimension(); i++) {
109
                p.setCoordinateAt(i, coordinate.getOrdinate(i));
110
            }
111
            break;
112
        }
113

    
114
        return null;
115
    }
116

    
117
    public static LineString createJTSLineString(CoordinateSequence coordinates) {
118
        return factory.createLineString(coordinates);
119
    }
120

    
121
    public static LinearRing createJTSLinearRing(CoordinateSequence coordinates) {
122
        return factory.createLinearRing(coordinates);
123
    }
124

    
125
    public static MultiPoint createJTSMultiPoint(CoordinateSequence coordinates) {
126
        return factory.createMultiPoint(coordinates);
127
    }
128

    
129
    public static Geometry createGeometry(com.vividsolutions.jts.geom.Geometry jtsGeom) {
130
        if (jtsGeom instanceof com.vividsolutions.jts.geom.Point) {
131
            com.vividsolutions.jts.geom.Point point = (com.vividsolutions.jts.geom.Point)jtsGeom;
132
            Coordinate coordinate = jtsGeom.getCoordinate();
133
            if (coordinate instanceof MCoordinate) {
134
                if (Double.isNaN(coordinate.z)) {
135
                    return new Point2DM(coordinate);
136
                } else {
137
                    return new Point3DM(coordinate);
138
                }
139
            } else {
140
                if (Double.isNaN(coordinate.z)) {
141
                    return new Point2D(coordinate);
142
                } else {
143
                    return new Point3D(coordinate);
144
                }
145
            }
146
        }
147

    
148
        if (jtsGeom instanceof com.vividsolutions.jts.geom.LineString) {
149
            Coordinate[] coordinates = jtsGeom.getCoordinates();
150
            Coordinate coordinate = jtsGeom.getCoordinate();
151
            if (coordinate instanceof MCoordinate) {
152
                if (Double.isNaN(coordinate.z)) {
153
                    return new Line2DM(coordinates);
154
                } else {
155
                    return new Line3DM(coordinates);
156
                }
157
            } else {
158
                if (Double.isNaN(coordinate.z)) {
159
                    return new Line2D(coordinates);
160
                } else {
161
                    return new Line3D(coordinates);
162
                }
163
            }
164
        }
165

    
166
        if (jtsGeom instanceof com.vividsolutions.jts.geom.Polygon) {
167
            Polygon polygon;
168
            com.vividsolutions.jts.geom.Polygon polygonJTS = (com.vividsolutions.jts.geom.Polygon)jtsGeom;
169
            Coordinate[] coordinates = polygonJTS.getExteriorRing().getCoordinates();
170
            Coordinate coordinate = jtsGeom.getCoordinate();
171
            if (coordinate instanceof MCoordinate) {
172
                if (Double.isNaN(coordinate.z)) {
173
                    polygon = new Polygon2DM(coordinates);
174
                } else {
175
                    polygon = new Polygon3DM(coordinates);
176
                }
177
            } else {
178
                if (Double.isNaN(coordinate.z)) {
179
                    polygon = new Polygon2D(coordinates);
180
                } else {
181
                    polygon = new Polygon3D(coordinates);
182
                }
183
            }
184
            for(int i = 0; i<polygonJTS.getNumInteriorRing(); i++){
185
                LineString ringJTS = polygonJTS.getInteriorRingN(i);
186
                coordinates = ringJTS.getCoordinates();
187
                coordinate = ringJTS.getCoordinate();
188
                Ring ring;
189
                if (coordinate instanceof MCoordinate) {
190
                    if (Double.isNaN(coordinate.z)) {
191
                        ring = new Ring2DM(coordinates);
192
                    } else {
193
                        ring = new Ring3DM(coordinates);
194
                    }
195
                } else {
196
                    if (Double.isNaN(coordinate.z)) {
197
                        ring = new Ring2D(coordinates);
198
                    } else {
199
                        ring = new Ring3D(coordinates);
200
                    }
201
                }
202
                polygon.addInteriorRing(ring);
203
            }
204
            return polygon;
205
        }
206

    
207
        if (jtsGeom instanceof com.vividsolutions.jts.geom.GeometryCollection) {
208
            GeometryCollection collection = (com.vividsolutions.jts.geom.GeometryCollection)jtsGeom;
209
            Coordinate coordinate = collection.getCoordinate();
210
            MultiPrimitive multiprimitive = null;
211
            if (jtsGeom instanceof MultiLineString) {
212
                if (coordinate instanceof MCoordinate) {
213
                    if (Double.isNaN(coordinate.z)) {
214
                        multiprimitive = new MultiLine2DM();
215
                    } else {
216
                        multiprimitive = new MultiLine3DM();
217
                    }
218
                } else {
219
                    if (Double.isNaN(coordinate.z)) {
220
                        multiprimitive = new MultiLine2D();
221
                    } else {
222
                        multiprimitive = new MultiLine3D();
223
                    }
224
                }
225
            }
226
            if (jtsGeom instanceof MultiPolygon) {
227
                if (coordinate instanceof MCoordinate) {
228
                    if (Double.isNaN(coordinate.z)) {
229
                        multiprimitive = new MultiPolygon2DM();
230
                    } else {
231
                        multiprimitive = new MultiPolygon3DM();
232
                    }
233
                } else {
234
                    if (Double.isNaN(coordinate.z)) {
235
                        multiprimitive = new MultiPolygon2D();
236
                    } else {
237
                        multiprimitive = new MultiPolygon3D();
238
                    }
239
                }
240
            }
241

    
242
            if (jtsGeom instanceof MultiPoint) {
243
                if (coordinate instanceof MCoordinate) {
244
                    if (Double.isNaN(coordinate.z)) {
245
                        multiprimitive = new MultiPoint2DM();
246
                    } else {
247
                        multiprimitive = new MultiPoint3DM();
248
                    }
249
                } else {
250
                    if (Double.isNaN(coordinate.z)) {
251
                        multiprimitive = new MultiPoint2D();
252
                    } else {
253
                        multiprimitive = new MultiPoint3D();
254
                    }
255
                }
256
            }
257

    
258
            if (multiprimitive != null) {
259
                for (int i = 0; i < collection.getNumGeometries(); i++) {
260
                    com.vividsolutions.jts.geom.Geometry geometry = collection.getGeometryN(i);
261
                    multiprimitive.addPrimitive((Primitive) createGeometry(geometry));
262
                }
263
            }
264
            return multiprimitive;
265
        }
266

    
267
        return null;
268
    }
269

    
270
    /**
271
     * This function is called when the we need force types, that is the
272
     * destination
273
     * type does not match with the input geometry type
274
     *
275
     * @param g
276
     * @param sourceType
277
     * @param destinationType
278
     * @return
279
     */
280
    public static com.vividsolutions.jts.geom.Geometry convertTypes(com.vividsolutions.jts.geom.Geometry g,
281
        int sourceType, int destinationType) {
282
        if ((sourceType == Geometry.TYPES.CURVE || sourceType == Geometry.TYPES.SPLINE
283
            || sourceType == Geometry.TYPES.ARC || sourceType == Geometry.TYPES.ELLIPTICARC
284
            || sourceType == Geometry.TYPES.CIRCUMFERENCE || sourceType == Geometry.TYPES.PERIELLIPSE)
285
            && destinationType == Geometry.TYPES.MULTISURFACE) {
286
            if (g instanceof MultiLineString) {
287
                com.vividsolutions.jts.geom.Polygon[] poly = new com.vividsolutions.jts.geom.Polygon[((MultiLineString) g).getNumGeometries()];
288
                for (int i = 0; i < ((MultiLineString) g).getNumGeometries(); i++) {
289
                    com.vividsolutions.jts.geom.Geometry lineString = ((MultiLineString) g).getGeometryN(i);
290
                    poly[i] = convertLineStringToPolygon((LineString) lineString);
291
                }
292
                return factory.createMultiPolygon(poly);
293
            } else {
294
                return convertLineStringToPolygon((LineString) g);
295
            }
296
        }
297

    
298
        if ((sourceType == Geometry.TYPES.CIRCLE || sourceType == Geometry.TYPES.ELLIPSE
299
            || sourceType == Geometry.TYPES.ELLIPTICARC || sourceType == Geometry.TYPES.FILLEDSPLINE)
300
            && destinationType == Geometry.TYPES.MULTICURVE) {
301
            if (g instanceof com.vividsolutions.jts.geom.Polygon) {
302
                com.vividsolutions.jts.geom.Polygon poly = (com.vividsolutions.jts.geom.Polygon) g;
303
                LineString lineString = factory.createLinearRing(poly.getCoordinates());
304
                return factory.createMultiLineString(new LineString[] { lineString });
305
            }
306
        }
307
        return g;
308
    }
309

    
310
    private static com.vividsolutions.jts.geom.Polygon convertLineStringToPolygon(LineString line) {
311
        Coordinate[] coordinates = line.getCoordinates();
312
        LinearRing shell = factory.createLinearRing(coordinates);
313
        com.vividsolutions.jts.geom.Polygon pol = factory.createPolygon(shell, null);
314
        return pol;
315
    }
316

    
317
    public static MCoordinate createMCoordinate(double x, double y, double m) {
318
        return MCoordinate.create2dWithMeasure(x, y, m);
319
    }
320

    
321
    public static MCoordinate createMCoordinate(double x, double y, double z, double m) {
322
        return MCoordinate.create3dWithMeasure(x, y, z, m);
323
    }
324

    
325
    /**
326
     * @param init
327
     * @param middle
328
     * @param end
329
     * @return
330
     */
331
    public static Coordinate getCircumcentre(Point init, Point middle, Point end) {
332
        Triangle triangle =
333
            new Triangle(((PointJTS) init).getJTSCoordinate(),
334
                ((PointJTS) middle).getJTSCoordinate(),
335
                ((PointJTS) end).getJTSCoordinate());
336
        return triangle.circumcentre();
337
    }
338

    
339
    public static LineString createJTSLineStringFromArcPoints(Point centre, double radius, double startAngle, double endAngle){
340
        GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
341
        shapeFactory.setCentre(((PointJTS)centre).getJTSCoordinate());
342
        shapeFactory.setSize(radius*2);
343
        return shapeFactory.createArc(startAngle, endAngle);
344
    }
345

    
346
    public static MultiLineString createJTSMultiLineString(LineString[] lineStrings) {
347
        return factory.createMultiLineString(lineStrings);
348
    }
349

    
350
    /**
351
     * @param coordinates
352
     * @param interiorRings
353
     * @return
354
     * @throws GeometryException
355
     */
356
    public static com.vividsolutions.jts.geom.Polygon createJTSPolygon(ArrayListCoordinateSequence coordinates,
357
        List<Ring> interiorRings) {
358
        LinearRing shell = factory.createLinearRing(coordinates);
359
        LinearRing[] holes = new LinearRing[interiorRings.size()];
360
        for(int i=0; i<interiorRings.size(); i++){
361
            Ring ring = interiorRings.get(i);
362
            holes[i] = (LinearRing) ((GeometryJTS) ring).getJTS();
363
        }
364
        return factory.createPolygon(shell, holes);
365
    }
366

    
367

    
368
    /**
369
     * @param coordinates
370
     * @return
371
     * @throws GeometryException
372
     */
373
    public static com.vividsolutions.jts.geom.Polygon createJTSPolygon(ArrayListCoordinateSequence coordinates) {
374
        LinearRing shell = factory.createLinearRing(coordinates);
375
        return factory.createPolygon(shell);
376
    }
377

    
378
    public static com.vividsolutions.jts.geom.MultiPolygon createJTSMultiPolygon(com.vividsolutions.jts.geom.Polygon[] polygons){
379
        return factory.createMultiPolygon(polygons);
380
    }
381

    
382
    /**
383
     * Returns the intersection point between an ellipse and her minor axis.
384
     *
385
     * @param init
386
     * @param middle
387
     * @param end
388
     * @return
389
     */
390
    public static Coordinate getPointAtYAxisInEllipse(Point init, Point end, Double ydist) {
391

    
392
        LineSegment segment = new LineSegment(((PointJTS) init).getJTSCoordinate(),
393
            ((PointJTS) end).getJTSCoordinate());
394
        Coordinate middle = segment.midPoint();
395

    
396
        LineSegment midSegment = new LineSegment(middle, ((PointJTS) end).getJTSCoordinate());
397
        double modulus = midSegment.getLength();
398

    
399
        //Mayor semi-axis unitary vector
400
        Coordinate uni = new Coordinate((end.getX()-middle.x)/modulus, (end.getY()-middle.y)/modulus);
401

    
402
        //Minor axis unitary vector
403
        Coordinate perpUni = new Coordinate(-uni.y,uni.x);
404

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

    
407
        return point;
408
    }
409

    
410
    /**
411
     * Returns the middle point between two points.
412
     *
413
     * @param init
414
     * @param middle
415
     * @param end
416
     * @return
417
     */
418
    public static Coordinate getMidPoint(Point init, Point end) {
419

    
420
        LineSegment segment = new LineSegment(((PointJTS) init).getJTSCoordinate(),
421
            ((PointJTS) end).getJTSCoordinate());
422
        Coordinate middle = segment.midPoint();
423
        return middle;
424
    }
425

    
426

    
427
}