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 java.rmi.RemoteException;
032    import java.util.HashMap;
033    
034    import visad.FlatField;
035    import visad.FunctionType;
036    import visad.Gridded3DSet;
037    import visad.Gridded2DSet;
038    import visad.RealTupleType;
039    import visad.RealType;
040    import visad.VisADException;
041    import visad.Set;
042    
043    
044    public class TrackDomain extends MultiDimensionAdapter {
045       RealTupleType domainType;
046       ArrayAdapter lonAdapter;
047       ArrayAdapter latAdapter;
048       ArrayAdapter altAdapter;
049    
050       float[] trackLongitude;
051       float[] trackLatitude;
052       float[] trackAltitude;
053    
054       int TrackLen;
055    
056       public TrackDomain() {
057       }
058    
059       public TrackDomain(ArrayAdapter lonAdapter, ArrayAdapter latAdapter) throws Exception {
060         this(lonAdapter, latAdapter, null);
061       }
062    
063       public TrackDomain(ArrayAdapter lonAdapter, ArrayAdapter latAdapter, ArrayAdapter altAdapter) throws Exception {
064         this.lonAdapter = lonAdapter;
065         this.latAdapter = latAdapter;
066         this.altAdapter = altAdapter;
067    
068         if (altAdapter != null) {
069           domainType = RealTupleType.SpatialEarth3DTuple;
070           trackAltitude = (altAdapter.getData(altAdapter.getDefaultSubset()).getFloats(false))[0];
071         }
072         else {
073           domainType = RealTupleType.SpatialEarth2DTuple;
074         }
075    
076         trackLongitude = (lonAdapter.getData(lonAdapter.getDefaultSubset()).getFloats(false))[0];
077         trackLatitude = (latAdapter.getData(latAdapter.getDefaultSubset()).getFloats(false))[0];
078         TrackLen = trackLongitude.length;
079       }
080    
081       public Set makeDomain(Object subset) throws VisADException, RemoteException {
082         
083         float[] lonValues = null;
084         float[] latValues = null;
085         float[] altValues = null;
086    
087         double[] coords = (double[]) ((HashMap)subset).get("TrackDim");
088         HashMap newSubset = this.getDefaultSubset();
089         double[] newCoords = (double[])newSubset.get("TrackDim");
090         System.arraycopy(coords, 0, newCoords, 0, coords.length);
091         subset = newSubset;
092    
093         try {
094           lonValues = (lonAdapter.getData(subset).getFloats())[0];
095           latValues = (latAdapter.getData(subset).getFloats())[0];
096    
097           if (altAdapter != null) {
098             altValues = (altAdapter.getData(subset).getFloats())[0];
099           }
100         }
101         catch (Exception e) {
102           e.printStackTrace();
103           return null;
104         }
105    
106         Set set = null;
107    
108         if (altAdapter != null) {
109           for (int k=0; k< altValues.length; k++) {
110             altValues[k] *= 1000.0;
111           }
112           set = new Gridded3DSet(domainType, new float[][] {lonValues, latValues, altValues}, lonValues.length);
113         }
114         else {
115           set = new Gridded2DSet(domainType, new float[][] {lonValues, latValues}, lonValues.length);
116         }
117         return set;
118       }
119    
120       public float[] getTrackLongitude() {
121         return trackLongitude;
122       }
123    
124       public float[] getTrackLatitude() {
125         return trackLatitude;
126       }
127    
128       public float[] getTrackAlitude() {
129         return trackAltitude;
130       }
131    
132       public int[] getTrackRangeInsideLonLatRect(double minLat, double maxLat, double minLon, double maxLon) {
133            int nn = 100;
134            int skip = TrackLen/nn;
135            double lon;
136            double lat;
137    
138            int idx = 0;
139            while (idx < TrackLen) {
140              lon = (double)trackLongitude[idx];
141              lat = (double)trackLatitude[idx];
142              if (((lon > minLon) && (lon < maxLon)) && ((lat > minLat)&&(lat < maxLat))) break;
143              idx += skip;
144            }
145            if (idx > TrackLen-1) idx = TrackLen-1;
146            if (idx == TrackLen-1) return new int[] {-1,-1};
147    
148            int low_idx = idx;
149            while (low_idx > 0) {
150              lon = (double)trackLongitude[low_idx];
151              lat = (double)trackLatitude[low_idx];
152              if (((lon > minLon) && (lon < maxLon)) && ((lat > minLat)&&(lat < maxLat))) {
153                low_idx -= 1;
154                continue;
155              }
156              else {
157                break;
158              }
159            }
160    
161            int hi_idx = idx;
162            while (hi_idx < TrackLen-1) {
163              lon = (double)trackLongitude[hi_idx];
164              lat = (double)trackLatitude[hi_idx];
165              if (((lon > minLon) && (lon < maxLon)) && ((lat > minLat)&&(lat < maxLat))) {
166                hi_idx += 1;
167                continue;
168              }
169              else {
170                break;
171              }
172            }
173            return new int[] {low_idx, hi_idx};
174       }
175    
176       public HashMap getSubsetFromLonLatRect(HashMap subset, double minLat, double maxLat, double minLon, double maxLon) {
177          double[] coords = (double[])subset.get("TrackDim");
178          int[] idxs = getTrackRangeInsideLonLatRect(minLat, maxLat, minLon, maxLon);
179          coords[0] = (double) idxs[0];
180          coords[1] = (double) idxs[1];
181          if ((coords[0] == -1) || (coords[1] == -1)) return null;
182          return subset;
183       }
184    
185       public HashMap getSubsetFromLonLatRect(HashMap subset, double minLat, double maxLat, double minLon, double maxLon,
186                                              int xStride, int yStride, int zStride) {
187          double[] coords = (double[])subset.get("TrackDim");
188          int[] idxs = getTrackRangeInsideLonLatRect(minLat, maxLat, minLon, maxLon);
189          coords[0] = (double) idxs[0];
190          coords[1] = (double) idxs[1];
191          if ((coords[0] == -1) || (coords[1] == -1)) return null;
192    
193          if (xStride > 0) {
194             coords[2] = xStride;
195          }
196    
197          return subset;
198       }
199    
200       public HashMap getDefaultSubset() {
201         return lonAdapter.getDefaultSubset();
202       }
203    }