Package org.geoserver.wps.gs

Source Code of org.geoserver.wps.gs.PolygonExtractionProcess

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.gs;

import jaitools.media.jai.contour.ContourDescriptor;
import jaitools.media.jai.contour.ContourRIF;
import jaitools.media.jai.vectorize.VectorizeDescriptor;
import jaitools.media.jai.vectorize.VectorizeRIF;
import jaitools.numeric.Range;

import java.awt.geom.AffineTransform;
import java.awt.image.RenderedImage;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.RenderedOp;

import org.geoserver.wps.jts.DescribeParameter;
import org.geoserver.wps.jts.DescribeProcess;
import org.geoserver.wps.jts.DescribeResult;
import org.geoserver.wps.raster.CoverageUtilities;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.image.jai.Registry;
import org.geotools.process.ProcessException;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.util.ProgressListener;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.util.AffineTransformation;

/**
* A process that wraps a {@link GridCoverage2D} as a collection of point feature.
*
* @author Simone Giannecchini, GeoSolutions
*
*/
@DescribeProcess(title = "PolygonExtraction", description = "Perform the polygon extraction on a provided raster")
public class PolygonExtractionProcess implements GeoServerProcess {
 
   
    static {
        Registry.registerRIF(JAI.getDefaultInstance(), new VectorizeDescriptor(), new VectorizeRIF(), Registry.JAI_TOOLS_PRODUCT);
    }

 
    @DescribeResult(name = "result", description = "The polygon feature collection")
    public SimpleFeatureCollection execute(
            @DescribeParameter(name = "data", description = "The raster to be used as the source") GridCoverage2D coverage,
            @DescribeParameter(name = "band", description = "(Integer, default=0) the source image band to process",min=0) Integer band,
            @DescribeParameter(name = "insideEdges", description = " (Boolean, default=true) whether to vectorize boundaries between adjacent regions with non-outside values",min=0) Boolean insideEdges,
            @DescribeParameter(name = "roi", description = "The geometry used to delineate the area of interest in model space",min=0) Geometry roi,
            @DescribeParameter(name = "ranges", description = "The list of ranges to be applied. \n"
                + "Each range is expressed as 'OPEN START ; END CLOSE'\n"
                + "where 'OPEN:=(|[, CLOSE=)|]',\n "
                + "START is the low value, or nothing to imply -INF,\n"
                + "CLOSE is the biggest value, or nothing to imply +INF", collectionType=Range.class, min=0) List<Range> classificationRanges,
            ProgressListener progressListener)
            throws ProcessException {
     
     
      //
      // initial checks
      //
        if (coverage ==null) {
            throw new ProcessException("Invalid input, source grid coverage should be not null");
        }
        if(band == null) {
          band = 0;
        } else if (band < 0 || band >= coverage.getNumSampleDimensions()) {
            throw new ProcessException("Invalid input, invalid band number:"+band);
        }
        // do we have classification ranges?
        boolean hasClassificationRanges= classificationRanges!=null&& classificationRanges.size()>0;
       
        // apply the classification by setting 0 as the default value and using 1, ..., numClasses for the other classes.
        // we use 0 also as the noData for the resulting coverage.
        if(hasClassificationRanges){

          final RangeLookupProcess lookup = new RangeLookupProcess();
          coverage=lookup.execute(
              coverage,
              band,
              classificationRanges,
              progressListener);
        }
       
        //
        // GRID TO WORLD preparation
        //
        final AffineTransform mt2D = (AffineTransform) coverage.getGridGeometry().getGridToCRS2D(PixelOrientation.UPPER_LEFT);
       
        // get the rendered image
        final RenderedImage raster=coverage.getRenderedImage();
       
        // perform jai operation
        ParameterBlockJAI pb = new ParameterBlockJAI("Vectorize");
        pb.setSource("source0", raster);
       
        if(roi!=null){
          pb.setParameter("roi", CoverageUtilities.prepareROI(roi,mt2D));
        }
        pb.setParameter("band", band);
        // TODO use no Data from the final coverage
        pb.setParameter("outsideValues", Arrays.asList(0))
        // pb.setParameter("removeCollinear", false); 
          final RenderedOp dest = JAI.create("Vectorize", pb);
    @SuppressWarnings("unchecked")
    final Collection<Polygon> prop = (Collection<Polygon>) dest.getProperty(VectorizeDescriptor.VECTOR_PROPERTY_NAME
    );
       
        // wrap as a feature collection and return
    final SimpleFeatureType featureType=CoverageUtilities.createFeatureType(coverage,Polygon.class);
        final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(featureType);
        int i=0;
        final ListFeatureCollection featureCollection= new ListFeatureCollection(featureType);
        final AffineTransformation jtsTransformation=new AffineTransformation(
          mt2D.getScaleX(),
          mt2D.getShearX(),
          mt2D.getTranslateX(),
          mt2D.getShearY(),
          mt2D.getScaleY(),
          mt2D.getTranslateY());
        for(Polygon polygon:prop){
          // get value
          Double  value= (Double) polygon.getUserData();
          polygon.setUserData(null);
          // filter coordinates in place
          polygon.apply(jtsTransformation);
         
          // create feature and add to list
          builder.set("the_geom", polygon);
          builder.set("value", value);
         
          featureCollection.add(builder.buildFeature(String.valueOf(i++)));
         
        }
       
        //return value
        return featureCollection;

    }
}
TOP

Related Classes of org.geoserver.wps.gs.PolygonExtractionProcess

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.