예제 #1
0
 public void UpdateRasterEnvelope(float rasterScale, int beginX, int beginY, int xSize, int ySize)
 {
     _rasterEnvelopeOfWnd.Location = new Point(beginX, beginY);
     _rasterEnvelopeOfWnd.Width    = xSize;
     _rasterEnvelopeOfWnd.Height   = ySize;
     //
     if (_wndExtandMultiple > 1)
     {
         float scale          = _rasterEnvelopeOfWnd.Width / _wndWidth;
         float extandWidth    = (_wndExtandMultiple * _wndWidth - _wndWidth) / 2f;
         float extandHeight   = (_wndExtandMultiple * _wndHeight - _wndHeight) / 2f;
         int   extandHalfCols = (int)(extandWidth * scale);
         int   extandHalfRows = (int)(extandHeight * scale);
         _rasterEnvelopeOfVirtualWnd.Location = new Point(beginX - extandHalfCols, beginY - extandHalfRows);
         _rasterEnvelopeOfVirtualWnd.Width    = _rasterEnvelopeOfWnd.Width + 2 * extandHalfCols;
         _rasterEnvelopeOfVirtualWnd.Height   = _rasterEnvelopeOfWnd.Height + 2 * extandHalfRows;
     }
     else//virtual window size = actual window size
     {
         _rasterEnvelopeOfVirtualWnd = _rasterEnvelopeOfWnd;
     }
     //计算当前显示级别
     _currentLevel = _tileComputer.GetNearestLevel(rasterScale);
     //
     UpdateCachedTiles();
 }
예제 #2
0
        private LevelId[] ComputerLevels()
        {
            int            levelNo = 0;
            int            w = _width, h = _height;
            List <LevelId> levels = new List <LevelId>();

            while (w > _tileSize || h > _tileSize)
            {
                LevelId lv = new LevelId();
                lv.No        = levelNo++;
                lv.Width     = w;
                lv.Height    = h;
                lv.Scale     = Math.Max(w / (float)_width, h / (float)_height);
                lv.TileCount = GetTileCount(ref lv, out lv.Tiles);
                w           /= 2;
                h           /= 2;
                levels.Add(lv);
            }
            if (w <= _tileSize && h <= _tileSize)
            {
                LevelId lv = new LevelId();
                lv.No        = levelNo++;
                lv.Width     = w;
                lv.Height    = h;
                lv.Scale     = Math.Max(w / (float)_width, h / (float)_height);
                lv.TileCount = GetTileCount(ref lv, out lv.Tiles);
                levels.Add(lv);
            }
            return(levels.Count > 0 ? levels.ToArray() : null);
        }
예제 #3
0
        public void LoadBySync_MaxLevel()
        {
            LevelId lv = _tileComputer.Levels[_tileComputer.Levels.Length - 1];

            LoadBySync(lv.No);
            for (int b = 0; b < _dataProvider.BandCount; b++)
            {
                if (Array.IndexOf <int>(_bands, b + 1) >= 0)
                {
                    continue;
                }
                _diskCacheManager.Enqueue(b + 1, lv);
            }
        }
예제 #4
0
        public void Enqueue(int bandNo, LevelId level)
        {
            string key = _cacheNameHelper.GetResourceKey(bandNo, level.No);

            if (_readFileStreams.ContainsKey(key))
            {
                return;
            }
            BandLevelTask task = new BandLevelTask();

            task.BandNo = bandNo;
            task.Level  = level;
            _bandLevelQueue.Enqueue(task);
        }
예제 #5
0
 public void LoadSync(int bandNo, LevelId level)
 {
     if (level.TileCount == 0 || level.Tiles == null || level.Tiles.Length == 0)
     {
         return;
     }
     for (int i = 0; i < level.Tiles.Length; i++)
     {
         TileTask task = new TileTask();
         task.Tile   = level.Tiles[i];
         task.BandNo = bandNo;
         task.Key    = GetTileTaskKey(bandNo, level.Tiles[i]);
         DoTileTask(task);
     }
 }
예제 #6
0
        private void BuildOneTile(TileData redData, TileData greenData, TileData blueData, int x, int y, Rectangle rasterWindowEnvelope, Graphics g)
        {
            LevelId lv      = _tileComputer.Levels[redData.Tile.LevelNo];
            int     w       = redData.Tile.Width;
            int     h       = redData.Tile.Height;
            Bitmap  tBitmap = new Bitmap(w, h, PixelFormat.Format24bppRgb);

            using (IBitmapBuilder <byte> builder = BitmapBuilderFactory.CreateBitmapBuilderByte())
            {
                builder.Build(w, h, redData.Data as byte[],
                              greenData.Data as byte[],
                              blueData.Data as byte[], ref tBitmap);
            }
            g.DrawImage(tBitmap, x, y);
            tBitmap.Dispose();
        }
예제 #7
0
        private void BuildOneTile(TileData[] datas, Rectangle rasterWindowEnvelope, Graphics g, int bRow, int bCol)
        {
            LevelId lv       = _tileComputer.Levels[datas[0].Tile.LevelNo];
            int     tileSize = _tileComputer.TileSize;
            int     y        = (int)(tileSize * (datas[0].Tile.Row - bRow));
            int     x        = (int)(tileSize * (datas[0].Tile.Col - bCol));

            if (datas.Length == 1)
            {
                BuildOneTile(datas[0], x, y, rasterWindowEnvelope, g);
            }
            else if (datas.Length == 3)
            {
                BuildOneTile(datas[0], datas[1], datas[2], x, y, rasterWindowEnvelope, g);
            }
        }
예제 #8
0
        public LevelId GetNearestLevel(float scale)
        {
            float   dlt;
            float   mindlt = float.MaxValue;
            LevelId lv     = new LevelId();

            for (int i = 0; i < _levels.Length; i++)
            {
                dlt = Math.Abs(_levels[i].Scale - scale);
                if (dlt < mindlt)
                {
                    mindlt = dlt;
                    lv     = _levels[i];
                }
            }
            return(lv);
        }
예제 #9
0
        private unsafe void DoBandLevelTask(BandLevelTask bandLevelTask)
        {
            _isDoingLargerTask = true;
            try
            {
                string fname = _cacheNameHelper.GetCacheFilename(_cacheFolder, bandLevelTask.BandNo, bandLevelTask.Level.No);
                using (FileStream fs = new FileStream(fname, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs))
                    {
                        IRasterBand band   = _dataProvider.GetRasterBand(bandLevelTask.BandNo);
                        int         tCount = bandLevelTask.Level.Tiles.Length;
                        TileId[]    tiles  = bandLevelTask.Level.Tiles;
                        TileId      tile;
                        LevelId     lv   = bandLevelTask.Level;
                        byte[]      data = new byte[_tileBufferSize];
                        fixed(byte *ptr = data)
                        {
                            IntPtr buffer = new IntPtr(ptr);

                            for (int i = 0; i < tCount; i++)
                            {
                                tile = tiles[i];
                                band.Read(
                                    (int)(_tileSize * tile.Col / lv.Scale),
                                    (int)(_tileSize * tile.Row / lv.Scale),
                                    (int)(tile.Width / lv.Scale),
                                    (int)(tile.Height / lv.Scale),
                                    buffer, _dataProvider.DataType, tile.Width, tile.Height);
                                bw.Write(data);
                                //
                                if (_needPauseLargerTask)
                                {
                                    Console.WriteLine("需要暂停长任务。");
                                    _needPauseLargerTask = false;
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                _isDoingLargerTask = false;
            }
        }
예제 #10
0
        public TileData[] GetTiles(int levelNo, Rectangle rasterEnvelope)
        {
            if (levelNo > _tileComputer.Levels.Length - 1)
            {
                return(null);
            }
            TileId[] visibleTiles = GetVisibileTiles(levelNo, rasterEnvelope);
            //如果本级没有缓存,则向上找分辨率较粗的一级代替
            if (!_cache.ContainsKey(levelNo))
            {
                //通知异步读取线程优先读取
                for (int i = 0; i < visibleTiles.Length; i++)
                {
                    TileId tile = visibleTiles[i];
                    _requestAgent.DoRequest(_bandNo, tile);
                }
                //找分辨率较粗的一级代替
                GetTiles(levelNo++, rasterEnvelope);
            }
            LevelId lv = _tileComputer.Levels[levelNo];
            Dictionary <int, TileData> lvTiles  = _cache[levelNo];
            List <TileData>            retTiles = new List <TileData>();
            int idx = 0;

            for (int i = 0; i < visibleTiles.Length; i++)
            {
                TileId tile = visibleTiles[i];
                if (lvTiles.ContainsKey(tile.Index))
                {
                    retTiles.Add(lvTiles[tile.Index]);
                }
                else//如果该块不在内存,则通知异步获取,向上查找较粗分辨率的一层代替
                {
                    TileData data = ToUpperLevel(lv.No, tile.Row, tile.Col);
                    if (data != null)
                    {
                        retTiles.Add(data);
                    }
                    _requestAgent.DoRequest(_bandNo, _tileComputer.Levels[lv.No].Tiles[idx]);
                }
            }
            return(retTiles.Count > 0 ? retTiles.ToArray() : null);
        }
예제 #11
0
        public Rectangle GetCacheWindow(int levelNo)
        {
            LevelId   lv      = _tileComputer.Levels[levelNo];
            int       rasterX = (int)(_rasterEnvelopeOfVirtualWnd.Left * lv.Scale);
            int       rasterY = (int)(_rasterEnvelopeOfVirtualWnd.Top * lv.Scale);
            int       width   = (int)(_rasterEnvelopeOfVirtualWnd.Width * lv.Scale);
            int       height  = (int)(_rasterEnvelopeOfVirtualWnd.Height * lv.Scale);
            Rectangle lvRect  = new Rectangle(0, 0, lv.Width, lv.Height);

            lvRect.Intersect(new Rectangle(rasterX, rasterY, width, height));
            if (lvRect.IsEmpty)
            {
                return(Rectangle.Empty);
            }
            int tileSize      = _tileComputer.TileSize;
            int bCol          = lvRect.Left / tileSize;
            int bRow          = lvRect.Top / tileSize;
            int tilesByHeight = (int)Math.Ceiling(lvRect.Height / (float)tileSize);
            int tilesByWidth  = (int)Math.Ceiling(lvRect.Width / (float)tileSize);

            return(new Rectangle(bCol, bRow, bCol + tilesByWidth, bRow + tilesByHeight));
        }
예제 #12
0
        private int GetTileCount(ref LevelId lv, out TileId[] tiles)
        {
            int rows = (int)Math.Ceiling(lv.Height / (float)_tileSize);
            int cols = (int)Math.Ceiling(lv.Width / (float)_tileSize);

            tiles   = new TileId[rows * cols];
            lv.Rows = rows;
            lv.Cols = cols;
            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < cols; c++)
                {
                    TileId tile = new TileId();
                    tile.LevelNo = lv.No;
                    if (c == cols - 1)
                    {
                        tile.Width = Math.Min(_tileSize, lv.Width - (cols - 1) * _tileSize);
                    }
                    else
                    {
                        tile.Width = _tileSize;
                    }
                    if (r == rows - 1)
                    {
                        tile.Height = Math.Min(_tileSize, lv.Height - (rows - 1) * _tileSize);
                    }
                    else
                    {
                        tile.Height = _tileSize;
                    }
                    tile.Row          = r;
                    tile.Col          = c;
                    tile.Index        = r * cols + c;
                    tiles[tile.Index] = tile;
                }
            }
            return(rows * cols);
        }
예제 #13
0
        public void Update(int levelNo, Rectangle rasterEnvelopeOfWnd, Rectangle rasterEnvelopeOfVirtualWnd)
        {
            LevelId lv = _tileComputer.Levels[levelNo];

            TileId[] visibleTiles = GetVisibileTiles(levelNo, rasterEnvelopeOfVirtualWnd);
            //通知异步读取线程优先读取(这里还可以优化)
            Console.WriteLine("---------------- bandNo " + _bandNo.ToString() + "--------------------");
            if (visibleTiles != null)
            {
                for (int i = 0; i < visibleTiles.Length; i++)
                {
                    TileId tile = visibleTiles[i];
                    if (!TileIsEixst(tile))
                    {
                        _requestAgent.DoRequest(_bandNo, tile);
                        Console.WriteLine("Request: " + tile.ToString());
                    }
                    else
                    {
                        Console.WriteLine("In Memeory: " + tile.ToString());
                    }
                }
            }
        }
예제 #14
0
        private TileId[] GetVisibileTiles(int levelNo, Rectangle viewport)
        {
            LevelId lv = _tileComputer.Levels[levelNo];
            //当视窗大小转换为本级分辨率下
            float scale  = lv.Scale;
            int   bCol   = (int)(viewport.Left * scale);
            int   bRow   = (int)(viewport.Top * scale);
            int   width  = (int)(viewport.Width * scale);
            int   height = (int)(viewport.Height * scale);
            //计算本级和视窗的交集
            Rectangle lvRect = new Rectangle(0, 0, lv.Width, lv.Height);

            lvRect.Intersect(new Rectangle(bCol, bRow, width, height));
            if (lvRect.IsEmpty)
            {
                return(null);
            }
            List <TileId> retTiles = new List <TileId>();
            int           tileSize = _tileComputer.TileSize;

            bCol = lvRect.Left / tileSize;
            bRow = lvRect.Top / tileSize;
            int tilesByHeight = (int)Math.Ceiling(lvRect.Height / (float)tileSize);
            int tilesByWidth  = (int)Math.Ceiling(lvRect.Width / (float)tileSize);
            int idx           = 0;

            for (int r = bRow; r < bRow + tilesByHeight; r++)
            {
                idx = r * lv.Cols + bCol;
                for (int c = bCol; c < bCol + tilesByWidth; c++, idx++)
                {
                    retTiles.Add(lv.Tiles[idx]);
                }
            }
            return(retTiles.Count > 0 ? retTiles.ToArray() : null);
        }
예제 #15
0
        private unsafe void DirectTileFromDataProvider(TileTask tileTask)
        {
            byte[] data = new byte[_tileBufferSize];
            fixed(byte *ptr = data)
            {
                IntPtr  buffer = new IntPtr(ptr);
                TileId  tile   = tileTask.Tile;
                LevelId lv     = _tileComputer.Levels[tile.LevelNo];

                _dataProvider.GetRasterBand(tileTask.BandNo).Read(
                    (int)(_tileSize * tile.Col / lv.Scale),
                    (int)(_tileSize * tile.Row / lv.Scale),
                    (int)(tile.Width / lv.Scale),
                    (int)(tile.Height / lv.Scale),
                    buffer, _dataProvider.DataType, tile.Width, tile.Height);
                //
                TileData tileData = new TileData();

                tileData.BandNo = tileTask.BandNo;
                tileData.Tile   = tile;
                tileData.Data   = data;
                _tileReadedCallback(tileData);
            }
        }
예제 #16
0
 public void LoadBySync(int bandNo, LevelId level)
 {
     _diskCacheManager.LoadSync(bandNo, level);
 }