Package com.bbn.openmap.layer.e00

Source Code of com.bbn.openmap.layer.e00.TX7

// **********************************************************************
//
// <copyright>
//
//  BBN Technologies
//  10 Moulton Street
//  Cambridge, MA 02138
//  (617) 873-8000
//
//  Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/e00/TX7.java,v $
// $RCSfile: TX7.java,v $
// $Revision: 1.4.2.2 $
// $Date: 2005/08/11 21:03:31 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.layer.e00;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import com.bbn.openmap.LatLonPoint;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.proj.GreatCircle;
import com.bbn.openmap.proj.Planet;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.Debug;

/**
* Description of the Class that displays a String along a polygon or
* a polyline defined by lat lon points.
*
* @author paricaud
*/
public class TX7 extends OMGraphic {
    double w = 1, angle = 0;
    LatLonPoint llp1 = new LatLonPoint(), llp2 = new LatLonPoint();
    Point pt1 = new Point(), pt2 = new Point();
    AffineTransform at = new AffineTransform();
    float llpoints[];
    String str;
    Font font = defaultFont;
    GlyphVector gv;
    //GeneralPath path;
    float distance;
    boolean badprojection;
    final static Font defaultFont = new Font("Arial", Font.PLAIN, 10);

    /**
     * Constructor for the TX7 object
     *
     * @param llpoints array on lat lon lat lon ...
     * @param str Text
     * @param isRadian true if lat lons given in radians
     * @since
     */
    public TX7(float llpoints[], String str, boolean isRadian) {
        this(llpoints, str, isRadian, null);
    }

    /**
     * Constructor for the TX7 object
     *
     * @param llpoints array on lat lon lat lon ...
     * @param str Text
     * @param isRadian true if lat lons given in radians
     * @param font font used to draw text
     * @since
     */
    public TX7(float llpoints[], String str, boolean isRadian, Font font) {
        if (str == null)
            this.str = " ";
        else
            this.str = str;
        if (font == null)
            this.font = defaultFont;
        else
            this.font = font;
        setLocation(llpoints, isRadian);
    }

    /**
     * Constructor for the TX7 object
     *
     * @param llpoints array on lat lon lat lon ...
     * @param str Text *
     * @since
     */
    public TX7(float llpoints[], String str) {
        this(llpoints, str, true, null);
    }

    /**
     * Sets the text attribute of the TX7 object
     *
     * @param S The new text value
     * @since
     */
    public void setText(String S) {
        str = S;
        compute();
    }

    /**
     * Sets the font attribute of the TX7 object
     *
     * @param f The new font value
     * @since
     */
    public void setFont(Font f) {
        font = f;
        compute();
    }

    /**
     * Sets the location attribute of the TX7 object
     *
     * @param llpoints array on lat lon lat lon ...
     * @param isRadian true if lat lons given in radians
     * @since
     */
    public void setLocation(float[] llpoints, boolean isRadian) {
        this.llpoints = llpoints;
        if (!isRadian) {
            float cv = (float) (Math.PI / 180.0);
            for (int i = 0; i < llpoints.length; i++)
                llpoints[i] *= cv;
        }
        compute();
    }

    /**
     * Gets the font attribute of the TX7 object
     *
     * @return The font value
     * @since
     */
    public Font getFont() {
        return font;
    }

    /**
     * Gets the text attribute of the TX7 object
     *
     * @return The text value
     * @since
     */
    public String getText() {
        return str;
    }

    /**
     * Gets the location attribute of the TX7 object
     *
     * @return array on lat lon lat lon ... in radians
     * @since
     */
    public float[] getLocation() {
        return llpoints;
    }

    /**
     * generate with a new projection
     *
     * @param proj new Projection
     * @return Description of the Returned Value
     * @since
     */
    public boolean generate(Projection proj) {
        proj.forward(llp1, pt1);
        proj.forward(llp2, pt2);
        int dx = pt2.x - pt1.x;
        int dy = pt2.y - pt1.y;
        at.setToTranslation(pt1.x, pt1.y);
        at.rotate(Math.atan2(dy, dx) - angle, 0, 0);
        double sc = Math.sqrt(dx * dx + dy * dy);
        badprojection = (Double.isNaN(sc) || sc / distance * proj.getScale() > 1000000);
        if (badprojection)
            Debug.message("e00", "badprojection " + str);
        else {
            sc /= w;
            at.scale(sc, sc);
        }
        return true;
    }

    /**
     * render
     *
     * @param g Graphics
     * @since
     */
    public void render(Graphics g) {
        if (!visible)
            return;
        if (badprojection)
            return;
        g.setColor(Color.red);
        Graphics2D g2d = (Graphics2D) g;
        if (selected)
            g2d.setPaint(selectPaint);
        else
            g2d.setPaint(linePaint);
        AffineTransform saveAT = g2d.getTransform();
        // Perform transformation
        g2d.transform(at);
        // Render
        g2d.drawGlyphVector(gv, 0, 0);
        g.setColor(Color.blue);
        /*
         * if (path != null) { Stroke st = g2d.getStroke();
         * g2d.setStroke(new BasicStroke(.3f)); g2d.draw(path);
         * g2d.setStroke(st); }
         */
        // Restore original transform
        g2d.setTransform(saveAT);
    }

    /**
     * compute the glyphVector
     *
     * @since
     */
    void compute() {
        float lt1;
        float ln1;
        float lt2;
        float ln2;
        FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
        gv = font.createGlyphVector(frc, str);
        Rectangle2D r = gv.getLogicalBounds();
        w = r.getWidth();
        angle = 0;
        int nseg = llpoints.length / 2 - 1;
        lt1 = llpoints[0];
        ln1 = llpoints[1];
        llp1.setLatLon(lt1, ln1, true);
        lt2 = llpoints[2 * nseg];
        ln2 = llpoints[2 * nseg + 1];
        llp2.setLatLon(lt2, ln2, true);
        distance = GreatCircle.spherical_distance(lt1, ln1, lt2, ln2)
                * Planet.wgs84_earthEquatorialRadiusMeters;
        //System.out.println(nseg+" "+llp1+" "+llp2);
        setNeedToRegenerate(true);
        visible = false;

        float[] ds = new float[nseg];
        float[] az = new float[nseg];
        float[] cs = new float[nseg];
        int j = 2;
        float s = 0;
        float corr = 0;
        float dz;
        float az0 = 0;
        for (int i = 0; i < nseg; i++) {
            //if(j>llpoints.length-2){System.out.println(j+" "+i+"
            // "+nseg);nseg=1;break;}
            lt2 = (float) llpoints[j++];
            ln2 = (float) llpoints[j++];
            if (lt2 == lt1 && ln2 == ln1) {
                // suppress null segments
                i--;
                nseg--;
            } else {
                s += GreatCircle.spherical_distance(lt1, ln1, lt2, ln2);
                ds[i] = s;
                az[i] = GreatCircle.spherical_azimuth(lt1, ln1, lt2, ln2);
                if (i > 0) {
                    dz = (float) Math.tan((az[i] - az0) / 2);
                    if (dz < 0) {
                        cs[i - 1] = -dz;
                        corr -= 2 * dz;
                    }
                }
                az0 = az[i];
                lt1 = lt2;
                ln1 = ln2;
            }
        }
        if (nseg <= 1)
            return;
        // now try to play with little boxes
        // rotate them either on upper left corner or lower lef corner
        // probably can be simplified ...
        visible = true;
        LineMetrics lm = font.getLineMetrics("MM", frc);
        if (lm == null) {
            System.out.println("null metrics");
            return;
        }
        float h = (float) lm.getAscent();
        //System.out.println("ascent:" + h + " w:" + w + " s:" + s +
        // " corr:" + corr + " wc:" + (w - corr * h) + " " + str);
        corr = 0f;
        w -= corr * h;
        float sc = (float) (w / s);
        for (int i = 0; i < nseg; i++)
            ds[i] *= sc;
        int m = gv.getNumGlyphs();
        float[] gp = gv.getGlyphPositions(0, m, null);
        if (gp == null)
            System.out.println("gp null");
        //path = new GeneralPath();
        AffineTransform at;
        double dx;
        double dy;
        double x = 0;
        double y = 0;
        double xa;
        double ya;
        double s0 = 0;
        double ps;
        double s1;
        double s2;
        double theta;
        double theta2;
        double thetai;
        double dtheta;
        double ch0 = 0;
        double cos1;
        double sin1;
        double cos2;
        double sin2;
        j = 0;
        for (int i = 0; i < m; i++) {
            s = (i == m - 1) ? (float) w : gp[2 * i + 2];
            ps = s - s0;
            theta = az[j];
            cos1 = Math.cos(theta);
            sin1 = Math.sin(theta);
            float ch = (float) (cs[j] * h);
            if (s + ch0 < ds[j] - ch || j == nseg - 1) {
                xa = x;
                ya = y;
                x += ps * cos1;
                y += ps * sin1;
            } else {
                theta2 = az[j + 1];
                cos2 = Math.cos(theta2);
                sin2 = Math.sin(theta2);
                dtheta = theta2 - theta;
                s1 = ds[j] - ch - ch0 - s0;
                s2 = s1 * Math.sin(dtheta);
                s2 = ps * ps - s2 * s2;
                s2 = Math.sqrt(s2) - s1 * Math.cos(dtheta);
                dx = s1 * cos1 + s2 * cos2;
                dy = s1 * sin1 + s2 * sin2;
                thetai = Math.atan2(dy, dx);
                if (ch == 0) {
                    xa = x;
                    ya = y;
                } else {
                    dx += ch * cos1 + ch * cos2;
                    dy += ch * sin1 + ch * sin2;
                    xa = x + h * sin1 - h * Math.sin(thetai);
                    ya = y - h * cos1 + h * Math.cos(thetai);
                }
                x += dx;
                y += dy;
                j++;
                ch0 = ch;
                theta = thetai;
            }

            gv.setGlyphPosition(i, new Point2D.Double(xa, ya));
            if (theta != 0) {
                at = new AffineTransform();
                at.rotate(theta);
                gv.setGlyphTransform(i, at);
            }
            s0 = s;
            /*
             * path.moveTo((float) xa, (float) ya); xa += ps *
             * Math.cos(theta); ya += ps * Math.sin(theta);
             * path.lineTo((float) xa, (float) ya); xa += h *
             * Math.sin(theta); ya -= h * Math.cos(theta);
             * path.lineTo((float) xa, (float) ya); xa -= ps *
             * Math.cos(theta); ya -= ps * Math.sin(theta);
             * path.lineTo((float) xa, (float) ya); path.closePath();
             */
        }
        angle = Math.atan2(y, x);
        w = Math.sqrt(x * x + y * y);

    }
}
TOP

Related Classes of com.bbn.openmap.layer.e00.TX7

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.