// // MapProjection.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.georef; import visad.*; /** * Abstract class for coordinate systems that support (lat,lon) <-> (x,y) * with a reference coordinate system of (lat, lon) or (lon, lat). * * @author Don Murray */ public abstract class MapProjection extends NavigatedCoordinateSystem { /** * Constructs from the type of the reference coordinate system and * units for values in this coordinate system. The reference coordinate * system must contain RealType.Latitude and RealType.Longitude only. * * @param reference The type of the reference coordinate system. The * reference must contain RealType.Latitude and * RealType.Longitude. Values in the reference * coordinate system shall be in units of * reference.getDefaultUnits() unless specified * otherwise. * @param units The default units for this coordinate system. * Numeric values in this coordinate system shall be * in units of units unless specified otherwise. * May be null or an array of null-s. * @exception VisADException Couldn't create necessary VisAD object or * reference does not contain RealType.Latitude * and/or RealType.Longitude or the reference * dimension is greater than 2. */ public MapProjection(RealTupleType reference, Unit[] units) throws VisADException { super(reference, units); if ( !(reference.equals(RealTupleType.LatitudeLongitudeTuple) || reference.equals(RealTupleType.SpatialEarth2DTuple))) throw new CoordinateSystemException( "MapProjection: Reference must be LatitudeLongitudeTuple or " + "SpatialEarth2DTuple"); } /** * Get a reasonable bounding box in this coordinate system. MapProjections * are typically specific to an area of the world; there's no bounding * box that works for all projections so each subclass must implement * this method. For example, the bounding box for a satellite image * MapProjection might have an upper left corner of (0,0) and the width * and height of the Rectangle2D would be the number of elements and * lines, respectively. * * @return the bounding box of the MapProjection * */ public abstract java.awt.geom.Rectangle2D getDefaultMapArea(); /** * Determine if the input to the toReference and output from the * fromReference is (x,y) or (y,x). Subclasses should override * if (y,x). * @return true if (x,y) */ public boolean isXYOrder() { return true;} /** * Determine if the fromReference and toReference expect the * to get the output and input values to be row/col ordered * or */ public boolean isLatLonOrder() { return (getLatitudeIndex() == 0); } /** * Get the center lat/lon point for this MapProjection. * @return the lat/lon point at the center of the projection. */ public LatLonPoint getCenterLatLon() throws VisADException { java.awt.geom.Rectangle2D rect = getDefaultMapArea(); return getLatLon(new double[][] { {rect.getCenterX()}, {rect.getCenterY()}}); } /** * Get the X index * @return the index */ public int getXIndex() { return isXYOrder() ? 0 : 1; } /** * Get the Y index * @return the index */ public int getYIndex() { return isXYOrder() ? 1 : 0; } /** * Get the lat/lon point for the given xy pairs. * this method will flip the order of the xy if it is not in xyorder * @return the lat/lon point for the given xy pairs */ public LatLonPoint getLatLon(double[][]xy) throws VisADException { //Flip them if needed if(!isXYOrder()) { double tmp; tmp = xy[0][0]; xy[0][0] = xy[0][1]; xy[0][1] = tmp; tmp = xy[1][0]; xy[1][0] = xy[1][1]; xy[1][1] = tmp; } double[][] latlon = toReference(xy); double lat = (isLatLonOrder()) ? CommonUnit.degree.toThis(latlon[0][0], getReferenceUnits()[0]) : CommonUnit.degree.toThis(latlon[1][0], getReferenceUnits()[1]); double lon = (isLatLonOrder()) ? CommonUnit.degree.toThis(latlon[1][0], getReferenceUnits()[1]) : CommonUnit.degree.toThis(latlon[0][0], getReferenceUnits()[0]); LatLonPoint llp = null; try { llp = new LatLonTuple(lat, lon); } catch (java.rmi.RemoteException re) {} // can't happen return llp; } /** * Print out a string representation of this MapProjection */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append("MapProjection: \n"); buf.append(" Reference = "); buf.append(getReference()); buf.append("\n"); buf.append(" DefaultMapArea = "); buf.append(getDefaultMapArea()); return buf.toString(); } }