001    /*
002     * $Id: LongitudeLatitudeCoordinateSystem.java,v 1.11 2012/02/19 17:35:42 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.data.hydra;
032    
033    import visad.CoordinateSystem;
034    import visad.GridCoordinateSystem;
035    import visad.VisADException;
036    import visad.RealTupleType;
037    import visad.Linear2DSet;
038    import visad.Gridded2DSet;
039    import visad.Linear1DSet;
040    import visad.Unit;
041    import visad.Set;
042    import visad.georef.MapProjection;
043    import java.awt.geom.Rectangle2D;
044    
045    
046    public class LongitudeLatitudeCoordinateSystem extends CoordinateSystem {
047    //public class LongitudeLatitudeCoordinateSystem extends MapProjection {
048    
049       Linear2DSet domainSet;
050       Linear2DSet subSet;
051       Gridded2DSet gset;
052    
053       //- assumes incoming GriddedSet is (longitude,latitude) with range (-180,+180)
054       boolean neg180pos180 = true;  //false: longitude range (0,+360)
055    
056       public LongitudeLatitudeCoordinateSystem(Linear2DSet domainSet, Gridded2DSet gset) throws VisADException {
057         this(domainSet, gset, false);
058       }
059    
060       public LongitudeLatitudeCoordinateSystem(Linear2DSet domainSet, Gridded2DSet gset, boolean lonFlag) throws VisADException {
061         super(RealTupleType.SpatialEarth2DTuple, null);
062         this.gset = gset;
063         this.domainSet = domainSet;
064         this.neg180pos180 = lonFlag;
065         int[] lengths = domainSet.getLengths();
066         int[] gset_lengths = gset.getLengths();
067         subSet = new Linear2DSet(0.0, gset_lengths[0]-1, lengths[0],
068                                  0.0, gset_lengths[1]-1, lengths[1]);
069       }
070    
071       public float[][] toReference(float[][] values) throws VisADException {
072         float[][] coords = domainSet.valueToGrid(values);
073         coords = subSet.gridToValue(coords);
074         coords = gset.gridToValue(coords);
075         if (!neg180pos180) { // force to longitude range (0,360)
076           for (int t=0; t<coords[0].length; t++) {
077             if (coords[0][t] < 0f) {
078               coords[0][t] += 360f;
079             }
080           }
081         }
082         return coords;
083       }
084    
085       public float[][] fromReference(float[][] values) throws VisADException {
086         if (!neg180pos180) { // force to longitude range (0,360)
087           for (int t=0; t<values[0].length; t++) {
088             if (values[0][t] > 180f) {
089               values[0][t] -= 360f;
090             }
091           }
092         }
093         float[][] grid_vals = gset.valueToGrid(values);
094         float[][] coords = subSet.valueToGrid(grid_vals);
095         coords = domainSet.gridToValue(coords);
096         return coords;
097       }
098    
099       public double[][] toReference(double[][] values) throws VisADException {
100         float[][] coords = domainSet.valueToGrid(Set.doubleToFloat(values));
101         coords = subSet.gridToValue(coords);
102         coords = gset.gridToValue(coords);
103         if (!neg180pos180) { // force to longitude range (0,360)
104           for (int t=0; t<coords[0].length; t++) {
105             if (coords[0][t] < 0f) {
106               coords[0][t] += 360f;
107             }
108           }
109         }
110         return Set.floatToDouble(coords);
111       }
112    
113       public double[][] fromReference(double[][] values) throws VisADException {
114         if (!neg180pos180) { // force to longitude range (0,360)
115           for (int t=0; t<values[0].length; t++) {
116             if (values[0][t] > 180.0) {
117               values[0][t] -= 360.0;
118             }
119           }
120         }
121         float[][] grid_vals = gset.valueToGrid(Set.doubleToFloat(values));
122         float[][] coords = subSet.valueToGrid(grid_vals);
123         coords = domainSet.gridToValue(coords);
124         return Set.floatToDouble(coords);
125       }
126    
127       public Rectangle2D getDefaultMapArea() {
128         float[] lo = domainSet.getLow();
129         float[] hi = domainSet.getHi();
130         return new Rectangle2D.Float(lo[0], lo[1], hi[0] - lo[0], hi[1] - lo[1]);
131       }
132    
133       public boolean equals(Object cs) {
134         return (cs instanceof LongitudeLatitudeCoordinateSystem);
135       }
136    }