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}