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    
032    import java.awt.Image;
033    import java.awt.Toolkit;
034    import java.awt.geom.Rectangle2D;
035    import java.awt.image.BufferedImage;
036    import java.io.BufferedReader;
037    import java.io.InputStream;
038    import java.io.InputStreamReader;
039    import java.rmi.RemoteException;
040    import java.util.ArrayList;
041    import java.util.HashMap;
042    import java.util.Hashtable;
043    import java.util.List;
044    
045    import edu.wisc.ssec.mcidasv.control.LambertAEA;
046    
047    import ucar.unidata.data.BadDataException;
048    import ucar.unidata.data.CompositeDataChoice;
049    import ucar.unidata.data.DataCategory;
050    import ucar.unidata.data.DataChoice;
051    import ucar.unidata.data.DataSelection;
052    import ucar.unidata.data.DataSourceDescriptor;
053    import ucar.unidata.data.DirectDataChoice;
054    import ucar.unidata.data.grid.GridUtil;
055    import ucar.unidata.data.imagery.ImageInfo;
056    import ucar.unidata.util.IOUtil;
057    import ucar.unidata.util.Misc;
058    import visad.Data;
059    import visad.FlatField;
060    import visad.FunctionType;
061    import visad.Gridded2DSet;
062    import visad.Gridded3DSet;
063    import visad.Linear2DSet;
064    import visad.RealTupleType;
065    import visad.RealType;
066    import visad.SampledSet;
067    import visad.Unit;
068    import visad.VisADException;
069    import visad.georef.MapProjection;
070    import visad.util.ImageHelper;
071    
072    
073    /**
074     * This is an implementation that will read in a generic data file
075     * and return a single Data choice that is a VisAD Data object.
076     */
077    public class FlatFileDataSource extends ucar.unidata.data.FilesDataSource {
078    
079        /**
080         *  Parameterless ctor
081         */
082        public FlatFileDataSource() {}
083    
084    
085        /**
086         * Just pass through to the base class the ctor arguments.
087         * @param descriptor    Describes this data source, has a label etc.
088         * @param filename      This is the filename (or url) that
089         *                      points to the actual data source.
090         * @param properties General properties used in the base class
091         *
092         * idv    * @throws VisADException   problem getting the data
093         */
094        public FlatFileDataSource(DataSourceDescriptor descriptor,
095                                  String filename, Hashtable properties)
096                throws VisADException {
097            super(descriptor, filename, "Image flat file data source", properties);
098            System.out.println("FlatFileDataSource.descriptor: " + descriptor.toString());
099            System.out.println("FlatFileDataSource.filename: " + filename);
100            System.out.println("FlatFileDataSource.properties: " + properties.toString());
101        }
102    
103        /**
104         * This method is called at initialization time and  should create
105         * a set of {@link ucar.unidata.data.DirectDataChoice}-s  and add them
106         * into the base class managed list of DataChoice-s with the method
107         * addDataChoice.
108         */
109        protected void doMakeDataChoices() {
110            String xmlFile = getFilePath();
111            List bandsDefault = new ArrayList();
112            bandsDefault.add("Band 1");
113                String name = getProperty("FLAT.NAME", "Unknown name");
114                List bandNames = (List)getProperty("FLAT.BANDNAMES", bandsDefault);
115                List bandFiles = (List)getProperty("FLAT.BANDFILES", bandsDefault);
116                
117                int lines = getProperty("FLAT.LINES", (int)0);
118                int elements = getProperty("FLAT.ELEMENTS", (int)0);
119                String unit = getProperty("FLAT.UNIT", "");
120                int stride = getProperty("FLAT.STRIDE", (int)1);
121    
122                if (bandNames.size() == bandFiles.size()) {
123                        for (int i=0; i<bandNames.size(); i++) {
124                            System.out.println(bandNames.get(i) + ": " + bandFiles.get(i));
125                        }
126                }
127                else {
128                    System.err.println("bandNames: " + bandNames.toString());
129                    System.err.println("bandFiles: " + bandFiles.toString());
130                    System.err.println("Huh... bandNames (" + bandNames.size() + ") and bandFiles (" + bandFiles.size() + ") should be the same size");
131                }
132                
133            Hashtable imageProps = Misc.newHashtable(DataChoice.PROP_ICON, "/auxdata/ui/icons/Earth16.gif");
134    
135                // Navigation
136                String navType = getProperty("NAV.TYPE", "UNKNOWN");
137                double ulLat = 0;
138                double ulLon = 0;
139                double lrLat = 0;
140                double lrLon = 0;
141                String latFile = null;
142                String lonFile = null;
143                if (navType == "FILES") {
144                    latFile = getProperty("FILE.LAT", "");
145                    lonFile = getProperty("FILE.LON", "");
146                }
147                else if (navType == "BOUNDS") {
148                        ulLat = getProperty("BOUNDS.ULLAT", (double)0);
149                        ulLon = getProperty("BOUNDS.ULLON", (double)0);
150                        lrLat = getProperty("BOUNDS.LRLAT", (double)0);
151                        lrLon = getProperty("BOUNDS.LRLON", (double)0);
152                }
153                else {
154                    System.err.println("FlatFileDataSource: Unknown navType: " + navType);
155                }
156                int scale = getProperty("NAV.SCALE", (int)1);
157                boolean eastPositive = getProperty("NAV.EASTPOS", false);
158                
159                // Format
160                String formatType = getProperty("FORMAT.TYPE", "UNKNOWN");
161                if (formatType == "BINARY") {
162                    int format = getProperty("BINARY.FORMAT", HeaderInfo.kFormat1ByteUInt);
163                    String interleave = getProperty("BINARY.INTERLEAVE", HeaderInfo.kInterleaveSequential);
164                    boolean bigEndian = getProperty("BINARY.BIGENDIAN", false);
165                    int offset = getProperty("BINARY.OFFSET", 0);
166                    
167                        List categories = DataCategory.parseCategories("IMAGE", false);
168                CompositeDataChoice cdc = new CompositeDataChoice(this, "", name, name, null);
169                for (int i=0; i<bandFiles.size(); i++) {
170                    FlatFileReader dataChoiceData = new FlatFileReader((String)bandFiles.get(i), lines, elements);
171                            dataChoiceData.setBinaryInfo(format, interleave, bigEndian, offset, i+1, bandFiles.size());
172                            dataChoiceData.setUnit(unit);
173                            dataChoiceData.setEastPositive(eastPositive);
174                            dataChoiceData.setStride(stride);
175                    if (latFile != null && lonFile != null) {
176                            dataChoiceData.setNavFiles(latFile, lonFile, scale);
177                    }
178                    else {
179                            dataChoiceData.setNavBounds(ulLat, ulLon, lrLat, lrLon);
180                    }
181                    String bandName = (String)bandNames.get(i);
182                        DirectDataChoice ddc = new DirectDataChoice(this, dataChoiceData, bandName, bandName, categories, imageProps);
183                        cdc.addDataChoice(ddc);
184                }
185                            addDataChoice(cdc);
186                System.err.println("Still working on binary data...");
187                }
188                else if (formatType == "ASCII") {
189                    String delimiter = getProperty("ASCII.DELIMITER", "");
190                    
191                        List categories = DataCategory.parseCategories("IMAGE", false);
192                CompositeDataChoice cdc = new CompositeDataChoice(this, "", name, name, null);
193                for (int i=0; i<bandFiles.size(); i++) {
194                    FlatFileReader dataChoiceData = new FlatFileReader((String)bandFiles.get(i), lines, elements);
195                            dataChoiceData.setAsciiInfo(delimiter, 1);
196                            dataChoiceData.setUnit(unit);
197                            dataChoiceData.setEastPositive(eastPositive);
198                            dataChoiceData.setStride(stride);
199                    if (latFile != null && lonFile != null) {
200                            dataChoiceData.setNavFiles(latFile, lonFile, scale);
201                    }
202                    else {
203                            dataChoiceData.setNavBounds(ulLat, ulLon, lrLat, lrLon);
204                    }
205                    String bandName = (String)bandNames.get(i);
206                        DirectDataChoice ddc = new DirectDataChoice(this, dataChoiceData, bandName, bandName, categories, imageProps);
207                        cdc.addDataChoice(ddc);
208                }
209                            addDataChoice(cdc);
210                System.err.println("Still working on ascii data...");
211                }
212                else if (formatType == "IMAGE") {
213                        List categories = DataCategory.parseCategories("RGBIMAGE", false);
214                        FlatFileReader dataChoiceData = new FlatFileReader((String)bandFiles.get(0), lines, elements);
215                    dataChoiceData.setImageInfo();
216                    dataChoiceData.setUnit(unit);
217                    dataChoiceData.setEastPositive(eastPositive);
218                    dataChoiceData.setStride(stride);
219                    if (latFile != null && lonFile != null) {
220                            dataChoiceData.setNavFiles(latFile, lonFile, scale);
221                    }
222                    else {
223                            dataChoiceData.setNavBounds(ulLat, ulLon, lrLat, lrLon);
224                    }
225                    String bandName = (String)bandNames.get(0);
226                    DirectDataChoice ddc = new DirectDataChoice(this, dataChoiceData, bandName, bandName, categories, imageProps);
227                    addDataChoice(ddc);
228                }
229                else {
230                    System.err.println("FlatFileDataSource: Unknown formatType: " + formatType);
231                }
232        }
233        
234        /**
235         * This method should create and return the visad.Data that is
236         * identified by the given {@link ucar.unidata.data.DataChoice}.
237         *
238         * @param dataChoice     This is one of the DataChoice-s that was created
239         *                       in the doMakeDataChoices call above.
240         * @param category       The specific {@link ucar.unidata.data.DataCategory}
241         *                       which the {@link ucar.unidata.idv.DisplayControl}
242         *                       was instantiated with. Usually can be ignored.
243         * @param dataSelection  This may contain a list of times which
244         *                       subsets the request.
245         * @param requestProperties  extra request properties
246         * @return The {@link visad.Data} object represented by the given dataChoice
247         *
248         * @throws RemoteException    Java RMI problem
249         * @throws VisADException     VisAD problem
250         */
251        protected Data getDataInner(DataChoice dataChoice, DataCategory category,
252                    DataSelection dataSelection,
253                    Hashtable requestProperties)
254        throws VisADException, RemoteException {
255            FlatFileReader stuff = (FlatFileReader) dataChoice.getId();
256            return stuff.getData();
257        }
258    
259    }
260