001/*
002 * Copyright (c) 2015 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-12-23 23:08:28 +0000 (Wed, 23 Dec 2015) $' 
007 * '$Revision: 34416 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029package org.kepler.gis.actor.io;
030
031import java.io.IOException;
032
033import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
034import org.geotools.coverage.grid.io.AbstractGridCoverageWriter;
035import org.geotools.gce.geotiff.GeoTiffWriter;
036import org.kepler.gis.data.RasterToken;
037import org.opengis.coverage.grid.GridCoverage;
038import org.opengis.referencing.crs.CoordinateReferenceSystem;
039
040import ptolemy.data.StringToken;
041import ptolemy.kernel.CompositeEntity;
042import ptolemy.kernel.util.IllegalActionException;
043import ptolemy.kernel.util.NameDuplicationException;
044
045/** Write a raster data set to a file.
046 *  <p>
047 *  If the coordinate reference system is specified in <i>crs</i>
048 *  and is different than the crs in the input data set, then the
049 *  data set will be reprojected.
050 *
051 *  @author Daniel Crawl
052 *  @version $Id: RasterWriter.java 34416 2015-12-23 23:08:28Z crawl $
053 */
054public class RasterWriter extends GISWriter {
055
056    /** Create a new RasterWriter in a container with the specified name. */
057    public RasterWriter(CompositeEntity container, String name)
058            throws IllegalActionException, NameDuplicationException {
059        super(container, name);
060        
061        data.setTypeEquals(RasterToken.RASTER);
062        
063        // TODO add to type combo box
064        type.addChoice("GeoTIFF");   
065        // TODO add ArcGrid
066    }
067    
068    @Override
069    public void fire() throws IllegalActionException {
070        
071        super.fire();
072
073        CoordinateReferenceSystem currentCRS = null;
074
075        RasterToken token = (RasterToken) data.get(0);
076
077        GridCoverage coverage = token.coverageValue();
078        AbstractGridCoverage2DReader reader = null;
079        //File rasterFile = null;
080        
081        if(coverage != null) {
082            currentCRS = coverage.getCoordinateReferenceSystem();
083        } else {
084            reader = token.reader();
085            if(reader != null) {
086                currentCRS = reader.getCoordinateReferenceSystem();
087            } else {
088                // TODO
089                throw new IllegalActionException(this, "Raster format not yet supported.");
090                /*
091                rasterFile = token.rasterFile();
092                RasterInfo rasterInfo = RasterUtilities.getInfo(rasterFile);
093                if(rasterInfo != null) {
094                    currentCRS = rasterInfo.getCRS();
095                }
096                */
097            }
098        }
099        
100        // see if we need to reproject
101        if(currentCRS != null && _crs != null &&
102            !currentCRS.equals(_crs)) {
103            // TODO
104            throw new IllegalActionException(this,
105                "Raster reprojection not yet supported.");
106        }
107        
108        boolean outputIsGeoTiff = false;
109        
110        // see if type was specified
111        if(_typeStr != null && !_typeStr.isEmpty()) {
112            if(_typeStr.equals("GeoTIFF")) {
113                outputIsGeoTiff = true;
114            } else {
115                throw new IllegalActionException("Unsupported output format.");
116            }
117        } else if(_fileNameStr.toLowerCase().endsWith(".tif") ||
118                _fileNameStr.toLowerCase().endsWith(".tiff")) {
119            outputIsGeoTiff = true;
120        } else {
121            throw new IllegalActionException(this, "Unknown output format.");
122        }
123
124        AbstractGridCoverageWriter writer = null;
125
126        if(outputIsGeoTiff) {
127            try {
128                writer = new GeoTiffWriter(_outputFile);       
129            } catch (IOException e) {
130                throw new IllegalActionException(this, e, "Error creating GeoTiffWriter.");
131            }
132        }
133        
134        try {
135            if(reader != null) {
136                coverage = reader.read(null);
137            }
138            
139            if(coverage != null) {
140                writer.write(coverage, null);
141            }
142        } catch (IllegalArgumentException | IOException e) {
143            throw new IllegalActionException(this, e, "Error writing raster to " + _fileNameStr);
144        } finally {
145            if(writer != null) {
146                writer.dispose();
147            }
148        }
149        
150        // finally send output name
151        done.broadcast(new StringToken(_fileNameStr));
152    }
153}