001/*
002 * $Id: ProfileAlongTrackControl.java,v 1.15 2011/03/24 16:06:32 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.control;
032
033import java.awt.Container;
034import java.rmi.RemoteException;
035import java.util.Enumeration;
036import java.util.HashMap;
037import java.util.Hashtable;
038
039import visad.Data;
040import visad.FlatField;
041import visad.FunctionType;
042import visad.Gridded3DSet;
043import visad.MathType;
044import visad.RealTuple;
045import visad.RealTupleType;
046import visad.RealType;
047import visad.SampledSet;
048import visad.Text;
049import visad.TextType;
050import visad.Tuple;
051import visad.TupleType;
052import visad.UnionSet;
053import visad.VisADException;
054
055import ucar.unidata.data.DataChoice;
056import ucar.unidata.data.DirectDataChoice;
057import ucar.unidata.data.GeoSelection;
058import ucar.unidata.data.GeoSelectionPanel;
059import ucar.unidata.idv.IntegratedDataViewer;
060import ucar.unidata.idv.ViewManager;
061import ucar.unidata.idv.control.DisplayControlImpl;
062import ucar.unidata.util.ColorTable;
063import ucar.unidata.util.Range;
064import ucar.visad.display.DisplayMaster;
065import ucar.visad.display.DisplayableData;
066import ucar.visad.display.LineDrawing;
067import ucar.visad.display.TextDisplayable;
068
069import edu.wisc.ssec.mcidasv.data.hydra.HydraRGBDisplayable;
070import edu.wisc.ssec.mcidasv.data.hydra.MultiDimensionDataSource;
071import edu.wisc.ssec.mcidasv.data.hydra.MultiDimensionSubset;
072
073
074
075public class ProfileAlongTrackControl extends DisplayControlImpl {
076
077  private DataChoice dataChoice;
078  
079  private DisplayableData imageDisplay;
080  private DisplayableData trackDisplay;
081  private DisplayableData meshDisplay;
082  private DisplayableData textDisplay;
083
084  private DisplayMaster mainViewMaster;
085
086  private RealType imageRangeType;
087
088  public MultiDimensionSubset subset;
089
090  private MultiDimensionDataSource dataSource;
091
092  private FlatField track;
093
094  private GeoSelection geoSelection;
095
096  private GeoSelectionPanel geoSelectionPanel;
097
098
099  public ProfileAlongTrackControl() {
100    super();
101    setAttributeFlags(FLAG_COLORTABLE | FLAG_SELECTRANGE);
102  }
103
104  public boolean init(DataChoice dataChoice) throws VisADException, RemoteException {
105    this.dataChoice = dataChoice;
106    dataSource = (MultiDimensionDataSource) ((DirectDataChoice)dataChoice).getDataSource();
107    ViewManager vm = getViewManager();
108    mainViewMaster = vm.getMaster();
109
110    Hashtable table = dataChoice.getProperties();
111    Enumeration keys = table.keys();
112    while (keys.hasMoreElements()) {
113      Object key = keys.nextElement();
114      if (key instanceof MultiDimensionSubset) {
115           subset = (MultiDimensionSubset) table.get(key);
116      }
117    }
118
119    subset.setGeoSelection(getDataSelection().getGeoSelection());
120    FlatField image = (FlatField) dataSource.getData(dataChoice, null, getDataSelection(), dataSource.getProperties());
121    if (image == null) {
122      return false;
123    }
124    imageRangeType = (RealType) ((FunctionType)image.getType()).getRange();
125    track = createTrackDisplay();
126    imageDisplay = create3DDisplay(image);
127    addDisplayable(imageDisplay, FLAG_COLORTABLE | FLAG_SELECTRANGE);
128    if (track != null) create3DMesh(track);
129    return true;
130  }
131
132  private FlatField createTrackDisplay() throws VisADException, RemoteException {
133    IntegratedDataViewer idv = getIdv();
134    FlatField track = null;
135
136    HashMap map = dataSource.getSubsetFromLonLatRect(subset, getDataSelection().getGeoSelection());
137    track = dataSource.track_adapter.getData(map);
138
139    LineDrawing trackDsp = new LineDrawing("track");
140    trackDsp.setLineWidth(2f);
141    trackDsp.setData(track);
142    mainViewMaster.addDisplayable(trackDsp);
143
144    trackDisplay = trackDsp;
145    return track;
146  }
147
148  private DisplayableData create3DDisplay(FlatField image) throws VisADException, RemoteException {
149    RealType imageRangeType = (RealType) ((FunctionType)image.getType()).getRange();
150    HydraRGBDisplayable imageDsp = new HydraRGBDisplayable("image", imageRangeType, (RealType) null, true, null);
151    imageDsp.setDefaultRenderer();
152    imageDsp.setData(image);
153    return imageDsp;
154  }
155
156  private void create3DMesh(FlatField track) throws VisADException, RemoteException {
157    float del_lat = 2f;
158    int n_sets = 3;
159    Gridded3DSet set = (Gridded3DSet) track.getDomainSet();
160
161    float[][] samples = set.getSamples();
162    SampledSet[] sets = new SampledSet[n_sets];
163    Tuple[] labels = new Tuple[n_sets];
164    float alt_start = 2000;
165    float alt_inc = 5000;
166    for (int k=0; k<n_sets; k++) {
167      for (int i=0; i<samples[2].length; i++) {
168        samples[2][i] = alt_start + k*alt_inc;
169      }
170      sets[k] = new Gridded3DSet(RealTupleType.SpatialEarth3DTuple, samples, samples[2].length);
171      Tuple tup = new Tuple(new TupleType(new MathType[] {RealTupleType.SpatialEarth3DTuple, TextType.Generic}),
172            new Data[] {new RealTuple(RealTupleType.SpatialEarth3DTuple, 
173                  new double[] {samples[0][0], samples[1][0] - del_lat, samples[2][0]}), 
174                          new Text(TextType.Generic, Float.toString(samples[2][0]))});
175      labels[k] = tup;
176    }
177
178    UnionSet u_set = new UnionSet(sets);
179    LineDrawing meshDsp = new LineDrawing("mesh");
180    meshDsp.setLineWidth(2f);
181    meshDsp.setData(u_set);
182    mainViewMaster.addDisplayable(meshDsp);
183
184    TextDisplayable txtDsp = new TextDisplayable(TextType.Generic);
185    txtDsp.setData(new Tuple(labels));
186    txtDsp.setLineWidth(2f);
187    mainViewMaster.addDisplayable(txtDsp);
188
189    meshDisplay = meshDsp;
190    textDisplay = txtDsp;
191    
192    return;
193  }
194
195  private DisplayableData create2DDisplay() throws VisADException, RemoteException {
196    return null;
197  }
198
199  protected ColorTable getInitialColorTable() {
200    return getDisplayConventions().getParamColorTable(imageRangeType.getName());
201  }
202
203  protected Range getInitialRange() throws RemoteException, VisADException {
204      Range range = getDisplayConventions().getParamRange(imageRangeType.getName(), null);
205      setSelectRange(range);
206      return range;
207  }
208
209  public void doRemove() throws RemoteException, VisADException{
210    mainViewMaster.removeDisplayable(meshDisplay);
211    mainViewMaster.removeDisplayable(trackDisplay);
212    mainViewMaster.removeDisplayable(textDisplay);
213    super.doRemove();
214  }
215
216  public void setDisplayVisibility(boolean on) {
217    super.setDisplayVisibility(on);
218    try {
219      meshDisplay.setVisible(on);
220      textDisplay.setVisible(on);
221      trackDisplay.setVisible(on);
222    }
223    catch( Exception e) {
224      e.printStackTrace();
225    }
226  }
227
228  public Container doMakeContentes() {
229    return null;
230  }
231
232}