📄 abstractairspace.java
字号:
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (drawStyle == null)
{
String message = Logging.getMessage("nullValue.StringIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.doRenderGeometry(dc, drawStyle);
}
public void renderExtent(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalStateException(message);
}
this.doRenderExtent(dc);
}
public void move(Position position)
{
if (position == null)
{
String message = Logging.getMessage("nullValue.PositionIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.moveTo(this.getReferencePosition().add(position));
}
public void moveTo(Position position)
{
if (position == null)
{
String message = Logging.getMessage("nullValue.PositionIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Position oldRef = this.getReferencePosition();
//noinspection UnnecessaryLocalVariable
Position newRef = position;
this.doMoveTo(oldRef, newRef);
}
protected void doMoveTo(Position oldRef, Position newRef)
{
if (oldRef == null)
{
String message = "nullValue.OldRefIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (newRef == null)
{
String message = "nullValue.NewRefIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
double[] altitudes = this.getAltitudes();
double elevDelta = newRef.getElevation() - oldRef.getElevation();
this.setAltitudes(altitudes[0] + elevDelta, altitudes[1] + elevDelta);
}
protected Position computeReferencePosition(List<? extends LatLon> locations, double[] altitudes)
{
if (locations == null)
{
String message = "nullValue.LocationsIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (altitudes == null)
{
String message = "nullValue.AltitudesIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
int count = locations.size();
if (count == 0)
return null;
LatLon ll;
if (count < 3)
ll = locations.get(0);
else
ll = locations.get(count / 2);
return new Position(ll, altitudes[0]);
}
//**************************************************************//
//******************** Geometry Rendering ********************//
//**************************************************************//
// TODO: utility method for transforming list of LatLons into equivalent list comparable of crossing the dateline
// (a) for computing a bounding sector, then bounding cylinder
// (b) for computing tessellations of the list as 2D points
// These lists of LatLons (Polygon) need to be capable of passing over
// (a) the dateline
// (b) either pole
protected abstract Extent doComputeExtent(DrawContext dc);
protected abstract void doRenderGeometry(DrawContext dc, String drawStyle);
protected GeometryBuilder getGeometryBuilder()
{
return this.geometryBuilder;
}
protected void setGeometryBuilder(GeometryBuilder gb)
{
if (gb == null)
{
String message = "nullValue.GeometryBuilderIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.geometryBuilder = gb;
}
protected void doRender(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
AirspaceRenderer renderer = this.getRenderer();
renderer.renderNow(dc, Arrays.asList(this));
}
protected void doRenderExtent(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Extent extent = this.getExtent(dc);
if (extent != null && extent instanceof Renderable)
((Renderable) extent).render(dc);
}
protected DetailLevel computeDetailLevel(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Iterable<DetailLevel> detailLevels = this.getDetailLevels();
if (detailLevels == null)
return null;
Iterator<DetailLevel> iter = detailLevels.iterator();
if (!iter.hasNext())
return null;
// Find the first detail level that meets rendering criteria.
DetailLevel level = iter.next();
while (iter.hasNext() && !level.meetsCriteria(dc, this))
level = iter.next();
return level;
}
protected Cylinder computeBoundingCylinder(DrawContext dc, Iterable<? extends LatLon> locations)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (dc.getGlobe() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGlobeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (locations == null)
{
String message = "nullValue.LocationsIsNull";
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Globe globe = dc.getGlobe();
double verticalExaggeration = dc.getVerticalExaggeration();
double[] altitudes = this.getAltitudes();
boolean[] terrainConformant = this.isTerrainConforming();
// Get the points corresponding to the given locations at the lower and upper altitudes.
ArrayList<Vec4> points = new ArrayList<Vec4>();
for (int a = 0; a < 2; a++)
for (LatLon ll : locations)
points.add(globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(),
verticalExaggeration * altitudes[a]));
if (points.size() == 0)
return null;
// Compute the average point.
Vec4 centerPoint = null;
for (Vec4 vec : points)
centerPoint = (centerPoint == null) ? vec : vec.add3(centerPoint);
if (centerPoint == null)
return null;
centerPoint = centerPoint.divide3(points.size());
// Get the center point and the lower and upper altitudes.
LatLon centerLocation = globe.computePositionFromPoint(centerPoint);
points.add(globe.computePointFromPosition(centerLocation.getLatitude(), centerLocation.getLongitude(),
verticalExaggeration * altitudes[0]));
points.add(globe.computePointFromPosition(centerLocation.getLatitude(), centerLocation.getLongitude(),
verticalExaggeration * altitudes[1]));
// Compute the surface normal at the center point. This will be the axis or up direction of the extent.
Vec4 axis = globe.computeSurfaceNormalAtPoint(centerPoint);
// Compute the extrema parallel and perpendicular projections of each point on the axis.
double min_parallel = 0.0;
double max_parallel = 0.0;
double max_perp = 0.0;
for (Vec4 vec : points)
{
Vec4 p = vec.subtract3(centerPoint);
double parallel_proj = p.dot3(axis);
Vec4 parallel = axis.multiply3(parallel_proj);
Vec4 perpendicular = p.subtract3(parallel);
double perpendicular_proj = perpendicular.getLength3();
if (parallel_proj < min_parallel)
min_parallel = parallel_proj;
else if (parallel_proj > max_parallel)
max_parallel = parallel_proj;
if (perpendicular_proj > max_perp)
max_perp = perpendicular_proj;
}
// If terrain conformance is enabled, add the minimum or maximum elevations around the locations to the
// extrema parallel projections.
if (terrainConformant[0] || terrainConformant[1])
{
double min_elev, max_elev;
if (LatLon.positionsCrossDateLine(locations))
{
Sector[] splitSector = Sector.splitBoundingSectors(locations);
double[] a = globe.getMinAndMaxElevations(splitSector[0]);
double[] b = globe.getMinAndMaxElevations(splitSector[1]);
min_elev = Math.min(a[0], b[0]); // Take the smallest min elevation.
max_elev = Math.max(a[1], b[1]); // Take the largest max elevation.
}
else
{
Sector sector = Sector.boundingSector(locations);
double[] a = globe.getMinAndMaxElevations(sector);
min_elev = a[0];
max_elev = a[1];
}
if (terrainConformant[0] && min_elev < 0.0)
min_parallel += verticalExaggeration * min_elev;
if (terrainConformant[1] && max_elev > 0.0)
max_parallel += verticalExaggeration * max_elev;
}
// The bottom and top of the cylinder are the extrema parallel projections from the center point along the axis.
Vec4 bottomPoint = axis.multiply3(min_parallel).add3(centerPoint);
Vec4 topPoint = axis.multiply3(max_parallel).add3(centerPoint);
// The radius of the cylinder is the extrama perpendicular projection.
double radius = max_perp;
return new Cylinder(bottomPoint, topPoint, radius);
}
protected Extent computeBoundingExtent(DrawContext dc, Iterable<? extends Airspace> airspaces)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (airspaces == null)
{
String message = Logging.getMessage("nullValue.IterableIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
Vec4 center = null;
double radius = 0;
int count = 0;
// Add the center point of all airspace extents. This is the first step in computing the mean center point.
for (Airspace airspace : airspaces)
{
Extent extent = airspace.getExtent(dc);
if (extent != null)
{
center = (center != null) ? extent.getCenter().add3(center) : extent.getCenter();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -