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.
Best Answer
"Longitude versus pixel" increments seems to me the same at all the globe, so do not use the cosine of latitude for them (you don't need the "real" distance, just the longitude).
The latitude increment is OK if you fix the "degrees per meter at the equator" ratio (360/(2.π.6378137)).
So in my opinion it should be something like the following:
A multiplier is required to make tiles seamless for some reason Seen here perfectly tiling at latitudes and longitudes over 60 degrees apart. Australia and America: