ThinkGeo.com    |     Documentation    |     Premium Support

Custom Cache Tiles Being Named Incorrectly on Save

Hi,

I was wondering if anyone can help me with a tile generating issue for a custom cache method I’ve implemented.

The method seems to create the tiles correctly. However, when the tiles are saved to the temporary folder, the tiles are numbered differently to what I believe should be expected, so that when the caching tool checks for tiles in the temporary folder, it believes that none are part of the correct grid and so generates its own.

Here’s the code for the tile generation below:

the parameters take: All the layers, The current scale, The extent (current view) of the map, GeographyUnit.Meter, and the cache files( usually in windows temp folder).

public static void GenerateCacheFiles(IEnumerable layers, double scale, RectangleShape restrictedExtent, GeographyUnit mapUnit, string cacheDirectory, string cacheId)
{
FileBitmapTileCache cache = new FileBitmapTileCache(cacheDirectory, cacheId);
cache.TileMatrix.Scale = scale;
cache.TileMatrix = new MapSuiteTileMatrix(scale, 256, 256, mapUnit, restrictedExtent);

        Collection<TileMatrixCell> cells = cache.TileMatrix.GetIntersectingCells(restrictedExtent);
        foreach (TileMatrixCell cell in cells)
        {
            using (Bitmap bitmap = new Bitmap(256, 256))
            {
                PlatformGeoCanvas geoCanvas = new PlatformGeoCanvas();
                geoCanvas.BeginDrawing(bitmap, cell.BoundingBox, mapUnit);
                foreach (Layer layer in layers)
                {
                    lock (layer)
                    {
                        if (!layer.IsOpen) { layer.Open(); }
                        layer.Draw(geoCanvas, new Collection<SimpleCandidate>());
                    }
                }
                geoCanvas.EndDrawing();
                GeoImage geoImage = new GeoImage(bitmap);
                // create tile object to maintain current tile information.
                BitmapTile tile = new BitmapTile(geoImage, cell.BoundingBox, scale);
                // save tile.
                cache.SaveTile(tile);
            }
        }
    }

Here is the init of the tile cache:

userOverlay.TileCache = new FileBitmapTileCache(Path.GetTempPath(), “test”);
userOverlay.TileCache.TileMatrix.BoundingBoxUnit = GeographyUnit.Meter;

Below is the folder where the cache tiles are saved. As you can see, the files that the cache generated on its own gives different results to the cache tiles that were created with the custom tile generator.

Regards,

Zak

Hi Zak,

We reproduce that, but that’s not a bug, your code have some problem, please try my code as below:

        public void GenerateCacheFiles(IEnumerable layers, double scale, RectangleShape restrictedExtent, GeographyUnit mapUnit, string cacheDirectory, string cacheId)
    {
        FileBitmapTileCache cache = new FileBitmapTileCache(cacheDirectory, cacheId);
        cache.TileMatrix.Scale = scale;
        

        MapSuiteTileMatrix tileMatrix = new MapSuiteTileMatrix(scale, 256, 256, mapUnit);
        tileMatrix.BoundingBoxUnit = mapUnit;

        cache.TileMatrix = tileMatrix;// new MapSuiteTileMatrix(scale, 256, 256, mapUnit, restrictedExtent);

        Collection<TileMatrixCell> cells = cache.TileMatrix.GetIntersectingCells(restrictedExtent);
        foreach (TileMatrixCell cell in cells)
        {
            using (Bitmap bitmap = new Bitmap(256, 256))
            {
                PlatformGeoCanvas geoCanvas = new PlatformGeoCanvas();
                geoCanvas.BeginDrawing(bitmap, cell.BoundingBox, mapUnit);
                foreach (Layer layer in layers)
                {
                    lock (layer)
                    {
                        if (!layer.IsOpen) { layer.Open(); }
                        layer.Draw(geoCanvas, new Collection<SimpleCandidate>());
                    }
                }

                geoCanvas.EndDrawing();
                GeoImage geoImage = new GeoImage(bitmap);

                // create tile object to maintain current tile information.
                BitmapTile tile = new BitmapTile(geoImage, cell.BoundingBox, scale);

                // save tile.
                cache.SaveTile(tile);
            }
        }
    }

And you can refer our sample for detail: https://github.com/ThinkGeo/CacheGeneratorSample-ForWinForms/blob/master/CacheGenerator/TileCacheGenerator.cs

Wish that’s helpful.

Regards,

Ethan

Hi Ethan,

That fixed the issue I was having.

Thank you for your help.

Regards,

Zak

Hi Zak,

I am glad to hear that works.

Regards,

Ethan

HI Ethan,

I have one more issue that I would like help with solving.

When the tiles are drawn, the text is sometimes cut off depending on the location of the point in the tile square. (We have an “annotations layer” to allow users to draw text on the screen which is just an override of the PointStyle’s DrawCore method).

Is there a way to look for features outside of the cell’s bounding box?

We can see here that the point is close to the edge of the tile, so it ‘overflows’ into the neighbouring tiles. Although, if it’s further away from the edges, it doesn’t (see below)

Is it possible to override the layer drawcore to increase the area it looks for surrounding features?

The code for the cache tile generator is the same as above.

Regards,

Zak

Hi Zak,

We created one sample to test your issue, it works fine. Could you please do the testing in your environment? if there is any issue, please let me know that.

Thanks
Mark

Hi Mark,

Thankyou for your reply.

Unfortunately, the issue still persists. I’ve attached a zip to the post so that you can see the issue that’s happening more clearly and understand it better.

Regards,

Zak

caching.zip (268.0 KB)

Hi Zak,

Please let us know your detail scenario, it looks your code logic is strange, maybe we can give you better suggestion about the solution.

If your target is draw the “scale and time label” at each tile image, and at the same time draw the “Sample Text” in separated tile images, I think we cannot do that. Today we takes much time to discuss and try to find a workaround but failed. The reason is because in our logic only the tile boudingbox contains valid feature, the drawcore of the style will be fired, that’s why your label looks cut because the other tiles won’t go into drawcore function, they don’t contains the point in this layer, that’s the only valid feature for this layer.

Our suggestion here is:

  1. Use our cachegenerator to generate cache images: https://github.com/ThinkGeo/CacheGeneratorSample-ForWinForms this utility also can add watermarker to tile image.

  2. Add two overlay, one open cache and the other don’t, always show the “Sample Text” dynamic, that means they won’t be saved into your cache tiles. Only the “scale and time label” will be saved into tile images.

Any question please let us know.

Regards,

Ethan

Hi Ethan,

Thank you to everyone who took their time to look at this.

The scale and time label part was for debug purposes so that I could see if the tiles were being drawn and saved correctly.

The sample text was an example of the text features that users may want to add to the map. When the drawCore is fired, is it not possible to check for a certain area outside of the boundingbox? Or perhaps increase the bounding box of the point to the size of the text?

Regards,

Zak

Hi Zak,

If you can draw a rectangle (increase the bounding box of the point), of course all tiles will be fired and the text will be drawn.

But do you think that looks correct if you draw a special rectangle for the label?

Regards,

Ethan

Hi Ethan,

If the rectangle is transparent, this should be fine as long as the entire text fits in the box. I will give this a try and see if it works.

Thanks for your help.

Regards,

Zak

Hi Zak,

Any question please let us know.

Regards,

Ethan