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