Package org.geotools.imageio.netcdf

Source Code of org.geotools.imageio.netcdf.NetCDFImageReaderSpi

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2007-2014, Open Source Geospatial Foundation (OSGeo)
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*/
package org.geotools.imageio.netcdf;

import it.geosolutions.imageio.stream.AccessibleStream;
import it.geosolutions.imageio.stream.input.FileImageInputStreamExtImpl;
import it.geosolutions.imageio.stream.input.URIImageInputStream;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.EnumSet;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;

import org.geotools.imageio.netcdf.utilities.NetCDFUtilities;
import org.geotools.util.logging.Logging;

import ucar.nc2.NetcdfFile;
import ucar.nc2.dataset.NetcdfDataset;
import ucar.nc2.dataset.NetcdfDataset.Enhance;

/**
* Service provider interface for the NetCDF Image
*
* @author Alessio Fabiani, GeoSolutions
*/
public class NetCDFImageReaderSpi extends ImageReaderSpi {

    public static final Class< ? >[] STANDARD_INPUT_TYPES = new Class[]{AccessibleStream.class, ImageInputStream.class,
        File.class, URL.class, URI.class};  

    public static final String VENDOR_NAME = "GeoTools";

    static {
         NetcdfDataset.setDefaultEnhanceMode(EnumSet.of(Enhance.CoordSystems));
    }

    /** Default Logger * */
    private static final Logger LOGGER = Logging.getLogger(NetCDFImageReaderSpi.class);

    static final String[] suffixes;

    static final String[] formatNames;

    static final String[] MIMETypes;

    static final String version = "1.0";

    static final String readerCN = "it.geosolutions.imageio.plugins.netcdf.NetCDFImageReader";

    // writerSpiNames
    static final String[] wSN = { null };

    // StreamMetadataFormatNames and StreamMetadataFormatClassNames
    static final boolean supportsStandardStreamMetadataFormat = false;
   
    static final String nativeStreamMetadataFormatName = null;

    static final String nativeStreamMetadataFormatClassName = null;

    static final String[] extraStreamMetadataFormatNames = { null };

    static final String[] extraStreamMetadataFormatClassNames = { null };

    // ImageMetadataFormatNames and ImageMetadataFormatClassNames
    static final boolean supportsStandardImageMetadataFormat = false;

    static final String nativeImageMetadataFormatName = null;

    static final String nativeImageMetadataFormatClassName = null;

    static final String[] extraImageMetadataFormatNames = { null };

    static final String[] extraImageMetadataFormatClassNames = { null };

    static{
        // If Grib Library is available, then the GRIB extension must be added to support
        if(NetCDFUtilities.isGribAvailable()){
            suffixes  = new String[]{ "nc", "NC", "grib", "grb", "grb2" };
            formatNames = new String[]{ "netcdf", "NetCDF", "grib", "grib2", "GRIB", "GRIB2" };
            MIMETypes = new String[]{ "application/x-netcdf", "image/netcdf", "image/x-netcdf", "image/x-nc" , "application/octet-stream" };
        }else{
            suffixes  = new String[]{ "nc", "NC" };
            formatNames = new String[]{ "netcdf", "NetCDF" };
            MIMETypes = new String[]{ "application/x-netcdf", "image/netcdf", "image/x-netcdf", "image/x-nc" };
        }
    }

   
    /** Default Constructor * */
    public NetCDFImageReaderSpi() {
        super(VENDOR_NAME, version, formatNames, suffixes, MIMETypes, readerCN, STANDARD_INPUT_TYPES, wSN,
                supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName,
                nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames,
                extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat,
                nativeImageMetadataFormatName, nativeImageMetadataFormatClassName,
                extraImageMetadataFormatNames, extraImageMetadataFormatClassNames);
       
        LOGGER.fine("NetCDFImageReaderSpi Constructor");
    }

    /**
     * @see javax.imageio.spi.ImageReaderSpi#createReaderInstance(java.lang.Object)
     */
    @Override
    public ImageReader createReaderInstance(Object extension)
            throws IOException {
        return new NetCDFImageReader(this);
    }

    /**
     * @see javax.imageio.spi.IIOServiceProvider#getDescription(java.util.Locale)
     */
    @Override
    public String getDescription(Locale locale) {
        return new StringBuffer("NetCDF-CF Image Reader, version ").append(
                version).toString();
    }

    @Override
    public boolean canDecodeInput(Object source) throws IOException {
        boolean canDecode = false;
        File input = null;
        if (source instanceof FileImageInputStreamExtImpl) {
            input = ((FileImageInputStreamExtImpl) source).getFile();
            if (LOGGER.isLoggable(Level.FINE))
                LOGGER.fine("Found a valid FileImageInputStream");
        }

        if (source instanceof File) {
            input = (File) source;
        }
        if (source instanceof URIImageInputStream) {
            URIImageInputStream uriInStream = (URIImageInputStream) source;
            try {
                // TODO perhaps it would be better to not make an online check. Might be slowing down.
                NetcdfDataset openDataset = NetcdfDataset.acquireDataset(uriInStream.getUri().toString(), null);
                openDataset.close();
                return true;
            } catch (IOException e) {
                return false;
            }
        }
        if (input != null) {
            NetcdfFile file = null;
            FileImageInputStream fis = null;
            try {

                // Checking Magic Number
                fis = new FileImageInputStream(input);
                byte[] b = new byte[4];
                fis.mark();
                fis.readFully(b);
                fis.reset();
                boolean cdfCheck = (b[0] == (byte)0x43 && b[1] == (byte)0x44 && b[2] == (byte)0x46);
                boolean hdf5Check = (b[0] == (byte)0x89 && b[1] == (byte)0x48 && b[2] == (byte)0x44);
                boolean gribCheck = (b[0] == (byte)0x47 && b[1] == (byte)0x52 && b[2] == (byte)0x49 && b[3] == (byte)0x42);

                // Check if the GRIB library is available
                gribCheck &= NetCDFUtilities.isGribAvailable();
               
                boolean isNetCDF = true;
                if (!cdfCheck && !hdf5Check && !gribCheck) {
                    if (!isNcML(input)) {
                        isNetCDF = false;
                    }
                }
                if (!isNetCDF) {
                    return false;
                }
                file = NetcdfDataset.acquireDataset(input.getPath(), null);
                if (file != null) {
                    if (LOGGER.isLoggable(Level.FINE))
                        LOGGER.fine("File successfully opened");
                    canDecode = true;
                }
            } catch (IOException ioe) {
                canDecode = false;
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (Throwable t) {

                    }
                }

                if (file != null)
                    file.close();
            }

        }
        return canDecode;
    }

    private boolean isNcML(File input) throws IOException {
        final StreamSource streamSource = new StreamSource(input);
        XMLStreamReader reader = null;
        try {
            reader = XMLInputFactory.newInstance().createXMLStreamReader(streamSource);
            reader.nextTag();
            if ("netcdf".equals(reader.getName().getLocalPart())) {
                return true;
            }
        } catch (XMLStreamException e) {

        } catch (FactoryConfigurationError e) {

        } finally {
            if (reader != null) {
                if (streamSource.getInputStream() != null) {
                    streamSource.getInputStream().close();
                }
                try {
                    reader.close();
                } catch (XMLStreamException e) {
                }
            }

        }
        return false;
    }

}
TOP

Related Classes of org.geotools.imageio.netcdf.NetCDFImageReaderSpi

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.