iosopenweathermapmktileoverlay

openweathermap MKTileOverlay does not show in mapview


Ive tried to read as many articles on this topic as possible. AFAIK Im doing this correctly however my map is never showing the results of my calls. Im trying to look at precipitation_new layer and while testing I set my Simulators location to an area that is currently showing precipitation but I never see anything on my map. This is my first attempt at using MKTileOverlay as well.

Ive tried changing canReplaceMapContent to NO and YES as well as varying the alpha with the same results.

Ive verified my map delegate is connected and working for all my other map calls. I also know that Im downloading requests because openweathermap has blocked me a couple times for calling their site too often (I only get 60 req/min right now).

Im doing the following:

- (void) setupTileRenderer
{
    NSString *tileTemplate = @"https://tile.openweathermap.org/{z}/{x}/{y}.png?appid=<my_app_id>";
    MKTileOverlay *tileOverlay = [[MKTileOverlay alloc] initWithURLTemplate:tileTemplate];
    tileOverlay.minimumZ = 2;
    tileOverlay.maximumZ = 16;

    tileOverlay.canReplaceMapContent = YES;
    _tileRenderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:tileOverlay];
    _tileRenderer.alpha = 0.5;

    DISPATCH_ASYNC {
        [_mapView addOverlay:tileOverlay level:MKOverlayLevelAboveLabels];
    });
}

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKTileOverlay class]])
    {
        _tileRendererRequests++;
        if (_tileRendererRequests > 55) {
            NSLog(@"OWMREQ - too many requests per min");
        }
        NSLog(@"OWMREQ _tileRendererRequests: %ld", (long)_tileRendererRequests);
        return _tileRenderer;
    }
}

A minor question: How do I count the number of requests Im making? It seems that the way Im doing it is not counting all the requests Im making and I get shut down very quickly.

Thanks for any help.

[EDIT] I actually did subclass it to cache the tiles however the tiles are always white (when I copy/paste link in browser) but I still don't see them show up on the map. The map just shows the normal map (nothing changed). I tried changing 'canReplaceMapContent' to false with same results. I verified that I get to the result(data, nil) line and it shows a count of 1444 bytes on a tile that should contain precipitation. I used another radar app to verify where I was looking had rain. Here's my code:

override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void) {

    let baseURL = "https://tile.openweathermap.org/map/precipitation_new/"
    let key = String(path.x) + "|" + String(path.y) + "|" + String(path.z)

    if let thisImg = cachedData.getRadarTileObject(key: key) {
        result(thisImg, nil)
    }
    else {
        let keyid = "my key id"
        let url = self.baseURL + String(path.z) + "/" + String(path.x) + "/" + String(path.y) + ".png?appid=" + keyid
        let theUrl = URL(string: url)
        print("URL: \(url)")
        let request = NSMutableURLRequest.init(url: theUrl!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 30)
        request.httpMethod = "GET"

        let session = URLSession.shared
        let dataTask = session.dataTask(with: request as URLRequest) {data,response,error in

            if error == nil {
                if let count = data?.count {
                    if count > 0 {
                        result(data, nil)
                        return
                    }
                }
            }
            else {
                print("ERROR loading tile data: \(String(describing: error?.localizedDescription))")
            }
            result(nil, nil)
        }
        dataTask.resume()
    }
}

Solution

  • Your code actually works perfectly, you just have your URL set as https://tile.openweathermap.org/{z}/{x}/{y}.png?appid=<my_app_id> when it should be https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid=<my_app_id>. The number of requests is totally wrong but the tiles do show up correctly. You also might want to set canReplaceMapContent to false.

    When I used your code, it was making a total of 28 requests to show the continental United States. I subclassed MKTileOverlay to add a cacheing mechanism which helped with the API limits.