@Test public void noContours() { GridCoverage2D cov = createVerticalGradient(10, 10, null, 0, 10); SimpleFeatureCollection fc = process.execute(cov, 0, new double[] {20}, null, null, null, null, null); assertNotNull(fc); assertTrue(fc.isEmpty()); }
@DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) public SimpleFeatureCollection execute( @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d, @DescribeParameter( name = "band", description = "Band number (zero base) to use for values to be contoured", min = 0, max = 1 ) Integer band, @DescribeParameter( name = "levels", description = "Values of levels at which to generate contours" ) double[] levels, @DescribeParameter( name = "interval", description = "Interval between contour values (ignored if levels parameter is supplied)", min = 0, minValue = 0 ) Double interval, @DescribeParameter( name = "simplify", description = "Indicates whether contour lines are simplified", min = 0 ) Boolean simplify, @DescribeParameter( name = "smooth", description = "Indicates whether contour lines are smoothed using Bezier smoothing", min = 0 ) Boolean smooth, @DescribeParameter( name = "roi", description = "Geometry delineating the region of interest (in raster coordinate system)", min = 0 ) Geometry roi, ProgressListener progressListener) throws ProcessException { if (gc2d == null) { throw new ProcessException("Invalid input, source grid coverage should be not null"); } if (band != null && (band < 0 || band >= gc2d.getNumSampleDimensions())) { throw new ProcessException("Invalid input, invalid band number:" + band); } boolean hasValues = !(levels == null || levels.length == 0); if (!hasValues && interval == null) { throw new ProcessException("One between interval and values must be valid"); } final AffineTransform mt2D = (AffineTransform) gc2d.getGridGeometry().getGridToCRS2D(PixelOrientation.CENTER); List<Object> noDataList = new ArrayList<Object>(); for (GridSampleDimension sd : gc2d.getSampleDimensions()) { final double[] sdNoData = sd.getNoDataValues(); if (sdNoData != null) { for (double nodata : sdNoData) { noDataList.add(nodata); } } if (sd.getCategories() != null) { for (Category cat : sd.getCategories()) { if (cat.getName().equals(NO_DATA)) { final NumberRange<? extends Number> catRange = cat.getRange(); if (!Double.isNaN(catRange.getMinimum())) { if (catRange.getMinimum() == catRange.getMaximum()) { noDataList.add(catRange.getMinimum()); } else { Range<Double> noData = new Range<Double>( catRange.getMinimum(), catRange.isMinIncluded(), catRange.getMaximum(), catRange.isMaxIncluded()); noDataList.add(noData); } } } } } } final RenderedImage raster = gc2d.getRenderedImage(); ParameterBlockJAI pb = new ParameterBlockJAI("Contour"); pb.setSource("source0", raster); if (roi != null) { pb.setParameter("roi", CoverageUtilities.prepareROI(roi, mt2D)); } if (band != null) { pb.setParameter("band", band); } if (levels != null && levels.length > 0) { final ArrayList<Double> elements = new ArrayList<Double>(levels.length); for (double level : levels) elements.add(level); pb.setParameter("levels", elements); } else { pb.setParameter("interval", interval); } if (simplify != null) { pb.setParameter("simplify", simplify); } if (smooth != null) { pb.setParameter("smooth", smooth); } if (!noDataList.isEmpty()) { pb.setParameter("nodata", noDataList); } final RenderedOp dest = JAI.create("Contour", pb); @SuppressWarnings("unchecked") final Collection<LineString> prop = (Collection<LineString>) dest.getProperty(ContourDescriptor.CONTOUR_PROPERTY_NAME); final SimpleFeatureType schema = CoverageUtilities.createFeatureType(gc2d, LineString.class); final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); int i = 0; final ListFeatureCollection featureCollection = new ListFeatureCollection(schema); final AffineTransformation jtsTransformation = new AffineTransformation( mt2D.getScaleX(), mt2D.getShearX(), mt2D.getTranslateX(), mt2D.getShearY(), mt2D.getScaleY(), mt2D.getTranslateY()); for (LineString line : prop) { if (!line.isValid()) { continue; } Double value = (Double) line.getUserData(); line.setUserData(null); line.apply(jtsTransformation); builder.set("the_geom", line); builder.set("value", value); featureCollection.add(builder.buildFeature(String.valueOf(i++))); } return featureCollection; }
ContourProcess implements RasterProcess { @DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) public SimpleFeatureCollection execute( @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d, @DescribeParameter( name = "band", description = "Band number (zero base) to use for values to be contoured", min = 0, max = 1 ) Integer band, @DescribeParameter( name = "levels", description = "Values of levels at which to generate contours" ) double[] levels, @DescribeParameter( name = "interval", description = "Interval between contour values (ignored if levels parameter is supplied)", min = 0, minValue = 0 ) Double interval, @DescribeParameter( name = "simplify", description = "Indicates whether contour lines are simplified", min = 0 ) Boolean simplify, @DescribeParameter( name = "smooth", description = "Indicates whether contour lines are smoothed using Bezier smoothing", min = 0 ) Boolean smooth, @DescribeParameter( name = "roi", description = "Geometry delineating the region of interest (in raster coordinate system)", min = 0 ) Geometry roi, ProgressListener progressListener) throws ProcessException { if (gc2d == null) { throw new ProcessException("Invalid input, source grid coverage should be not null"); } if (band != null && (band < 0 || band >= gc2d.getNumSampleDimensions())) { throw new ProcessException("Invalid input, invalid band number:" + band); } boolean hasValues = !(levels == null || levels.length == 0); if (!hasValues && interval == null) { throw new ProcessException("One between interval and values must be valid"); } final AffineTransform mt2D = (AffineTransform) gc2d.getGridGeometry().getGridToCRS2D(PixelOrientation.CENTER); List<Object> noDataList = new ArrayList<Object>(); for (GridSampleDimension sd : gc2d.getSampleDimensions()) { final double[] sdNoData = sd.getNoDataValues(); if (sdNoData != null) { for (double nodata : sdNoData) { noDataList.add(nodata); } } if (sd.getCategories() != null) { for (Category cat : sd.getCategories()) { if (cat.getName().equals(NO_DATA)) { final NumberRange<? extends Number> catRange = cat.getRange(); if (!Double.isNaN(catRange.getMinimum())) { if (catRange.getMinimum() == catRange.getMaximum()) { noDataList.add(catRange.getMinimum()); } else { Range<Double> noData = new Range<Double>( catRange.getMinimum(), catRange.isMinIncluded(), catRange.getMaximum(), catRange.isMaxIncluded()); noDataList.add(noData); } } } } } } final RenderedImage raster = gc2d.getRenderedImage(); ParameterBlockJAI pb = new ParameterBlockJAI("Contour"); pb.setSource("source0", raster); if (roi != null) { pb.setParameter("roi", CoverageUtilities.prepareROI(roi, mt2D)); } if (band != null) { pb.setParameter("band", band); } if (levels != null && levels.length > 0) { final ArrayList<Double> elements = new ArrayList<Double>(levels.length); for (double level : levels) elements.add(level); pb.setParameter("levels", elements); } else { pb.setParameter("interval", interval); } if (simplify != null) { pb.setParameter("simplify", simplify); } if (smooth != null) { pb.setParameter("smooth", smooth); } if (!noDataList.isEmpty()) { pb.setParameter("nodata", noDataList); } final RenderedOp dest = JAI.create("Contour", pb); @SuppressWarnings("unchecked") final Collection<LineString> prop = (Collection<LineString>) dest.getProperty(ContourDescriptor.CONTOUR_PROPERTY_NAME); final SimpleFeatureType schema = CoverageUtilities.createFeatureType(gc2d, LineString.class); final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); int i = 0; final ListFeatureCollection featureCollection = new ListFeatureCollection(schema); final AffineTransformation jtsTransformation = new AffineTransformation( mt2D.getScaleX(), mt2D.getShearX(), mt2D.getTranslateX(), mt2D.getShearY(), mt2D.getScaleY(), mt2D.getTranslateY()); for (LineString line : prop) { if (!line.isValid()) { continue; } Double value = (Double) line.getUserData(); line.setUserData(null); line.apply(jtsTransformation); builder.set("the_geom", line); builder.set("value", value); featureCollection.add(builder.buildFeature(String.valueOf(i++))); } return featureCollection; } }
ContourProcess implements RasterProcess { @DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) public SimpleFeatureCollection execute( @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d, @DescribeParameter( name = "band", description = "Band number (zero base) to use for values to be contoured", min = 0, max = 1 ) Integer band, @DescribeParameter( name = "levels", description = "Values of levels at which to generate contours" ) double[] levels, @DescribeParameter( name = "interval", description = "Interval between contour values (ignored if levels parameter is supplied)", min = 0, minValue = 0 ) Double interval, @DescribeParameter( name = "simplify", description = "Indicates whether contour lines are simplified", min = 0 ) Boolean simplify, @DescribeParameter( name = "smooth", description = "Indicates whether contour lines are smoothed using Bezier smoothing", min = 0 ) Boolean smooth, @DescribeParameter( name = "roi", description = "Geometry delineating the region of interest (in raster coordinate system)", min = 0 ) Geometry roi, ProgressListener progressListener) throws ProcessException { if (gc2d == null) { throw new ProcessException("Invalid input, source grid coverage should be not null"); } if (band != null && (band < 0 || band >= gc2d.getNumSampleDimensions())) { throw new ProcessException("Invalid input, invalid band number:" + band); } boolean hasValues = !(levels == null || levels.length == 0); if (!hasValues && interval == null) { throw new ProcessException("One between interval and values must be valid"); } final AffineTransform mt2D = (AffineTransform) gc2d.getGridGeometry().getGridToCRS2D(PixelOrientation.CENTER); List<Object> noDataList = new ArrayList<Object>(); for (GridSampleDimension sd : gc2d.getSampleDimensions()) { final double[] sdNoData = sd.getNoDataValues(); if (sdNoData != null) { for (double nodata : sdNoData) { noDataList.add(nodata); } } if (sd.getCategories() != null) { for (Category cat : sd.getCategories()) { if (cat.getName().equals(NO_DATA)) { final NumberRange<? extends Number> catRange = cat.getRange(); if (!Double.isNaN(catRange.getMinimum())) { if (catRange.getMinimum() == catRange.getMaximum()) { noDataList.add(catRange.getMinimum()); } else { Range<Double> noData = new Range<Double>( catRange.getMinimum(), catRange.isMinIncluded(), catRange.getMaximum(), catRange.isMaxIncluded()); noDataList.add(noData); } } } } } } final RenderedImage raster = gc2d.getRenderedImage(); ParameterBlockJAI pb = new ParameterBlockJAI("Contour"); pb.setSource("source0", raster); if (roi != null) { pb.setParameter("roi", CoverageUtilities.prepareROI(roi, mt2D)); } if (band != null) { pb.setParameter("band", band); } if (levels != null && levels.length > 0) { final ArrayList<Double> elements = new ArrayList<Double>(levels.length); for (double level : levels) elements.add(level); pb.setParameter("levels", elements); } else { pb.setParameter("interval", interval); } if (simplify != null) { pb.setParameter("simplify", simplify); } if (smooth != null) { pb.setParameter("smooth", smooth); } if (!noDataList.isEmpty()) { pb.setParameter("nodata", noDataList); } final RenderedOp dest = JAI.create("Contour", pb); @SuppressWarnings("unchecked") final Collection<LineString> prop = (Collection<LineString>) dest.getProperty(ContourDescriptor.CONTOUR_PROPERTY_NAME); final SimpleFeatureType schema = CoverageUtilities.createFeatureType(gc2d, LineString.class); final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); int i = 0; final ListFeatureCollection featureCollection = new ListFeatureCollection(schema); final AffineTransformation jtsTransformation = new AffineTransformation( mt2D.getScaleX(), mt2D.getShearX(), mt2D.getTranslateX(), mt2D.getShearY(), mt2D.getScaleY(), mt2D.getTranslateY()); for (LineString line : prop) { if (!line.isValid()) { continue; } Double value = (Double) line.getUserData(); line.setUserData(null); line.apply(jtsTransformation); builder.set("the_geom", line); builder.set("value", value); featureCollection.add(builder.buildFeature(String.valueOf(i++))); } return featureCollection; }  }
ContourProcess implements RasterProcess { @DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) public SimpleFeatureCollection execute( @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d, @DescribeParameter( name = "band", description = "Band number (zero base) to use for values to be contoured", min = 0, max = 1 ) Integer band, @DescribeParameter( name = "levels", description = "Values of levels at which to generate contours" ) double[] levels, @DescribeParameter( name = "interval", description = "Interval between contour values (ignored if levels parameter is supplied)", min = 0, minValue = 0 ) Double interval, @DescribeParameter( name = "simplify", description = "Indicates whether contour lines are simplified", min = 0 ) Boolean simplify, @DescribeParameter( name = "smooth", description = "Indicates whether contour lines are smoothed using Bezier smoothing", min = 0 ) Boolean smooth, @DescribeParameter( name = "roi", description = "Geometry delineating the region of interest (in raster coordinate system)", min = 0 ) Geometry roi, ProgressListener progressListener) throws ProcessException { if (gc2d == null) { throw new ProcessException("Invalid input, source grid coverage should be not null"); } if (band != null && (band < 0 || band >= gc2d.getNumSampleDimensions())) { throw new ProcessException("Invalid input, invalid band number:" + band); } boolean hasValues = !(levels == null || levels.length == 0); if (!hasValues && interval == null) { throw new ProcessException("One between interval and values must be valid"); } final AffineTransform mt2D = (AffineTransform) gc2d.getGridGeometry().getGridToCRS2D(PixelOrientation.CENTER); List<Object> noDataList = new ArrayList<Object>(); for (GridSampleDimension sd : gc2d.getSampleDimensions()) { final double[] sdNoData = sd.getNoDataValues(); if (sdNoData != null) { for (double nodata : sdNoData) { noDataList.add(nodata); } } if (sd.getCategories() != null) { for (Category cat : sd.getCategories()) { if (cat.getName().equals(NO_DATA)) { final NumberRange<? extends Number> catRange = cat.getRange(); if (!Double.isNaN(catRange.getMinimum())) { if (catRange.getMinimum() == catRange.getMaximum()) { noDataList.add(catRange.getMinimum()); } else { Range<Double> noData = new Range<Double>( catRange.getMinimum(), catRange.isMinIncluded(), catRange.getMaximum(), catRange.isMaxIncluded()); noDataList.add(noData); } } } } } } final RenderedImage raster = gc2d.getRenderedImage(); ParameterBlockJAI pb = new ParameterBlockJAI("Contour"); pb.setSource("source0", raster); if (roi != null) { pb.setParameter("roi", CoverageUtilities.prepareROI(roi, mt2D)); } if (band != null) { pb.setParameter("band", band); } if (levels != null && levels.length > 0) { final ArrayList<Double> elements = new ArrayList<Double>(levels.length); for (double level : levels) elements.add(level); pb.setParameter("levels", elements); } else { pb.setParameter("interval", interval); } if (simplify != null) { pb.setParameter("simplify", simplify); } if (smooth != null) { pb.setParameter("smooth", smooth); } if (!noDataList.isEmpty()) { pb.setParameter("nodata", noDataList); } final RenderedOp dest = JAI.create("Contour", pb); @SuppressWarnings("unchecked") final Collection<LineString> prop = (Collection<LineString>) dest.getProperty(ContourDescriptor.CONTOUR_PROPERTY_NAME); final SimpleFeatureType schema = CoverageUtilities.createFeatureType(gc2d, LineString.class); final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); int i = 0; final ListFeatureCollection featureCollection = new ListFeatureCollection(schema); final AffineTransformation jtsTransformation = new AffineTransformation( mt2D.getScaleX(), mt2D.getShearX(), mt2D.getTranslateX(), mt2D.getShearY(), mt2D.getScaleY(), mt2D.getTranslateY()); for (LineString line : prop) { if (!line.isValid()) { continue; } Double value = (Double) line.getUserData(); line.setUserData(null); line.apply(jtsTransformation); builder.set("the_geom", line); builder.set("value", value); featureCollection.add(builder.buildFeature(String.valueOf(i++))); } return featureCollection; }  static SimpleFeatureCollection process(
            GridCoverage2D gc2d,
            Integer band,
            double[] levels,
            Double interval,
            Boolean simplify,
            Boolean smooth,
            Geometry roi,
            ProgressListener progressListener); @DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) SimpleFeatureCollection execute(
            @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d,
            @DescribeParameter(
                        name = "band",
                        description = "Band number (zero base) to use for values to be contoured",
                        min = 0,
                        max = 1
                    )
                    Integer band,
            @DescribeParameter(
                        name = "levels",
                        description = "Values of levels at which to generate contours"
                    )
                    double[] levels,
            @DescribeParameter(
                        name = "interval",
                        description =
                                "Interval between contour values (ignored if levels parameter is supplied)",
                        min = 0,
                        minValue = 0
                    )
                    Double interval,
            @DescribeParameter(
                        name = "simplify",
                        description = "Indicates whether contour lines are simplified",
                        min = 0
                    )
                    Boolean simplify,
            @DescribeParameter(
                        name = "smooth",
                        description =
                                "Indicates whether contour lines are smoothed using Bezier smoothing",
                        min = 0
                    )
                    Boolean smooth,
            @DescribeParameter(
                        name = "roi",
                        description =
                                "Geometry delineating the region of interest (in raster coordinate system)",
                        min = 0
                    )
                    Geometry roi,
            ProgressListener progressListener); }
ContourProcess implements RasterProcess { @DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) public SimpleFeatureCollection execute( @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d, @DescribeParameter( name = "band", description = "Band number (zero base) to use for values to be contoured", min = 0, max = 1 ) Integer band, @DescribeParameter( name = "levels", description = "Values of levels at which to generate contours" ) double[] levels, @DescribeParameter( name = "interval", description = "Interval between contour values (ignored if levels parameter is supplied)", min = 0, minValue = 0 ) Double interval, @DescribeParameter( name = "simplify", description = "Indicates whether contour lines are simplified", min = 0 ) Boolean simplify, @DescribeParameter( name = "smooth", description = "Indicates whether contour lines are smoothed using Bezier smoothing", min = 0 ) Boolean smooth, @DescribeParameter( name = "roi", description = "Geometry delineating the region of interest (in raster coordinate system)", min = 0 ) Geometry roi, ProgressListener progressListener) throws ProcessException { if (gc2d == null) { throw new ProcessException("Invalid input, source grid coverage should be not null"); } if (band != null && (band < 0 || band >= gc2d.getNumSampleDimensions())) { throw new ProcessException("Invalid input, invalid band number:" + band); } boolean hasValues = !(levels == null || levels.length == 0); if (!hasValues && interval == null) { throw new ProcessException("One between interval and values must be valid"); } final AffineTransform mt2D = (AffineTransform) gc2d.getGridGeometry().getGridToCRS2D(PixelOrientation.CENTER); List<Object> noDataList = new ArrayList<Object>(); for (GridSampleDimension sd : gc2d.getSampleDimensions()) { final double[] sdNoData = sd.getNoDataValues(); if (sdNoData != null) { for (double nodata : sdNoData) { noDataList.add(nodata); } } if (sd.getCategories() != null) { for (Category cat : sd.getCategories()) { if (cat.getName().equals(NO_DATA)) { final NumberRange<? extends Number> catRange = cat.getRange(); if (!Double.isNaN(catRange.getMinimum())) { if (catRange.getMinimum() == catRange.getMaximum()) { noDataList.add(catRange.getMinimum()); } else { Range<Double> noData = new Range<Double>( catRange.getMinimum(), catRange.isMinIncluded(), catRange.getMaximum(), catRange.isMaxIncluded()); noDataList.add(noData); } } } } } } final RenderedImage raster = gc2d.getRenderedImage(); ParameterBlockJAI pb = new ParameterBlockJAI("Contour"); pb.setSource("source0", raster); if (roi != null) { pb.setParameter("roi", CoverageUtilities.prepareROI(roi, mt2D)); } if (band != null) { pb.setParameter("band", band); } if (levels != null && levels.length > 0) { final ArrayList<Double> elements = new ArrayList<Double>(levels.length); for (double level : levels) elements.add(level); pb.setParameter("levels", elements); } else { pb.setParameter("interval", interval); } if (simplify != null) { pb.setParameter("simplify", simplify); } if (smooth != null) { pb.setParameter("smooth", smooth); } if (!noDataList.isEmpty()) { pb.setParameter("nodata", noDataList); } final RenderedOp dest = JAI.create("Contour", pb); @SuppressWarnings("unchecked") final Collection<LineString> prop = (Collection<LineString>) dest.getProperty(ContourDescriptor.CONTOUR_PROPERTY_NAME); final SimpleFeatureType schema = CoverageUtilities.createFeatureType(gc2d, LineString.class); final SimpleFeatureBuilder builder = new SimpleFeatureBuilder(schema); int i = 0; final ListFeatureCollection featureCollection = new ListFeatureCollection(schema); final AffineTransformation jtsTransformation = new AffineTransformation( mt2D.getScaleX(), mt2D.getShearX(), mt2D.getTranslateX(), mt2D.getShearY(), mt2D.getScaleY(), mt2D.getTranslateY()); for (LineString line : prop) { if (!line.isValid()) { continue; } Double value = (Double) line.getUserData(); line.setUserData(null); line.apply(jtsTransformation); builder.set("the_geom", line); builder.set("value", value); featureCollection.add(builder.buildFeature(String.valueOf(i++))); } return featureCollection; }  static SimpleFeatureCollection process(
            GridCoverage2D gc2d,
            Integer band,
            double[] levels,
            Double interval,
            Boolean simplify,
            Boolean smooth,
            Geometry roi,
            ProgressListener progressListener); @DescribeResult( name = "result", description = "Contour line features. Contour level is in value attribute." ) SimpleFeatureCollection execute(
            @DescribeParameter(name = "data", description = "Input raster") GridCoverage2D gc2d,
            @DescribeParameter(
                        name = "band",
                        description = "Band number (zero base) to use for values to be contoured",
                        min = 0,
                        max = 1
                    )
                    Integer band,
            @DescribeParameter(
                        name = "levels",
                        description = "Values of levels at which to generate contours"
                    )
                    double[] levels,
            @DescribeParameter(
                        name = "interval",
                        description =
                                "Interval between contour values (ignored if levels parameter is supplied)",
                        min = 0,
                        minValue = 0
                    )
                    Double interval,
            @DescribeParameter(
                        name = "simplify",
                        description = "Indicates whether contour lines are simplified",
                        min = 0
                    )
                    Boolean simplify,
            @DescribeParameter(
                        name = "smooth",
                        description =
                                "Indicates whether contour lines are smoothed using Bezier smoothing",
                        min = 0
                    )
                    Boolean smooth,
            @DescribeParameter(
                        name = "roi",
                        description =
                                "Geometry delineating the region of interest (in raster coordinate system)",
                        min = 0
                    )
                    Geometry roi,
            ProgressListener progressListener);  }