001package sec.geo; 002import armyc2.c2sd.graphics2d.*; 003import java.util.ArrayList; 004import armyc2.c2sd.JavaLineArray.POINT2; 005import org.gavaghan.geodesy.Ellipsoid; 006import org.gavaghan.geodesy.GeodeticCalculator; 007 008import org.gavaghan.geodesy.GeodeticCurve; 009import org.gavaghan.geodesy.GlobalCoordinates; 010 011public class GeoBlock /*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 GeoBlock(GeoPoint p1, GeoPoint p2, double widthMeters, 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 radius = widthMeters / 2; 037 //diagnostic to prevent error in calculate global coords if points are identical 038 if(p1.x==p2.x && p1.y==p2.y) 039 return; 040 //end section 041 GlobalCoordinates c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c1, a1 - 90, radius); 042 moveToLatLong(c.getLongitude(), c.getLatitude()); 043 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c2, a2 + 90, radius); 044 lineToLatLong(c.getLongitude(), c.getLatitude()); 045 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c2, a2 - 90, radius); 046 lineToLatLong(c.getLongitude(), c.getLatitude()); 047 c = geoCalc.calculateEndingGlobalCoordinates(REFERENCE_ELLIPSOID, c1, a1 + 90, radius); 048 lineToLatLong(c.getLongitude(), c.getLatitude()); 049 closePath(); 050 } 051 public void moveTo(GeoPoint point) { 052 path.moveTo(point.x, point.y); 053 toPoints.add(point); 054 } 055 056 public final void moveToLatLong(double longitudeDegrees, double latitudeDegrees) { 057 moveTo(new GeoPoint(longitudeDegrees, latitudeDegrees)); 058 } 059 public void simplify() 060 { 061 PathIterator pi=path.getPathIterator(null); 062 ArrayList<POINT2>pts=pi.getPoints(); 063 ArrayList<POINT2>newPts=new ArrayList(); 064 int j=0; 065 int style=-1,lastStyle=-1,nextstyle=-1; 066 POINT2 currentPt=null, lastPt=null; 067 int n=pts.size(); 068 //for(j=0;j<pts.size();j++) 069 for(j=0;j<n;j++) 070 { 071 style=pts.get(j).style; 072 currentPt=pts.get(j); 073 if(j>0) 074 { 075 lastStyle=pts.get(j-1).style; 076 lastPt=pts.get(j-1); 077 } 078 if(lastStyle==PathIterator.SEG_LINETO && style==PathIterator.SEG_MOVETO) 079 { 080 //if the last move as lineto and the current move is moveto then 081 //don't add the current point if the last point is equal 082 if(currentPt.x==lastPt.x && currentPt.y==lastPt.y) 083 continue; 084 } 085 newPts.add(currentPt); 086 } 087 pi.setPathIterator(newPts); 088 } 089 public void lineTo(GeoPoint point) { 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 // Append the new path to the existing path 114 path.append(newPath, true); 115 //path.lineTo(point.x, point.y); 116 toPoints.add(point); 117 simplify(); 118 119 } 120 121 public final void lineToLatLong(double longitudeDegrees, double latitudeDegrees) { 122 lineTo(new GeoPoint(longitudeDegrees, latitudeDegrees)); 123 } 124 125 126 public ArrayList<GeoPoint> getToPoints() { 127 return toPoints; 128 } 129 130 public final void closePath() { 131 132 133 if (toPoints.size() > 0 && !toPoints.get(0).equals(toPoints.get(toPoints.size() - 1))) { 134 lineTo(toPoints.get(0)); 135 } 136 } 137 138 139// @Override 140 public PathIterator getPathIterator(AffineTransform at) { 141 return path.getPathIterator(at); 142 } 143 144 145 @Override 146 public String toString() { 147 return toPoints.toString(); 148 } 149 150 protected final GlobalCoordinates toGlobalCoord(GeoPoint point) { 151 return new GlobalCoordinates(point.getLatitude(), point.getLongitude()); 152 } 153}