001/* 002 * Copyright (c) 2014-2015 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2018-07-24 17:17:37 +0000 (Tue, 24 Jul 2018) $' 007 * '$Revision: 34705 $' 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.conversions; 030 031import org.geotools.coverage.grid.GridCoverage2D; 032import org.geotools.data.simple.SimpleFeatureCollection; 033import org.geotools.geometry.jts.ReferencedEnvelope; 034import org.geotools.process.vector.VectorToRasterProcess; 035import org.kepler.gis.actor.GetBoundingBox; 036import org.kepler.gis.data.RasterToken; 037import org.kepler.gis.data.VectorToken; 038import org.kepler.gis.util.RasterUtilities; 039import org.opengis.feature.simple.SimpleFeatureType; 040 041import ptolemy.actor.TypedIOPort; 042import ptolemy.actor.lib.Transformer; 043import ptolemy.actor.parameters.PortParameter; 044import ptolemy.data.IntToken; 045import ptolemy.data.StringToken; 046import ptolemy.data.Token; 047import ptolemy.data.type.BaseType; 048import ptolemy.kernel.CompositeEntity; 049import ptolemy.kernel.util.IllegalActionException; 050import ptolemy.kernel.util.NameDuplicationException; 051import ptolemy.kernel.util.SingletonAttribute; 052 053/** An actor that converts a vector/feature data set into a raster. 054 * 055 * @author Daniel Crawl 056 * @version $Id: VectorToRaster.java 34705 2018-07-24 17:17:37Z crawl $ 057 */ 058public class VectorToRaster extends Transformer { 059 060 public VectorToRaster(CompositeEntity container, String name) 061 throws IllegalActionException, NameDuplicationException { 062 063 super(container, name); 064 065 input.setTypeEquals(VectorToken.VECTOR); 066 new SingletonAttribute(input, "_showName"); 067 068 output.setTypeEquals(RasterToken.RASTER); 069 070 attributeName = new PortParameter(this, "attributeName"); 071 attributeName.setTypeEquals(BaseType.STRING); 072 attributeName.setStringMode(true); 073 new SingletonAttribute(attributeName.getPort(), "_showName"); 074 075 height = new PortParameter(this, "height"); 076 height.setTypeEquals(BaseType.INT); 077 new SingletonAttribute(height.getPort(), "_showName"); 078 height.setToken(String.valueOf(100)); 079 080 width = new PortParameter(this, "width"); 081 width.setTypeEquals(BaseType.INT); 082 new SingletonAttribute(width.getPort(), "_showName"); 083 width.setToken(String.valueOf(100)); 084 085 title = new PortParameter(this, "title"); 086 title.setTypeEquals(BaseType.STRING); 087 title.setStringMode(true); 088 new SingletonAttribute(title.getPort(), "_showName"); 089 title.setToken("title"); 090 091 reference = new TypedIOPort(this, "reference", true, false); 092 reference.setTypeEquals(RasterToken.RASTER); 093 new SingletonAttribute(reference, "_showName"); 094 095 } 096 097 @Override 098 public void fire() throws IllegalActionException { 099 100 super.fire(); 101 102 attributeName.update(); 103 height.update(); 104 width.update(); 105 title.update(); 106 107 String attributeNameStr = ((StringToken)attributeName.getToken()).stringValue(); 108 if(attributeNameStr.trim().isEmpty()) { 109 throw new IllegalActionException(this, "Attribute name must be specified."); 110 } 111 112 String titleStr = ((StringToken)title.getToken()).stringValue(); 113 if(titleStr.trim().isEmpty()) { 114 throw new IllegalActionException(this, "Title must be specified."); 115 } 116 117 RasterToken referenceRaster = null; 118 boolean heightValid = false; 119 boolean widthValid = false; 120 int widthVal = 0; 121 int heightVal = 0; 122 if(reference.numberOfSources() > 0) { 123 referenceRaster = (RasterToken)reference.get(0); 124 } else { 125 Token token = width.getToken(); 126 if(token != null) { 127 widthVal = ((IntToken)width.getToken()).intValue(); 128 if(widthVal < 1) { 129 throw new IllegalActionException(this, "Width must be greater than 0."); 130 } 131 widthValid = true; 132 } 133 134 token = height.getToken(); 135 if(token != null) { 136 heightVal = ((IntToken)height.getToken()).intValue(); 137 if(heightVal < 1) { 138 throw new IllegalActionException(this, "Height must be greater than 0."); 139 } 140 heightValid = true; 141 } 142 143 } 144 145 146 SimpleFeatureCollection features = ((VectorToken)input.get(0)).getVectors(); 147 148 SimpleFeatureType schema = features.getSchema(); 149 150 if(schema == null) { 151 throw new IllegalActionException(this, "Features do not have schema."); 152 } 153 154 if(schema.getType(attributeNameStr) == null) { 155 throw new IllegalActionException(this, "Attribute " + 156 attributeNameStr + " not found in input vector collection."); 157 } 158 159 ReferencedEnvelope envelope = null; 160 161 if(referenceRaster != null) { 162 envelope = GetBoundingBox.getBoundingBox(referenceRaster); 163 Integer[] sizes = RasterUtilities.getGridSize(referenceRaster); 164 widthVal = sizes[0]; 165 heightVal = sizes[1]; 166 167 //System.out.println("env ref raster: " + referenceRaster.reader().getOriginalEnvelope()); 168 169 } else { 170 envelope = features.getBounds(); 171 172 if(!widthValid) { 173 //widthVal = Math.abs(Double.valueOf(envelope.getMaxX() - envelope.getMinX()).intValue()); 174 widthVal = (int) envelope.getWidth(); 175 } 176 177 if(!heightValid) { 178 //heightVal = Math.abs(Double.valueOf(envelope.getMaxY() - envelope.getMinY()).intValue()); 179 heightVal = (int) envelope.getHeight(); 180 } 181 } 182 183 VectorToRasterProcess process = new VectorToRasterProcess(); 184 185 GridCoverage2D coverage = 186 process.execute(features, widthVal, heightVal, titleStr, 187 attributeNameStr, envelope, null); 188 189 //System.out.println("env vector: " + features.getBounds()); 190 //System.out.println("env out raster: " + coverage.getEnvelope()); 191 192 output.broadcast(new RasterToken(coverage)); 193 } 194 195 @Override 196 public void preinitialize() throws IllegalActionException { 197 super.preinitialize(); 198 199 if(reference.numberOfSources() > 0) { 200 if(height.getPort().numberOfSources() > 0) { 201 throw new IllegalActionException(this, "Reference and height ports cannot be both used."); 202 } else if(width.getPort().numberOfSources() > 0) { 203 throw new IllegalActionException(this, "Reference and width ports cannot be both used."); 204 } 205 } 206 207 } 208 209 210 /** The attribute in the features to use as the raster values. */ 211 public PortParameter attributeName; 212 213 /** The height of the raster in pixels. If not specified, 214 * the height of the vector bounding box is used. 215 */ 216 public PortParameter height; 217 218 /** The width of the raster in pixels. If not specified, the width of 219 * the vector bounding box is used. 220 */ 221 public PortParameter width; 222 223 /** The title of the raster. */ 224 public PortParameter title; 225 226 /** Raster to use for height, width, and cell size. */ 227 public TypedIOPort reference; 228}