ucar.nc2.iosp.mcidas.McIDASAreaProjection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* 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;
}
}