Search in sources :

Example 1 with PixelInCell

use of org.opengis.referencing.datum.PixelInCell in project geotoolkit by Geomatys.

the class GridToEnvelopeMapper method createTransform.

/**
 * Creates a <cite>Grid to Envelope</cite> (or <cite>grid to CRS</cite>) transform using
 * the information provided by setter methods. The default implementation returns an instance
 * of {@link LinearTransform}, but subclasses could create more complex transforms.
 *
 * @return The <cite>grid to CRS</cite> transform.
 * @throws IllegalStateException if the grid envelope or the georeferenced envelope were not set.
 */
public MathTransform createTransform() throws IllegalStateException {
    if (transform == null) {
        final GridExtent gridEnvelope = getGridExtent();
        final Envelope userEnvelope = getEnvelope();
        final boolean swapXY = getSwapXY();
        final boolean[] reverse = getReverseAxis();
        final PixelInCell gridType = getPixelAnchor();
        final int dimension = gridEnvelope.getDimension();
        /*
             * Setup the multi-dimensional affine transform for use with OpenGIS.
             * According OpenGIS specification, transforms must map pixel center.
             * This is done by adding 0.5 to grid coordinates.
             */
        final double translate;
        if (PixelInCell.CELL_CENTER.equals(gridType)) {
            translate = 0.5;
        } else if (PixelInCell.CELL_CORNER.equals(gridType)) {
            translate = 0.0;
        } else {
            throw new IllegalStateException(Errors.format(Errors.Keys.IllegalArgument_2, "gridType", gridType));
        }
        final Matrix matrix = Matrices.createIdentity(dimension + 1);
        for (int i = 0; i < dimension; i++) {
            // NOTE: i is a dimension in the 'gridEnvelope' space (source coordinates).
            // j is a dimension in the 'userEnvelope' space (target coordinates).
            int j = i;
            if (swapXY && j <= 1) {
                j = 1 - j;
            }
            double scale = userEnvelope.getSpan(j) / gridEnvelope.getSize(i);
            double offset;
            if (reverse == null || j >= reverse.length || !reverse[j]) {
                offset = userEnvelope.getMinimum(j);
            } else {
                scale = -scale;
                offset = userEnvelope.getMaximum(j);
            }
            offset -= scale * (gridEnvelope.getLow(i) - translate);
            matrix.setElement(j, j, 0.0);
            matrix.setElement(j, i, scale);
            matrix.setElement(j, dimension, offset);
        }
        transform = MathTransforms.linear(matrix);
    }
    return transform;
}
Also used : GridExtent(org.apache.sis.coverage.grid.GridExtent) Matrix(org.opengis.referencing.operation.Matrix) Envelope(org.opengis.geometry.Envelope) PixelInCell(org.opengis.referencing.datum.PixelInCell)

Example 2 with PixelInCell

use of org.opengis.referencing.datum.PixelInCell in project geotoolkit by Geomatys.

the class CoverageToFeaturesProcess method convertToFeature.

/**
 * Create a Feature with a cell coordinate (x,y).
 *
 * @param type the FeatureType
 * @param x
 * @param y
 * @param coverage
 * @param resource
 * @param gridGeom
 * @return the cell Feature
 * @throws DataStoreException
 * @throws TransformException
 */
static Feature convertToFeature(FeatureType type, long x, long y, GridCoverage coverage, GridCoverageResource resource, GridGeometry gridGeom) throws DataStoreException, TransformException {
    final GeometryFactory geomFac = org.geotoolkit.geometry.jts.JTS.getFactory();
    // get the number of band contained in a cell
    final List<SampleDimension> dims = coverage.getSampleDimensions();
    final int nbBand = dims.size();
    // Define the pixel position in cells
    PixelInCell posPix = PixelInCell.CELL_CENTER;
    // rep.getPointInPixel();
    final PixelOrientation pixOr = PixelOrientation.CENTER;
    if (pixOr == PixelOrientation.CENTER) {
        posPix = PixelInCell.CELL_CENTER;
    } else if (pixOr == PixelOrientation.UPPER_LEFT) {
        posPix = PixelInCell.CELL_CORNER;
    }
    // get the MathTransform frome grid to the CRS
    final MathTransform transfo = gridGeom.getGridToCRS(posPix);
    double[] pt1 = new double[] { x, y };
    double[] pt2 = new double[2];
    // transform x,y cell coordinate with the gridToCRS MathTransform
    transfo.transform(pt1, 0, pt2, 0, 1);
    // make a Point2D with transformed coordinates in order to get cell bands
    DirectPosition2D point2d = new DirectPosition2D();
    point2d.setLocation(pt2[0], pt2[1]);
    double[] infoBand = coverage.evaluator().apply(point2d);
    final double[] resolution = gridGeom.getResolution(true);
    double gapX = resolution[0];
    double gapY = resolution[1];
    // compute the cell geometry from transform coordinates
    Coordinate[] coord;
    if (posPix == PixelInCell.CELL_CENTER) {
        coord = new Coordinate[] { new Coordinate(pt2[0] - gapX / 2, pt2[1] + gapY / 2), new Coordinate(pt2[0] + gapX / 2, pt2[1] + gapY / 2), new Coordinate(pt2[0] + gapX / 2, pt2[1] - gapY / 2), new Coordinate(pt2[0] - gapX / 2, pt2[1] - gapY / 2), new Coordinate(pt2[0] - gapX / 2, pt2[1] + gapY / 2) };
    } else {
        coord = new Coordinate[] { new Coordinate(pt2[0], pt2[1]), new Coordinate(pt2[0] + gapX, pt2[1]), new Coordinate(pt2[0] + gapX, pt2[1] - gapY), new Coordinate(pt2[0], pt2[1] - gapY), new Coordinate(pt2[0], pt2[1]) };
    }
    // create the Feature
    Feature myfeature = type.newInstance();
    myfeature.setPropertyValue(AttributeConvention.IDENTIFIER, "id-" + x + "-" + y);
    myfeature.setPropertyValue("cellgeom", geomFac.createPolygon(geomFac.createLinearRing(coord), null));
    myfeature.setPropertyValue("position", geomFac.createPoint(new Coordinate(pt2[0], pt2[1])));
    myfeature.setPropertyValue("orientation", posPix.name());
    for (int att = 0; att < nbBand; att++) {
        myfeature.setPropertyValue("band-" + att, infoBand[att]);
    }
    return myfeature;
}
Also used : PixelOrientation(org.opengis.metadata.spatial.PixelOrientation) GeometryFactory(org.locationtech.jts.geom.GeometryFactory) MathTransform(org.opengis.referencing.operation.MathTransform) SampleDimension(org.apache.sis.coverage.SampleDimension) DirectPosition2D(org.apache.sis.geometry.DirectPosition2D) Feature(org.opengis.feature.Feature) Point(org.locationtech.jts.geom.Point) PixelInCell(org.opengis.referencing.datum.PixelInCell) Coordinate(org.locationtech.jts.geom.Coordinate)

Example 3 with PixelInCell

use of org.opengis.referencing.datum.PixelInCell 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 PixelInCell

use of org.opengis.referencing.datum.PixelInCell in project geowave by locationtech.

the class RasterUtils method createTransform.

/**
 * Creates a math transform using the information provided.
 *
 * @return The math transform.
 * @throws IllegalStateException if the grid range or the envelope were not set.
 */
public static MathTransform createTransform(final double[] idRangePerDimension, final MultiDimensionalNumericData fullBounds) throws IllegalStateException {
    final GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
    final boolean swapXY = mapper.getSwapXY();
    final boolean[] reverse = mapper.getReverseAxis();
    final PixelInCell gridType = PixelInCell.CELL_CORNER;
    final int dimension = 2;
    /*
     * Setup the multi-dimensional affine transform for use with OpenGIS. According OpenGIS
     * specification, transforms must map pixel center. This is done by adding 0.5 to grid
     * coordinates.
     */
    final double translate;
    if (PixelInCell.CELL_CENTER.equals(gridType)) {
        translate = 0.5;
    } else if (PixelInCell.CELL_CORNER.equals(gridType)) {
        translate = 0.0;
    } else {
        throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, "gridType", gridType));
    }
    final Matrix matrix = MatrixFactory.create(dimension + 1);
    final Double[] minValuesPerDimension = fullBounds.getMinValuesPerDimension();
    final Double[] maxValuesPerDimension = fullBounds.getMaxValuesPerDimension();
    for (int i = 0; i < dimension; i++) {
        // NOTE: i is a dimension in the 'gridRange' space (source
        // coordinates).
        // j is a dimension in the 'userRange' space (target coordinates).
        int j = i;
        if (swapXY) {
            j = 1 - j;
        }
        double scale = idRangePerDimension[j];
        double offset;
        if ((reverse == null) || (j >= reverse.length) || !reverse[j]) {
            offset = minValuesPerDimension[j];
        } else {
            scale = -scale;
            offset = maxValuesPerDimension[j];
        }
        offset -= scale * (-translate);
        matrix.setElement(j, j, 0.0);
        matrix.setElement(j, i, scale);
        matrix.setElement(j, dimension, offset);
    }
    return ProjectiveTransform.create(matrix);
}
Also used : Matrix(org.opengis.referencing.operation.Matrix) GridToEnvelopeMapper(org.geotools.referencing.operation.builder.GridToEnvelopeMapper) PixelInCell(org.opengis.referencing.datum.PixelInCell)

Example 5 with PixelInCell

use of org.opengis.referencing.datum.PixelInCell in project geotoolkit by Geomatys.

the class AmendedCoverageResource method read.

private GridCoverage read(GridCoverageReadParam param) throws DataStoreException, CancellationException {
    GridCoverage coverage;
    if (isGridGeometryOverriden()) {
        final CoordinateReferenceSystem overrideCRS = getOverrideCRS();
        final MathTransform overrideGridToCrs = getOverrideGridToCrs();
        final PixelInCell overridePixelInCell = getOverridePixelInCell();
        final GridGeometry overrideGridGeometry = getGridGeometry();
        final GridGeometry originalGridGeometry = getOriginalGridGeometry();
        // convert parameters to fit overrides
        double[] queryRes = param == null ? null : param.getResolution();
        CoordinateReferenceSystem queryCrs = param == null ? null : param.getCoordinateReferenceSystem();
        Envelope queryEnv = param == null ? null : param.getEnvelope();
        // find requested envelope
        if (queryEnv == null && queryCrs != null) {
            try {
                queryEnv = Envelopes.transform(overrideGridGeometry.getEnvelope(), queryCrs);
            } catch (TransformException ex) {
                throw new DataStoreException(ex.getMessage(), ex);
            }
        }
        // convert resolution to coverage crs
        double[] coverageRes = queryRes;
        if (queryRes != null) {
            try {
                coverageRes = ReferencingUtilities.convertResolution(queryEnv, queryRes, overrideGridGeometry.getCoordinateReferenceSystem());
            } catch (TransformException ex) {
                throw new DataStoreException(ex.getMessage(), ex);
            }
        }
        // get envelope in coverage crs
        Envelope coverageEnv;
        if (queryEnv == null) {
            // if no envelope is defined, use the full extent
            coverageEnv = overrideGridGeometry.getEnvelope();
        } else {
            try {
                coverageEnv = Envelopes.transform(queryEnv, overrideGridGeometry.getCoordinateReferenceSystem());
            } catch (TransformException ex) {
                throw new DataStoreException(ex.getMessage(), ex);
            }
        }
        // change the crs to original one
        if (overrideCRS != null) {
            coverageEnv = new GeneralEnvelope(coverageEnv);
            ((GeneralEnvelope) coverageEnv).setCoordinateReferenceSystem(originalGridGeometry.getCoordinateReferenceSystem());
        }
        // change the queried envelope
        MathTransform fixedToOriginal = null;
        MathTransform originalToFixed = null;
        if (overrideGridToCrs != null || overridePixelInCell != null) {
            try {
                final MathTransform overrideCrsToGrid = overrideGridGeometry.getGridToCRS(PixelInCell.CELL_CENTER).inverse();
                fixedToOriginal = MathTransforms.concatenate(overrideCrsToGrid, originalGridGeometry.getGridToCRS(PixelInCell.CELL_CENTER));
                originalToFixed = fixedToOriginal.inverse();
                coverageEnv = Envelopes.transform(fixedToOriginal, coverageEnv);
                coverageEnv = new GeneralEnvelope(coverageEnv);
                ((GeneralEnvelope) coverageEnv).setCoordinateReferenceSystem(originalGridGeometry.getCoordinateReferenceSystem());
            } catch (TransformException ex) {
                throw new DataStoreException(ex);
            }
        }
        if (originalToFixed != null && coverageRes != null) {
            // adjust resolution
            double s = AffineTransforms2D.getScale((AffineTransform2D) originalToFixed);
            coverageRes[0] /= s;
            coverageRes[1] /= s;
        }
        // query original reader
        final GridCoverageReadParam refParam = new GridCoverageReadParam(param);
        refParam.setResolution(coverageRes);
        refParam.setCoordinateReferenceSystem(null);
        refParam.setEnvelope(null);
        if (coverageEnv != null) {
            refParam.setCoordinateReferenceSystem(coverageEnv.getCoordinateReferenceSystem());
            refParam.setEnvelope(coverageEnv);
        }
        coverage = ref.read(toBaseGridGeometry(refParam));
        // fix coverage transform and crs
        final GridCoverageBuilder gcb = new GridCoverageBuilder();
        CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem();
        GridExtent extent = coverage.getGridGeometry().getExtent();
        MathTransform gridToCRS = coverage.getGridGeometry().getGridToCRS(PixelInCell.CELL_CENTER);
        if (overrideCRS != null) {
            crs = overrideCRS;
        }
        if (overrideGridToCrs != null || overridePixelInCell != null) {
            gridToCRS = MathTransforms.concatenate(gridToCRS, originalToFixed);
        }
        gcb.setDomain(new GridGeometry(extent, PixelInCell.CELL_CENTER, gridToCRS, crs));
        gcb.setRanges(coverage.getSampleDimensions());
        gcb.setValues(coverage.render(null));
        coverage = gcb.build();
    } else {
        coverage = ref.read(toBaseGridGeometry(param));
    }
    // override sample dimensions
    final List<SampleDimension> overrideDims = getOverrideDims();
    if (overrideDims != null) {
        List<SampleDimension> sd = coverage.getSampleDimensions();
        // check if size match
        List<SampleDimension> overs = overrideDims;
        int[] sourceBands = param.getSourceBands();
        if (sourceBands != null) {
            // we make an extra check not all readers honor the band selection parameters
            if (sd == null || overrideDims.size() != sd.size()) {
                overs = new ArrayList<>();
                for (int i : sourceBands) {
                    overs.add(overrideDims.get(i));
                }
            }
        }
        final GridCoverageBuilder gcb = new GridCoverageBuilder();
        gcb.setValues(coverage.render(null));
        gcb.setDomain(coverage.getGridGeometry());
        gcb.setRanges(overs.toArray(new SampleDimension[overs.size()]));
        coverage = gcb.build();
    }
    return coverage;
}
Also used : GridGeometry(org.apache.sis.coverage.grid.GridGeometry) DataStoreException(org.apache.sis.storage.DataStoreException) GridExtent(org.apache.sis.coverage.grid.GridExtent) MathTransform(org.opengis.referencing.operation.MathTransform) TransformException(org.opengis.referencing.operation.TransformException) Envelope(org.opengis.geometry.Envelope) GeneralEnvelope(org.apache.sis.geometry.GeneralEnvelope) SampleDimension(org.apache.sis.coverage.SampleDimension) PixelInCell(org.opengis.referencing.datum.PixelInCell) GridCoverage(org.apache.sis.coverage.grid.GridCoverage) GridCoverageBuilder(org.apache.sis.coverage.grid.GridCoverageBuilder) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) GridCoverageReadParam(org.geotoolkit.coverage.io.GridCoverageReadParam) GeneralEnvelope(org.apache.sis.geometry.GeneralEnvelope)

Aggregations

PixelInCell (org.opengis.referencing.datum.PixelInCell)6 GridExtent (org.apache.sis.coverage.grid.GridExtent)3 GridGeometry (org.apache.sis.coverage.grid.GridGeometry)3 MathTransform (org.opengis.referencing.operation.MathTransform)3 SampleDimension (org.apache.sis.coverage.SampleDimension)2 Point (org.locationtech.jts.geom.Point)2 Feature (org.opengis.feature.Feature)2 Envelope (org.opengis.geometry.Envelope)2 PixelOrientation (org.opengis.metadata.spatial.PixelOrientation)2 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)2 Matrix (org.opengis.referencing.operation.Matrix)2 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 ImageReader (javax.imageio.ImageReader)1 GridCoverage (org.apache.sis.coverage.grid.GridCoverage)1 GridCoverageBuilder (org.apache.sis.coverage.grid.GridCoverageBuilder)1