Beispiel #1
0
        public override Bitmap Fill(TileTreeNode n)
        {
            var stride    = n.Stride;
            var demFirstY = n.Y * Height * n.Stride;
            var demFirstX = n.X * Width * n.Stride;

            Console.WriteLine($"PSRFiller X={n.X} Y={n.Y} Stride={n.Stride} demFirstY={demFirstY} demFirstX={demFirstX}");

            var bitmap     = n._bitmap ?? new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                for (var iy = 0; iy < Height; iy++)
                {
                    var rowptr = (byte *)(bitmapData.Scan0 + iy * bitmapData.Stride);
                    for (var ix = 0; ix < Width; ix++)
                    {
                        var val = ImgFile.ReadByte(demFirstY + iy * stride, demFirstX + ix * stride);
                        *(rowptr++) = val;  // B
                        *(rowptr++) = val;  // G
                        *(rowptr++) = val;  // R
                        *(rowptr++) = 255;  // A
                    }
                }
            }
            bitmap.UnlockBits(bitmapData);
            return(bitmap);
        }
Beispiel #2
0
        public override Bitmap Fill(TileTreeNode n)
        {
            if (StabilityTileGenerator == null)
            {
                lock (StabilityTileGeneratorLock)
                {
                    if (StabilityTileGenerator == null)
                    {
                        var generator = new IceStabilityTileGenerator();
                        generator.Load();
                        StabilityTileGenerator = generator;
                    }
                }
            }
            var demFirstY = n.Y * Height * n.Stride;
            var demFirstX = n.X * Width * n.Stride;

            Console.WriteLine($"IceStabilityFiller X={n.X} Y={n.Y} Stride={n.Stride} demFirstY={demFirstY} demFirstX={demFirstX}");
            lock (StabilityTileGeneratorLock)
            {
                var bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
                using (var g = Graphics.FromImage(bitmap))
                {
                    g.ScaleTransform(1f / n.Stride, 1f / n.Stride);
                    g.TranslateTransform(-demFirstX, -demFirstY);
                    StabilityTileGenerator.Draw(g, new Rectangle(demFirstX, demFirstY, Width * n.Stride, Height * n.Stride));
                }
                return(bitmap);
            }
        }
Beispiel #3
0
 /// <summary>
 /// Fetch a node.  Create one if it's not already there.
 /// </summary>
 /// <param name="a">An address</param>
 /// <returns></returns>
 public TileTreeNode Fetch(int a)
 {
     if (_tileCache.TryGetValue(a, out TileTreeNode r))
     {
         return(r);
     }
     r = new TileTreeNode(a, _CacheDirectory);
     _tileCache.Add(a, r);
     return(r);
 }
Beispiel #4
0
        public override Bitmap Fill(TileTreeNode n)
        {
            var stride    = n.Stride;
            var demFirstY = n.Y * Height * n.Stride;
            var demFirstX = n.X * Width * n.Stride;

            Console.WriteLine($"SlopeFiller isNorth={InMemoryTerrainManager.Singleton.IsNorth} X={n.X} Y={n.Y} Stride={n.Stride} demFirstY={demFirstY} demFirstX={demFirstX}");
            var dem     = new short[Height, Width];
            var terrain = InMemoryTerrainManager.Singleton;

            for (var iy = 0; iy < Height; iy++)
            {
                for (var ix = 0; ix < TileTreeNode.Width; ix++)
                {
                    dem[iy, ix] = terrain.Fetch(demFirstY + iy * stride, demFirstX + ix * stride);
                }
            }

            var bitmap = n._bitmap ?? new Bitmap(TileTreeNode.Width, TileTreeNode.Height, PixelFormat.Format32bppArgb);

            var green  = Color.FromArgb(255, Color.PaleGreen).ToArgb();
            var yellow = Color.FromArgb(255, Color.LightGoldenrodYellow).ToArgb();
            var red    = Color.FromArgb(255, Color.IndianRed).ToArgb();

            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                for (var y = 0; y < Height; y++)
                {
                    var rowptr = (Int32 *)(bitmapData.Scan0 + y * bitmapData.Stride);
                    for (var x = 0; x < Width; x++)
                    {
                        var slope     = SlopesForHillshade(x, y, dem, Width, Height, 20f * stride);
                        var angle_deg = Math.Atan(slope) * 180d / Math.PI;

                        if (angle_deg <= 11d)    // matches the round-down in the traverse planner.
                        {
                            *(rowptr++) = green;
                        }
                        else if (angle_deg <= 16d)
                        {
                            *(rowptr++) = yellow;
                        }
                        else
                        {
                            *(rowptr++) = red;
                        }
                    }
                }
            }
            bitmap.UnlockBits(bitmapData);
            return(bitmap);
        }
Beispiel #5
0
        public void Draw(Graphics g, DisplayTransform t, ImageAttributes attributes = null)
        {
            var r = g.ClipBounds;
            //Console.WriteLine($"-- clipbounds={r}");
            // Scale indicates the number of map pixels per screen pixel.
            // OffsetX and OffsetY indicate the offset of the window origin relative to the upper left
            // corner of the tile array at the current level.

            var level = (int)(Math.Log(t.Scale) / Log2);                 // Log2(Scale);

            level = Math.Min(TileTreeNode.TopLevel, Math.Max(0, level)); // Clip level
            var stride = TileTreeNode.PowersOf2[level];

            var drawScale = t.Scale / stride;                      // range = [1,2)
            var cellSize  = (int)(TileTreeNode.Width / drawScale); // range = (475, 950], width==height
            var cellMax   = TileTreeNode.MapWidth / (TileTreeNode.Width * stride);

            var x1 = Math.Max(0, -t.OffsetX / cellSize - 1);
            var y1 = Math.Max(0, -t.OffsetY / cellSize - 1);

            var x2 = cellMax - 1;
            var y2 = cellMax - 1;

            for (var y = y1; y <= y2; y++)
            {
                var pixelY = t.OffsetY + y * cellSize;
                if (pixelY > r.Bottom)
                {
                    //Console.WriteLine($"  break pixelY {pixelY} > r.Bottom {r.Bottom}");
                    break;
                }
                for (var x = x1; x <= x2; x++)
                {
                    var pixelX = t.OffsetX + x * cellSize;
                    if (pixelX > r.Right)
                    {
                        //Console.WriteLine($"  break pixelX {pixelX} > r.Right {r.Right}");
                        break;
                    }
                    //Console.WriteLine($"  drawing x={pixelX} y={pixelY} x={x} y={y} width={r.Width} height={r.Height}");
                    var address = TileTreeNode.CalculateAddress(level, x, y);
                    var cell    = Fetch(address);
                    var bitmap  = Filler != null?cell.GenerateBitmap(Filler) : null;

                    if (bitmap != null)
                    {
                        var r1 = new Rectangle(pixelX, pixelY, cellSize, cellSize);
                        if (attributes == null)
                        {
                            g.DrawImage(bitmap, r1);
                        }
                        else
                        {
                            g.DrawImage(bitmap, r1, 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, attributes);
                        }
                    }
                    else
                    {
                        if (attributes == null)
                        {
                            g.FillRectangle(Brushes.DarkGray, pixelX, pixelY, cellSize, cellSize);
                        }
                    }
                }
            }
        }
Beispiel #6
0
        public override Bitmap Fill(TileTreeNode n)
        {
            var          stride      = n.Stride;
            const double elevation   = 30d * Math.PI / 180d;
            const double azimuth     = -Math.PI / 2;
            var          Zenith_rad  = Math.PI / 2d - elevation;
            var          Azimuth_rad = Math.PI - azimuth; // Convert from map azimuth to hillshade azimuth

            var demFirstY = n.Y * Height * n.Stride;
            var demFirstX = n.X * Width * n.Stride;

            Console.WriteLine($"HillshadeFiller isNorth={InMemoryTerrainManager.Singleton.IsNorth} X={n.X} Y={n.Y} Stride={n.Stride} demFirstY={demFirstY} demFirstX={demFirstX}");
            var dem     = new short[Height, Width];
            var terrain = InMemoryTerrainManager.Singleton;

            for (var iy = 0; iy < Height; iy++)
            {
                for (var ix = 0; ix < TileTreeNode.Width; ix++)
                {
                    dem[iy, ix] = terrain.Fetch(demFirstY + iy * stride, demFirstX + ix * stride);
                }
            }

            var bitmap  = n._bitmap != null ? n._bitmap : new Bitmap(TileTreeNode.Width, TileTreeNode.Height, PixelFormat.Format8bppIndexed);
            var palette = bitmap.Palette;

            for (var i = 0; i < 256; i++)
            {
                palette.Entries[i] = Color.FromArgb(i, i, i);
            }
            bitmap.Palette = palette;

            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

            unsafe
            {
                for (var y = 0; y < Height; y++)
                {
                    var rowptr = (byte *)(bitmapData.Scan0 + y * bitmapData.Stride);
                    for (var x = 0; x < Width; x++)
                    {
                        SlopesForHillshade(x, y, dem, Width, Height, 20f * stride, out float dzdx, out float dzdy);

                        double Aspect_rad;
                        if (dzdx != 0f)
                        {
                            Aspect_rad = Math.Atan2(dzdy, -dzdx);
                            if (Aspect_rad < 0f)
                            {
                                Aspect_rad = Math.PI * 2d + Aspect_rad;
                            }
                        }
                        else
                        {
                            if (dzdy > 0f)
                            {
                                Aspect_rad = Math.PI / 2d;
                            }
                            else if (dzdy < 0)
                            {
                                Aspect_rad = 1.5d * Math.PI;
                            }
                            else
                            {
                                Aspect_rad = 0d;
                            }
                        }

                        // Should be this.  There's some inversion in the slopes (I think)
                        //const double z_factor = 1d;
                        //var Slope_rad = Math.Atan(z_factor * Math.Sqrt(dzdx * dzdx + dzdy * dzdy));

                        var Slope_rad = -Math.Atan(Math.Sqrt(dzdx * dzdx + dzdy * dzdy));
                        var Hillshade = (Math.Cos(Zenith_rad) * Math.Cos(Slope_rad)) + (Math.Sin(Zenith_rad) * Math.Sin(Slope_rad) * Math.Cos(Azimuth_rad - Aspect_rad));

                        Hillshade   = Math.Max(0d, Hillshade);
                        *(rowptr++) = (byte)(255 * Hillshade);
                    }
                }
            }
            bitmap.UnlockBits(bitmapData);
            return(bitmap);
        }
Beispiel #7
0
 abstract public Bitmap Fill(TileTreeNode n);