public int GetPriority(TileId tileId)
        {
            var point4D1 = vTL0 + (tileId.X - VisibleTileId.X) * vR + (tileId.Y - VisibleTileId.Y) * vD;
            var point4D2 = vTL0 + (tileId.X + 1L - VisibleTileId.X) * vR + (tileId.Y - VisibleTileId.Y) * vD;
            var point4D3 = vTL0 + (tileId.X + 1L - VisibleTileId.X) * vR + (tileId.Y + 1L - VisibleTileId.Y) * vD;
            var point4D4 = vTL0 + (tileId.X - VisibleTileId.X) * vR + (tileId.Y + 1L - VisibleTileId.Y) * vD;
            var num      = double.MaxValue;

            if (point4D1.W > 0.0)
            {
                num = Math.Min(num, Point2D.DistanceSquared(new Point2D(point4D1.X / point4D1.W, point4D1.Y / point4D1.W), viewportCenter));
            }
            if (point4D2.W > 0.0)
            {
                num = Math.Min(num, Point2D.DistanceSquared(new Point2D(point4D2.X / point4D2.W, point4D2.Y / point4D2.W), viewportCenter));
            }
            if (point4D3.W > 0.0)
            {
                num = Math.Min(num, Point2D.DistanceSquared(new Point2D(point4D3.X / point4D3.W, point4D3.Y / point4D3.W), viewportCenter));
            }
            if (point4D4.W > 0.0)
            {
                num = Math.Min(num, Point2D.DistanceSquared(new Point2D(point4D4.X / point4D4.W, point4D4.Y / point4D4.W), viewportCenter));
            }
            return(4 - VectorMath.Clamp((int)Math.Floor(Math.Sqrt(num) / bucketRadiusInterval), 0, 4));
        }
예제 #2
0
        public override void GetTile(TileId tileId, out TileRenderable tileRenderable, out bool tileWillNeverBeAvailable)
        {
            if (!relevantTileSet.Contains(tileId))
            {
                throw new InvalidOperationException("Cannot get a tile that is not currently set as relevant.");
            }
            tileRenderable           = null;
            tileWillNeverBeAvailable = false;
            var rasterTileCacheValue = rasterTileImageCache.GetValue(tileId);

            if (rasterTileCacheValue is null)
            {
                return;
            }
            if (rasterTileCacheValue.Image is null)
            {
                tileWillNeverBeAvailable = true;
            }
            else
            {
                if (tileRenderables.TryGetValue(tileId, out tileRenderable))
                {
                    return;
                }
                var newToCache = DateTime.UtcNow.Subtract(rasterTileCacheValue.TimeAdded).TotalMilliseconds < 500.0;
                tileRenderable = CreateTileRenderable(tileId, rasterTileCacheValue.Image, rasterTileCacheValue.TileSubregion, newToCache);
                tileRenderables.Add(tileId, tileRenderable);
            }
        }
 public override void UpdateTileDownloadPriority(TileId tileId, int priority)
 {
     if (!tileRequests.TryGetValue(tileId, out var tileRequest))
     {
         throw new InvalidOperationException("Tile download must be in progress to update its priority.");
     }
     tileRequest.WebRequest.NetworkPriority = (NetworkPriority)priority;
 }
 public override void CancelTileDownload(TileId tileId)
 {
     if (!tileRequests.TryGetValue(tileId, out var tileRequest))
     {
         throw new InvalidOperationException("Tile download must be in progress to be cancelled.");
     }
     tileRequest.Cancelled = true;
     tileRequest.WebRequest.AbortIfInQueue();
     tileRequests.Remove(tileId);
 }
예제 #5
0
 public TileRecord(
     Canvas layerCanvas,
     TilePyramidDescriptor tilePyramidDescriptor,
     TileId tileId)
 {
     tilePyramidCanvas          = layerCanvas;
     this.tilePyramidDescriptor = tilePyramidDescriptor;
     this.tileId          = tileId;
     visible              = false;
     WillNeverBeAvailable = false;
 }
        public RasterTileCacheValue GetValue(TileId tileId)
        {
            var tileId1 = transformTileId(tileId);

            if (useGlobalMemoryCache)
            {
                return(MemoryCache.Instance.GetValue <RasterTileCacheValue>(new RasterTileCacheKey(rasterTileCacheId, tileId1)));
            }
            var rasterTileCacheValue = (RasterTileCacheValue)null;

            rasterTileCacheValues.TryGetValue(tileId1, out rasterTileCacheValue);
            return(rasterTileCacheValue);
        }
예제 #7
0
        private TileRenderable CreateTileRenderable(TileId tileId, BitmapSource bitmapSource, Rect tileSubregion, bool newToCache)
        {
            FrameworkElement element;

            if (tileSubregion.X == 1.0 && tileSubregion.Y == 1.0 && (tileSubregion.Width == bitmapSource.PixelWidth - 2 && tileSubregion.Height == bitmapSource.PixelHeight - 2))
            {
                var image1 = imagePool.Get(new Size(bitmapSource.PixelWidth, bitmapSource.PixelHeight));
                if (image1 is null)
                {
                    var image2 = new Image
                    {
                        Width  = bitmapSource.PixelWidth,
                        Height = bitmapSource.PixelHeight
                    };
                    image1 = image2;
                }
                image1.Source           = bitmapSource;
                image1.Stretch          = Stretch.None;
                image1.IsHitTestVisible = false;
                element = image1;
            }
            else
            {
                var rectangle1  = new Rectangle();
                var rectangle2  = rectangle1;
                var imageBrush1 = new ImageBrush
                {
                    ImageSource = bitmapSource,
                    AlignmentX  = AlignmentX.Left,
                    AlignmentY  = AlignmentY.Top,
                    Stretch     = Stretch.None,
                    Transform   = new TranslateTransform()
                    {
                        X = (-tileSubregion.X + 1.0),
                        Y = (-tileSubregion.Y + 1.0)
                    }
                };
                var imageBrush2 = imageBrush1;
                rectangle2.Fill             = imageBrush2;
                rectangle1.IsHitTestVisible = false;
                rectangle1.Width            = tileSubregion.Width + 2.0;
                rectangle1.Height           = tileSubregion.Height + 2.0;
                element = rectangle1;
            }
            var flag = tileId.LevelOfDetail > MinimumLevelOfDetail + 1;

            return(new TileRenderable(tileId, element, flag ? TileFadeInDuration : new TimeSpan?()));
        }
        private bool IsChildIrrelevantOrOccluder(TileId tileId, int childIdx)
        {
            var tileId1 = new TileId(tileId.LevelOfDetail + 1, (tileId.X << 1) + childIdx % 2, (tileId.Y << 1) + childIdx / 2);

            GetTileBoundsAtLod(tileId1.LevelOfDetail, out var lodX0, out var lodY0, out var lodX1, out var lodY1);
            if (tileId1.X < lodX0 || tileId1.X >= lodX1 || (tileId1.Y < lodY0 || tileId1.Y >= lodY1))
            {
                return(true);
            }
            var occluderFlag = GetOccluderFlag(tileId1);

            if (occluderFlag.HasValue)
            {
                return(occluderFlag.Value);
            }
            return(true);
        }
        public override void DownloadTile(
            TileId tileId,
            TileEdgeFlags tileEdgeFlags,
            object token,
            RasterTileAvailableDelegate tileAvailableDelegate,
            int priority)
        {
            var uri = tileUriDelegate(tileId);

            if (uri is object)
            {
                if (tileRequests.TryGetValue(tileId, out var tileRequest1))
                {
                    throw new InvalidOperationException("Multiple concurrent downloads of the same tile is not supported.");
                }
                TileRequest tileRequest2;
                tileRequests[tileId] = tileRequest2 = new TileRequest()
                {
                    TileId                = tileId,
                    Token                 = token,
                    TileEdgeFlags         = tileEdgeFlags,
                    TileAvailableDelegate = tileAvailableDelegate
                };
                tileRequest2.WebRequest = BitmapImageRequestQueue.Instance.CreateRequest(uri, (NetworkPriority)priority, tileRequest2, new BitmapImageRequestCompletedHandler(TileDownloadCompleted));
            }
            else if (tileSource.SuppliesImagesDirectly)
            {
                if (tileRequests.TryGetValue(tileId, out var tileRequest1))
                {
                    throw new InvalidOperationException("Multiple concurrent downloads of the same tile is not supported.");
                }
                TileRequest tileRequest2;
                tileRequests[tileId] = tileRequest2 = new TileRequest()
                {
                    TileId                = tileId,
                    Token                 = token,
                    TileEdgeFlags         = tileEdgeFlags,
                    TileAvailableDelegate = tileAvailableDelegate
                };
                tileRequest2.WebRequest = BitmapImageRequestQueue.Instance.CreateRequest(tileImageDelegate, (NetworkPriority)priority, tileRequest2, new BitmapImageRequestCompletedHandler(TileDownloadCompleted));
            }
            else
            {
                tileAvailableDelegate(null, new Rect(), null, token);
            }
        }
예제 #10
0
 public TileRenderable(TileId tileId, FrameworkElement element, TimeSpan?fadeInDuration)
 {
     if (element is null)
     {
         throw new ArgumentNullException(nameof(element));
     }
     if (element.Parent is object)
     {
         throw new ArgumentException("element.Parent not null");
     }
     TileId  = tileId;
     Element = element;
     Canvas.SetLeft(element, 0.0);
     Canvas.SetTop(element, 0.0);
     this.fadeInDuration = fadeInDuration;
     Opacity             = TargetOpacity = 0.0;
     configurationDirty  = true;
 }
        public void Initialize(
            TilePyramidDescriptor tilePyramid,
            ref Matrix3D renderableToViewportTransform,
            Point2D viewportSize,
            TileId visibleTileId)
        {
            VisibleTileId        = visibleTileId;
            viewportCenter       = 0.5 * viewportSize;
            bucketRadiusInterval = 0.5 * Math.Sqrt(viewportSize.X * viewportSize.X + viewportSize.Y * viewportSize.Y) / 5.0 - 1.0;
            lod = visibleTileId.LevelOfDetail;
            tileWidthAtFinestLod  = tilePyramid.TileWidth * (1 << tilePyramid.FinestLevelOfDetail - lod);
            tileHeightAtFinestLod = tilePyramid.TileHeight * (1 << tilePyramid.FinestLevelOfDetail - lod);
            vTL0 = VectorMath.Transform(renderableToViewportTransform, new Point4D(tileWidthAtFinestLod * visibleTileId.X, tileHeightAtFinestLod * visibleTileId.Y, 0.0, 1.0));
            var point4D1 = VectorMath.Transform(renderableToViewportTransform, new Point4D(tileWidthAtFinestLod * (visibleTileId.X + 1L), tileHeightAtFinestLod * visibleTileId.Y, 0.0, 1.0));
            var point4D2 = VectorMath.Transform(renderableToViewportTransform, new Point4D(tileWidthAtFinestLod * visibleTileId.X, tileHeightAtFinestLod * (visibleTileId.Y + 1L), 0.0, 1.0));

            vR = point4D1 - vTL0;
            vD = point4D2 - vTL0;
        }
 public void CalculateOcclusions()
 {
     for (var levelOfDetail = this.levelOfDetail; levelOfDetail >= minimumLevelOfDetail; --levelOfDetail)
     {
         if (levelOfDetail != this.levelOfDetail)
         {
             GetTileBoundsAtLod(levelOfDetail, out var lodX0, out var lodY0, out var lodX1, out var lodY1);
             for (var y = lodY0; y < lodY1; ++y)
             {
                 for (var x = lodX0; x < lodX1; ++x)
                 {
                     var tileId = new TileId(levelOfDetail, x, y);
                     if (GetOccluderFlag(tileId).HasValue&& (IsChildIrrelevantOrOccluder(tileId, 0) && IsChildIrrelevantOrOccluder(tileId, 1) && IsChildIrrelevantOrOccluder(tileId, 2) && IsChildIrrelevantOrOccluder(tileId, 3)))
                     {
                         SetOccludedFlag(tileId, true);
                         SetOccluderFlag(tileId, new bool?(true));
                     }
                 }
             }
         }
     }
 }
 private int GetIndexInLodArray(TileId tileId)
 {
     GetTileBoundsAtLod(tileId.LevelOfDetail, out var lodX0, out var lodY0, out var lodX1, out var lodY1);
     return((int)((tileId.Y - lodY0) * (lodX1 - lodX0) + (tileId.X - lodX0)));
 }
예제 #14
0
 public bool Contains(TileId tileId) => relevantTilesSet.Contains(tileId);
 public void MarkAsOccluder(TileId tileId, bool occluder) => SetOccluderFlag(tileId, new bool?(occluder));
 public bool IsOccludedByDescendents(TileId tileId) => GetOccludedFlag(tileId);
예제 #17
0
 public static Uri TileSourceGetUriWrapper(MapControl.WPF.TileSource tileSource, TileId tileId) => tileSource.GetUri((int)tileId.X, (int)tileId.Y, tileId.LevelOfDetail - 8);
예제 #18
0
 public abstract void GetTile(
     TileId tileId,
     out TileRenderable tileRenderable,
     out bool tileWillNeverBeAvailable);
 private void SetOccluderFlag(TileId tileId, bool?occluderFlag) => occluderFlags[tileId.LevelOfDetail][GetIndexInLodArray(tileId)] = occluderFlag;
 private bool GetOccludedFlag(TileId tileId) => occludedFlags[tileId.LevelOfDetail][GetIndexInLodArray(tileId)];