001/*
002 * $Id: PreviewSelection.java,v 1.21 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.data;
032
033import edu.wisc.ssec.mcidasv.data.hydra.HydraRGBDisplayable;
034import edu.wisc.ssec.mcidasv.data.hydra.SubsetRubberBandBox;
035import edu.wisc.ssec.mcidasv.data.hydra.MultiSpectralData;
036import edu.wisc.ssec.mcidasv.data.hydra.MultiDimensionSubset;
037import edu.wisc.ssec.mcidasv.data.hydra.HydraContext;
038import edu.wisc.ssec.mcidasv.control.LambertAEA;
039
040import java.rmi.RemoteException;
041
042import java.util.ArrayList;
043import java.util.Enumeration;
044import java.util.HashMap;
045import java.util.Hashtable;
046import java.util.List;
047
048import ucar.unidata.data.DataSource;
049import ucar.unidata.data.DataSourceImpl;
050import ucar.unidata.data.DataCategory;
051import ucar.unidata.data.DataChoice;
052import ucar.unidata.data.DirectDataChoice;
053import ucar.unidata.data.DataSelection;
054import ucar.unidata.data.DataSourceDescriptor;
055import ucar.unidata.data.DataSelectionComponent;
056import ucar.unidata.data.DirectDataChoice;
057import ucar.unidata.data.GeoLocationInfo;
058import ucar.unidata.data.GeoSelection;
059import ucar.unidata.data.GeoSelectionPanel;
060import ucar.unidata.data.grid.GridUtil;
061
062import ucar.unidata.idv.DisplayConventions;
063
064import ucar.unidata.geoloc.*;
065import ucar.unidata.util.Range;
066import ucar.unidata.util.Misc;
067import ucar.unidata.util.ColorTable;
068
069import visad.Data;
070import visad.FlatField;
071import visad.GriddedSet;
072import visad.Gridded2DSet;
073import visad.SampledSet;
074import visad.VisADException;
075import visad.georef.MapProjection;
076import visad.data.mcidas.BaseMapAdapter;
077
078import java.io.File;
079import java.net.URL;
080
081import javax.swing.*;
082import javax.swing.event.*;
083import java.awt.geom.Rectangle2D;
084
085import visad.*;
086import visad.bom.RubberBandBoxRendererJ3D;
087import visad.java3d.DisplayImplJ3D;
088import visad.java3d.TwoDDisplayRendererJ3D;
089import ucar.unidata.view.geoloc.MapProjectionDisplayJ3D;
090import ucar.unidata.view.geoloc.MapProjectionDisplay;
091import java.awt.Component;
092import java.awt.BorderLayout;
093import java.awt.Color;
094import ucar.visad.display.XYDisplay;
095import ucar.visad.display.MapLines;
096import ucar.visad.display.DisplayMaster;
097import ucar.visad.display.LineDrawing;
098import ucar.visad.display.RubberBandBox;
099
100import ucar.visad.ProjectionCoordinateSystem;
101import ucar.unidata.geoloc.projection.LatLonProjection;
102
103
104public class PreviewSelection extends DataSelectionComponent {
105      DataChoice dataChoice;
106      FlatField image;
107      boolean isLL;
108      MapProjection sampleProjection;
109
110      double[] x_coords = new double[2];
111      double[] y_coords = new double[2];
112      boolean hasSubset = false;
113      MapProjectionDisplayJ3D mapProjDsp;
114      DisplayMaster dspMaster;
115
116      DataSourceImpl dataSource;
117
118      static SampledSet lines_outlsupu = null;
119      static SampledSet lines_outlsupw = null;
120      static SampledSet lines_outlhpol = null;
121                                    
122
123      public PreviewSelection() {
124        super("Region");
125      }
126
127      public PreviewSelection(DataChoice dataChoice, FlatField image,
128             MapProjection sample) throws VisADException, RemoteException {
129        this(dataChoice, image, sample, null, null);
130      }
131
132      public PreviewSelection(DataChoice dataChoice, FlatField image,
133             MapProjection sample, Range displayRange, byte[][] colorTable) throws VisADException, RemoteException {
134        super("Region");
135
136        this.dataChoice = dataChoice;
137        this.dataSource = (DataSourceImpl) ((DirectDataChoice)dataChoice).getDataSource();
138        this.image = image;
139        this.sampleProjection = sample;
140        sample = getDataProjection();
141
142        DisplayConventions dspConv = dataSource.getDataContext().getIdv().getDisplayConventions();
143
144        if (this.sampleProjection == null) {
145            this.sampleProjection = sample;
146        }
147
148        isLL = sampleProjection.isLatLonOrder();
149
150        mapProjDsp = new MapProjectionDisplayJ3D(MapProjectionDisplay.MODE_2Din3D);
151        mapProjDsp.enableRubberBanding(false);
152        dspMaster = mapProjDsp;
153        mapProjDsp.setMapProjection(sampleProjection);
154        RealType imageRangeType = 
155          (((FunctionType)image.getType()).getFlatRange().getRealComponents())[0];
156        HydraRGBDisplayable imageDsp = new HydraRGBDisplayable("image", imageRangeType, null, true, null);
157        imageDsp.setData(image);
158
159        dspMaster.addDisplayable(imageDsp);
160
161        MapLines mapLines  = new MapLines("maplines");
162        URL      mapSource =
163        mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPU");
164        try {
165            if (lines_outlsupu == null) {
166              BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource);
167              lines_outlsupu = (SampledSet) mapAdapter.getData();
168            }
169            mapLines.setMapLines(lines_outlsupu);
170            mapLines.setColor(java.awt.Color.cyan);
171            mapProjDsp.addDisplayable(mapLines);
172        } catch (Exception excp) {
173            System.out.println("Can't open map file " + mapSource);
174            System.out.println(excp);
175        }
176
177        mapLines  = new MapLines("maplines");
178        mapSource =
179        mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPW");
180        try {
181            if (lines_outlsupw == null) {
182              BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource);
183              lines_outlsupw = (SampledSet) mapAdapter.getData();
184            }
185            mapLines.setMapLines(lines_outlsupw);
186            mapLines.setColor(java.awt.Color.cyan);
187            mapProjDsp.addDisplayable(mapLines);
188        } catch (Exception excp) {
189            System.out.println("Can't open map file " + mapSource);
190            System.out.println(excp);
191        }
192
193        mapLines  = new MapLines("maplines");
194        mapSource =
195        mapProjDsp.getClass().getResource("/auxdata/maps/OUTLHPOL");
196        try {
197            if (lines_outlhpol == null) {
198              BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource);
199              lines_outlhpol = (SampledSet) mapAdapter.getData();
200            }
201            mapLines.setMapLines(lines_outlhpol);
202            mapLines.setColor(java.awt.Color.cyan);
203            mapProjDsp.addDisplayable(mapLines);
204        } catch (Exception excp) {
205            System.out.println("Can't open map file " + mapSource);
206            System.out.println(excp);
207        }
208
209
210
211        Hashtable table = dataChoice.getProperties();
212        Enumeration keys = table.keys();
213        while (keys.hasMoreElements()) {
214           Object key = keys.nextElement();
215           if (key instanceof MultiDimensionSubset) {
216             hasSubset = true;
217             MultiDimensionSubset select = (MultiDimensionSubset) table.get(key);
218             HydraContext hydraContext = HydraContext.getHydraContext(dataSource);
219             if (hydraContext.getMultiDimensionSubset() == null) {
220                hydraContext.setMultiDimensionSubset(select);
221             }
222           }
223        }
224
225        final SubsetRubberBandBox rbb =
226            new SubsetRubberBandBox(isLL, image, ((MapProjectionDisplay)mapProjDsp).getDisplayCoordinateSystem(), 1);
227        rbb.setColor(Color.green);
228        rbb.addAction(new CellImpl() {
229          boolean init = false;
230          public void doAction()
231             throws VisADException, RemoteException
232           {
233             if (!init) {
234               init = true;
235               return;
236             }
237             Gridded2DSet set = rbb.getBounds();
238             float[] low = set.getLow();
239             float[] hi = set.getHi();
240             x_coords[0] = low[0];
241             x_coords[1] = hi[0];
242
243             y_coords[0] = low[1];
244             y_coords[1] = hi[1];
245
246             if (hasSubset) {
247               HydraContext hydraContext = HydraContext.getHydraContext(dataSource);
248               MultiDimensionSubset select = hydraContext.getMultiDimensionSubset();
249               HashMap map = select.getSubset();
250
251               double[] coords0 = (double[]) map.get("Track");
252               coords0[0] = y_coords[0];
253               coords0[1] = y_coords[1];
254               coords0[2] = 1;
255               double[] coords1 = (double[]) map.get("XTrack");
256               coords1[0] = x_coords[0];
257               coords1[1] = x_coords[1];
258               coords1[2] = 1;
259               
260               hydraContext.setMultiDimensionSubset(new MultiDimensionSubset(map));
261             }
262           }
263        });
264        dspMaster.addDisplayable(rbb);
265
266        ScalarMap colorMap = imageDsp.getColorMap();
267        Range[] range = GridUtil.fieldMinMax(this.image);
268        Range imageRange = range[0];
269        double max;
270        double min;
271        double dMax = imageRange.getMax();
272        double dMin = imageRange.getMin();
273        String name = this.dataChoice.getName();
274
275        float[][] clrTbl = BaseColorControl.initTableGreyWedge(new float[4][256], true);
276
277        if (name.endsWith("BRIT")) {
278           dMin = imageRange.getMin();
279           min = dMax;
280           max = dMin;
281        } 
282        else if (imageRangeType.getName().contains("Reflectance")) {
283           min = dMax;
284           max = 0.0;
285        }
286        else if (imageRangeType.getName().equals("BrightnessTemp")) {
287           max = dMax*1.06;
288           min = dMax * 0.74;
289        }
290        else {
291           Range rng = dspConv.getParamRange(name, null);
292           max = dMax;
293           min = dMin;
294           ColorTable ct = dspConv.getParamColorTable(name);
295           clrTbl = ct.getTable();
296        }
297        colorMap.setRange(min, max);
298
299        /*-  must to draw first so colorMap has a Control */
300        dspMaster.draw();
301
302        BaseColorControl clrCntrl = (BaseColorControl) colorMap.getControl();
303        clrCntrl.setTable(clrTbl);
304      }
305
306       public MapProjection getDataProjection() {
307         MapProjection mp = null;
308
309         if (image == null) return mp;
310
311         Rectangle2D rect = MultiSpectralData.getLonLatBoundingBox(image);
312         try {
313           mp = new LambertAEA(rect);
314         } catch (Exception e) {
315             System.out.println(" getDataProjection"+e);
316         }
317         return mp;
318      }
319
320      public JComponent doMakeContents() {
321        try {
322          JPanel panel = new JPanel(new BorderLayout());
323          panel.add("Center", dspMaster.getDisplayComponent());
324          return panel;
325        }
326        catch (Exception e) {
327          System.out.println(e);
328        }
329        return null;
330      }
331                                                                                                                                             
332      public void applyToDataSelection(DataSelection dataSelection) {
333         if (hasSubset) {
334           HydraContext hydraContext = HydraContext.getHydraContext(dataSource);
335           Hashtable table = dataChoice.getProperties();
336           table.put(MultiDimensionSubset.key, hydraContext.getMultiDimensionSubset());
337
338           table = dataSelection.getProperties();
339           table.put(MultiDimensionSubset.key, hydraContext.getMultiDimensionSubset());
340
341           dataChoice.setDataSelection(dataSelection);
342         }
343      }
344  }