001    /*
002     * This file is part of McIDAS-V
003     *
004     * Copyright 2007-2013
005     * Space Science and Engineering Center (SSEC)
006     * University of Wisconsin - Madison
007     * 1225 W. Dayton Street, Madison, WI 53706, USA
008     * https://www.ssec.wisc.edu/mcidas
009     * 
010     * All Rights Reserved
011     * 
012     * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013     * some McIDAS-V source code is based on IDV and VisAD source code.  
014     * 
015     * McIDAS-V is free software; you can redistribute it and/or modify
016     * it under the terms of the GNU Lesser Public License as published by
017     * the Free Software Foundation; either version 3 of the License, or
018     * (at your option) any later version.
019     * 
020     * McIDAS-V is distributed in the hope that it will be useful,
021     * but WITHOUT ANY WARRANTY; without even the implied warranty of
022     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023     * GNU Lesser Public License for more details.
024     * 
025     * You should have received a copy of the GNU Lesser Public License
026     * along with this program.  If not, see http://www.gnu.org/licenses.
027     */
028    
029    package edu.wisc.ssec.mcidasv.data.hydra;
030    
031    import visad.CoordinateSystem;
032    import visad.GridCoordinateSystem;
033    import visad.VisADException;
034    import visad.RealTupleType;
035    import visad.Linear2DSet;
036    import visad.Gridded2DSet;
037    import visad.Linear1DSet;
038    import visad.Unit;
039    import visad.Set;
040    import visad.georef.MapProjection;
041    import java.awt.geom.Rectangle2D;
042    
043    
044    public class LongitudeLatitudeCoordinateSystem extends CoordinateSystem {
045    //public class LongitudeLatitudeCoordinateSystem extends MapProjection {
046    
047       Linear2DSet domainSet;
048       Linear2DSet subSet;
049       Gridded2DSet gset;
050    
051       //- assumes incoming GriddedSet is (longitude,latitude) with range (-180,+180)
052       boolean neg180pos180 = true;  //false: longitude range (0,+360)
053    
054       public LongitudeLatitudeCoordinateSystem(Linear2DSet domainSet, Gridded2DSet gset) throws VisADException {
055         this(domainSet, gset, false);
056       }
057    
058       public LongitudeLatitudeCoordinateSystem(Linear2DSet domainSet, Gridded2DSet gset, boolean lonFlag) throws VisADException {
059         super(RealTupleType.SpatialEarth2DTuple, null);
060         this.gset = gset;
061         this.domainSet = domainSet;
062         this.neg180pos180 = lonFlag;
063         int[] lengths = domainSet.getLengths();
064         int[] gset_lengths = gset.getLengths();
065         subSet = new Linear2DSet(0.0, gset_lengths[0]-1, lengths[0],
066                                  0.0, gset_lengths[1]-1, lengths[1]);
067       }
068    
069       public float[][] toReference(float[][] values) throws VisADException {
070         float[][] coords = domainSet.valueToGrid(values);
071         coords = subSet.gridToValue(coords);
072         coords = gset.gridToValue(coords);
073         return coords;
074       }
075    
076       public float[][] fromReference(float[][] values) throws VisADException {
077         if (!neg180pos180) { // force to longitude range (0,360)
078           for (int t=0; t<values[0].length; t++) {
079             if (values[0][t] > 180f) {
080               values[0][t] -= 360f;
081             }
082           }
083         }
084         float[][] grid_vals = gset.valueToGrid(values);
085         float[][] coords = subSet.valueToGrid(grid_vals);
086         coords = domainSet.gridToValue(coords);
087         return coords;
088       }
089    
090       public double[][] toReference(double[][] values) throws VisADException {
091         float[][] coords = domainSet.valueToGrid(Set.doubleToFloat(values));
092         coords = subSet.gridToValue(coords);
093         coords = gset.gridToValue(coords);
094         return Set.floatToDouble(coords);
095       }
096    
097       public double[][] fromReference(double[][] values) throws VisADException {
098         if (!neg180pos180) { // force to longitude range (0,360)
099           for (int t=0; t<values[0].length; t++) {
100             if (values[0][t] > 180.0) {
101               values[0][t] -= 360.0;
102             }
103           }
104         }
105         float[][] grid_vals = gset.valueToGrid(Set.doubleToFloat(values));
106         float[][] coords = subSet.valueToGrid(grid_vals);
107         coords = domainSet.gridToValue(coords);
108         return Set.floatToDouble(coords);
109       }
110    
111       public Rectangle2D getDefaultMapArea() {
112         float[] lo = domainSet.getLow();
113         float[] hi = domainSet.getHi();
114         return new Rectangle2D.Float(lo[0], lo[1], hi[0] - lo[0], hi[1] - lo[1]);
115       }
116    
117       public boolean equals(Object cs) {
118         return (cs instanceof LongitudeLatitudeCoordinateSystem);
119       }
120    }