001/*
002 * $Id: LambertAEA.java,v 1.6 2011/03/24 16:06:32 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 * 
012 * All Rights Reserved
013 * 
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.  
016 * 
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 * 
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025 * GNU Lesser Public License for more details.
026 * 
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program.  If not, see http://www.gnu.org/licenses.
029 */
030
031package edu.wisc.ssec.mcidasv.control;
032
033import visad.georef.MapProjection;
034import visad.data.hdfeos.LambertAzimuthalEqualArea;
035import visad.RealTupleType;
036import visad.CoordinateSystem;
037import visad.Data;
038import visad.SI;
039import visad.Unit;
040import java.awt.geom.Rectangle2D;
041import visad.VisADException;
042import java.rmi.RemoteException;
043
044
045public class LambertAEA extends MapProjection {
046
047   CoordinateSystem cs;
048   Rectangle2D rect;
049
050   public LambertAEA(Rectangle2D ll_rect) throws VisADException {
051     super(RealTupleType.SpatialEarth2DTuple, new Unit[] {SI.meter, SI.meter});
052
053     float minLon = (float) ll_rect.getX();
054     float minLat = (float) ll_rect.getY();
055     float del_lon = (float) ll_rect.getWidth();
056     float del_lat = (float) ll_rect.getHeight();
057     float maxLon = minLon + del_lon;
058     float maxLat = minLat + del_lat;
059
060
061     float earthRadius = 6367470; //- meters
062
063     float lonDiff = maxLon - minLon;
064     float lonCenter = minLon + (maxLon - minLon)/2;
065     if (lonDiff > 180f) {
066       lonCenter += 180f;
067     }
068     float latCenter = minLat + (maxLat - minLat)/2;
069
070     cs = new LambertAzimuthalEqualArea(getReference(), earthRadius,
071                   lonCenter*Data.DEGREES_TO_RADIANS, latCenter*Data.DEGREES_TO_RADIANS,
072                         0,0);
073
074     float[][] xy = cs.fromReference(new float[][] {{minLon,maxLon,minLon,maxLon}, 
075                                                    {minLat,minLat,maxLat,maxLat}});
076
077     float min_x = Float.MAX_VALUE;
078     float min_y = Float.MAX_VALUE;
079     float max_x = Float.MIN_VALUE;
080     float max_y = Float.MIN_VALUE;
081
082     for (int k=0; k<xy[0].length;k++) {
083       if (xy[0][k] < min_x) min_x = xy[0][k];
084       if (xy[1][k] < min_y) min_y = xy[1][k];
085       if (xy[0][k] > max_x) max_x = xy[0][k];
086       if (xy[1][k] > max_y) max_y = xy[1][k];
087     }
088
089     float del_x = max_x - min_x;
090     float del_y = max_y - min_y;
091 
092     if (del_x < del_y) del_x = del_y;
093     if (del_y < del_x) del_y = del_x;
094  
095     rect = new Rectangle2D.Float(min_x, min_y, del_x, del_y);
096   }
097
098   public Rectangle2D getDefaultMapArea() {
099     return rect;
100   }
101     
102   public float[][] toReference(float[][] values) throws VisADException {
103     return cs.toReference(values);
104   }
105
106   public float[][] fromReference(float[][] values) throws VisADException {
107     return cs.fromReference(values);
108   }
109
110   public double[][] toReference(double[][] values) throws VisADException {
111     return cs.toReference(values);
112   }
113
114   public double[][] fromReference(double[][] values) throws VisADException {
115     return cs.fromReference(values);
116   }
117
118   public boolean equals(Object cs) {
119     return false;
120   }
121
122}