Beispiel #1
0
        public static List <PointLatLngAlt> CreateCorridor(List <PointLatLngAlt> polygon, double altitude, double distance,
                                                           double spacing, double angle, double overshoot1, double overshoot2, StartPosition startpos, bool shutter,
                                                           float minLaneSeparation, double width, float leadin = 0)
        {
            if (spacing < 4 && spacing != 0)
            {
                spacing = 4;
            }

            if (distance < 0.1)
            {
                distance = 0.1;
            }

            if (polygon.Count == 0)
            {
                return(new List <PointLatLngAlt>());
            }

            List <PointLatLngAlt> ans = new List <PointLatLngAlt>();

            // utm zone distance calcs will be done in
            int utmzone = polygon[0].GetUTMZone();

            // utm position list
            List <utmpos> utmpositions = utmpos.ToList(PointLatLngAlt.ToUTM(utmzone, polygon), utmzone);

            var lanes = (width / distance);
            var start = (int)((lanes / 2) * -1);
            var end   = start * -1;

            for (int lane = start; lane <= end; lane++)
            {
                // correct side of the line we are on because of list reversal
                int multi = 1;
                if ((lane - start) % 2 == 1)
                {
                    multi = -1;
                }

                if (startpos != StartPosition.Home)
                {
                    utmpositions.Reverse();
                }

                GenerateOffsetPath(utmpositions, distance * multi * lane, spacing, utmzone)
                .ForEach(pnt => { ans.Add(pnt); });

                if (startpos == StartPosition.Home)
                {
                    utmpositions.Reverse();
                }
            }

            // set the altitude on all points
            ans.ForEach(plla => { plla.Alt = altitude; });

            return(ans);
        }
Beispiel #2
0
 public utmpos(PointLatLngAlt pos)
 {
     double[] dd = pos.ToUTM(pos.GetUTMZone());
     this.x = dd[0];
     this.y = dd[1];
     this.zone = pos.GetUTMZone();
     this.Tag = null;
 }
Beispiel #3
0
 public utmpos(PointLatLngAlt pos)
 {
     double[] dd = pos.ToUTM();
     this.x    = dd[0];
     this.y    = dd[1];
     this.zone = pos.GetUTMZone();
     this.Tag  = null;
 }
Beispiel #4
0
        public static srtm.altresponce getAltitude(double lat, double lng, double zoom = 16)
        {
            lock (index)
                if (index.Count == 0)
                {
                    return(srtm.altresponce.Invalid);
                }

            var answer = new srtm.altresponce();

            foreach (var geotiffdata in index.ToArray())
            {
                if (geotiffdata.Area.Contains(lat, lng))
                {
                    // get answer
                    var xf = map(lat, geotiffdata.Area.Top, geotiffdata.Area.Bottom, 0, geotiffdata.height - 1);
                    var yf = map(lng, geotiffdata.Area.Left, geotiffdata.Area.Right, 0, geotiffdata.width - 1);

                    //wgs84 && etrs89
                    if (geotiffdata.ProjectedCSTypeGeoKey >= 3038 && geotiffdata.ProjectedCSTypeGeoKey <= 3051 ||
                        geotiffdata.ProjectedCSTypeGeoKey >= 32601 && geotiffdata.ProjectedCSTypeGeoKey <= 32760 ||
                        geotiffdata.ProjectedCSTypeGeoKey >= 25828 && geotiffdata.ProjectedCSTypeGeoKey <= 25838)
                    {
                        var pnt = PointLatLngAlt.ToUTM((geotiffdata.UTMZone) * 1, lat, lng);

                        xf = map(pnt[1], geotiffdata.y, geotiffdata.y - geotiffdata.height * geotiffdata.yscale, 0,
                                 geotiffdata.height - 1);
                        yf = map(pnt[0], geotiffdata.x, geotiffdata.x + geotiffdata.width * geotiffdata.xscale, 0,
                                 geotiffdata.width - 1);
                    }

                    int    x_int  = (int)xf;
                    double x_frac = xf - x_int;

                    int    y_int  = (int)yf;
                    double y_frac = yf - y_int;


                    //could be on one of the other images
                    if (x_int < 0 || y_int < 0 || x_int >= geotiffdata.width - 1 || y_int >= geotiffdata.height - 1)
                    {
                        continue;
                    }

                    double alt00 = GetAlt(geotiffdata, x_int, y_int);
                    double alt10 = GetAlt(geotiffdata, x_int + 1, y_int);
                    double alt01 = GetAlt(geotiffdata, x_int, y_int + 1);
                    double alt11 = GetAlt(geotiffdata, x_int + 1, y_int + 1);

                    double v1 = avg(alt00, alt10, x_frac);
                    double v2 = avg(alt01, alt11, x_frac);
                    double v  = avg(v1, v2, y_frac);

                    if (v > -1000)
                    {
                        answer.currenttype = srtm.tiletype.valid;
                    }
                    if (alt00 < -1000 || alt10 < -1000 || alt01 < -1000 || alt11 < -1000)
                    {
                        answer.currenttype = srtm.tiletype.invalid;
                    }
                    answer.alt       = v;
                    answer.altsource = "GeoTiff";
                    return(answer);
                }
            }

            return(srtm.altresponce.Invalid);
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="polygon">the polygon outside edge</param>
        /// <param name="altitude">flight altitude</param>
        /// <param name="distance">distance between lines</param>
        /// <param name="spacing">space between triggers</param>
        /// <param name="angle">angle of the lines</param>
        /// <param name="overshoot1"></param>
        /// <param name="overshoot2"></param>
        /// <param name="startpos"></param>
        /// <param name="shutter"></param>
        /// <param name="minLaneSeparation"></param>
        /// <param name="leadin1"></param>
        /// <param name="leadin2"></param>
        /// <param name="HomeLocation"></param>
        /// <param name="useextendedendpoint">use the leadout point to find the next closes line</param>
        /// <returns></returns>
        public static List <PointLatLngAlt> CreateGrid(List <PointLatLngAlt> polygon, double altitude, double distance, double spacing, double angle, double overshoot1, double overshoot2, StartPosition startpos, bool shutter, float minLaneSeparation, float leadin1, float leadin2, PointLatLngAlt HomeLocation, bool useextendedendpoint = true)
        {
            //DoDebug();

            if (spacing < 0.1 && spacing != 0)
            {
                spacing = 0.1;
            }

            if (distance < 0.1)
            {
                distance = 0.1;
            }

            if (polygon.Count == 0)
            {
                return(new List <PointLatLngAlt>());
            }


            // Make a non round number in case of corner cases
            if (minLaneSeparation != 0)
            {
                minLaneSeparation += 0.5F;
            }
            // Lane Separation in meters
            double minLaneSeparationINMeters = minLaneSeparation * distance;

            List <PointLatLngAlt> ans = new List <PointLatLngAlt>();

            // utm zone distance calcs will be done in
            int utmzone = polygon[0].GetUTMZone();

            // utm position list
            List <utmpos> utmpositions = utmpos.ToList(PointLatLngAlt.ToUTM(utmzone, polygon), utmzone);

            // close the loop if its not already
            if (utmpositions[0] != utmpositions[utmpositions.Count - 1])
            {
                utmpositions.Add(utmpositions[0]); // make a full loop
            }
            // get mins/maxs of coverage area
            Rect area = getPolyMinMax(utmpositions);

            // get initial grid

            // used to determine the size of the outer grid area
            double diagdist = area.DiagDistance();

            // somewhere to store out generated lines
            List <linelatlng> grid = new List <linelatlng>();
            // number of lines we need
            int lines = 0;

            // get start point middle
            double x = area.MidWidth;
            double y = area.MidHeight;

            addtomap(new utmpos(x, y, utmzone), "Base");

            // get left extent
            double xb1 = x;
            double yb1 = y;

            // to the left
            newpos(ref xb1, ref yb1, angle - 90, diagdist / 2 + distance);
            // backwards
            newpos(ref xb1, ref yb1, angle + 180, diagdist / 2 + distance);

            utmpos left = new utmpos(xb1, yb1, utmzone);

            addtomap(left, "left");

            // get right extent
            double xb2 = x;
            double yb2 = y;

            // to the right
            newpos(ref xb2, ref yb2, angle + 90, diagdist / 2 + distance);
            // backwards
            newpos(ref xb2, ref yb2, angle + 180, diagdist / 2 + distance);

            utmpos right = new utmpos(xb2, yb2, utmzone);

            addtomap(right, "right");

            // set start point to left hand side
            x = xb1;
            y = yb1;

            // draw the outergrid, this is a grid that cover the entire area of the rectangle plus more.
            while (lines < ((diagdist + distance * 2) / distance))
            {
                // copy the start point to generate the end point
                double nx = x;
                double ny = y;
                newpos(ref nx, ref ny, angle, diagdist + distance * 2);

                linelatlng line = new linelatlng();
                line.p1      = new utmpos(x, y, utmzone);
                line.p2      = new utmpos(nx, ny, utmzone);
                line.basepnt = new utmpos(x, y, utmzone);
                grid.Add(line);

                // addtomap(line);

                newpos(ref x, ref y, angle + 90, distance);
                lines++;
            }

            // find intersections with our polygon

            // store lines that dont have any intersections
            List <linelatlng> remove = new List <linelatlng>();

            int gridno = grid.Count;

            // cycle through our grid
            for (int a = 0; a < gridno; a++)
            {
                double closestdistance = double.MaxValue;
                double farestdistance  = double.MinValue;

                utmpos closestpoint = utmpos.Zero;
                utmpos farestpoint  = utmpos.Zero;

                // somewhere to store our intersections
                List <utmpos> matchs = new List <utmpos>();

                int    b         = -1;
                int    crosses   = 0;
                utmpos newutmpos = utmpos.Zero;
                foreach (utmpos pnt in utmpositions)
                {
                    b++;
                    if (b == 0)
                    {
                        continue;
                    }
                    newutmpos = FindLineIntersection(utmpositions[b - 1], utmpositions[b], grid[a].p1, grid[a].p2);
                    if (!newutmpos.IsZero)
                    {
                        crosses++;
                        matchs.Add(newutmpos);
                        if (closestdistance > grid[a].p1.GetDistance(newutmpos))
                        {
                            closestpoint.y    = newutmpos.y;
                            closestpoint.x    = newutmpos.x;
                            closestpoint.zone = newutmpos.zone;
                            closestdistance   = grid[a].p1.GetDistance(newutmpos);
                        }
                        if (farestdistance < grid[a].p1.GetDistance(newutmpos))
                        {
                            farestpoint.y    = newutmpos.y;
                            farestpoint.x    = newutmpos.x;
                            farestpoint.zone = newutmpos.zone;
                            farestdistance   = grid[a].p1.GetDistance(newutmpos);
                        }
                    }
                }
                if (crosses == 0) // outside our polygon
                {
                    if (!PointInPolygon(grid[a].p1, utmpositions) && !PointInPolygon(grid[a].p2, utmpositions))
                    {
                        remove.Add(grid[a]);
                    }
                }
                else if (crosses == 1) // bad - shouldnt happen
                {
                }
                else if (crosses == 2) // simple start and finish
                {
                    linelatlng line = grid[a];
                    line.p1 = closestpoint;
                    line.p2 = farestpoint;
                    grid[a] = line;
                }
                else // multiple intersections
                {
                    linelatlng line = grid[a];
                    remove.Add(line);

                    while (matchs.Count > 1)
                    {
                        linelatlng newline = new linelatlng();

                        closestpoint = findClosestPoint(closestpoint, matchs);
                        newline.p1   = closestpoint;
                        matchs.Remove(closestpoint);

                        closestpoint = findClosestPoint(closestpoint, matchs);
                        newline.p2   = closestpoint;
                        matchs.Remove(closestpoint);

                        newline.basepnt = line.basepnt;

                        grid.Add(newline);
                    }
                }
            }

            // cleanup and keep only lines that pass though our polygon
            foreach (linelatlng line in remove)
            {
                grid.Remove(line);
            }

            // debug
            foreach (linelatlng line in grid)
            {
                addtomap(line);
            }

            if (grid.Count == 0)
            {
                return(ans);
            }

            // pick start positon based on initial point rectangle
            utmpos startposutm;

            switch (startpos)
            {
            default:
            case StartPosition.Home:
                startposutm = new utmpos(HomeLocation);
                break;

            case StartPosition.BottomLeft:
                startposutm = new utmpos(area.Left, area.Bottom, utmzone);
                break;

            case StartPosition.BottomRight:
                startposutm = new utmpos(area.Right, area.Bottom, utmzone);
                break;

            case StartPosition.TopLeft:
                startposutm = new utmpos(area.Left, area.Top, utmzone);
                break;

            case StartPosition.TopRight:
                startposutm = new utmpos(area.Right, area.Top, utmzone);
                break;

            case StartPosition.Point:
                startposutm = new utmpos(StartPointLatLngAlt);
                break;
            }

            // find the closes polygon point based from our startpos selection
            startposutm = findClosestPoint(startposutm, utmpositions);

            // find closest line point to startpos
            linelatlng closest = findClosestLine(startposutm, grid, 0 /*Lane separation does not apply to starting point*/, angle);

            utmpos lastpnt;

            // get the closes point from the line we picked
            if (closest.p1.GetDistance(startposutm) < closest.p2.GetDistance(startposutm))
            {
                lastpnt = closest.p1;
            }
            else
            {
                lastpnt = closest.p2;
            }

            // S =  start
            // E = end
            // ME = middle end
            // SM = start middle

            while (grid.Count > 0)
            {
                // for each line, check which end of the line is the next closest
                if (closest.p1.GetDistance(lastpnt) < closest.p2.GetDistance(lastpnt))
                {
                    utmpos newstart = newpos(closest.p1, angle, -leadin1);
                    newstart.Tag = "S";
                    addtomap(newstart, "S");
                    ans.Add(newstart);

                    if (leadin1 < 0)
                    {
                        var p2 = new utmpos(newstart)
                        {
                            Tag = "SM"
                        };
                        addtomap(p2, "SM");
                        ans.Add(p2);
                    }
                    else
                    {
                        closest.p1.Tag = "SM";
                        addtomap(closest.p1, "SM");
                        ans.Add(closest.p1);
                    }

                    if (spacing > 0)
                    {
                        for (double d = (spacing - ((closest.basepnt.GetDistance(closest.p1)) % spacing));
                             d < (closest.p1.GetDistance(closest.p2));
                             d += spacing)
                        {
                            double ax = closest.p1.x;
                            double ay = closest.p1.y;

                            newpos(ref ax, ref ay, angle, d);
                            var utmpos1 = new utmpos(ax, ay, utmzone)
                            {
                                Tag = "M"
                            };
                            addtomap(utmpos1, "M");
                            ans.Add(utmpos1);
                        }
                    }

                    utmpos newend = newpos(closest.p2, angle, overshoot1);

                    if (overshoot1 < 0)
                    {
                        var p2 = new utmpos(newend)
                        {
                            Tag = "ME"
                        };
                        addtomap(p2, "ME");
                        ans.Add(p2);
                    }
                    else
                    {
                        closest.p2.Tag = "ME";
                        addtomap(closest.p2, "ME");
                        ans.Add(closest.p2);
                    }

                    newend.Tag = "E";
                    addtomap(newend, "E");
                    ans.Add(newend);

                    lastpnt = closest.p2;

                    grid.Remove(closest);
                    if (grid.Count == 0)
                    {
                        break;
                    }

                    if (useextendedendpoint)
                    {
                        closest = findClosestLine(newend, grid, minLaneSeparationINMeters, angle);
                    }
                    else
                    {
                        closest = findClosestLine(closest.p2, grid, minLaneSeparationINMeters, angle);
                    }
                }
                else
                {
                    utmpos newstart = newpos(closest.p2, angle, leadin2);
                    newstart.Tag = "S";
                    addtomap(newstart, "S");
                    ans.Add(newstart);

                    if (leadin2 < 0)
                    {
                        var p2 = new utmpos(newstart)
                        {
                            Tag = "SM"
                        };
                        addtomap(p2, "SM");
                        ans.Add(p2);
                    }
                    else
                    {
                        closest.p2.Tag = "SM";
                        addtomap(closest.p2, "SM");
                        ans.Add(closest.p2);
                    }

                    if (spacing > 0)
                    {
                        for (double d = ((closest.basepnt.GetDistance(closest.p2)) % spacing);
                             d < (closest.p1.GetDistance(closest.p2));
                             d += spacing)
                        {
                            double ax = closest.p2.x;
                            double ay = closest.p2.y;

                            newpos(ref ax, ref ay, angle, -d);
                            var utmpos2 = new utmpos(ax, ay, utmzone)
                            {
                                Tag = "M"
                            };
                            addtomap(utmpos2, "M");
                            ans.Add(utmpos2);
                        }
                    }

                    utmpos newend = newpos(closest.p1, angle, -overshoot2);

                    if (overshoot2 < 0)
                    {
                        var p2 = new utmpos(newend)
                        {
                            Tag = "ME"
                        };
                        addtomap(p2, "ME");
                        ans.Add(p2);
                    }
                    else
                    {
                        closest.p1.Tag = "ME";
                        addtomap(closest.p1, "ME");
                        ans.Add(closest.p1);
                    }

                    newend.Tag = "E";
                    addtomap(newend, "E");
                    ans.Add(newend);

                    lastpnt = closest.p1;

                    grid.Remove(closest);
                    if (grid.Count == 0)
                    {
                        break;
                    }

                    if (useextendedendpoint)
                    {
                        closest = findClosestLine(newend, grid, minLaneSeparationINMeters, angle);
                    }
                    else
                    {
                        closest = findClosestLine(closest.p1, grid, minLaneSeparationINMeters, angle);
                    }
                }
            }

            // set the altitude on all points
            ans.ForEach(plla => { plla.Alt = altitude; });

            return(ans);
        }
Beispiel #6
0
        public static List <PointLatLngAlt> CreateRotary(List <PointLatLngAlt> polygon, double altitude, double distance, double spacing, double angle, double overshoot1, double overshoot2, StartPosition startpos, bool shutter, float minLaneSeparation, float leadin, PointLatLngAlt HomeLocation)
        {
            spacing = 0;

            if (distance < 0.1)
            {
                distance = 0.1;
            }

            if (polygon.Count == 0)
            {
                return(new List <PointLatLngAlt>());
            }

            List <utmpos> ans = new List <utmpos>();

            // utm zone distance calcs will be done in
            int utmzone = polygon[0].GetUTMZone();

            // utm position list
            List <utmpos> utmpositions = utmpos.ToList(PointLatLngAlt.ToUTM(utmzone, polygon), utmzone);

            // close the loop if its not already
            if (utmpositions[0] != utmpositions[utmpositions.Count - 1])
            {
                utmpositions.Add(utmpositions[0]); // make a full loop
            }
            var maxlane = 200;                     // (Centroid(utmpositions).GetDistance(utmpositions[0]) / distance);

            ClipperLib.ClipperOffset clipperOffset = new ClipperLib.ClipperOffset();

            clipperOffset.AddPath(utmpositions.Select(a => { return(new ClipperLib.IntPoint(a.x * 1000.0, a.y * 1000.0)); }).ToList(), ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);

            for (int lane = 0; lane < maxlane; lane++)
            {
                List <utmpos> ans1 = new List <utmpos>();

                ClipperLib.PolyTree tree = new ClipperLib.PolyTree();
                clipperOffset.Execute(ref tree, (Int64)(distance * 1000.0 * -lane));

                if (tree.ChildCount == 0)
                {
                    break;
                }

                foreach (var treeChild in tree.Childs)
                {
                    ans1 = treeChild.Contour.Select(a => new utmpos(a.X / 1000.0, a.Y / 1000.0, utmzone))
                           .ToList();

                    if (ans.Count() > 2)
                    {
                        var start1 = ans[ans.Count() - 1];
                        var end1   = ans[ans.Count() - 2];

                        var start2 = ans1[0];
                        var end2   = ans1[ans1.Count() - 1];
                    }

                    ans.AddRange(ans1);
                }
            }

            // set the altitude on all points
            return(ans.Select(plla => { var a = plla.ToLLA(); a.Alt = altitude; a.Tag = "S"; return a; }).ToList());
        }
Beispiel #7
0
        public static List <PointLatLngAlt> CreateRotary(List <PointLatLngAlt> polygon, double altitude, double distance, double spacing, double angle, double overshoot1, double overshoot2, StartPosition startpos, bool shutter, float minLaneSeparation, float leadin, PointLatLngAlt HomeLocation, int clockwise_laps, bool match_spiral_perimeter, int laps)
        {
            spacing = 0;

            if (distance < 0.1)
            {
                distance = 0.1;
            }

            if (polygon.Count == 0)
            {
                return(new List <PointLatLngAlt>());
            }

            List <utmpos> ans = new List <utmpos>();

            // utm zone distance calcs will be done in
            int utmzone = polygon[0].GetUTMZone();

            // utm position list
            List <utmpos> utmpositions = utmpos.ToList(PointLatLngAlt.ToUTM(utmzone, polygon), utmzone);

            // close the loop if its not already
            if (utmpositions[0] != utmpositions[utmpositions.Count - 1])
            {
                utmpositions.Add(utmpositions[0]); // make a full loop
            }
            var maxlane = laps;                    // (Centroid(utmpositions).GetDistance(utmpositions[0]) / distance);

            ClipperLib.ClipperOffset clipperOffset = new ClipperLib.ClipperOffset();

            clipperOffset.AddPath(utmpositions.Select(a => { return(new ClipperLib.IntPoint(a.x * 1000.0, a.y * 1000.0)); }).ToList(), ClipperLib.JoinType.jtMiter, ClipperLib.EndType.etClosedPolygon);

            for (int lane = 0; lane < maxlane; lane++)
            {
                List <utmpos> ans1 = new List <utmpos>();

                ClipperLib.PolyTree tree = new ClipperLib.PolyTree();
                clipperOffset.Execute(ref tree, (Int64)(distance * 1000.0 * -lane));

                if (tree.ChildCount == 0)
                {
                    break;
                }

                if (lane < clockwise_laps || clockwise_laps < 0)
                {
                    ClipperLib.Clipper.ReversePaths(ClipperLib.Clipper.PolyTreeToPaths(tree));
                }

                foreach (var treeChild in tree.Childs)
                {
                    ans1 = treeChild.Contour.Select(a => new utmpos(a.X / 1000.0, a.Y / 1000.0, utmzone))
                           .ToList();

                    if (lane == 0 && clockwise_laps != 1 && match_spiral_perimeter)
                    {
                        ans1.Insert(0, ans1.Last <utmpos>());   // start at the last point of the first calculated lap
                                                                // to make a closed polygon on the first trip around
                    }


                    if (lane == clockwise_laps - 1)
                    {
                        ans1.Add(ans1.First <utmpos>());  // revisit the first waypoint on this lap to cleanly exit the CW pattern
                    }

                    if (ans.Count() > 2)
                    {
                        var start1 = ans[ans.Count() - 1];
                        var end1   = ans[ans.Count() - 2];

                        var start2 = ans1[0];
                        var end2   = ans1[ans1.Count() - 1];
                    }

                    ans.AddRange(ans1);
                }
            }

            // set the altitude on all points
            return(ans.Select(plla => { var a = plla.ToLLA(); a.Alt = altitude; a.Tag = "S"; return a; }).ToList());
        }