Beispiel #1
0
        /// <summary>
        /// Render the specified target, projection, layers, zoomFactor and coordinate.
        /// </summary>
        /// <param name="target">The target to render on.</param>
        /// <param name="projection">The projection being used to render.</param>
        /// <param name="layers">The layers to rendering in the given order.</param>
        /// <param name="view">The view to show.</param>
        /// <param name="viewRender">The view to determine what to render. It may be needed to render a bit more along the edges.</param>
        /// <param name="zoomFactor">The zoom factor relative to the projection.</param>
        public bool Render(TTarget target, IProjection projection, List <Layer> layers, View2D view, View2D viewRender, float zoomFactor)
        {
            // create and concatenate primitives from all layers.
            IEnumerable <Primitive2D> primitives = new List <Primitive2D>();

            // calculate zoom level.
            var zoomLevel = (float)projection.ToZoomLevel(zoomFactor);

            // draw all layers seperatly but in the correct order.
            var scenes = new List <Scene2D>();

            for (int layerIdx = 0; layerIdx < layers.Count; layerIdx++)
            {
                if (layers[layerIdx].IsLayerVisibleFor(zoomLevel))
                {
                    primitives = primitives.Concat(
                        layers[layerIdx].Get(zoomFactor, viewRender));
                }
            }

            // get the backcolor.
            int?backcolor = null;

            if (layers.Count > 0)
            { // use the backcolor of the first layer.
                backcolor = layers[0].BackColor;
            }

            // render the scenes.
            return(_renderer.Render(target, view, zoomFactor, primitives, backcolor));
        }
Beispiel #2
0
        /// <summary>
        /// Returns all primitives from this layer visible for the given parameters.
        /// </summary>
        /// <param name="zoomFactor"></param>
        /// <param name="view"></param>
        /// <returns></returns>
        public override IEnumerable <Primitive2D> Get(float zoomFactor, View2D view)
        {
            var primitives = new List <Primitive2D>();

            //if(_suspended)
            //{ // just return an empty primitives list if suspended.
            //    return primitives;
            //}
            try
            {
                // calculate the current zoom level.
                var zoomLevel = (int)System.Math.Round(_projection.ToZoomLevel(zoomFactor), 0);

                if (zoomLevel >= _minZoomLevel && zoomLevel <= _maxZoomLevel)
                {
                    // build the bounding box.
                    var viewBox = view.OuterBox;
                    var box     = new GeoCoordinateBox(_projection.ToGeoCoordinates(viewBox.Min[0], viewBox.Min[1]),
                                                       _projection.ToGeoCoordinates(viewBox.Max[0], viewBox.Max[1]));

                    var tileRange      = TileRange.CreateAroundBoundingBox(box, zoomLevel);
                    var tileRangeIndex = new TileRangeIndex(tileRange);

                    var primitivePerTile = new Dictionary <Tile, Primitive2D>();
                    lock (_cache)
                    {
                        Image2D temp;
                        foreach (var tile in _cache)
                        {
                            if (tile.Value.IsVisibleIn(view))
                            {
                                tileRangeIndex.Add(tile.Key);
                                primitivePerTile.Add(tile.Key, tile.Value);

                                var minZoom = _projection.ToZoomFactor(tile.Key.Zoom - _zoomMinOffset);
                                var maxZoom = _projection.ToZoomFactor(tile.Key.Zoom + (1 - _zoomMinOffset));
                                if (zoomFactor < maxZoom && zoomFactor > minZoom)
                                { // just hit the cache for tiles of this zoom level.
                                    _cache.TryGet(tile.Key, out temp);
                                }
                            }
                        }

                        // set the ascending flag.
                        if (_previousZoomFactor != zoomFactor)
                        { // only change flag when difference.
                            _ascending          = (_previousZoomFactor < zoomFactor);
                            _previousZoomFactor = zoomFactor;
                        }

                        // get candidate tiles for every tile.
                        var selectedTiles = new List <Tile>();
                        foreach (var tile in tileRange)
                        {
                            var best = tileRangeIndex.ChooseBest(tile, _ascending);
                            foreach (var bestTile in best)
                            {
                                if (!selectedTiles.Contains(bestTile))
                                { // make sure no doubles are added!
                                    selectedTiles.Add(bestTile);
                                }
                            }
                        }

                        // sort according to the tiles index.
                        selectedTiles.Sort(delegate(Tile x, Tile y)
                        {
                            return(TileRangeIndex.TileWeight(tileRange.Zoom, x.Zoom, !_ascending).CompareTo(
                                       TileRangeIndex.TileWeight(tileRange.Zoom, y.Zoom, !_ascending)));
                        });
                        selectedTiles.Reverse();

                        // recursively remove tiles.
                        for (int idx = selectedTiles.Count; idx > 0; idx--)
                        {
                            if (selectedTiles[selectedTiles.Count - idx].IsOverlappedBy(
                                    selectedTiles.GetRange(selectedTiles.Count - idx + 1, selectedTiles.Count - (selectedTiles.Count - idx + 1))))
                            {
                                selectedTiles.RemoveAt(selectedTiles.Count - idx);
                            }
                        }

                        // TODO: trim this collection so that only tiles remain close to the zoom level not overlapping.
                        Image2D primitive;
                        foreach (Tile tile in selectedTiles)
                        {
                            if (_cache.TryPeek(tile, out primitive))
                            { // add to the primitives list.
                                primitives.Add(primitive);
                            }
                        }
                    }
                }
                OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Information,
                                                string.Format("LayerTile returned {0} primitives.", primitives.Count));
                return(primitives);
            }
            catch (Exception ex)
            { // don't worry about exceptions here.
                OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Error, ex.Message);
            }
            return(primitives);
        }
Beispiel #3
0
 /// <summary>
 /// Returns true if this layer is visible for the given project and relative zoom factor.
 /// </summary>
 /// <param name="projection"></param>
 /// <param name="zoomFactor"></param>
 /// <returns></returns>
 public bool IsLayerVisibleFor(IProjection projection, float zoomFactor)
 {
     return(this.IsLayerVisibleFor((float)projection.ToZoomLevel(zoomFactor)));
 }
Beispiel #4
0
 /// <summary>
 /// Returns true if this layer is visible for the given project and relative zoom factor.
 /// </summary>
 /// <param name="projection"></param>
 /// <param name="zoomFactor"></param>
 /// <returns></returns>
 public bool IsLayerVisibleFor(IProjection projection, float zoomFactor)
 {
     return this.IsLayerVisibleFor((float)projection.ToZoomLevel(zoomFactor));
 }