/// <summary> /// Returns all polygon points from given airspace polygon object /// </summary> /// <param name="polygon">airspace polygon</param> /// <param name="floor">floor altitude</param> /// <returns>position list object with all polygon points</returns> private static Czml.PositionList GetPolygonPointsFromAirspacePolygon(Airspace.Polygon polygon, Altitude floor) { double height = HeightFromAltitude(floor); var positions = new Czml.PositionList(); foreach (var segment in polygon.Segments) { if (segment is Airspace.Polygon.PolygonPoint point) { positions.Add(point.Point.Latitude, point.Point.Longitude, height); } if (segment is Airspace.Polygon.PolygonArc arc) { var convertedArcSegment = ConvertPolygonArcToArcSegment(arc, height); AddArcSegmentPolygonPoints(convertedArcSegment, positions, height); positions.Add(arc.End.Latitude, arc.End.Longitude, height); } if (segment is Airspace.Polygon.PolygonArcSegment arcSegment) { AddArcSegmentPolygonPoints(arcSegment, positions, height); } } return(positions); }
/// <summary> /// Generates all points for a PolygonArcSegment object and adds it to the positions /// </summary> /// <param name="arcSegment">arc segment to use</param> /// <param name="positions">positions to add to</param> /// <param name="height">height value</param> private static void AddArcSegmentPolygonPoints( Airspace.Polygon.PolygonArcSegment arcSegment, Czml.PositionList positions, double height) { var center = arcSegment.Center.ToMapPoint(height); bool isClockwise = arcSegment.Direction == Airspace.Polygon.ArcDirection.Clockwise; double endAngle = arcSegment.EndAngle; double startAngle = arcSegment.StartAngle; // adjust angles so that we don't have to deal with wrap around if (isClockwise && startAngle > endAngle) { endAngle += 360.0; } if (!isClockwise && startAngle < endAngle) { startAngle += 360.0; } bool isAtEnd; double step = (isClockwise ? 1.0 : -1.0) * ArcSegmentAngleStepByRadius(arcSegment.Radius); double bearing = startAngle; do { var point = center.PolarOffset(arcSegment.Radius, -bearing, height); positions.Add(point.Latitude, point.Longitude, height); bearing += step; isAtEnd = isClockwise ? bearing > endAngle : bearing < endAngle; }while (!isAtEnd); // add end point when the step angle didn't hit the end angle directly if (Math.Abs(bearing - arcSegment.EndAngle) > 1e-6) { var point = center.PolarOffset(arcSegment.Radius, -arcSegment.EndAngle, height); positions.Add(point.Latitude, point.Longitude, height); } }