mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
83871a0336
#issue[65] #fix
123 lines
4.5 KiB
Java
123 lines
4.5 KiB
Java
package seng302.model;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import javafx.geometry.Point2D;
|
|
import seng302.utilities.GeoUtility;
|
|
|
|
/**
|
|
* Contains information on a scaled lat lon point for use with mapping geographical elements to a 2d plane.
|
|
*/
|
|
public class ScaledPoint extends GeoPoint {
|
|
|
|
public enum ScaleDirection {
|
|
HORIZONTAL,
|
|
VERTICAL
|
|
}
|
|
|
|
private double x, y, scaleFactor;
|
|
private ScaleDirection scaleDirection;
|
|
|
|
private ScaledPoint(double lat, double lng, double x, double y, double scaleFactor, ScaleDirection direction) {
|
|
super(lat, lng);
|
|
this.x = x;
|
|
this.y = y;
|
|
this.scaleFactor = scaleFactor;
|
|
this.scaleDirection = direction;
|
|
}
|
|
|
|
public double getX() {
|
|
return x;
|
|
}
|
|
|
|
public double getY() {
|
|
return y;
|
|
}
|
|
|
|
public double getScaleFactor() {
|
|
return scaleFactor;
|
|
}
|
|
|
|
public ScaleDirection getScaleDirection() {
|
|
return scaleDirection;
|
|
}
|
|
|
|
public Point2D findScaledXY(GeoPoint unscaled) {
|
|
return findScaledXY(unscaled.getLat(), unscaled.getLng());
|
|
}
|
|
|
|
public Point2D findScaledXY(double unscaledLat, double unscaledLon) {
|
|
double distanceFromReference;
|
|
double angleFromReference;
|
|
double xReference = this.getX();
|
|
double yReference = this.getY();
|
|
|
|
angleFromReference = GeoUtility.getBearingRad(
|
|
this, new GeoPoint(unscaledLat, unscaledLon)
|
|
);
|
|
distanceFromReference = GeoUtility.getDistance(
|
|
this, new GeoPoint(unscaledLat, unscaledLon)
|
|
);
|
|
if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) {
|
|
xReference += scaleFactor * Math.sin(angleFromReference) * distanceFromReference;
|
|
yReference -= scaleFactor * Math.cos(angleFromReference) * distanceFromReference;
|
|
} else if (angleFromReference >= 0) {
|
|
angleFromReference = angleFromReference - Math.PI / 2;
|
|
xReference += scaleFactor * Math.cos(angleFromReference) * distanceFromReference;
|
|
yReference += scaleFactor * Math.sin(angleFromReference) * distanceFromReference;
|
|
} else if (angleFromReference < 0 && angleFromReference >= -Math.PI / 2) {
|
|
angleFromReference = Math.abs(angleFromReference);
|
|
xReference -= scaleFactor * Math.sin(angleFromReference) * distanceFromReference;
|
|
yReference -= scaleFactor * Math.cos(angleFromReference) * distanceFromReference;
|
|
} else {
|
|
angleFromReference = Math.abs(angleFromReference) - Math.PI / 2;
|
|
xReference -= scaleFactor * Math.cos(angleFromReference) * distanceFromReference;
|
|
yReference += scaleFactor * Math.sin(angleFromReference) * distanceFromReference;
|
|
}
|
|
return new Point2D(xReference, yReference);
|
|
}
|
|
|
|
public static ScaledPoint makeScaledPoint(double width, double height,
|
|
List<? extends GeoPoint> points, boolean centered) {
|
|
|
|
double referencePointX, referencePointY, scaleFactor, lat, lng;
|
|
ScaleDirection scaleDirection;
|
|
points = new ArrayList<>(points);
|
|
points.sort(Comparator.comparingDouble(GeoPoint::getLat));
|
|
GeoPoint minLatPoint = points.get(0);
|
|
GeoPoint maxLatPoint = points.get(points.size() - 1);
|
|
|
|
points.sort(Comparator.comparingDouble(GeoPoint::getLng));
|
|
GeoPoint minLonPoint = points.get(0);
|
|
GeoPoint maxLonPoint = points.get(points.size() - 1);
|
|
|
|
referencePointX = centered ? 0 : width / 2;
|
|
referencePointY = centered ? 0 : height / 2;
|
|
|
|
lat = (maxLatPoint.getLat() - minLatPoint.getLat()) / 2 + minLatPoint.getLat();
|
|
lng = (maxLonPoint.getLng() - minLonPoint.getLng()) / 2 + minLonPoint.getLng();
|
|
|
|
GeoPoint ref = new GeoPoint(lat, lng);
|
|
|
|
double vertDistance = GeoUtility.getDistance(
|
|
ref, new GeoPoint(ref.getLat(), maxLonPoint.getLng())
|
|
) * 2.1;
|
|
|
|
double horiDistance = GeoUtility.getDistance(
|
|
ref, new GeoPoint(maxLatPoint.getLat(), ref.getLng())
|
|
) * 2.1;
|
|
|
|
double vertScale = height / vertDistance;
|
|
|
|
if (horiDistance * vertScale > width) {
|
|
scaleFactor = width / horiDistance;
|
|
scaleDirection = ScaleDirection.HORIZONTAL;
|
|
} else {
|
|
scaleFactor = vertScale;
|
|
scaleDirection = ScaleDirection.VERTICAL;
|
|
}
|
|
return new ScaledPoint(lat, lng, referencePointX, referencePointY, scaleFactor, scaleDirection);
|
|
}
|
|
}
|