📄 flatglobe.java
字号:
}
@Override
public Matrix computeTransformToPosition(Angle latitude, Angle longitude, double metersElevation)
{
if (latitude == null || longitude == null)
{
String message = Logging.getMessage("nullValue.LatitudeOrLongitudeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Vec4 point = this.geodeticToCartesian(latitude, longitude, metersElevation);
return Matrix.fromTranslation(point);
}
@Override
public Matrix computeTransformToPosition(Position position)
{
if (position == null)
{
String message = Logging.getMessage("nullValue.PositionIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return this.computeTransformToPosition(position.getLatitude(), position.getLongitude(),
position.getElevation());
}
@Override
public double getElevation(Angle latitude, Angle longitude)
{
if (latitude == null || longitude == null)
{
String message = Logging.getMessage("nullValue.LatitudeOrLongitudeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
// Flat World Note: return zero if outside the lat/lon normal boundaries (OK)
if (latitude.degrees < -90 || latitude.degrees > 90 || longitude.degrees < -180 || longitude.degrees > 180)
return 0d;
return super.getElevation(latitude, longitude);
}
/**
* Maps a position to a flat world Cartesian coordinates. The world plane is located at the origin and has UNIT-Z as
* normal. The Y axis points to the north pole. The Z axis points up. The X axis completes a right-handed coordinate
* system, and points east. Latitude and longitude zero are at the origine on y and x respectively. Sea level is at
* z = zero.
*
* @param latitude the latitude of the position.
* @param longitude the longitude of the position.
* @param metersElevation the number of meters above or below mean sea level.
*
* @return The Cartesian point corresponding to the input position.
*/
@Override
protected Vec4 geodeticToCartesian(Angle latitude, Angle longitude, double metersElevation)
{
if (latitude == null || longitude == null)
{
String message = Logging.getMessage("nullValue.LatitudeOrLongitudeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Vec4 cart = null;
if (this.projection.equals(PROJECTION_LAT_LON))
{
// Lat/Lon projection - plate carree
cart = new Vec4(this.equatorialRadius * longitude.radians,
this.equatorialRadius * latitude.radians,
metersElevation);
}
else if (this.projection.equals(PROJECTION_MERCATOR))
{
// Mercator projection
if (latitude.degrees > 75) latitude = Angle.fromDegrees(75);
if (latitude.degrees < -75) latitude = Angle.fromDegrees(-75);
cart = new Vec4(this.equatorialRadius * longitude.radians,
this.equatorialRadius * Math.log(Math.tan(Math.PI / 4 + latitude.radians / 2)),
metersElevation);
}
else if (this.projection.equals(PROJECTION_SINUSOIDAL))
{
// Sinusoidal projection
double latCos = latitude.cos();
cart = new Vec4(
latCos > 0 ? this.equatorialRadius * longitude.radians * latitude.cos() : 0,
this.equatorialRadius * latitude.radians,
metersElevation);
}
else if (this.projection.equals(PROJECTION_MODIFIED_SINUSOIDAL))
{
// Modified Sinusoidal projection
double latCos = latitude.cos();
cart = new Vec4(
latCos > 0 ? this.equatorialRadius * longitude.radians * Math.pow(latCos, .3) : 0,
this.equatorialRadius * latitude.radians,
metersElevation);
}
return cart;
}
@Override
protected Position cartesianToGeodetic(Vec4 cart)
{
if (cart == null)
{
String message = Logging.getMessage("nullValue.PointIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Position pos = null;
if (this.projection.equals(PROJECTION_LAT_LON))
{
// Lat/Lon projection - plate carree
pos = Position.fromRadians(
cart.y / this.equatorialRadius,
cart.x / this.equatorialRadius,
cart.z);
}
else if (this.projection.equals(PROJECTION_MERCATOR))
{
// Mercator projection
pos = Position.fromRadians(
Math.atan(Math.sinh(cart.y / this.equatorialRadius)),
cart.x / this.equatorialRadius,
cart.z);
}
else if (this.projection.equals(PROJECTION_SINUSOIDAL))
{
// Sinusoidal projection
double latCos = Math.cos(cart.y / this.equatorialRadius);
pos = Position.fromRadians(
cart.y / this.equatorialRadius,
latCos > 0 ? cart.x / this.equatorialRadius / Angle.fromRadians(latCos).cos() : 0,
cart.z);
}
else if (this.projection.equals(PROJECTION_MODIFIED_SINUSOIDAL))
{
// Modified Sinusoidal projection
double latCos = Math.cos(cart.y / this.equatorialRadius);
pos = Position.fromRadians(
cart.y / this.equatorialRadius,
latCos > 0 ? cart.x / this.equatorialRadius / Math.pow(latCos, .3) : 0,
cart.z);
}
return pos;
}
/**
* Returns a cylinder that minimally surrounds the specified minimum and maximum elevations in the sector at a
* specified vertical exaggeration.
*
* @param verticalExaggeration the vertical exaggeration to apply to the minimum and maximum elevations when
* computing the cylinder.
* @param sector the sector to return the bounding cylinder for.
* @param minElevation the minimum elevation of the bounding cylinder.
* @param maxElevation the maximum elevation of the bounding cylinder.
*
* @return The minimal bounding cylinder in Cartesian coordinates.
* @throws IllegalArgumentException if <code>sector</code> is null
*/
@Override
public Cylinder computeBoundingCylinder(double verticalExaggeration, Sector sector,
double minElevation, double maxElevation)
{
if (sector == null)
{
String msg = Logging.getMessage("nullValue.SectorIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
// Compute the center points of the bounding cylinder's top and bottom planes.
LatLon center = sector.getCentroid();
double minHeight = minElevation * verticalExaggeration;
double maxHeight = maxElevation * verticalExaggeration;
Vec4 centroidTop = this.computePointFromPosition(center.getLatitude(), center.getLongitude(), maxHeight);
Vec4 centroidBot = this.computePointFromPosition(center.getLatitude(), center.getLongitude(), minHeight);
// Compute radius of circumscribing circle using largest distance from center to corners.
Vec4 northwest = this.computePointFromPosition(sector.getMaxLatitude(), sector.getMinLongitude(), maxHeight);
Vec4 southeast = this.computePointFromPosition(sector.getMinLatitude(), sector.getMaxLongitude(), maxHeight);
Vec4 southwest = this.computePointFromPosition(sector.getMinLatitude(), sector.getMinLongitude(), maxHeight);
Vec4 northeast = this.computePointFromPosition(sector.getMaxLatitude(), sector.getMaxLongitude(), maxHeight);
double a = southwest.distanceTo3(centroidBot);
double b = southeast.distanceTo3(centroidBot);
double c = northeast.distanceTo3(centroidBot);
double d = northwest.distanceTo3(centroidBot);
double radius = Math.max(Math.max(a, b), Math.max(c, d));
return new Cylinder(centroidBot, centroidTop, radius);
}
/**
* Determines whether a point is above a given elevation
*
* @param point the <code>Vec4</code> point to test.
* @param elevation the elevation to test for.
* @return true if the given point is above the given elevation.
*/
public boolean isPointAboveElevation(Vec4 point, double elevation)
{
if (point == null)
{
String msg = Logging.getMessage("nullValue.PointIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
return point.z() > elevation;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -