package com.revolsys.raster; import java.awt.Rectangle; import java.awt.image.BufferedImage; import com.revolsys.geometry.cs.CoordinateSystem; import com.revolsys.geometry.cs.projection.CoordinatesOperation; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.GeometryFactory; public class ProjectionImageFilter extends WholeImageFilter { private static final long serialVersionUID = 1L; private final BoundingBox destBoundingBox; private final int destHeight; private final double destPixelSize; private final int destWidth; private final BoundingBox sourceBoundingBox; public ProjectionImageFilter(final BoundingBox imageBoundingBox, final CoordinateSystem destCoordinateSystem, final double resolution) { this(imageBoundingBox, destCoordinateSystem.getGeometryFactory(), resolution); } public ProjectionImageFilter(final BoundingBox sourceBoundingBox, final GeometryFactory destGeometryFactory, final double destPixelSize) { this.sourceBoundingBox = sourceBoundingBox; this.destBoundingBox = sourceBoundingBox.convert(destGeometryFactory); this.destPixelSize = destPixelSize; final double width = this.destBoundingBox.getWidth(); this.destWidth = (int)(width / destPixelSize); final double height = this.destBoundingBox.getHeight(); this.destHeight = (int)(height / destPixelSize); } public BufferedImage filter(final BufferedImage source) { if (this.destWidth < 1 || this.destHeight < 1) { return source; } else { final BufferedImage dest = new BufferedImage(this.destWidth, this.destHeight, BufferedImage.TYPE_INT_ARGB); return super.filter(source, dest); } } @Override protected int[] filterPixels(final int imageWidth, final int imageHeight, final int[] inPixels, final Rectangle transformedSpace) { final int[] outPixels = new int[transformedSpace.width * transformedSpace.height]; final double minX = this.sourceBoundingBox.getMinX(); final double minY = this.sourceBoundingBox.getMinY(); final double width = this.sourceBoundingBox.getWidth(); final double height = this.sourceBoundingBox.getHeight(); final double pixelWidth = width / imageWidth; final double pixelHeight = height / imageHeight; final double newMinX = this.destBoundingBox.getMinX(); final double newMaxY = this.destBoundingBox.getMaxY(); final int newImageWidth = transformedSpace.width; final int newImageHeight = transformedSpace.height; final GeometryFactory sourceGeometryFactory = this.sourceBoundingBox.getGeometryFactory(); final GeometryFactory destGeometryFactory = this.destBoundingBox.getGeometryFactory(); final CoordinatesOperation operation = destGeometryFactory .getCoordinatesOperation(sourceGeometryFactory); if (operation == null) { return inPixels; } final double[] source = new double[2]; final double[] dest = new double[2]; for (int i = 0; i < newImageWidth; i++) { final double newImageX = newMinX + i * this.destPixelSize; dest[0] = newImageX; for (int j = 0; j < newImageHeight; j++) { final double newImageY = newMaxY - j * this.destPixelSize; dest[1] = newImageY; operation.perform(2, dest, 2, source); final double imageX = source[0]; final double imageY = source[1]; final int imageI = (int)((imageX - minX) / pixelWidth); final int imageJ = imageHeight - (int)((imageY - minY) / pixelHeight); if (imageI > -1 && imageI < imageWidth) { if (imageJ > -1 && imageJ < imageHeight) { final int rgb = inPixels[imageJ * imageWidth + imageI]; if (rgb != -1) { outPixels[j * newImageWidth + i] = rgb; // // TODO better interpolation } } } } } return outPixels; } public BoundingBox getDestBoundingBox() { return this.destBoundingBox; } public int getDestHeight() { return this.destHeight; } public int getDestWidth() { return this.destWidth; } @Override protected void transformSpace(final Rectangle rect) { super.transformSpace(rect); rect.width = this.destWidth; rect.height = this.destHeight; } }