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