001/*
002 * Copyright (c) 2016 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2016-03-09 23:10:49 +0000 (Wed, 09 Mar 2016) $' 
007 * '$Revision: 34453 $'
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.util.LinkedList;
032import java.util.List;
033
034import org.geotools.data.DataUtilities;
035import org.geotools.data.simple.SimpleFeatureCollection;
036import org.geotools.data.simple.SimpleFeatureIterator;
037import org.geotools.feature.simple.SimpleFeatureBuilder;
038import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
039import org.geotools.referencing.crs.DefaultGeographicCRS;
040import org.kepler.gis.data.GISToken;
041import org.kepler.gis.data.VectorToken;
042import org.opengis.feature.simple.SimpleFeature;
043import org.opengis.feature.simple.SimpleFeatureType;
044import com.vividsolutions.jts.geom.Geometry;
045import com.vividsolutions.jts.geom.Point;
046import org.opengis.referencing.crs.CoordinateReferenceSystem;
047
048import ptolemy.actor.lib.Transformer;
049import ptolemy.data.Token;
050import ptolemy.kernel.CompositeEntity;
051import ptolemy.kernel.util.IllegalActionException;
052import ptolemy.kernel.util.NameDuplicationException;
053
054/** Get a the centroid(s) of a GIS data set.
055 * 
056 *  @author Daniel Crawl
057 *  @version $Id: GetCentroids.java 34453 2016-03-09 23:10:49Z crawl $
058 */
059public class GetCentroids extends Transformer {
060
061    public GetCentroids(CompositeEntity container, String name) throws NameDuplicationException, IllegalActionException {
062        super(container, name);
063        
064        input.setTypeAtMost(GISToken.GIS);
065        output.setTypeEquals(VectorToken.VECTOR);
066        
067    }
068    
069    @Override
070    public void fire() throws IllegalActionException {
071     
072        super.fire();
073        
074        Token in = input.get(0);
075
076        SimpleFeatureCollection centroids;
077        
078        if(in instanceof VectorToken) {
079            SimpleFeatureCollection features = ((VectorToken)in).getVectors();
080            
081            CoordinateReferenceSystem crs = features.getSchema().getCoordinateReferenceSystem();
082            if(crs == null) {
083                crs = DefaultGeographicCRS.WGS84;
084            }
085            
086            SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
087            typeBuilder.setCRS(crs);
088            typeBuilder.setName("centroids"); 
089            typeBuilder.add("centroid", Point.class);
090
091            SimpleFeatureType centroidSchema = typeBuilder.buildFeatureType();
092
093            SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(centroidSchema);
094            
095            List<SimpleFeature> list = new LinkedList<SimpleFeature>();
096            
097            try(SimpleFeatureIterator iterator = features.features()) {
098                int i = 1;
099                while(iterator.hasNext()) {
100                    SimpleFeature feature = iterator.next();
101                    Geometry geometry = (Geometry) feature.getDefaultGeometry();
102                    Point point = geometry.getCentroid();
103                    featureBuilder.add(point);
104                    list.add(featureBuilder.buildFeature("id" + i));
105                    i++;
106                }
107            }
108            
109            centroids = DataUtilities.collection(list);
110            
111        } /*else if(in instanceof BoundingBoxToken) {
112            ReferencedEnvelope envelope = ((BoundingBoxToken)in).boundingBoxValue();
113            
114        } */ else {
115            throw new IllegalActionException(this, "Unsupported GIS input type: " + in.getClass());
116        }
117
118        output.broadcast(new VectorToken(centroids));
119        
120    }
121
122}