package sec.geo; import armyc2.c2sd.graphics2d.*; import java.util.ArrayList; import org.gavaghan.geodesy.Angle; import org.gavaghan.geodesy.Ellipsoid; import org.gavaghan.geodesy.GeodeticCalculator; import org.gavaghan.geodesy.GeodeticCurve; import org.gavaghan.geodesy.GlobalCoordinates; public class GeoArc /*extends GeoPath*/ { protected static final Ellipsoid REFERENCE_ELLIPSOID = Ellipsoid.WGS84; private GeneralPath path = null; private ArrayList<GeoPoint> toPoints; private double maxDistanceMeters; private double flatnessDistanceMeters; private int limit; protected final GeodeticCalculator geoCalc; public GeoArc(GeoPoint pivot, double widthMeters, double heightMeters, double leftAzimuth, double rightAzimuth, double maxDistanceMeters, double flatnessDistanceMeters, int limit) { //super(maxDistanceMeters, flatnessDistanceMeters, limit); path = new GeneralPath(); toPoints = new ArrayList<GeoPoint>(); geoCalc = new GeodeticCalculator(); this.maxDistanceMeters = maxDistanceMeters; this.flatnessDistanceMeters = flatnessDistanceMeters; this.limit = limit; moveTo(pivot); arcTo(pivot, widthMeters, heightMeters, leftAzimuth, rightAzimuth); closePath(); } public final void moveTo(GeoPoint point) { path.moveTo(point.x, point.y); toPoints.add(point); } public void moveToLatLong(double longitudeDegrees, double latitudeDegrees) { moveTo(new GeoPoint(longitudeDegrees, latitudeDegrees)); } public void lineTo(GeoPoint point) { GeneralPath newPath = new GeneralPath(); // Move to the initial point GeoPoint lastPoint = new GeoPoint(); if (toPoints.size() > 0) { lastPoint = toPoints.get(toPoints.size() - 1); newPath.moveTo(lastPoint.x, lastPoint.y); } // Calculate the curve to the new point GlobalCoordinates start = toGlobalCoord(lastPoint); GlobalCoordinates end = toGlobalCoord(point); GeodeticCurve curve = geoCalc.calculateGeodeticCurve(REFERENCE_ELLIPSOID, start, end); // Generate points along the curve, adding them to the new path double distance = maxDistanceMeters; while (distance < curve.getEllipsoidalDistance()) { GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, start, curve .getAzimuth(), distance); newPath.lineTo(c.getLongitude(), c.getLatitude()); distance += maxDistanceMeters; } newPath.lineTo(point.x, point.y); // Append the new path to the existing path path.append(newPath, true); toPoints.add(point); } public void lineToLatLong(double longitudeDegrees, double latitudeDegrees) { lineTo(new GeoPoint(longitudeDegrees, latitudeDegrees)); } public final void arcTo(GeoPoint pivot, double widthMeters, double heightMeters, double leftAzimuthDegrees, double rightAzimuthDegrees) { GeneralPath newPath = new GeneralPath(); Arc2D arc; if (leftAzimuthDegrees > rightAzimuthDegrees) { arc = new Arc2D(-widthMeters / 2, -heightMeters / 2, widthMeters, heightMeters, leftAzimuthDegrees - 90, Math.abs((360 - leftAzimuthDegrees) + rightAzimuthDegrees), Arc2D.OPEN); } else { arc = new Arc2D(-widthMeters / 2, -heightMeters / 2, widthMeters, heightMeters, leftAzimuthDegrees - 90, Math.abs(leftAzimuthDegrees - rightAzimuthDegrees), Arc2D.OPEN); } GeoPoint point = null; if (pivot != null) { FlatteningPathIterator it = new FlatteningPathIterator(arc.getPathIterator(null), flatnessDistanceMeters, limit); while (!it.isDone()) { // Add a point to the list for each segment flattened from the curve double[] strokePoints = new double[6]; int type = it.currentSegment(strokePoints); double x = strokePoints[0]; double y = strokePoints[1]; double azimuth = Angle.toDegrees(Math.atan2(x, y)); GlobalCoordinates coord = new GlobalCoordinates(pivot.getLatitude(), pivot.getLongitude()); GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, coord, azimuth, //new Point2D.Double(0,0).distance(x, y)); Point2D.distance(0, 0, x, y)); switch (type) { case PathIterator.SEG_MOVETO: newPath.moveTo(c.getLongitude(), c.getLatitude()); GeoPoint startPoint = new GeoPoint(c.getLongitude(), c.getLatitude()); if (toPoints.size() > 0 && !startPoint.equals(toPoints.get(toPoints.size() - 1))) { lineTo(startPoint); } break; case PathIterator.SEG_LINETO: newPath.lineTo(c.getLongitude(), c.getLatitude()); point = new GeoPoint(c.getLongitude(), c.getLatitude()); break; } it.next(); } } path.append(newPath, true); toPoints.add(point); } public ArrayList<GeoPoint> getToPoints() { return toPoints; } public final void closePath() { if(toPoints.get(0)!=null && toPoints.get(toPoints.size() - 1) != null) if (toPoints.size() > 0 && !toPoints.get(0).equals(toPoints.get(toPoints.size() - 1))) { lineTo(toPoints.get(0)); } } public PathIterator getPathIterator(AffineTransform at) { return path.getPathIterator(at); } public String toString() { return toPoints.toString(); } protected GlobalCoordinates toGlobalCoord(GeoPoint point) { return new GlobalCoordinates(point.getLatitude(), point.getLongitude()); } }