svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.api / src / main / java / org / gvsig / fmap / geom / GeometryUtils.java @ 45308
History | View | Annotate | Download (32.6 KB)
1 |
/**
|
---|---|
2 |
* gvSIG. Desktop Geographic Information System.
|
3 |
*
|
4 |
* Copyright (C) 2007-2013 gvSIG Association.
|
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 3
|
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 |
* For any additional information, do not hesitate to contact us
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com.
|
23 |
*/
|
24 |
package org.gvsig.fmap.geom; |
25 |
|
26 |
import java.awt.geom.Point2D; |
27 |
import java.util.List; |
28 |
import java.util.Objects; |
29 |
import org.apache.commons.lang3.StringUtils; |
30 |
import org.cresques.cts.IProjection; |
31 |
import org.gvsig.euclidean.EuclideanLine2D; |
32 |
import org.gvsig.euclidean.EuclideanManager; |
33 |
import org.gvsig.fmap.geom.aggregate.MultiLine; |
34 |
import org.gvsig.fmap.geom.aggregate.MultiPoint; |
35 |
import org.gvsig.fmap.geom.aggregate.MultiPolygon; |
36 |
import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
37 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
38 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
39 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
40 |
import org.gvsig.fmap.geom.primitive.Arc; |
41 |
import org.gvsig.fmap.geom.primitive.Circle; |
42 |
import org.gvsig.fmap.geom.primitive.Ellipse; |
43 |
import org.gvsig.fmap.geom.primitive.Envelope; |
44 |
import org.gvsig.fmap.geom.primitive.Line; |
45 |
import org.gvsig.fmap.geom.primitive.Point; |
46 |
import org.gvsig.fmap.geom.primitive.Polygon; |
47 |
import org.gvsig.fmap.geom.primitive.Spline; |
48 |
import org.gvsig.fmap.geom.type.GeometryType; |
49 |
import org.gvsig.tools.exception.BaseException; |
50 |
import org.gvsig.tools.util.ToolsUtilLocator; |
51 |
|
52 |
/**
|
53 |
*
|
54 |
* @author jjdelcerro
|
55 |
*/
|
56 |
@SuppressWarnings("UseSpecificCatch") |
57 |
public class GeometryUtils { |
58 |
|
59 |
private GeometryUtils() {
|
60 |
|
61 |
} |
62 |
|
63 |
public static GeometryType getGeometryType(int geometryType, int geometrySubType) { |
64 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
65 |
try {
|
66 |
return geomManager.getGeometryType(geometryType, geometrySubType);
|
67 |
} catch (Exception ex) { |
68 |
return null; |
69 |
} |
70 |
} |
71 |
|
72 |
public static boolean isSubtype(int geomTypeParent, int geomTypeChild) { |
73 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
74 |
return geomManager.isSubtype(geomTypeParent, geomTypeChild);
|
75 |
} |
76 |
|
77 |
public static boolean canAggregate(int geomTypeParent, int geomTypeChild) { |
78 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
79 |
return geomManager.canAggregate(geomTypeParent, geomTypeChild);
|
80 |
} |
81 |
|
82 |
public static Envelope createEnvelope(int subType) { |
83 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
84 |
try {
|
85 |
return geomManager.createEnvelope(subType);
|
86 |
} catch (CreateEnvelopeException ex) {
|
87 |
return null; |
88 |
} |
89 |
} |
90 |
|
91 |
public static Envelope createEnvelope(double minX, double minY, double maxX, |
92 |
double maxY, int subType) { |
93 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
94 |
try {
|
95 |
return geomManager.createEnvelope(minX, minY, maxX, maxY, subType);
|
96 |
} catch (CreateEnvelopeException ex) {
|
97 |
return null; |
98 |
} |
99 |
} |
100 |
|
101 |
public static Line createLine(int subType) { |
102 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
103 |
try {
|
104 |
return geomManager.createLine(subType);
|
105 |
} catch (CreateGeometryException ex) {
|
106 |
return null; |
107 |
} |
108 |
} |
109 |
|
110 |
public static MultiLine createMultiLine(int subType) { |
111 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
112 |
try {
|
113 |
return geomManager.createMultiLine(subType);
|
114 |
} catch (CreateGeometryException ex) {
|
115 |
return null; |
116 |
} |
117 |
} |
118 |
|
119 |
public static Polygon createPolygon(int subType) { |
120 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
121 |
try {
|
122 |
return geomManager.createPolygon(subType);
|
123 |
} catch (CreateGeometryException ex) {
|
124 |
return null; |
125 |
} |
126 |
} |
127 |
|
128 |
public static MultiPolygon createMultiPolygon(int subType) { |
129 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
130 |
try {
|
131 |
return geomManager.createMultiPolygon(subType);
|
132 |
} catch (CreateGeometryException ex) {
|
133 |
return null; |
134 |
} |
135 |
} |
136 |
|
137 |
public static Point createPoint(double x, double y) { |
138 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
139 |
try {
|
140 |
return geomManager.createPoint(x, y, Geometry.SUBTYPES.GEOM2D);
|
141 |
} catch (CreateGeometryException ex) {
|
142 |
return null; |
143 |
} |
144 |
} |
145 |
|
146 |
public static Point createPoint(double x, double y, double z) { |
147 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
148 |
try {
|
149 |
Point p = geomManager.createPoint(x, y, Geometry.SUBTYPES.GEOM3D);
|
150 |
p.setCoordinateAt(Geometry.DIMENSIONS.Z, z); |
151 |
return p;
|
152 |
} catch (CreateGeometryException ex) {
|
153 |
return null; |
154 |
} |
155 |
} |
156 |
|
157 |
public static Point createPoint(double x, double y, double z, double m) { |
158 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
159 |
try {
|
160 |
Point p = geomManager.createPoint(x, y, Geometry.SUBTYPES.GEOM3DM);
|
161 |
p.setCoordinateAt(Geometry.DIMENSIONS.Z, z); |
162 |
p.setCoordinateAt(p.getDimension()-1, m);
|
163 |
return p;
|
164 |
} catch (CreateGeometryException ex) {
|
165 |
return null; |
166 |
} |
167 |
} |
168 |
|
169 |
public static Point createPoint(Point center, double radius, double angle) { |
170 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
171 |
return GeometryUtils.createPoint(
|
172 |
center.getX() + radius * Math.cos(angle),
|
173 |
center.getY() + radius * Math.sin(angle)
|
174 |
); |
175 |
} |
176 |
|
177 |
|
178 |
public static Geometry createFrom(Object data) { |
179 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
180 |
try {
|
181 |
return geomManager.createFrom(data);
|
182 |
} catch (GeometryException ex) {
|
183 |
return null; |
184 |
} |
185 |
} |
186 |
|
187 |
public static Geometry createFrom(String wkt, String srs) { |
188 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
189 |
try {
|
190 |
return geomManager.createFrom(wkt, srs);
|
191 |
} catch (GeometryException ex) {
|
192 |
return null; |
193 |
} |
194 |
} |
195 |
|
196 |
public static Geometry createFrom(String wkt, IProjection srs) { |
197 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
198 |
try {
|
199 |
return geomManager.createFrom(wkt, srs);
|
200 |
} catch (GeometryException ex) {
|
201 |
return null; |
202 |
} |
203 |
} |
204 |
|
205 |
public static Geometry createFrom(String wkt) { |
206 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
207 |
try {
|
208 |
return geomManager.createFrom(wkt);
|
209 |
} catch (GeometryException ex) {
|
210 |
return null; |
211 |
} |
212 |
} |
213 |
|
214 |
public static Object convertTo(Geometry geom, String format) { |
215 |
try {
|
216 |
return geom.convertTo(format);
|
217 |
} catch (Exception ex) { |
218 |
return null; |
219 |
} |
220 |
} |
221 |
|
222 |
public static String toWKT(Geometry geom) { |
223 |
try {
|
224 |
return geom.convertToWKT();
|
225 |
} catch (Exception ex) { |
226 |
return null; |
227 |
} |
228 |
} |
229 |
|
230 |
public static byte[] toWKB(Geometry geom) { |
231 |
try {
|
232 |
return geom.convertToWKB();
|
233 |
} catch (Exception ex) { |
234 |
return null; |
235 |
} |
236 |
} |
237 |
|
238 |
public static byte[] toEWKB(Geometry geom) { |
239 |
try {
|
240 |
return geom.convertToEWKB();
|
241 |
} catch (Exception ex) { |
242 |
return null; |
243 |
} |
244 |
} |
245 |
|
246 |
public static boolean intersects(Geometry geom1, Geometry geom2) { |
247 |
try {
|
248 |
return geom1.intersects(geom2);
|
249 |
} catch (Exception ex) { |
250 |
return false; |
251 |
} |
252 |
} |
253 |
|
254 |
public static String getGeometryTypeName(int type) { |
255 |
switch (type) {
|
256 |
case Geometry.TYPES.GEOMETRY:
|
257 |
return "Geometry"; |
258 |
case Geometry.TYPES.POINT:
|
259 |
return "Point"; |
260 |
case Geometry.TYPES.CURVE:
|
261 |
return "Curve"; |
262 |
case Geometry.TYPES.SURFACE:
|
263 |
return "Surface"; |
264 |
case Geometry.TYPES.SOLID:
|
265 |
return "Solid"; |
266 |
case Geometry.TYPES.AGGREGATE:
|
267 |
return "Aggregate"; |
268 |
case Geometry.TYPES.MULTIPOINT:
|
269 |
return "Multipoint"; |
270 |
case Geometry.TYPES.MULTICURVE:
|
271 |
return "Multicurve"; |
272 |
case Geometry.TYPES.MULTISURFACE:
|
273 |
return "Multisurface"; |
274 |
case Geometry.TYPES.MULTISOLID:
|
275 |
return "Multisolid"; |
276 |
case Geometry.TYPES.CIRCLE:
|
277 |
return "Circle"; |
278 |
case Geometry.TYPES.ARC:
|
279 |
return "Arc"; |
280 |
case Geometry.TYPES.ELLIPSE:
|
281 |
return "Ellipse"; |
282 |
case Geometry.TYPES.SPLINE:
|
283 |
return "Spline"; |
284 |
case Geometry.TYPES.ELLIPTICARC:
|
285 |
return "Ellipticarc"; |
286 |
case Geometry.TYPES.COMPLEX:
|
287 |
return "Complex"; |
288 |
case Geometry.TYPES.LINE:
|
289 |
return "Line"; |
290 |
case Geometry.TYPES.POLYGON:
|
291 |
return "Polygon"; |
292 |
case Geometry.TYPES.RING:
|
293 |
return "Ring"; |
294 |
case Geometry.TYPES.MULTILINE:
|
295 |
return "Multiline"; |
296 |
case Geometry.TYPES.MULTIPOLYGON:
|
297 |
return "Multipolygon"; |
298 |
case Geometry.TYPES.CIRCUMFERENCE:
|
299 |
return "Circumference"; |
300 |
case Geometry.TYPES.PERIELLIPSE:
|
301 |
return "Periellipse"; |
302 |
case Geometry.TYPES.FILLEDSPLINE:
|
303 |
return "Filledspline"; |
304 |
default:
|
305 |
return "Geometry"; |
306 |
} |
307 |
} |
308 |
|
309 |
public static String getGeometrySubtypeName(int subtype) { |
310 |
switch (subtype) {
|
311 |
case Geometry.SUBTYPES.GEOM2D:
|
312 |
return "2D"; |
313 |
case Geometry.SUBTYPES.GEOM3D:
|
314 |
return "3D"; |
315 |
case Geometry.SUBTYPES.GEOM2DM:
|
316 |
return "2DM"; |
317 |
case Geometry.SUBTYPES.GEOM3DM:
|
318 |
return "3DM"; |
319 |
default:
|
320 |
return "Unknown"; |
321 |
} |
322 |
} |
323 |
|
324 |
public static int getGeometryType(String typeName) { |
325 |
if( StringUtils.isBlank(typeName) ) {
|
326 |
return Geometry.TYPES.UNKNOWN;
|
327 |
} |
328 |
switch(typeName.toLowerCase()) {
|
329 |
case "geometry": |
330 |
return Geometry.TYPES.GEOMETRY;
|
331 |
case "point": |
332 |
return Geometry.TYPES.POINT;
|
333 |
case "curve": |
334 |
return Geometry.TYPES.CURVE;
|
335 |
case "surface": |
336 |
return Geometry.TYPES.SURFACE;
|
337 |
case "solid": |
338 |
return Geometry.TYPES.SOLID;
|
339 |
case "aggregate": |
340 |
return Geometry.TYPES.AGGREGATE;
|
341 |
case "multipoint": |
342 |
return Geometry.TYPES.MULTIPOINT;
|
343 |
case "multicurve": |
344 |
return Geometry.TYPES.MULTICURVE;
|
345 |
case "multisurface": |
346 |
return Geometry.TYPES.MULTISURFACE;
|
347 |
case "multisolid": |
348 |
return Geometry.TYPES.MULTISOLID;
|
349 |
case "circle": |
350 |
return Geometry.TYPES.CIRCLE;
|
351 |
case "arc": |
352 |
return Geometry.TYPES.ARC;
|
353 |
case "ellipse": |
354 |
return Geometry.TYPES.ELLIPSE;
|
355 |
case "spline": |
356 |
return Geometry.TYPES.SPLINE;
|
357 |
case "ellipticarc": |
358 |
return Geometry.TYPES.ELLIPTICARC;
|
359 |
case "complex": |
360 |
return Geometry.TYPES.COMPLEX;
|
361 |
case "line": |
362 |
return Geometry.TYPES.LINE;
|
363 |
case "polygon": |
364 |
return Geometry.TYPES.POLYGON;
|
365 |
case "ring": |
366 |
return Geometry.TYPES.RING;
|
367 |
case "multiline": |
368 |
return Geometry.TYPES.MULTILINE;
|
369 |
case "multipolygon": |
370 |
return Geometry.TYPES.MULTIPOLYGON;
|
371 |
case "circumference": |
372 |
return Geometry.TYPES.CIRCUMFERENCE;
|
373 |
case "periellipse": |
374 |
return Geometry.TYPES.PERIELLIPSE;
|
375 |
case "filledspline": |
376 |
return Geometry.TYPES.FILLEDSPLINE;
|
377 |
default:
|
378 |
return Geometry.TYPES.UNKNOWN;
|
379 |
} |
380 |
} |
381 |
|
382 |
public static int getGeometrySubtype(String subtype) { |
383 |
if( StringUtils.isBlank(subtype) ) {
|
384 |
return Geometry.SUBTYPES.UNKNOWN;
|
385 |
} |
386 |
switch(subtype.toUpperCase()) {
|
387 |
case "GEOM2D": |
388 |
case "2D": |
389 |
return Geometry.SUBTYPES.GEOM2D;
|
390 |
case "GEOM3D": |
391 |
case "3D": |
392 |
return Geometry.SUBTYPES.GEOM3D;
|
393 |
case "GEOM2DM": |
394 |
case "2DM": |
395 |
return Geometry.SUBTYPES.GEOM2DM;
|
396 |
case "GEOM3DM": |
397 |
case "3DM": |
398 |
return Geometry.SUBTYPES.GEOM3DM;
|
399 |
default:
|
400 |
return Geometry.SUBTYPES.UNKNOWN;
|
401 |
} |
402 |
} |
403 |
|
404 |
/**
|
405 |
* Creates a circle as of center and radius.
|
406 |
*
|
407 |
* @param center
|
408 |
* of new circle
|
409 |
* @param radius
|
410 |
* of new circle
|
411 |
* @param subtype
|
412 |
* subtype of circle. See {@link Geometry.SUBTYPES}
|
413 |
* @return The circle created with center and radius
|
414 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
415 |
*/
|
416 |
public static Circle createCircle(Point center, double radius, int subtype) |
417 |
throws CreateGeometryException {
|
418 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
419 |
Circle circle = (Circle) geomManager.create(Geometry.TYPES.CIRCLE, subtype); |
420 |
circle.setPoints(center, radius); |
421 |
|
422 |
return circle;
|
423 |
} |
424 |
|
425 |
/**
|
426 |
* Creates a circle from three points.
|
427 |
*
|
428 |
* @param firstPoint
|
429 |
* of circle
|
430 |
* @param secondPoint
|
431 |
* of circle
|
432 |
* @param thirdPoint
|
433 |
* of circle
|
434 |
* @param subtype
|
435 |
* subtype of circle. See {@link Geometry.SUBTYPES}
|
436 |
* @return The circle created from three points received as parameters.
|
437 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
438 |
*/
|
439 |
public static Circle createCircle(Point firstPoint, Point secondPoint, |
440 |
Point thirdPoint, int subtype) throws CreateGeometryException { |
441 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
442 |
Circle circle = (Circle) geomManager.create(Geometry.TYPES.CIRCLE, subtype); |
443 |
circle.setPoints(firstPoint, secondPoint, thirdPoint); |
444 |
|
445 |
return circle;
|
446 |
} |
447 |
|
448 |
/**
|
449 |
* Creates a circle from five points.The first two points are two points on a tangent to the circle.The next two are two points on another tangent to the circle.The last one is a point near the center of the circle.
|
450 |
*
|
451 |
* @param firstPoint
|
452 |
* @param secondPoint
|
453 |
* @param thirdPoint
|
454 |
* @param fourthPoint
|
455 |
* @param fifthPoint
|
456 |
* @param subtype
|
457 |
* subtype of circle. See {@link Geometry.SUBTYPES}
|
458 |
* @return The circle created from three points received as parameters.
|
459 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
460 |
*/
|
461 |
public static Circle createCircle(Point firstPoint, Point secondPoint, Point thirdPoint, Point fourthPoint, Point fifthPoint, int subtype) throws CreateGeometryException { |
462 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
463 |
EuclideanLine2D line1 = euclideanManager.createLine2D(firstPoint.getX(), firstPoint.getY(), secondPoint.getX(), secondPoint.getY()); |
464 |
EuclideanLine2D line2 = euclideanManager.createLine2D(thirdPoint.getX(), thirdPoint.getY(), fourthPoint.getX(), fourthPoint.getY()); |
465 |
return createCircle(line1, line2, fifthPoint, subtype);
|
466 |
} |
467 |
|
468 |
/**
|
469 |
* Creates a circle from two tangents and one point.
|
470 |
*
|
471 |
* @param line1
|
472 |
* A tangent line
|
473 |
* @param line2
|
474 |
* Another tangent line
|
475 |
* @param point
|
476 |
* A point near the center of the circle.
|
477 |
* @param subtype
|
478 |
* subtype of circle. See {@link Geometry.SUBTYPES}
|
479 |
* @return The circle created from two tangents and one point received as parameters.
|
480 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
481 |
*/
|
482 |
public static Circle createCircle(EuclideanLine2D line1, EuclideanLine2D line2, Point point, int subtype) throws CreateGeometryException { |
483 |
|
484 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
485 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
486 |
|
487 |
try {
|
488 |
EuclideanLine2D perpendicular; |
489 |
EuclideanLine2D bisector; |
490 |
if (line1.isParallel(line2)) {
|
491 |
|
492 |
if (Objects.equals(line1.getYIntercept(), line2.getYIntercept())
|
493 |
|| (Objects.equals(Math.abs(line1.getYIntercept()), 0.0) |
494 |
&& Objects.equals(Math.abs(line2.getYIntercept()), 0.0))) { //Same lines |
495 |
perpendicular = line1.getPerpendicular(point.getX(), point.getY()); |
496 |
Point2D intersection = line1.getIntersection(perpendicular);
|
497 |
return createCircle(point, point.distance(geomManager.createPoint(intersection.getX(), intersection.getY(), subtype)), subtype);
|
498 |
} else if (Double.isInfinite(line1.getSlope())) { //Parallel and vertical lines |
499 |
Point center = createPoint(-(line2.getC() + line1.getC()) / 2.0, point.getY(), subtype); |
500 |
double radius = line1.getDistance(center.getX(), center.getY());
|
501 |
return createCircle(center, radius, subtype);
|
502 |
} else { //Parallel lines |
503 |
bisector = euclideanManager.createLine2D(line1.getA(), line1.getB(), (line2.getC()+line1.getC())/2);
|
504 |
} |
505 |
|
506 |
} else {
|
507 |
|
508 |
EuclideanLine2D[] bisectors = line1.getBisectors(line2);
|
509 |
|
510 |
double distance1 = bisectors[0].getDistance(point.getX(), point.getY()); |
511 |
double distance2 = bisectors[1].getDistance(point.getX(), point.getY()); |
512 |
|
513 |
bisector = bisectors[0];
|
514 |
if (distance1 > distance2) {
|
515 |
bisector = bisectors[1];
|
516 |
} |
517 |
} |
518 |
|
519 |
if (Double.isInfinite(bisector.getSlope())) { |
520 |
Point2D intersection = line1.getIntersection(line2);
|
521 |
Point center = createPoint(intersection.getX(), point.getY(), subtype);
|
522 |
Double radius = line1.getDistance(center.getX(), center.getY());
|
523 |
return createCircle(center, radius, subtype);
|
524 |
} else if (bisector.getSlope() == 0.0) { |
525 |
if (line1.isParallel(line2)) { //Objects.equals(m0, m1)) { //Same slope |
526 |
Point center = createPoint(point.getX(), bisector.getYIntercept(), subtype);
|
527 |
Double radius = line1.getDistance(center.getX(), center.getY());
|
528 |
return createCircle(center, radius, subtype);
|
529 |
} else {
|
530 |
Point2D intersection = line1.getIntersection(line2);
|
531 |
Point center = createPoint(point.getX(), intersection.getY(), subtype);
|
532 |
Double radius = line1.getDistance(center.getX(), center.getY());
|
533 |
return createCircle(center, radius, subtype);
|
534 |
} |
535 |
} |
536 |
|
537 |
perpendicular = bisector.getPerpendicular(point.getX(), point.getY()); |
538 |
Point2D intersection = bisector.getIntersection(perpendicular);
|
539 |
Double radius = line1.getDistance(intersection.getX(), intersection.getY());
|
540 |
return createCircle(
|
541 |
geomManager.createPoint(intersection.getX(), intersection.getY(), subtype), |
542 |
radius, |
543 |
subtype); |
544 |
|
545 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
546 |
throw new CreateGeometryException(Geometry.TYPES.CIRCLE, subtype, ex); |
547 |
} |
548 |
} |
549 |
|
550 |
/**
|
551 |
* Creates a circle from two tangent geometries and the radius.
|
552 |
*
|
553 |
* @param geometry1
|
554 |
* A tangent geometry
|
555 |
* @param geometry2
|
556 |
* Another tangent geometry
|
557 |
* @param radius
|
558 |
* the radius of the cicle.
|
559 |
* @param firstPoint
|
560 |
* a point near tangent point of geometry1
|
561 |
* @param secondPoint
|
562 |
* a point near tangent point of geometry2
|
563 |
* @param subtype
|
564 |
* subtype of circle. See {@link Geometry.SUBTYPES}
|
565 |
* @return The circle created from two tangent geometries and the radius received as parameters.
|
566 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
567 |
*/
|
568 |
public static Circle createCircle(Geometry geometry1, Geometry geometry2, double radius, Point firstPoint, Point secondPoint, int subtype) throws CreateGeometryException { |
569 |
|
570 |
try {
|
571 |
Geometry buffer1 = geometry1.buffer(radius); |
572 |
MultiLine lines1 = buffer1.toLines(); |
573 |
|
574 |
Geometry buffer2 = geometry2.buffer(radius); |
575 |
MultiLine lines2 = buffer2.toLines(); |
576 |
|
577 |
Geometry intersection = lines1.intersection(lines2); |
578 |
|
579 |
Point center = null; |
580 |
if(intersection!=null){ |
581 |
MultiPoint points = intersection.toPoints(); |
582 |
|
583 |
double distance = Double.POSITIVE_INFINITY; |
584 |
for (int i = 0; i < points.getPrimitivesNumber(); i++) { |
585 |
Point point = points.getPointAt(i);
|
586 |
double pointDistance = point.distance(firstPoint)+point.distance(secondPoint);
|
587 |
if(pointDistance<distance){
|
588 |
center = point; |
589 |
distance = pointDistance; |
590 |
} |
591 |
} |
592 |
} |
593 |
if(center == null){ |
594 |
return null; |
595 |
} |
596 |
return createCircle(center, radius, subtype);
|
597 |
|
598 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException | GeometryException ex) {
|
599 |
throw new CreateGeometryException(Geometry.TYPES.CIRCLE, subtype, ex); |
600 |
} |
601 |
|
602 |
} |
603 |
|
604 |
/**
|
605 |
* Creates an arc as of center, radius, start angle and extension angle.
|
606 |
*
|
607 |
* @param center
|
608 |
* center of arc.
|
609 |
* @param radius
|
610 |
* of arc.
|
611 |
* @param startAngle
|
612 |
* of arc in radians
|
613 |
* @param angleExt
|
614 |
* of arc in radians
|
615 |
* @param subtype
|
616 |
* subtype of arc. See {@link Geometry.SUBTYPES}
|
617 |
* @return The arc created with center, radius, start angle and extension
|
618 |
* angle.
|
619 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
620 |
*/
|
621 |
public static Arc createArc(Point center, double radius, double startAngle, |
622 |
double angleExt, int subtype) throws CreateGeometryException { |
623 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
624 |
Arc arc = (Arc) geomManager.create(Geometry.TYPES.ARC, subtype); |
625 |
arc.setPoints(center, radius, startAngle, angleExt); |
626 |
return arc;
|
627 |
} |
628 |
|
629 |
/**
|
630 |
* Creates an arc as of three points.
|
631 |
*
|
632 |
* @param start
|
633 |
* point of arc
|
634 |
* @param middle
|
635 |
* point of arc. It can be any point of arc.
|
636 |
* @param end
|
637 |
* point of arc
|
638 |
* @param subtype
|
639 |
* of arc. See {@link Geometry.SUBTYPES}
|
640 |
* @return The arc created that it start at start point, cross middle
|
641 |
* point and end at end point.
|
642 |
* @throws org.gvsig.tools.exception.BaseException
|
643 |
*/
|
644 |
public static Arc createArc(Point start, Point middle, Point end, int subtype) |
645 |
throws BaseException {
|
646 |
|
647 |
Arc arc = (Arc) GeometryLocator.getGeometryManager().create(Geometry.TYPES.ARC, subtype); |
648 |
arc.setPoints(start, middle, end); |
649 |
return arc;
|
650 |
|
651 |
} |
652 |
|
653 |
/**
|
654 |
* Creates an ellipse from start and end point of A axis and half length
|
655 |
* of B axis.
|
656 |
*
|
657 |
* @param firstPointAxisA
|
658 |
* first point of A axis
|
659 |
* @param secondPointAxisA
|
660 |
* second point of B axis
|
661 |
* @param halfLengthAxisB
|
662 |
* half length of B axis
|
663 |
* @param subtype
|
664 |
* of ellipse See {@link Geometry.SUBTYPES}
|
665 |
* @return The ellipse created
|
666 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
667 |
*/
|
668 |
public static Arc createEllipse(Point firstPointAxisA, Point secondPointAxisA, |
669 |
double halfLengthAxisB, int subtype) throws CreateGeometryException { |
670 |
try {
|
671 |
double lengthAxisA = secondPointAxisA.distance(firstPointAxisA);
|
672 |
|
673 |
Point origen = createPoint(0, 0, subtype); |
674 |
Arc ellipse = createArc( |
675 |
origen, |
676 |
lengthAxisA / 2,
|
677 |
0,
|
678 |
2 * Math.PI, |
679 |
subtype); |
680 |
|
681 |
ellipse.scale(origen, 1, halfLengthAxisB * 2 / lengthAxisA); |
682 |
final EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
|
683 |
EuclideanLine2D axisA = euclideanManager.createLine2D( |
684 |
firstPointAxisA.getX(), |
685 |
firstPointAxisA.getY(), |
686 |
secondPointAxisA.getX(), |
687 |
secondPointAxisA.getY()); |
688 |
double angle = axisA.getAngle();
|
689 |
ellipse.rotate(angle, 0, 0); |
690 |
Point centerOfEllipse = getMidPoint(firstPointAxisA, secondPointAxisA, subtype);
|
691 |
ellipse.move(centerOfEllipse.getX(), centerOfEllipse.getY()); |
692 |
return ellipse;
|
693 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException e) {
|
694 |
throw new CreateGeometryException(Geometry.TYPES.ARC, subtype, e); |
695 |
} |
696 |
} |
697 |
|
698 |
/**
|
699 |
* Creates a filled ellipse from start and end point of A axis and half length
|
700 |
* of B axis.
|
701 |
*
|
702 |
* @param firstPointAxisA
|
703 |
* first point of A axis
|
704 |
* @param secondPointAxisA
|
705 |
* second point of B axis
|
706 |
* @param halfLengthAxisB
|
707 |
* half length of B axis
|
708 |
* @param subtype
|
709 |
* of ellipse See {@link Geometry.SUBTYPES}
|
710 |
* @return The ellipse created
|
711 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
712 |
*/
|
713 |
public static Ellipse createFilledEllipse(Point firstPointAxisA, |
714 |
Point secondPointAxisA, double halfLengthAxisB, int subtype) |
715 |
throws CreateGeometryException {
|
716 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
717 |
Ellipse ellipse = (Ellipse) geomManager.create(Geometry.TYPES.ELLIPSE, subtype); |
718 |
ellipse.setPoints(firstPointAxisA, secondPointAxisA, halfLengthAxisB); |
719 |
return ellipse;
|
720 |
} |
721 |
|
722 |
/**
|
723 |
* Gets center point of three points.
|
724 |
*
|
725 |
* @param a
|
726 |
* Point one
|
727 |
* @param b
|
728 |
* Point two
|
729 |
* @param c
|
730 |
* Point three
|
731 |
* @param subtype
|
732 |
* of point created. See {@link Geometry.SUBTYPES}
|
733 |
* @return Point center.
|
734 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
735 |
*/
|
736 |
public static Point getCenter(Point a, Point b, Point c, int subtype) |
737 |
throws CreateGeometryException {
|
738 |
|
739 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
740 |
|
741 |
Point midPointAC = getMidPoint(a, c, subtype);
|
742 |
EuclideanLine2D lineAC = euclideanManager.createLine2D(a.getX(), a.getY(), c.getX(), c.getY()); |
743 |
EuclideanLine2D bisectorAC = lineAC.getPerpendicular(midPointAC.getX(), midPointAC.getY()); |
744 |
|
745 |
Point midPointBC = getMidPoint(b, c, subtype);
|
746 |
EuclideanLine2D lineBC = euclideanManager.createLine2D(b.getX(), b.getY(), c.getX(), c.getY()); |
747 |
EuclideanLine2D bisectorBC = lineBC.getPerpendicular(midPointBC.getX(), midPointBC.getY()); |
748 |
|
749 |
Point2D intersection = bisectorAC.getIntersection(bisectorBC);
|
750 |
|
751 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
752 |
return geomManager.createPoint(intersection.getX(), intersection.getY(), subtype);
|
753 |
} |
754 |
|
755 |
/**
|
756 |
* Gets midpoint of two points
|
757 |
*
|
758 |
* @param a
|
759 |
* Point one
|
760 |
* @param b
|
761 |
* Point two
|
762 |
* @param subtype
|
763 |
* of point created. See {@link Geometry.SUBTYPES}
|
764 |
* @return Mid point of points.
|
765 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
766 |
*/
|
767 |
public static Point getMidPoint(Point a, Point b, int subtype) |
768 |
throws CreateGeometryException {
|
769 |
double x = (a.getX() + b.getX()) / 2; |
770 |
double y = (a.getY() + b.getY()) / 2; |
771 |
return createPoint(x, y, subtype);
|
772 |
} |
773 |
|
774 |
/**
|
775 |
* Creates line as of two point coordinates.
|
776 |
*
|
777 |
* @param x1
|
778 |
* The X1 coordinate
|
779 |
* @param y1
|
780 |
* The y1 coordinate
|
781 |
* @param x2
|
782 |
* The X2 coordinate
|
783 |
* @param y2
|
784 |
* The y2 coordinate
|
785 |
* @param subtype
|
786 |
* of line. See {@link Geometry.SUBTYPES}
|
787 |
* @return The Line created.
|
788 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
789 |
*/
|
790 |
public static Line createLine(double x1, double y1, double x2, double y2, |
791 |
int subtype) throws CreateGeometryException { |
792 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
793 |
Line line = (Line) geomManager.create(Geometry.TYPES.CURVE, subtype); |
794 |
line.addVertex(x1, y1); |
795 |
line.addVertex(x2, y2); |
796 |
return line;
|
797 |
} |
798 |
|
799 |
/**
|
800 |
* Creates line as of two point objects.
|
801 |
*
|
802 |
* @param p1
|
803 |
* First point
|
804 |
* @param p2
|
805 |
* Second point
|
806 |
* @param subtype
|
807 |
* of line. See {@link Geometry.SUBTYPES}
|
808 |
* @return The Line created.
|
809 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
810 |
*/
|
811 |
public static Line createLine(Point p1, Point p2, int subtype) |
812 |
throws CreateGeometryException {
|
813 |
return createLine(p1.getX(), p1.getY(), p2.getX(), p2.getY(),
|
814 |
subtype); |
815 |
} |
816 |
|
817 |
/**
|
818 |
* Create Spline from point list
|
819 |
*
|
820 |
* @param points
|
821 |
* @param subtype
|
822 |
* @return
|
823 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException
|
824 |
*/
|
825 |
public static Spline createSpline(List<Point> points, int subtype) |
826 |
throws CreateGeometryException {
|
827 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
828 |
Spline spline = (Spline) geomManager.create(Geometry.TYPES.SPLINE, subtype); |
829 |
|
830 |
points.forEach((point) -> { |
831 |
spline.addVertex(point); |
832 |
}); |
833 |
|
834 |
return spline;
|
835 |
} |
836 |
|
837 |
|
838 |
/**
|
839 |
* Calculate the angle between points p1 and p2 with vertex at vertex point
|
840 |
*
|
841 |
* @param vertex
|
842 |
* @param p1
|
843 |
* @param p2
|
844 |
* @return
|
845 |
*/
|
846 |
public static double calculateAngle(Point vertex, Point p1, Point p2){ |
847 |
double angle = Math.atan2( |
848 |
p2.getY() - vertex.getY(), |
849 |
p2.getX() - vertex.getX() |
850 |
) - Math.atan2(
|
851 |
p1.getY() - vertex.getY(), |
852 |
p1.getX() - vertex.getX() |
853 |
); |
854 |
if (angle<0){ |
855 |
return 2*Math.PI+angle; |
856 |
} |
857 |
return angle;
|
858 |
} |
859 |
|
860 |
/**
|
861 |
* Find the angle in the counterclockwise direction between
|
862 |
* the horizontal line and point p relative to the vertex
|
863 |
*
|
864 |
* @param vertex
|
865 |
* @param p
|
866 |
* @return
|
867 |
*/
|
868 |
public static double calculateAngle(Point vertex, Point p){ |
869 |
|
870 |
double angle = Math.atan2( |
871 |
p.getY() - vertex.getY(), |
872 |
p.getX() - vertex.getX() |
873 |
) - Math.atan2(
|
874 |
0,
|
875 |
1
|
876 |
); |
877 |
if (angle<0){ |
878 |
return 2*Math.PI+angle; |
879 |
} |
880 |
return angle;
|
881 |
} |
882 |
|
883 |
public static boolean areThreePointsInLine(Point a, Point b, Point c){ |
884 |
if(a.equals(b) || a.equals(c) || b.equals(c)){
|
885 |
return true; |
886 |
} |
887 |
return ((b.getX()-a.getX())/(c.getX()-b.getX()) == (b.getY()-a.getY())/(c.getY()-b.getY()));
|
888 |
} |
889 |
|
890 |
} |