001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2015
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 java.rmi.RemoteException;
032import java.util.HashMap;
033
034import visad.FlatField;
035import visad.FunctionType;
036import visad.Gridded3DSet;
037import visad.Gridded2DSet;
038import visad.RealTupleType;
039import visad.RealType;
040import visad.VisADException;
041import visad.Set;
042
043
044public 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}