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