org.opentripplanner.util.WorldEnvelope Maven / Gradle / Ivy
package org.opentripplanner.util;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import java.io.Serializable;
/**
* This class calculates borders of envelopes that can be also on 180th meridian
* The same way as it was previously calculated in GraphMetadata constructor
*
*/
public class WorldEnvelope implements Serializable {
Envelope leftEnv;
Envelope rightEnv;
double aRightCoordinate;
private double lowerLeftLongitude;
private double lowerLeftLatitude;
private double upperRightLongitude;
private double upperRightLatitude;
boolean coordinatesCalculated = false;
public WorldEnvelope() {
this.leftEnv = new Envelope();
this.rightEnv = new Envelope();
this.aRightCoordinate = 0;
}
public WorldEnvelope(WorldEnvelope envelope) {
this.leftEnv = envelope.leftEnv;
this.rightEnv = envelope.rightEnv;
this.aRightCoordinate = envelope.aRightCoordinate;
this.coordinatesCalculated = false;
}
public void expandToInclude(Coordinate c) {
this.expandToInclude(c.x, c.y);
}
public void expandToInclude(double x, double y) {
if (x < 0) {
leftEnv.expandToInclude(x, y);
} else {
rightEnv.expandToInclude(x, y);
aRightCoordinate = x;
}
}
/**
* Calculates lower/upper right/left latitude and longitude of all the coordintes
*
* This takes into account that envelope can extends over 180th meridian
*/
private void calculateCoordinates() {
if (coordinatesCalculated) {
return;
}
if (this.leftEnv.getArea() == 0) {
//the entire area is in the eastern hemisphere
this.lowerLeftLongitude = rightEnv.getMinX();
this.upperRightLongitude = rightEnv.getMaxX();
this.lowerLeftLatitude = rightEnv.getMinY();
this.upperRightLatitude = rightEnv.getMaxY();
} else if (this.rightEnv.getArea() == 0) {
//the entire area is in the western hemisphere
this.lowerLeftLongitude = leftEnv.getMinX();
this.upperRightLongitude = leftEnv.getMaxX();
this.lowerLeftLatitude = leftEnv.getMinY();
this.upperRightLatitude = leftEnv.getMaxY();
} else {
//the area spans two hemispheres. Either it crosses the prime meridian,
//or it crosses the 180th meridian (roughly, the international date line). We'll check a random
//coordinate to find out
if (aRightCoordinate < 90) {
//assume prime meridian
this.lowerLeftLongitude = leftEnv.getMinX();
this.upperRightLongitude = rightEnv.getMaxX();
} else {
//assume 180th meridian
this.lowerLeftLongitude = leftEnv.getMaxX();
this.upperRightLongitude = rightEnv.getMinX();
}
this.upperRightLatitude = Math.max(rightEnv.getMaxY(), leftEnv.getMaxY());
this.lowerLeftLatitude = Math.min(rightEnv.getMinY(), leftEnv.getMinY());
}
coordinatesCalculated = true;
}
public double getLowerLeftLongitude() {
calculateCoordinates();
return lowerLeftLongitude;
}
public double getLowerLeftLatitude() {
calculateCoordinates();
return lowerLeftLatitude;
}
public double getUpperRightLongitude() {
calculateCoordinates();
return upperRightLongitude;
}
public double getUpperRightLatitude() {
calculateCoordinates();
return upperRightLatitude;
}
public boolean contains(Coordinate c) {
if (c.x < 0) {
return leftEnv.contains(c);
} else {
return rightEnv.contains(c);
}
}
}