All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.iosp.mcidas.McIDASAreaProjection Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

There is a newer version: 4.3.22
Show newest version
/*
 * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
 *
 * Portions of this software were developed by the Unidata Program at the
 * University Corporation for Atmospheric Research.
 *
 * Access and use of this software shall impose the following obligations
 * and understandings on the user. The user is granted the right, without
 * any fee or cost, to use, copy, modify, alter, enhance and distribute
 * this software, and any derivative works thereof, and its supporting
 * documentation for any purpose whatsoever, provided that this entire
 * notice appears in all copies of the software, derivative works and
 * supporting documentation.  Further, UCAR requests that the user credit
 * UCAR/Unidata in any publications that result from the use of this
 * software or in any product that includes this software. The names UCAR
 * and/or Unidata, however, may not be used in any advertising or publicity
 * to endorse or promote any products or commercial entity unless specific
 * written permission is obtained from UCAR/Unidata. The user also
 * understands that UCAR/Unidata is not obligated to provide the user with
 * any support, consulting, training or assistance of any kind with regard
 * to the use, operation and performance of this software nor to provide
 * the user with any updates, revisions, new versions or "bug fixes."
 *
 * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
 */



package ucar.nc2.iosp.mcidas;


import edu.wisc.ssec.mcidas.AREAnav;
import edu.wisc.ssec.mcidas.AreaFile;
import edu.wisc.ssec.mcidas.McIDASException;

import ucar.unidata.geoloc.*;
import ucar.unidata.util.Parameter;

import java.awt.geom.Rectangle2D;


/**
 * McIDASAreaProjection is the ProjectionImpl for McIDAS Area navigation
 * modules.
 */
public class McIDASAreaProjection extends ucar.unidata.geoloc.ProjectionImpl {

    /** Attribute for the Area Directory */
    public static String ATTR_AREADIR = "AreaDirectory";

    /** Attribute for the Navigation Block */
    public static String ATTR_NAVBLOCK = "NavBlock";

    /** Attribute for the Navigation Block */
    public static String ATTR_AUXBLOCK = "AuxBlock";

    /** Attribute for the Navigation Block */
    public static String GRID_MAPPING_NAME = "mcidas_area";

    /** Area navigation */                                                  
    private AREAnav anav = null;

    /** number of lines */
    private int lines;

    /** number of elements */
    private int elements;

    /** directory block */
    private int[] dirBlock;

    /** navigation block */
    private int[] navBlock;

    /** aux block */
    private int[] auxBlock;

    /**
     * copy constructor - avoid clone !!
     *
     * @return construct a copy of this
     */
    public ProjectionImpl constructCopy() {
        return new McIDASAreaProjection(dirBlock, navBlock, auxBlock);
    }

    /**
     * Default bean constructor
     */
    public McIDASAreaProjection() {}

    /**
     * create a McIDAS AREA projection from the Area file's
     *  directory and navigation blocks.
     *
     *  This routine uses a flipped Y axis (first line of
     *  the image file is number 0)
     *
     *  @param af is the associated AreaFile
     *
     */
    public McIDASAreaProjection(AreaFile af) {
        this(af.getDir(), af.getNav(), af.getAux());
    }

    /**
     * Create a AREA coordinate system from the Area file's
     * directory and navigation blocks.
     *
     * This routine uses a flipped Y axis (first line of
     * the image file is number 0)
     *
     * @param dir is the AREA file directory block
     * @param nav is the AREA file navigation block
     */
    public McIDASAreaProjection(int[] dir, int[] nav) {
        this(dir, nav, null);
    }

    /**
     * Create a AREA coordinate system from the Area file's
     * directory and navigation blocks.
     *
     * This routine uses a flipped Y axis (first line of
     * the image file is number 0)
     *
     * @param dir is the AREA file directory block
     * @param nav is the AREA file navigation block
     * @param aux is the AREA file auxillary block
     */
    public McIDASAreaProjection(int[] dir, int[] nav, int[] aux) {

        try {
            anav = AREAnav.makeAreaNav(nav, aux);
        } catch (McIDASException excp) {
            throw new IllegalArgumentException(
                "McIDASAreaProjection: problem creating projection" + excp);
        }
        dirBlock = dir;
        navBlock = nav;
        auxBlock = aux;
        anav.setImageStart(dir[5], dir[6]);
        anav.setRes(dir[11], dir[12]);
        anav.setStart(0, 0);
        anav.setMag(1, 1);
        lines    = dir[8];
        elements = dir[9];
        anav.setFlipLineCoordinates(dir[8]);  // invert Y axis coordinates

        addParameter(ATTR_NAME, GRID_MAPPING_NAME);
        addParameter(new Parameter(ATTR_AREADIR, makeDoubleArray(dir)));
        addParameter(new Parameter(ATTR_NAVBLOCK, makeDoubleArray(nav)));
        if (aux != null) {
            addParameter(new Parameter(ATTR_AUXBLOCK, makeDoubleArray(aux)));
        }
    }


    /**
     * Get the directory block used to initialize this McIDASAreaProjection
     *
     * @return the area directory
     */
    public int[] getDirBlock() {
        return dirBlock;
    }

    /**
     * Get the navigation block used to initialize this McIDASAreaProjection
     *
     * @return the navigation block
     */
    public int[] getNavBlock() {
        return navBlock;
    }

    /**
     * Get the auxilliary block used to initialize this McIDASAreaProjection
     *
     * @return the auxilliary block (may be null)
     */
    public int[] getAuxBlock() {
        return auxBlock;
    }

    /*MACROBODY
      latLonToProj {} {
        double[][] xy = anav.toLinEle(new double[][] {{fromLat},{fromLon}});
        toX = xy[0][0];
        toY = xy[1][0];
      }

      projToLatLon {} {
        double[][] latlon = anav.toLatLon(new double[][] {{fromX},{fromY}});
        toLat = latlon[0][0];
        toLon = latlon[1][0];
      }

    MACROBODY*/
    /*BEGINGENERATED*/

    /*
    Note this section has been generated using the convert.tcl script.
    This script, run as:
    tcl convert.tcl McIDASAreaProjection.java
    takes the actual projection conversion code defined in the MACROBODY
    section above and generates the following 6 methods
    */


    /**
     * Convert a LatLonPoint to projection coordinates
     *
     * @param latLon convert from these lat, lon coordinates
     * @param result the object to write to
     *
     * @return the given result
     */
    public ProjectionPoint latLonToProj(LatLonPoint latLon,
                                        ProjectionPointImpl result) {
        double     toX, toY;
        double     fromLat = latLon.getLatitude();
        double     fromLon = latLon.getLongitude();


        double[][] xy      = anav.toLinEle(new double[][] {
            { fromLat }, { fromLon }
        });
        toX = xy[0][0];
        toY = xy[1][0];

        result.setLocation(toX, toY);
        return result;
    }

    /**
     * Convert projection coordinates to a LatLonPoint
     *   Note: a new object is not created on each call for the return value.
     *
     * @param world convert from these projection coordinates
     * @param result the object to write to
     *
     * @return LatLonPoint convert to these lat/lon coordinates
     */
    public LatLonPoint projToLatLon(ProjectionPoint world,
                                    LatLonPointImpl result) {
        double     toLat, toLon;
        double     fromX  = world.getX();
        double     fromY  = world.getY();


        double[][] latlon = anav.toLatLon(new double[][] {
            { fromX }, { fromY }
        });
        toLat = latlon[0][0];
        toLon = latlon[1][0];

        result.setLatitude(toLat);
        result.setLongitude(toLon);
        return result;
    }

    /**
     * Convert lat/lon coordinates to projection coordinates.
     *
     * @param from     array of lat/lon coordinates: from[2][n],
     *                 where from[0][i], from[1][i] is the (lat,lon)
     *                 coordinate of the ith point
     * @param to       resulting array of projection coordinates,
     *                 where to[0][i], to[1][i] is the (x,y) coordinate
     *                 of the ith point
     * @param latIndex index of latitude in "from"
     * @param lonIndex index of longitude in "from"
     *
     * @return the "to" array.
     */
    public float[][] latLonToProj(float[][] from, float[][] to, int latIndex,
                                  int lonIndex) {
        float[]   fromLatA = from[latIndex];
        float[]   fromLonA = from[lonIndex];

        float[][] xy       = anav.toLinEle(new float[][] {
            fromLatA, fromLonA
        });
        to[INDEX_X] = xy[0];
        to[INDEX_Y] = xy[1];
        return to;
    }

    /**
     * Convert lat/lon coordinates to projection coordinates.
     *
     * @param from     array of lat/lon coordinates: from[2][n], where
     *                 (from[0][i], from[1][i]) is the (lat,lon) coordinate
     *                 of the ith point
     * @param to       resulting array of projection coordinates: to[2][n]
     *                 where (to[0][i], to[1][i]) is the (x,y) coordinate
     *                 of the ith point
     * @return the "to" array
     */
    public float[][] projToLatLon(float[][] from, float[][] to) {
        float[]   fromXA = from[INDEX_X];
        float[]   fromYA = from[INDEX_Y];
        float[][] latlon = anav.toLatLon(new float[][] {
            fromXA, fromYA
        });
        to[INDEX_LAT] = latlon[0];
        to[INDEX_LON] = latlon[1];
        return to;
    }

    /**
     * Convert lat/lon coordinates to projection coordinates.
     *
     * @param from     array of lat/lon coordinates: from[2][n],
     *                 where from[0][i], from[1][i] is the (lat,lon)
     *                 coordinate of the ith point
     * @param to       resulting array of projection coordinates,
     *                 where to[0][i], to[1][i] is the (x,y) coordinate
     *                 of the ith point
     * @param latIndex index of latitude in "from"
     * @param lonIndex index of longitude in "from"
     *
     * @return the "to" array.
     */
    public double[][] latLonToProj(double[][] from, double[][] to,
                                   int latIndex, int lonIndex) {
        double[]   fromLatA = from[latIndex];
        double[]   fromLonA = from[lonIndex];

        double[][] xy       = anav.toLinEle(new double[][] {
            fromLatA, fromLonA
        });
        to[INDEX_X] = xy[0];
        to[INDEX_Y] = xy[1];
        return to;
    }

    /**
     * Convert lat/lon coordinates to projection coordinates.
     *
     * @param from     array of lat/lon coordinates: from[2][n], where
     *                 (from[0][i], from[1][i]) is the (lat,lon) coordinate
     *                 of the ith point
     * @param to       resulting array of projection coordinates: to[2][n]
     *                 where (to[0][i], to[1][i]) is the (x,y) coordinate
     *                 of the ith point
     * @return the "to" array
     */
    public double[][] projToLatLon(double[][] from, double[][] to) {
        double[]   fromXA = from[INDEX_X];
        double[]   fromYA = from[INDEX_Y];
        double[][] latlon = anav.toLatLon(new double[][] {
            fromXA, fromYA
        });
        to[INDEX_LAT] = latlon[0];
        to[INDEX_LON] = latlon[1];
        return to;
    }

    /*ENDGENERATED*/

    /**
     * Get the bounds for this image
     *
     * @return the projection bounds
     */
    public ProjectionRect getDefaultMapArea() {
        return new ProjectionRect(new Rectangle2D.Float(0, 0, elements,
                lines));
    }

    /**
     *  This returns true when the line between pt1 and pt2 crosses the seam.
     *  When the cone is flattened, the "seam" is lon0 +- 180.
     *
     * @param pt1   point 1
     * @param pt2   point 2
     * @return true when the line between pt1 and pt2 crosses the seam.
     */
    public boolean crossSeam(ProjectionPoint pt1, ProjectionPoint pt2) {
        // either point is infinite
        if (ProjectionPointImpl.isInfinite(pt1)
                || ProjectionPointImpl.isInfinite(pt2)) {
            return true;
        }
        if (Double.isNaN(pt1.getX()) || Double.isNaN(pt1.getY())
                || Double.isNaN(pt2.getX()) || Double.isNaN(pt2.getY())) {
            return true;
        }
        // opposite signed X values, larger then 5000 km
        return (pt1.getX() * pt2.getX() < 0)
               && (Math.abs(pt1.getX() - pt2.getX()) > 5000.0);
    }

    /**
     * Determines whether or not the Object in question is
     * the same as this McIDASAreaProjection.  The specified
     * Object is equal to this McIDASAreaProjection
     * if it is an instance of McIDASAreaProjection and it has
     * the same navigation module and default map area as this one.
     *
     * @param obj the Object in question
     *
     * @return true if they are equal
     */
    public boolean equals(Object obj) {
        if ( !(obj instanceof McIDASAreaProjection)) {
            return false;
        }
        McIDASAreaProjection that = (McIDASAreaProjection) obj;
        return (this == that)
               || (anav.equals(that.anav) && (this.lines == that.lines)
                   && (this.elements == that.elements));
    }

    /**
     * Return a String which tells some info about this navigation
     * @return wordy String
     */
    public String toString() {
        return "Image (" + anav.toString() + ") Projection";
    }

    /**
     * Get the parameters as a String
     * @return the parameters as a String
     */
    public String paramsToString() {
        return " nav " + anav.toString();
    }


    /**
     * Test routine
     *
     * @param args  Area file name
     *
     * @throws Exception  problem reading data
     */
    public static void main(String[] args) throws Exception {
        String               file = (args.length > 0)
                                    ? args[0]
                                    : "c:/data/satellite/AREA8760";
        AreaFile             af   = new AreaFile(file);
        McIDASAreaProjection proj = new McIDASAreaProjection(af);
        LatLonPoint          llp  = new LatLonPointImpl(45, -105);
        System.out.println("lat/lon = " + llp);
        ProjectionPoint pp = proj.latLonToProj(llp);
        System.out.println("proj point = " + pp);
        llp = proj.projToLatLon(pp);
        System.out.println("reverse llp = " + llp);
        double[][] latlons = new double[][] {
            { 45 }, { -105 }
        };
        double[][] linele  = proj.latLonToProj(latlons);
        System.out.println("proj point = " + linele[0][0] + ","
                           + linele[1][0]);
        double[][] outll = proj.projToLatLon(linele);
        System.out.println("proj point = " + outll[0][0] + "," + outll[1][0]);
    }

    /**
     * make a double array out of an int array
     *
     * @param ints  array of ints
     *
     * @return  array of doubles
     */
    private double[] makeDoubleArray(int[] ints) {
        double[] newArray = new double[ints.length];
        for (int i = 0; i < ints.length; i++) {
            newArray[i] = ints[i];
        }
        return newArray;
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy