001/* 002 * Copyright (c) 2015 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2016-03-22 23:28:13 +0000 (Tue, 22 Mar 2016) $' 007 * '$Revision: 34456 $' 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; 030 031import java.io.File; 032 033import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; 034import org.geotools.geometry.jts.ReferencedEnvelope; 035import org.kepler.gis.data.BoundingBoxToken; 036import org.kepler.gis.data.GISToken; 037import org.kepler.gis.data.RasterToken; 038import org.kepler.gis.data.VectorToken; 039import org.kepler.gis.util.RasterUtilities; 040import org.kepler.gis.util.RasterUtilities.RasterInfo; 041import org.opengis.referencing.FactoryException; 042import org.opengis.referencing.crs.CoordinateReferenceSystem; 043import org.opengis.referencing.operation.TransformException; 044 045import ptolemy.actor.TypedIOPort; 046import ptolemy.data.Token; 047import ptolemy.kernel.CompositeEntity; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NameDuplicationException; 050 051/** Get the bounding box for a GIS data set. 052 * <p> 053 * If the coordinate reference system is specified in <i>crs</i> 054 * and is different than the crs in the input data set, then the 055 * bounding box will be reprojected. 056 * 057 * @author Daniel Crawl 058 * @version $Id: GetBoundingBox.java 34456 2016-03-22 23:28:13Z crawl $ 059 */ 060public class GetBoundingBox extends CRSActor { 061 062 /** Create a new GetBoundingBox with a given container and name. */ 063 public GetBoundingBox(CompositeEntity container, String name) 064 throws NameDuplicationException, IllegalActionException { 065 super(container, name); 066 067 input = new TypedIOPort(this, "input", true, false); 068 input.setTypeAtMost(GISToken.GIS); 069 070 output = new TypedIOPort(this, "output", false, true); 071 output.setTypeEquals(BoundingBoxToken.BOUNDING_BOX); 072 } 073 074 /** Output the bounding box for the data. */ 075 @Override 076 public void fire() throws IllegalActionException { 077 super.fire(); 078 Token token = input.get(0); 079 ReferencedEnvelope envelope = getBoundingBox(token, _crs); 080 output.broadcast(new BoundingBoxToken(envelope)); 081 } 082 083 /** Get the bounding box for a GIS dataset in a token. */ 084 public static ReferencedEnvelope getBoundingBox(Token token) throws IllegalActionException { 085 return getBoundingBox(token, null); 086 } 087 088 /** Get the bounding box for a GIS dataset in a token with a specific crs. */ 089 public static ReferencedEnvelope getBoundingBox(Token token, CoordinateReferenceSystem crs) throws IllegalActionException { 090 091 ReferencedEnvelope envelope = null; 092 093 if(token instanceof VectorToken) { 094 envelope = ((VectorToken)token).getVectors().getBounds(); 095 } else if(token instanceof RasterToken) { 096 AbstractGridCoverage2DReader reader = ((RasterToken)token).reader(); 097 if(reader != null) { 098 envelope = ReferencedEnvelope.create(reader.getOriginalEnvelope(), 099 reader.getCoordinateReferenceSystem()); 100 } else { 101 File file = ((RasterToken)token).rasterFile(); 102 RasterInfo rasterInfo = RasterUtilities.getInfo(file); 103 if(rasterInfo != null) { 104 envelope = rasterInfo.getEnvelope(); 105 } 106 } 107 } else if(token instanceof BoundingBoxToken) { 108 envelope = ((BoundingBoxToken)token).boundingBoxValue(); 109 } else { 110 throw new IllegalActionException("Unknown GIS input type: " + token.getClass()); 111 } 112 113 if(envelope == null) { 114 throw new IllegalActionException("Unable to get bounding box for input."); 115 } 116 117 ReferencedEnvelope newEnvelope; 118 if(crs == null) { 119 newEnvelope = envelope; 120 } else { 121 try { 122 newEnvelope = envelope.transform(crs, true); 123 } catch (TransformException | FactoryException e) { 124 throw new IllegalActionException("Error reprojecting bounding box: " + e.getMessage()); 125 } 126 } 127 128 return newEnvelope; 129 } 130 131 /** The input GIS data set. */ 132 public TypedIOPort input; 133 134 /** The bounding box of the data set. */ 135 public TypedIOPort output; 136 137}