terrainprofilelayer.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,710 行 · 第 1/5 页
JAVA
1,710 行
gl.glVertex3d(x, 0, 0);
gl.glVertex3d(x, y, 0);
}
gl.glEnd();
// Line graph
float[] colorRGB = this.color.getRGBColorComponents(null);
gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());
gl.glBegin(GL.GL_LINE_STRIP);
for (i = 0; i < this.samples; i++)
{
x = i * lengthStep * stepX;
y = (this.positions[i].getElevation() - min) * stepY;
gl.glVertex3d(x, y, 0);
}
gl.glEnd();
// Middle vertical line
gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity() * .3); // increased transparency here
if (!this.follow.equals(FOLLOW_PATH))
drawVerticalLine(dc, dimension, x / 2);
// Eye or object position
double eyeX = -1, eyeY = -1;
if ((this.follow.equals(FOLLOW_EYE) ||
(this.follow.equals(FOLLOW_OBJECT) && this.objectPosition != null) ||
(this.follow.equals(FOLLOW_PATH) && this.objectPosition != null))
&& this.showEyePosition)
{
eyeX = x / 2;
eyeY = (dc.getView().getEyePosition().getElevation() - min) * stepY;
if (this.follow.equals(FOLLOW_PATH))
eyeX = computeObjectSample(this.objectPosition) * lengthStep * stepX;
if (this.follow.equals(FOLLOW_OBJECT) || this.follow.equals(FOLLOW_PATH))
eyeY = (this.objectPosition.getElevation() - min) * stepY;
if (eyeX >= 0 && eyeY >= 0)
this.drawFilledRectangle(dc, new Vec4(eyeX - 2, eyeY - 2, 0), new Dimension(5, 5), this.color);
// Vertical line at object position when follow path
if (this.follow.equals(FOLLOW_PATH) && eyeX >= 0)
drawVerticalLine(dc, dimension, eyeX);
}
// Selected/picked vertical and horizontal lines
if (this.pickedSample != -1)
{
double pickedX = this.pickedSample * lengthStep * stepX;
double pickedY = (positions[this.pickedSample].getElevation() - min) * stepY;
gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2] * .5, this.getOpacity() * .8); // yellower color
drawVerticalLine(dc, dimension, pickedX);
drawHorizontalLine(dc, dimension, pickedY);
// Eye or object - picked position line
if (eyeX >= 0 && eyeY >= 0)
{
// Line
drawLine(dc, pickedX, pickedY, eyeX, eyeY);
// Distance label
double distance = dc.getView().getEyePoint().distanceTo3(
dc.getGlobe().computePointFromPosition(positions[this.pickedSample]));
if (this.follow.equals(FOLLOW_OBJECT) || this.follow.equals(FOLLOW_PATH))
distance = dc.getGlobe().computePointFromPosition(this.objectPosition).distanceTo3(
dc.getGlobe().computePointFromPosition(positions[this.pickedSample]));
String label = String.format("Dist %.0fm", distance);
if (this.unit.equals(UNIT_IMPERIAL))
label = String.format("Dist %.0fft", distance * METER_TO_FEET);
drawLabel(dc, label, new Vec4(pickedX + 5, pickedY - 12, 0), -1); // left aligned
}
}
// Min elevation horizontal line
if (this.minElevation != min)
{
y = (this.minElevation - min) * stepY;
gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity() * .5); // medium transparency
drawHorizontalLine(dc, dimension, y);
}
// Max elevation horizontal line
if (this.maxElevation != max)
{
y = (this.maxElevation - min) * stepY;
gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity() * .5); // medium transparency
drawHorizontalLine(dc, dimension, y);
}
// Sea level in between positive elevations only (not across land)
if (min < 0 && max >= 0)
{
gl.glColor4d(colorRGB[0] * .7, colorRGB[1] * .7, colorRGB[2], this.getOpacity() * .5); // bluer color
y = -this.minElevation * stepY;
double previousX = -1;
for (i = 0; i < this.samples; i++)
{
x = i * lengthStep * stepX;
if (this.positions[i].getElevation() > 0 || i == this.samples - 1)
{
if (previousX >= 0)
{
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(previousX, y, 0);
gl.glVertex3d(x, y, 0);
gl.glEnd();
previousX = -1;
}
}
else
previousX = previousX < 0 ? x : previousX;
}
}
}
private void drawGUI(DrawContext dc, Dimension dimension)
{
GL gl = dc.getGL();
int buttonSize = 16;
int hs = buttonSize / 2;
int buttonBorder = 4;
Dimension buttonDimension = new Dimension(buttonSize, buttonSize);
Color highlightColor = new Color(color.getRed(), color.getGreen(),
color.getBlue(), (int) (color.getAlpha() * .5));
Color backColor = getBackgroundColor(this.color);
backColor = new Color(backColor.getRed(), backColor.getGreen(),
backColor.getBlue(), (int) (backColor.getAlpha() * .5)); // Increased transparency
Color drawColor;
int y = dimension.height - buttonDimension.height - buttonBorder;
int x = dimension.width;
Object pickedObject = dc.getPickedObjects() != null ? dc.getPickedObjects().getTopObject() : null;
// Maximize button
if (!isMaximized)
{
x -= buttonDimension.width + buttonBorder;
if (dc.isPickingMode())
{
drawColor = dc.getUniquePickColor();
int colorCode = drawColor.getRGB();
this.pickSupport.addPickableObject(colorCode, this.buttonMaximize, null, false);
}
else
drawColor = this.buttonMaximize == pickedObject ? highlightColor : backColor;
drawFilledRectangle(dc, new Vec4(x, y, 0), buttonDimension, drawColor);
if (!dc.isPickingMode())
{
gl.glColor4ub((byte) color.getRed(), (byte) color.getGreen(),
(byte) color.getBlue(), (byte) color.getAlpha());
// Draw '+'
drawLine(dc, x + 3, y + hs, x + buttonDimension.width - 3, y + hs); // Horizontal line
drawLine(dc, x + hs, y + 3, x + hs, y + buttonDimension.height - 3); // Vertical line
}
}
// Minimize button
x -= buttonDimension.width + buttonBorder;
if (dc.isPickingMode())
{
drawColor = dc.getUniquePickColor();
int colorCode = drawColor.getRGB();
this.pickSupport.addPickableObject(colorCode, this.buttonMinimize, null, false);
}
else
drawColor = this.buttonMinimize == pickedObject ? highlightColor : backColor;
drawFilledRectangle(dc, new Vec4(x, y, 0), buttonDimension, drawColor);
if (!dc.isPickingMode())
{
gl.glColor4ub((byte) color.getRed(), (byte) color.getGreen(),
(byte) color.getBlue(), (byte) color.getAlpha());
// Draw '-'
drawLine(dc, x + 3, y + hs, x + buttonDimension.width - 3, y + hs); // Horizontal line
}
}
private void drawHorizontalLine(DrawContext dc, Dimension dimension, double y)
{
drawLine(dc, 0, y, dimension.getWidth(), y);
}
private void drawVerticalLine(DrawContext dc, Dimension dimension, double x)
{
drawLine(dc, x, 0, x, dimension.getHeight());
}
private void drawFilledRectangle(DrawContext dc, Vec4 origin, Dimension dimension, Color color)
{
GL gl = dc.getGL();
gl.glColor4ub((byte) color.getRed(), (byte) color.getGreen(),
(byte) color.getBlue(), (byte) color.getAlpha());
gl.glDisable(GL.GL_TEXTURE_2D); // no textures
gl.glBegin(GL.GL_POLYGON);
gl.glVertex3d(origin.x, origin.y, 0);
gl.glVertex3d(origin.x + dimension.getWidth(), origin.y, 0);
gl.glVertex3d(origin.x + dimension.getWidth(), origin.y + dimension.getHeight(), 0);
gl.glVertex3d(origin.x, origin.y + dimension.getHeight(), 0);
gl.glVertex3d(origin.x, origin.y, 0);
gl.glEnd();
}
private void drawLine(DrawContext dc, double x1, double y1, double x2, double y2)
{
GL gl = dc.getGL();
gl.glBegin(GL.GL_LINE_STRIP);
gl.glVertex3d(x1, y1, 0);
gl.glVertex3d(x2, y2, 0);
gl.glEnd();
}
// Draw a text label
// Align = -1: left, 0: center and 1: right
private void drawLabel(DrawContext dc, String text, Vec4 screenPoint, int align)
{
TextRenderer textRenderer = dc.getTextRendererCache().getOrCreate(this.defaultFont);
Rectangle2D nameBound = textRenderer.getBounds(text);
int x = (int) screenPoint.x(); // left
if (align == 0)
x = (int) (screenPoint.x() - nameBound.getWidth() / 2d); // centered
if (align > 0)
x = (int) (screenPoint.x() - nameBound.getWidth()); // right
int y = (int) screenPoint.y();
textRenderer.begin3DRendering();
textRenderer.setColor(this.getBackgroundColor(this.color));
textRenderer.draw(text, x + 1, y - 1);
textRenderer.setColor(this.color);
textRenderer.draw(text, x, y);
textRenderer.end3DRendering();
}
// Compute background color for best contrast
private Color getBackgroundColor(Color color)
{
float[] compArray = new float[4];
Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), compArray);
if (compArray[2] > 0.5)
return new Color(0, 0, 0, (int) (this.color.getAlpha() * 0.7f));
else
return new Color(255, 255, 255, (int) (this.color.getAlpha() * 0.7f));
}
// ** Dimensions and positionning ************************************************************
private double computeScale(java.awt.Rectangle viewport)
{
if (this.resizeBehavior.equals(AVKey.RESIZE_SHRINK_ONLY))
{
return Math.min(1d, (this.toViewportScale) * viewport.width / this.size.width);
}
else if (this.resizeBehavior.equals(AVKey.RESIZE_STRETCH))
{
return (this.toViewportScale) * viewport.width / this.size.width;
}
else if (this.resizeBehavior.equals(AVKey.RESIZE_KEEP_FIXED_SIZE))
{
return 1d;
}
else
{
return 1d;
}
}
private Vec4 computeLocation(java.awt.Rectangle viewport, double scale)
{
double scaledWidth = scale * (isMinimized ? MINIMIZED_SIZE :
isMaximized ? viewport.width - this.borderWidth * 2 : this.size.width);
double scaledHeight = scale * (isMinimized ? MINIMIZED_SIZE :
isMaximized ? viewport.height * 2 / 3 - this.borderWidth * 2 : this.size.height);
double x;
double y;
if (this.locationCenter != null)
{
x = this.locationCenter.x - scaledWidth / 2;
y = this.locationCenter.y - scaledHeight / 2;
}
else if (this.position.equals(AVKey.NORTHEAST))
{
x = viewport.getWidth() - scaledWidth - this.borderWidth;
y = viewport.getHeight() - scaledHeight - this.borderWidth;
}
else if (this.position.equals(AVKey.SOUTHEAST))
{
x = viewport.getWidth() - scaledWidth - this.borderWidth;
y = 0d + this.borderWidth;
}
else if (this.position.equals(AVKey.NORTHWEST))
{
x = 0d + this.borderWidth;
y = viewport.getHeight() - scaledHeight - this.borderWidth;
}
else if (this.position.equals(AVKey.SOUTHWEST))
{
x = 0d + this.borderWidth;
y = 0d + this.borderWidth;
}
else // use North East
{
x = viewport.getWidth() - scaledWidth / 2 - this.borderWidth;
y = viewport.getHeight() - scaledHeight / 2 - this.borderWidth;
}
if (this.locationOffset != null)
{
x += this.locationOffset.x;
y += this.locationOffset.y;
}
return new Vec4(x, y, 0);
}
/**
* Computes the Position of the pickPoint over the graph and updates pickedSample indice
*
* @param dc the current DrawContext
* @param locationSW the screen location of the bottom left corner of the graph
* @param mapSize the graph screen dimension in pixels
* @return the picked Position
*/
private Position computePickPosition(DrawContext dc, Vec4 locationSW, Dimension mapSize)
{
Position pickPosition = null;
this.pickedSample = -1;
Point pickPoint = dc.getPickPoint();
if (pickPoint != null && this.positions != null && !this.follow.equals(FOLLOW_CURSOR))
{
Rectangle viewport = dc.getView().getViewport();
// Check if pickpoint is inside the graph
if (pickPoint.getX() >= locationSW.getX()
&& pickPoint.getX() < locationSW.getX() + mapSize.width
&& viewport.height - pickPoint.getY() >= locationSW.getY()
&& viewport.height - pickPoint.getY() < locationSW.getY() + mapSize.height)
{
// Find sample - Note: only works when graph expends over the full width
int sample = (int) (((double) (pickPoint.getX() - locationSW.getX()) / mapSize.width) * this.samples);
if (sample >= 0 && sample < this.samples)
{
pickPosition = this.positions[sample];
this.pickedSample = sample;
// Update polyline indicator
ArrayList<Position> posList = new ArrayList<Position>();
posList.add(positions[sample]);
posList.add(new Position(positions[sample].getLatitude(), positions[sample].getLongitude(),
positions[sample].getElevation() + this.length / 10));
if (this.pickedShape == null)
{
this.pickedShape = new Polyline(posList);
this.pickedShape.setPathType(Polyline.LINEAR);
this.pickedShape.setLineWidth(2);
this.pickedShape.setColor(new Color(this.color.getRed(),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?