예제 #1
0
파일: Program.cs 프로젝트: speedyjeff/tides
        private async static Task <int> Tides(Predictions predictions)
        {
            var querycount = 0;

            predictions.OnQuery += () =>
            {
                querycount++;
            };

            // this should cause a query
            var tides = await predictions.CurrentTides();

            foreach (var tide in tides)
            {
                Console.WriteLine($"{tide.Date} {tide.Value}");
            }

            if (tides.Count == 0 || querycount != 1)
            {
                throw new Exception("Invalid query");
            }

            // this round should not cause a query
            tides = await predictions.CurrentTides();

            if (tides.Count == 0 || querycount != 1)
            {
                throw new Exception("Invalid query");
            }

            Console.WriteLine();

            var extremes = await predictions.CurrentExtremes();

            foreach (var e in extremes)
            {
                Console.WriteLine($"{e.Date} {e.Value} {e.Type}");
            }

            if (extremes.Count == 0 || querycount != 2)
            {
                throw new Exception($"Invalid query : {extremes.Count} {querycount}");
            }

            // this round should not cause a query
            extremes = await predictions.CurrentExtremes();

            if (extremes.Count == 0 || querycount != 2)
            {
                throw new Exception("Invalid query");
            }

            return(0);
        }
예제 #2
0
        private async void FrameUpdate(object state)
        {
            if (Canvas == null)
            {
                throw new Exception("must have a valid canvas to draw too");
            }

            // the timer is reentrant, so only allow one instance to run
            if (System.Threading.Interlocked.CompareExchange(ref FrameLock, 1, 0) != 0)
            {
                return;
            }

            // grab predictions
            var tides = await Prediction.CurrentTides();

            var suns = await Prediction.CurrentSuns();

            // locations
            var dimension = Math.Min(Canvas.Width, Canvas.Height);
            var center    = new Point((dimension / 2f), (dimension / 2f), z: 0f);
            var points    = new Point[2];
            var fontsize  = 18f * Ratio;
            var fontname  = "Courier New";

            // outer ring
            var ringthickness = (float)Math.Round(0.25f * Ratio, 1);

            if (ringthickness < 1f)
            {
                ringthickness = 1f;
            }
            var innerradius       = dimension / 20f;
            var outerradius       = (dimension * 0.37f) + innerradius + ringthickness;
            var tidelinethickness = (float)Math.Round(0.25f * Ratio, 1);

            if (tidelinethickness < 1f)
            {
                tidelinethickness = 1f;
            }

            // get time
            var now   = DateTime.Now;
            var later = now.AddHours(24);

            // calculate the local min/max
            var min = Single.MaxValue;
            var max = Single.MinValue;

            foreach (var tide in tides)
            {
                if (tide.Date >= now && tide.Date < later)
                {
                    min = Math.Min(min, tide.Value);
                    max = Math.Max(max, tide.Value);
                }
            }

            // adjust so that the min/max do not rest on the line
            min -= (0.1f * Ratio);
            max += (0.1f * Ratio);

            // flip the sign of min to bring to 0
            min *= -1;

            try
            {
                await Canvas.SuspendLayout();

                // clear
                Canvas.Clear(RGBA.Black);

                // outer ring
                Canvas.Ellipse(RingColor, center, width: 2 * outerradius, height: 2 * outerradius, fill: false, border: false, ringthickness);

                // clock numbers
                for (int i = 1; i <= 24; i++)
                {
                    var angle = i * (360f / 24f);

                    // draw line
                    CalculateLineByAngle(center.X, center.Y, angle, outerradius, out points[0].X, out points[0].Y, out points[1].X, out points[1].Y);
                    Canvas.Polygon(RingColor, points, fill: false, border: false, ringthickness);

                    // draw number
                    CalculateLineByAngle(center.X, center.Y, angle, outerradius + (25f * Ratio), out points[0].X, out points[0].Y, out points[1].X, out points[1].Y);

                    // adjust for the font size
                    points[1].X -= (15f * Ratio);
                    points[1].Y -= (8f * Ratio);

                    Canvas.Text(RingColor, points[1], Clocknumber(i), fontsize, fontname);
                }

                // draw the tides as a sun burst
                var count = 0;
                foreach (var tide in tides)
                {
                    if (tide.Date >= now && tide.Date < later)
                    {
                        if (LowResolution && count++ % 2 == 0)
                        {
                            continue;
                        }
                        // calculate angles
                        CalculateAngleByClockface(tide.Date.Hour, tide.Date.Minute, tide.Date.Second, out float hour, out float minute, out float seccond);

                        // calculate the magnitude of the line
                        var distance = ((tide.Value + min) / (min + max)) * (outerradius - innerradius);

                        // calculate the line
                        CalculateLineByAngle(center.X, center.Y, hour, innerradius, out points[1].X, out points[1].Y, out points[0].X, out points[0].Y);
                        CalculateLineByAngle(points[0].X, points[0].Y, hour, distance, out points[0].X, out points[0].Y, out points[1].X, out points[1].Y);

                        // draw the line
                        var angledelta = Math.Min(Math.Min(Math.Abs(Angle - hour), Math.Abs((Angle + 360) - hour)), Math.Abs(Angle - (hour + 360)));
                        var color      = RGBA.Black;
                        if (tide.Date.Subtract(now).TotalMinutes < (LowResolution ? 12 : 6))
                        {
                            color = CurrentTimeColor;
                        }
                        else if (angledelta < 10)
                        {
                            color = HighlightHghColor;
                        }
                        else if (angledelta < 20)
                        {
                            color = HighlightMidColor;
                        }
                        else if (angledelta < 30)
                        {
                            color = HighlightLowColor;
                        }
                        else
                        {
                            color = SpokeColor;
                        }
                        Canvas.Polygon(color, points, fill: false, border: false, tidelinethickness);
                    }
                }

                // insert sunrise/sunset information
                foreach (var sun in suns)
                {
                    if (sun.Date.Date == now.Date.Date)
                    {
                        // calculate angles
                        CalculateAngleByClockface(sun.Date.Hour, sun.Date.Minute, sun.Date.Second, out float hour, out float minute, out float seccond);
                        CalculateLineByAngle(center.X, center.Y, hour, outerradius, out points[1].X, out points[1].Y, out points[0].X, out points[0].Y);
                        var diameter = (20f * Ratio);

                        if (sun.Type.Equals("sunrise", StringComparison.OrdinalIgnoreCase))
                        {
                            Canvas.Ellipse(RGBA.White, points[0], diameter, diameter, fill: true, border: false, thickness: 2f * Ratio);
                        }
                        else if (sun.Type.Equals("sunset", StringComparison.OrdinalIgnoreCase))
                        {
                            Canvas.Ellipse(RGBA.White, points[0], diameter, diameter, fill: false, border: true, thickness: 2f * Ratio);
                        }
                        else
                        {
                            throw new Exception($"unknown sun type : {sun.Type}");
                        }
                    }
                }
            }
            finally
            {
                await Canvas.ResumeLayout();
            }

            // fire that the frame is done
            if (OnRendered != null)
            {
                OnRendered();
            }

            // set state back to not running
            System.Threading.Volatile.Write(ref FrameLock, 0);

            // increase the angle
            Angle = (Angle + (LowResolution ? 2f : 0.25f)) % 360f;
        }