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 + -
显示快捷键?