Esempio n. 1
0
        private async static Task <int> Suns(Predictions predictions)
        {
            var querycount = 0;

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

            // this should cause a query
            var suns = await predictions.CurrentSuns();

            foreach (var s in suns)
            {
                Console.WriteLine($"{s.Date} {s.Type}");
            }

            if (suns.Count == 0 || querycount <= 0)
            {
                throw new Exception("Invalid query");
            }

            var previousquerycount = querycount;

            // this round should not cause a query
            suns = await predictions.CurrentSuns();

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

            return(0);
        }
Esempio n. 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;
        }
Esempio n. 3
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 extremes = await Prediction.CurrentExtremes();

            var suns = await Prediction.CurrentSuns();

            // gather the tide extreme data
            var            extremedetails = new List <ExtremeDetails>();
            ExtremeDetails current        = null;

            foreach (var ex in extremes.OrderBy(e => e.Date))
            {
                // check if the current is complete
                if (current != null && (current.Date.Date != ex.Date.Date || current.HighDate != default(DateTime)))
                {
                    // add it
                    extremedetails.Add(current);
                    current = null;
                }
                // check if we need to create a new one
                if (current == null)
                {
                    current = new ExtremeDetails()
                    {
                        Date = ex.Date.Date
                    };
                }

                // add the tide info
                if (ex.Type.Equals("h", StringComparison.OrdinalIgnoreCase))
                {
                    if (current.HighDate != default(DateTime))
                    {
                        throw new Exception("Invalid high tide");
                    }
                    current.HighDate  = ex.Date;
                    current.HighValue = ex.Value;
                }
                else if (ex.Type.Equals("l", StringComparison.OrdinalIgnoreCase))
                {
                    if (current.LowDate != default(DateTime))
                    {
                        throw new Exception("Invalid low tide");
                    }
                    current.LowDate  = ex.Date;
                    current.LowValue = ex.Value;
                }
                else
                {
                    throw new Exception($"unknown extreme type {ex.Type}");
                }
            }
            if (current != null)
            {
                extremedetails.Add(current);
            }

            var now            = DateTime.Now;
            var rowheight      = 24f * Ratio;
            var margin         = 20f * Ratio;
            var headerfontsize = 20f * Ratio;
            var headerfontname = "Courier New";             // "Eras Light ITC";
            var datafontsize   = 18f * Ratio;
            var datafontname   = "Courier New";
            var point          = new Point()
            {
                X = 0f, Y = 0f
            };

            try
            {
                await Canvas.SuspendLayout();

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

                Canvas.Text(RGBA.White, point, $"{now:MMM dd, yyyy} {Prediction.Location}", headerfontsize, headerfontname);

                //
                // tide extremes
                //
                point.Y = (rowheight * 1.5f);
                point.X = (datafontsize * 4f);
                Canvas.Text(RGBA.White, point, "low", datafontsize, datafontname);
                point.X = (datafontsize * 17f);
                Canvas.Text(RGBA.White, point, "high", datafontsize, datafontname);
                var prvdate = default(DateTime);
                foreach (var ex in extremedetails)
                {
                    if (ex.Date.Date >= now.Date && point.Y < (Canvas.Height - (rowheight * 2)))
                    {
                        point.Y += rowheight;
                        if (!prvdate.Date.Equals(ex.Date.Date))
                        {
                            point.Y += (rowheight / 4f);
                            point.X  = 0f;
                            Canvas.Text(RGBA.White, point, $"{ex.Date:ddd}", datafontsize, datafontname);
                        }
                        if (ex.LowDate != default(DateTime))
                        {
                            point.X = (datafontsize * 4f);
                            Canvas.Text(RGBA.White, point, $"{ex.LowDate:hh:mm tt} {(ex.LowValue > 0f ? " " : "")}{ex.LowValue:f2}", datafontsize, datafontname);
                        }
                        if (ex.HighDate != default(DateTime))
                        {
                            point.X = (datafontsize * 16f);
                            Canvas.Text(RGBA.White, point, $"{ex.HighDate:hh:mm tt} {(ex.HighValue < 10f ? " " : "")}{ex.HighValue:f2}", datafontsize, datafontname);
                        }
                        prvdate = ex.Date;
                    }
                }
            }
            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);
        }