What kind of solution is it
Looks like you need not a javascript solution but for python to use it not in browser but on a server. I've created a python example, but it is the math that I am going to stand on, math is all you need to calculate coordinates. Let me do it with js as well to make snippet work in browser. You can see, that python and js give the same results.
Jump to the answer
If you just need formulae for degrees per pixel, here you are. They are simple enough and you don't need any external libraries but just a python's math. The explanation can be found further.
#!/usr/bin/python
import math
w = 400
h = 400
zoom = 16
lat = 53.4055429
lng = -2.9976502
def getPointLatLng(x, y):
parallelMultiplier = math.cos(lat * math.pi / 180)
degreesPerPixelX = 360 / math.pow(2, zoom + 8)
degreesPerPixelY = 360 / math.pow(2, zoom + 8) * parallelMultiplier
pointLat = lat - degreesPerPixelY * ( y - h / 2)
pointLng = lng + degreesPerPixelX * ( x - w / 2)
return (pointLat, pointLng)
print 'NE: ', getPointLatLng(w, 0)
print 'SW: ', getPointLatLng(0, h)
print 'NW: ', getPointLatLng(0, 0)
print 'SE: ', getPointLatLng(w, h)
The output of the script is
$ python getcoords.py
NE: (53.40810128625675, -2.9933586655761717)
SW: (53.40298451374325, -3.001941734423828)
NW: (53.40810128625675, -3.001941734423828)
SE: (53.40298451374325, -2.9933586655761717)
What we have to start with
We have some parameters needed in url https://maps.googleapis.com/maps/api/staticmap?center=53.4055429,-2.9976502&zoom=16&size=400x400&maptype=satellite&key=YOUR_API_KEY – coordinates, zoom, size in pixels.
Let's introduce some initial variables:
var config = {
lat: 53.4055429,
lng: -2.9976502,
zoom: 16,
size: {
x: 400,
y: 400,
}
};
The math of the Earth of 512 pixels
The math is as follows. Zoom 1 stands for full view of the Earth equator 360° when using image size 512 (see the docs for size and zoom). See the example at zoom 1. It is a very important point. The scale (degrees per pixel) doesn't depend on the image size. When one changes image size, one sees the same scale: compare 1 and 2 – the second image is a cropped version of the bigger one. The maximum image size for googleapis is 640.
Every zoom-in increases resolution twice. Therefore the width of your image in terms of longitude is
lngDegrees = 360 / 2**(zoom - 1); // full image width in degrees, ** for power
Then use linear function to find coordinates for any point of the image. It should be mentioned, that linearity works well only for high zoomed images, you can't use it for low zooms like 5 or less. Low zooms have slightly more complex math.
lngDegreesPerPixel = lngDegrees / 512 = 360 / 2**(zoom - 1) / 2**9 = 360 / 2**(zoom + 8);
lngX = config.lng + lngDegreesPerPixel * ( point.x - config.size.x / 2);
Latitude degrees are different
Latitude degree and longitude degree on the equator are of the same size, but if we go north or south, longitude degree become smaller since rings of parallels on the Earth have smaller radii - r = R * cos(lat) < R and therefore image height in degrees becomes smaller (see P.S.).
latDegrees = 360 / 2**(zoom - 1) * cos(lat); // full image height in degrees, ** for power
And respectively
latDegreesPerPixel = latDegrees / 512 = 360 / 2**(zoom - 1) * cos(lat) / 2**9 = 360 / 2**(zoom + 8) * cos(lat);
latY = config.lat - latDegreesPerPixel * ( point.y - config.size.y / 2)
The sign after config.lat differs from the sign for lngX since earth longitude direction coincide with image x direction, but latitude direction is opposed to y direction on the image.
So we can make a simple function now to find a pixel's coordinates using its x and y coordinates on the picture.
var config = {
lat: 53.4055429,
lng: -2.9976502,
zoom: 16,
size: {
x: 400,
y: 400,
}
};
function getCoordinates(x, y) {
var degreesPerPixelX = 360 / Math.pow(2, config.zoom + 8);
var degreesPerPixelY = 360 / Math.pow(2, config.zoom + 8) * Math.cos(config.lat * Math.PI / 180);
return {
lat: config.lat - degreesPerPixelY * ( y - config.size.y / 2),
lng: config.lng + degreesPerPixelX * ( x - config.size.x / 2),
};
}
console.log('SW', getCoordinates(0, config.size.y));
console.log('NE', getCoordinates(config.size.x, 0));
console.log('SE', getCoordinates(config.size.x, config.size.y));
console.log('NW', getCoordinates(0, 0));
console.log('Something at 300,128', getCoordinates(300, 128));
P.S. You can probably ask me, why I place cos(lat) multiplier to latitude, not as a divider to longitude formula. I found, that google chooses to have constant longitude scale per pixel on different latitudes, so, cos goes to latitude as a multiplier.