// License: GPL. For details, see LICENSE file.
package pdfimport;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.Properties;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.projection.Projection;
public class FilePlacement {
public Projection projection = null;
public double minX = 0;
public double maxX = 1;
public double minY = 0;
public double maxY = 1;
public double minEast = 0;
public double maxEast = 10000;
public double minNorth = 0;
public double maxNorth = 10000;
private AffineTransform transform;
public void setPdfBounds(double minX, double minY, double maxX, double maxY) {
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;
}
public void setEastNorthBounds(double minEast, double minNorth, double maxEast, double maxNorth) {
this.minEast = minEast;
this.maxEast = maxEast;
this.minNorth = minNorth;
this.maxNorth = maxNorth;
}
public Properties toProperties() {
Properties p = new Properties();
if (projection != null) {
p.setProperty("Projection", projection.toCode());
}
p.setProperty("minX", Double.toString(minX));
p.setProperty("maxX", Double.toString(maxX));
p.setProperty("minY", Double.toString(minY));
p.setProperty("maxY", Double.toString(maxY));
p.setProperty("minEast", Double.toString(minEast));
p.setProperty("maxEast", Double.toString(maxEast));
p.setProperty("minNorth", Double.toString(minNorth));
p.setProperty("maxNorth", Double.toString(maxNorth));
return p;
}
public void fromProperties(Properties p) {
String projectionCode = p.getProperty("Projection", null);
if (projectionCode != null) {
projection = ProjectionInfo.getProjectionByCode(projectionCode);
} else {
projection = null;
}
minX = parseProperty(p, "minX", minX);
maxX = parseProperty(p, "maxX", maxX);
minY = parseProperty(p, "minY", minY);
maxY = parseProperty(p, "maxY", maxY);
minEast = parseProperty(p, "minEast", minEast);
maxEast = parseProperty(p, "maxEast", maxEast);
minNorth = parseProperty(p, "minNorth", minNorth);
maxNorth = parseProperty(p, "maxNorth", maxNorth);
}
private double parseProperty(Properties p, String name, double defaultValue) {
if (!p.containsKey(name)) {
return defaultValue;
}
String value = p.getProperty(name);
try {
return Double.parseDouble(value);
} catch (Exception e) {
return defaultValue;
}
}
public String prepareTransform() {
if (this.minX > this.maxX) {
return tr("Transform error: Min X must be smaller than max");
}
if (this.minY > this.maxY) {
return tr("Transform error: Min Y must be smaller than max");
}
if (Math.abs(this.minY - this.maxY) < 1 &&
Math.abs(this.minX - this.maxX) < 1) {
return tr("Transform error: Points too close");
} else if (Math.abs(this.minX - this.maxX) < 1) {
//x axis equal, assume same scale in both dimensions
if (this.minEast == this.maxEast) {
//no rotation
this.maxX = this.minX + this.maxY - this.minY;
this.maxEast = this.minEast + this.maxNorth - this.minNorth;
} else if (this.minNorth == this.maxNorth) {
//needs rotated 90 degrees clockwise, or counter
this.maxX = this.minX + this.maxY - this.minY;
this.maxNorth = this.minNorth - (this.maxEast - this.minEast);
} else {
return tr("Transform error: Unsupported variant.");
}
} else if (Math.abs(this.minY - this.maxY) < 1) {
//Y axis equal, assume same scale in both dimensions
if (this.minNorth == this.maxNorth) {
//no rotation
this.maxY = this.minY + this.maxX - this.minX;
this.maxNorth = this.minNorth + this.maxEast - this.minEast;
} else if (this.minEast == this.maxEast) {
//needs rotated 90 degrees clockwise, or counter
this.maxY = this.minY + this.maxX - this.minX;
this.maxEast = this.minEast - (this.maxNorth - this.minNorth);
} else {
return tr("Transform error: Unsupported variant.");
}
}
if (this.minEast < this.maxEast && this.minNorth < this.maxNorth) {
//no rotation
this.transform = new AffineTransform();
this.transform.translate(this.minEast, this.minNorth);
this.transform.scale(
(this.maxEast - this.minEast) / (this.maxX - this.minX),
(this.maxNorth - this.minNorth) / (this.maxY - this.minY));
this.transform.translate(-this.minX, -this.minY);
} else if (this.minEast > this.maxEast && this.minNorth < this.maxNorth) {
//need to rotate 90 degrees counterclockwise
this.transform = new AffineTransform();
//transform to 0..1, 0..1 range
this.transform.preConcatenate(AffineTransform.getTranslateInstance(-this.minX, -this.minY));
this.transform.preConcatenate(AffineTransform.getScaleInstance(1/(this.maxX - this.minX), 1/(this.maxY - this.minY)));
//rotate -90 degs around min
this.transform.preConcatenate(AffineTransform.getQuadrantRotateInstance(1, 0, 0));
//transform back to target range
this.transform.preConcatenate(AffineTransform.getScaleInstance(
(this.minEast - this.maxEast),
(this.maxNorth - this.minNorth)));
this.transform.preConcatenate(AffineTransform.getTranslateInstance(this.minEast, this.minNorth));
} else if (this.minEast < this.maxEast && this.minNorth > this.maxNorth) {
//need to rotate 90 degrees clockwise
this.transform = new AffineTransform();
//transform to 0..1, 0..1 range
this.transform.preConcatenate(AffineTransform.getTranslateInstance(-this.minX, -this.minY));
this.transform.preConcatenate(AffineTransform.getScaleInstance(1/(this.maxX - this.minX), 1/(this.maxY - this.minY)));
//rotate 90 degs around min
this.transform.preConcatenate(AffineTransform.getQuadrantRotateInstance(-1, 0, 0));
//transform back to target range
this.transform.preConcatenate(AffineTransform.getScaleInstance(
(this.maxEast - this.minEast),
(this.minNorth - this.maxNorth)));
this.transform.preConcatenate(AffineTransform.getTranslateInstance(this.minEast, this.minNorth));
} else {
return tr("Transform error: Unsupported orientation");
}
return null;
}
EastNorth en = new EastNorth(0, 0);
Point2D src = new Point2D.Double();
public Bounds getWorldBounds(PathOptimizer data) {
LatLon min = this.tranformCoords(new Point2D.Double(data.bounds.getMinX(), data.bounds.getMinY()));
LatLon max = this.tranformCoords(new Point2D.Double(data.bounds.getMaxX(), data.bounds.getMaxY()));
return new Bounds(min, max);
}
public LatLon tranformCoords(Point2D pt) {
if (this.projection == null) {
return new LatLon(pt.getY() / 1000, pt.getX() / 1000);
} else {
Point2D dest = new Point2D.Double();
this.transform.transform(pt, dest);
en = new EastNorth(dest.getX(), dest.getY());
return this.projection.eastNorth2latlon(en);
}
}
public EastNorth reverseTransform(LatLon coor) {
if (this.projection == null) {
return new EastNorth(coor.lon() * 1000, coor.lat() * 1000);
} else {
return null;
}
}
}