Search in sources :

Example 1 with RectifiedGrid

use of org.opengis.coverage.grid.RectifiedGrid in project geotoolkit by Geomatys.

the class TiffImageReader method createMetadata.

/**
 * {@inheritDoc }.
 */
@Override
protected SpatialMetadata createMetadata(final int imageIndex) throws IOException {
    if (imageIndex < 0) {
        // stream metadata
        return super.createMetadata(imageIndex);
    }
    checkLayers();
    final int layerIndex = getLayerIndex(imageIndex);
    if (metaHeads[layerIndex] == null) {
        selectLayer(layerIndex);
    }
    headProperties = metaHeads[layerIndex];
    fillRootMetadataNode(layerIndex);
    // -- find geotiff extensions
    if (extensions == null) {
        extensions = Collections.unmodifiableList(Arrays.stream(GeoTiffExtension.getExtensions()).filter(ext -> ext.isPresent(input)).map(GeoTiffExtension::newInstance).collect(Collectors.toList()));
    }
    final IIOTiffMetadata metadata = new IIOTiffMetadata(roots[layerIndex]);
    final GeoTiffMetaDataReader metareader = new GeoTiffMetaDataReader(metadata);
    SpatialMetadata spatialMetadata;
    /*
         * We'll try to fill referencing information from GeoTiff file. If it
         * fails, we delay error, because there's a chance that one of the
         * declared extensions is able to provide it. For example, user could
         * have provided prj and tfw file, transforming the geotiff in a world
         * file tiff image.
         */
    FactoryException referencingError = null;
    try {
        spatialMetadata = metareader.readSpatialMetaData();
    } catch (FactoryException ex) {
        if (extensions.isEmpty()) {
            throw new IOException("Bad referencing information found in GeoTiff", ex);
        }
        LOGGER.log(Level.WARNING, "Bad referencing information found. We'll continue and try to check on potential extensions (Dimap, Worldd file, etc.)", ex);
        spatialMetadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(SpatialMetadataFormat.GEOTK_FORMAT_NAME));
        // Even if geographic information is bad, we try to get other metadata, as it could be important for data description.
        new ThirdPartyMetaDataReader(metadata).fillSpatialMetaData(spatialMetadata);
    }
    // -- fill extensions informations
    for (GeoTiffExtension ext : extensions) {
        spatialMetadata = ext.fillSpatialMetaData(this, spatialMetadata);
    }
    final CoordinateReferenceSystem crs = spatialMetadata.getInstanceForType(CoordinateReferenceSystem.class);
    final RectifiedGrid rectifiedGrid = spatialMetadata.getInstanceForType(RectifiedGrid.class);
    if ((crs == null || rectifiedGrid == null) && referencingError != null) {
        // Geotiff referencing is bad, and no extension allowed for proper correction, so we stop reading immediately.
        throw new IOException("Bad referencing information found", referencingError);
    }
    // -- search for the coordinate reference system
    if (crs == null) {
        LOGGER.log(Level.FINE, "Current data : " + input.toString() + " doesn't contain any Coordinate Reference System.");
    }
    // -- verify GridToCrs pertinency
    if (rectifiedGrid == null) {
        LOGGER.log(Level.FINE, "Current data : " + input.toString() + " doesn't contain any Tie Points or GridToCrs transformation function.");
    }
    return spatialMetadata;
}
Also used : GeoTiffMetaDataReader(org.geotoolkit.metadata.geotiff.GeoTiffMetaDataReader) SpatialMetadata(org.geotoolkit.image.io.metadata.SpatialMetadata) FactoryException(org.opengis.util.FactoryException) GeoTiffExtension(org.geotoolkit.metadata.geotiff.GeoTiffExtension) RectifiedGrid(org.opengis.coverage.grid.RectifiedGrid) IIOException(javax.imageio.IIOException) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) ThirdPartyMetaDataReader(org.geotoolkit.metadata.geotiff.ThirdPartyMetaDataReader) SystemOverride(org.geotoolkit.lang.SystemOverride)

Example 2 with RectifiedGrid

use of org.opengis.coverage.grid.RectifiedGrid in project geotoolkit by Geomatys.

the class AsciiGridWriter method prepareHeader.

/**
 * Fills the given {@code header} map with values extracted from the given image metadata.
 * The {@code "NCOLS"} and {@code "NROWS"} attributes are already defined when this method
 * is invoked. This method is responsible for filling the remaining attributes.
 *
 * @param  metadata The metadata.
 * @param  header The map in which to store the (<var>key</var>, <var>value</var>) pairs
 *         to be written.
 * @return The fill value, or {@code Double#NaN} if none.
 * @throws IOException If the metadata can not be prepared.
 */
private String prepareHeader(final SpatialMetadata metadata, final Map<String, String> header, final ImageWriteParam param) throws IOException {
    final MetadataHelper helper = new MetadataHelper(this);
    final Georectified spatialRp = metadata.getInstanceForType(Georectified.class);
    final RectifiedGrid domain = metadata.getInstanceForType(RectifiedGrid.class);
    final PixelOrientation ptInPixel = (spatialRp != null) ? spatialRp.getPointInPixel() : null;
    final AffineTransform gridToCRS = helper.getAffineTransform(domain, param);
    String xll = "XLLCORNER";
    String yll = "YLLCORNER";
    // reverted (i.e. the corresponding value in OffsetVectors is negative).
    if (ptInPixel != null && !ptInPixel.equals(PixelOrientation.UPPER_LEFT)) {
        if (ptInPixel.equals(PixelOrientation.CENTER)) {
            xll = "XLLCENTER";
            yll = "YLLCENTER";
        } else if (ptInPixel.equals(PixelOrientation.valueOf("UPPER"))) {
            yll = "YLLCENTER";
        } else if (ptInPixel.equals(PixelOrientation.valueOf("LEFT"))) {
            xll = "XLLCENTER";
        } else {
            throw new ImageMetadataException(Warnings.message(this, Errors.Keys.IllegalParameterValue_2, "pointInPixel", ptInPixel));
        }
    }
    header.put(xll, String.valueOf(gridToCRS.getTranslateX()));
    header.put(yll, String.valueOf(gridToCRS.getTranslateY()));
    /*
         * Use the CELLSIZE attribute if the pixels are square, or the DX, DY attibutes
         * if they are rectangular and we are allowed to use those non-standard attributes.
         */
    try {
        header.put("CELLSIZE", String.valueOf(helper.getCellSize(gridToCRS)));
    } catch (IIOException e) {
        final Dimension2D size;
        if (strictCellSize || (size = helper.getCellDimension(gridToCRS)) == null) {
            throw e;
        }
        Warnings.log(this, null, AsciiGridWriter.class, "writeHeader", e);
        header.put("DX", String.valueOf(size.getWidth()));
        header.put("DY", String.valueOf(size.getHeight()));
    }
    /*
         * Get the fill sample value, which is optional. The default defined by
         * the ASCII grid format is -9999.
         */
    String fillValue = DEFAULT_FILL;
    final List<SampleDimension> dimensions = metadata.getListForType(SampleDimension.class);
    if (!isNullOrEmpty(dimensions)) {
        final SampleDimension dim = dimensions.get(0);
        if (dim != null) {
            final double[] fillValues = dim.getFillSampleValues();
            if (fillValues != null && fillValues.length != 0) {
                final double value = fillValues[0];
                if (!Double.isNaN(value)) {
                    fillValue = CharSequences.trimFractionalPart(String.valueOf(value)).toString();
                    header.put("NODATA_VALUE", fillValue);
                }
            }
        }
    }
    return fillValue;
}
Also used : PixelOrientation(org.opengis.metadata.spatial.PixelOrientation) Dimension2D(java.awt.geom.Dimension2D) IIOException(javax.imageio.IIOException) Georectified(org.opengis.metadata.spatial.Georectified) SampleDimension(org.geotoolkit.image.io.metadata.SampleDimension) MetadataHelper(org.geotoolkit.image.io.metadata.MetadataHelper) RectifiedGrid(org.opengis.coverage.grid.RectifiedGrid) AffineTransform(java.awt.geom.AffineTransform) ImageMetadataException(org.geotoolkit.image.io.ImageMetadataException)

Example 3 with RectifiedGrid

use of org.opengis.coverage.grid.RectifiedGrid in project geotoolkit by Geomatys.

the class ImageCoverageReader method getGridGeometry.

/**
 * Returns the grid geometry for the {@link GridCoverage2D} to be read at the given index.
 * The default implementation performs the following:
 * <p>
 * <ul>
 *   <li>The {@link GridExtent} is determined from the
 *       {@linkplain SpatialImageReader#getGridEnvelope(int) spatial image reader}
 *       if possible, or from the image {@linkplain ImageReader#getWidth(int) width}
 *       and {@linkplain ImageReader#getHeight(int) height} otherwise.</li>
 *   <li>The {@link CoordinateReferenceSystem} and the "<cite>grid to CRS</cite>" conversion
 *       are determined from the {@link SpatialMetadata} if any.</li>
 * </ul>
 *
 * @return The grid geometry for the {@link GridCoverage} at the specified index.
 * @throws IllegalStateException If the input source has not been set.
 * @throws IndexOutOfBoundsException If the supplied index is out of bounds.
 * @throws CoverageStoreException If an error occurs while reading the information from the input source.
 * @throws CancellationException If {@link #abort()} has been invoked in an other thread during
 *         the execution of this method.
 *
 * @see ImageReader#getWidth(int)
 * @see ImageReader#getHeight(int)
 */
public GridGeometry getGridGeometry() throws DataStoreException {
    final int index = 0;
    GridGeometry gridGeometry = getCached(gridGeometries, index);
    if (gridGeometry == null) {
        // Protect from changes.
        final ImageReader imageReader = this.imageReader;
        if (imageReader == null) {
            throw new IllegalStateException(formatErrorMessage(Errors.Keys.NoImageInput));
        }
        /*
             * Get the required information from the SpatialMetadata, if any.
             * For now we just collect them - they will be processed later.
             */
        CoordinateReferenceSystem crs = null;
        MathTransform gridToCRS = null;
        PixelOrientation pointInPixel = null;
        final int width, height;
        try {
            width = imageReader.getWidth(index);
            height = imageReader.getHeight(index);
            final SpatialMetadata metadata = getImageMetadata(imageReader, index);
            if (metadata != null) {
                crs = metadata.getInstanceForType(CoordinateReferenceSystem.class);
                if (crs == null) {
                    crs = PredefinedCRS.GRID_2D;
                }
                if (crs instanceof GridGeometry) {
                    // Some formats (e.g. NetCDF) do that.
                    gridToCRS = ((GridGeometry) crs).getGridToCRS(PixelInCell.CELL_CENTER);
                } else {
                    final RectifiedGrid grid = metadata.getInstanceForType(RectifiedGrid.class);
                    if (grid != null) {
                        gridToCRS = getMetadataHelper().getGridToCRS(grid);
                    }
                    final Georectified georect = metadata.getInstanceForType(Georectified.class);
                    if (georect != null) {
                        pointInPixel = georect.getPointInPixel();
                    }
                }
            }
        } catch (IOException e) {
            throw new CoverageStoreException(formatErrorMessage(e), e);
        }
        /*
             * If any metadata are still null, replace them by their default values. Those default
             * values are selected in order to be as neutral as possible: An ImageCRS which is not
             * convertible to GeodeticCRS, an identity "grid to CRS" conversion, a PixelOrientation
             * equivalent to performing no shift at all in the "grid to CRS" conversion.
             */
        if (crs == null) {
            crs = PredefinedCRS.GRID_2D;
        }
        final int dimension = crs.getCoordinateSystem().getDimension();
        if (gridToCRS == null) {
            gridToCRS = MathTransforms.identity(dimension);
        }
        if (pointInPixel == null) {
            pointInPixel = PixelOrientation.CENTER;
        }
        /*
             * Now build the grid geometry. Note that the grid extent spans shall be set to 1
             * for all dimensions other than X and Y, even if the original file has more data,
             * since this is a GridGeometry2D requirement.
             */
        final long[] lower = new long[dimension];
        final long[] upper = new long[dimension];
        Arrays.fill(upper, 1);
        upper[X_DIMENSION] = width;
        upper[Y_DIMENSION] = height;
        final GridExtent gridExtent = new GridExtent(null, lower, upper, false);
        final PixelInCell pixelInCell = pointInPixel == PixelOrientation.CENTER ? PixelInCell.CELL_CENTER : PixelInCell.CELL_CORNER;
        gridGeometry = new GridGeometry(gridExtent, pixelInCell, gridToCRS, crs);
        Map.Entry<Map<Integer, GridGeometry>, GridGeometry> entry = setCached(gridGeometry, gridGeometries, index);
        gridGeometries = entry.getKey();
        gridGeometry = entry.getValue();
    }
    return gridGeometry;
}
Also used : PixelOrientation(org.opengis.metadata.spatial.PixelOrientation) GridGeometry(org.apache.sis.coverage.grid.GridGeometry) GridExtent(org.apache.sis.coverage.grid.GridExtent) MathTransform(org.opengis.referencing.operation.MathTransform) SpatialMetadata(org.geotoolkit.image.io.metadata.SpatialMetadata) IOException(java.io.IOException) Georectified(org.opengis.metadata.spatial.Georectified) PixelInCell(org.opengis.referencing.datum.PixelInCell) RectifiedGrid(org.opengis.coverage.grid.RectifiedGrid) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) ImageReader(javax.imageio.ImageReader) SpatialImageReader(org.geotoolkit.image.io.SpatialImageReader) Map(java.util.Map) HashMap(java.util.HashMap)

Example 4 with RectifiedGrid

use of org.opengis.coverage.grid.RectifiedGrid in project geotoolkit by Geomatys.

the class MetadataHelperTest method testUniformTransform.

/**
 * Same as {@link #testAffineTransform}, but with a uniform scale.
 *
 * @throws ImageMetadataException Should not happen.
 */
@Test
public void testUniformTransform() throws ImageMetadataException {
    // Creates a simple metadata.
    final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
    final GridDomainAccessor accessor = new GridDomainAccessor(metadata);
    accessor.setOrigin(-10, -20);
    accessor.addOffsetVector(4, 0);
    accessor.addOffsetVector(0, -4);
    // Tests the metadata.
    final MetadataHelper hlp = new MetadataHelper(this);
    final RectifiedGrid grid = metadata.getInstanceForType(RectifiedGrid.class);
    final AffineTransform tr = hlp.getAffineTransform(grid, null);
    assertEquals(-10, tr.getTranslateX(), EPS);
    assertEquals(-20, tr.getTranslateY(), EPS);
    assertEquals(4, tr.getScaleX(), EPS);
    assertEquals(-4, tr.getScaleY(), EPS);
    assertEquals(0, tr.getShearX(), EPS);
    assertEquals(0, tr.getShearY(), EPS);
    assertEquals(4, hlp.getCellSize(tr), EPS);
    assertEquals(new DoubleDimension2D(4, 4), hlp.getCellDimension(tr));
    assertEquals("4", hlp.formatCellDimension(grid, null));
}
Also used : RectifiedGrid(org.opengis.coverage.grid.RectifiedGrid) AffineTransform(java.awt.geom.AffineTransform) GridDomainAccessor(org.geotoolkit.internal.image.io.GridDomainAccessor) DoubleDimension2D(org.geotoolkit.display.shape.DoubleDimension2D)

Example 5 with RectifiedGrid

use of org.opengis.coverage.grid.RectifiedGrid in project geotoolkit by Geomatys.

the class SpatialMetadataTest method testRectifiedGrid.

/**
 * Tests the {@link SpatialMetadata#getInstanceForType} method for an {@link RectifiedGrid}
 * metadata.
 */
@Test
public void testRectifiedGrid() {
    final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
    /*
         * Write a few data using the accessor.
         */
    final int[] limitsLow = new int[] { 4, 10, 16 };
    final int[] limitsHigh = new int[] { 6, 2, 8 };
    final double[] vector0 = new double[] { 2, 5, 8 };
    final double[] vector1 = new double[] { 3, 1, 4 };
    MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null, "RectifiedGridDomain/Limits", null);
    accessor.setAttribute("low", limitsLow);
    accessor.setAttribute("high", limitsHigh);
    accessor = new MetadataNodeAccessor(metadata, null, "RectifiedGridDomain/OffsetVectors", "OffsetVector");
    accessor.selectChild(accessor.appendChild());
    accessor.setAttribute("values", vector0);
    accessor.selectChild(accessor.appendChild());
    accessor.setAttribute("values", vector1);
    /*
         * Read the RectifiedGrid metadata.
         */
    final RectifiedGrid grid = metadata.getInstanceForType(RectifiedGrid.class);
    final GridEnvelope ge = grid.getExtent();
    // assertArrayEquals(limitsLow,  ge.getLow ().getCoordinateValues());
    // assertArrayEquals(limitsHigh, ge.getHigh().getCoordinateValues());
    final List<double[]> vectors = grid.getOffsetVectors();
    assertEquals(2, vectors.size());
    assertTrue(Arrays.equals(vector0, vectors.get(0)));
    assertTrue(Arrays.equals(vector1, vectors.get(1)));
}
Also used : GridEnvelope(org.opengis.coverage.grid.GridEnvelope) RectifiedGrid(org.opengis.coverage.grid.RectifiedGrid)

Aggregations

RectifiedGrid (org.opengis.coverage.grid.RectifiedGrid)12 AffineTransform (java.awt.geom.AffineTransform)6 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)5 SpatialMetadata (org.geotoolkit.image.io.metadata.SpatialMetadata)4 GridDomainAccessor (org.geotoolkit.internal.image.io.GridDomainAccessor)4 IIOException (javax.imageio.IIOException)3 MetadataHelper (org.geotoolkit.image.io.metadata.MetadataHelper)3 Georectified (org.opengis.metadata.spatial.Georectified)3 PixelOrientation (org.opengis.metadata.spatial.PixelOrientation)3 GeneralDirectPosition (org.apache.sis.geometry.GeneralDirectPosition)2 ImageMetadataException (org.geotoolkit.image.io.ImageMetadataException)2 GridEnvelope (org.opengis.coverage.grid.GridEnvelope)2 MathTransform (org.opengis.referencing.operation.MathTransform)2 Dimension2D (java.awt.geom.Dimension2D)1 Point2D (java.awt.geom.Point2D)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1