Ejemplo n.º 1
0
        protected List <string> GetChildTiles(int tx, int ty, int zoom)
        {
            var boundingBox = PointToTile.TileBounds(zoom, tx, ty);
            var s           = new List <string>();
            var v           = PointToTile.LatLonToTile(zoom + 1, boundingBox.Min.Lat, boundingBox.Min.Lon);
            var x           = PointToTile.LatLonToTile(zoom + 1, boundingBox.Max.Lat, boundingBox.Max.Lon);

            s.Add($"{zoom + 1}/{v.X + 0}/{v.Y + 0}");
            s.Add($"{zoom + 1}/{v.X + 1}/{v.Y + 0}");
            s.Add($"{zoom + 1}/{v.X + 0}/{v.Y + 1}");
            s.Add($"{zoom + 1}/{v.X + 1}/{v.Y + 1}");

            return(s);
        }
Ejemplo n.º 2
0
        public void GetJobSize(IRasterDataset dataset, int maxDesiredLevel, out int maxActualLevel, out int numTiles)
        {
            double xMin, yMin, xMax, yMax;

            maxActualLevel = 0;

            RasterInfo r = dataset.Info;

            xMin = r.FieldInfo[0].Envelope.XMin;
            xMax = r.FieldInfo[0].Envelope.XMax;
            yMin = r.FieldInfo[0].Envelope.YMin;
            yMax = r.FieldInfo[0].Envelope.YMax;
            var sourceSample = dataset.Info.FieldInfo[0].CellSizeX.Decimal;

            int  total = 0;
            bool atMax = false;
            int  zoom  = 0;

            while (!atMax)
            {
                var southWestTile = PointToTile.LatLonToTile(zoom, yMin, xMin);
                var northEastTile = PointToTile.LatLonToTile(zoom, yMax, xMax);
                var dx            = northEastTile.X - southWestTile.X;
                var dy            = northEastTile.Y - southWestTile.Y;

                //copy paste quick+ dirty code to determine whether we are creating this zoom level
                var boundingBox = PointToTile.TileBounds(zoom, northEastTile.X, northEastTile.Y);
                var tileSample  = (boundingBox.Max.Lon - boundingBox.Min.Lon) / 64;

                if (tileSample < (sourceSample / 2.0) || zoom > maxDesiredLevel)
                {
                    atMax = true;
                }
                else
                {
                    maxActualLevel = zoom;
                    zoom++;
                    total += ((dx + 1) * (dy + 1));
                }
            }

            numTiles = total;
        }
        public override bool CreateTile(int tx, int ty, int zoom, IRasterDataset dataset, byte[] tile)
        {
            var boundingBox = PointToTile.TileBounds(zoom, tx, ty);
            var iterator    = dataset.GetRandomIterator(IteratorMode.Read);

            iterator.Begin();

            //using band 0 in this example.  Be careful with your
            //own data as MRR is multifield, multiband
            IRandomBand rband = iterator[0];

            //get the distance between samples
            var dx    = (boundingBox.Max.Lon - boundingBox.Min.Lon) / 64;
            var dy    = (boundingBox.Max.Lat - boundingBox.Min.Lat) / 64;
            int accum = 0;
            //64 samples with one row of overlap with the next tile.
            //Hence 65 * (1/64) tile size
            bool hasData = false;

            for (int lat = 0; lat < 65; lat++)
            {
                for (int lon = 0; lon < 65; lon++)
                {
                    //read evenly across the whole tile
                    var    wX = boundingBox.Min.Lon + (lon * dx);
                    var    wY = boundingBox.Max.Lat - (lat * dy);
                    int    cX, cY;
                    double value = 0;
                    bool   valid = false;

                    var inside = !GetCellPosition(wX, wY, dataset, out cX, out cY);
                    if (inside)
                    {
                        rband.GetCellValue((long)cX, (long)cY, out value, out valid);
                    }
                    else
                    {
                        valid = false;
                    }

                    if (valid)
                    {
                        hasData = true;
                        var sValue = Convert.ToUInt16((value + 1000) * 5);
                        var conv   = BitConverter.GetBytes(sValue);
                        tile[accum]     = conv[0];
                        tile[accum + 1] = conv[1];
                    }
                    //otherwise, sea level
                    else
                    {
                        var conv = BitConverter.GetBytes(5000);
                        tile[accum]     = conv[0];
                        tile[accum + 1] = conv[1];
                    }
                    accum += 2;
                }
            }
            //don't forget to close the iterator
            iterator.End();

            return(hasData);
        }
Ejemplo n.º 4
0
        public override bool CreateTile(int tx, int ty, int zoom, IRasterDataset dataset, byte[] tile)
        {
            int accum       = 0;
            var boundingBox = PointToTile.TileBounds(zoom, tx, ty);
            var seaLevel    = BitConverter.GetBytes(5000);
            var iterator    = dataset.GetBlockIterator(0, IteratorMode.Read);

            iterator.Begin();

            //get the distance between samples
            var dx = (boundingBox.Max.Lon - boundingBox.Min.Lon) / 64;
            var dy = (boundingBox.Max.Lat - boundingBox.Min.Lat) / 64;

            var cellSize   = dataset.Info.FieldInfo[0].CellSizeX.Decimal;
            var rat        = dx / cellSize;
            int resolution = 0;

            //when sample size is less than cell size use an underview
            while (rat < 1.0)
            {
                resolution--;
                cellSize = cellSize / 2.0;
                rat      = rat * 2.0;
            }
            //when sample size is greater than cell size use an overview
            while (rat > 2.0)
            {
                resolution++;
                cellSize = cellSize * 2.0;
                rat      = rat / 2.0;
            }
            //We've added an optional resolution parameter to our cell position calculation
            int westmost, southmost;

            GetCellPosition(boundingBox.Min.Lon, boundingBox.Min.Lat, dataset, out westmost, out southmost, resolution);


            //64 samples with one row of overlap with the next tile.
            //Hence desired width is 65 tile samples, converted into cell units
            var    width             = (int)Math.Ceiling((dx * 65) / cellSize);
            double cellToSampleRatio = width / 65.0;

            double[] actualData  = null;
            bool[]   actualValid = null;

            try
            {
                GetGridBlock(westmost, southmost, width, width, resolution, dataset, out actualData, out actualValid);
            }
            catch
            {
                Console.WriteLine();
            }


            bool hasData = false;

            //cesium expects the northwest position first, but the raster block
            //gives the southwest as the first element so remember to transform
            for (int lat = 64; lat >= 0; lat--)
            {
                //     var Y = dy * lat;
                var Y = (int)((cellToSampleRatio * lat) + 0.5);
                for (int lon = 0; lon < 65; lon++)
                {
                    //transform lat and lon into block units

                    var X = (int)((cellToSampleRatio * lon) + 0.5);
                    // var X = (int)((dx * lon)+0.5);
                    var place = (width * Y) + X;

                    bool isValid = actualValid[place];

                    if (isValid)
                    {
                        var value = actualData[place];
                        hasData = true;
                        var sValue = Convert.ToUInt16((value + 1000) * 5);
                        var conv   = BitConverter.GetBytes(sValue);
                        tile[accum]     = conv[0];
                        tile[accum + 1] = conv[1];
                    }
                    else
                    {
                        tile[accum]     = seaLevel[0];
                        tile[accum + 1] = seaLevel[1];
                    }
                    accum += 2;
                }
            }
            iterator.End();
            return(hasData);
        }
Ejemplo n.º 5
0
        public void CreateAllTiles(IRasterDataset dataset, int maxZoom, IOutput output, System.IProgress <int> progress = null)
        {
            double     xMin, yMin, xMax, yMax;
            var        bytes = 65 * 65 * 2;
            byte       zero  = 0;
            int        count = 0;
            RasterInfo r     = dataset.Info;

            xMin = r.FieldInfo[0].Envelope.XMin;
            xMax = r.FieldInfo[0].Envelope.XMax;
            yMin = r.FieldInfo[0].Envelope.YMin;
            yMax = r.FieldInfo[0].Envelope.YMax;


            Dictionary <string, string> existingTiles = new Dictionary <string, string>();

            for (int zoom = maxZoom; zoom >= 0; zoom--)
            {
                //only generate tiles within the extents of the data
                var southWestTile = PointToTile.LatLonToTile(zoom, yMin, xMin);
                var northEastTile = PointToTile.LatLonToTile(zoom, yMax, xMax);
                var dx            = northEastTile.X - southWestTile.X;
                var dy            = northEastTile.Y - southWestTile.Y;

                var boundingBox  = PointToTile.TileBounds(zoom, northEastTile.X, northEastTile.Y);
                var tileSample   = (boundingBox.Max.Lon - boundingBox.Min.Lon) / 64;
                var sourceSample = dataset.Info.FieldInfo[0].CellSizeX.Decimal;


                ThreadLocal <byte[]> terrainTileLocal = new ThreadLocal <byte[]>(() => new byte[(bytes + 2)]);
                Console.WriteLine($"{(dx+1)*dy}");
                Parallel.For(0, dx + 1, (easterlyOffset) =>
                {
                    Parallel.For(0, dy + 1, (northerlyOffset) =>
                    {
                        int tX               = southWestTile.X + easterlyOffset;
                        int tY               = southWestTile.Y + northerlyOffset;
                        var terrainTile      = terrainTileLocal.Value;
                        byte childQuadSwitch = zero;
                        if (zoom != maxZoom)
                        {
                            childQuadSwitch = GetChildQuads(zoom, tX, tY, existingTiles);
                        }
                        //always create tiles with child tiles
                        bool create = childQuadSwitch > 0 || (zoom == maxZoom);
                        if (create)
                        {
                            bool created = false;

                            created = CreateTile(tX, tY, zoom, dataset, terrainTile);


                            if (zoom == maxZoom)
                            {
                                create = created;
                            }
                        }


                        if (create)
                        {
                            terrainTile[bytes]     = childQuadSwitch;
                            terrainTile[bytes + 1] = 0;   //We'll say it's all land for now

                            output.WriteTile(zoom, tX, tY, terrainTile);
                            existingTiles.Add($"{zoom}/{tX}/{tY}", "");
                        }
                        progress?.Report(++count);
                    });
                });
            }
        }