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(); }
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); }
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); } }
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); }
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); } }
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(); }
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); } }
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); }
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; } }
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); }
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)); }
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); }
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()); } } } }
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); }
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); } }
public void LoadBySync(int bandNo, LevelId level) { _diskCacheManager.LoadSync(bandNo, level); }