001package sec.geo; 002 003import java.util.ArrayList; 004import armyc2.c2sd.graphics2d.*; 005import org.gavaghan.geodesy.Angle; 006import org.gavaghan.geodesy.Ellipsoid; 007import org.gavaghan.geodesy.GeodeticCalculator; 008import org.gavaghan.geodesy.GeodeticCurve; 009import org.gavaghan.geodesy.GlobalCoordinates; 010 011public class GeoEllipse /* extends GeoPath */ { 012 013 protected static final Ellipsoid REFERENCE_ELLIPSOID = Ellipsoid.WGS84; 014 015 //private final Path2D path; 016 private GeneralPath path; 017 private ArrayList<GeoPoint> toPoints; 018 private double maxDistanceMeters; 019 private double flatnessDistanceMeters; 020 private int limit; 021 022 protected final GeodeticCalculator geoCalc; 023 024 public GeoEllipse(GeoPoint pivot, double widthMeters, double heightMeters, double maxDistanceMeters, 025 double flatnessDistanceMeters, int limit) { 026 //super(maxDistanceMeters, flatnessDistanceMeters, limit); 027 //path = new Path2D.Double(); 028 path = new GeneralPath(); 029 toPoints = new ArrayList<GeoPoint>(); 030 geoCalc = new GeodeticCalculator(); 031 this.maxDistanceMeters = maxDistanceMeters; 032 this.flatnessDistanceMeters = flatnessDistanceMeters; 033 this.limit = limit; 034 035 arcTo(pivot, widthMeters, heightMeters, 0, 180); 036 arcTo(pivot, widthMeters, heightMeters, 180, 0); 037 } 038 039 public final void arcTo(GeoPoint pivot, double widthMeters, double heightMeters, double leftAzimuthDegrees, 040 double rightAzimuthDegrees) { 041 //Path2D newPath = new Path2D.Double(); 042 GeneralPath newPath = new GeneralPath(); 043 Arc2D arc; 044 045 if (leftAzimuthDegrees > rightAzimuthDegrees) { 046 arc = new Arc2D(-widthMeters / 2, -heightMeters / 2, widthMeters, heightMeters, 047 leftAzimuthDegrees - 90, Math.abs((360 - leftAzimuthDegrees) + rightAzimuthDegrees), Arc2D.OPEN); 048 } else { 049 arc = new Arc2D(-widthMeters / 2, -heightMeters / 2, widthMeters, heightMeters, 050 leftAzimuthDegrees - 90, Math.abs(leftAzimuthDegrees - rightAzimuthDegrees), Arc2D.OPEN); 051 } 052 053 GeoPoint point = null; 054 if (pivot != null) { 055 FlatteningPathIterator it = new FlatteningPathIterator(arc.getPathIterator(null), flatnessDistanceMeters, limit); 056 while (!it.isDone()) { 057 // Add a point to the list for each segment flattened from the curve 058 double[] strokePoints = new double[6]; 059 int type = it.currentSegment(strokePoints); 060 double x = strokePoints[0]; 061 double y = strokePoints[1]; 062 double azimuth = Angle.toDegrees(Math.atan2(x, y)); 063 GlobalCoordinates coord = new GlobalCoordinates(pivot.getLatitude(), pivot.getLongitude()); 064 GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, coord, azimuth, 065 //new Point2D().distance(x, y)); 066 Point2D.distance(0, 0, x, y)); 067 switch (type) { 068 case PathIterator.SEG_MOVETO: 069 newPath.moveTo(c.getLongitude(), c.getLatitude()); 070 GeoPoint startPoint = new GeoPoint(c.getLongitude(), c.getLatitude()); 071 if (toPoints.size() > 0 && !startPoint.equals(toPoints.get(toPoints.size() - 1))) { 072 lineTo(startPoint); 073 } 074 break; 075 case PathIterator.SEG_LINETO: 076 newPath.lineTo(c.getLongitude(), c.getLatitude()); 077 point = new GeoPoint(c.getLongitude(), c.getLatitude()); 078 break; 079 } 080 it.next(); 081 } 082 } 083 084 path.append(newPath, true); 085 toPoints.add(point); 086 } 087 088 public void lineTo(GeoPoint point) { 089 //Path2D newPath = new Path2D.Double(); 090 GeneralPath newPath = new GeneralPath(); 091 092 // Move to the initial point 093 GeoPoint lastPoint = new GeoPoint(); 094 if (toPoints.size() > 0) { 095 lastPoint = toPoints.get(toPoints.size() - 1); 096 newPath.moveTo(lastPoint.x, lastPoint.y); 097 } 098 099 // Calculate the curve to the new point 100 GlobalCoordinates start = toGlobalCoord(lastPoint); 101 GlobalCoordinates end = toGlobalCoord(point); 102 GeodeticCurve curve = geoCalc.calculateGeodeticCurve(REFERENCE_ELLIPSOID, start, end); 103 104 // Generate points along the curve, adding them to the new path 105 double distance = maxDistanceMeters; 106 while (distance < curve.getEllipsoidalDistance()) { 107 GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, start, curve 108 .getAzimuth(), distance); 109 newPath.lineTo(c.getLongitude(), c.getLatitude()); 110 distance += maxDistanceMeters; 111 } 112 newPath.lineTo(point.x, point.y); 113 114 // Append the new path to the existing path 115 path.append(newPath, true); 116 toPoints.add(point); 117 118 } 119 120 protected GlobalCoordinates toGlobalCoord(GeoPoint point) { 121 return new GlobalCoordinates(point.getLatitude(), point.getLongitude()); 122 } 123 124 public PathIterator getPathIterator(AffineTransform at) { 125 return path.getPathIterator(at); 126 } 127 //added path accessor for use by Ellipse only 128 public GeneralPath getPath() 129 { 130 return path; 131 } 132 133}