001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2016
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
029package edu.wisc.ssec.mcidasv.data.hydra;
030
031import visad.CoordinateSystem;
032import visad.GridCoordinateSystem;
033import visad.VisADException;
034import visad.RealTupleType;
035import visad.Linear2DSet;
036import visad.Gridded2DSet;
037import visad.Linear1DSet;
038import visad.Unit;
039import visad.Set;
040import visad.georef.MapProjection;
041import java.awt.geom.Rectangle2D;
042
043
044public 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}