terrainprofilelayer.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,710 行 · 第 1/5 页
JAVA
1,710 行
* @param heading the object heading the graph follows.
*/
public void setObjectHeading(Angle heading)
{
this.objectHeading = heading;
if (this.follow.equals(FOLLOW_OBJECT))
this.setUpdate(true);
}
/**
* Get the path positions that the profile follows if set to {@link #FOLLOW_PATH}.
* @return the path positions that the profile follows.
*/
public ArrayList<? extends LatLon> getPathPositions()
{
return this.pathPositions;
}
/**
* Set the path positions that the profile should follow if {@link #FOLLOW_PATH}.
* @param positions the path positions that the profile should follow.
*/
public void setPathPositions(ArrayList<? extends LatLon> positions)
{
if (positions == null)
{
String msg = Logging.getMessage("nullValue.PositionsListIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.pathPositions = positions;
if (this.follow.equals(FOLLOW_PATH))
this.setUpdate(true);
}
public int getPathType()
{
return this.pathType;
}
/**
* Sets the type of path to follow, one of {@link Polyline#GREAT_CIRCLE}, which computes each segment of the path
* as a great circle, or {@link Polyline#RHUMB_LINE}, which computes each segment of the path as a line of
* constant heading.
*
* @param type the type of path to follow.
*/
public void setPathType(int type)
{
this.pathType = type;
}
/**
* Get the <code>Polyline</code> used to render the profile line on the ground.
* @return the <code>Polyline</code> used to render the profile line on the ground.
*/
public Polyline getProfileLine()
{
return this.selectionShape;
}
/**
* Get the <code>Polyline</code> used to render the picked position on the terrain.
* @return the <code>Polyline</code> used to render the picked position on the terrain.
*/
public Polyline getPickedLine()
{
return this.selectionShape;
}
/**
* Get whether the profile line is displayed over the ground.
* @return true is the profile line is displayed over the ground.
*/
public boolean isShowProfileLine()
{
return this.showProfileLine;
}
/**
* Set whether the profile line should be displayed over the terrain.
* @param state true if the profile line should be displayed over the terrain.
*/
public void setShowProfileLine(boolean state)
{
this.showProfileLine = state;
}
/**
* Get whether the picked line is displayed over the ground.
* @return true if the picked line is displayed over the ground.
*/
public boolean isShowPickedLine()
{
return this.showPickedLine;
}
/**
* Set whether the picked line should be displayed over the ground.
* @param state if the picked line should be displayed over the ground.
*/
public void setShowPickedLine(boolean state)
{
this.showPickedLine = state;
}
// ** Rendering ************************************************************
@Override
public void doRender(DrawContext dc)
{
// Delegate graph rendering to OrderedRenderable list
dc.addOrderedRenderable(this.orderedImage);
// Render section line on the ground now
if (!isMinimized && this.positions != null && this.selectionShape != null)
{
if (this.showProfileLine)
this.selectionShape.render(dc);
// If picking in progress, render pick indicator
if (this.showPickedLine && this.pickedSample != -1 && this.pickedShape != null)
this.pickedShape.render(dc);
}
}
@Override
public void doPick(DrawContext dc, Point pickPoint)
{
dc.addOrderedRenderable(this.orderedImage);
}
private void initialize(DrawContext dc)
{
if (this.initialized || this.positions != null)
return;
if (this.wwd != null)
this.computeProfile(dc);
if (this.positions != null)
this.initialized = true;
}
// Profile graph rendering - ortho
public void drawProfile(DrawContext dc)
{
if (this.update)
this.computeProfile(dc);
if ((this.positions == null || (this.minElevation == 0 && this.maxElevation == 0))
&& !this.initialized)
this.initialize(dc);
if (this.positions == null || (this.minElevation == 0 && this.maxElevation == 0))
return;
GL gl = dc.getGL();
boolean attribsPushed = false;
boolean modelviewPushed = false;
boolean projectionPushed = false;
try
{
gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT
| GL.GL_COLOR_BUFFER_BIT
| GL.GL_ENABLE_BIT
| GL.GL_TEXTURE_BIT
| GL.GL_TRANSFORM_BIT
| GL.GL_VIEWPORT_BIT
| GL.GL_CURRENT_BIT);
attribsPushed = true;
gl.glDisable(GL.GL_TEXTURE_2D); // no textures
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
gl.glDisable(GL.GL_DEPTH_TEST);
Rectangle viewport = dc.getView().getViewport();
Dimension drawSize = isMinimized ? new Dimension(MINIMIZED_SIZE, MINIMIZED_SIZE) :
isMaximized ? new Dimension(viewport.width - this.borderWidth * 2,
viewport.height * 2 / 3 - this.borderWidth * 2) : this.size;
double width = drawSize.width;
double height = drawSize.height;
// Load a parallel projection with xy dimensions (viewportWidth, viewportHeight)
// into the GL projection matrix.
gl.glMatrixMode(javax.media.opengl.GL.GL_PROJECTION);
gl.glPushMatrix();
projectionPushed = true;
gl.glLoadIdentity();
double maxwh = width > height ? width : height;
gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPushMatrix();
modelviewPushed = true;
gl.glLoadIdentity();
// Scale to a width x height space
// located at the proper position on screen
double scale = this.computeScale(viewport);
Vec4 locationSW = this.computeLocation(viewport, scale);
gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
gl.glScaled(scale, scale, 1d);
if (!dc.isPickingMode())
{
// Draw grid - Set color using current layer opacity
this.drawGrid(dc, drawSize);
// Draw profile graph
this.drawGraph(dc, drawSize);
if (!isMinimized)
{
// Draw GUI buttons
drawGUI(dc, drawSize);
// Draw labels
String label = String.format("min %.0fm max %.0fm", this.minElevation, this.maxElevation);
if (this.unit.equals(UNIT_IMPERIAL))
label = String.format("min %.0fft max %.0fft", this.minElevation * METER_TO_FEET,
this.maxElevation * METER_TO_FEET);
gl.glLoadIdentity();
gl.glDisable(GL.GL_CULL_FACE);
drawLabel(dc, label, locationSW.add3(new Vec4(0, -12, 0)), -1); // left aligned
if (this.pickedSample != -1)
{
double pickedElevation = positions[this.pickedSample].getElevation();
label = String.format("%.0fm", pickedElevation);
if (this.unit.equals(UNIT_IMPERIAL))
label = String.format("%.0fft", pickedElevation * METER_TO_FEET);
drawLabel(dc, label, locationSW.add3(new Vec4(width, -12, 0)), 1); // right aligned
}
}
}
else
{
// Picking
this.pickSupport.clearPickList();
this.pickSupport.beginPicking(dc);
// Draw unique color across the rectangle
Color color = dc.getUniquePickColor();
int colorCode = color.getRGB();
if (!isMinimized)
{
// Update graph pick point
computePickPosition(dc, locationSW, new Dimension((int) (width * scale), (int) (height * scale)));
// Draw GUI buttons
drawGUI(dc, drawSize);
}
else
{
// Add graph to the pickable list for 'un-minimize' click
this.pickSupport.addPickableObject(colorCode, this);
gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
gl.glBegin(GL.GL_POLYGON);
gl.glVertex3d(0, 0, 0);
gl.glVertex3d(width, 0, 0);
gl.glVertex3d(width, height, 0);
gl.glVertex3d(0, height, 0);
gl.glVertex3d(0, 0, 0);
gl.glEnd();
}
// Done picking
this.pickSupport.endPicking(dc);
this.pickSupport.resolvePick(dc, dc.getPickPoint(), this);
}
}
catch (Exception e)
{
//e.printStackTrace();
}
finally
{
if (projectionPushed)
{
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix();
}
if (modelviewPushed)
{
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPopMatrix();
}
if (attribsPushed)
gl.glPopAttrib();
}
}
// Draw grid graphic
private void drawGrid(DrawContext dc, Dimension dimension)
{
// Background color
Color backColor = getBackgroundColor(this.color);
drawFilledRectangle(dc, new Vec4(0, 0, 0), dimension, new Color(backColor.getRed(),
backColor.getGreen(), backColor.getBlue(), (int) (backColor.getAlpha() * .5))); // Increased transparency
// Grid - minimal
float[] colorRGB = this.color.getRGBColorComponents(null);
dc.getGL().glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());
drawVerticalLine(dc, dimension, 0);
drawVerticalLine(dc, dimension, dimension.getWidth());
drawHorizontalLine(dc, dimension, 0);
}
// Draw profile graphic
private void drawGraph(DrawContext dc, Dimension dimension)
{
GL gl = dc.getGL();
// Adjust min/max elevation for the graph
double min = this.minElevation;
double max = this.maxElevation;
if (this.showEyePosition && this.follow.equals(FOLLOW_EYE))
max = Math.max(max, dc.getView().getEyePosition().getElevation());
if (this.showEyePosition && (this.follow.equals(FOLLOW_OBJECT) || this.follow.equals(FOLLOW_PATH))
&& this.objectPosition != null)
max = Math.max(max, this.objectPosition.getElevation());
if (this.zeroBased)
{
if (min > 0)
min = 0;
if (max < 0)
max = 0;
}
int i;
double stepX = dimension.getWidth() / this.length;
double stepY = dimension.getHeight() / (max - min);
if (this.keepProportions)
{
stepX = Math.min(stepX, stepY);
stepY = stepX;
}
double lengthStep = this.length / (this.samples - 1);
double x = 0, y;
// Filled graph
gl.glColor4ub((byte) this.color.getRed(), (byte) this.color.getGreen(),
(byte) this.color.getBlue(), (byte) 100);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
for (i = 0; i < this.samples; i++)
{
x = i * lengthStep * stepX;
y = (this.positions[i].getElevation() - min) * stepY;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?