⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surfacetext.java

📁 world wind java sdk 源码
💻 JAVA
字号:
/*
Copyright (C) 2001, 2009 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.render;

import com.sun.opengl.util.j2d.TextRenderer;
import gov.nasa.worldwind.Movable;
import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.util.Logging;

import javax.media.opengl.GL;
import java.awt.*;
import java.awt.geom.*;
import java.util.Arrays;

/**
 * Surface text.
 *
 * @author Patrick Murris
 * @version $Id: SurfaceText.java 10409 2009-04-22 18:36:06Z patrickmurris $
 */
public class SurfaceText extends AbstractSurfaceRenderable implements Movable  // TODO: implement GeographicText?
{
    private String text;
    private LatLon location;
    private Font font = Font.decode("Arial-BOLD-24");
    private Color color = Color.WHITE;

    protected TextRenderer textRenderer;
    protected Rectangle2D textBounds;

    // TODO: add min and max text dimension in meter
    // TODO: add location offset
    // TODO: handle opacity
    // TODO: add outline effect

    public SurfaceText(String text, LatLon location, Font font, Color color)
    {
        this.setText(text);
        this.setLocation(location);
        this.setFont(font);
        this.setColor(color);
    }

    public String getText()
    {
        return this.text;
    }

    public void setText(String text)
    {
        if (text == null)
        {
            String message = Logging.getMessage("nullValue.StringIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        this.text = text;
        this.updateTextBounds();
    }
    public LatLon getLocation()
    {
        return this.location;
    }

    public void setLocation(LatLon location)
    {
        if (location == null)
        {
            String message = Logging.getMessage("nullValue.LatLonIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        this.location = location;
    }

    public Font getFont()
    {
        return this.font;
    }

    public void setFont(Font font)
    {
        if (font == null)
        {
            String message = Logging.getMessage("nullValue.FontIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        this.font = font;
        if (this.textRenderer != null)
            this.textRenderer.dispose();
        this.textRenderer = null;
    }

    public Color getColor()
    {
        return this.color;
    }

    public void setColor(Color color)
    {
        if (color == null)
        {
            String message = Logging.getMessage("nullValue.ColorIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        this.color = color;
    }

    //*** SurfaceObject

    public long getLastModifiedTime()
    {
        return System.currentTimeMillis();  // Refresh all the time
    }
    
    public Iterable<? extends Sector> getSectors(DrawContext dc)
    {
        return Arrays.asList(computeSector(dc));
    }

    public void doRenderToRegion(DrawContext dc, Sector sector, int x, int y, int width, int height)
    {
        GL gl = dc.getGL();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();
        try
        {
            this.applyDrawTransform(dc, sector, x, y, width, height);

            // Draw text
            this.drawText(this.text, Vec4.ZERO);
        }
        finally
        {
            // Restore gl state
            gl.glPopMatrix();
        }
    }

    protected Sector computeSector(DrawContext dc)
    {
        // Compute text extent depending on distance from eye
        Globe globe = dc.getGlobe();
        double pixelSize = computePixelSizeAtLocation(dc, this.location);
        double dLatRadians = this.textBounds.getHeight() * pixelSize / globe.getRadius();
        double dLonRadians = this.textBounds.getWidth() * pixelSize / globe.getRadius() / location.getLatitude().cos();
        Sector sector = new Sector(
            location.getLatitude(),
            location.getLatitude().addRadians(dLatRadians),
            location.getLongitude().subtractRadians(dLonRadians / 2),
            location.getLongitude().addRadians(dLonRadians / 2)
        );

        // Rotate sector around location
        return computeRotatedSectorBounds(sector, this.location, computeDrawHeading(dc));
    }

    protected Angle computeDrawHeading(DrawContext dc)
    {
        return getViewHeading(dc);
    }

    protected TextRenderer getTextRenderer()
    {
        if (this.textRenderer == null)
            this.textRenderer =  new TextRenderer(this.font, true, true);

        return this.textRenderer;
    }

    // TODO: use text renderer cache from dc
//    protected TextRenderer getTextRenderer(DrawContext dc, Font font)
//    {
//        TextRenderer tr = dc.getTextRendererCache().get(font);
//        if (tr == null)
//        {
//            tr = new TextRenderer(font, true, true);
//            tr.setUseVertexArrays(false);
//            dc.getTextRendererCache().add(font, tr);
//        }
//        return tr;
//    }

    protected void updateTextBounds()
    {
        this.textBounds = getTextRenderer().getBounds(this.text);
    }

    protected void applyDrawTransform(DrawContext dc, Sector sector, int x, int y, int width, int height)
    {
        // Compute text viewport point
        Vec4 point = computeDrawPoint(this.location, sector, x, y, width, height);

        // Compute scaling depending on eye distance
        double regionPixelSize = computeDrawPixelSize(dc, sector, width, height);
        double viewPixelSize = computePixelSizeAtLocation(dc, this.location);
        double drawScale = viewPixelSize / regionPixelSize;

        GL gl = dc.getGL();
        gl.glTranslated(point.x(), point.y(), point.z());

        // Add x scaling transform to maintain text width and aspect ratio at any latitude
        gl.glScaled(drawScale/ this.location.getLatitude().cos(), drawScale, 1);

        // Add rotation to maintain text facing the eye
        gl.glRotated(computeDrawHeading(dc).degrees, 0, 0, -1);
    }

    protected void drawText(String text, Vec4 screenPoint)
    {
        TextRenderer tr = getTextRenderer();
        int x = (int) (screenPoint.x() - this.textBounds.getWidth() / 2d);
        int y = (int) screenPoint.y();

        tr.begin3DRendering();

        tr.setColor(this.computeBackgroundColor(this.color));
        tr.draw(text, x + 1, y - 1);
        tr.setColor(this.color);
        tr.draw(text, x, y);

        tr.end3DRendering();
    }

    private final float[] compArray = new float[4];
    // Compute background color for best contrast
    protected Color computeBackgroundColor(Color color)
    {
        Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), compArray);
        if (compArray[2] > 0.5)
            return new Color(0, 0, 0, 0.7f);
        else
            return new Color(1, 1, 1, 0.7f);
    }


    // *** Movable interface

    public Position getReferencePosition()
    {
        return new Position(this.location, 0);
    }

    public void move(Position position)
    {
        moveTo(getReferencePosition().add(position));

    }

    public void moveTo(Position position)
    {
        this.setLocation(position.getLatLon());
    }

}

⌨️ 快捷键说明

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