package com.revolsys.raster; import java.awt.geom.AffineTransform; import java.util.Map; import com.revolsys.beans.AbstractPropertyChangeSupportProxy; import com.revolsys.collection.map.LinkedHashMapEx; import com.revolsys.collection.map.MapEx; import com.revolsys.collection.map.Maps; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.GeometryFactoryProxy; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.impl.PointDoubleXY; import com.revolsys.io.map.MapSerializer; public class MappedLocation extends AbstractPropertyChangeSupportProxy implements GeometryFactoryProxy, MapSerializer { public static Point targetPointToPixel(final BoundingBox boundingBox, final Point point, final int imageWidth, final int imageHeight) { return toImagePoint(boundingBox, point, imageWidth, imageHeight); } public static Point toImagePoint(final BoundingBox boundingBox, Point modelPoint, final int imageWidth, final int imageHeight) { modelPoint = modelPoint.convertPoint2d(boundingBox.getGeometryFactory()); final double modelX = modelPoint.getX(); final double modelY = modelPoint.getY(); final double modelDeltaX = modelX - boundingBox.getMinX(); final double modelDeltaY = modelY - boundingBox.getMinY(); final double modelWidth = boundingBox.getWidth(); final double modelHeight = boundingBox.getHeight(); final double xRatio = modelDeltaX / modelWidth; final double yRatio = modelDeltaY / modelHeight; final double imageX = imageWidth * xRatio; final double imageY = imageHeight * yRatio; return new PointDoubleXY(imageX, imageY); } public static double[] toModelCoordinates(final GeoreferencedImage image, final BoundingBox boundingBox, final boolean useTransform, final double... coordinates) { double[] targetCoordinates; if (useTransform) { targetCoordinates = new double[10]; final AffineTransform transform = image.getAffineTransformation(boundingBox); transform.transform(coordinates, 0, targetCoordinates, 0, coordinates.length / 2); } else { targetCoordinates = coordinates.clone(); } final int imageWidth = image.getImageWidth(); final int imageHeight = image.getImageHeight(); for (int vertexIndex = 0; vertexIndex < coordinates.length / 2; vertexIndex++) { final int vertexOffset = vertexIndex * 2; final double xPercent = targetCoordinates[vertexOffset] / imageWidth; final double yPercent = (imageHeight - targetCoordinates[vertexOffset + 1]) / imageHeight; final double modelWidth = boundingBox.getWidth(); final double modelHeight = boundingBox.getHeight(); final double modelX = boundingBox.getMinX() + modelWidth * xPercent; final double modelY = boundingBox.getMinY() + modelHeight * yPercent; targetCoordinates[vertexOffset] = modelX; targetCoordinates[vertexOffset + 1] = modelY; } return targetCoordinates; } private GeometryFactory geometryFactory = GeometryFactory.floating(0, 2); private Point sourcePixel; private Point targetPoint; public MappedLocation(final Map<String, Object> map) { final double sourceX = Maps.getDouble(map, "sourceX", 0.0); final double sourceY = Maps.getDouble(map, "sourceY", 0.0); this.sourcePixel = new PointDoubleXY(sourceX, sourceY); this.targetPoint = this.geometryFactory.geometry((String)map.get("target")); } public MappedLocation(final Point sourcePixel, final Point targetPoint) { this.sourcePixel = sourcePixel; this.targetPoint = targetPoint; this.geometryFactory = targetPoint.getGeometryFactory().convertAxisCount(2); } @Override public GeometryFactory getGeometryFactory() { return this.geometryFactory; } public Point getSourcePixel() { return this.sourcePixel; } public double getSourcePixelX() { return this.sourcePixel.getX(); } public double getSourcePixelY() { return this.sourcePixel.getY(); } public Point getSourcePoint(final GeoreferencedImage image, final BoundingBox boundingBox, final boolean useTransform) { final Point sourcePixel = getSourcePixel(); final double[] sourcePoint = toModelCoordinates(image, boundingBox, useTransform, sourcePixel.getX(), image.getImageHeight() - sourcePixel.getY()); final GeometryFactory geometryFactory = boundingBox.getGeometryFactory(); return geometryFactory.point(sourcePoint[0], sourcePoint[1]); } public LineString getSourceToTargetLine(final GeoreferencedImage image, final BoundingBox boundingBox, final boolean useTransform) { final Point sourcePixel = getSourcePixel(); final double[] sourcePoint = toModelCoordinates(image, boundingBox, useTransform, sourcePixel.getX(), image.getImageHeight() - sourcePixel.getY()); final GeometryFactory geometryFactory = boundingBox.getGeometryFactory(); final double sourceX = sourcePoint[0]; final double sourceY = sourcePoint[1]; final Point targetPoint = getTargetPoint().convertGeometry(geometryFactory); final double targetX = targetPoint.getX(); final double targetY = targetPoint.getY(); return geometryFactory.lineString(2, sourceX, sourceY, targetX, targetY); } public Point getTargetPixel(final BoundingBox boundingBox, final int imageWidth, final int imageHeight) { final GeometryFactory geometryFactory = boundingBox.getGeometryFactory(); final Point targetPointCoordinates = this.targetPoint.convertPoint2d(geometryFactory); return targetPointToPixel(boundingBox, targetPointCoordinates, imageWidth, imageHeight); } // public Point getSourcePoint(final WarpFilter filter, // final BoundingBox boundingBox) { // if (filter == null) { // return null; // } else { // final Point sourcePixel = getSourcePixel(); // final Point sourcePoint = filter.sourcePixelToTargetPoint(boundingBox, // sourcePixel); // final GeometryFactory geometryFactory = filter.getGeometryFactory(); // return geometryFactory.point(sourcePoint); // } // } public Point getTargetPoint() { return this.targetPoint; } public double getTargetPointX() { return this.targetPoint.getX(); } public double getTargetPointY() { return this.targetPoint.getY(); } public void setGeometryFactory(final GeometryFactory geometryFactory) { this.geometryFactory = geometryFactory.convertAxisCount(2); this.targetPoint = this.targetPoint.convertGeometry(this.geometryFactory); } public void setSourcePixel(final Point sourcePixel) { final Object oldValue = this.sourcePixel; this.sourcePixel = sourcePixel; firePropertyChange("sourcePixel", oldValue, sourcePixel); } public void setTargetPoint(final Point targetPoint) { final Object oldValue = this.targetPoint; this.targetPoint = targetPoint; firePropertyChange("targetPoint", oldValue, targetPoint); } @Override public MapEx toMap() { final MapEx map = new LinkedHashMapEx(); map.put("sourceX", this.sourcePixel.getX()); map.put("sourceY", this.sourcePixel.getY()); map.put("target", this.targetPoint.toEwkt()); return map; } @Override public String toString() { return this.sourcePixel + "->" + this.targetPoint; } }