21 package org.matsim.core.utils.geometry;
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
25 import org.locationtech.jts.geom.Coordinate;
29 import java.math.BigDecimal;
30 import java.math.RoundingMode;
31 import java.util.concurrent.atomic.AtomicLong;
34 final private static Logger
LOG = LogManager.getLogger(
CoordUtils.class);
38 return new Coordinate( coord.
getX(), coord.
getY() ) ;
42 return new Coord( coordinate.x, coordinate.y ) ;
46 return new Coord(xx, yy);
50 return new Coord(xx, yy, zz);
54 if( !coord1.
hasZ() && !coord2.
hasZ() ){
56 double xx = coord1.
getX() + coord2.
getX();
57 double yy = coord1.
getY() + coord2.
getY();
58 return new Coord(xx, yy);
59 }
else if( coord1.
hasZ() && coord2.
hasZ() ){
61 double xx = coord1.
getX() + coord2.
getX();
62 double yy = coord1.
getY() + coord2.
getY();
63 double zz = coord1.
getZ() + coord2.
getZ();
64 return new Coord(xx, yy, zz);
66 throw new RuntimeException(
"Cannot 'plus' coordinates if one has elevation (z) and the other not; coord1.hasZ=" + coord1.
hasZ()
67 +
"; coord2.hasZ=" + coord2.
hasZ() );
72 if( !coord1.
hasZ() && !coord2.
hasZ() ){
74 double xx = coord1.
getX() - coord2.
getX();
75 double yy = coord1.
getY() - coord2.
getY();
76 return new Coord(xx, yy);
77 }
else if( coord1.
hasZ() && coord2.
hasZ() ){
79 double xx = coord1.
getX() - coord2.
getX();
80 double yy = coord1.
getY() - coord2.
getY();
81 double zz = coord1.
getZ() - coord2.
getZ();
82 return new Coord(xx, yy, zz);
84 throw new RuntimeException(
"Cannot 'minus' coordinates if one has elevation (z) and the other not.");
91 double xx = alpha * coord.
getX();
92 double yy = alpha * coord.
getY();
93 return new Coord(xx, yy);
96 double xx = alpha * coord.
getX();
97 double yy = alpha * coord.
getY();
98 double zz = alpha * coord.
getZ();
99 return new Coord(xx, yy, zz);
105 if( !coord1.
hasZ() && !coord2.
hasZ() ){
107 double xx = 0.5*( coord1.
getX() + coord2.
getX() ) ;
108 double yy = 0.5*( coord1.
getY() + coord2.
getY() ) ;
109 return new Coord(xx, yy);
110 }
else if( coord1.
hasZ() && coord2.
hasZ() ){
112 double xx = 0.5*( coord1.
getX() + coord2.
getX() ) ;
113 double yy = 0.5*( coord1.
getY() + coord2.
getY() ) ;
114 double zz = 0.5*( coord1.
getZ() + coord2.
getZ() ) ;
115 return new Coord(xx, yy, zz);
117 throw new RuntimeException(
"Cannot get the center for coordinates if one has elevation (z) and the other not.");
143 final double y = -coord.
getX();
147 final double y = -coord.
getX();
154 if( !coord1.
hasZ() && !coord2.
hasZ() ){
159 return centerWOffset ;
160 }
else if( coord1.
hasZ() && coord2.
hasZ() ){
164 throw new RuntimeException(
"Cannot get the center for coordinates if one has elevation (z) and the other not.");
174 int scale = Math.abs(coord.
getX()) > 180 || Math.abs(coord.
getY()) > 180 ? 2 : 6;
175 return round(coord, scale);
190 return BigDecimal.valueOf(x).setScale(scale, RoundingMode.HALF_EVEN).doubleValue();
207 double xDiff = other.
getX()-coord.
getX();
208 double yDiff = other.
getY()-coord.
getY();
209 return Math.sqrt((xDiff*xDiff) + (yDiff*yDiff));
221 if( !coord1.
hasZ() && !coord2.
hasZ() ){
223 return coord1.
getX()*coord2.
getX() +
225 }
else if( coord1.
hasZ() && coord2.
hasZ() ){
227 return coord1.
getX()*coord2.
getX() +
231 throw new RuntimeException(
"Cannot get the dot-product of coordinates if one has elevation (z) and the other not.");
257 if( !lineFrom.
hasZ() && !lineTo.
hasZ() && !point.
hasZ() ){
276 double lineDX = lineTo.
getX() - lineFrom.
getX();
277 double lineDY = lineTo.
getY() - lineFrom.
getY();
279 if ((lineDX == 0.0) && (lineDY == 0.0)) {
284 double u = ((point.
getX() - lineFrom.
getX())*lineDX + (point.
getY() - lineFrom.
getY())*lineDY) /
285 (lineDX*lineDX + lineDY*lineDY);
297 }
else if( lineFrom.
hasZ() && lineTo.
hasZ() && point.
hasZ() ){
299 double lineDX = lineTo.
getX() - lineFrom.
getX();
300 double lineDY = lineTo.
getY() - lineFrom.
getY();
301 double lineDZ = lineTo.
getZ() - lineFrom.
getZ();
303 if((lineDX == 0.0) && (lineDY == 0.0) && (lineDZ == 0.0)){
327 if (!onlyOnceWarnGiven) {
328 LogManager.getLogger(
CoordUtils.class).warn(
"Mix of 2D / 3D coordinates. Assuming 2D only.\n" +
Gbl.
ONLYONCE);
329 onlyOnceWarnGiven =
true;
358 if( !lineFrom.
hasZ() && !lineTo.
hasZ() && !point.
hasZ() ){
364 double lineDX = lineTo.
getX() - lineFrom.
getX();
365 double lineDY = lineTo.
getY() - lineFrom.
getY();
367 if ((lineDX == 0.0) && (lineDY == 0.0)) {
372 double u = ((point.
getX() - lineFrom.
getX())*lineDX + (point.
getY() - lineFrom.
getY())*lineDY) /
373 (lineDX*lineDX + lineDY*lineDY);
383 return new Coord(lineFrom.
getX() + u * lineDX, lineFrom.
getY() + u * lineDY);
384 }
else if(lineFrom.
hasZ() && lineTo.
hasZ() && point.
hasZ() ){
392 if (!onlyOnceWarnGiven) {
393 LogManager.getLogger(
CoordUtils.class).warn(
"Mix of 2D / 3D coordinates. Assuming 2D only.\n" +
Gbl.
ONLYONCE);
394 onlyOnceWarnGiven =
true;
417 if( !coord.
hasZ() && !other.
hasZ() ){
419 double xDiff = other.
getX()-coord.
getX();
420 double yDiff = other.
getY()-coord.
getY();
421 return Math.sqrt((xDiff*xDiff) + (yDiff*yDiff));
422 }
else if( coord.
hasZ() && other.
hasZ() ){
424 double xDiff = other.
getX()-coord.
getX();
425 double yDiff = other.
getY()-coord.
getY();
426 double zDiff = other.
getZ()-coord.
getZ();
427 return Math.sqrt((xDiff*xDiff) + (yDiff*yDiff) + (zDiff*zDiff));
432 LOG.warn(
"Mixed use of elevation in coordinates: " + coord +
434 LOG.warn(
"Returning projected coordinate distance (using x and y components only)");
437 LOG.warn(
"Future occurences of this logging statement are suppressed.");
static final String ONLYONCE
static double length(Coord coord)
static double roundNumber(double x, int scale)
static double calcEuclideanDistance(Coord coord, Coord other)
static double dotProduct(Coord coord1, Coord coord2)
final AtomicLong warnCounter
static Coord round(Coord coord)
static Coord orthogonalProjectionOnLineSegment(final Coord lineFrom, final Coord lineTo, final Coord point)
static Coord rotateToRight(Coord coord)
static Coord minus(Coord coord1, Coord coord2)
static double distancePointLinesegment(final Coord lineFrom, final Coord lineTo, final Coord point)
static Coordinate createGeotoolsCoordinate(final Coord coord)
static Coord getCenter(Coord coord1, Coord coord2)
static Coord createCoord(final Coordinate coordinate)
final static EucledianDistanceCalculator eucledianDistanceCalculator
static Coord plus(Coord coord1, Coord coord2)
static Coord round(Coord coord, int scale)
double calculateDistance(Coord coord, Coord other)
static Coord getCenterWOffset(Coord coord1, Coord coord2)
static Coord scalarMult(double alpha, Coord coord)
static double calcProjectedEuclideanDistance(Coord coord, Coord other)
static Coord createCoord(final double xx, final double yy, final double zz)
static Coord createCoord(final double xx, final double yy)
static boolean onlyOnceWarnGiven
static final int maxWarnCount