001    /*
002     * $Id: LambertAEA.java,v 1.9 2012/02/19 17:35:38 davep Exp $
003     *
004     * This file is part of McIDAS-V
005     *
006     * Copyright 2007-2012
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    
031    package edu.wisc.ssec.mcidasv.control;
032    
033    import visad.georef.MapProjection;
034    import visad.data.hdfeos.LambertAzimuthalEqualArea;
035    import visad.RealTupleType;
036    import visad.CoordinateSystem;
037    import visad.Data;
038    import visad.SI;
039    import visad.Unit;
040    import java.awt.geom.Rectangle2D;
041    import visad.VisADException;
042    import java.rmi.RemoteException;
043    
044    
045    public class LambertAEA extends MapProjection {
046    
047       CoordinateSystem cs;
048       Rectangle2D rect;
049       float earthRadius = 6367470; //- meters
050    
051       public LambertAEA(Rectangle2D ll_rect) throws VisADException {
052         this(ll_rect, true);
053       }
054    
055       public LambertAEA(Rectangle2D ll_rect, boolean forceSquareMapArea) throws VisADException {
056         super(RealTupleType.SpatialEarth2DTuple, new Unit[] {SI.meter, SI.meter});
057    
058         float minLon = (float) ll_rect.getX();
059         float minLat = (float) ll_rect.getY();
060         float del_lon = (float) ll_rect.getWidth();
061         float del_lat = (float) ll_rect.getHeight();
062         float maxLon = minLon + del_lon;
063         float maxLat = minLat + del_lat;
064    
065         float lonDiff = maxLon - minLon;
066         float lonCenter = minLon + (maxLon - minLon)/2;
067         if (lonDiff > 180f) {
068           lonCenter += 180f;
069         }
070         float latCenter = minLat + (maxLat - minLat)/2;
071    
072         cs = new LambertAzimuthalEqualArea(getReference(), earthRadius,
073                       lonCenter*Data.DEGREES_TO_RADIANS, latCenter*Data.DEGREES_TO_RADIANS,
074                             0,0);
075    
076         float[][] xy = cs.fromReference(new float[][] {{minLon,maxLon,minLon,maxLon}, 
077                                                        {minLat,minLat,maxLat,maxLat}});
078    
079    
080         float min_x = Float.MAX_VALUE;
081         float min_y = Float.MAX_VALUE;
082         float max_x = Float.MIN_VALUE;
083         float max_y = Float.MIN_VALUE;
084    
085         for (int k=0; k<xy[0].length;k++) {
086           if (xy[0][k] < min_x) min_x = xy[0][k];
087           if (xy[1][k] < min_y) min_y = xy[1][k];
088           if (xy[0][k] > max_x) max_x = xy[0][k];
089           if (xy[1][k] > max_y) max_y = xy[1][k];
090         }
091    
092         float del_x = max_x - min_x;
093         float del_y = max_y - min_y;
094     
095         if (forceSquareMapArea) {
096           if (del_x < del_y) {
097             del_x = del_y;
098           }
099           else if (del_y < del_x) {
100             del_y = del_x;
101           }
102         }
103    
104         min_x = -del_x/2;
105         min_y = -del_y/2;
106      
107         rect = new Rectangle2D.Float(min_x, min_y, del_x, del_y);
108       }
109    
110       public Rectangle2D getDefaultMapArea() {
111         return rect;
112       }
113         
114       public float[][] toReference(float[][] values) throws VisADException {
115         return cs.toReference(values);
116       }
117    
118       public float[][] fromReference(float[][] values) throws VisADException {
119         return cs.fromReference(values);
120       }
121    
122       public double[][] toReference(double[][] values) throws VisADException {
123         return cs.toReference(values);
124       }
125    
126       public double[][] fromReference(double[][] values) throws VisADException {
127         return cs.fromReference(values);
128       }
129    
130       public boolean equals(Object cs) {
131         return false;
132       }
133    
134    }