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