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