4

I am trying to imitate GetMap requests for GeoServer and have an application which generates these requests (requests are for cached layers). The problem is that sometimes I get geowebcache-cache-result:HIT and sometimes geowebcache-cache-result:MISS with geowebcache-miss-reason:request does not align to grid(s) 'XXXX'. I understand that for these "miss" requests I have generated invalid BBox parameter. For example (pay attention to marked numbers):

...REQUEST=GetMap&BBOX=55|6|865.8627022989,6104809.344416159,55|8|155.8627022989,6106099.344416159...

results in HIT

when

...REQUEST=GetMap&BBOX=55|5|865.8627022989,6104809.344416159,55|7|155.8627022989,6106099.344416159...

results in MISS with geowebcache-miss-reason:request does not align to grid(s) 'XXXX'.

What would be the formula for generating correct BBox?

NOTE: I have checked and the generated BBox coordinates fit inside layer's and grid extent.

UPDATE: Question also could be formulated as - how to validate if BBox coordinates are aligned to the grid that is used?

1 Answer 1

3

The easy way to do this is to make WMTS requests instead of WMS requests since then all you need to do is specify the zoom level, row and column number to get a hit.

If you have to calculate the tile bounds you should fetch the WMTS capabilities document. Then under the layer you are asking for will be a TileMatrixSetLink that tells you the projection and limits for each level of tiles.

 <TileMatrixSetLink>
    <TileMatrixSet>EPSG:4326</TileMatrixSet>
    <TileMatrixSetLimits>
      <TileMatrixLimits>
        <TileMatrix>EPSG:4326:0</TileMatrix>
        <MinTileRow>0</MinTileRow>
        <MaxTileRow>0</MaxTileRow>
        <MinTileCol>0</MinTileCol>
        <MaxTileCol>0</MaxTileCol>
      </TileMatrixLimits>
      <TileMatrixLimits>
        <TileMatrix>EPSG:4326:1</TileMatrix>
        <MinTileRow>0</MinTileRow>
        <MaxTileRow>0</MaxTileRow>
        <MinTileCol>0</MinTileCol>
        <MaxTileCol>1</MaxTileCol>
      </TileMatrixLimits>
      <TileMatrixLimits>
      [.....]

This gives you the row and column ranges for each zoom level, don't request a tile outside these limits. Then look for the TileMatrixSet towards the end of the file that matches this name.

  <TileMatrixSet>
  <ows:Identifier>EPSG:4326</ows:Identifier>
  <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS>
  <TileMatrix>
    <ows:Identifier>EPSG:4326:0</ows:Identifier>
    <ScaleDenominator>2.795411320143589E8</ScaleDenominator>
    <TopLeftCorner>90.0 -180.0</TopLeftCorner>
    <TileWidth>256</TileWidth>
    <TileHeight>256</TileHeight>
    <MatrixWidth>2</MatrixWidth>
    <MatrixHeight>1</MatrixHeight>
  </TileMatrix>
  <TileMatrix>
    <ows:Identifier>EPSG:4326:1</ows:Identifier>
    <ScaleDenominator>1.3977056600717944E8</ScaleDenominator>
    <TopLeftCorner>90.0 -180.0</TopLeftCorner>
    <TileWidth>256</TileWidth>
    <TileHeight>256</TileHeight>
    <MatrixWidth>4</MatrixWidth>
    <MatrixHeight>2</MatrixHeight>
  </TileMatrix>
  [......]

Now for any zoom level, you can look up the origin of the grid and then calculate the bounds for any tile as:

pixelSize = scaleDenom * 2.8e-4 
if CRS is degrees then / by 111319 else convert from metres if needed
tileWidth = 256 * pixelSize
tileHeight = 256 * pixelSize

minX = col * tileWidth + originX
maxY = originY - row * tileHeight 
maxX = minX + tileWidth
minY = maxY - tileHeight

You can see a full implementation with axis order handling and all the other exciting issues from GeoTools.

0

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.