diff --git a/examples/pom.xml b/examples/pom.xml index 54f777fb5b1..cfa4fc64296 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -24,6 +24,11 @@ geowave-adapter-vector ${project.version} + + mil.nga.giat + geowave-adapter-raster + ${project.version} + com.github.sakserv hadoop-mini-clusters-hbase diff --git a/extensions/adapters/raster/src/main/java/mil/nga/giat/geowave/adapter/raster/RasterUtils.java b/extensions/adapters/raster/src/main/java/mil/nga/giat/geowave/adapter/raster/RasterUtils.java index 221420245be..f853e973043 100644 --- a/extensions/adapters/raster/src/main/java/mil/nga/giat/geowave/adapter/raster/RasterUtils.java +++ b/extensions/adapters/raster/src/main/java/mil/nga/giat/geowave/adapter/raster/RasterUtils.java @@ -690,9 +690,21 @@ private static BufferedImage rescaleImageViaPlanarImage( 0.0f, interpolation); final RenderedOp result = w.getRenderedOperation(); + Raster raster = result.getData(); + final WritableRaster scaledImageRaster; + if (raster instanceof WritableRaster) { + scaledImageRaster = (WritableRaster) raster; + } + else { + scaledImageRaster = raster.createCompatibleWritableRaster(); - final WritableRaster scaledImageRaster = (WritableRaster) result.getData(); - + scaledImageRaster.setDataElements( + 0, + 0, + raster.getWidth(), + raster.getHeight(), + raster.getDataBuffer()); + } final ColorModel colorModel = image.getColorModel(); try { final BufferedImage scaledImage = new BufferedImage( diff --git a/extensions/adapters/vector/pom.xml b/extensions/adapters/vector/pom.xml index 47c72b307cc..835fa7d0a60 100644 --- a/extensions/adapters/vector/pom.xml +++ b/extensions/adapters/vector/pom.xml @@ -75,7 +75,6 @@ org.apache.commons commons-vfs2 - 2.0 junit diff --git a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/GeoToolsRasterDataStoreIngestPlugin.java b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/GeoToolsRasterDataStoreIngestPlugin.java index 86b1e0eb0a7..a83d78714a5 100644 --- a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/GeoToolsRasterDataStoreIngestPlugin.java +++ b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/GeoToolsRasterDataStoreIngestPlugin.java @@ -43,8 +43,7 @@ public class GeoToolsRasterDataStoreIngestPlugin implements LocalFileIngestPlugin { - private final static Logger LOGGER = Logger.getLogger( - GeoToolsRasterDataStoreIngestPlugin.class); + private final static Logger LOGGER = Logger.getLogger(GeoToolsRasterDataStoreIngestPlugin.class); private final RasterOptionProvider optionProvider; public GeoToolsRasterDataStoreIngestPlugin() { @@ -71,8 +70,7 @@ public boolean supportsFile( final File file ) { AbstractGridFormat format = null; try { - format = GridFormatFinder.findFormat( - file); + format = GridFormatFinder.findFormat(file); } catch (final Exception e) { LOGGER.info( @@ -89,24 +87,20 @@ private static AbstractGridFormat prioritizedFindFormat( final File input ) { final AbstractGridFormat format = null; try { - final Set formats = GridFormatFinder.findFormats( - input); + final Set formats = GridFormatFinder.findFormats(input); if ((formats == null) || formats.isEmpty()) { - LOGGER.warn( - "Unable to support raster file " + input.getAbsolutePath()); + LOGGER.warn("Unable to support raster file " + input.getAbsolutePath()); return null; } // world image and geotiff can both open tif files, give // priority to gdalgeotiff, followed by geotiff for (final AbstractGridFormat f : formats) { - if ("GDALGeoTiff".equals( - f.getName())) { + if ("GDALGeoTiff".equals(f.getName())) { return f; } } for (final AbstractGridFormat f : formats) { - if ("GeoTIFF".equals( - f.getName())) { + if ("GeoTIFF".equals(f.getName())) { return f; } } @@ -131,8 +125,7 @@ public CloseableIterator> toGeoWaveData( final File input, final Collection primaryIndexIds, final String globalVisibility ) { - final AbstractGridFormat format = prioritizedFindFormat( - input); + final AbstractGridFormat format = prioritizedFindFormat(input); if (format == null) { return new Wrapper( Collections.emptyIterator()); @@ -140,8 +133,7 @@ public CloseableIterator> toGeoWaveData( Hints hints = null; if ((optionProvider.getCrs() != null) && !optionProvider.getCrs().trim().isEmpty()) { try { - final CoordinateReferenceSystem crs = CRS.decode( - optionProvider.getCrs()); + final CoordinateReferenceSystem crs = CRS.decode(optionProvider.getCrs()); if (crs != null) { hints = new Hints(); hints.put( @@ -156,16 +148,15 @@ public CloseableIterator> toGeoWaveData( } } final GridCoverage2DReader reader = format.getReader( - input, hints); + input, + hints); if (reader == null) { - LOGGER.error( - "Unable to get reader instance, getReader returned null"); + LOGGER.error("Unable to get reader instance, getReader returned null"); return new Wrapper( Collections.emptyIterator()); } try { - final GridCoverage2D coverage = reader.read( - null); + final GridCoverage2D coverage = reader.read(null); if (coverage != null) { final Map metadata = new HashMap(); final String coverageName = coverage.getName().toString(); @@ -173,8 +164,7 @@ public CloseableIterator> toGeoWaveData( // wrapping with try-catch block because often the reader // does not support operations on coverage name // if not, we just don't have metadata, and continue - final String[] mdNames = reader.getMetadataNames( - coverageName); + final String[] mdNames = reader.getMetadataNames(coverageName); if ((mdNames != null) && (mdNames.length > 0)) { for (final String mdName : mdNames) { metadata.put( @@ -195,8 +185,7 @@ public CloseableIterator> toGeoWaveData( if (optionProvider.isSeparateBands() && (coverage.getNumSampleDimensions() > 1)) { final String baseName = optionProvider.getCoverageName() != null ? optionProvider.getCoverageName() : input.getName(); - final double[][] nodata = optionProvider.getNodata( - coverage.getNumSampleDimensions()); + final double[][] nodata = optionProvider.getNodata(coverage.getNumSampleDimensions()); for (int b = 0; b < coverage.getNumSampleDimensions(); b++) { final RasterDataAdapter adapter = new RasterDataAdapter( baseName + "_B" + b, @@ -212,11 +201,10 @@ public CloseableIterator> toGeoWaveData( new double[][] { nodata[b] }); - coverages.add( - new GeoWaveData( - adapter, - primaryIndexIds, - coverage)); + coverages.add(new GeoWaveData( + adapter, + primaryIndexIds, + coverage)); } } else { @@ -228,13 +216,11 @@ public CloseableIterator> toGeoWaveData( optionProvider.getTileSize(), optionProvider.isBuildPyramid(), optionProvider.isBuildHistogream(), - optionProvider.getNodata( - coverage.getNumSampleDimensions())); - coverages.add( - new GeoWaveData( - adapter, - primaryIndexIds, - coverage)); + optionProvider.getNodata(coverage.getNumSampleDimensions())); + coverages.add(new GeoWaveData( + adapter, + primaryIndexIds, + coverage)); } return new Wrapper( coverages.iterator()) { @@ -247,9 +233,8 @@ public void close() }; } else { - LOGGER.warn( - "Null grid coverage from file '" + input.getAbsolutePath() - + "' for discovered geotools format '" + format.getName() + "'"); + LOGGER.warn("Null grid coverage from file '" + input.getAbsolutePath() + + "' for discovered geotools format '" + format.getName() + "'"); } } catch (final IOException e) { diff --git a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/NoDataMergeStrategyProvider.java b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/NoDataMergeStrategyProvider.java new file mode 100644 index 00000000000..1a2d60f7313 --- /dev/null +++ b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/NoDataMergeStrategyProvider.java @@ -0,0 +1,21 @@ +package mil.nga.giat.geowave.format.geotools.raster; + +import mil.nga.giat.geowave.adapter.raster.adapter.merge.RasterTileMergeStrategy; +import mil.nga.giat.geowave.adapter.raster.adapter.merge.nodata.NoDataMergeStrategy; + +public class NoDataMergeStrategyProvider implements + RasterMergeStrategyProviderSpi +{ + public static String NAME = "no-data"; + + @Override + public String getName() { + return NAME; + } + + @Override + public RasterTileMergeStrategy getStrategy() { + return new NoDataMergeStrategy(); + } + +} diff --git a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/NoMergeStrategyProvider.java b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/NoMergeStrategyProvider.java new file mode 100644 index 00000000000..a6d9330cb49 --- /dev/null +++ b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/NoMergeStrategyProvider.java @@ -0,0 +1,20 @@ +package mil.nga.giat.geowave.format.geotools.raster; + +import mil.nga.giat.geowave.adapter.raster.adapter.merge.RasterTileMergeStrategy; + +public class NoMergeStrategyProvider implements + RasterMergeStrategyProviderSpi +{ + public static String NAME = "none"; + + @Override + public String getName() { + return NAME; + } + + @Override + public RasterTileMergeStrategy getStrategy() { + return null; + } + +} diff --git a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterMergeStrategyProviderSpi.java b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterMergeStrategyProviderSpi.java new file mode 100644 index 00000000000..e7589d283c2 --- /dev/null +++ b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterMergeStrategyProviderSpi.java @@ -0,0 +1,10 @@ +package mil.nga.giat.geowave.format.geotools.raster; + +import mil.nga.giat.geowave.adapter.raster.adapter.merge.RasterTileMergeStrategy; + +public interface RasterMergeStrategyProviderSpi +{ + public String getName(); + + public RasterTileMergeStrategy getStrategy(); +} diff --git a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterOptionProvider.java b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterOptionProvider.java index 4e9d5c3ec18..759bf6997f0 100644 --- a/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterOptionProvider.java +++ b/extensions/formats/geotools-raster/src/main/java/mil/nga/giat/geowave/format/geotools/raster/RasterOptionProvider.java @@ -1,38 +1,52 @@ package mil.nga.giat.geowave.format.geotools.raster; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.beust.jcommander.Parameter; import com.beust.jcommander.converters.DoubleConverter; import mil.nga.giat.geowave.adapter.raster.adapter.RasterDataAdapter; +import mil.nga.giat.geowave.adapter.raster.adapter.merge.RasterTileMergeStrategy; import mil.nga.giat.geowave.core.ingest.spi.IngestFormatOptionProvider; public class RasterOptionProvider implements IngestFormatOptionProvider { - + // for now, default to no merging + private static final RasterTileMergeStrategy DEFAULT_MERGE_STRATEGY = null; + private final static Logger LOGGER = LoggerFactory.getLogger(RasterOptionProvider.class); + private static Map registeredMergeStrategies = null; @Parameter(names = "--pyramid", description = "Build an image pyramid on ingest for quick reduced resolution query") - private boolean buildPyramid = false; + private final boolean buildPyramid = false; @Parameter(names = "--crs", description = "A CRS override for the provided raster file") - private String crs = null; - + private final String crs = null; + @Parameter(names = "--histogram", description = "Build a histogram of samples per band on ingest for performing band equalization") - private boolean buildHistogream = false; + private final boolean buildHistogream = false; @Parameter(names = "--tileSize", description = "Optional parameter to set the tile size stored (default is 256)") - private int tileSize = RasterDataAdapter.DEFAULT_TILE_SIZE; + private final int tileSize = RasterDataAdapter.DEFAULT_TILE_SIZE; @Parameter(names = "--coverage", description = "Optional parameter to set the coverage name (default is the file name)") - private String coverageName = null; + private final String coverageName = null; @Parameter(names = "--nodata", variableArity = true, description = "Optional parameter to set 'no data' values, if 1 value is giving it is applied for each band, if multiple are given then the first totalNoDataValues/totalBands are applied to the first band and so on, so each band can have multiple differing 'no data' values if needed", converter = DoubleConverter.class) - private List nodata = new ArrayList<>(); + private final List nodata = new ArrayList<>(); @Parameter(names = "--separateBands", description = "Optional parameter to separate each band into its own coverage name. By default the coverage name will have '_Bn' appended to it where `n` is the band's index.") - private boolean separateBands = false; + private final boolean separateBands = false; + + @Parameter(names = "--mergeStrategy", description = "Optional parameter to choose a tile merge strategy used for mosaic. Default behavior will be `none`. Alternatively 'no-data' will mosaic the most recent tile over previous tiles, except where there are no data values.") + private final String mergeStrategy = NoMergeStrategyProvider.NAME; public RasterOptionProvider() {} @@ -89,4 +103,34 @@ public double[][] getNodata( } return retVal; } + + public RasterTileMergeStrategy getMergeStrategy() { + final Map internalMergeStrategies = getRegisteredMergeStrategies(); + if ((mergeStrategy == null) || mergeStrategy.trim().isEmpty()) { + LOGGER.warn("Merge Strategy not found"); + return DEFAULT_MERGE_STRATEGY; + } + final RasterMergeStrategyProviderSpi provider = internalMergeStrategies.get(mergeStrategy); + if (provider == null) { + LOGGER.warn("Merge Strategy Provider not found for '" + mergeStrategy + "'"); + return DEFAULT_MERGE_STRATEGY; + } + return provider.getStrategy(); + } + + private synchronized Map getRegisteredMergeStrategies() { + if (registeredMergeStrategies == null) { + registeredMergeStrategies = new HashMap(); + final ServiceLoader converters = ServiceLoader + .load(RasterMergeStrategyProviderSpi.class); + final Iterator it = converters.iterator(); + while (it.hasNext()) { + final RasterMergeStrategyProviderSpi converter = it.next(); + registeredMergeStrategies.put( + converter.getName(), + converter); + } + } + return registeredMergeStrategies; + } } diff --git a/extensions/formats/geotools-raster/src/main/resources/META-INF/services/mil.nga.giat.geowave.format.geotools.raster.RasterMergeStrategyProviderSpi b/extensions/formats/geotools-raster/src/main/resources/META-INF/services/mil.nga.giat.geowave.format.geotools.raster.RasterMergeStrategyProviderSpi new file mode 100644 index 00000000000..50107be9e24 --- /dev/null +++ b/extensions/formats/geotools-raster/src/main/resources/META-INF/services/mil.nga.giat.geowave.format.geotools.raster.RasterMergeStrategyProviderSpi @@ -0,0 +1,2 @@ +mil.nga.giat.geowave.format.geotools.raster.NoDataMergeStrategyProvider +mil.nga.giat.geowave.format.geotools.raster.NoMergeStrategyProvider \ No newline at end of file diff --git a/pom.xml b/pom.xml index ea093566f8b..4d8624d44a2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 mil.nga.giat geowave-parent @@ -29,13 +30,14 @@ https://github.com/ngageoint/geowave.git scm:git:https://github.com/ngageoint/geowave.git - v0.9.2.1 - + v0.9.2.1 + 14.2 hadoop2 2.8.2 1.7.2 + 2.1 1.2.1 2.7.2 1.7.6 @@ -345,6 +347,12 @@ jersey-proxy-client ${jersey.version} + + + org.apache.commons + commons-vfs2 + ${vfs2.version} + @@ -729,10 +737,10 @@ maven-release-plugin 2.5.3 - v@{project.version} + v@{project.version} true - +