terrainprofilelayer.java

来自「world wind java sdk 源码」· Java 代码 · 共 1,710 行 · 第 1/5 页

JAVA
1,710
字号
/*
Copyright (C) 2001, 2008 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.layers;

import com.sun.opengl.util.j2d.*;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.avlist.*;
import gov.nasa.worldwind.event.*;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.pick.*;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.util.*;
import gov.nasa.worldwind.view.*;

import javax.media.opengl.*;
import java.awt.*;
import java.awt.geom.*;
import java.beans.*;
import java.util.*;

/**
 * Displays a terrain profile graph in a screen corner.
 *
 * <p> Usage: do setEventSource(wwd) to have the graph activated and updated with position changes. See public
 * properties for options: keepProportions, follow, unit, start and end latlon... </p>
 *
 * @author Patrick Murris
 * @version $Id: TerrainProfileLayer.java 10925 2009-05-06 22:22:50Z dcollins $
 */
public class TerrainProfileLayer extends AbstractLayer implements PositionListener, SelectListener
{
    // Units constants
    public final static String UNIT_METRIC = "gov.nasa.worldwind.TerrainProfileLayer.Metric";
    public final static String UNIT_IMPERIAL = "gov.nasa.worldwind.TerrainProfileLayer.Imperial";
    public final static double METER_TO_FEET = 3.280839895;
    // Follow constants
    public final static String FOLLOW_VIEW = "gov.nasa.worldwind.TerrainProfileLayer.FollowView";
    public final static String FOLLOW_EYE = "gov.nasa.worldwind.TerrainProfileLayer.FollowEye";
    public final static String FOLLOW_CURSOR = "gov.nasa.worldwind.TerrainProfileLayer.FollowCursor";
    public final static String FOLLOW_NONE = "gov.nasa.worldwind.TerrainProfileLayer.FollowNone";
    public final static String FOLLOW_OBJECT = "gov.nasa.worldwind.TerrainProfileLayer.FollowObject";
    public final static String FOLLOW_PATH = "gov.nasa.worldwind.TerrainProfileLayer.FollowPath";
    // Graph size when minimized
    private final static int MINIMIZED_SIZE = 32;

    // GUI pickable objects
    private final String buttonMinimize = new String("gov.nasa.worldwind.TerrainProfileLayer.ButtonMinimize");
    private final String buttonMaximize = new String("gov.nasa.worldwind.TerrainProfileLayer.ButtonMaximize");

    // Display parameters - TODO: make configurable
    private Dimension size = new Dimension(250, 100);
    private Color color = Color.white;
    private int borderWidth = 20;
    private String position = AVKey.SOUTHWEST;
    private String resizeBehavior = AVKey.RESIZE_SHRINK_ONLY;
    private String unit = UNIT_METRIC;
    private Font defaultFont = Font.decode("Arial-PLAIN-12");
    private double toViewportScale = 1;
    private Point locationCenter = null;
    private Vec4 locationOffset = null;
    private PickSupport pickSupport = new PickSupport();
    private boolean initialized = false;
    private boolean isMinimized = false;     // True when graph is minimized to an icon
    private boolean isMaximized = false;     // True when graph is 'full screen'
    private boolean showProfileLine = true;  // True to show the profile path line on the ground
    private boolean showPickedLine = true;   // True to show the picked position line on the terrain

    private boolean update = true;           // Recompute profile if true
    private int pickedSample = -1;           // Picked sample number if not -1
    Polyline selectionShape;                 // Shape showing section on the ground
    Polyline pickedShape;                    // Shape showing actual pick position on the ground
    private boolean keepProportions = false; // Keep graph distance/elevation proportions
    private boolean zeroBased = true;        // Pad graph elevation scale to include sea level if true
    private String follow = FOLLOW_VIEW;     // Profile position follow behavior
    private boolean showEyePosition = false; // When FOLLOW_EYE, draw the eye position on graph when true
    private double profileLengthFactor = 1;  // Applied to default profile length (zoom on profile)
    private LatLon startLatLon;              // Section start lat/lon when FOLLOW_NONE
    private LatLon endLatLon;                // Section end lat/lon when FOLLOW_NONE
    private Position objectPosition;         // Object position if FOLLOW_OBJECT
    private Angle objectHeading;             // Object heading if FOLLOW_OBJECT
    private ArrayList<? extends LatLon> pathPositions;  // Path position list if FOLLOW_PATH
    private int pathType = Polyline.GREAT_CIRCLE;

    // Terrain profile data
    private int samples = 250;              // Number of position samples
    private double minElevation;            // Minimum elevation along the profile
    private double maxElevation;            // Maximum elevation along the profile
    private double length;                  // Profile length along great circle in meter
    private Position positions[];           // Position list

    // Worldwind
    private WorldWindow wwd;

    // Draw it as ordered with an eye distance of 0 so that it shows up in front of most other things.
    // TODO: Add general support for this common pattern.
    private OrderedIcon orderedImage = new OrderedIcon();

    private class OrderedIcon implements OrderedRenderable
    {
        public double getDistanceFromEye()
        {
            return 0;
        }

        public void pick(DrawContext dc, Point pickPoint)
        {
            TerrainProfileLayer.this.drawProfile(dc);
        }

        public void render(DrawContext dc)
        {
            TerrainProfileLayer.this.drawProfile(dc);
        }
    }

    /**
     * Renders a terrain profile graphic in a screen corner.
     */
    public TerrainProfileLayer()
    {
    }

    // ** Public properties ************************************************************

    /**
     * Get whether the profile should be recomputed.
     *
     * @return true if the profile should be recomputed.
     */
    public boolean getUpdate()
    {
        return this.update;
    }

    /**
     * Set wheter the profile should be recomputed.
     *
     * @param state true if the profile should be recomputed.
     */
    public void setUpdate(boolean state)
    {
        this.update = state;
    }

    /**
     * Get whether the profile graph is minimized.
     *
     * @return true if the profile graph is minimized.
     */
    public boolean getIsMinimized()
    {
        return this.isMinimized;
    }

    /**
     * Set wheter the profile graph should be minimized. <p>Note that the graph can be both minimized and maximized at
     * the same time. The minimized state will take precedence and the graph will display as an icon. When
     * 'un-minimized' it will display as maximized.</p>
     *
     * @param state true if the profile should be minimized.
     * @see this.setIsMaximized()
     */
    public void setIsMinimized(boolean state)
    {
        this.isMinimized = state;
        this.pickedSample = -1;  // Clear picked position
    }

    /**
     * Get whether the profile graph is maximized - displays over the whole viewport.
     *
     * @return true if the profile graph is maximized.
     */
    public boolean getIsMaximized()
    {
        return this.isMaximized;
    }

    /**
     * Set wheter the profile graph should be maximized - displays over the whole viewport.
     *
     * @param state true if the profile should be maximized.
     */
    public void setIsMaximized(boolean state)
    {
        this.isMaximized = state;
    }

    /**
     * Get the graphic Dimension (in pixels).
     *
     * @return the scalebar graphic Dimension.
     */
    public Dimension getSize()
    {
        return this.size;
    }

    /**
     * Set the graphic Dimension (in pixels).
     *
     * @param size the graphic Dimension.
     */
    public void setSize(Dimension size)
    {
        if (size == null)
        {
            String message = Logging.getMessage("nullValue.DimensionIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        this.size = size;
    }

    /**
     * Get the graphic color.
     *
     * @return the graphic Color.
     */
    public Color getColor()
    {
        return this.color;
    }

    /**
     * Set the graphic Color.
     *
     * @param color the graphic Color.
     */
    public void setColor(Color color)
    {
        if (color == null)
        {
            String msg = Logging.getMessage("nullValue.ColorIsNull");
            Logging.logger().severe(msg);
            throw new IllegalArgumentException(msg);
        }
        this.color = color;
    }

    /**
     * Sets the layer opacity, which is applied to the layer's chart. The opacity is modified slightly for various
     * elements of the chart to distinguish among them.
     *
     * @param opacity the current opacity value, which is ignored by this layer.
     * @see #setColor
     */
    @Override
    public void setOpacity(double opacity)
    {
        super.setOpacity(opacity);
    }

    /**
     * Returns the layer's opacity value. The opacity is modified slightly for various elements of the chart to
     * distinguish among them.
     *
     * @return The layer opacity, a value between 0 and 1.
     * @see #getColor
     */
    @Override
    public double getOpacity()
    {
        return super.getOpacity();
    }

    /**
     * Returns the graphic-to-viewport scale factor.
     *
     * @return the graphic-to-viewport scale factor.
     */
    public double getToViewportScale()
    {
        return toViewportScale;
    }

    /**
     * Sets the scale factor applied to the viewport size to determine the displayed size of the graphic. This scale
     * factor is used only when the layer's resize behavior is {@link AVKey#RESIZE_STRETCH} or
     * {@link AVKey#RESIZE_SHRINK_ONLY}. The graphic's width is adjusted to occupy the proportion of the viewport's
     * width indicated by this factor. The graphic's height is adjusted to maintain the graphic's Dimension aspect
     * ratio.
     *
     * @param toViewportScale the graphic to viewport scale factor.
     */
    public void setToViewportScale(double toViewportScale)
    {
        this.toViewportScale = toViewportScale;
    }

    public String getPosition()
    {
        return this.position;
    }

    /**
     * Sets the relative viewport location to display the graphic. Can be one of {@link AVKey#NORTHEAST},
     * {@link AVKey#NORTHWEST}, {@link AVKey#SOUTHEAST}, or {@link AVKey#SOUTHWEST} (the default). These indicate
     * the corner of the viewport.
     *
     * @param position the desired graphic position.
     */
    public void setPosition(String position)
    {
        if (position == null)
        {
            String msg = Logging.getMessage("nullValue.PositionIsNull");
            Logging.logger().severe(msg);
            throw new IllegalArgumentException(msg);
        }
        this.position = position;
    }

    /**
     * Get the screen location of the graph center if set (can be null).
     *
     * @return the screen location of the graph center if set (can be null).
     */
    public Point getLocationCenter()
    {
        return this.locationCenter;
    }

    /**
     * Set the screen location of the graph center - overrides {@link #setPosition} if not null.
     *
     * @param point the screen location of the graph center (can be null).
     */
    public void setLocationCenter(Point point)
    {
        this.locationCenter = point;
    }

    /**
     * Returns the current location offset. See {@link #setLocationOffset} for a description of the offset and
     * its values.
     *
     * @return the location offset. Will be null if no offset has been specified.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?