Package com.bbn.openmap.layer.dted

Source Code of com.bbn.openmap.layer.dted.DTEDCoverageManager

// **********************************************************************
//
// <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/dted/DTEDCoverageManager.java,v $
// $RCSfile: DTEDCoverageManager.java,v $
// $Revision: 1.3.2.2 $
// $Date: 2004/10/14 18:27:04 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.layer.dted;

/*  Java Core  */
import java.awt.Color;
import java.awt.Paint;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;

/*  OpenMap  */
import com.bbn.openmap.LatLonPoint;
import com.bbn.openmap.event.ProgressEvent;
import com.bbn.openmap.event.ProgressListener;
import com.bbn.openmap.event.ProgressSupport;
import com.bbn.openmap.io.BinaryBufferedFile;
import com.bbn.openmap.io.BinaryFile;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.omGraphics.OMGraphicList;
import com.bbn.openmap.omGraphics.OMRect;
import com.bbn.openmap.proj.Cylindrical;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.Debug;

/**
* A DTEDCoverageManager knows how to look at DTED data and figure out
* what coverage is available. When it is constructed, it needs to
* know where the data is located, and where it can look for a
* coverage summary file. If a coverage summary file is not available,
* it will create one after looking at the data. Using the file is
* soooo much faster. The coverage manager also takes a URL of a
* coverage file, but assumes that the file is there. If it isn't,
* then it falls back on it's behavior of looking for a local summary
* file, and then to the data itself, to come up with coverage.
*/
public class DTEDCoverageManager {

    /** The default line color for level 0. */
    public final static String defaultLevel0ColorString = "CE4F3F"; // redish
    /** The default line color for level 1. */
    public final static String defaultLevel1ColorString = "339159"; // greenish
    /** The default line color for level 2. */
    public final static String defaultLevel2ColorString = "0C75D3"; // bluish

    /** The color to outline the shapes for level 0. */
    protected Paint level0Color = new Color(Integer.parseInt(defaultLevel0ColorString,
            16));
    /** The color to outline the shapes for level 1. */
    protected Paint level1Color = new Color(Integer.parseInt(defaultLevel1ColorString,
            16));
    /** The color to outline the shapes for level 2. */
    protected Paint level2Color = new Color(Integer.parseInt(defaultLevel2ColorString,
            16));

    /**
     * A setting for how transparent to make the images. The default
     * is 255, which is totally opaque.
     */
    protected int opaqueness = 255;
    /** Flag to fill the coverage rectangles. */
    protected boolean fillRects = false;

    /** The array of coverage for level 0 data. */
    protected boolean[][] level0Frames = null;
    /** The array of coverage for level 1 data. */
    protected boolean[][] level1Frames = null;
    /** The array of coverage for level 2 data. */
    protected boolean[][] level2Frames = null;

    protected ProgressSupport progressSupport;

    public DTEDCoverageManager(String[] paths, String[] paths2,
            String coverageURL, String coverageFile) {

        progressSupport = new ProgressSupport(this);

        if (!readCoverageFile(coverageURL, coverageFile)) {
            // Swing issues with threading, this is trouble.
            //             ProgressListenerGauge plg = new
            // ProgressListenerGauge("Creating DTED Coverage File");
            //             addProgressListener(plg);
            fireProgressUpdate(ProgressEvent.START,
                    "Building DTED Coverage file...",
                    0,
                    100);

            level0Frames = new boolean[180][360];
            level1Frames = new boolean[180][360];
            level2Frames = new boolean[180][360];

            if (paths != null || paths2 != null) {
                Debug.output("DTEDCoverageManager: Scanning for frames - This could take several minutes!");
                checkOutCoverage(paths, paths2);
            } else {
                Debug.message("dtedcov",
                        "DTEDCoverageManader: No paths for DTED data given.");
            }

            //Write out the new coverage file.
            if (coverageFile != null) {
                fireProgressUpdate(ProgressEvent.UPDATE,
                        "Writing DTED Coverage file...",
                        100,
                        100);

                writeCoverageFile(coverageFile);
            } else {
                Debug.message("dtedcov",
                        "DTEDCoverageManager: No file path specified to write coverage file!");
            }

            fireProgressUpdate(ProgressEvent.DONE,
                    "Wrote DTED Coverage file",
                    100,
                    100);
        }
    }

    /**
     * Set the color arraignment for the rectangles. Opaqueness is not
     * supported in JDK 1.1, so this doesn't really mean anything.
     * It's a hook for later.
     *
     * @param lev0Color Paint for level 0 frame rectangles.
     * @param lev1Color Paint for level 1 frame rectangles.
     * @param lev2Color Paint for level 2 frame rectangles.
     * @param opaque how transparent the frames should be if they are
     *        filled.
     * @param fillRectangles whether to fill the rectangles with
     *        Paint.
     */
    public void setPaint(Paint lev0Color, Paint lev1Color, Paint lev2Color,
                         int opaque, boolean fillRectangles) {
        level0Color = lev0Color;
        level1Color = lev1Color;
        level2Color = lev2Color;
        opaqueness = opaque;
        fillRects = fillRectangles;
    }

    /**
     * The method that cycles through all the paths, looking for the
     * frames. This takes time, so it's only done when a coverage file
     * can't be found.
     *
     * @param paths paths to the level 0 and 1 dted root directory.
     * @param paths2 paths to the level 2 dted root directory.
     */
    public void checkOutCoverage(String[] paths, String[] paths2) {
        int latindex, lonindex;
        int maxNumPaths = 0;

        if (paths != null)
            maxNumPaths = paths.length;
        if ((paths2 != null) && (paths2.length > maxNumPaths))
            maxNumPaths = paths2.length;

        if (maxNumPaths == 0) {
            System.err.println("DTEDCoverageManader: No paths for DTED data given.");
            return;
        }

        if (paths != null) {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: checking out DTED level 0, 1 at paths:");
            for (int d1 = 0; d1 < paths.length; d1++) {
                if (Debug.debugging("dtedcov")) {
                    Debug.output("       " + paths[d1]);
                }
                if (!BinaryFile.exists(paths[d1])) {
                    paths[d1] = null;
                    Debug.message("dtedcov", "       - path invalid, ignoring.");
                }
            }
        } else {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: No DTED level 0, 1 paths specified.");
        }

        if (paths2 != null) {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: checking out DTED level 2 at paths:");
            for (int d1 = 0; d1 < paths2.length; d1++) {
                if (Debug.debugging("dtedcov")) {
                    Debug.output("       " + paths2[d1]);
                }
                if (!BinaryFile.exists(paths2[d1])) {
                    paths2[d1] = null;
                    Debug.message("dtedcov", "       - path invalid, ignoring.");
                }
            }
        } else {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: No DTED level 2 paths specified.");
        }

        for (int pathNum = 0; pathNum < maxNumPaths; pathNum++) {
            for (int lat = -90; lat < 90; lat++) {
                for (int lon = -180; lon < 180; lon++) {
                    latindex = lat + 90;
                    lonindex = lon + 180;

                    if (paths != null && pathNum < paths.length) {
                        if (paths[pathNum] != null) {
                            if (level0Frames[latindex][lonindex] == false) {
                                level0Frames[latindex][lonindex] = BinaryFile.exists(paths[pathNum]
                                        + File.separator
                                        + DTEDFrameUtil.lonToFileString((float) lon)
                                        + File.separator
                                        + DTEDFrameUtil.latToFileString((float) lat,
                                                0));
                            }

                            if (level1Frames[latindex][lonindex] == false) {
                                level1Frames[latindex][lonindex] = BinaryFile.exists(paths[pathNum]
                                        + File.separator
                                        + DTEDFrameUtil.lonToFileString((float) lon)
                                        + File.separator
                                        + DTEDFrameUtil.latToFileString((float) lat,
                                                1));

                            }
                        }
                    }

                    if ((paths2 != null) && (pathNum < paths2.length)) {
                        if (paths2[pathNum] != null) {
                            if (level2Frames[latindex][lonindex] == false) {
                                level2Frames[latindex][lonindex] = BinaryFile.exists(paths2[pathNum]
                                        + File.separator
                                        + DTEDFrameUtil.lonToFileString((float) lon)
                                        + File.separator
                                        + DTEDFrameUtil.latToFileString((float) lat,
                                                1));
                            }
                        }
                    }
                }

                float pathFactor = ((float) pathNum + 1f) / (float) maxNumPaths;
                float latFactor = 100f * ((float) lat + 90f) / 180f;
                int whereWeAre = (int) (pathFactor * latFactor);
                if (Debug.debugging("dtedcov")) {
                    Debug.output("Building DTED Coverage, " + whereWeAre
                            + "% complete.");
                }

                fireProgressUpdate(ProgressEvent.UPDATE,
                        "Finding DTED frames...",
                        whereWeAre,
                        100);
            }
        }

    }

    /**
     * Method organizes the query based on the projection, and returns
     * the applicable rectangles representing the frame coverages. If
     * the coverage spans over the dateline, then two queries are
     * performed, one for each side of the dateline.
     *
     * @param proj the projection of the screen
     * @return an array of lists, one for each level of dted data.
     */
    public OMGraphicList[] getCoverageRects(Projection proj) {
        OMGraphicList[] ret1;
        OMGraphicList[] ret2;

        int LineType;

        LatLonPoint ul = proj.getUpperLeft();
        LatLonPoint lr = proj.getLowerRight();

        int startx = (int) Math.floor(ul.getLongitude());
        int endx = (int) Math.floor(lr.getLongitude());
        if (endx > 179)
            endx = 179;
        if (startx > 179)
            startx = 179;

        int starty = (int) Math.floor(lr.getLatitude());
        int endy = (int) Math.floor(ul.getLatitude());
        if (endy > 89)
            endy = 89;
        if (starty > 89)
            starty = 89;

        if (proj instanceof Cylindrical)
            LineType = OMGraphic.LINETYPE_STRAIGHT;
        else
            LineType = OMGraphic.LINETYPE_RHUMB;

        if (startx > endx) {
            ret1 = getCoverageRects(startx, starty, 179, endy, LineType);
            ret2 = getCoverageRects(-180, starty, endx, endy, LineType);
            ret1[0].add(ret2[0]);
            ret1[1].add(ret2[1]);
            ret1[2].add(ret2[2]);
            return ret1;
        } else
            return getCoverageRects(startx, starty, endx, endy, LineType);
    }

    /**
     * Method looks at the coverage arrays, and returns the applicable
     * rectangles representing the frame coverages.
     *
     * @param startx the western-most longitude.
     * @param starty the southern-most latitude.
     * @param endx the eastern-most longitude.
     * @param endy the northern-most latitude.
     * @param LineType the type of line to use on the rectangles -
     *        Cylindrical projections can use straight lines, but
     *        other projections should use Rhumb lines.
     * @return an array of lists, one for each level of dted data.
     */
    public OMGraphicList[] getCoverageRects(int startx, int starty, int endx,
                                            int endy, int LineType) {
        OMGraphicList gl0 = new OMGraphicList();
        OMGraphicList gl1 = new OMGraphicList();
        OMGraphicList gl2 = new OMGraphicList();
        OMGraphicList[] ret = new OMGraphicList[3];

        ret[0] = gl0;
        ret[1] = gl1;
        ret[2] = gl2;

        OMRect rect;

        for (int lat = starty; lat <= endy; lat++) {
            for (int lon = startx; lon <= endx; lon++) {
                if (level0Frames[lat + 90][lon + 180]) {
                    rect = new OMRect((float) lat, (float) lon, (float) lat + 1, (float) lon + 1, LineType);
                    rect.setLinePaint(level0Color);
                    if (fillRects)
                        rect.setFillPaint(level0Color);
                    gl0.add(rect);
                }

                if (level1Frames[lat + 90][lon + 180]) {
                    rect = new OMRect((float) lat + .1f, (float) lon + .1f, (float) lat + .9f, (float) lon + .9f, LineType);
                    rect.setLinePaint(level1Color);
                    if (fillRects)
                        rect.setFillPaint(level1Color);
                    gl1.add(rect);
                }

                if (level2Frames[lat + 90][lon + 180]) {
                    rect = new OMRect((float) lat + .2f, (float) lon + .2f, (float) lat + .8f, (float) lon + .8f, LineType);
                    rect.setLinePaint(level2Color);
                    if (fillRects)
                        rect.setFillPaint(level2Color);
                    gl2.add(rect);
                }
            }
        }
        return ret;
    }

    /**
     * Read in the coverage file, which is basically three
     * byte[180][360] written out to file. These are converted to
     * booleans.
     *
     * @param coverage the path to the file.
     * @return whether the file was read! True means yes.
     */
    public boolean readCoverageFile(String coverage) {
        try {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: Reading coverage file - " + coverage);
            BinaryBufferedFile binFile = new BinaryBufferedFile(coverage);
            level0Frames = new boolean[180][];
            level1Frames = new boolean[180][];
            level2Frames = new boolean[180][];

            byte[] row = new byte[360];

            for (int level = 0; level < 3; level++) {
                for (int lat = 0; lat < 180; lat++) {
                    binFile.read(row);

                    if (level == 0)
                        level0Frames[lat] = convertBytesToBooleans(row);
                    else if (level == 1)
                        level1Frames[lat] = convertBytesToBooleans(row);
                    else
                        level2Frames[lat] = convertBytesToBooleans(row);
                }
            }
            return true;

        } catch (IOException ioe) {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: No coverage file - will create one at "
                            + coverage);
            level0Frames = null;
            level1Frames = null;
            level2Frames = null;
            return false;
        }

    }

    /**
     * Read in the coverage file, which is basically three
     * byte[180][360] written out to file. These are converted to
     * booleans.
     *
     * @param urlCov an url to a coverage file, if available. Should
     *        be null if not used.
     * @param coverage the path to the file.
     * @return whether the file was read! True means yes.
     */
    protected boolean readCoverageFile(String urlCov, String coverage) {
        URL url = null;
        BufferedInputStream bin = null;
        BinaryBufferedFile binFile = null;

        level0Frames = null;
        level1Frames = null;
        level2Frames = null;

        if (urlCov != null) {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: Reading coverage file from URL - "
                            + urlCov);
            try {
                url = new URL(urlCov);
                bin = new BufferedInputStream(url.openStream());
            } catch (MalformedURLException mue) {
                System.err.println("DTEDCoverageManager: Weird URL given : \""
                        + urlCov + "\"");
                bin = null;
            } catch (java.io.IOException e) {
                System.err.println("DTEDCoverageManager: Unable to read coverage file at \""
                        + urlCov + "\"");
                bin = null;
            }
        }

        if (bin == null && coverage != null) {
            try {
                Debug.message("dtedcov",
                        "DTEDCoverageManager: Reading coverage file - "
                                + coverage);
                binFile = new BinaryBufferedFile(coverage);
            } catch (java.io.IOException e) {
                System.err.println("DTEDCoverageManager: Unable to read coverage file at \""
                        + coverage + "\"");
            }
        }

        if (bin != null || binFile != null) {
            try {
                level0Frames = new boolean[180][];
                level1Frames = new boolean[180][];
                level2Frames = new boolean[180][];

                byte[] row = new byte[360];

                for (int level = 0; level < 3; level++) {
                    for (int lat = 0; lat < 180; lat++) {

                        if (bin != null) {
                            for (int k = 0; k < row.length; k++) {
                                row[k] = (byte) bin.read();
                            }
                        } else
                            binFile.read(row);

                        if (level == 0)
                            level0Frames[lat] = convertBytesToBooleans(row);
                        else if (level == 1)
                            level1Frames[lat] = convertBytesToBooleans(row);
                        else
                            level2Frames[lat] = convertBytesToBooleans(row);
                    }
                }
                return true;

            } catch (IOException ioe) {
                System.err.println("DTECoverageLayer: Error reading coverage.");

                level0Frames = null;
                level1Frames = null;
                level2Frames = null;
            }
        }

        if (level0Frames == null) {
            System.err.println("DTEDCoverageManager: Error reading coverage file - will try to create a valid one at "
                    + coverage);
        }
        return false;
    }

    /**
     * Convert the bytes read in to the file to the booleans used in
     * the coverage arrays.
     *
     * @param row array of bytes
     * @return array of booleans
     */
    protected boolean[] convertBytesToBooleans(byte[] row) {
        boolean[] ret = new boolean[row.length];
        for (int i = 0; i < row.length; i++)
            ret[i] = (row[i] == 0) ? false : true;
        return ret;
    }

    /**
     * Convert the booleans to write out to bytes.
     *
     * @param row the input array of booleans
     * @return an array of bytes.
     */
    protected byte[] convertBooleansToBytes(boolean[] row) {
        byte[] ret = new byte[row.length];
        for (int i = 0; i < row.length; i++)
            ret[i] = (row[i]) ? (byte) 1 : (byte) 0;
        return ret;
    }

    /**
     * Write the coverage summary to a file.
     *
     * @param covFilename the file name to write the arrays into.
     */
    public void writeCoverageFile(String covFilename) {
        try {
            Debug.message("dtedcov",
                    "DTEDCoverageManager: Writing coverage summary file...");

            FileOutputStream binFile = new FileOutputStream(covFilename);

            byte[] row;

            for (int level = 0; level < 3; level++) {
                if (Debug.debugging("dtedcov")) {
                    Debug.output("-- level " + level);
                }
                for (int lat = 0; lat < 180; lat++) {

                    if (level == 0) {
                        row = convertBooleansToBytes(level0Frames[lat]);
                    } else if (level == 1) {
                        row = convertBooleansToBytes(level1Frames[lat]);
                    } else {
                        row = convertBooleansToBytes(level2Frames[lat]);
                    }

                    binFile.write(row);
                    if (Debug.debugging("dtedcov")) {
                        Debug.output("--- latitude " + lat);
                    }
                }
            }

            binFile.close();

        } catch (IOException ioe) {
            System.err.println("DTEDCoverageManager: Error writing coverage file!");
        }
    }

    /**
     * Add a ProgressListener that will display build progress.
     */
    public void addProgressListener(ProgressListener list) {
        progressSupport.addProgressListener(list);
    }

    /**
     * Remove a ProgressListener that displayed build progress.
     */
    public void removeProgressListener(ProgressListener list) {
        progressSupport.removeProgressListener(list);
    }

    /**
     * Clear all progress listeners.
     */
    public void clearProgressListeners() {
        progressSupport.removeAll();
    }

    /**
     * Fire an build update to progress listeners.
     *
     * @param frameNumber the current frame count
     * @param totalFrames the total number of frames.
     */
    protected void fireProgressUpdate(int type, String task, int frameNumber,
                                      int totalFrames) {
        progressSupport.fireUpdate(type, task, totalFrames, frameNumber);
    }

}
TOP

Related Classes of com.bbn.openmap.layer.dted.DTEDCoverageManager

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.