package au.gov.amsa.geo.projection;
import java.awt.Point;
import java.awt.geom.Point2D;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import au.gov.amsa.util.navigation.Position;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
* Uses geotools libraries to perform transformations between coordinate
* reference systems
*
* @author dxm
*
*/
public class Projector {
private final ProjectorTarget target;
private final ProjectorBounds bounds;
private final MathTransform transform;
private final GeometryFactory geometryFactory;
public Projector(ProjectorBounds bounds, ProjectorTarget target) {
this.target = target;
this.bounds = bounds;
try {
transform = CRS.findMathTransform(
FeatureUtil.getCrs(FeatureUtil.EPSG_4326),
FeatureUtil.getCrs(bounds.getSrs()));
} catch (FactoryException e) {
throw new RuntimeException(e);
}
geometryFactory = new GeometryFactory();
}
public Point toPoint(double lat, double lon) {
Point2D point2D = toPoint2D(lat, lon);
Point p = new Point();
p.x = (int) Math.round(point2D.getX());
p.y = (int) Math.round(point2D.getY());
return p;
}
public Point2D.Double toPointInSrs(double lat, double lon) {
Coordinate coordinate = new Coordinate(lon, lat);
com.vividsolutions.jts.geom.Point point = geometryFactory
.createPoint(coordinate);
try {
point = (com.vividsolutions.jts.geom.Point) JTS.transform(point,
transform);
return new Point2D.Double(point.getX(), point.getY());
} catch (MismatchedDimensionException e) {
throw new RuntimeException(e);
} catch (TransformException e) {
throw new RuntimeException(e);
}
}
public Point2D.Double toPoint2D(double lat, double lon) {
Coordinate coordinate = new Coordinate(lon, lat);
com.vividsolutions.jts.geom.Point point = geometryFactory
.createPoint(coordinate);
try {
point = (com.vividsolutions.jts.geom.Point) JTS.transform(point,
transform);
} catch (MismatchedDimensionException e) {
throw new RuntimeException(e);
} catch (TransformException e) {
throw new RuntimeException(e);
}
double proportionX = (point.getX() - bounds.getMinX())
/ (bounds.getMaxX() - bounds.getMinX());
double proportionY = (bounds.getMaxY() - point.getY())
/ (bounds.getMaxY() - bounds.getMinY());
Point2D.Double point2D = new Point2D.Double(proportionX
* target.getWidth(), proportionY * target.getHeight());
return point2D;
}
public Position toPosition(double targetX, double targetY) {
double proportionX = targetX / target.getWidth();
double proportionY = targetY / target.getHeight();
double x = proportionX * (bounds.getMaxX() - bounds.getMinX())
+ bounds.getMinX();
double y = bounds.getMaxY() - proportionY
* (bounds.getMaxY() - bounds.getMinY());
Coordinate coordinate = new Coordinate(x, y);
com.vividsolutions.jts.geom.Point point = geometryFactory
.createPoint(coordinate);
try {
point = (com.vividsolutions.jts.geom.Point) JTS.transform(point,
transform.inverse());
} catch (MismatchedDimensionException e) {
throw new RuntimeException(e);
} catch (TransformException e) {
throw new RuntimeException(e);
}
return new Position(point.getY(), point.getX());
}
@Override
public String toString() {
return "ProjectorImpl [target=" + target + ", bounds=" + bounds + "]";
}
}