package au.gov.amsa.geo.model;
import au.gov.amsa.risky.format.HasFix;
import au.gov.amsa.util.navigation.Position;
/**
* Geographic bounds using a latitude, longitude rectangle.
*/
public class Bounds {
private final double topLeftLat, topLeftLon, bottomRightLat, bottomRightLon;
public Bounds(double topLeftLat, double topLeftLon, double bottomRightLat, double bottomRightLon) {
this.topLeftLat = topLeftLat;
this.topLeftLon = Position.to180(topLeftLon);
this.bottomRightLat = bottomRightLat;
this.bottomRightLon = Position.to180(bottomRightLon);
}
public double getTopLeftLat() {
return topLeftLat;
}
public double getTopLeftLon() {
return topLeftLon;
}
public double getBottomRightLat() {
return bottomRightLat;
}
public double getBottomRightLon() {
return bottomRightLon;
}
public double getWidthDegrees() {
if (bottomRightLon < topLeftLon)
return bottomRightLon + 360 - topLeftLon;
else
return bottomRightLon - topLeftLon;
}
public double getHeightDegrees() {
return topLeftLat - bottomRightLat;
}
public boolean contains(HasFix p) {
return contains(p.fix().lat(), p.fix().lon());
}
public boolean contains(double lat, double lon) {
return topLeftLat >= lat && bottomRightLat <= lat
&& betweenLongitudes(topLeftLon, bottomRightLon, Position.to180(lon));
}
/**
* Returns true if and only if lon is between the longitudes topLeftLon and
* bottomRightLon.
*
* @param topLeftLon
* must be between -180 and 180
* @param bottomRightLon
* must be between -180 and 180
* @param lon
* must be between -180 and 180
* @return
*/
private static boolean betweenLongitudes(double topLeftLon, double bottomRightLon, double lon) {
if (topLeftLon <= bottomRightLon)
return lon >= topLeftLon && lon <= bottomRightLon;
else
return lon >= topLeftLon || lon <= bottomRightLon;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Bounds [topLeftLat=");
builder.append(topLeftLat);
builder.append(", topLeftLon=");
builder.append(topLeftLon);
builder.append(", bottomRightLat=");
builder.append(bottomRightLat);
builder.append(", bottomRightLon=");
builder.append(bottomRightLon);
builder.append("]");
return builder.toString();
}
public Bounds expand(double latExpansionDegrees, double lonExpansionDegrees) {
return new Bounds(Math.min(90, topLeftLat + latExpansionDegrees), topLeftLon
- lonExpansionDegrees, Math.max(-90, bottomRightLat - latExpansionDegrees),
bottomRightLon + lonExpansionDegrees);
}
}