/** @param file */ public void export(File file) { LOG.debug("Writing index file for directory..."); ObjectOutputStream out = null; try { out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); out.writeObject(qtree); out.writeObject(createEnvelope(envelope)); out.writeObject(rasterDataInfo); out.writeObject(rasterGeoReference.getOriginLocation()); out.writeDouble(rasterGeoReference.getResolutionX()); out.writeDouble(rasterGeoReference.getResolutionY()); out.writeDouble(rasterGeoReference.getRotationX()); out.writeDouble(rasterGeoReference.getRotationY()); out.writeDouble(rasterGeoReference.getOriginEasting()); out.writeDouble(rasterGeoReference.getOriginNorthing()); out.writeObject(rasterGeoReference.getCrs()); out.writeObject(resolutionInfo); out.writeObject(options); LOG.debug("Done."); } catch (IOException e) { LOG.debug( "Raster pyramid file '{}' could not be written: '{}'.", file, e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } finally { if (out != null) { try { out.close(); } catch (IOException e) { LOG.debug( "Raster pyramid file '{}' could not be closed: '{}'.", file, e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } } } }
/** * Creates a new empty SimpleRaster with same DataType and InterleaveType. Size is determined by * the given envelope. * * @param rEnv The raster envelope of the new SimpleRaster. * @param env The boundary of the new SimpleRaster. * @return A new empty SimpleRaster. */ public SimpleRaster createCompatibleSimpleRaster(RasterGeoReference rEnv, Envelope env) { int[] size = rEnv.getSize(env); RasterRect rasterRect = new RasterRect(0, 0, size[0], size[1]); RasterData data = this.getRasterData(); BandType[] bands = data.getDataInfo().bandInfo; RasterData newRaster = data.createCompatibleWritableRasterData(rasterRect, bands); return new SimpleRaster(newRaster, env, rEnv, metadata); }
private WarpPolynomial createWarp( int dstWidth, int dstHeight, ICRS srcCRS, RasterGeoReference srcREnv, RasterGeoReference dstREnv) throws TransformationException { int k = 0; // create/calculate reference points float dx = (dstWidth - 1) / (float) (refPointsGridSize - 1); float dy = (dstHeight - 1) / (float) (refPointsGridSize - 1); float[] srcCoords = new float[refPointsGridSize * refPointsGridSize * 2]; float[] dstCoords = new float[refPointsGridSize * refPointsGridSize * 2]; List<Point3d> points = new ArrayList<Point3d>(refPointsGridSize * refPointsGridSize); for (int j = 0; j < refPointsGridSize; j++) { for (int i = 0; i < refPointsGridSize; i++) { dstCoords[k] = i * dx; dstCoords[k + 1] = j * dy; double[] dstWCoords = dstREnv.getWorldCoordinate((int) dstCoords[k], (int) dstCoords[k + 1]); points.add(new Point3d(dstWCoords[0], dstWCoords[1], Double.NaN)); k += 2; } } List<Point3d> resultList = transformDstToSrc(srcCRS, points); k = 0; for (Point3d point : resultList) { double[] srcRCoords = srcREnv.getRasterCoordinateUnrounded(point.x, point.y); srcCoords[k] = (float) srcRCoords[0]; srcCoords[k + 1] = (float) srcRCoords[1]; k += 2; } // create a best fit polynomial for out grid WarpPolynomial warp = WarpPolynomial.createWarp( srcCoords, 0, dstCoords, 0, srcCoords.length, 1f, 1f, 1f, 1f, polynomialOrder); return warp; }
/** * Creates a transformed raster from a given source raster. * * <p>This method transforms the requested envelope and returns a new raster with the requested * size. The source raster can be larger than the requested envelope (like a large tiled raster), * or smaller (the source raster nodata value will be used outside the source raster). * * <p>If the dstEnvelope does not contain a CRS or the CRS is the same as the {@link * AbstractRaster#getCoordinateSystem()} only interpolation will be applied. If the requested size * is the same as the number of rows/columns of the source raster, only the subset of the given * raster will be returned, without interpolation being applied. * * @param sourceRaster the source raster * @param dstEnvelope the requested envelope (already in the target crs) * @param dstWidth the requested raster size * @param dstHeight the requested raster size * @param interpolationType the type of the interpolation * @return the transformed raster * @throws TransformationException */ public AbstractRaster transform( AbstractRaster sourceRaster, Envelope dstEnvelope, int dstWidth, int dstHeight, InterpolationType interpolationType) throws TransformationException { synchronized (sourceRaster) { ICRS srcCRS = sourceRaster.getCoordinateSystem(); // get the (transformed) subraster which intersects with the given envelope. AbstractRaster source = getSubRaster(srcCRS, sourceRaster, dstEnvelope); if (source.getColumns() == dstHeight && source.getRows() == dstWidth) { // no need to interpolate. return source; } SimpleRaster simpleSourceRaster = source.getAsSimpleRaster(); RasterData srcData = simpleSourceRaster.getReadOnlyRasterData(); RasterGeoReference srcREnv = simpleSourceRaster.getRasterReference(); if (backgroundValue != null) { srcData.setNoDataValue(backgroundValue); } // interpolation is needed. Interpolation interpolation = InterpolationFactory.getInterpolation(interpolationType, srcData); RasterRect rr = new RasterRect(0, 0, dstWidth, dstHeight); RasterData dstData = srcData.createCompatibleWritableRasterData(rr, null); RasterGeoReference dstREnv = RasterGeoReference.create( sourceRaster.getRasterReference().getOriginLocation(), dstEnvelope, dstWidth, dstHeight); // use warp to calculate the correct sample positions in the source raster. // the warp is a cubic polynomial function created of 100 points in the dstEnvelope. This // function will map // points from the source crs to the target crs very accurate. WarpPolynomial warp = createWarp(dstWidth, dstHeight, srcCRS, srcREnv, dstREnv); warpTransform(warp, interpolation, dstData); return new SimpleRaster(dstData, dstEnvelope, dstREnv, null); } }
/** @param file */ public DiskBasedTileContainer(File file) { ObjectInputStream in = null; LOG.debug("Reading index file for directory..."); try { in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))); qtree = (QTree<File>) in.readObject(); envelope = createEnvelope((float[]) in.readObject(), null); rasterDataInfo = (RasterDataInfo) in.readObject(); rasterGeoReference = new RasterGeoReference( (OriginLocation) in.readObject(), in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), in.readDouble(), (CRS) in.readObject()); envelope.setCoordinateSystem(rasterGeoReference.getCrs()); resolutionInfo = (ResolutionInfo) in.readObject(); options = (RasterIOOptions) in.readObject(); initialized = true; LOG.debug("Done."); } catch (FileNotFoundException e) { LOG.debug("Raster pyramid file '{}' could not be found.", file); LOG.trace("Stack trace:", e); } catch (IOException e) { LOG.debug("Raster pyramid file '{}' could not be read: '{}'", file, e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } catch (ClassNotFoundException e) { LOG.debug("Raster pyramid file '{}' was in the wrong format.", file); LOG.trace("Stack trace:", e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { LOG.debug( "Raster pyramid file '{}' could not be closed: '{}'.", file, e.getLocalizedMessage()); LOG.trace("Stack trace:", e); } } } }
/** * Merge two Raster references. Returns a new RasterReference where the upper-left corner is set * to the values of the smallest upper and smallest left ordinate. The resolution is set to the * minimum value (i.e. the highest resolution [unit/pixel]). Some assumptions are made (not * checked): * * <ul> * <li>The pixel location (center/outer) of the origin are equal, if not, the location of the * first reference will be used (translated origin of second) * <li>Crs is identical * <li>rotation around axis are equal * </ul> * * @param geoRef1 * @param geoRef2 * @return new RasterReference */ public static RasterGeoReference merger(RasterGeoReference geoRef1, RasterGeoReference geoRef2) { if (geoRef1 == null) { return geoRef2; } if (geoRef2 == null) { return geoRef1; } RasterGeoReference geoRef2Copy = geoRef2; if (geoRef1.location != geoRef2.location) { double[] orig = geoRef2.getOrigin(geoRef1.location); geoRef2Copy = new RasterGeoReference( geoRef1.location, geoRef2.getResolutionX(), geoRef2.getResolutionY(), geoRef2.getRotationX(), geoRef2.getRotationY(), orig[0], orig[1], geoRef2.crs); } double[] origin1 = geoRef1.getOrigin(); double[] origin2 = geoRef2Copy.getOrigin(); double res1x = geoRef1.getResolutionX(); double res1y = geoRef1.getResolutionY(); double res2x = geoRef2Copy.getResolutionX(); double res2y = geoRef2Copy.getResolutionY(); double nResx = (res1x < 0) ? max(res1x, res2x) : min(res1x, res2x); double nResy = (res1y < 0) ? max(res1y, res2y) : min(res1y, res2y); double nOrigx = (res1x < 0) ? max(origin1[0], origin2[0]) : min(origin1[0], origin2[0]); double nOrigy = (res1y < 0) ? max(origin1[1], origin2[1]) : min(origin1[1], origin2[1]); return new RasterGeoReference( geoRef1.location, nResx, nResy, geoRef1.getRotationX(), geoRef1.getRotationY(), nOrigx, nOrigy, geoRef1.crs); }