I'm trying to overlay tiles from a WMS server (a map of the ocean biomass) on a Google Map (android), but the projection is slightly distorted.

As you can see in this picture, the longitudes are OK, but the latitudes get distorted the farther away from the equator you get:

Map distortion

When zooming in, the distortion is no longer visible:

enter image description here

The WMS accepts EPSG:4326 bounding boxes (I've reviewed other questions on this topic, but they all use a WMS that accepts different coordinate systems).

I'm calculating the WMS BBOX coordinates out of the (x,y,zoom) parameters in getTile by calling tile2boundingBox(x,y,zoom) (calculation taken from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames):

double tile2lon(int x, int z) {
  return x / pow(2.0, z) * 360.0 - 180;

double tile2lat(int y, int z) {
  double n = pi - (2.0 * pi * y) / pow(2.0, z);
  return vector_math.degrees(atan(sinh(n)));

tile2boundingBox(final int x, final int y, final int zoom) async {
  final north = tile2lat(y, zoom);
  final south = tile2lat(y + 1, zoom);
  final west = tile2lon(x, zoom);
  final east = tile2lon(x + 1, zoom);

  return [south, west, north, east];

And then I create a WMS url to fetch the tile with the BBOX e.g:


I've also compared my calculation to the python program in MapTiler: https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/ and the coordinated are exactly the same:

enter image description here

What am I doing wrong?


1 Answer 1


Firstly, I recommend using an existing library rather than implementing your own XYZ tile to latitude/longitude conversion. https://github.com/mapbox/mercantile is good if you're using Python. There's much less likely to be bugs in popular open source projects than in a roll-your-own.

To use this, you would:

import mercantile
mercantile.xy_bounds(2, 2, 3)
Bbox(left=-10018754.171394622, bottom=5009377.085697311, right=-5009377.085697311, top=10018754.171394622)

Substitute those into your WMS call, using CRS=EPSG:3857 as well:


Secondly, you shouldn't need to perform this conversion at all! What the comments on your post suggest is that the service supports using EPSG:3857 (Web Mercator) which is the typical projection of XYZ tile services.


  1. https://my.cmems-du.eu/thredds/wms/global-reanalysis-bio-001-029-daily?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=chl&STYLES=boxfill%2Frainbow&TILED=true&COLORSCALERANGE=0.049000002%2C10.9050001&WIDTH=512&HEIGHT=512&BBOX=-10948228.4353,2993885.5239,-4872401.9310,9147983.5452&CRS=EPSG:3857
  2. https://my.cmems-du.eu/thredds/wms/global-reanalysis-bio-001-029-daily?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=chl&STYLES=boxfill%2Frainbow&TILED=true&COLORSCALERANGE=0.049000002%2C10.9050001&WIDTH=512&HEIGHT=512&BBOX=0.0,-90.0,40.0,-45.0&CRS=EPSG:4326

The former is Web Mercator (EPSG:3857), and the latter is WGS84 (EPSG:4326). However note that your BBOX parameter must match the coordinate system that you request. You cannot request an output in Web Mercator if you give it a WGS84 bounding box. (Well, you can try, but you won't get sensible output.)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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