Calculating pixels coordinates from lat/lon

I'm trying to develop a WPS that would print maps to images and PDFs. I don't want to use Mapfish because of its limitations, and because of some customization I need to add to the printed maps.

My method goes something like the following:

1- User selects a BBox to print.

2- The WPS converts the BBox coordinates to pixels coordinates.

3- Then calculates the resulting image's width and height using the calculated pixels coordinates.

4- Then call a WMS GetMap request to get the map image.

The problem is that the resulting image is stretched longitudinally.

I have reviewed the code many times and it seems that the problem is in the calculations of the pixels coordinates, it returns incorrect values which result in incorrect width and height, which in turn makes the image stretched.

Here is the code I use to convert from latitude/longitude to pixels coordinates, I took it from an opensource project called MOBAC.

Note that my layer is in EPSG:900913.

``````private void init() {
for (int zoom = 0; zoom < worldSize.length; zoom++)
worldSize[zoom] = tileSize * (1 << zoom);
}

/**
* Returns the absolute number of pixels in y or x, defined as: 2<sup>zoom</sup> * <code>tileSize</code>
*
* @param zoom
*            [0..22] (for tileSize = 256)
* @return
*/
private int getMaxPixels(int zoom) {
return worldSize[zoom];
}

private int falseNorthing(int aZoomlevel) {
return (-1 * getMaxPixels(aZoomlevel) / 2);
}

private int cLatToY(double lat, int zoom) {
lat = Math.max(MIN_LAT, Math.min(MAX_LAT, lat));
lat = -Math.log(tsfn(lat, Math.sin(lat)));
int mp = getMaxPixels(zoom);
int y = (-1) * (int) (mp * lat / (2 * Math.PI));
y = y - falseNorthing(zoom) - (y > 0 ? -1 : 1);
y = Math.min(y, mp - 1);
return y;
}

private int cLonToX(double lon, int zoom) {
int mp = getMaxPixels(zoom);
int x = (int) ((mp * (lon + 180l)) / 360l);
x = Math.min(x, mp - 1);
return x;
}
``````
• Why not just fix the width and multiply by the ratio of the bbox? – Ian Turton May 2 at 15:36
• @IanTurton That's a good idea, but I'm worry about if the calculations are not accurate, the printed map scale will not be accurate too. So, I need to have the correct calculations to convert from lat/lon to pixels coordinates. – Faz B May 4 at 8:04
• your map is 3857 so the scale will vary between the top and the bottom anyway. There is no correct scale for the map. – Ian Turton May 4 at 8:05
• @IanTurton, thanks for your help. I need to have a printed map with an accurate scale, so should I change the CRS of the map? and to which CRS? – Faz B May 4 at 8:17
• I do not fully grasp your formulae, but they looking nothing like Mercator's cylindrical projection. I would suggest you to use an existing library to perform the projection and only then compute pixel coordinates. Also: 900913 is not a valid EPSG code. – Luís de Sousa May 5 at 9:23