001package sec.geo; 002import org.gavaghan.geodesy.Ellipsoid; 003import org.gavaghan.geodesy.GeodeticCalculator; 004import armyc2.c2sd.JavaLineArray.POINT2; 005import org.gavaghan.geodesy.GeodeticCurve; 006import org.gavaghan.geodesy.GlobalCoordinates; 007import java.util.ArrayList; 008import armyc2.c2sd.graphics2d.GeneralPath; 009import armyc2.c2sd.graphics2d.AffineTransform; 010import armyc2.c2sd.graphics2d.PathIterator; 011public class GeoBlock2 /*extends GeoPath*/ { 012 protected static final Ellipsoid REFERENCE_ELLIPSOID = Ellipsoid.WGS84; 013 014 private GeneralPath path; 015 private ArrayList<GeoPoint> toPoints; 016 private double maxDistanceMeters; 017 private double flatnessDistanceMeters; 018 private int limit; 019 020 protected final GeodeticCalculator geoCalc; 021 public GeoBlock2(GeoPoint p1, GeoPoint p2, double leftWidthMeters, double rightWidthMeters, double maxDistanceMeters, 022 double flatnessDistanceMeters, int limit) { 023 //super(maxDistanceMeters, flatnessDistanceMeters, limit); 024 path = new GeneralPath(); 025 toPoints = new ArrayList<GeoPoint>(); 026 geoCalc = new GeodeticCalculator(); 027 this.maxDistanceMeters = maxDistanceMeters; 028 //this.flatnessDistanceMeters = flatnessDistanceMeters; 029 //this.limit = limit; 030 031 GlobalCoordinates c1 = toGlobalCoord(p1); 032 GlobalCoordinates c2 = toGlobalCoord(p2); 033 GeodeticCurve curve = geoCalc.calculateGeodeticCurve(REFERENCE_ELLIPSOID, c1, c2); 034 double a1 = curve.getAzimuth(); 035 double a2 = curve.getReverseAzimuth(); 036 double leftRadius = leftWidthMeters; 037 double rightRadius = rightWidthMeters; 038 //diagnostic to prevent error in calculate global coords if points are identical 039 if(p1.x==p2.x && p1.y==p2.y) 040 return; 041 //end section 042 GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c1, a1 - 90, leftRadius); 043 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c1, a1 - 90, leftRadius); 044 moveToLatLong(c.getLongitude(), c.getLatitude()); 045 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c2, a2 + 90, leftRadius); 046 lineToLatLong(c.getLongitude(), c.getLatitude()); 047 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c2, a2 - 90, rightRadius); 048 lineToLatLong(c.getLongitude(), c.getLatitude()); 049 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c1, a1 + 90, rightRadius); 050 lineToLatLong(c.getLongitude(), c.getLatitude()); 051 closePath(); 052 } 053 public void moveTo(GeoPoint point) { 054 path.moveTo(point.x, point.y); 055 toPoints.add(point); 056 } 057 058 public final void moveToLatLong(double longitudeDegrees, double latitudeDegrees) { 059 moveTo(new GeoPoint(longitudeDegrees, latitudeDegrees)); 060 } 061 062 public void lineTo(GeoPoint point) { 063 GeneralPath newPath = new GeneralPath(); 064 065 // Move to the initial point 066 GeoPoint lastPoint = new GeoPoint(); 067 if (toPoints.size() > 0) { 068 lastPoint = toPoints.get(toPoints.size() - 1); 069 newPath.moveTo(lastPoint.x, lastPoint.y); 070 } 071 072 // Calculate the curve to the new point 073 GlobalCoordinates start = toGlobalCoord(lastPoint); 074 GlobalCoordinates end = toGlobalCoord(point); 075 GeodeticCurve curve = geoCalc.calculateGeodeticCurve(REFERENCE_ELLIPSOID, start, end); 076 077 // Generate points along the curve, adding them to the new path 078 double distance = maxDistanceMeters; 079 while (distance < curve.getEllipsoidalDistance()) { 080 GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, start, curve 081 .getAzimuth(), distance); 082 newPath.lineTo(c.getLongitude(), c.getLatitude()); 083 distance += maxDistanceMeters; 084 } 085 newPath.lineTo(point.x, point.y); 086 087 // Append the new path to the existing path 088 path.append(newPath, true); 089 toPoints.add(point); 090 simplify(); 091 092 } 093 094 public final void lineToLatLong(double longitudeDegrees, double latitudeDegrees) { 095 lineTo(new GeoPoint(longitudeDegrees, latitudeDegrees)); 096 } 097 098 099 public ArrayList<GeoPoint> getToPoints() { 100 return toPoints; 101 } 102 public final void closePath() { 103 104 105 if (toPoints.size() > 0 && !toPoints.get(0).equals(toPoints.get(toPoints.size() - 1))) { 106 lineTo(toPoints.get(0)); 107 } 108 } 109 110 111// @Override 112 public PathIterator getPathIterator(AffineTransform at, double flatness) { 113 //return path.getPathIterator(at, flatness); 114 return path.getPathIterator(at); 115 } 116 117 118 @Override 119 public String toString() { 120 return toPoints.toString(); 121 } 122 123 protected final GlobalCoordinates toGlobalCoord(GeoPoint point) { 124 return new GlobalCoordinates(point.getLatitude(), point.getLongitude()); 125 } 126 public void simplify() 127 { 128 PathIterator pi=path.getPathIterator(null); 129 ArrayList<POINT2>pts=pi.getPoints(); 130 ArrayList<POINT2>newPts=new ArrayList(); 131 int j=0; 132 int style=-1,lastStyle=-1,nextstyle=-1; 133 POINT2 currentPt=null, lastPt=null; 134 int n=pts.size(); 135 //for(j=0;j<pts.size();j++) 136 for(j=0;j<n;j++) 137 { 138 style=pts.get(j).style; 139 currentPt=pts.get(j); 140 if(j>0) 141 { 142 lastStyle=pts.get(j-1).style; 143 lastPt=pts.get(j-1); 144 } 145 if(lastStyle==PathIterator.SEG_LINETO && style==PathIterator.SEG_MOVETO) 146 { 147 //if the last move as lineto and the current move is moveto then 148 //don't add the current point if the last point is equal 149 if(currentPt.x==lastPt.x && currentPt.y==lastPt.y) 150 continue; 151 } 152 newPts.add(currentPt); 153 } 154 pi.setPathIterator(newPts); 155 } 156}