【基于STK Components(STK组件)的.Net4.5编程】之[SatelliteVisibility.sln]卫星可见性计算

项目代码及swf录制视频下载地址:
【带运行效果录屏】卫星可见性计算(基于STKComponents组件编程).zip-其它文档类资源-CSDN下载

Code is everything!直接上代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

//Add using directives for STK Components namespaces:
using AGI.Foundation;
using AGI.Foundation.Access;
using AGI.Foundation.Access.Constraints;
using AGI.Foundation.Celestial;
using AGI.Foundation.Coordinates;
using AGI.Foundation.Geometry;
using AGI.Foundation.Graphics;
using AGI.Foundation.Graphics.Advanced;
using AGI.Foundation.Platforms;
using AGI.Foundation.Propagators;
using AGI.Foundation.Time;


namespace SatelliteVisibility
{
    public partial class Form1 : Form
    {
        // for user input values.
        public double longitude;
        public double latitude;
        public double minimumElevationAngle;
        public TwoLineElementSet tle;
        public JulianDate startDate;
        public JulianDate endDate;

        // for animation.
        public ModelPrimitive satellite;
        public MarkerBatchPrimitive facility;
        public PolylinePrimitive orbitLine;
        public PolylinePrimitive accessLine;
        public List<Cartesian> orbitPoints;

        // for access computation and animation update.
        public Platform satellitePlatform;
        public Platform facilityPlatform;
        public PointEvaluator satellitePositionEvaluator;
        public AxesEvaluator satelliteOrientationEvaluator;
        public PointEvaluator facilityInertialEvaluator;
        public TimeIntervalCollection accessIntervals;

        public Insight3D Insight3D;

        public struct ViewingOpportunity
        {
            public GregorianDate StartDate;
            public GregorianDate EndDate;
            public double ApproachAzimuth;
            public double DepartureAzimuth;
        }

        public Form1()
        {
            InitializeComponent();
            //JSLS添加
            Insight3D = new Insight3D();
            Insight3D.Location = new System.Drawing.Point(8, 8);
            Insight3D.Name = "Insight3D";
            Insight3D.Size = new Size(752, 752); //三维地球视图的尺寸大小,需要调试运行时调整

            tabPage_Visualization.Controls.Add(Insight3D);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //获取地球中心体——我们需要它来计算接近和离开的方位角,卫星在地球参考系中的位置,以及卫星的方向轴。
            EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;

            // 从[hs601.mdl]创建 卫星对象
            satellite = new ModelPrimitive("hs601.mdl");
            satellite.ReferenceFrame = earth.InertialFrame;
            orbitLine = new PolylinePrimitive(PolylineType.LineStrip, SetHint.Frequent);
            orbitLine.ReferenceFrame = earth.InertialFrame;
            accessLine = new PolylinePrimitive(PolylineType.Lines, SetHint.Frequent);
            accessLine.ReferenceFrame = earth.InertialFrame;

            // 用[facility.png]创建标记以表示场景中的设施
            facility = new MarkerBatchPrimitive(SetHint.Infrequent);
            facility.RenderPass = MarkerBatchRenderPass.Translucent;
            facility.Texture = SceneManager.Textures.FromUri("facility.png");

            // Create the list of points for the orbit polyline.
            orbitPoints = new List<Cartesian>();

            // Add TimeChanged event handler to the SceneManager
            SceneManager.TimeChanged += TimeChanged;
        }
        private void maskedTextBox_StartDate_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
        {
            MessageBox.Show("输入的时间格式不正确,请重新输入!");
        }

        private void maskedTextBox_StopDate_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
        {
            MessageBox.Show("输入的时间格式不正确,请重新输入!");
        }

        public void TimeChanged(object sender, TimeChangedEventArgs message)
        {
            // Should not execute if the scene is not animating so the event does not interfere
            // with the AccessQuery.
            if (satellitePositionEvaluator != null && satelliteOrientationEvaluator != null)
            {
                // Set the current position and orientation of the satellite at the current time.
                satellite.Position = satellitePositionEvaluator.Evaluate(message.Time);
                satellite.Orientation = satelliteOrientationEvaluator.Evaluate(message.Time);

                // Add the point to the list of polyline points.
                orbitPoints.Add(satellite.Position);
                orbitLine.Set(orbitPoints);

                // If the satellite has access to the facility at the current time, render
                // a polyline from the satellite to the facility.
                if (accessIntervals.Contains(message.Time))
                {
                    List<Cartesian> accessPoints = new List<Cartesian>
            {
                satellite.Position,
                facilityInertialEvaluator.Evaluate(message.Time)
            };

                    accessLine.Set(accessPoints, new[] { Color.Yellow, Color.Yellow }, RenderPassHint.Opaque);

                    if (!SceneManager.Primitives.Contains(accessLine))
                    {
                        SceneManager.Primitives.Add(accessLine);
                    }
                }
                else
                {
                    // Otherwise, remove any polyline from the satellite to the facility if it exists.
                    if (SceneManager.Primitives.Contains(accessLine))
                    {
                        SceneManager.Primitives.Remove(accessLine);
                    }
                }
            }
        }

        public void ResetScene()
        {
            // If a satellite has been added to the SceneManager,
            // then all three primitives were added.
            if (SceneManager.Primitives.Contains(satellite))
            {
                SceneManager.Primitives.Remove(satellite);
                SceneManager.Primitives.Remove(facility);
                SceneManager.Primitives.Remove(orbitLine);
            }

            // The polyline from the satellite to the facility is not always included
            // in the Scene, so must have its own check.
            if (SceneManager.Primitives.Contains(accessLine))
            {
                SceneManager.Primitives.Remove(accessLine);
            }

            // Remove the current line representing the orbit.
            orbitPoints.Clear();
        }

        public void UpdateVisualization()
        {
            // Reset the Scene in case the button was pressed more than once.
            ResetScene();

            EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;

            // Get the starting position and orientation of the satellite and set the global evaluators
            // for the TimeChanged event handler.
            satellitePositionEvaluator = GeometryTransformer.ObservePoint(satellitePlatform.LocationPoint, earth.InertialFrame);
            satelliteOrientationEvaluator = GeometryTransformer.GetAxesTransformation(satellitePlatform.OrientationAxes, earth.InertialFrame.Axes);
            facilityInertialEvaluator = GeometryTransformer.ObservePoint(facilityPlatform.LocationPoint, earth.InertialFrame);

            Cartesian satellitePosition = satellitePositionEvaluator.Evaluate(startDate);
            UnitQuaternion satelliteOrientation = satelliteOrientationEvaluator.Evaluate(startDate);

            satellite.Position = satellitePosition;
            satellite.Orientation = satelliteOrientation;

            // Set the scale once, then add it to the Scene.
            satellite.Scale = 1e5;
            SceneManager.Primitives.Add(satellite);

            // Set the position once, then add it to the Scene.
            Cartographic facilityPosition = new Cartographic(Trig.DegreesToRadians(longitude), Trig.DegreesToRadians(latitude), 0.0);
            facility.SetCartographic(earth, new[] { facilityPosition });
            SceneManager.Primitives.Add(facility);

            // Add the satellites initial position to the set of orbit points.
            orbitPoints.Add(satellitePosition);
            SceneManager.Primitives.Add(orbitLine);

            // Set up animation times.
            SimulationAnimation animation = (SimulationAnimation)SceneManager.Animation;
            if (animation.IsAnimating)
                animation.Reset();

            animation.TimeStep = new Duration(0, 5.0);
            animation.StartCycle = SimulationAnimationCycle.Continue;
            animation.EndCycle = SimulationAnimationCycle.Loop;
            animation.StartTime = startDate;
            animation.EndTime = endDate;
            animation.Time = startDate;

            // Start animation.
            animation.PlayForward();
        }

        public AccessQuery CreateAccessQuery()
        {
            // Create an Access constraint requiring that the satellite be above a particular elevation
            // angle relative to the local horizontal plane of the facility.
            ElevationAngleConstraint elevationAngleConstraint = new ElevationAngleConstraint();
            elevationAngleConstraint.MinimumValue = Trig.DegreesToRadians(minimumElevationAngle);
            elevationAngleConstraint.MaximumValue = Constants.HalfPi;

            //Create a new link between the satellite and facility, and assign that link to the
            //elevation angle constraint. Then specify that the elevation angle constraint applies
            //to the receiving end of the link (the facility).
            LinkInstantaneous link = new LinkInstantaneous(satellitePlatform, facilityPlatform);
            elevationAngleConstraint.ConstrainedLink = link;
            elevationAngleConstraint.ConstrainedLinkEnd = LinkRole.Receiver;

            return elevationAngleConstraint;
        }

        public List<ViewingOpportunity> GetViewingOpportunities()
        {
            EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;

            // Use the CreateAccessQuery method below to create an AccessQuery object.
            AccessQuery access = CreateAccessQuery();

            //Create the access evaluator. An access evaluator generally needs a specified
            //observer. This is because access computations with light time delays can cause
            //different platforms to have different time intervals for the same constraints.
            //However, AccessQueries that are purely made out of instantaneous links (like here)
            //do not need a specified observer.
            AccessEvaluator evaluator = access.GetEvaluator();

            // Compute the time intervals when the viewing location is able to see the satellite.
            AccessQueryResult accessResult = evaluator.Evaluate(startDate, endDate);
            accessIntervals = accessResult.SatisfactionIntervals;

            // Get an evaluator to find the topographic azimuth, elevation, and range of the satellite
            // as observed by the viewing location.  We'll use this evaluator to evaluate the AER at the
            // start and end of each viewing opportunity interval.
            VectorTrueDisplacement vector = new VectorTrueDisplacement(facilityPlatform.LocationPoint, satellitePlatform.LocationPoint);
            MotionEvaluator<AzimuthElevationRange> aerEvaluator = earth.GetAzimuthElevationRangeEvaluator(vector);

            List<ViewingOpportunity> results = new List<ViewingOpportunity>();

            // Copy the output intervals to the return structure.
            foreach (TimeInterval interval in accessIntervals)
            {
                ViewingOpportunity opportunity = new ViewingOpportunity();

                // Convert the start and stop dates of the interval to UTC GregorianDate instances for 
                // human-readable display.
                opportunity.StartDate = interval.Start.ToGregorianDate();
                opportunity.EndDate = interval.Stop.ToGregorianDate();

                // Compute the azimuth of the satellite observed from the viewing location
                // at the start of the interval.
                AzimuthElevationRange aer = aerEvaluator.Evaluate(interval.Start);
                opportunity.ApproachAzimuth = Trig.RadiansToDegrees(aer.Azimuth);

                // Compute the azimuth of the satellite observed from the viewing location
                // at the end of the interval.
                aer = aerEvaluator.Evaluate(interval.Stop);
                opportunity.DepartureAzimuth = Trig.RadiansToDegrees(aer.Azimuth);

                results.Add(opportunity);
            }

            // Return the ViewingOpportunity instances
            return results;
        }

        private void button_Go_Click(object sender, EventArgs e)
        {
            try
            {
                //Parse the text input from the boxes on the form into appropriate
                //class instances and store them in private variables.
                startDate = GregorianDate.Parse(maskedTextBox_StartDate.Text).ToJulianDate();
                endDate = GregorianDate.Parse(maskedTextBox_StopDate.Text).ToJulianDate();
                latitude = double.Parse(textBox_WeiDu.Text);
                longitude = double.Parse(textBox_JingDu.Text);
                minimumElevationAngle = double.Parse(textBox_ZheBiJiao.Text);
                tle = new TwoLineElementSet(textBox_TLE.Text);

                EarthCentralBody earth = CentralBodiesFacet.GetFromContext().Earth;

                // Create an SGP4 propagator to propagate the TLE.
                Sgp4Propagator propagator = new Sgp4Propagator(tle);

                // Create a Platform for the satellite, including a Point representing the position
                // as reported by the propagator.  The propagator produces raw ephemeris, while the
                // Point enables the results of propagation to work with the GeometryTransformer in
                // order to observe the ephemeris in different reference frames.
                satellitePlatform = new Platform();

                PropagatorPoint point = propagator.CreatePoint();
                satellitePlatform.LocationPoint = point;
                satellitePlatform.OrientationAxes = new AxesVehicleVelocityLocalHorizontal(earth.InertialFrame, satellitePlatform.LocationPoint);

                // Create a facility at the view location.  The longitude and latitude of the facility's
                // location are specified using radians, so convert degrees to radians.
                // Since we don't care about the orientation of the facility, we just
                // use Axes.Root.
                facilityPlatform = new Platform();

                Cartographic location = new Cartographic(Trig.DegreesToRadians(longitude), Trig.DegreesToRadians(latitude), 0.0);
                facilityPlatform.LocationPoint = new PointCartographic(CentralBodiesFacet.GetFromContext().Earth, location);
                facilityPlatform.OrientationAxes = Axes.Root;

                // Call method GetViewingOpportunities to calculate the viewing opportunities from
                // the input parameters.
                List<ViewingOpportunity> opportunities = GetViewingOpportunities();

                // Clear all items from the Output box before writing anything new.
                listView_DataOutput.Items.Clear();

                // Write each viewing opportunity to the output box on the form.
                foreach (ViewingOpportunity opportunity in opportunities)
                {
                    ListViewItem item = new ListViewItem(new[]
                    {
                        opportunity.StartDate.ToString(),
                        opportunity.ApproachAzimuth.ToString(),
                        opportunity.EndDate.ToString(),
                        opportunity.DepartureAzimuth.ToString(),
                    });
                    listView_DataOutput.Items.Add(item);
                }

                // Update the animation in the Insight3D component.
                UpdateVisualization();
            }
            catch
            {
                // If any of the input values could not be parsed...
                MessageBox.Show("Check your input values!");
            }
        }
    }
}

运行效果:

更多推荐

【基于STK Components(STK组件)的.Net4.5编程】之[SatelliteVisibility.sln]卫星可见性计算