I'm working on a project that hopes to convert Google Maps static images into larger, stitched together maps.
I have created an algorithm that given a starting and ending, latitude and longitude, it will fetch the Google Maps Static image for that lat,lng pair, then increment lng by the pixel width of the fetched image, in this case 700px, using an algorithm for determining pixel to longitude ratio using a couple of formulas.
The formulas seem to be working perfectly for latitude, as you can see in my attachment, the vertically tiling images line up almost perfectly.
Yet horizontally, the longitude increment seems to be off by a factor of 2, or slightly more.
To increment latitude, I use a constant metres to latitude ratio
const metresToLatRatio = 0.001 / 111 // Get lat value from metres
const metresPerPxLat = getMetresPerPxLng(currentLat, zoom)
const latIncrement = metresToLatRatio * (metresPerPxLat * 700)
But for longitude, I replace the metresToLngRatio
constant with a variable derived from this formula
const metresToLngRatio = getMetresToLngRatio(currentLat)
const metresPerPxLng = getMetresPerPxLng(currentLat, zoom)
lngIncrement = (metresToLngRatio * (metresPerPxLng * 700))
Where getMetresToLngRatio
and getMetresPerPxLng
are
function getMetresPerPxLng(lat, zoom = 19, scale = 2) {
return Math.abs((156543.03392 * Math.cos(lat * Math.PI / 180) / (2 ** zoom)) / scale)
}
function getMetresToLngRatio(lat) {
return 1 / Math.abs(111111 * Math.cos(lat))
}
The getMetresPerPxLng
function is derived from this post and this answer: https://groups.google.com/g/google-maps-js-api-v3/c/hDRO4oHVSeM / What ratio scales do Google Maps zoom levels correspond to?
What I noticed is that if I change getMetresToLng
Ratio to return (1 / Math.abs(111111 * Math.cos(lat))) * 2
, the stitching appears more accurate, only off by a few tens of pixels, instead of almost half the image.
Am I doing something wrong with my longitude equation? I know that 111111*cos(lat)
is a rough estimate, so I'm wondering if there's a more accurate formula.