Package org.opengis.coverage.grid

Examples of org.opengis.coverage.grid.GridEnvelope


            // Getting the rectifiedGrid node
            //
            // //
            final RectifiedGrid rg = metadata.getRectifiedGrid();
            final AffineTransform at = Utilities.getAffineTransform(rg);
            final GridEnvelope gridRange = Utilities.getGridRange(rg);
            final MathTransform raster2Model = ProjectiveTransform.create(at);
            raster2ModelMap.put(coverageName, raster2Model);
            final double[] highestRes = CoverageUtilities.getResolution((AffineTransform) raster2Model);
            highestResMap.put(coverageName, highestRes);
            g2d = new GridGeometry2D(gridRange, raster2Model,spatialReferenceSystem2DMap.get(coverageName));
View Full Code Here


        }
        final double xScale =  at.getScaleX();
        final double yScale =  at.getScaleY();
        final double xTrans = -at.getTranslateX()/xScale;
        final double yTrans = -at.getTranslateY()/yScale;
        final GridEnvelope      range = gridGeometry.getGridRange();
        final ParameterBlock param = new ParameterBlock().add(function)
                                                         .add(range.getSpan(0)) // width
                                                         .add(range.getSpan(1)) // height
                                                         .add((float) xScale)
                                                         .add((float) yScale)
                                                         .add((float) xTrans)
                                                         .add((float) yTrans);
        final PlanarImage image = JAI.create("ImageFunction", param);
View Full Code Here

   * edited (i.e the image node as been re-rendered). Since {@code GridCoverage2D} are immutable
   * by design, we are not allowed to propagate the image change here. The {@link #getGridGeometry}
   * method will thrown an {@link IllegalStateException} in this case.
   */
  static String checkConsistency(final RenderedImage image, final GridGeometry2D grid) {
      final GridEnvelope range = grid.getGridRange();
      final int dimension = range.getDimension();
      for (int i=0; i<dimension; i++) {
          final int min, length;
          final Object label;
          if (i == grid.gridDimensionX) {
              min    = image.getMinX();
              length = image.getWidth();
              label  = "\"X\"";
          } else if (i == grid.gridDimensionY) {
              min    = image.getMinY();
              length = image.getHeight();
              label  = "\"Y\"";
          } else {
              min    = range.getLow(i);
              length = Math.min(Math.max(range.getHigh(i)+1, 0), 1);
              label  = Integer.valueOf(i);
          }
          if (range.getLow(i)!=min || range.getSpan(i)!=length) {
              return Errors.format(ErrorKeys.BAD_GRID_RANGE_$3, label, min, min + length);
          }
      }
      return null;
  }
View Full Code Here

     * @return The math transform.
     * @throws IllegalStateException if the grid range or the envelope were not set.
     */
    public MathTransform createTransform() throws IllegalStateException {
        if (transform == null) {
            final GridEnvelope gridRange = getGridRange();
            final Envelope     userRange = getEnvelope();
            final boolean      swapXY    = getSwapXY();
            final boolean[]    reverse   = getReverseAxis();
            final PixelInCell  gridType  = getPixelAnchor();
            final int          dimension = gridRange.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(ErrorKeys.ILLEGAL_ARGUMENT_$2,
                            "gridType", gridType));
            }
            final Matrix matrix = MatrixFactory.create(dimension + 1);
            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 = 1-j;
                }
                double scale = userRange.getSpan(j) / gridRange.getSpan(i);
                double offset;
                if (reverse==null || j>=reverse.length || !reverse[j]) {
                    offset = userRange.getMinimum(j);
                } else {
                    scale  = -scale;
                    offset = userRange.getMaximum(j);
                }
                offset -= scale * (gridRange.getLow(i) - translate);
                matrix.setElement(j, j,         0.0   );
                matrix.setElement(j, i,         scale );
                matrix.setElement(j, dimension, offset);
            }
            transform = ProjectiveTransform.create(matrix);
View Full Code Here

         * 'gridToCRS' transform in the GridGeometry object. In any case, the envelope must be
         * non-empty and its dimension must matches the coordinate reference system's dimension.
         */
        final int dimension = crs.getCoordinateSystem().getDimension();
        if (!gridGeometry.isDefined(GridGeometry2D.GRID_RANGE_BITMASK)) {
            final GridEnvelope r = new GeneralGridEnvelope(image, dimension);
            if (gridGeometry.isDefined(GridGeometry2D.GRID_TO_CRS_BITMASK)) {
                gridGeometry = new GridGeometry2D(r, PIXEL_IN_CELL,
                        gridGeometry.getGridToCRS(PIXEL_IN_CELL), crs, hints);
            } else {
                /*
 
View Full Code Here

             * - 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 Rectangle queryRect = new Rectangle(
                    x - halfWidth, y - halfWidth,
                    CACHED_RASTER_WIDTH, CACHED_RASTER_WIDTH);

            GridEnvelope gridEnv = reader.getOriginalGridRange();
                Rectangle rect = new Rectangle(
                        gridEnv.getLow(0), gridEnv.getLow(1),
                        gridEnv.getSpan(0), gridEnv.getSpan(1));

            XRectangle2D.intersect(queryRect, rect, queryRect);
            return queryRect;

        } catch (Exception ex) {
View Full Code Here

        final BorderExtender be =  BorderExtender.createInstance(BorderExtender.BORDER_COPY);
        Rectangle  rectangle = PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getBounds();
        rectangle       = new Rectangle(rectangle.x,rectangle.y,rectangle.width+interpolation.getWidth(), rectangle.height+interpolation.getHeight());
        final Raster          data = PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getExtendedData(rectangle,be);
        final Envelope    envelope = coverage.getEnvelope();
        final GridEnvelope   range = coverage.getGridGeometry().getGridRange();
        final double          left = envelope.getMinimum(0);
        final double         upper = envelope.getMaximum(1);
        final Point2D.Double point = new Point2D.Double(); // Will maps to pixel upper-left corner
        for (int j=range.getSpan(1); j>=0;--j) {
            for (int i=range.getSpan(0); i>=0;--i) {
                point.x  = left  + PIXEL_SIZE*i;
                point.y  = upper - PIXEL_SIZE*j;
                buffer   = coverage.evaluate(point, buffer);
                double t = buffer[band];

View Full Code Here

        assertNotNull("Couldn't obtain a reader for " + tableName, reader);

        // http://localhost:8080/geoserver/wms?WIDTH=256&LAYERS=sde%3AIMG_USGSQUAD_SGBASE&STYLES=&SRS=EPSG%3A26986&HEIGHT=256&FORMAT=image%2Fjpeg&TILED=true&TILESORIGIN=169118.35%2C874964.388&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&BBOX=239038.74625,916916.62575,253022.8255,930900.705

        final GeneralEnvelope requestEnvelope =  new GeneralEnvelope(reader.getOriginalEnvelope());
        final GridEnvelope originalGridRange = reader.getOriginalGridRange();

        final int reqWidth = 1000;// originalGridRange.getSpan(0) / 30;
        final int reqHeight = 447;//originalGridRange.getSpan(1) / 30;

View Full Code Here

                        final AbstractGridCoverage2DReader reader = getReader();
                        assertNotNull("Couldn't obtain a reader for " + tableName, reader);

                        final GeneralEnvelope originalEnvelope = reader.getOriginalEnvelope();
                        final GridEnvelope originalGridRange = reader.getOriginalGridRange();

                        final int reqWidth = originalGridRange.getSpan(0) / 200;
                        final int reqHeight = originalGridRange.getSpan(1) / 200;

                        for (int i = 0; i < count; i++) {
                            final GeneralEnvelope reqEnv = new GeneralEnvelope(originalEnvelope);
                            {
                                double dx = (originalEnvelope.getSpan(0) / 2) / (2 * i + 1);
View Full Code Here

TOP

Related Classes of org.opengis.coverage.grid.GridEnvelope

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.