/// <summary>
        /// Perfoms a median filter on the specified image
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="size">The size (pixels squared) of the area to take the median of.</param>
        /// <returns>The filtered median</returns>
        public static Image BlurFilter(Image image, int size)
        {
            var sourceBitmap = new Bitmap(image);
            var medianBitmap = new Bitmap(image.Width, image.Height);

            var apetureMin = -(size / 2);
            var apetureMax = (size / 2);

            var medianFastBitmap = new BitmapAccessor(medianBitmap);
            var sourceFastBitmap = new BitmapAccessor(sourceBitmap);

            for (var x = 0; x < medianBitmap.Width; x++)
            {
                for (var y = 0; y < medianBitmap.Height; y++)
                {
                    var rValue     = 0;
                    var gValue     = 0;
                    var bValue     = 0;
                    var pixelCount = 0;

                    for (var currentX = x + apetureMin; currentX < x + apetureMax; currentX++)
                    {
                        if (currentX < 0 || currentX >= medianBitmap.Width)
                        {
                            continue;
                        }
                        for (var currentY = y + apetureMin; currentY < y + apetureMax; currentY++)
                        {
                            if (currentY < 0 || currentY >= medianBitmap.Height)
                            {
                                continue;
                            }
                            var currentColor = sourceFastBitmap.GetPixel(currentX, currentY);
                            rValue += currentColor.R;
                            gValue += currentColor.G;
                            bValue += currentColor.B;
                            pixelCount++;
                        }
                    }

                    var medianColor = Color.FromArgb(rValue / pixelCount,
                                                     gValue / pixelCount,
                                                     bValue / pixelCount);

                    medianFastBitmap.SetPixel(x, y, medianColor);
                }
            }

            medianFastBitmap.Dispose();
            sourceFastBitmap.Dispose();
            sourceBitmap.Dispose();

            return(medianBitmap);
        }
        public async virtual Task <Bitmap> GetStaticMapImage(string region, int polygonMultiplier, int width, int height)
        {
            try
            {
                string geoJSON = await Geocoder.GetGeoJsonByName(region);

                string geoImageURL = LinkFormatter.GetImageStringURL(geoJSON, polygonMultiplier, width, height);
                Bitmap image       = await BitmapAccessor.Download(geoImageURL);

                return(image);
            }
            catch { return(null); }
        }
        public static Image DarkenImage(Image image, double darkenAmount)
        {
            var sourceBitmap = new Bitmap(image);
            var destBitmap   = new Bitmap(image.Width, image.Height);

            var destFastBitmap   = new BitmapAccessor(destBitmap);
            var sourceFastBitmap = new BitmapAccessor(sourceBitmap);

            for (var x = 0; x < destBitmap.Width; x++)
            {
                for (var y = 0; y < destBitmap.Height; y++)
                {
                    var color = sourceFastBitmap.GetPixel(x, y);
                    destFastBitmap.SetPixel(x, y, DarkenColor(color, darkenAmount));
                }
            }

            destFastBitmap.Dispose();
            sourceFastBitmap.Dispose();
            sourceBitmap.Dispose();

            return(destBitmap);
        }
        /// <summary>
        /// Perfoms a median filter on the specified image
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="size">The size (pixels squared) of the area to take the median of.</param>
        /// <returns>The filtered median</returns>
        public static Image BlurFilter(Image image, int size)
        {
            Bitmap sourceBitmap = new Bitmap(image);
            Bitmap medianBitmap = new Bitmap(image.Width, image.Height);

            int apetureMin = -(size / 2);
            int apetureMax = (size / 2);

            Color medianColor;
            Color currentColor;
            int rValue = 0;
            int gValue = 0;
            int bValue = 0;
            int pixelCount = 0;

            var medianFastBitmap = new BitmapAccessor(medianBitmap);
            var sourceFastBitmap = new BitmapAccessor(sourceBitmap);

            for (int x = 0; x < medianBitmap.Width; x++)
            {
                for (int y = 0; y < medianBitmap.Height; y++)
                {
                    rValue = 0;
                    gValue = 0;
                    bValue = 0;
                    pixelCount = 0;

                    for (int currentX = x + apetureMin; currentX < x + apetureMax; currentX++)
                    {
                        if (currentX >= 0 && currentX < medianBitmap.Width)
                        {
                            for (int currentY = y + apetureMin; currentY < y + apetureMax; currentY++)
                            {
                                if (currentY >= 0 && currentY < medianBitmap.Height)
                                {
                                    currentColor = sourceFastBitmap.GetPixel(currentX, currentY);
                                    rValue += currentColor.R;
                                    gValue += currentColor.G;
                                    bValue += currentColor.B;
                                    pixelCount++;
                                }
                            }
                        }
                    }

                    medianColor = Color.FromArgb(rValue / pixelCount,
                        gValue / pixelCount,
                        bValue / pixelCount);

                    medianFastBitmap.SetPixel(x, y, medianColor);
                }
            }

            medianFastBitmap.Dispose();
            sourceFastBitmap.Dispose();
            sourceBitmap.Dispose();

            return (Image)medianBitmap;
        }
        /// <summary>
        /// Perfoms a median filter on the specified image
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="size">The size (pixels squared) of the area to take the median of.</param>
        /// <returns>The filtered median</returns>
        public static Image MedianFilter(Image image, int size)
        {
            Bitmap sourceBitmap = new Bitmap(image);
            Bitmap medianBitmap = new Bitmap(image.Width, image.Height);

            var medianFastBitmap = new BitmapAccessor(medianBitmap);
            var sourceFastBitmap = new BitmapAccessor(sourceBitmap);

            int apetureMin = -(size / 2);
            int apetureMax = (size / 2);

            List<int> rValues = new List<int>();
            List<int> gValues = new List<int>();
            List<int> bValues = new List<int>();

            Color medianColor;
            Color currentColor;

            for (int x = 0; x < medianBitmap.Width; x++)
            {
                for (int y = 0; y < medianBitmap.Height; y++)
                {
                    for (int currentX = x + apetureMin; currentX < x + apetureMax; currentX++)
                    {
                        if (currentX >= 0 && currentX < medianBitmap.Width)
                        {
                            for (int currentY = y + apetureMin; currentY < y + apetureMax; currentY++)
                            {
                                if (currentY >= 0 && currentY < medianBitmap.Height)
                                {
                                    currentColor = sourceFastBitmap.GetPixel(currentX, currentY);
                                    rValues.Add(currentColor.R);
                                    gValues.Add(currentColor.G);
                                    bValues.Add(currentColor.B);
                                }
                            }
                        }
                    }

                    rValues.Sort();
                    gValues.Sort();
                    bValues.Sort();

                    medianColor = Color.FromArgb(rValues[rValues.Count / 2],
                        gValues[gValues.Count / 2],
                        bValues[bValues.Count / 2]);

                    medianFastBitmap.SetPixel(x, y, medianColor);

                    rValues.Clear();
                    gValues.Clear();
                    bValues.Clear();
                }
            }

            medianFastBitmap.Dispose();
            sourceFastBitmap.Dispose();
            sourceBitmap.Dispose();

            return (Image)medianBitmap;
        }
        /// <summary>
        /// Perfoms a median filter on the specified image
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="size">The size (pixels squared) of the area to take the median of.</param>
        /// <returns>The filtered median</returns>
        public static Image MedianFilter(Image image, int size)
        {
            var sourceBitmap = new Bitmap(image);
            var medianBitmap = new Bitmap(image.Width, image.Height);

            var medianFastBitmap = new BitmapAccessor(medianBitmap);
            var sourceFastBitmap = new BitmapAccessor(sourceBitmap);

            var apetureMin = -(size / 2);
            var apetureMax = (size / 2);

            var rValues = new List <int>();
            var gValues = new List <int>();
            var bValues = new List <int>();

            Color medianColor;
            Color currentColor;

            for (var x = 0; x < medianBitmap.Width; x++)
            {
                for (var y = 0; y < medianBitmap.Height; y++)
                {
                    for (var currentX = x + apetureMin; currentX < x + apetureMax; currentX++)
                    {
                        if (currentX >= 0 && currentX < medianBitmap.Width)
                        {
                            for (var currentY = y + apetureMin; currentY < y + apetureMax; currentY++)
                            {
                                if (currentY >= 0 && currentY < medianBitmap.Height)
                                {
                                    currentColor = sourceFastBitmap.GetPixel(currentX, currentY);
                                    rValues.Add(currentColor.R);
                                    gValues.Add(currentColor.G);
                                    bValues.Add(currentColor.B);
                                }
                            }
                        }
                    }

                    rValues.Sort();
                    gValues.Sort();
                    bValues.Sort();

                    medianColor = Color.FromArgb(rValues[rValues.Count / 2],
                                                 gValues[gValues.Count / 2],
                                                 bValues[bValues.Count / 2]);

                    medianFastBitmap.SetPixel(x, y, medianColor);

                    rValues.Clear();
                    gValues.Clear();
                    bValues.Clear();
                }
            }

            medianFastBitmap.Dispose();
            sourceFastBitmap.Dispose();
            sourceBitmap.Dispose();

            return(medianBitmap);
        }