protected override void InternalOnTileLoaded(object o, TileLoadEventArgs a) { if (a.GeneratedMethod != TileGeneratedSource.DynamicOutput) { return; } if (o is DataSourceRasterImage && !ConfigManager.App_AllowFileCacheOfRasterImage || IsOnlineMap && !ConfigManager.App_AllowFileCacheOfOnlineMaps) { return; } string key = string.Format("{0}/{1}/{2}", a.Level, a.Column, a.Row); if (base._dictTilesToBeLocalCached.ContainsKey(key)) { return; } _dictTilesToBeLocalCached.TryAdd(key, a.TileBytes); if (_dictTilesToBeLocalCached.Count >= 1000) { WriteTilesToLocalCacheFile(_dictTilesToBeLocalCached); _dictTilesToBeLocalCached.Clear(); } }
public override byte[] GetTileBytes(int level, int row, int col) { string baseUrl = _baseUrl; //for bing maps, using quadkey if (_mapName.ToLower().Contains("bing")) { baseUrl = baseUrl.Replace("{$q}", Utility.TileXYToQuadKey(col, row, level)); } string subdomain = string.Empty; string uri = string.Empty; subdomain = _subDomains[(level + col + row) % _subDomains.Length]; byte[] bytes; try { uri = string.Format(baseUrl, subdomain, level, col, row); if (!ConvertingStatus.IsInProgress)//accessing from PBSServiceProvider by PBS service client { bytes = HttpGetTileBytes(uri); return(bytes); } else //accessing from DataSource directly when do format converting //Because when convert to MBTiles, bytes are retriving from datasource directly other than from PBSService, so TileLoaded event and local file cache checking in PBSServiceProvider.cs will not fire. Need to check if local file cache exist first, if not, fire TileLoaded event to let internal function to save tile to local file cache. { TileLoadEventArgs tileLEA = new TileLoadEventArgs() { Level = level, Row = row, Column = col }; //check if tile exist in local file cache bytes = GetTileBytesFromLocalCache(level, row, col); if (bytes != null) { tileLEA.GeneratedMethod = TileGeneratedSource.FromFileCache; } else { bytes = HttpGetTileBytes(uri); tileLEA.GeneratedMethod = TileGeneratedSource.DynamicOutput; } tileLEA.TileBytes = bytes; if (TileLoaded != null) { TileLoaded(this, tileLEA); } } return(bytes); } catch (Exception e) { //when this datasource is using for converting online tiles to offline format, return null if there is something wrong with downloading, otherwise, return a error image for PBS service to display. if (ConvertingStatus.IsInProgress) { return(null); } //if server has response(not a downloading error) and tell pbs do not have the specific tile, return null if (e is WebException && (e as WebException).Response != null && ((e as WebException).Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound) { return(null); } string suffix = this.TilingScheme.CacheTileFormat.ToString().ToUpper().Contains("PNG") ? "png" : "jpg"; Stream stream = this.GetType().Assembly.GetManifestResourceStream("PBS.Assets.badrequest" + this.TilingScheme.TileCols + "." + suffix); bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); return(bytes); } }
void pbsLayer_TileLoaded(object sender, TileLoadEventArgs e) { Dispatcher.BeginInvoke(new Action(() => { string key = e.Level + "/" + e.Row + "/" + e.Column; //avoid to draw a grid duplicately if (_dictDrawedGrids.ContainsKey(key)) { TileWatermark tw = null; if (_dictDrawedGrids.TryGetValue(key, out tw)) { _gLayer.Graphics.Remove(tw.GraphicBoundingBox); _gLayer.Graphics.Remove(tw.GraphicTextLabel); _dictDrawedGrids.TryRemove(key, out tw); } } double xmin, ymin, xmax, ymax; CalculateTileBBox(e.Level, e.Row, e.Column, out xmin, out ymin, out xmax, out ymax); //polygon as bounding box Polygon boundingLine = new Polygon(); ESRI.ArcGIS.Client.Geometry.PointCollection pc = new ESRI.ArcGIS.Client.Geometry.PointCollection(); pc.Add(new MapPoint(xmin, ymax, map1.SpatialReference)); pc.Add(new MapPoint(xmax, ymax, map1.SpatialReference)); pc.Add(new MapPoint(xmax, ymin, map1.SpatialReference)); pc.Add(new MapPoint(xmin, ymin, map1.SpatialReference)); pc.Add(new MapPoint(xmin, ymax, map1.SpatialReference)); boundingLine.Rings.Add(pc); SimpleFillSymbol sfs = new SimpleFillSymbol() { //BorderThickness = 2.0, BorderBrush = new SolidColorBrush(Color.FromArgb(200, 255, 255, 255)), }; //dynamic-red, filecache-yellow, memcached-green if (e.GeneratedMethod == TileGeneratedSource.DynamicOutput) { sfs.Fill = new SolidColorBrush(Color.FromArgb(80, 200, 0, 0)); } else if (e.GeneratedMethod == TileGeneratedSource.FromFileCache) { sfs.Fill = new SolidColorBrush(Color.FromArgb(80, 200, 200, 0)); } else if (e.GeneratedMethod == TileGeneratedSource.FromMemcached) { sfs.Fill = new SolidColorBrush(Color.FromArgb(80, 0, 200, 0)); } Graphic gBoundingBox = new Graphic() { Geometry = boundingLine, Symbol = sfs, }; _gLayer.Graphics.Add(gBoundingBox); //textsymol MapPoint center = new MapPoint((xmin + xmax) / 2, (ymin + ymax) / 2, map1.SpatialReference); TextSymbol tSymbol = new TextSymbol() { FontSize = 16, Text = "Level/Row/Column\r\n" + e.Level + "/" + e.Row + "/" + e.Column, Foreground = new SolidColorBrush(Colors.White), }; if (_service.DataSource.Type == DataSourceTypePredefined.MBTiles.ToString()) { tSymbol.Text = _service.DataSource.generateSymbolText(e.Level, e.Row, e.Column); } //where the tile comes from string generatedSource = FindResource("tbDynamic").ToString(); //if tile comes from memcached if (e.GeneratedMethod == TileGeneratedSource.FromMemcached) { generatedSource = FindResource("tbMemCached").ToString(); } //if tile comes from file cache else if (e.GeneratedMethod == TileGeneratedSource.FromFileCache) { generatedSource = FindResource("tbFileCache").ToString(); } //if tile bytes count string bytesCount = e.TileBytes == null ? "null" : Math.Round(e.TileBytes.Length / 1024.0, 3).ToString() + "KB"; tSymbol.Text += "\r\noutput from: " + generatedSource + "\r\nsize: " + bytesCount; tSymbol.OffsetY = 16; tSymbol.OffsetX = MeasureTextWidth(tSymbol.Text, 16, "Verdana").Width / 2; Graphic gText = new Graphic() { Geometry = center, Symbol = tSymbol }; _gLayer.Graphics.Add(gText); _dictDrawedGrids.TryAdd(key, new TileWatermark() { GraphicBoundingBox = gBoundingBox, GraphicTextLabel = gText }); })); }
public override byte[] GetTileBytes(int level, int row, int col) { string baseUrl = _baseUrl; string subdomain = string.Empty; string uri = string.Empty; subdomain = _subDomains[Math.Abs(level + col + row) % _subDomains.Length]; byte[] bytes; try { if ("BaiduBase" == _mapName) { uri = string.Format(baseUrl, level, col, row, subdomain); } else if ("BaiduSate" == _mapName) { uri = string.Format(baseUrl, level, col, row, Version, subdomain); } else if ("BaiduPanoMark" == _mapName) { uri = string.Format(baseUrl, Version, col, row, level); } TileLoadEventArgs tileLEA = new TileLoadEventArgs() { Level = level, Row = row, Column = col }; //check if tile exist in local file cache bytes = GetTileBytesFromLocalCache(level, row, col); if (bytes != null) { tileLEA.GeneratedMethod = TileGeneratedSource.FromFileCache; } else { bytes = HttpGetTileBytes(uri); tileLEA.GeneratedMethod = TileGeneratedSource.DynamicOutput; } tileLEA.TileBytes = bytes; if (TileLoaded != null) { TileLoaded(this, tileLEA); } return(bytes); } catch (Exception e) { //when this datasource is using for converting online tiles to offline format, return null if there is something wrong with downloading, otherwise, return a error image for PBS service to display. if (ConvertingStatus.IsInProgress) { recordFailure(uri, e.Message); return(null); } //if server has response(not a downloading error) and tell pbs do not have the specific tile, return null if (e is WebException && (e as WebException).Response != null && ((e as WebException).Response as HttpWebResponse).StatusCode == HttpStatusCode.NotFound) { return(null); } string suffix = this.TilingScheme.CacheTileFormat.ToString().ToUpper().Contains("PNG") ? "png" : "jpg"; Stream stream = this.GetType().Assembly.GetManifestResourceStream("PBS.Assets.badrequest" + this.TilingScheme.TileCols + "." + suffix); bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); return(bytes); } }