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 @ 47669
History | View | Annotate | Download (32.7 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 3
|
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 com.vividsolutions.jts.geom.Coordinate; |
26 |
import com.vividsolutions.jts.geom.CoordinateSequence; |
27 |
import com.vividsolutions.jts.geom.CoordinateSequenceFactory; |
28 |
import com.vividsolutions.jts.geom.CoordinateSequences; |
29 |
import com.vividsolutions.jts.geom.GeometryCollection; |
30 |
import com.vividsolutions.jts.geom.GeometryFactory; |
31 |
import com.vividsolutions.jts.geom.LineSegment; |
32 |
import com.vividsolutions.jts.geom.LineString; |
33 |
import com.vividsolutions.jts.geom.LinearRing; |
34 |
import com.vividsolutions.jts.geom.MultiLineString; |
35 |
import com.vividsolutions.jts.geom.MultiPoint; |
36 |
import com.vividsolutions.jts.geom.MultiPolygon; |
37 |
import com.vividsolutions.jts.geom.Triangle; |
38 |
import com.vividsolutions.jts.linearref.LengthLocationMap; |
39 |
import com.vividsolutions.jts.linearref.LinearLocation; |
40 |
import com.vividsolutions.jts.linearref.LocationIndexedLine; |
41 |
import com.vividsolutions.jts.operation.buffer.BufferParameters; |
42 |
import com.vividsolutions.jts.operation.buffer.OffsetCurveBuilder; |
43 |
import com.vividsolutions.jts.util.GeometricShapeFactory; |
44 |
import java.util.ArrayList; |
45 |
import java.util.List; |
46 |
import org.cresques.cts.IProjection; |
47 |
import org.gvsig.fmap.geom.Geometry; |
48 |
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_BEVEL; |
49 |
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_MITRE; |
50 |
import static org.gvsig.fmap.geom.Geometry.JOIN_STYLE_ROUND; |
51 |
import org.gvsig.fmap.geom.aggregate.MultiPrimitive; |
52 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
53 |
import org.gvsig.fmap.geom.jts.GeometryJTS; |
54 |
import org.gvsig.fmap.geom.jts.aggregate.MultiLine2D; |
55 |
import org.gvsig.fmap.geom.jts.aggregate.MultiLine2DM; |
56 |
import org.gvsig.fmap.geom.jts.aggregate.MultiLine3D; |
57 |
import org.gvsig.fmap.geom.jts.aggregate.MultiLine3DM; |
58 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint2D; |
59 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint2DM; |
60 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint3D; |
61 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPoint3DM; |
62 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon2D; |
63 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon2DM; |
64 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon3D; |
65 |
import org.gvsig.fmap.geom.jts.aggregate.MultiPolygon3DM; |
66 |
import org.gvsig.fmap.geom.jts.complex.DefaultComplex; |
67 |
import org.gvsig.fmap.geom.jts.mgeom.MCoordinate; |
68 |
import org.gvsig.fmap.geom.jts.mgeom.MCoordinateSequence; |
69 |
import org.gvsig.fmap.geom.jts.mgeom.MGeometryFactory; |
70 |
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line2D; |
71 |
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line2DM; |
72 |
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line3D; |
73 |
import org.gvsig.fmap.geom.jts.primitive.curve.line.Line3DM; |
74 |
import org.gvsig.fmap.geom.jts.primitive.point.Point2D; |
75 |
import org.gvsig.fmap.geom.jts.primitive.point.Point2DM; |
76 |
import org.gvsig.fmap.geom.jts.primitive.point.Point3D; |
77 |
import org.gvsig.fmap.geom.jts.primitive.point.Point3DM; |
78 |
import org.gvsig.fmap.geom.jts.primitive.point.PointJTS; |
79 |
import org.gvsig.fmap.geom.jts.primitive.ring.Ring2D; |
80 |
import org.gvsig.fmap.geom.jts.primitive.ring.Ring2DM; |
81 |
import org.gvsig.fmap.geom.jts.primitive.ring.Ring3D; |
82 |
import org.gvsig.fmap.geom.jts.primitive.ring.Ring3DM; |
83 |
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon2D; |
84 |
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon2DM; |
85 |
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon3D; |
86 |
import org.gvsig.fmap.geom.jts.primitive.surface.polygon.Polygon3DM; |
87 |
import org.gvsig.fmap.geom.primitive.Line; |
88 |
import org.gvsig.fmap.geom.primitive.Point; |
89 |
import org.gvsig.fmap.geom.primitive.Polygon; |
90 |
import org.gvsig.fmap.geom.primitive.Primitive; |
91 |
import org.gvsig.fmap.geom.primitive.Ring; |
92 |
import org.gvsig.fmap.geom.type.GeometryType; |
93 |
import org.slf4j.Logger; |
94 |
import org.slf4j.LoggerFactory; |
95 |
|
96 |
/**
|
97 |
* @author fdiaz
|
98 |
*
|
99 |
*/
|
100 |
public class JTSUtils { |
101 |
|
102 |
public static final Logger logger = LoggerFactory.getLogger(JTSUtils.class); |
103 |
|
104 |
private static class MyMGeometryFactory extends MGeometryFactory { |
105 |
|
106 |
/**
|
107 |
*
|
108 |
*/
|
109 |
private static final long serialVersionUID = -8174926092714691479L; |
110 |
|
111 |
@Override
|
112 |
public com.vividsolutions.jts.geom.Point createPoint(CoordinateSequence coordinates) {
|
113 |
if(!(coordinates instanceof MCoordinateSequence)){ |
114 |
if (coordinates != null) { |
115 |
coordinates = new MCoordinateSequence(coordinates);
|
116 |
} |
117 |
} |
118 |
return (com.vividsolutions.jts.geom.Point) new com.vividsolutions.jts.geom.Point(coordinates, this); |
119 |
} |
120 |
|
121 |
@Override
|
122 |
public LinearRing createLinearRing(CoordinateSequence coordinates) {
|
123 |
if(!(coordinates instanceof MCoordinateSequence)){ |
124 |
if (coordinates != null) { |
125 |
coordinates = new MCoordinateSequence(coordinates);
|
126 |
} |
127 |
} |
128 |
return super.createLinearRing(coordinates); |
129 |
} |
130 |
|
131 |
@Override
|
132 |
public LineString createLineString(CoordinateSequence coordinates) {
|
133 |
if(!(coordinates instanceof MCoordinateSequence)){ |
134 |
if (coordinates != null) { |
135 |
coordinates = new MCoordinateSequence(coordinates);
|
136 |
} |
137 |
} |
138 |
return super.createLineString(coordinates); |
139 |
} |
140 |
|
141 |
@Override
|
142 |
public MultiPoint createMultiPoint(CoordinateSequence coordinates) {
|
143 |
if(!(coordinates instanceof MCoordinateSequence)){ |
144 |
if (coordinates != null) { |
145 |
coordinates = new MCoordinateSequence(coordinates);
|
146 |
} |
147 |
} |
148 |
return super.createMultiPoint(coordinates); |
149 |
} |
150 |
|
151 |
} |
152 |
|
153 |
|
154 |
private static final com.vividsolutions.jts.geom.GeometryFactory factory = |
155 |
new com.vividsolutions.jts.geom.GeometryFactory();
|
156 |
|
157 |
private static final com.vividsolutions.jts.geom.GeometryFactory mfactory = new MyMGeometryFactory(); |
158 |
|
159 |
public static Point createPoint(GeometryType type, IProjection proj, Coordinate coordinate) throws CreateGeometryException { |
160 |
|
161 |
Point p;
|
162 |
switch (type.getSubType()) {
|
163 |
case Geometry.SUBTYPES.GEOM2D:
|
164 |
p = new Point2D(proj, coordinate); |
165 |
break;
|
166 |
case Geometry.SUBTYPES.GEOM2DM:
|
167 |
p = new Point2DM(proj, coordinate);
|
168 |
break;
|
169 |
case Geometry.SUBTYPES.GEOM3D:
|
170 |
p = new Point3D(proj, coordinate);
|
171 |
break;
|
172 |
case Geometry.SUBTYPES.GEOM3DM:
|
173 |
p = new Point3DM(proj, coordinate);
|
174 |
break;
|
175 |
default:
|
176 |
p = (Point) type.create();
|
177 |
for (int i = 0; i < p.getDimension(); i++) { |
178 |
p.setCoordinateAt(i, coordinate.getOrdinate(i)); |
179 |
} |
180 |
p.setProjection(proj); |
181 |
break;
|
182 |
} |
183 |
return p;
|
184 |
} |
185 |
|
186 |
public static com.vividsolutions.jts.geom.GeometryFactory getFactory(CoordinateSequence coordinates){ |
187 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = JTSUtils.factory; |
188 |
if(coordinates.size()>0 && coordinates.getCoordinate(0) instanceof MCoordinate){ |
189 |
theFactory = mfactory; |
190 |
} |
191 |
return theFactory;
|
192 |
} |
193 |
|
194 |
public static com.vividsolutions.jts.geom.GeometryFactory getFactory(Coordinate coordinate) { |
195 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = JTSUtils.factory; |
196 |
if(coordinate instanceof MCoordinate){ |
197 |
theFactory = mfactory; |
198 |
} |
199 |
return theFactory;
|
200 |
} |
201 |
|
202 |
public static com.vividsolutions.jts.geom.GeometryFactory getFactory(Coordinate[] coordinates) { |
203 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = JTSUtils.factory; |
204 |
if(coordinates.length>0 && coordinates[0] instanceof MCoordinate){ |
205 |
theFactory = mfactory; |
206 |
} |
207 |
return theFactory;
|
208 |
} |
209 |
|
210 |
public static LineString createJTSLineString(CoordinateSequence coordinates) { |
211 |
return getFactory(coordinates).createLineString(coordinates);
|
212 |
} |
213 |
|
214 |
public static LinearRing createJTSLinearRing(CoordinateSequence coordinates) { |
215 |
GeometryFactory fact = getFactory(coordinates); |
216 |
return fact.createLinearRing(CoordinateSequences.ensureValidRing(fact.getCoordinateSequenceFactory(), coordinates));
|
217 |
} |
218 |
|
219 |
public static LinearRing createJTSLinearRing(Coordinate[] coordinates) { |
220 |
GeometryFactory fact = getFactory(coordinates); |
221 |
CoordinateSequenceFactory coordinateSequenceFactory = fact.getCoordinateSequenceFactory(); |
222 |
return fact.createLinearRing(CoordinateSequences.ensureValidRing(coordinateSequenceFactory, coordinateSequenceFactory.create(coordinates)));
|
223 |
} |
224 |
|
225 |
public static MultiPoint createJTSMultiPoint(CoordinateSequence coordinates) { |
226 |
return getFactory(coordinates).createMultiPoint(coordinates);
|
227 |
} |
228 |
|
229 |
public static Geometry createGeometry(IProjection proj, com.vividsolutions.jts.geom.Geometry jtsGeom) { |
230 |
return createGeometry(proj, jtsGeom, null); |
231 |
} |
232 |
|
233 |
public static Geometry createGeometry(IProjection proj, com.vividsolutions.jts.geom.Geometry jtsGeom, GeometryType typeWhenEmpty) { |
234 |
if(jtsGeom.isEmpty()){
|
235 |
if(typeWhenEmpty == null){ |
236 |
return null; |
237 |
} |
238 |
try {
|
239 |
return typeWhenEmpty.create();
|
240 |
} catch (CreateGeometryException ex) {
|
241 |
return null; |
242 |
} |
243 |
} |
244 |
if (jtsGeom instanceof com.vividsolutions.jts.geom.Point) { |
245 |
Coordinate coordinate = jtsGeom.getCoordinate(); |
246 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
247 |
if (Double.isNaN(coordinate.z)) { |
248 |
return new Point2DM(proj, coordinate); |
249 |
} else {
|
250 |
return new Point3DM(proj, coordinate); |
251 |
} |
252 |
} else {
|
253 |
if (Double.isNaN(coordinate.z)) { |
254 |
return new Point2D(proj, coordinate); |
255 |
} else {
|
256 |
return new Point3D(proj, coordinate); |
257 |
} |
258 |
} |
259 |
} |
260 |
|
261 |
if (jtsGeom instanceof com.vividsolutions.jts.geom.LineString) { |
262 |
Coordinate[] coordinates = jtsGeom.getCoordinates();
|
263 |
Coordinate coordinate = jtsGeom.getCoordinate(); |
264 |
com.vividsolutions.jts.geom.LineString lineString = (com.vividsolutions.jts.geom.LineString) jtsGeom; |
265 |
if (!lineString.isEmpty()) {
|
266 |
Line line;
|
267 |
if (jtsGeom.getFactory() instanceof MGeometryFactory) { |
268 |
if (coordinate!=null && Double.isNaN(coordinate.z)) { |
269 |
line = new Line2DM(coordinates);
|
270 |
} else {
|
271 |
line = new Line3DM(coordinates);
|
272 |
} |
273 |
} else {
|
274 |
if (coordinate!=null && Double.isNaN(coordinate.z)) { |
275 |
line = new Line2D(coordinates); |
276 |
} else {
|
277 |
line = new Line3D(coordinates);
|
278 |
} |
279 |
} |
280 |
line.setProjection(proj); |
281 |
return line;
|
282 |
} |
283 |
} |
284 |
|
285 |
if (jtsGeom instanceof com.vividsolutions.jts.geom.Polygon && !jtsGeom.isEmpty()) { |
286 |
Polygon polygon;
|
287 |
com.vividsolutions.jts.geom.Polygon polygonJTS = (com.vividsolutions.jts.geom.Polygon)jtsGeom; |
288 |
Coordinate[] coordinates = polygonJTS.getExteriorRing().getCoordinates();
|
289 |
Coordinate coordinate = jtsGeom.getCoordinate(); |
290 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
291 |
if (Double.isNaN(coordinate.z)) { |
292 |
polygon = new Polygon2DM(coordinates);
|
293 |
} else {
|
294 |
polygon = new Polygon3DM(coordinates);
|
295 |
} |
296 |
} else {
|
297 |
if (Double.isNaN(coordinate.z)) { |
298 |
polygon = new Polygon2D(coordinates);
|
299 |
} else {
|
300 |
polygon = new Polygon3D(coordinates);
|
301 |
} |
302 |
} |
303 |
polygon.setProjection(proj); |
304 |
for(int i = 0; i<polygonJTS.getNumInteriorRing(); i++){ |
305 |
LineString ringJTS = polygonJTS.getInteriorRingN(i); |
306 |
coordinates = ringJTS.getCoordinates(); |
307 |
coordinate = ringJTS.getCoordinate(); |
308 |
Ring ring; |
309 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
310 |
if (Double.isNaN(coordinate.z)) { |
311 |
ring = new Ring2DM(coordinates);
|
312 |
} else {
|
313 |
ring = new Ring3DM(coordinates);
|
314 |
} |
315 |
} else {
|
316 |
if (Double.isNaN(coordinate.z)) { |
317 |
ring = new Ring2D(coordinates);
|
318 |
} else {
|
319 |
ring = new Ring3D(coordinates);
|
320 |
} |
321 |
} |
322 |
ring.setProjection(proj); |
323 |
polygon.addInteriorRing(ring); |
324 |
} |
325 |
return polygon;
|
326 |
} |
327 |
|
328 |
if (jtsGeom instanceof com.vividsolutions.jts.geom.GeometryCollection) { |
329 |
GeometryCollection collection = (com.vividsolutions.jts.geom.GeometryCollection)jtsGeom; |
330 |
Coordinate coordinate = collection.getCoordinate(); |
331 |
MultiPrimitive multiprimitive = null;
|
332 |
if (jtsGeom instanceof MultiLineString) { |
333 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
334 |
if (Double.isNaN(coordinate.z)) { |
335 |
multiprimitive = new MultiLine2DM();
|
336 |
} else {
|
337 |
multiprimitive = new MultiLine3DM();
|
338 |
} |
339 |
} else {
|
340 |
if (Double.isNaN(coordinate.z)) { |
341 |
multiprimitive = new MultiLine2D();
|
342 |
} else {
|
343 |
multiprimitive = new MultiLine3D();
|
344 |
} |
345 |
} |
346 |
} else if (jtsGeom instanceof MultiPolygon) { |
347 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
348 |
if (Double.isNaN(coordinate.z)) { |
349 |
multiprimitive = new MultiPolygon2DM();
|
350 |
} else {
|
351 |
multiprimitive = new MultiPolygon3DM();
|
352 |
} |
353 |
} else {
|
354 |
if (Double.isNaN(coordinate.z)) { |
355 |
multiprimitive = new MultiPolygon2D();
|
356 |
} else {
|
357 |
multiprimitive = new MultiPolygon3D();
|
358 |
} |
359 |
} |
360 |
} else if (jtsGeom instanceof MultiPoint) { |
361 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
362 |
if (Double.isNaN(coordinate.z)) { |
363 |
multiprimitive = new MultiPoint2DM();
|
364 |
} else {
|
365 |
multiprimitive = new MultiPoint3DM();
|
366 |
} |
367 |
} else {
|
368 |
if (Double.isNaN(coordinate.z)) { |
369 |
multiprimitive = new MultiPoint2D();
|
370 |
} else {
|
371 |
multiprimitive = new MultiPoint3D();
|
372 |
} |
373 |
} |
374 |
} |
375 |
|
376 |
if (multiprimitive != null) { |
377 |
for (int i = 0; i < collection.getNumGeometries(); i++) { |
378 |
com.vividsolutions.jts.geom.Geometry geometry = collection.getGeometryN(i); |
379 |
multiprimitive.addPrimitive((Primitive) createGeometry(proj, geometry)); |
380 |
} |
381 |
multiprimitive.setProjection(proj); |
382 |
return multiprimitive;
|
383 |
} else {
|
384 |
int subtype;
|
385 |
if (jtsGeom.getFactory() instanceof MyMGeometryFactory) { |
386 |
if (Double.isNaN(coordinate.z)) { |
387 |
subtype = Geometry.SUBTYPES.GEOM2DM; |
388 |
} else {
|
389 |
subtype = Geometry.SUBTYPES.GEOM3DM; |
390 |
} |
391 |
} else {
|
392 |
if (Double.isNaN(coordinate.z)) { |
393 |
subtype = Geometry.SUBTYPES.GEOM2D; |
394 |
} else {
|
395 |
subtype = Geometry.SUBTYPES.GEOM3D; |
396 |
} |
397 |
} |
398 |
DefaultComplex complex = new DefaultComplex(subtype);
|
399 |
for (int i = 0; i < collection.getNumGeometries(); i++) { |
400 |
com.vividsolutions.jts.geom.Geometry geometry = collection.getGeometryN(i); |
401 |
complex.addPrimitive((Primitive) createGeometry(proj, geometry)); |
402 |
} |
403 |
complex.setProjection(proj); |
404 |
return complex;
|
405 |
} |
406 |
} |
407 |
|
408 |
return null; |
409 |
} |
410 |
|
411 |
/**
|
412 |
* This function is called when the we need force types, that is the
|
413 |
* destination
|
414 |
* type does not match with the input geometry type
|
415 |
*
|
416 |
* @param g
|
417 |
* @param sourceType
|
418 |
* @param destinationType
|
419 |
* @return
|
420 |
*/
|
421 |
public static com.vividsolutions.jts.geom.Geometry convertTypes(com.vividsolutions.jts.geom.Geometry g, |
422 |
int sourceType, int destinationType) { |
423 |
|
424 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = g.getFactory(); |
425 |
|
426 |
if ((sourceType == Geometry.TYPES.CURVE || sourceType == Geometry.TYPES.SPLINE
|
427 |
|| sourceType == Geometry.TYPES.ARC || sourceType == Geometry.TYPES.ELLIPTICARC |
428 |
|| sourceType == Geometry.TYPES.CIRCUMFERENCE || sourceType == Geometry.TYPES.PERIELLIPSE) |
429 |
&& destinationType == Geometry.TYPES.MULTISURFACE) { |
430 |
if (g instanceof MultiLineString) { |
431 |
com.vividsolutions.jts.geom.Polygon[] poly = new com.vividsolutions.jts.geom.Polygon[((MultiLineString) g).getNumGeometries()]; |
432 |
for (int i = 0; i < ((MultiLineString) g).getNumGeometries(); i++) { |
433 |
com.vividsolutions.jts.geom.Geometry lineString = ((MultiLineString) g).getGeometryN(i); |
434 |
poly[i] = convertLineStringToPolygon((LineString) lineString); |
435 |
} |
436 |
return theFactory.createMultiPolygon(poly);
|
437 |
} else {
|
438 |
return convertLineStringToPolygon((LineString) g);
|
439 |
} |
440 |
} |
441 |
|
442 |
if ((sourceType == Geometry.TYPES.CIRCLE || sourceType == Geometry.TYPES.ELLIPSE
|
443 |
|| sourceType == Geometry.TYPES.ELLIPTICARC || sourceType == Geometry.TYPES.FILLEDSPLINE) |
444 |
&& destinationType == Geometry.TYPES.MULTICURVE) { |
445 |
if (g instanceof com.vividsolutions.jts.geom.Polygon) { |
446 |
com.vividsolutions.jts.geom.Polygon poly = (com.vividsolutions.jts.geom.Polygon) g; |
447 |
LineString lineString = theFactory.createLinearRing(poly.getCoordinates()); |
448 |
return theFactory.createMultiLineString(new LineString[] { lineString }); |
449 |
} |
450 |
} |
451 |
return g;
|
452 |
} |
453 |
|
454 |
private static com.vividsolutions.jts.geom.Polygon convertLineStringToPolygon(LineString line) { |
455 |
Coordinate[] coordinates = line.getCoordinates();
|
456 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = line.getFactory(); |
457 |
LinearRing shell = theFactory.createLinearRing(coordinates); |
458 |
com.vividsolutions.jts.geom.Polygon pol = theFactory.createPolygon(shell, null);
|
459 |
return pol;
|
460 |
} |
461 |
|
462 |
public static MCoordinate createMCoordinate(double x, double y, double m) { |
463 |
return MCoordinate.create2dWithMeasure(x, y, m);
|
464 |
} |
465 |
|
466 |
public static MCoordinate createMCoordinate(double x, double y, double z, double m) { |
467 |
return MCoordinate.create3dWithMeasure(x, y, z, m);
|
468 |
} |
469 |
|
470 |
/**
|
471 |
* @param init
|
472 |
* @param middle
|
473 |
* @param end
|
474 |
* @return
|
475 |
*/
|
476 |
public static Coordinate getCircumcentre(Point init, Point middle, Point end) { |
477 |
Triangle triangle = |
478 |
new Triangle(((PointJTS) init).getJTSCoordinate(),
|
479 |
((PointJTS) middle).getJTSCoordinate(), |
480 |
((PointJTS) end).getJTSCoordinate()); |
481 |
return triangle.circumcentre();
|
482 |
} |
483 |
|
484 |
public static LineString createJTSLineStringFromArcPoints(Point centre, double radius, double startAngle, double endAngle){ |
485 |
GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
|
486 |
shapeFactory.setCentre(((PointJTS)centre).getJTSCoordinate()); |
487 |
shapeFactory.setSize(radius*2);
|
488 |
return shapeFactory.createArc(startAngle, endAngle);
|
489 |
} |
490 |
|
491 |
public static MultiLineString createJTSMultiLineString(LineString[] lineStrings) { |
492 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = JTSUtils.factory; |
493 |
if(lineStrings.length>0){ |
494 |
theFactory = lineStrings[0].getFactory();
|
495 |
} |
496 |
return theFactory.createMultiLineString(lineStrings);
|
497 |
} |
498 |
|
499 |
/**
|
500 |
* @param coordinates
|
501 |
* @param interiorRings
|
502 |
* @return
|
503 |
*/
|
504 |
public static com.vividsolutions.jts.geom.Polygon createJTSPolygon(ArrayListCoordinateSequence coordinates, |
505 |
List<Ring> interiorRings) {
|
506 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = getFactory(coordinates); |
507 |
|
508 |
LinearRing shell = theFactory.createLinearRing(coordinates); |
509 |
LinearRing[] holes = new LinearRing[interiorRings.size()]; |
510 |
for(int i=0; i<interiorRings.size(); i++){ |
511 |
Ring ring = interiorRings.get(i); |
512 |
holes[i] = (LinearRing) ((GeometryJTS) ring).getJTS(); |
513 |
} |
514 |
return theFactory.createPolygon(shell, holes);
|
515 |
} |
516 |
|
517 |
|
518 |
/**
|
519 |
* @param coordinates
|
520 |
* @return
|
521 |
*/
|
522 |
public static com.vividsolutions.jts.geom.Polygon createJTSPolygon(ArrayListCoordinateSequence coordinates) { |
523 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = getFactory(coordinates); |
524 |
|
525 |
LinearRing shell = theFactory.createLinearRing(coordinates); |
526 |
return theFactory.createPolygon(shell);
|
527 |
} |
528 |
|
529 |
public static com.vividsolutions.jts.geom.MultiPolygon createJTSMultiPolygon(com.vividsolutions.jts.geom.Polygon[] polygons){ |
530 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = JTSUtils.factory; |
531 |
if(polygons.length>0){ |
532 |
theFactory = polygons[0].getFactory();
|
533 |
} |
534 |
return theFactory.createMultiPolygon(polygons);
|
535 |
} |
536 |
|
537 |
/**
|
538 |
* Returns the intersection point between an ellipse and her minor axis.
|
539 |
*
|
540 |
* @param init
|
541 |
* @param end
|
542 |
* @param ydist
|
543 |
* @return
|
544 |
*/
|
545 |
public static Coordinate getPointAtYAxisInEllipse(Point init, Point end, Double ydist) { |
546 |
|
547 |
LineSegment segment = new LineSegment(((PointJTS) init).getJTSCoordinate(),
|
548 |
((PointJTS) end).getJTSCoordinate()); |
549 |
Coordinate middle = segment.midPoint(); |
550 |
|
551 |
LineSegment midSegment = new LineSegment(middle, ((PointJTS) end).getJTSCoordinate());
|
552 |
double modulus = midSegment.getLength();
|
553 |
|
554 |
//Mayor semi-axis unitary vector
|
555 |
Coordinate uni = new Coordinate((end.getX()-middle.x)/modulus, (end.getY()-middle.y)/modulus);
|
556 |
|
557 |
//Minor axis unitary vector
|
558 |
Coordinate perpUni = new Coordinate(-uni.y,uni.x);
|
559 |
|
560 |
Coordinate point = new Coordinate(middle.x+(perpUni.x*ydist), middle.y+(perpUni.y*ydist));
|
561 |
|
562 |
return point;
|
563 |
} |
564 |
|
565 |
/**
|
566 |
* Returns the middle point between two points.
|
567 |
*
|
568 |
* @param init
|
569 |
* @param end
|
570 |
* @return
|
571 |
*/
|
572 |
public static Coordinate getMidPoint(Point init, Point end) { |
573 |
|
574 |
LineSegment segment = new LineSegment(((PointJTS) init).getJTSCoordinate(),
|
575 |
((PointJTS) end).getJTSCoordinate()); |
576 |
Coordinate middle = segment.midPoint(); |
577 |
return middle;
|
578 |
} |
579 |
|
580 |
/**
|
581 |
* @param coordinate
|
582 |
* @return
|
583 |
*/
|
584 |
public static com.vividsolutions.jts.geom.Geometry createJTSPoint(Coordinate coordinate) { |
585 |
return getFactory(coordinate).createPoint(coordinate);
|
586 |
} |
587 |
|
588 |
/**
|
589 |
* @param coordinates
|
590 |
* @return
|
591 |
*/
|
592 |
public static com.vividsolutions.jts.geom.Geometry createJTSPolygon(Coordinate[] coordinates) { |
593 |
return getFactory(coordinates).createPolygon(coordinates);
|
594 |
} |
595 |
|
596 |
public static BufferParameters getBufferParameters(){ |
597 |
BufferParameters bufParams = new BufferParameters();
|
598 |
bufParams.setSingleSided(true);
|
599 |
bufParams.setEndCapStyle(BufferParameters.CAP_FLAT); |
600 |
bufParams.setJoinStyle(BufferParameters.CAP_ROUND); |
601 |
return bufParams;
|
602 |
} |
603 |
|
604 |
public static BufferParameters getBufferParameters(int joinStyle, int endCapStyle){ |
605 |
BufferParameters bufParams = new BufferParameters();
|
606 |
bufParams.setSingleSided(true);
|
607 |
bufParams.setEndCapStyle(endCapStyle); |
608 |
bufParams.setJoinStyle(joinStyle); |
609 |
bufParams.setQuadrantSegments(calculateQuadrantSegments(joinStyle)); |
610 |
return bufParams;
|
611 |
} |
612 |
|
613 |
public static int calculateQuadrantSegments(int joinStyle) throws IllegalArgumentException { |
614 |
int quadrantSegments = BufferParameters.DEFAULT_QUADRANT_SEGMENTS;
|
615 |
switch(joinStyle){
|
616 |
case JOIN_STYLE_ROUND:
|
617 |
quadrantSegments = BufferParameters.DEFAULT_QUADRANT_SEGMENTS; |
618 |
break;
|
619 |
case JOIN_STYLE_MITRE:
|
620 |
quadrantSegments = - (int) BufferParameters.DEFAULT_MITRE_LIMIT;
|
621 |
break;
|
622 |
case JOIN_STYLE_BEVEL:
|
623 |
quadrantSegments = 0;
|
624 |
break;
|
625 |
default:
|
626 |
throw new IllegalArgumentException("Invalid jointStyle "+joinStyle); |
627 |
} |
628 |
return quadrantSegments;
|
629 |
} |
630 |
|
631 |
/**
|
632 |
* Creates a offset from a closed line at a distance
|
633 |
*
|
634 |
* @param proj
|
635 |
* @param coordinates
|
636 |
* @param distance
|
637 |
* @return
|
638 |
*/
|
639 |
public static Geometry offsetClosedLine(IProjection proj, ArrayListCoordinateSequence coordinates, double distance) { |
640 |
com.vividsolutions.jts.geom.Geometry jtsGeom = JTSUtils.createJTSPolygon(coordinates); |
641 |
com.vividsolutions.jts.geom.Geometry geomJTS = jtsGeom.buffer(distance); |
642 |
return jtsPolygonToJtsMultiLineString(geomJTS, proj);
|
643 |
} |
644 |
|
645 |
/**
|
646 |
* Creates a offset from a closed line at a distance
|
647 |
*
|
648 |
* @param proj
|
649 |
* @param coordinates
|
650 |
* @param joinStyle
|
651 |
* @param distance
|
652 |
* @return
|
653 |
*/
|
654 |
public static Geometry offsetClosedLine(IProjection proj, ArrayListCoordinateSequence coordinates, int joinStyle, double distance) { |
655 |
com.vividsolutions.jts.geom.Geometry jtsGeom = JTSUtils.createJTSPolygon(coordinates); |
656 |
com.vividsolutions.jts.geom.Geometry geomJTS = jtsGeom.buffer(distance, calculateQuadrantSegments(joinStyle), BufferParameters.CAP_FLAT); |
657 |
return jtsPolygonToJtsMultiLineString(geomJTS, proj);
|
658 |
} |
659 |
|
660 |
protected static Geometry jtsPolygonToJtsMultiLineString(com.vividsolutions.jts.geom.Geometry geomJTS, IProjection proj) { |
661 |
if (geomJTS instanceof com.vividsolutions.jts.geom.Polygon) { |
662 |
com.vividsolutions.jts.geom.Polygon polygonJTS = (com.vividsolutions.jts.geom.Polygon) geomJTS; |
663 |
LineString shell = polygonJTS.getExteriorRing(); |
664 |
int numHoles = polygonJTS.getNumInteriorRing();
|
665 |
if (numHoles > 0) { |
666 |
LineString[] lineStrings = new LineString[numHoles + 1]; |
667 |
lineStrings[0] = shell;
|
668 |
for (int i = 0; i < numHoles; i++) { |
669 |
LineString hole = polygonJTS.getInteriorRingN(i); |
670 |
lineStrings[i + 1] = hole;
|
671 |
} |
672 |
return JTSUtils.createGeometry(proj, JTSUtils.createJTSMultiLineString(lineStrings));
|
673 |
} |
674 |
return JTSUtils.createGeometry(proj, shell);
|
675 |
} else if (geomJTS instanceof com.vividsolutions.jts.geom.MultiPolygon) { |
676 |
MultiPolygon multiPolygonJTS = (com.vividsolutions.jts.geom.MultiPolygon) geomJTS; |
677 |
List<LineString> lineStringList = new ArrayList<>(); |
678 |
for (int i = 0; i < multiPolygonJTS.getNumGeometries(); i++) { |
679 |
com.vividsolutions.jts.geom.Polygon polygonJTS = |
680 |
(com.vividsolutions.jts.geom.Polygon) multiPolygonJTS.getGeometryN(i); |
681 |
lineStringList.add(polygonJTS.getExteriorRing()); |
682 |
int numHoles = polygonJTS.getNumInteriorRing();
|
683 |
if (numHoles > 0) { |
684 |
for (int h = 0; h < numHoles; h++) { |
685 |
LineString hole = polygonJTS.getInteriorRingN(i); |
686 |
lineStringList.add(hole); |
687 |
} |
688 |
} |
689 |
} |
690 |
return JTSUtils.createGeometry(proj, JTSUtils.createJTSMultiLineString(lineStringList.toArray(new LineString[lineStringList.size()]))); |
691 |
} |
692 |
//No deber?a pasar por aqu?
|
693 |
logger.warn("offsetClosedLine does not return or Polygon JTS or MultiPolygon JTS");
|
694 |
return null; |
695 |
} |
696 |
|
697 |
/**
|
698 |
* Creates a raw offset of a open line at a distance.
|
699 |
*
|
700 |
* @param coordinates
|
701 |
* @param distance
|
702 |
* @return
|
703 |
*/
|
704 |
public static Geometry offsetRawOpenLine(IProjection proj, ArrayListCoordinateSequence coordinates, double distance) { |
705 |
com.vividsolutions.jts.geom.GeometryFactory theFactory = getFactory(coordinates); |
706 |
|
707 |
BufferParameters bufParams = JTSUtils.getBufferParameters(); |
708 |
LineString jtsGeom = JTSUtils.createJTSLineString(coordinates); |
709 |
|
710 |
OffsetCurveBuilder ocb = new
|
711 |
OffsetCurveBuilder(theFactory.getPrecisionModel(), bufParams); |
712 |
Coordinate[] coords = ocb.getOffsetCurve(jtsGeom.getCoordinates(), distance);
|
713 |
CoordinateSequence coordSequence = theFactory.getCoordinateSequenceFactory().create(coords); |
714 |
com.vividsolutions.jts.geom.Geometry offsetGeom = JTSUtils.createJTSLineString(coordSequence); |
715 |
|
716 |
return JTSUtils.createGeometry(proj, offsetGeom);
|
717 |
} |
718 |
|
719 |
/*
|
720 |
*
|
721 |
*/
|
722 |
public static double straightLineThroughTwoPointsEquation(double x1, double x2, double y1, double y2, double x) { |
723 |
if (x2 - x1 == 0.0) { |
724 |
return Double.POSITIVE_INFINITY; |
725 |
} |
726 |
return ((y2 - y1) * (x - x1) / (x2 - x1)) + y1;
|
727 |
} |
728 |
|
729 |
|
730 |
public static Point extractPointFromLine(GeometryJTS geom, double len) { |
731 |
com.vividsolutions.jts.geom.Geometry jts = geom.getJTS(); |
732 |
LinearLocation location = LengthLocationMap.getLocation(jts, len); |
733 |
|
734 |
LineString lineComp = (LineString) jts.getGeometryN(location.getComponentIndex()); |
735 |
Coordinate coordinate = lineComp.getCoordinateN(location.getSegmentIndex()); |
736 |
if (!(location.getSegmentIndex() >= lineComp.getNumPoints() - 1)){ |
737 |
Coordinate p1 = lineComp.getCoordinateN(location.getSegmentIndex() + 1);
|
738 |
coordinate = pointAlongSegmentByFraction(coordinate, p1, location.getSegmentFraction()); |
739 |
} |
740 |
|
741 |
GeometryType type = geom.getGeometryType(); |
742 |
|
743 |
if(type.hasZ() && type.hasM()){
|
744 |
return new Point3DM(geom.getProjection(), coordinate); |
745 |
} |
746 |
if(type.hasZ()){
|
747 |
return new Point3D(geom.getProjection(), coordinate); |
748 |
} |
749 |
if(type.hasM()){
|
750 |
return new Point2DM(geom.getProjection(), coordinate); |
751 |
} |
752 |
return new Point2D(geom.getProjection(), coordinate); |
753 |
|
754 |
} |
755 |
|
756 |
|
757 |
private static Coordinate pointAlongSegmentByFraction(Coordinate p0, Coordinate p1, double frac) { |
758 |
if (frac <= 0.0) { |
759 |
return p0;
|
760 |
} |
761 |
if (frac >= 1.0) { |
762 |
return p1;
|
763 |
} |
764 |
|
765 |
double x = (p1.x - p0.x) * frac + p0.x;
|
766 |
double y = (p1.y - p0.y) * frac + p0.y;
|
767 |
// interpolate Z value. If either input Z is NaN, result z will be NaN as well.
|
768 |
double z = (p1.z - p0.z) * frac + p0.z;
|
769 |
if (p0 instanceof MCoordinate && p1 instanceof MCoordinate) { |
770 |
// interpolate M value. If either input M is NaN, result M will be NaN as well.
|
771 |
double m = (((MCoordinate)p1).m - ((MCoordinate)p0).m) * frac + ((MCoordinate)p0).m;
|
772 |
return new MCoordinate(x, y, z, m); |
773 |
} |
774 |
|
775 |
return new Coordinate(x, y, z); |
776 |
} |
777 |
|
778 |
public static double getPathLengthFromLine(GeometryJTS geom, Point point) { |
779 |
LocationIndexedLine lil = new LocationIndexedLine(geom.getJTS());
|
780 |
LinearLocation pointLocation = lil.indexOf(((PointJTS)point).getJTSCoordinate()); |
781 |
|
782 |
LinearLocation startLocation = lil.getStartIndex(); |
783 |
|
784 |
com.vividsolutions.jts.geom.Geometry geomJTS = lil.extractLine(startLocation, pointLocation); |
785 |
|
786 |
return geomJTS.getLength();
|
787 |
} |
788 |
|
789 |
} |