Пример #1
0
 internal virtual void AddTileInProgress(Tile tileInProgress)
 {
     lock (this)
     {
         tilesInProgress.Add(tileInProgress);
     }
 }
Пример #2
0
        private void DrawTileCoordinates(TilePosition tilePosition, ICanvas canvas)
        {
            int  x    = (int)(tilePosition.Point.X + 8 * displayModel.ScaleFactor);
            int  y    = (int)(tilePosition.Point.Y + 24 * displayModel.ScaleFactor);
            Tile tile = tilePosition.Tile;

            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append("X: ");
            stringBuilder.Append(tile.TileX);
            string text = stringBuilder.ToString();

            canvas.DrawText(text, x, y, this.paintBack);
            canvas.DrawText(text, x, y, this.paintFront);

            stringBuilder.Length = 0;
            stringBuilder.Append("Y: ");
            stringBuilder.Append(tile.TileY);
            text = stringBuilder.ToString();
            canvas.DrawText(text, x, (int)(y + 24 * displayModel.ScaleFactor), this.paintBack);
            canvas.DrawText(text, x, (int)(y + 24 * displayModel.ScaleFactor), this.paintFront);

            stringBuilder.Length = 0;
            stringBuilder.Append("Z: ");
            stringBuilder.Append(tile.ZoomLevel);
            text = stringBuilder.ToString();
            canvas.DrawText(text, x, (int)(y + 48 * displayModel.ScaleFactor), this.paintBack);
            canvas.DrawText(text, x, (int)(y + 48 * displayModel.ScaleFactor), this.paintFront);
        }
        public virtual void ExecuteQueryTest()
        {
            MapFile mapFile = new MapFile(MAP_FILE);

            MapFileInfo mapFileInfo = mapFile.MapFileInfo;

            Assert.True(mapFileInfo.DebugFile);

            for (sbyte zoomLevel = ZOOM_LEVEL_MIN; zoomLevel <= ZOOM_LEVEL_MAX; ++zoomLevel)
            {
                int  tileX = MercatorProjection.LongitudeToTileX(0.04, zoomLevel);
                int  tileY = MercatorProjection.LatitudeToTileY(0.04, zoomLevel);
                Tile tile  = new Tile(tileX, tileY, zoomLevel, 256);

                MapReadResult mapReadResult = mapFile.ReadMapData(tile);

                Assert.AreEqual(1, mapReadResult.PointOfInterests.Count);
                Assert.AreEqual(1, mapReadResult.Ways.Count);

                CheckPointOfInterest(mapReadResult.PointOfInterests[0]);
                CheckWay(mapReadResult.Ways[0]);
            }

            mapFile.Close();
        }
Пример #4
0
 internal virtual void RemoveTileInProgress(Tile tile)
 {
     if (this.tileDependencies != null)
     {
         this.tileDependencies.RemoveTileInProgress(tile);
     }
 }
 /// <summary>
 /// Returns if a tile is in the current tile set and no data is stored for this tile. </summary>
 /// <param name="tile"> the tile </param>
 /// <returns> true if the tile is in the current tile set, but no data is stored for it. </returns>
 public virtual bool requiresTile(Tile tile)
 {
     lock (this)
     {
         return(this.lastVisibleTileSet.Contains(tile) && !this.ContainsKey(tile));
     }
 }
Пример #6
0
        internal static void RunTest(MapFile mapFile)
        {
            int  tileX = MercatorProjection.LongitudeToTileX(0, ZOOM_LEVEL);
            int  tileY = MercatorProjection.LatitudeToTileY(0, ZOOM_LEVEL);
            Tile tile  = new Tile(tileX, tileY, ZOOM_LEVEL, 256);

            MapReadResult mapReadResult = mapFile.ReadMapData(tile);

            mapFile.Close();

            Assert.AreEqual(mapReadResult.PointOfInterests.Count, 0);
            Assert.AreEqual(1, mapReadResult.Ways.Count);

            LatLong latLong1 = new LatLong(0.0, 0.0, true);
            LatLong latLong2 = new LatLong(0.0, 0.1, true);
            LatLong latLong3 = new LatLong(-0.1, 0.1, true);
            LatLong latLong4 = new LatLong(-0.1, 0.0, true);

            LatLong[][] latLongsExpected = new LatLong[][]
            {
                new LatLong[] { latLong1, latLong2, latLong3, latLong4, latLong1 }
            };

            Way way = mapReadResult.Ways[0];

            // TODO: Was ArrayEquals()
            Assert.AreEqual(latLongsExpected, way.LatLongs);
        }
Пример #7
0
 internal virtual bool IsTileInProgress(Tile tile)
 {
     lock (this)
     {
         return(tilesInProgress.Contains(tile));
     }
 }
Пример #8
0
        private void DrawParentTileBitmap(ICanvas canvas, Point point, Tile tile)
        {
            Tile cachedParentTile = GetCachedParentTile(tile, 4);

            if (cachedParentTile != null)
            {
                IBitmap bitmap = this.tileCache.GetImmediately(CreateJob(cachedParentTile));
                if (bitmap != null)
                {
                    int   tileSize      = this.displayModel.TileSize;
                    long  translateX    = tile.GetShiftX(cachedParentTile) * tileSize;
                    long  translateY    = tile.GetShiftY(cachedParentTile) * tileSize;
                    sbyte zoomLevelDiff = (sbyte)(tile.ZoomLevel - cachedParentTile.ZoomLevel);
                    float scaleFactor   = (float)Math.Pow(2, zoomLevelDiff);

                    int x = (int)Math.Round(point.X);
                    int y = (int)Math.Round(point.Y);

                    this.matrix.Reset();
                    this.matrix.Translate(x - translateX, y - translateY);
                    this.matrix.Scale(scaleFactor, scaleFactor);

                    canvas.SetClip(x, y, this.displayModel.TileSize, this.displayModel.TileSize);
                    canvas.DrawBitmap(bitmap, this.matrix);
                    canvas.ResetClip();
                    bitmap.DecrementRefCount();
                }
            }
        }
Пример #9
0
 /// <summary>
 /// Cache maintenance operation to remove data for a tile from the cache. This should be excuted
 /// if a tile is removed from the TileCache and will be drawn again. </summary>
 /// <param name="from"> </param>
 internal virtual void RemoveTileData(Tile from, Tile to)
 {
     if (overlapData.ContainsKey(from))
     {
         overlapData[from].Remove(to);
     }
 }
Пример #10
0
 internal virtual void RemoveTileInProgress(Tile tileFinished)
 {
     lock (this)
     {
         tilesInProgress.Remove(tileFinished);
     }
 }
Пример #11
0
        public override void Draw(BoundingBox boundingBox, sbyte zoomLevel, ICanvas canvas, Point topLeftPoint)
        {
            IList <TilePosition> tilePositions = LayerUtil.GetTilePositions(boundingBox, zoomLevel, topLeftPoint, this.displayModel.TileSize);

            // In a rotation situation it is possible that drawParentTileBitmap sets the
            // clipping bounds to portrait, while the device is just being rotated into
            // landscape: the result is a partially painted screen that only goes away
            // after zooming (which has the effect of resetting the clip bounds if drawParentTileBitmap
            // is called again).
            // Always resetting the clip bounds here seems to avoid the problem,
            // I assume that this is a pretty cheap operation, otherwise it would be better
            // to hook this into the onConfigurationChanged call chain.
            canvas.ResetClip();

            if (!isTransparent)
            {
                canvas.FillColor(this.displayModel.BackgroundColor);
            }

            ISet <Job> jobs = new HashSet <Job>();

            foreach (TilePosition tilePosition in tilePositions)
            {
                jobs.Add(CreateJob(tilePosition.Tile));
            }
            this.tileCache.WorkingSet = jobs;

            for (int i = tilePositions.Count - 1; i >= 0; --i)
            {
                TilePosition tilePosition = tilePositions[i];
                Point        point        = tilePosition.Point;
                Tile         tile         = tilePosition.Tile;
                T            job          = CreateJob(tile);
                ITileBitmap  bitmap       = this.tileCache.GetImmediately(job);

                if (bitmap == null)
                {
                    if (this.hasJobQueue && !this.tileCache.ContainsKey(job))
                    {
                        this.jobQueue.Add(job);
                    }
                    DrawParentTileBitmap(canvas, point, tile);
                }
                else
                {
                    if (IsTileStale(tile, bitmap) && this.hasJobQueue && !this.tileCache.ContainsKey(job))
                    {
                        this.jobQueue.Add(job);
                    }
                    RetrieveLabelsOnly(job);
                    canvas.DrawBitmap(bitmap, (int)Math.Round(point.X), (int)Math.Round(point.Y));
                    bitmap.DecrementRefCount();
                }
            }
            if (this.hasJobQueue)
            {
                this.jobQueue.NotifyWorkers();
            }
        }
 /// <summary>
 /// Stores a list of MapElements against a tile.
 /// </summary>
 /// <param name="tile"> tile on which the mapItems reside. </param>
 /// <param name="mapItems"> the map elements. </param>
 public virtual void StoreMapItems(Tile tile, ICollection <MapElementContainer> mapItems)
 {
     lock (this)
     {
         this.Add(tile, LayerUtil.CollisionFreeOrdered(mapItems));
         this.version += 1;
     }
 }
Пример #13
0
 /// <summary>
 /// Retrieves the overlap data from the neighbouring tiles </summary>
 /// <param name="from"> the origin tile </param>
 /// <param name="to"> the tile the label clashesWith to </param>
 /// <returns> a List of the elements </returns>
 internal virtual ISet <MapElementContainer> GetOverlappingElements(Tile from, Tile to)
 {
     if (overlapData.ContainsKey(from) && overlapData[from].ContainsKey(to))
     {
         return(overlapData[from][to]);
     }
     return(new HashSet <MapElementContainer>());
 }
Пример #14
0
 /// <summary>
 /// Whether the tile is stale and should be refreshed.
 /// <para>
 /// This method is called from <seealso cref="#draw(BoundingBox, byte, Canvas, Point)"/> to determine whether the tile needs to
 /// be refreshed.
 /// </para>
 /// <para>
 /// A tile is considered stale if one or more of the following two conditions apply:
 /// <ul>
 /// <li>The {@code bitmap}'s <seealso cref="MapsforgeSharp.Core.Graphics.ITileBitmap#isExpired()"/> method returns {@code True}.</li>
 /// <li>The layer has a time-to-live (TTL) set (<seealso cref="#getCacheTimeToLive()"/> returns a nonzero value) and the sum of
 /// the {@code bitmap}'s <seealso cref="MapsforgeSharp.Core.Graphics.ITileBitmap#getTimestamp()"/> and TTL is less than current
 /// time (as returned by <seealso cref="java.lang.System#currentTimeMillis()"/>).</li>
 /// </ul>
 /// </para>
 /// <para>
 /// When a tile has become stale, the layer will first display the tile referenced by {@code bitmap} and attempt to
 /// obtain a fresh copy in the background. When a fresh copy becomes available, the layer will replace it and update
 /// the cache. If a fresh copy cannot be obtained (e.g. because the tile is obtained from an online source which
 /// cannot be reached), the stale tile will continue to be used until another
 /// {@code #draw(BoundingBox, byte, Canvas, Point)} operation requests it again.
 ///
 /// </para>
 /// </summary>
 /// <param name="tile">
 ///            A tile. This parameter is not used for a {@code TileDownloadLayer} and can be null. </param>
 /// <param name="bitmap">
 ///            The bitmap for {@code tile} currently held in the layer's cache. </param>
 protected internal override bool IsTileStale(Tile tile, ITileBitmap bitmap)
 {
     if (bitmap.Expired)
     {
         return(true);
     }
     return(cacheTimeToLive != 0 && ((bitmap.Timestamp + cacheTimeToLive) < DateTimeHelperClass.CurrentUnixTimeMillis()));
 }
Пример #15
0
 internal PolylineContainer(Way way, Tile tile)
 {
     this.coordinatesAbsolute       = null;
     this.coordinatesRelativeToTile = null;
     this.tags = way.Tags;
     this.tile = tile;
     layer     = way.Layer;
     this.way  = way;
     this.isClosedWay_Renamed = IsClosedWay(way.LatLongs[0]);
 }
Пример #16
0
        public Job(Tile tile, bool hasAlpha)
        {
            if (tile == null)
            {
                throw new System.ArgumentException("tile must not be null");
            }

            this.tile     = tile;
            this.hasAlpha = hasAlpha;
            this.key      = ComposeKey(this.tile.ZoomLevel, this.tile.TileX, this.tile.TileY);
        }
Пример #17
0
 internal PolylineContainer(Point[] coordinates, Tile tile, IList <Tag> tags)
 {
     this.coordinatesAbsolute       = new Point[1][];
     this.coordinatesRelativeToTile = null;
     this.coordinatesAbsolute[0]    = new Point[coordinates.Length];
     Array.Copy(coordinates, 0, coordinatesAbsolute[0], 0, coordinates.Length);
     this.tags           = tags;
     this.tile           = tile;
     this.layer          = 0;
     isClosedWay_Renamed = coordinates[0].Equals(coordinates[coordinates.Length - 1]);
 }
Пример #18
0
 /// <summary>
 /// stores an MapElementContainer that clashesWith from one tile (the one being drawn) to
 /// another (which must not have been drawn before). </summary>
 /// <param name="from"> origin tile </param>
 /// <param name="to"> tile the label clashesWith to </param>
 /// <param name="element"> the MapElementContainer in question </param>
 internal virtual void AddOverlappingElement(Tile from, Tile to, MapElementContainer element)
 {
     if (!overlapData.ContainsKey(from))
     {
         overlapData[from] = new Dictionary <Tile, ISet <MapElementContainer> >();
     }
     if (!overlapData[from].ContainsKey(to))
     {
         overlapData[from][to] = new HashSet <MapElementContainer>();
     }
     overlapData[from][to].Add(element);
 }
Пример #19
0
        internal virtual void DrawMapElements(ISet <MapElementContainer> elements, Tile tile)
        {
            // we have a set of all map elements (needed so we do not draw elements twice),
            // but we need to draw in priority order as we now allow overlaps. So we
            // convert into list, then sort, then draw.
            // draw elements in order of priority: lower priority first, so more important
            // elements will be drawn on top (in case of display=true) items.
            var elementsAsList = from element in elements orderby element.Priority ascending select element;

            foreach (MapElementContainer element in elementsAsList)
            {
                element.Draw(canvas, tile.Origin, this.symbolMatrix);
            }
        }
Пример #20
0
        public override Uri GetTileUrl(Tile tile)
        {
            StringBuilder stringBuilder = new StringBuilder(32);

            stringBuilder.Append(baseUrl);
            stringBuilder.Append(tile.ZoomLevel);
            stringBuilder.Append('/');
            stringBuilder.Append(tile.TileX);
            stringBuilder.Append('/');
            stringBuilder.Append(tile.TileY);
            stringBuilder.Append('.').Append(extension);

            return(new Uri(string.Format("{0}://{1}:{2}{3}", this.protocol, HostName, this.port, stringBuilder.ToString())));
        }
        public virtual void LatitudeToTileYTest()
        {
            for (sbyte zoomLevel = ZOOM_LEVEL_MIN; zoomLevel <= ZOOM_LEVEL_MAX; ++zoomLevel)
            {
                long tileY = MercatorProjection.LatitudeToTileY(MercatorProjection.LATITUDE_MAX, zoomLevel);
                Assert.AreEqual(0, tileY);
                tileY = MercatorProjection.LatitudeToTileY(MercatorProjection.LATITUDE_MAX, MercatorProjection.ZoomLevelToScaleFactor(zoomLevel));
                Assert.AreEqual(0, tileY);

                tileY = MercatorProjection.LatitudeToTileY(MercatorProjection.LATITUDE_MIN, zoomLevel);
                Assert.AreEqual(Tile.GetMaxTileNumber(zoomLevel), tileY);
                tileY = MercatorProjection.LatitudeToTileY(MercatorProjection.LATITUDE_MIN, MercatorProjection.ZoomLevelToScaleFactor(zoomLevel));
                Assert.AreEqual(Tile.GetMaxTileNumber(zoomLevel), tileY);
            }
        }
        public virtual void LongitudeToTileXTest()
        {
            for (sbyte zoomLevel = ZOOM_LEVEL_MIN; zoomLevel <= ZOOM_LEVEL_MAX; ++zoomLevel)
            {
                long tileX = MercatorProjection.LongitudeToTileX(LatLongUtils.LONGITUDE_MIN, zoomLevel);
                Assert.AreEqual(0, tileX);
                tileX = MercatorProjection.LongitudeToTileX(LatLongUtils.LONGITUDE_MIN, MercatorProjection.ZoomLevelToScaleFactor(zoomLevel));
                Assert.AreEqual(0, tileX);

                tileX = MercatorProjection.LongitudeToTileX(LatLongUtils.LONGITUDE_MAX, zoomLevel);
                Assert.AreEqual(Tile.GetMaxTileNumber(zoomLevel), tileX);
                tileX = MercatorProjection.LongitudeToTileX(LatLongUtils.LONGITUDE_MAX, MercatorProjection.ZoomLevelToScaleFactor(zoomLevel));
                Assert.AreEqual(Tile.GetMaxTileNumber(zoomLevel), tileX);
            }
        }
Пример #23
0
        public virtual void ExecuteQueryTest()
        {
            MapFile mapFile = new MapFile(MAP_FILE);

            for (sbyte zoomLevel = 0; zoomLevel <= ZOOM_LEVEL_MAX; ++zoomLevel)
            {
                int  tileX = MercatorProjection.LongitudeToTileX(1, zoomLevel);
                int  tileY = MercatorProjection.LatitudeToTileY(1, zoomLevel);
                Tile tile  = new Tile(tileX, tileY, zoomLevel, 256);

                MapReadResult mapReadResult = mapFile.ReadMapData(tile);

                Assert.AreEqual(0, mapReadResult.PointOfInterests.Count);
                Assert.AreEqual(0, mapReadResult.Ways.Count);
            }

            mapFile.Close();
        }
Пример #24
0
        public RendererJob(Tile tile, MapDataStore mapFile, RenderThemeFuture renderThemeFuture, DisplayModel displayModel, float textScale, bool isTransparent, bool labelsOnly) : base(tile, isTransparent)
        {
            if (mapFile == null)
            {
                throw new System.ArgumentException("mapFile must not be null");
            }
            else if (textScale <= 0 || float.IsNaN(textScale))
            {
                throw new System.ArgumentException("invalid textScale: " + textScale);
            }

            this.labelsOnly        = labelsOnly;
            this.displayModel      = displayModel;
            this.mapDataStore      = mapFile;
            this.renderThemeFuture = renderThemeFuture;
            this.textScale         = textScale;

            this.hashCodeValue = CalculateHashCode();
        }
Пример #25
0
        /// <returns> the first parent object of the given object whose tileCacheBitmap is cached (may be null). </returns>
        private Tile GetCachedParentTile(Tile tile, int level)
        {
            if (level == 0)
            {
                return(null);
            }

            Tile parentTile = tile.Parent;

            if (parentTile == null)
            {
                return(null);
            }
            else if (this.tileCache.ContainsKey(CreateJob(parentTile)))
            {
                return(parentTile);
            }

            return(GetCachedParentTile(parentTile, level - 1));
        }
Пример #26
0
 public override Uri GetTileUrl(Tile tile)
 {
     return(new Uri(string.Format("{0}://{1}:{2}{3}", PROTOCOL, HostName, this.port, "/cycle/" + tile.ZoomLevel + '/' + tile.TileX + '/' + tile.TileY + ".png")));
 }
Пример #27
0
 public DownloadJob(Tile tile, TileSource tileSource) : base(tile, tileSource.HasAlpha())
 {
     this.tileSource = tileSource;
 }
Пример #28
0
        private ISet <MapElementContainer> ProcessLabels(RenderContext renderContext)
        {
            // if we are drawing the labels per tile, we need to establish which tile-overlapping
            // elements need to be drawn.

            ISet <MapElementContainer> labelsToDraw = new HashSet <MapElementContainer>();

            lock (tileDependencies)
            {
                // first we need to get the labels from the adjacent tiles if they have already been drawn
                // as those overlapping items must also be drawn on the current tile. They must be drawn regardless
                // of priority clashes as a part of them has alread been drawn.
                ISet <Tile> neighbours = renderContext.rendererJob.tile.Neighbours;
                ISet <MapElementContainer> undrawableElements = new HashSet <MapElementContainer>();

                tileDependencies.AddTileInProgress(renderContext.rendererJob.tile);
                for (var i = neighbours.Count - 1; i >= 0; i--)
                {
                    Tile neighbour = neighbours.ElementAt(i);

                    if (tileDependencies.IsTileInProgress(neighbour) || tileCache.ContainsKey(renderContext.rendererJob.OtherTile(neighbour)))
                    {
                        // if a tile has already been drawn, the elements drawn that overlap onto the
                        // current tile should be in the tile dependencies, we add them to the labels that
                        // need to be drawn onto this tile. For the multi-threaded renderer we also need to take
                        // those tiles into account that are not yet in the TileCache: this is taken care of by the
                        // set of tilesInProgress inside the TileDependencies.
                        labelsToDraw.UnionWith(tileDependencies.GetOverlappingElements(neighbour, renderContext.rendererJob.tile));

                        // but we need to remove the labels for this tile that overlap onto a tile that has been drawn
                        foreach (MapElementContainer current in renderContext.labels)
                        {
                            if (current.Intersects(neighbour.BoundaryAbsolute))
                            {
                                undrawableElements.Add(current);
                            }
                        }
                        // since we already have the data from that tile, we do not need to get the data for
                        // it, so remove it from the neighbours list.
                        neighbours.Remove(neighbour);
                    }
                    else
                    {
                        tileDependencies.RemoveTileData(neighbour);
                    }
                }

                // now we remove the elements that overlap onto a drawn tile from the list of labels
                // for this tile
                foreach (var element in undrawableElements)
                {
                    renderContext.labels.Remove(element);
                }

                // at this point we have two lists: one is the list of labels that must be drawn because
                // they already overlap from other tiles. The second one is currentLabels that contains
                // the elements on this tile that do not overlap onto a drawn tile. Now we sort this list and
                // remove those elements that clash in this list already.
                IList <MapElementContainer> currentElementsOrdered = LayerUtil.CollisionFreeOrdered(renderContext.labels);

                // now we go through this list, ordered by priority, to see which can be drawn without clashing.
                IEnumerator <MapElementContainer> currentMapElementsIterator = currentElementsOrdered.GetEnumerator();
                while (currentMapElementsIterator.MoveNext())
                {
                    MapElementContainer current = currentMapElementsIterator.Current;
                    foreach (MapElementContainer label in labelsToDraw)
                    {
                        if (label.ClashesWith(current))
                        {
                            break;
                        }
                    }
                }

                labelsToDraw.UnionWith(currentElementsOrdered);

                // update dependencies, add to the dependencies list all the elements that overlap to the
                // neighbouring tiles, first clearing out the cache for this relation.
                foreach (Tile tile in neighbours)
                {
                    tileDependencies.RemoveTileData(renderContext.rendererJob.tile, tile);
                    foreach (MapElementContainer element in labelsToDraw)
                    {
                        if (element.Intersects(tile.BoundaryAbsolute))
                        {
                            tileDependencies.AddOverlappingElement(renderContext.rendererJob.tile, tile, element);
                        }
                    }
                }
            }
            return(labelsToDraw);
        }
Пример #29
0
 internal virtual void MatchWay(RenderCallback renderCallback, PolylineContainer way, Tile tile, Closed closed, IList <RenderInstruction> matchingList, RenderContext renderContext)
 {
     if (MatchesWay(way.Tags, tile.ZoomLevel, closed))
     {
         for (int i = 0, n = this.renderInstructions.Count; i < n; ++i)
         {
             this.renderInstructions[i].RenderWay(renderCallback, renderContext, way);
             matchingList.Add(this.renderInstructions[i]);
         }
         for (int i = 0, n = this.subRules.Count; i < n; ++i)
         {
             this.subRules[i].MatchWay(renderCallback, way, tile, closed, matchingList, renderContext);
         }
     }
 }
Пример #30
0
 /// <summary>
 /// Just a way of generating a hash key for a tile if only the RendererJob is known. </summary>
 /// <param name="tile"> the tile that changes </param>
 /// <returns> a RendererJob based on the current one, only tile changes </returns>
 public virtual RendererJob OtherTile(Tile tile)
 {
     return(new RendererJob(tile, this.mapDataStore, this.renderThemeFuture, this.displayModel, this.textScale, this.hasAlpha, this.labelsOnly));
 }