2

My app uses the CartoDB static map API to get a "center" map at zoom level 19 or 20. Most times it gets a good map, but depending where it's looking it sometimes gets a "Map data not yet available" map like this:

map data not yet available

It uses the ESRI tiles http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x} because these provide sufficient clarity for most of our coverage area (New Zealand).

I want to be able to detect when I get these (perhaps by running another command first to determine availability) so that I can use a different basemap instead, and avoid returning this kind of result to my customer.

This all happens within a C# program, where I can do all sorts of things programatically, but nothing manually.

2 Answers 2

1

I have tested the basemap you have shared within the CartoDB Editor and it works at zoom level 19, but as you pointed out it does not work at zoom 20 (there are not tiles).

1
  • You're right - I was getting mixed up with a different basemap I'm trying - Stamen. Thanks. Incidentally, I think the basemap I'm using doesn't affect the principle of the solution. It might affect the detail of the implementation however (e.g. a different basemap might return a predominantly black image at zoom levels greater than its maximum). Jun 21, 2016 at 11:44
0

In C# you can examine each pixel of the resulting map (which comes in as a byte array), count the number of pixels of each colour and check if there's an abundance of grey. The principle probably applies in other programming languages, providing you have the right image analysis capabilities.

A valid satellite image would have many colours appearing approximately as frequently as each other. The "map data not yet available" results have about 100 times more ffcccccc pixels than the next most frequent colour (different basemaps may result in different predominant colours).

Using that knowledge, here was my implementation:

    /// <summary>
    /// Count the colour frequencies to determine validity of map
    /// </summary>
    /// <param name="jpegBytes"></param>
    /// <returns></returns>
    public static bool IsValidMap(byte[] jpegBytes)
    {
        var colourFrequency = new Dictionary<Color, int>();

        // get the image into a Bitmap
        using (var ms = new MemoryStream(jpegBytes))
        {
            using (var bmap = new Bitmap(ms))
            {
                // iterate through the bitmap
                for (var x = 0; x < bmap.Width; x++)
                {
                    for (var y = 0; y < bmap.Height; y++)
                    {
                        var colour = bmap.GetPixel(x, y);
                        if (!colourFrequency.ContainsKey(colour))
                        {
                            colourFrequency.Add(colour, 0);
                        }
                        colourFrequency[colour]++;
                    }
                }
            }
        }

        if (colourFrequency.Count < 3)
        {
            return false;
        }

        var coloursByFrequency = colourFrequency
            .OrderByDescending(cf => cf.Value)
            .Take(2)
            .ToList();

        var colour1 = coloursByFrequency.First();
        var colour2 = coloursByFrequency.Last();

        // if the predominant colour is grey
        // and it's a lot more frequent than
        // the next most common colour, then
        // this is a "map data not available".
        var mapDataNotAvailable = colour1.Key.Name == "ffcccccc"
            && colour1.Value > colour2.Value * 10;

        return !mapDataNotAvailable;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.