Example #1
0
        public MemoryStream RenderWeatherImage(WeatherRendererInfo info)
        {
            MemoryStream output = new MemoryStream();

            using (Image <Rgba32> image = images["background"].Clone())
            {
                var now = info.Date;

                var topDateLine    = now.ToString("h:mm:ss tt", CultureInfo.CurrentCulture).ToUpper();
                var bottomDateLine = now.ToString("ddd MMM d", CultureInfo.CurrentCulture).ToUpper();
                var tickerLine     = info.Alert != null ? info.Alert + "\n" : "";
                tickerLine +=
                    $"Temp: {(int)info.Temperature}°{info.Unit}   Feels Like: {(int)info.FeelsLike}°{info.Unit}";

                if (info.Alert != null)
                {
                    image.Mutate(i => i.Fill <Rgba32>(WeatherColors.Red, new Rectangle(0, 480, image.Width, 96)));
                }

                // everything except the forecast
                var cmds = new List <DrawCommand>
                {
                    new DrawCommand()
                    {
                        Text  = info.Address,
                        Font  = mdFont,
                        X     = 150,
                        Y     = 8,
                        Color = WeatherColors.White
                    },
                    new DrawCommand()
                    {
                        Text       = "Extended Forecast",
                        Font       = mdFont,
                        IsRelative = true,
                        X          = 0,
                        Y          = 36,
                        Color      = WeatherColors.Yellow
                    },
                    new DrawCommand()
                    {
                        Text = topDateLine, Font = smFont, X = 695, Y = 12, Color = WeatherColors.White
                    },
                    new DrawCommand()
                    {
                        Text       = bottomDateLine,
                        Font       = smFont,
                        IsRelative = true,
                        X          = 0,
                        Y          = 25,
                        Color      = WeatherColors.White
                    },
                    new DrawCommand()
                    {
                        Text = tickerLine, Font = mdFont, X = 5, Y = 485, Color = WeatherColors.White
                    },
                };

                int bx = 15, by = 90;
                foreach (var day in info.Forecast)
                {
                    cmds.AddRange(new List <DrawCommand>
                    {
                        new DrawCommand()
                        {
                            X = bx, Y = by
                        },

                        // day of week, icon, summary
                        new DrawCommand()
                        {
                            Text = day.Date.ToString("ddd", CultureInfo.CurrentCulture).ToUpper(),
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment   = VerticalAlignment.Center,
                            IsRelative          = true,
                            X     = 100,
                            Y     = 30,
                            Font  = mdFont,
                            Color = WeatherColors.Yellow
                        },
                        new DrawCommand()
                        {
                            Image = images.ContainsKey(day.Icon) ? images[day.Icon] : images["clear-day"],
                            HorizontalAlignment = HorizontalAlignment.Center,
                            ContentWidth        = 190,
                            IsRelative          = true,
                            X = -90,
                            Y = 40
                        },
                        new DrawCommand()
                        {
                            Text = day.Summary,
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment   = VerticalAlignment.Center,
                            IsRelative          = true,
                            X     = 90,
                            Y     = 150,
                            Font  = mdFont,
                            Color = WeatherColors.White
                        },

                        // low temperature
                        new DrawCommand()
                        {
                            Text = "Lo",
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment   = VerticalAlignment.Center,
                            IsRelative          = true,
                            X     = -50,
                            Y     = 75,
                            Font  = mdFont,
                            Color = WeatherColors.TealAlso
                        },
                        new DrawCommand()
                        {
                            Text = day.LoTemp != null ? Math.Round(day.LoTemp.Value, 0).ToString() : "",
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment   = VerticalAlignment.Center,
                            IsRelative          = true,
                            X     = 0,
                            Y     = 50,
                            Font  = lgFont,
                            Color = WeatherColors.White
                        },

                        // high temperature
                        new DrawCommand()
                        {
                            Text = "Hi",
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment   = VerticalAlignment.Center,
                            IsRelative          = true,
                            X     = 100,
                            Y     = -50,
                            Font  = mdFont,
                            Color = WeatherColors.Yellow
                        },
                        new DrawCommand()
                        {
                            Text = day.HiTemp != null ? Math.Round(day.HiTemp.Value, 0).ToString() : "",
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment   = VerticalAlignment.Center,
                            IsRelative          = true,
                            X     = 0,
                            Y     = 50,
                            Font  = lgFont,
                            Color = WeatherColors.White
                        },
                    });

                    bx += 244;
                }

                int x = 0, y = 0;
                foreach (var cmd in cmds)
                {
                    // reset the position if it's not relative
                    if (cmd.IsRelative)
                    {
                        x += cmd.X;
                        y += cmd.Y;
                    }
                    else
                    {
                        x = cmd.X;
                        y = cmd.Y;
                    }

                    // if we have a text object, use textalignment, color, and text fields
                    if (cmd.Text != null)
                    {
                        var textOpts = new TextGraphicsOptions(false)
                        {
                            HorizontalAlignment = cmd.HorizontalAlignment, VerticalAlignment = cmd.VerticalAlignment
                        };
                        image.Mutate(i => i.DrawText(textOpts, cmd.Text, cmd.Font, WeatherColors.Black, new Vector2(x + 2, y + 2)));
                        image.Mutate(i => i.DrawText(textOpts, cmd.Text, cmd.Font, cmd.Color, new Vector2(x, y)));
                    }

                    // if we have an image object, use the image field
                    if (cmd.Image != null)
                    {
                        Point pos = new Point(x, y);
                        if (cmd.ContentWidth > 0 && cmd.HorizontalAlignment == HorizontalAlignment.Center)
                        {
                            pos.X += (cmd.ContentWidth - cmd.Image.Width) / 2;
                        }

                        image.Mutate(i => i.DrawImage(cmd.Image, PixelBlenderMode.Normal, 1.0f, pos));
                    }
                }
                image.SaveAsPng(output);
            }
            output.Seek(0, SeekOrigin.Begin);
            return(output);
        }
Example #2
0
        // only get the data here, buddy
        public async Task <WeatherRendererInfo> GetForecastAsync(string query)
        {
            // use google to get address, lat, and lng for a human-entered string
            Location location;

            try
            {
                IGeocoder geocoder  = new BingMapsGeocoder(bingApiKey);
                var       geoResult = await geocoder.GeocodeAsync(query);

                dynamic address = geoResult.FirstOrDefault();

                if (address == null)
                {
                    return(null);
                }

                location = new Location
                {
                    Latitude         = address.Coordinates.Latitude,
                    Longitude        = address.Coordinates.Longitude,
                    FormattedAddress = address.FormattedAddress
                };

                if (address.Type.ToString().StartsWith("Postcode"))
                {
                    location.FormattedAddress = $"{address.Locality} {address.FormattedAddress}";
                }
            }
            catch (Exception)
            {
                return(null);
            }

            // request darksky without minutely/hourly, and use location to determine units
            var             WeatherService = new DarkSkyService(darkSkyApiKey);
            DarkSkyResponse forecast       = await WeatherService.GetForecast(location.Latitude, location.Longitude,
                                                                              new DarkSkyService.OptionalParameters
            {
                DataBlocksToExclude = new List <ExclusionBlock> {
                    ExclusionBlock.Minutely, ExclusionBlock.Hourly,
                },
                MeasurementUnits = "auto"
            });

            var timezone = DateTimeZoneProviders.Tzdb[forecast.Response.TimeZone];
            var myTime   = SystemClock.Instance.GetCurrentInstant();
            var info     = new WeatherRendererInfo()
            {
                Address     = location.FormattedAddress,
                Unit        = forecast.Response.Flags.Units == "us" ? "F" : "C",
                Date        = myTime.InZone(timezone),
                Temperature = forecast.Response.Currently.Temperature,
                FeelsLike   = forecast.Response.Currently.ApparentTemperature,
                Alert       = forecast.Response.Alerts?[0].Title
            };

            int counter = 0;

            foreach (var day in forecast.Response.Daily.Data.Take(4))
            {
                var dayRender = new WeatherRendererDay()
                {
                    HiTemp  = day.TemperatureHigh,
                    LoTemp  = day.TemperatureLow,
                    Summary = weatherDescription.ContainsKey(day.Icon.ToString())
                        ? weatherDescription[day.Icon.ToString()]
                        : day.Icon.ToString().Replace("-", ""),
                    Icon = string.Join("-", Regex.Split(day.Icon.ToString(), @"(?<!^)(?=[A-Z])")).ToLower(),
                    Date = info.Date.Plus(Duration.FromDays(counter))
                };

                info.Forecast.Add(dayRender);
                counter++;
            }
            return(info);
        }