Search in sources :

Example 1 with AbstractOperation

use of org.geotools.coverage.processing.AbstractOperation in project geowave by locationtech.

the class RasterIngestRunner method processPreviousScene.

@SuppressWarnings({ "rawtypes", "unchecked" })
protected void processPreviousScene() {
    if (!ingestOptions.isCoveragePerBand()) {
        // ingest as single image for all bands
        if (!lastSceneBands.isEmpty()) {
            // we are sorting by band name to ensure a consistent order for
            // bands
            final TreeMap<String, RasterBandData> sceneData = new TreeMap<>();
            Writer writer;
            // get coverage info, ensuring that all coverage names are the
            // same
            String coverageName = null;
            for (final SimpleFeature band : lastSceneBands) {
                RasterBandData bandData;
                try {
                    bandData = getBandData(band);
                    if (coverageName == null) {
                        coverageName = bandData.name;
                    } else if (!coverageName.equals(bandData.name)) {
                        LOGGER.warn("Unable to use band data as the band coverage name '" + bandData.name + "' is unexpectedly different from default name '" + coverageName + "'");
                    }
                    final String bandName = band.getAttribute(BandFeatureIterator.BAND_ATTRIBUTE_NAME).toString();
                    sceneData.put(bandName, bandData);
                } catch (IOException | TemplateException e) {
                    LOGGER.warn("Unable to read band data", e);
                }
            }
            if (coverageName == null) {
                LOGGER.warn("No valid bands found for scene");
                lastSceneBands.clear();
                return;
            }
            final GridCoverage2D mergedCoverage;
            if (sceneData.size() == 1) {
                mergedCoverage = sceneData.firstEntry().getValue().coverage;
            } else {
                final CoverageProcessor processor = CoverageProcessor.getInstance();
                final AbstractOperation op = (AbstractOperation) processor.getOperation("BandMerge");
                final ParameterValueGroup params = op.getParameters();
                final List<GridCoverage2D> sources = new ArrayList<>();
                for (final RasterBandData bandData : sceneData.values()) {
                    sources.add(bandData.coverage);
                }
                params.parameter("Sources").setValue(sources);
                params.parameter(BandMerge.TRANSFORM_CHOICE).setValue(TransformList.FIRST.toString());
                mergedCoverage = (GridCoverage2D) op.doOperation(params, null);
            }
            final String[] thisSceneBands = sceneData.keySet().toArray(new String[] {});
            if (bandsIngested == null) {
                // this means this is the first scene
                // setup adapter and other required info
                final Map<String, String> metadata = new HashMap<>();
                final double[][] noDataValues = new double[sceneData.size()][];
                int b = 0;
                // merge metadata from all readers
                for (final RasterBandData bandData : sceneData.values()) {
                    try {
                        final String[] metadataNames = bandData.reader.getMetadataNames();
                        if ((metadataNames != null) && (metadataNames.length > 0)) {
                            for (final String metadataName : metadataNames) {
                                metadata.put(metadataName, bandData.reader.getMetadataValue(metadataName));
                            }
                        }
                    } catch (final Exception e) {
                        LOGGER.warn("Unable to get metadata for coverage '" + coverageName + "'.", e);
                    }
                    noDataValues[b++] = new double[] { bandData.nodataValue };
                }
                final RasterDataAdapter adapter = new RasterDataAdapter(coverageName, metadata, mergedCoverage, ingestOptions.getTileSize(), ingestOptions.isCreatePyramid(), ingestOptions.isCreateHistogram(), noDataValues, new NoDataMergeStrategy());
                store.addType(adapter, indices);
                writer = store.createWriter(adapter.getTypeName());
                writerCache.put(coverageName, writer);
                bandsIngested = thisSceneBands;
            } else if (!Arrays.equals(bandsIngested, thisSceneBands)) {
                LOGGER.warn("The bands in this scene ('" + Arrays.toString(thisSceneBands) + "') differ from the previous scene ('" + Arrays.toString(bandsIngested) + "').  To merge bands all scenes must use the same bands.  Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.ENTITY_ID_ATTRIBUTE_NAME) + "'.");
                lastSceneBands.clear();
                return;
            } else {
                writer = writerCache.get(coverageName);
                if (writer == null) {
                    LOGGER.warn("Unable to find writer for coverage '" + coverageName + "'.  Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.ENTITY_ID_ATTRIBUTE_NAME) + "'.");
                    lastSceneBands.clear();
                    return;
                }
            }
            writer.write(mergedCoverage);
            lastSceneBands.clear();
        }
    }
}
Also used : GridCoverage2D(org.geotools.coverage.grid.GridCoverage2D) TemplateException(freemarker.template.TemplateException) CoverageProcessor(org.geotools.coverage.processing.CoverageProcessor) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) IOException(java.io.IOException) TreeMap(java.util.TreeMap) SimpleFeature(org.opengis.feature.simple.SimpleFeature) FactoryException(org.opengis.referencing.FactoryException) ParameterException(com.beust.jcommander.ParameterException) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException) TransformException(org.opengis.referencing.operation.TransformException) InvalidParameterValueException(org.opengis.parameter.InvalidParameterValueException) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) TemplateException(freemarker.template.TemplateException) IOException(java.io.IOException) RasterDataAdapter(org.locationtech.geowave.adapter.raster.adapter.RasterDataAdapter) NoDataMergeStrategy(org.locationtech.geowave.adapter.raster.adapter.merge.nodata.NoDataMergeStrategy) AbstractOperation(org.geotools.coverage.processing.AbstractOperation) Writer(org.locationtech.geowave.core.store.api.Writer)

Example 2 with AbstractOperation

use of org.geotools.coverage.processing.AbstractOperation in project geowave by locationtech.

the class RasterIngestRunner method processPreviousScene.

protected void processPreviousScene() {
    if (!ingestOptions.isCoveragePerBand()) {
        // ingest as single image for all bands
        if (!lastSceneBands.isEmpty()) {
            // we are sorting by band name to ensure a consistent order for
            // bands
            final TreeMap<String, BandData> sceneData = new TreeMap<>();
            Writer writer;
            // get coverage info, ensuring that all coverage names are the
            // same
            String coverageName = null;
            for (final SimpleFeature band : lastSceneBands) {
                BandData bandData;
                try {
                    bandData = getBandData(band);
                    if (coverageName == null) {
                        coverageName = bandData.name;
                    } else if (!coverageName.equals(bandData.name)) {
                        LOGGER.warn("Unable to use band data as the band coverage name '" + bandData.name + "' is unexpectedly different from default name '" + coverageName + "'");
                    }
                    final String bandName = band.getAttribute(BandFeatureIterator.BAND_ATTRIBUTE_NAME).toString();
                    sceneData.put(bandName, bandData);
                } catch (IOException | TemplateException e) {
                    LOGGER.warn("Unable to read band data", e);
                }
            }
            if (coverageName == null) {
                LOGGER.warn("No valid bands found for scene");
                lastSceneBands.clear();
                return;
            }
            final GridCoverage2D mergedCoverage;
            if (sceneData.size() == 1) {
                mergedCoverage = sceneData.firstEntry().getValue().coverage;
            } else {
                final CoverageProcessor processor = CoverageProcessor.getInstance();
                final AbstractOperation op = (AbstractOperation) processor.getOperation("BandMerge");
                final ParameterValueGroup params = op.getParameters();
                final List<GridCoverage2D> sources = new ArrayList<>();
                for (final BandData b : sceneData.values()) {
                    sources.add(b.coverage);
                }
                params.parameter("Sources").setValue(sources);
                params.parameter(BandMerge.TRANSFORM_CHOICE).setValue(TransformList.FIRST.toString());
                mergedCoverage = (GridCoverage2D) op.doOperation(params, null);
            }
            final String[] thisSceneBands = sceneData.keySet().toArray(new String[] {});
            if (bandsIngested == null) {
                // this means this is the first scene
                // setup adapter and other required info
                final Map<String, String> metadata = new HashMap<>();
                // merge metadata from all readers
                for (final BandData b : sceneData.values()) {
                    final String[] mdNames = b.reader.getMetadataNames();
                    if ((mdNames != null) && (mdNames.length > 0)) {
                        for (final String mdName : mdNames) {
                            metadata.put(mdName, b.reader.getMetadataValue(mdName));
                        }
                    }
                }
                final double[][] noDataValues = new double[sceneData.size()][];
                int b = 0;
                for (final String bandName : sceneData.keySet()) {
                    noDataValues[b++] = new double[] { getNoDataValueFromName(bandName) };
                }
                final RasterDataAdapter adapter = new RasterDataAdapter(coverageName, metadata, mergedCoverage, ingestOptions.getTileSize(), ingestOptions.isCreatePyramid(), ingestOptions.isCreateHistogram(), noDataValues, new NoDataMergeStrategy());
                store.addType(adapter, indices);
                writer = store.createWriter(adapter.getTypeName());
                writerCache.put(coverageName, writer);
                bandsIngested = thisSceneBands;
            } else if (!Arrays.equals(bandsIngested, thisSceneBands)) {
                LOGGER.warn("The bands in this scene ('" + Arrays.toString(thisSceneBands) + "') differ from the previous scene ('" + Arrays.toString(bandsIngested) + "').  To merge bands all scenes must use the same bands.  Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.PRODUCT_ID_ATTRIBUTE_NAME) + "'.");
                lastSceneBands.clear();
                return;
            } else {
                writer = writerCache.get(coverageName);
                if (writer == null) {
                    LOGGER.warn("Unable to find writer for coverage '" + coverageName + "'.  Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.PRODUCT_ID_ATTRIBUTE_NAME) + "'.");
                    lastSceneBands.clear();
                    return;
                }
            }
            writer.write(mergedCoverage);
            lastSceneBands.clear();
            if (!ingestOptions.isRetainImages()) {
                for (final BandData b : sceneData.values()) {
                    if (!b.geotiffFile.delete()) {
                        LOGGER.warn("Unable to delete '" + b.geotiffFile.getAbsolutePath() + "'");
                    }
                }
            }
        }
    }
}
Also used : GridCoverage2D(org.geotools.coverage.grid.GridCoverage2D) TemplateException(freemarker.template.TemplateException) CoverageProcessor(org.geotools.coverage.processing.CoverageProcessor) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) IOException(java.io.IOException) TreeMap(java.util.TreeMap) SimpleFeature(org.opengis.feature.simple.SimpleFeature) RasterDataAdapter(org.locationtech.geowave.adapter.raster.adapter.RasterDataAdapter) NoDataMergeStrategy(org.locationtech.geowave.adapter.raster.adapter.merge.nodata.NoDataMergeStrategy) AbstractOperation(org.geotools.coverage.processing.AbstractOperation) Writer(org.locationtech.geowave.core.store.api.Writer)

Example 3 with AbstractOperation

use of org.geotools.coverage.processing.AbstractOperation in project geowave by locationtech.

the class RasterIngestRunner method getBandData.

protected BandData getBandData(final SimpleFeature band) throws IOException, TemplateException {
    final Map<String, Object> model = new HashMap<>();
    final SimpleFeatureType type = band.getFeatureType();
    for (final AttributeDescriptor attr : type.getAttributeDescriptors()) {
        final String attrName = attr.getLocalName();
        final Object attrValue = band.getAttribute(attrName);
        if (attrValue != null) {
            model.put(attrName, attrValue);
        }
    }
    final String coverageName = FreeMarkerTemplateUtils.processTemplateIntoString(coverageNameTemplate, model);
    final File geotiffFile = DownloadRunner.getDownloadFile(band, landsatOptions.getWorkspaceDir());
    final GDALGeoTiffReader reader = new GDALGeoTiffReader(geotiffFile);
    GridCoverage2D coverage = reader.read(null);
    reader.dispose();
    if ((ingestOptions.getCoverageConverter() != null) && !ingestOptions.getCoverageConverter().trim().isEmpty()) {
        // a converter was supplied, attempt to use it
        final Landsat8BandConverterSpi converter = getConverter(ingestOptions.getCoverageConverter());
        if (converter != null) {
            coverage = converter.convert(coverageName, coverage, band);
        }
    }
    if (ingestOptions.isSubsample()) {
        coverage = (GridCoverage2D) RasterUtils.getCoverageOperations().filteredSubsample(coverage, ingestOptions.getScale(), ingestOptions.getScale(), null);
    }
    // its unclear whether cropping should be done first or subsampling
    if (ingestOptions.isCropToSpatialConstraint()) {
        boolean cropped = false;
        final Filter filter = landsatOptions.getCqlFilter();
        if (filter != null) {
            final ExtractGeometryFilterVisitorResult geometryAndCompareOp = ExtractGeometryFilterVisitor.getConstraints(filter, GeometryUtils.getDefaultCRS(), SceneFeatureIterator.SHAPE_ATTRIBUTE_NAME);
            Geometry geometry = geometryAndCompareOp.getGeometry();
            if (geometry != null) {
                // go ahead and intersect this with the scene geometry
                final Geometry sceneShape = (Geometry) band.getAttribute(SceneFeatureIterator.SHAPE_ATTRIBUTE_NAME);
                if (geometry.contains(sceneShape)) {
                    cropped = true;
                } else {
                    geometry = geometry.intersection(sceneShape);
                    final CoverageProcessor processor = CoverageProcessor.getInstance();
                    final AbstractOperation op = (AbstractOperation) processor.getOperation("CoverageCrop");
                    final ParameterValueGroup params = op.getParameters();
                    params.parameter("Source").setValue(coverage);
                    try {
                        final MathTransform transform = CRS.findMathTransform(GeometryUtils.getDefaultCRS(), coverage.getCoordinateReferenceSystem(), true);
                        params.parameter(Crop.CROP_ROI.getName().getCode()).setValue(JTS.transform(geometry, transform));
                        final double nodataValue = getNoDataValue(band);
                        params.parameter(Crop.NODATA.getName().getCode()).setValue(RangeFactory.create(nodataValue, nodataValue));
                        params.parameter(Crop.DEST_NODATA.getName().getCode()).setValue(new double[] { nodataValue });
                        coverage = (GridCoverage2D) op.doOperation(params, null);
                        cropped = true;
                    } catch (InvalidParameterValueException | ParameterNotFoundException | FactoryException | MismatchedDimensionException | TransformException e) {
                        LOGGER.warn("Unable to crop image", e);
                    }
                }
            }
            if (!cropped) {
                LOGGER.warn("Option to crop spatially was set but no spatial constraints were provided in CQL expression");
            }
        }
    }
    return new BandData(coverageName, coverage, reader, geotiffFile);
}
Also used : MathTransform(org.opengis.referencing.operation.MathTransform) HashMap(java.util.HashMap) CoverageProcessor(org.geotools.coverage.processing.CoverageProcessor) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) FactoryException(org.opengis.referencing.FactoryException) AttributeDescriptor(org.opengis.feature.type.AttributeDescriptor) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) InvalidParameterValueException(org.opengis.parameter.InvalidParameterValueException) ExtractGeometryFilterVisitorResult(org.locationtech.geowave.core.geotime.util.ExtractGeometryFilterVisitorResult) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException) GridCoverage2D(org.geotools.coverage.grid.GridCoverage2D) TransformException(org.opengis.referencing.operation.TransformException) GDALGeoTiffReader(org.locationtech.geowave.adapter.raster.plugin.gdal.GDALGeoTiffReader) Geometry(org.locationtech.jts.geom.Geometry) AbstractOperation(org.geotools.coverage.processing.AbstractOperation) SimpleFeatureType(org.opengis.feature.simple.SimpleFeatureType) Filter(org.opengis.filter.Filter) File(java.io.File)

Example 4 with AbstractOperation

use of org.geotools.coverage.processing.AbstractOperation in project geowave by locationtech.

the class RasterIngestRunner method getBandData.

protected RasterBandData getBandData(final SimpleFeature band) throws IOException, TemplateException {
    final Map<String, Object> model = new HashMap<>();
    final SimpleFeatureType type = band.getFeatureType();
    for (final AttributeDescriptor descriptor : type.getAttributeDescriptors()) {
        final String name = descriptor.getLocalName();
        final Object value = band.getAttribute(name);
        if (value != null) {
            model.put(name, value);
        }
    }
    final String coverageName = FreeMarkerTemplateUtils.processTemplateIntoString(coverageNameTemplate, model);
    final RasterBandData bandData = provider.getCoverage(band, sentinel2Options.getWorkspaceDir());
    GridCoverage2D coverage = bandData.coverage;
    final GridCoverageReader reader = bandData.reader;
    final double nodataValue = bandData.nodataValue;
    if ((ingestOptions.getCoverageConverter() != null) && !ingestOptions.getCoverageConverter().trim().isEmpty()) {
        // a converter was supplied, attempt to use it
        final Sentinel2BandConverterSpi converter = getConverter(ingestOptions.getCoverageConverter());
        if (converter != null) {
            coverage = converter.convert(coverageName, coverage, band);
        }
    }
    if (ingestOptions.isSubsample()) {
        coverage = (GridCoverage2D) RasterUtils.getCoverageOperations().filteredSubsample(coverage, ingestOptions.getScale(), ingestOptions.getScale(), null);
    }
    // its unclear whether cropping should be done first or subsampling
    if (ingestOptions.isCropToSpatialConstraint()) {
        boolean cropped = false;
        final Filter filter = sentinel2Options.getCqlFilter();
        if (filter != null) {
            final ExtractGeometryFilterVisitorResult geometryAndCompareOp = ExtractGeometryFilterVisitor.getConstraints(filter, GeoWaveGTRasterFormat.DEFAULT_CRS, SceneFeatureIterator.SHAPE_ATTRIBUTE_NAME);
            Geometry geometry = geometryAndCompareOp.getGeometry();
            if (geometry != null) {
                // go ahead and intersect this with the scene geometry
                final Geometry sceneShape = (Geometry) band.getAttribute(SceneFeatureIterator.SHAPE_ATTRIBUTE_NAME);
                if (geometry.contains(sceneShape)) {
                    cropped = true;
                } else {
                    geometry = geometry.intersection(sceneShape);
                    final CoverageProcessor processor = CoverageProcessor.getInstance();
                    final AbstractOperation op = (AbstractOperation) processor.getOperation("CoverageCrop");
                    final ParameterValueGroup params = op.getParameters();
                    params.parameter("Source").setValue(coverage);
                    try {
                        final MathTransform transform = CRS.findMathTransform(GeometryUtils.getDefaultCRS(), coverage.getCoordinateReferenceSystem(), true);
                        params.parameter(Crop.CROP_ROI.getName().getCode()).setValue(JTS.transform(geometry, transform));
                        params.parameter(Crop.NODATA.getName().getCode()).setValue(RangeFactory.create(nodataValue, nodataValue));
                        params.parameter(Crop.DEST_NODATA.getName().getCode()).setValue(new double[] { nodataValue });
                        coverage = (GridCoverage2D) op.doOperation(params, null);
                        cropped = true;
                    } catch (InvalidParameterValueException | ParameterNotFoundException | FactoryException | MismatchedDimensionException | TransformException e) {
                        LOGGER.warn("Unable to crop image", e);
                    }
                }
            }
            if (!cropped) {
                LOGGER.warn("Option to crop spatially was set but no spatial constraints were provided in CQL expression");
            }
        }
    }
    return new RasterBandData(coverageName, coverage, reader, nodataValue);
}
Also used : MathTransform(org.opengis.referencing.operation.MathTransform) HashMap(java.util.HashMap) CoverageProcessor(org.geotools.coverage.processing.CoverageProcessor) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) FactoryException(org.opengis.referencing.FactoryException) GridCoverageReader(org.opengis.coverage.grid.GridCoverageReader) AttributeDescriptor(org.opengis.feature.type.AttributeDescriptor) MismatchedDimensionException(org.opengis.geometry.MismatchedDimensionException) InvalidParameterValueException(org.opengis.parameter.InvalidParameterValueException) ExtractGeometryFilterVisitorResult(org.locationtech.geowave.core.geotime.util.ExtractGeometryFilterVisitorResult) ParameterNotFoundException(org.opengis.parameter.ParameterNotFoundException) GridCoverage2D(org.geotools.coverage.grid.GridCoverage2D) TransformException(org.opengis.referencing.operation.TransformException) Geometry(org.locationtech.jts.geom.Geometry) AbstractOperation(org.geotools.coverage.processing.AbstractOperation) SimpleFeatureType(org.opengis.feature.simple.SimpleFeatureType) Filter(org.opengis.filter.Filter)

Aggregations

HashMap (java.util.HashMap)4 GridCoverage2D (org.geotools.coverage.grid.GridCoverage2D)4 AbstractOperation (org.geotools.coverage.processing.AbstractOperation)4 CoverageProcessor (org.geotools.coverage.processing.CoverageProcessor)4 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)4 MismatchedDimensionException (org.opengis.geometry.MismatchedDimensionException)3 InvalidParameterValueException (org.opengis.parameter.InvalidParameterValueException)3 ParameterNotFoundException (org.opengis.parameter.ParameterNotFoundException)3 FactoryException (org.opengis.referencing.FactoryException)3 TransformException (org.opengis.referencing.operation.TransformException)3 TemplateException (freemarker.template.TemplateException)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 TreeMap (java.util.TreeMap)2 RasterDataAdapter (org.locationtech.geowave.adapter.raster.adapter.RasterDataAdapter)2 NoDataMergeStrategy (org.locationtech.geowave.adapter.raster.adapter.merge.nodata.NoDataMergeStrategy)2 ExtractGeometryFilterVisitorResult (org.locationtech.geowave.core.geotime.util.ExtractGeometryFilterVisitorResult)2 Writer (org.locationtech.geowave.core.store.api.Writer)2 Geometry (org.locationtech.jts.geom.Geometry)2 SimpleFeature (org.opengis.feature.simple.SimpleFeature)2