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