/** * Creates a {@link GridCoverage} for the provided {@link PlanarImage} using the {@link * #raster2Model} that was provided for this coverage. * * <p>This method is vital when working with coverages that have a raster to model transformation * that is not a simple scale and translate. * * @param coverageName * @param image contains the data for the coverage to create. * @param raster2Model is the {@link MathTransform} that maps from the raster space to the model * space. * @return a {@link GridCoverage} * @throws IOException */ protected final GridCoverage2D createImageCoverage( String coverageName, PlanarImage image, MathTransform raster2Model) throws IOException { // creating bands final SampleModel sm = image.getSampleModel(); final ColorModel cm = image.getColorModel(); final int numBands = sm.getNumBands(); final GridSampleDimension[] bands = new GridSampleDimension[numBands]; // setting bands names. for (int i = 0; i < numBands; i++) { final ColorInterpretation colorInterpretation = TypeMap.getColorInterpretation(cm, i); if (colorInterpretation == null) throw new IOException("Unrecognized sample dimension type"); bands[i] = new GridSampleDimension(colorInterpretation.name()).geophysics(true); } // creating coverage if (raster2Model != null) { return coverageFactory.create( coverageName, image, getCoordinateReferenceSystem(coverageName), raster2Model, bands, null, null); } return coverageFactory.create( coverageName, image, new GeneralEnvelope(getOriginalEnvelope(coverageName)), bands, null, null); }
private GridSampleDimension[] getSampleDimensions(final RenderedImage coverageRaster) throws IOException { GridSampleDimension[] bands = rasterInfo.getGridSampleDimensions(); // may the image have been promoted? build the correct band info then final int imageBands = coverageRaster.getSampleModel().getNumBands(); if (bands.length == 1 && imageBands > 1) { LOGGER.fine( coverageName + " was promoted from 1 to " + coverageRaster.getSampleModel().getNumBands() + " bands, returning an appropriate set of GridSampleDimension"); // stolen from super.createCoverage: final ColorModel cm = coverageRaster.getColorModel(); bands = new GridSampleDimension[imageBands]; // setting bands names. for (int i = 0; i < imageBands; i++) { final ColorInterpretation colorInterpretation; colorInterpretation = TypeMap.getColorInterpretation(cm, i); if (colorInterpretation == null) { throw new IOException("Unrecognized sample dimension type"); } bands[i] = new GridSampleDimension(colorInterpretation.name()).geophysics(true); } } return bands; }
/** * Creates a {@link SimpleFeatureType} that exposes a coverage as a collections of feature points, * mapping the centre of each pixel as a point plus all the bands as attributes. * * <p>The FID is the long that combines x+y*width. * * @param gc2d the {@link GridCoverage2D} to wrap. * @param geometryClass the class for the geometry. * @return a {@link SimpleFeatureType} or <code>null</code> in case we are unable to wrap the * coverage */ public static SimpleFeatureType createFeatureType( final GridCoverage2D gc2d, final Class<? extends Geometry> geometryClass) { // checks Utilities.ensureNonNull("gc2d", gc2d); // building a feature type for this coverage final SimpleFeatureTypeBuilder ftBuilder = new SimpleFeatureTypeBuilder(); ftBuilder.setName(gc2d.getName().toString()); ftBuilder.setNamespaceURI("http://www.geotools.org/"); // CRS ftBuilder.setCRS(gc2d.getCoordinateReferenceSystem2D()); // ftBuilder.setCRS(DefaultEngineeringCRS.GENERIC_2D); // TYPE is as follows the_geom | band ftBuilder.setDefaultGeometry("the_geom"); ftBuilder.add("the_geom", geometryClass); if (!geometryClass.equals(Point.class)) { ftBuilder.add("value", Double.class); } else { // get sample type on bands final GridSampleDimension[] sampleDimensions = gc2d.getSampleDimensions(); for (GridSampleDimension sd : sampleDimensions) { final SampleDimensionType sdType = sd.getSampleDimensionType(); final int dataBuffType = TypeMap.getDataBufferType(sdType); // TODO I think this should be a public utility inside the FeatureUtilities class @SuppressWarnings("rawtypes") final Class bandClass; switch (dataBuffType) { case DataBuffer.TYPE_BYTE: bandClass = Byte.class; break; case DataBuffer.TYPE_DOUBLE: bandClass = Double.class; break; case DataBuffer.TYPE_FLOAT: bandClass = Float.class; break; case DataBuffer.TYPE_INT: bandClass = Integer.class; break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: bandClass = Short.class; break; case DataBuffer.TYPE_UNDEFINED: default: return null; } ftBuilder.add(sd.getDescription().toString(), bandClass); } } return ftBuilder.buildFeatureType(); }
private void handleSampleDimensionType(SampleDimensionType sdType) { // old data dirs upgrading will have this empty if (sdType == null) { // pick the one with the largest domain and be done with it sdType = SampleDimensionType.REAL_64BITS; } final NumberRange<? extends Number> indicativeRange = TypeMap.getRange(sdType); setRange(indicativeRange); }
/** * Creates a {@link GridCoverage} for the provided {@link PlanarImage} using the {@link * #raster2Model} that was provided for this coverage. * * <p>This method is vital when working with coverages that have a raster to model transformation * that is not a simple scale and translate. * * @param image contains the data for the coverage to create. * @param raster2Model is the {@link MathTransform} that maps from the raster space to the model * space. * @return a {@link GridCoverage} * @throws IOException */ protected final GridCoverage2D createCoverage(PlanarImage image, MathTransform raster2Model) throws IOException { // creating bands final SampleModel sm = image.getSampleModel(); final ColorModel cm = image.getColorModel(); final int numBands = sm.getNumBands(); final GridSampleDimension[] bands = new GridSampleDimension[numBands]; // setting bands names. Category noDataCategory = null; final Map<String, Double> properties = new HashMap<String, Double>(); if (!Double.isNaN(noData)) { noDataCategory = new Category( Vocabulary.formatInternational(VocabularyKeys.NODATA), new Color[] {new Color(0, 0, 0, 0)}, NumberRange.create(noData, noData), NumberRange.create(noData, noData)); properties.put("GC_NODATA", new Double(noData)); } Set<String> bandNames = new HashSet<String>(); for (int i = 0; i < numBands; i++) { final ColorInterpretation colorInterpretation = TypeMap.getColorInterpretation(cm, i); if (colorInterpretation == null) throw new IOException("Unrecognized sample dimension type"); Category[] categories = null; if (noDataCategory != null) { categories = new Category[] {noDataCategory}; } String bandName = colorInterpretation.name(); // make sure we create no duplicate band names if (colorInterpretation == ColorInterpretation.UNDEFINED || bandNames.contains(bandName)) { bandName = "Band" + (i + 1); } bands[i] = new GridSampleDimension(bandName, categories, null).geophysics(true); } // creating coverage if (raster2Model != null) { return coverageFactory.create( coverageName, image, crs, raster2Model, bands, null, properties); } return coverageFactory.create( coverageName, image, new GeneralEnvelope(originalEnvelope), bands, null, properties); }
/** * Helper classes for creating {@link DimensionlessAxis} for the most common color models' bands. * * <p>Suypported colorspaces incluse RGBA, GRAY, GRAYA, HSV,HLS, LAB, LUV, IHS, CI_XYZ, CMY(K). * Notice that RGB is not handled here but through a wavelength axis. * * <p>This method returns null if an unsupported {@link ColorModel} is provided. * * @param raster a {@link RenderedImage} implementation from which to extract needed info, usually * {@link ColorModel} and {@link SampleModel}. * @return a {@link DimensionlessAxis} or null if an unsupported {@link ColorModel} is provided. */ public static DimensionlessAxis createFromRenderedImage(final RenderedImage raster) { if (raster == null) throw new IllegalArgumentException("Provided null input image"); final ColorModel cm = raster.getColorModel(); if (cm == null) throw new IllegalArgumentException("Provided input image with null color model"); final SampleModel sm = raster.getSampleModel(); if (sm == null) throw new IllegalArgumentException("Provided input image with null SampleModel"); // get the color interpretation for the three bands final ColorInterpretation firstBandCI = TypeMap.getColorInterpretation(cm, 0); // CMY - CMYK if (firstBandCI == ColorInterpretation.CYAN_BAND) { if (sm.getNumBands() == 3) return new DimensionlessAxis( Arrays.asList("CYAN", "MAGENTA", "YELLOW"), new NameImpl("CMY-AXIS"), new SimpleInternationalString("Axis for CMY bands")); else return new DimensionlessAxis( Arrays.asList("CYAN", "MAGENTA", "YELLOW", "BLACK"), new NameImpl("CMYK-AXIS"), new SimpleInternationalString("Axis for CMYK bands")); } // HSV if (firstBandCI == ColorInterpretation.HUE_BAND) { return new DimensionlessAxis( Arrays.asList("HUE", "SATURATION", "VALUE"), new NameImpl("HSV-AXIS"), new SimpleInternationalString("Axis for HSV bands")); } // RGBA if (firstBandCI == ColorInterpretation.RED_BAND) { return new DimensionlessAxis( Arrays.asList("RED", "GREEN", "BLUE", "ALPHA"), new NameImpl("RGBA-AXIS"), new SimpleInternationalString("Axis for RGBA bands")); } // PALETTE if (firstBandCI == ColorInterpretation.PALETTE_INDEX) return new DimensionlessAxis( Arrays.asList("PALETTE_INDEX"), new NameImpl("PALETTE_INDEX-AXIS"), new SimpleInternationalString("Axis for PALETTE INDEX bands")); // GRAY, GRAY+ALPHA if (firstBandCI == ColorInterpretation.GRAY_INDEX) { if (sm.getNumBands() == 2) return new DimensionlessAxis( Arrays.asList("GRAY", "ALPHA"), new NameImpl("GA-AXIS"), new SimpleInternationalString("Axis for GRAY-ALPHA bands")); else return new DimensionlessAxis( Arrays.asList("GRAY"), new NameImpl("GRAY-AXIS"), new SimpleInternationalString("Axis for GRAY bands")); } final ColorSpace cs = cm.getColorSpace(); // IHS if (cs instanceof IHSColorSpace) return new DimensionlessAxis( Arrays.asList("INTENSITY", "HUE", "SATURATION"), new NameImpl("IHS-AXIS"), new SimpleInternationalString("Axis for IHS bands")); // YCbCr, LUV, LAB, HLS, IEXYZ switch (cs.getType()) { case ColorSpace.TYPE_YCbCr: return new DimensionlessAxis( Arrays.asList("LUMA", "CHROMA-A", "CHROMA-B"), new NameImpl("YCbCr-AXIS"), new SimpleInternationalString("Axis for YCbCr bands")); case ColorSpace.TYPE_Luv: return new DimensionlessAxis( Arrays.asList("LIGHTNESS", "U", "V"), new NameImpl("LUV-AXIS"), new SimpleInternationalString("Axis for LUV bands")); case ColorSpace.TYPE_Lab: return new DimensionlessAxis( Arrays.asList("LIGHTNESS", "A", "B"), new NameImpl("LAB-AXIS"), new SimpleInternationalString("Axis for LAB bands")); case ColorSpace.TYPE_HLS: return new DimensionlessAxis( Arrays.asList("HUE", "LIGHTNESS", "SATURATION"), new NameImpl("HLS-AXIS"), new SimpleInternationalString("Axis for HLS bands")); case ColorSpace.CS_CIEXYZ: return new DimensionlessAxis( Arrays.asList("X", "Y", "Z"), new NameImpl("XYZ-AXIS"), new SimpleInternationalString("Axis for XYZ bands")); default: return null; } }