Esempio n. 1
0
 public static int DistanceToGeoPositionMeters(this IGeographicPosition pos1, IGeographicPosition pos2)
 {
     var dLat = deg2rad(pos2.PositionLatDegrees - pos1.PositionLatDegrees);
     var dLon = deg2rad(pos2.PositionLonDegrees - pos1.PositionLonDegrees);
     var lat1 = deg2rad(pos1.PositionLatDegrees);
     var lat2 = deg2rad(pos2.PositionLatDegrees);
     var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat1) * Math.Cos(lat2);
     var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
     return (int) Math.Round(meanEarthRadius * c * 1000);
 }
        /// <summary>
        /// Subscribe an observation point (lat / lon / elevation) and attach a callback for detected events.
        /// </summary>
        /// <param name="airfieldKey">a definable key</param>
        /// <param name="airfieldPosition">position and elevation of the observation point (usually an airfield)</param>
        /// <param name="eventDetectedCallback">callback on event detected</param>
        public void SubscribeAirfieldForMovmentEvents(string airfieldKey, IGeographicPosition airfieldPosition, Action<AircraftTrackEvent> eventDetectedCallback = null)
        {
            if(airfieldSubscriptions.ContainsKey(airfieldKey))
            {
                if(eventDetectedCallback != null)
                    airfieldSubscriptions[airfieldKey].EventDetected += eventDetectedCallback;

                return;
            }

            var subscription = new AirfieldSubscription { AirfieldKey = airfieldKey, AirfieldPosition = airfieldPosition };

            if (eventDetectedCallback != null)
                subscription.EventDetected += eventDetectedCallback;

            airfieldSubscriptions.Add(airfieldKey, subscription);
        }
Esempio n. 3
0
        public static float InitialBearingToGeoPositionDegrees(this IGeographicPosition pos1, IGeographicPosition pos2)
        {
            var lat1 = deg2rad(pos1.PositionLatDegrees); // φ1
            var lat2 = deg2rad(pos2.PositionLatDegrees); // φ2
            var lon1 = deg2rad(pos1.PositionLonDegrees); // λ1
            var lon2 = deg2rad(pos2.PositionLonDegrees); // λ2
            var dLat = deg2rad(pos2.PositionLatDegrees - pos1.PositionLatDegrees); // Δφ
            var dLon = deg2rad(pos2.PositionLonDegrees - pos1.PositionLonDegrees); // Δλ

            var y = Math.Sin(dLon) * Math.Cos(lat2);
            var x = Math.Cos(lat1) * Math.Sin(lat2) - Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(dLon);
            var bearing = rad2deg(Math.Atan2(y, x));

            if (bearing < 0d)
                bearing += 360d;

            return (float) Math.Round(bearing, 1);
        }
        public static IEnumerable<AircraftTrackEvent> DetectTrackEvents(this CircularFifoBuffer<AircraftBeaconSpeedAndTrack> fifoBuffer, DateTime evalDateTimeUtc, TimeSpan maxTimeSpan, IGeographicPosition eventTargetCenter)
        {
            var events = new List<AircraftTrackEvent>();

            List<AircraftBeaconSpeedAndTrack> evalWindow = fifoBuffer.extractAndReverseBufferForEvalWindow(evalDateTimeUtc, maxTimeSpan, getAlreadyAnalysed: true);

            // we need 4 beacons to detect - two one state - two other state
            if (evalWindow.Count < 4)
                return events;

            int i = 0;
            while(++i <= evalWindow.Count - 4)
            {
                var subWindow = evalWindow.Skip(i).Take(4).ToArray();

                // accuracy check
                if (subWindow[3].PositionTimeUTC.Subtract(subWindow[0].PositionTimeUTC).TotalSeconds > accuracyCheck4BeaconsMaxTimeSpanSeconds)
                    continue;
                
                bool landing = subWindow[0].isMoving()
                            && subWindow[1].isMoving()
                            && subWindow[2].isStoppedOnGround(eventTargetCenter.PositionAltitudeMeters)
                            && subWindow[2].isWithinRefPositionRange(eventTargetCenter)
                            && subWindow[3].isStoppedOnGround(eventTargetCenter.PositionAltitudeMeters)
                            && subWindow[3].isWithinRefPositionRange(eventTargetCenter);

                if (landing)
                    events.Add(new AircraftTrackEvent { EventType = AircraftTrackEventTypes.Landing, EventDateTimeUTC = subWindow[2].PositionTimeUTC, ReferenceBeacon = subWindow[2] });

                bool takeOff = subWindow[0].isStoppedOnGround(eventTargetCenter.PositionAltitudeMeters)
                            && subWindow[0].isWithinRefPositionRange(eventTargetCenter)
                            && subWindow[1].isStoppedOnGround(eventTargetCenter.PositionAltitudeMeters)
                            && subWindow[1].isWithinRefPositionRange(eventTargetCenter)
                            && subWindow[2].isMoving()
                            && subWindow[3].isMoving();

                if (takeOff)
                    events.Add(new AircraftTrackEvent { EventType = AircraftTrackEventTypes.TakeOff, EventDateTimeUTC = subWindow[1].PositionTimeUTC, ReferenceBeacon = subWindow[2] });
            }

            return events.Distinct(new AircraftTrackEventComparer());
        }
 private static bool isWithinRefPositionRange(this AircraftBeaconSpeedAndTrack beacon, IGeographicPosition refPos) => beacon.DistanceToGeoPositionMeters(refPos) <= airportRangeRadiusMeters;