Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map doesn't loading Tile Layers in Android #668

Closed
RajeethKalluru opened this issue May 30, 2019 · 18 comments
Closed

Map doesn't loading Tile Layers in Android #668

RajeethKalluru opened this issue May 30, 2019 · 18 comments

Comments

@RajeethKalluru
Copy link

Hi Team,

Map doesn't loading Tile layers in Android showing white screen but loading in UWP.
Please guide how to resolve.
I am attaching the sample project.

MapsUIDemo.zip

Android Map:

Android_Map

UWP Map:

UWP_Map

Thanks,
Rajeethulla

@nijsf
Copy link

nijsf commented May 30, 2019

I have the same problem. Mapsui sample works but then I make my own solution the map stays white. I have even copied my source to the Mapsui project and it works just fine.

Can't find out what the difference is. I have been chewing on it for 3 days and my customers are getting impatient.... so I hope we can solve the issue soon!

@RajeethKalluru RajeethKalluru changed the title Map doesn't loading in Android Map Tile Layers doesn't loading in Android May 30, 2019
@RajeethKalluru RajeethKalluru changed the title Map Tile Layers doesn't loading in Android Map doesn't loading Tile Layers in Android May 30, 2019
@JesrigPineda
Copy link

Hello, I have the same problem too. What you can do as an alternative is to use your own map server or use one of the ones that OSM has, that's what I did, I do not know what's happening.

https://wiki.openstreetmap.org/wiki/ES:Teselas

            var map = new Mapsui.Map
           {
            Transformation = new MinimalTransformation(),
            CRS = "EPSG:3857",
            BackColor = Mapsui.Styles.Color.Gray
        };


        var attribution = new BruTile.Attribution("© OpenStreetMap contributors",
            "http://www.openstreetmap.org/copyright");


        var tileSource = new HttpTileSource(new GlobalSphericalMercator(),
            "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",
            new[] { "a", "b", "c" }, name: "OpenStreetMap",
            attribution: attribution);

        var tileLayer = new TileLayer(tileSource) { Name = "Carto Light" };


        map.Layers.Add(tileLayer);

@nijsf
Copy link

nijsf commented May 30, 2019

@Jesrigt, I did a quick test and you are right! It works for me as well.

Strange that this does not happen on iPhone, just Android. My App (which still used 1.4.8) worked well but users with Android 9 (Pie) smartphones started reporting white maps.

I tried to catch all Exceptions and noticed a 429 "Too many requests" error when downloading the tiles. That could be related to the issue we are experiencing.

@nijsf
Copy link

nijsf commented May 30, 2019

@Jesrigt I forgot to say thanks for sharing your solution!

@nijsf
Copy link

nijsf commented May 30, 2019

I get this error: 429 (Too Many Requests) when fetching tiles in /Mapsui/Fetcher/TileFetchDispatcher.cs:85 with the OpenStreetMap tiles.

Seems a violation of the terms of use. Don't know why this is happening on Android only though...

@JesrigPineda
Copy link

@nijsf You're welcome, thanks for commenting on the error

@RajeethKalluru
Copy link
Author

@Jesrigt It worked for me but tiles are in gray color.

Thanks.

Map

@nijsf
Copy link

nijsf commented May 31, 2019

I have a fix for the issue:

Following yesterday's error I read that you need to supply a UserAgent in your http request. So I tried the following change and that works:

In BruTile.Web.HttpTileProvider add the UserAgent to your request:

public HttpTileProvider(IRequest request = null, IPersistentCache<byte[]> persistentCache = null,
           Func<Uri, byte[]> fetchTile = null)
       {
          //Add this header, so OpenStreetMap can track you are not abusing their systems
           _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("YOUR APP NAME HERE");

           _request = request ?? new NullRequest();
           PersistentCache = persistentCache ?? new NullCache();
           _fetchTile = fetchTile ?? FetchTile;
       }

@JesrigPineda
Copy link

@RajeethKalluru Yes, that's right, you are using a tile with these characteristics, check the link that you send to know more.

@nijsf Thanks for sharing the solution, you're right I had not read in detail about the UserAgen

@helluvamatt
Copy link

helluvamatt commented Jun 1, 2019

This issue was also affecting me in WPF. I resolved it using a very simple custom ITileSource that forwards requests to a wrapped HttpTileSource that is passed a custom Func<byte[], TileInfo> tileFetcher which uses my own HttpClient with pre-populated default headers (including the User-Agent header):

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("User-Agent", USER_AGENT);

var osmAttribution = new Attribution("© OpenStreetMap contributors", "https://www.openstreetmap.org/copyright");
var osmSource = new HttpClientTileSource(httpClient, new GlobalSphericalMercator(), "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", new[] { "a", "b", "c" }, name: "OpenStreetMap", attribution: osmAttribution);
var osmLayer = new TileLayer(osmSource) { Name = "OpenStreetMap" };
using System;
using System.Collections.Generic;
using System.Net.Http;
using BruTile;
using BruTile.Web;

namespace WpfApp1
{
    internal class HttpClientTileSource : ITileSource
    {
        private readonly HttpClient _HttpClient;
        private readonly HttpTileSource _WrappedSource;

        public HttpClientTileSource(HttpClient httpClient, ITileSchema tileSchema, string urlFormatter, IEnumerable<string> serverNodes = null, string apiKey = null, string name = null, BruTile.Cache.IPersistentCache<byte[]> persistentCache = null, Attribution attribution = null)
        {
            _HttpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
            _WrappedSource = new HttpTileSource(tileSchema, urlFormatter, serverNodes, apiKey, name, persistentCache, ClientFetch, attribution);
        }

        public ITileSchema Schema => _WrappedSource.Schema;

        public string Name => _WrappedSource.Name;

        public Attribution Attribution => _WrappedSource.Attribution;

        public byte[] GetTile(TileInfo tileInfo) => _WrappedSource.GetTile(tileInfo);

        private byte[] ClientFetch(Uri uri) => _HttpClient.GetByteArrayAsync(uri).ConfigureAwait(false).GetAwaiter().GetResult();
    }
}

@RajeethKalluru
Copy link
Author

Now its working fine. But I have done nothing.

Thanks.

Screenshot (18)

@nijsf
Copy link

nijsf commented Jun 11, 2019 via email

@RajeethKalluru
Copy link
Author

I have a fix for the issue:
Following yesterday's error I read that you need to supply a UserAgent in your http request. So I tried the following change and that works:
In BruTile.Web.HttpTileProvider add the UserAgent to your request:
public HttpTileProvider(IRequest request = null, IPersistentCache<byte[]> persistentCache = null,
Func<Uri, byte[]> fetchTile = null)
{
//Add this header, so OpenStreetMap can track you are not abusing their systems
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("YOUR APP NAME HERE");

       _request = request ?? new NullRequest();
       PersistentCache = persistentCache ?? new NullCache();
       _fetchTile = fetchTile ?? FetchTile;
   }

@nijsf,
Where did you read that we need to supply UserAgent. If possible please provide the resource it would be helpful.

Thanks,
Rajeethulla.

@nijsf
Copy link

nijsf commented Jun 17, 2019 via email

@RajeethKalluru
Copy link
Author

@nijsf

Thanks for the information.

@ssombat
Copy link

ssombat commented Jul 9, 2019

On all the forms and UWP samples, they are also blank white pages.

@pauldendulk
Copy link
Member

With the next release we use the new version of BruTile. It has a default values set for the user-agent and will not be blocked by openstreetmap. It is advised though to set a user-agent for your application because if just one osm abuser uses the default user-agent your app will be blocked as well.

@pauldendulk
Copy link
Member

In 2.0.0-beta.26 this is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants