Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a tiling services which generates tiles on demand but TiledMapServiceLayer does not use a callback for getTileUrl so how would one implement this? I've tried using the refresh! method to no avail. I've also tried using the undocumented img argument but didn't get far. Thoughts? Solutions?

Here's my code showing some of what I've tried:

getTileUrl: function ( level, row, col, esriImg )
{
    var that = this, imageNumber, folder, url;
    imageNumber = ( Math.pow( 2, level ) * row ) + col;
    folder = Math.floor( imageNumber / this.tileInfo.width );
    url = this.url.substitute( {
        x: col,
        y: row,
        z: level,
        folder: folder
    } );
    if ( h$.yes( mapVars.OnDemandTiles ) )
    {
        var img = dojo.create( "img", { src: url } );
        dojo.connect( img, "onerror", function ()
        {
            infor.gis.hansen.setMapEvent( "tilegeneration", {
                callback: function ()
                {
                    $.delay( 5000, that.id, function () {
                        that.refresh();
                    } );
                },
                custdata: url,
                extent: mapVars.FullExtent
            } );
        } );
        return url;
    }
    else
    {
        return url; // getRefreshURL(url);
    }
}
share|improve this question
    
Two questions: how did you come to the conclusion that getTileUrl has a fourth parameters? Why do you need to render tiles on the fly? –  Derek Swingley Feb 1 '12 at 3:57
    
The answer is to override the _tileErrorHandler. In this case our proprietary tile generator has an on-demand feature but the feature is driven from the client. If the client fails to load a tile it sends a request to the server to generate the tiles. If that service returns successfully the tiles are sure to exist. Appending a ?uniqueId to the URL forces the image to reload. –  ca0v Feb 1 '12 at 5:29

2 Answers 2

Override _tileErrorHandler to invoke the necessary code to generate the tile. Once tile is generated evt.currentTarget.src += "?unique" will load the missing image. First lines of _tileErrorHandler:

dojo.style( evt.currentTarget, "visibility", "visible" );
this._tilePopPop( evt.currentTarget );

In my case I could then request that the tile be generated and the callback would update the src:

img.src += "?blah";

And the tile is loaded.

share|improve this answer
    
Glad you found a solution. My only comment would be that you should subclass ArcGISTiledMapServiceLayer and override _tileErrorHandler there rather than clobbering it in your app. Also, you never responded to my question about getTileUrl having four parameters. It does not have a fourth undocumented parameter. –  Derek Swingley Feb 1 '12 at 17:37
    
Actually esri.layers.TiledMapServiceLayer:getTileUrl is called with 4 parameters. I didn't want to complicate the conversation as it wasn't part of the solution but here's how you can use it: getTileUrl: function ( level, row, col, img ) { alert(img.id); } I'm using 2.6...perhaps it's not true in earlier versions? –  ca0v Feb 1 '12 at 17:49
    
Strange, I work on the JS API team and don't see how/why it's doing that. Can you post a jsfiddle showing this in action? –  Derek Swingley Feb 1 '12 at 22:43
    
I had to work hard to get this so you can see it happening in the ESRI source...anyway my problem has long since been resolved: img._onload_connect = dc(img, "onload", this, "_tileLoadHandler"); img._onerror_connect = dc(img, "onerror", this, "_tileErrorHandler"); img._onabort_connect = dc(img, "onabort", this, "_tileErrorHandler"); var url = this.getTileUrl(_5a, r, c, img); –  ca0v Feb 15 '12 at 15:40
    
Thanks for following up. As you've shown, _tileLoadHandler handler does indeed take four arguments but getTileUrl only takes three. If you'd like to continue to discuss, please email me: dswingley at esri.com –  Derek Swingley Feb 15 '12 at 18:38

If I understand correctly, I think you're trying to do something that is better suited for a dynamic map service layer. If you need to render data on the fly, use a dynamic map service layer.

share|improve this answer
    
I have a proprietary tile generator which has an OnDemand mode and can only access the tiles via an image url. Client must detect the image is missing, request its generation and then reload it. TiledDynamicLayer would work if it existed but DynamicLayer.getImageUrl(extent, width, height, callback) doesn't allow for this...it gets an image to fill the extent. Would be cool if callback could return an array of [row, col, url]. –  ca0v Feb 1 '12 at 5:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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