Package org.geotools.coverage.grid

Examples of org.geotools.coverage.grid.GeneralGridEnvelope


    if ((height < GIF_HEIGHT) && (width < GIF_WIDTH)) {
      return gc;
    }

    // new grid range
    final GeneralGridEnvelope newGridrange = new GeneralGridEnvelope(new int[] {0, 0 }, new int[] { GIF_WIDTH, GIF_HEIGHT });
    final GridGeometry2D newGridGeometry = new GridGeometry2D(newGridrange,gc.getEnvelope());

    // resample this coverage
    final ParameterValueGroup pvg= resampleFactory.getParameters();
    pvg.parameter("Source").setValue(gc);
View Full Code Here


     */
    @Test
    public void testCrop() {
        final GridGeometry2D g1,g2;
        final MathTransform gridToCRS = null;
        g1 = new GridGeometry2D(new GeneralGridEnvelope(new Rectangle(50,50,100,100), 2), gridToCRS, null);
        g2 = new GridGeometry2D(new GeneralGridEnvelope(new Rectangle(50,50,200,200), 2), gridToCRS, null);
        assertEquals("Crop",   showProjected(coverage,        null, g2, null, false));
        assertEquals("Lookup", showProjected(coverage,        null, g2, null, true ));
        assertEquals("Crop",   showProjected(indexedCoverage, null, g1, null, false));
        assertEquals("Crop",   showProjected(indexedCoverageWithTransparency, null, g1, null, false));
        assertEquals("Crop",   showProjected(floatCoverage, null, g1,
View Full Code Here

          0,
          0);
      g2w.concatenate(adjustments);
      finalGridToWorldCorner = new AffineTransform2D(g2w);
      finalWorldToGridCorner = finalGridToWorldCorner.inverse();// compute raster bounds
      rasterBounds=new GeneralGridEnvelope(CRS.transform(finalWorldToGridCorner, bbox),PixelInCell.CELL_CORNER,false).toRectangle();
     
      // create Init the granuleWorker
      final GranuleWorker worker = new GranuleWorker();
      worker.init(new ReferencedEnvelope(coverageEnvelope));
      worker.produce();
View Full Code Here

      if(destinationToSourceTransform==null||destinationToSourceTransform.isIdentity()){

     
      // now get the requested bbox which have been already adjusted and project it back to raster space
      try {
        destinationRasterArea = new GeneralGridEnvelope(CRS.transform(requestedWorldToGrid,new GeneralEnvelope(cropBBox)),PixelInCell.CELL_CORNER,false).toRectangle();
      } catch (IllegalStateException e) {
        throw new DataSourceException(e);
      } catch (TransformException e) {
        throw new DataSourceException(e);
      }
      }
      else
      {
        //
        // reproject the crop bbox back and then crop, notice that we are imposing
        //
        try {
                final GeneralEnvelope cropBBOXInRequestCRS = CRS.transform(cropBBox,
                        requestedBBox.getCoordinateReferenceSystem());
        cropBBOXInRequestCRS.setCoordinateReferenceSystem(requestedBBox.getCoordinateReferenceSystem());
        //make sure it falls within the requested envelope
        cropBBOXInRequestCRS.intersect(requestedBBox);
       
        //now go back to raster space
        destinationRasterArea =  new GeneralGridEnvelope(CRS.transform(requestedWorldToGrid,cropBBOXInRequestCRS),PixelInCell.CELL_CORNER,false).toRectangle();
        //intersect with the original requested raster space to be sure that we stay within the requested raster area
        XRectangle2D.intersect(destinationRasterArea, requestedRasterArea, destinationRasterArea);
      } catch (NoninvertibleTransformException e) {
        throw new DataSourceException(e);
      } catch (TransformException e) {
View Full Code Here

        ///////////////////////////////////////////////////////////////
        ///  Tests the setting of grid range and envelope.
        ///
        Point2D.Double point = new Point2D.Double();
        GeneralGridEnvelope gridRange;
        GeneralEnvelope envelope;
        gridRange = new GeneralGridEnvelope(new int[] {10, 20}, new int[] {110, 220}, false);
        envelope  = new GeneralEnvelope(new double[] {1, 4, 6}, new double[] {11, 44, 66});
        mapper.setGridRange(gridRange);
        assertSame(gridRange, mapper.getGridRange());
        try {
            mapper.getEnvelope();
View Full Code Here

                     * (at least approximatively).
                     */
                    Envelope gridRange;
                    gridRange = toEnvelope(sourceGG.getGridRange());
                    gridRange = CRS.transform(allSteps.inverse(), gridRange);
                    targetGG  = new GridGeometry2D(new GeneralGridEnvelope(gridRange,PixelInCell.CELL_CORNER), targetGG.getGridToCRS(PixelInCell.CELL_CENTER), targetCRS);
                }
            }
        } else {
            if (sourceCRS == null) {
                throw new CannotReprojectException(Errors.format(ErrorKeys.UNSPECIFIED_CRS));
            }
            final Envelope        sourceEnvelope;
            final GeneralEnvelope targetEnvelope;
            final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
            final boolean force2D = (sourceCRS != compatibleSourceCRS);
            step2          = factory.createOperation(targetCRS, compatibleSourceCRS).getMathTransform();
            step3          = (force2D ? sourceGG.getGridToCRS2D(CORNER) : sourceGG.getGridToCRS(CORNER)).inverse();
            sourceEnvelope = sourceCoverage.getEnvelope(); // Don't force this one to 2D.
            targetEnvelope = CRS.transform(operation, sourceEnvelope);
            targetEnvelope.setCoordinateReferenceSystem(targetCRS);
            // 'targetCRS' may be different than the one set by CRS.transform(...).
            /*
             * If the target GridGeometry is incomplete, provides default
             * values for the missing fields. Three cases may occurs:
             *
             * - User provided no GridGeometry at all. Then, constructs an image of the same size
             *   than the source image and set an envelope big enough to contains the projected
             *   coordinates. The transform will derive from the grid range and the envelope.
             *
             * - User provided only a grid range.  Then, set an envelope big enough to contains
             *   the projected coordinates. The transform will derive from the grid range and
             *   the envelope.
             *
             * - User provided only a "grid to CRS" transform. Then, transform the projected
             *   envelope to "grid units" using the specified transform and create a grid range
             *   big enough to hold the result.
             */
            if (targetGG == null) {
                final GridEnvelope targetGR;
                targetGR = force2D ? new GridEnvelope2D(sourceGG.getGridRange2D()) : sourceGG.getGridRange();
                targetGG = new GridGeometry2D(targetGR, targetEnvelope);
                step1    = targetGG.getGridToCRS(CORNER);
            } else if (!targetGG.isDefined(GridGeometry2D.GRID_TO_CRS_BITMASK)) {
                targetGG = new GridGeometry2D(targetGG.getGridRange(), targetEnvelope);
                step1    = targetGG.getGridToCRS(CORNER);
            } else {
                step1 = targetGG.getGridToCRS(CORNER);
                if (!targetGG.isDefined(GridGeometry2D.GRID_RANGE_BITMASK)) {
                    GeneralEnvelope gridRange = CRS.transform(step1.inverse(), targetEnvelope);
                    // According OpenGIS specification, GridGeometry maps pixel's center.
                    targetGG = new GridGeometry2D(new GeneralGridEnvelope(gridRange, PixelInCell.CELL_CENTER), step1, targetCRS);
                }
            }
            /*
             * Computes the final transform.
             */
            allSteps = mtFactory.createConcatenatedTransform(
                       mtFactory.createConcatenatedTransform(step1, step2), step3);
        }
        allSteps2D = toMathTransform2D(allSteps, mtFactory, targetGG);
        if (!(allSteps2D instanceof MathTransform2D)) {
            // Should not happen with Geotools implementations. May happen
            // with some external implementations, but should stay unusual.
            throw new TransformException(Errors.format(ErrorKeys.NO_TRANSFORM2D_AVAILABLE));
        }

        ////////////////////////////////////////////////////////////////////////////////////////
        ////                                                                                ////
        ////            STEP 1: Extracts needed informations from the parameters            ////
        ////            STEP 2: Creates the "target to source" MathTransform                ////
        //// =======>>  STEP 3: Computes the target image layout                   <<====== ////
        ////            STEP 4: Applies the JAI operation ("Affine", "Warp", etc)           ////
        ////                                                                                ////
        ////////////////////////////////////////////////////////////////////////////////////////

        final RenderingHints targetHints = processingView.getRenderingHints(sourceImage);
        if (hints != null) {
            targetHints.add(hints);
        }
        ImageLayout layout = (ImageLayout) targetHints.get(JAI.KEY_IMAGE_LAYOUT);
        if (layout != null) {
            layout = (ImageLayout) layout.clone();
        } else {
            layout = new ImageLayout();
            // Do not inherit the color model and sample model from the 'sourceImage';
            // Let the operation decide itself. This is necessary in case we change the
            // source, as we do if we choose the "Mosaic" operation.
        }
        final Rectangle sourceBB = sourceGG.getGridRange2D();
        final Rectangle targetBB = targetGG.getGridRange2D();
        if (isBoundsUndefined(layout, false)) {
            layout.setMinX  (targetBB.x);
            layout.setMinY  (targetBB.y);
            layout.setWidth (targetBB.width);
            layout.setHeight(targetBB.height);
        }
        if (isBoundsUndefined(layout, true)) {
            Dimension size = new Dimension(layout.getWidth (sourceImage),
                                           layout.getHeight(sourceImage));
            size = ImageUtilities.toTileSize(size);
            layout.setTileGridXOffset(layout.getMinX(sourceImage));
            layout.setTileGridYOffset(layout.getMinY(sourceImage));
            layout.setTileWidth (size.width);
            layout.setTileHeight(size.height);
        }
        /*
         * Creates the background values array.
         */
        final double[] background = backgroundValues != null ? backgroundValues : CoverageUtilities.getBackgroundValues(sourceCoverage);

       
        /*
         * We need to correctly manage the Hints to control the replacement of IndexColorModel.
         * It is worth to point out that setting the JAI.KEY_REPLACE_INDEX_COLOR_MODEL hint to
         * Boolean.TRUE is not enough to force the operators to do an expansion. If we explicitly
         * provide an ImageLayout built with the source image where the CM and the SM are valid.
         * those will be employed overriding a the possibility to expand the color model.
         */
        if (ViewType.PHOTOGRAPHIC.equals(processingView)) {
            layout.unsetValid(ImageLayout.COLOR_MODEL_MASK | ImageLayout.SAMPLE_MODEL_MASK);
        }
        targetHints.put(JAI.KEY_IMAGE_LAYOUT, layout);

        ////////////////////////////////////////////////////////////////////////////////////////
        ////                                                                                ////
        ////            STEP 1: Extracts needed informations from the parameters            ////
        ////            STEP 2: Creates the "target to source" MathTransform                ////
        ////            STEP 3: Computes the target image layout                            ////
        //// =======>>  STEP 4: Applies the JAI operation ("Affine", "Warp", etc)  <<====== ////
        ////                                                                                ////
        ////////////////////////////////////////////////////////////////////////////////////////
        /*
         * If the user requests a new grid geometry with the same coordinate reference system,
         * and if the grid geometry is equivalents to a simple extraction of a sub-area, then
         * delegates the work to a "Crop" operation.
         */
        final String operation;
        final ParameterBlock paramBlk = new ParameterBlock().addSource(sourceImage);
        final Map<String, Object> imageProperties = new HashMap<String, Object>();
        Warp warp = null;
        if (allSteps.isIdentity() || (allSteps instanceof AffineTransform &&
                XAffineTransform.isIdentity((AffineTransform) allSteps, EPS)))
        {
            /*
             * Since there is no interpolation to perform, use the native view (which may be
             * packed or geophysics - it is just the view which is closest to original data).
             */
            sourceCoverage = sourceCoverage.view(ViewType.NATIVE);
            sourceImage = PlanarImage.wrapRenderedImage(sourceCoverage.getRenderedImage());
            paramBlk.removeSources();
            paramBlk.addSource(sourceImage);
            if (targetBB.equals(sourceBB)) {
                /*
                 * Optimization in case we have nothing to do, not even a crop. Reverts to the
                 * original coverage BEFORE to creates Resampler2D. Note that while there is
                 * nothing to do, the target CRS is not identical to the source CRS (so we need
                 * to create a new coverage) otherwise this condition would have been detected
                 * sooner in this method.
                 */
                sourceCoverage = sourceCoverage.view(finalView);
                sourceImage = PlanarImage.wrapRenderedImage(sourceCoverage.getRenderedImage());
                return create(sourceCoverage, sourceImage, targetGG, ViewType.SAME, null, null, hints);
            }
            if (sourceBB.contains(targetBB)) {
                operation = "Crop";
                paramBlk.add(Float.valueOf(targetBB.x))
                        .add(Float.valueOf(targetBB.y))
                        .add(Float.valueOf(targetBB.width))
                        .add(Float.valueOf(targetBB.height));
            } else {
                operation = "Mosaic";
                paramBlk.add(MosaicDescriptor.MOSAIC_TYPE_OVERLAY)
                        .add(null).add(null).add(null).add(background);
            }
        } else {
            /*
             * Special case for the affine transform. Try to use the JAI "Affine" operation
             * instead of the more general "Warp" one. JAI provides native acceleration for
             * the affine operation.
             *
             * NOTE 1: There is no need to check for "Scale" and "Translate" as special cases
             *         of "Affine" since JAI already does this check for us.
             *
             * NOTE 2: "Affine", "Scale", "Translate", "Rotate" and similar operations ignore
             *         the 'xmin', 'ymin', 'width' and 'height' image layout. Consequently, we
             *         can't use this operation if the user provided explicitly a grid range.
             *
             * NOTE 3: If the user didn't specified any grid geometry, then a yet cheaper approach
             *         is to just update the 'gridToCRS' value. We returns a grid coverage wrapping
             *         the SOURCE image with the updated grid geometry.
             */
            if ((automaticGR || targetBB.equals(sourceBB)) && allSteps instanceof AffineTransform) {
                if (automaticGG) {
                    // Cheapest approach: just update 'gridToCRS'.
                    MathTransform mtr;
                    mtr = sourceGG.getGridToCRS(CORNER);
                    mtr = mtFactory.createConcatenatedTransform(mtr,  step2.inverse());
                    targetGG = new GridGeometry2D(sourceGG.getGridRange(), mtr, targetCRS);
                    /*
                     * Note: do NOT use the "GridGeometry2D(sourceGridRange, targetEnvelope)"
                     * constructor in the above line. We must give a MathTransform argument to
                     * the constructor, not an Envelope, because the later infer a MathTransform
                     * using heuristic rules. Only the constructor with a MathTransform argument
                     * is fully accurate.
                     */
                    return create(sourceCoverage, sourceImage, targetGG, finalView, null, null, hints);
                }
                // More general approach: apply the affine transform.
                operation = "Affine";
                final AffineTransform affine = (AffineTransform) allSteps.inverse();
                paramBlk.add(affine).add(interpolation).add(background);
            } else {
                /*
                 * General case: constructs the warp transform.
                 *
                 * TODO: JAI 1.1.3 seems to have a bug when the target envelope is greater than
                 *       the source envelope:  Warp on float values doesn't set to 'background'
                 *       the points outside the envelope. The operation seems to work correctly
                 *       on integer values, so as a workaround we restart the operation without
                 *       interpolation (which increase the chances to get it down on integers).
                 *       Remove this hack when this JAI bug will be fixed.
                 *
                 * TODO: Move the check for AffineTransform into WarpTransform2D.
                 */
                boolean forceAdapter = false;
                switch (sourceImage.getSampleModel().getTransferType()) {
                    case DataBuffer.TYPE_DOUBLE:
                    case DataBuffer.TYPE_FLOAT: {
                        Envelope source = CRS.transform(sourceGG.getEnvelope(), targetCRS);
                        Envelope target = CRS.transform(targetGG.getEnvelope(), targetCRS);
                        source = targetGG.reduce(source);
                        target = targetGG.reduce(target);
                        if (!(new GeneralEnvelope(source).contains(target, true))) {
                            if (interpolation != null && !(interpolation instanceof InterpolationNearest)) {
                                return reproject(sourceCoverage, targetCRS, targetGG, null, hints, background);
                            } else {
                                // If we were already using nearest-neighbor interpolation, force
                                // usage of WarpAdapter2D instead of WarpAffine. The price will be
                                // a slower reprojection.
                                forceAdapter = true;
                            }
                        }
                    }
                }
                // -------- End of JAI bug workaround --------
                final MathTransform2D transform = (MathTransform2D) allSteps2D;
                final CharSequence name = sourceCoverage.getName();
                operation = "Warp";
                if (forceAdapter) {
                    warp = new WarpBuilder(0.0).buildWarp(transform, sourceBB);
                } else {
                    warp = createWarp(name, sourceBB, targetBB, transform, mtFactory, hints);
                }
                // store the transormation in the properties, as we might want to retrieve and chain
                // it with affine transforms down the chain
                imageProperties.put("MathTransform", transform);
                imageProperties.put("SourceBoundingBox", sourceBB);
                paramBlk.add(warp).add(interpolation).add(background);
            }
        }
        final RenderedOp targetImage = getJAI(hints).createNS(operation, paramBlk, targetHints);
        for (Map.Entry<String, Object> entry : imageProperties.entrySet()) {
            targetImage.setProperty(entry.getKey(), entry.getValue());
        }
        final Locale locale = sourceCoverage.getLocale()// For logging purpose.
        /*
         * The JAI operation sometime returns an image with a bounding box different than what we
         * expected. This is true especially for the "Affine" operation: the JAI documentation said
         * explicitly that xmin, ymin, width and height image layout hints are ignored for this one.
         * As a safety, we check the bounding box in any case. If it doesn't matches, then we will
         * reconstruct the target grid geometry.
         */
        final GridEnvelope targetGR = targetGG.getGridRange();
        final int[] lower = targetGR.getLow().getCoordinateValues();
        final int[] upper = targetGR.getHigh().getCoordinateValues();
        for (int i=0; i<upper.length; i++) {
            upper[i]++; // Make them exclusive.
        }
        lower[targetGG.gridDimensionX] = targetImage.getMinX();
        lower[targetGG.gridDimensionY] = targetImage.getMinY();
        upper[targetGG.gridDimensionX] = targetImage.getMaxX();
        upper[targetGG.gridDimensionY] = targetImage.getMaxY();
        final GridEnvelope actualGR = new GeneralGridEnvelope(lower, upper);
        if (!targetGR.equals(actualGR)) {
          targetGG = new GridGeometry2D(actualGR, targetGG.getGridToCRS(PixelInCell.CELL_CENTER),targetCRS);
            if (!automaticGR) {
                log(Loggings.getResources(locale).getLogRecord(Level.FINE,
                    LoggingKeys.ADJUSTED_GRID_GEOMETRY_$1, sourceCoverage.getName().toString(locale)));
View Full Code Here

            // //
            final Envelope requestedEnvelopeCropped = CRS.transform(adjustedRequestedEnvelope,
                    requestedEnvelopeCRS2D);
            final Rectangle2D ordinates = CRS.transform(readGridToWorld.inverse(),
                    requestedEnvelopeCropped).toRectangle2D();
            final GeneralGridEnvelope finalRange = new GeneralGridEnvelope(ordinates.getBounds());
            final Rectangle tempRect = finalRange.toRectangle();
            // check that we stay inside the source rectangle
            XRectangle2D.intersect(tempRect, requestedDim, tempRect);
            requestedDim.setRect(tempRect);
        } catch (TransformException te) {
            // something bad happened while trying to transform this
View Full Code Here

            MathTransform originalGridToWorld, GeneralEnvelope requestedEnvelope,
            Rectangle sourceRegion, Rectangle requestedDim, MathTransform2D readGridToWorld,
            Envelope2D wgs84BaseEnvelope2D) throws DataSourceException {

        GeneralEnvelope adjustedRequestedEnvelope = new GeneralEnvelope(2);
        GeneralGridEnvelope baseGridRange = (GeneralGridEnvelope) originalGridRange;

        try {
            // ////////////////////////////////////////////////////////////////
            //
            // Check if we have something to load by intersecting the
            // requested envelope with the bounds of this data set.
            //
            // ////////////////////////////////////////////////////////////////
            if (requestedEnvelope != null) {
                final GeneralEnvelope requestedEnvelope2D = Utilities
                        .getRequestedEnvelope2D(requestedEnvelope);

                // ////////////////////////////////////////////////////////////
                //
                // INTERSECT ENVELOPES AND CROP Destination REGION
                //
                // ////////////////////////////////////////////////////////////
                adjustedRequestedEnvelope = Utilities.getIntersection(baseEnvelope2D,
                        spatialReferenceSystem2D, requestedEnvelope2D, requestedDim,
                        readGridToWorld, wgs84BaseEnvelope2D);
                if (adjustedRequestedEnvelope == null)
                    return null;

                // /////////////////////////////////////////////////////////////////////
                //
                // CROP SOURCE REGION
                //
                // /////////////////////////////////////////////////////////////////////
                sourceRegion.setRect(Utilities.getCropRegion(adjustedRequestedEnvelope, Utilities
                        .getOriginalGridToWorld(originalGridToWorld, PixelInCell.CELL_CORNER)));
                if (sourceRegion.isEmpty()) {
                    if (LOGGER.isLoggable(Level.INFO)) {
                        LOGGER.log(Level.INFO,
                                "Too small envelope resulting in empty cropped raster region");
                    }
                    return null;
                    // TODO: Future versions may define a 1x1 rectangle starting
                    // from the lower coordinate
                }
                if (!sourceRegion.intersects(baseGridRange.toRectangle()) || sourceRegion.isEmpty())
                    throw new DataSourceException("The crop region is invalid.");
                sourceRegion.setRect(sourceRegion.intersection(baseGridRange.toRectangle()));

                if (LOGGER.isLoggable(Level.FINE)) {
                    StringBuilder sb = new StringBuilder("Adjusted Requested Envelope = ")
                            .append(adjustedRequestedEnvelope.toString()).append("\n")
                            .append("Requested raster dimension = ")
View Full Code Here

        //
        // //
        if (requestedEnvelope != null) {
            final GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper();
            geMapper.setEnvelope(requestedEnvelope);
            geMapper.setGridRange(new GeneralGridEnvelope(requestedDim, 2));
            geMapper.setPixelAnchor(pixelInCell);
            final AffineTransform transform = geMapper.createAffineTransform();
            requestedRes = CoverageUtilities.getResolution(transform);
        }
View Full Code Here

        if (destinationToSourceTransform == null || destinationToSourceTransform.isIdentity()) {

            // now get the requested bbox which have been already adjusted and project it back to raster space
            try {
                destinationRasterArea = new GeneralGridEnvelope(CRS.transform(requestedWorldToGrid,
                        new GeneralEnvelope(cropBBox)), PixelInCell.CELL_CORNER, false).toRectangle();
            } catch (IllegalStateException e) {
                throw new DataSourceException(e);
            } catch (TransformException e) {
                throw new DataSourceException(e);
            }
        } else {
            //
            // reproject the crop bbox back and then crop, notice that we are imposing
            //
            try {
                final GeneralEnvelope cropBBOXInRequestCRS = CRS.transform(cropBBox,
                        requestedBBox.getCoordinateReferenceSystem());
                cropBBOXInRequestCRS.setCoordinateReferenceSystem(requestedBBox.getCoordinateReferenceSystem());
                // make sure it falls within the requested envelope
                cropBBOXInRequestCRS.intersect(requestedBBox);

                // now go back to raster space
                destinationRasterArea = new GeneralGridEnvelope(CRS.transform(requestedWorldToGrid,
                        cropBBOXInRequestCRS), PixelInCell.CELL_CORNER, false).toRectangle();
                // intersect with the original requested raster space to be sure that we stay within the requested raster area
                XRectangle2D.intersect(destinationRasterArea, requestedRasterArea, destinationRasterArea);
            } catch (NoninvertibleTransformException e) {
                throw new DataSourceException(e);
View Full Code Here

TOP

Related Classes of org.geotools.coverage.grid.GeneralGridEnvelope

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.