//
// 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();
  }
}

 

Ads help maintain this website.