Unrequested tiles for non-square level of detail

3181
4
Jump to solution
06-20-2013 01:51 PM
PatrickHartling
New Contributor III
I am making a subclass of AGSTiledLayer to act as the base layer if our app has no Internet connection. My plan is to use a single image that is part of the application bundle, and then the layer will create tiles from that image on the fly. I am using version 10.1.1-u1 on iOS 6.x.

My custom layer works fine as long as the number of rows equals the number of columns in a given level of detail. That requires the use of a square image, but I have one with an aspect ratio of 2:1 that I would like to use. For this particular image, I create the AGSLOD objects for the tileInfo property of the layer such that there are twice as many columns as rows per level of detail. However, my custom AGSTiledLayer instance receives AGSTileKey objects for only half the tiles. For example, I get the following upon initial load (sorted for readability as the order appears to vary based on threading):

AGSTileKey- level: 2, column: 0, row: 0 AGSTileKey- level: 2, column: 1, row: 0 AGSTileKey- level: 2, column: 2, row: 0 AGSTileKey- level: 2, column: 3, row: 0 AGSTileKey- level: 2, column: 0, row: 1 AGSTileKey- level: 2, column: 1, row: 1 AGSTileKey- level: 2, column: 2, row: 1 AGSTileKey- level: 2, column: 3, row: 1 AGSTileKey- level: 2, column: 0, row: 2 AGSTileKey- level: 2, column: 1, row: 2 AGSTileKey- level: 2, column: 2, row: 2 AGSTileKey- level: 2, column: 3, row: 2 AGSTileKey- level: 2, column: 0, row: 3 AGSTileKey- level: 2, column: 1, row: 3 AGSTileKey- level: 2, column: 2, row: 3 AGSTileKey- level: 2, column: 3, row: 3


From those 16 tile requests, I see the Western Hemisphere rendered at the correct aspect ratio, but the Eastern Hemisphere is not rendered at all.

The AGSLOD for level 2 was constructed with the following parameters:

AGSLOD *levelOfDetail = [[AGSLOD alloc] initWithLevel:2 resolution:resolution scale:scale]; levelOfDetail.startTileRow = 0; levelOfDetail.endTileRow = 3; levelOfDetail.startTileColumn = 0; levelOfDetail.endTileColumn = 7;


Based on that, I expect there to be 32 tiles for level 2. Is that an incorrect conclusion? My tile sizes are currently 256x256 in case that matters.
0 Kudos
1 Solution

Accepted Solutions
PatrickHartling
New Contributor III
I believe that I have resolved my issues with this. First, sending -computeTileBounds: to the AGSTileInfo object was a massive help. That alone allowed me to try a variety of resolution and scale settings quickly and easily. For the image that I want to use, the GoogleCRS84Quad scale set looks great.

Second, I was misinterpreting the endTileRow and endTileColumn properties on instances of AGSLOD. I thought that those were the upper bound of an inclusive range such as [startTileRow,endTileRow]. If instead I use them for the upper bound of an exclusive range such as [startTileRow,endTileRow), then everything renders correctly.

View solution in original post

0 Kudos
4 Replies
DiveshGoyal
Esri Regular Contributor
Interesting. I have never come across this situation before, and I'm not quite sure how the layer framework will handle it.

Out of curiosity, can you try setting rows to 7 too? You could pass back nil for the for all rows > 3.
That might turn out to be a viable workaround.

Another thing you could try is that for each AGSLOD object, just specify the level, resolution and scale.
Pack these LODs into the TileInfo object as you normally do, but then call [tileInfo computeTileBounds:envelope] passing in the full envelope of your layer.

The computeTileBounds: method will go through each AGSLOD and setup its start/end TileRow/Column properties based on the layers envelope.
0 Kudos
PatrickHartling
New Contributor III
If I change the end tile row as proposed, then only the northwestern quadrant of my map image is rendered. The set of tiles requested is the same as before.

The closest I have come is to halve the starting resolution value for LOD 0. If I do that, then the entire image gets rendered at the correct aspect ratio, but it occupies only the top half of the AGSMapView frame. Is there any information on how I should compute the resolution and/or scale for each level of detail? I start with base-level scale and resolution values for LOD 0 and then divide by two for each successive level of detail:

const size_t divisor = 2ul << (zoomLevel - 1);
resolution = baseResolution / divisor;
scale = baseScale / divisor;


Whether the initial values for baseResolution and baseScale are correct may well be a factor.
0 Kudos
PatrickHartling
New Contributor III
I think I am closing in on a solution to this. It appears that what I want is something similar to GoogleCRS84Quad or GlobalCRS84Pixel, but I haven't quite figured out the correct resolution and scale values to use.
0 Kudos
PatrickHartling
New Contributor III
I believe that I have resolved my issues with this. First, sending -computeTileBounds: to the AGSTileInfo object was a massive help. That alone allowed me to try a variety of resolution and scale settings quickly and easily. For the image that I want to use, the GoogleCRS84Quad scale set looks great.

Second, I was misinterpreting the endTileRow and endTileColumn properties on instances of AGSLOD. I thought that those were the upper bound of an inclusive range such as [startTileRow,endTileRow]. If instead I use them for the upper bound of an exclusive range such as [startTileRow,endTileRow), then everything renders correctly.
0 Kudos