I\'m trying to develop a page in ASP.NET that will act as a tile-server for a Google Map
It will pull a collection of latitude/longitude points from the database, th
"If it is a Mercator projection, you shouldn't need to worry about the curvature of the earth since all of the lat/lon lines are at equal spacing"
Perhaps you're thinking of the Geographic (aka Plate Carree) projection? The Mercator projection does have equally spaced lines of longitude, but does not have equally spaced lines of latitude (lat = atan(sinh(y)), so 90° is at infinity).
BTW, the math for the Mercator projection on a sphere is here, but if Google Maps is using the WGS84 ellipsoid and you need to get it exact it gets more complicated. In that case, I'd look at this, but beware: it's not for the faint of heart.
Here's some code I'm currently using. It's in PHP.
// Returns longitude in pixels at a certain zoom level
function lonToX($lon, $zoom) {
$offset = 256 << ($zoom-1);
return round($offset + ($offset * $lon / 180));
}
// Returns latitude in pixels at a certain zoom level
function latToY($lat, $zoom) {
$offset = 256 << ($zoom-1);
return round($offset - $offset/pi() * log((1 + sin($lat * pi() / 180)) / (1 - sin($lat * pi() / 180))) / 2);
}
Based on code from this page, written by this guy.
Good luck!
Update: This map is a great way to help understand how tiles work in Google Maps
Edit: Here's an equivalent set of functions in VB.NET:
Public Function LonToX(Lon As Double, Zoom as UInteger) As UInteger
Dim Offset = 256 << (Zoom - 1)
Return Math.Round(Offset + (Offset * Lon / 180))
End Function
Public Function LatToY(Lat As Double, Zoom as UInteger) As UInteger
Dim Offset = 256 << (Zoom - 1)
Return Math.Round(Offset - Offset / Math.Pi * Math.Log((1 + Math.Sin(Lat * Math.Pi / 180)) / (1 - Math.Sin(Lat * Math.Pi / 180))) / 2)
End Function
And in C#:
public uint lonToX(double lon, uint zoom) {
uint offset = 256 << (zoom - 1);
return Math.Round(offset + (offset * lon / 180));
}
public uint latToY(double lat, uint zoom) {
uint offset = 256 << (zoom - 1);
return Math.Round(offset - offset / Math.Pi * Math.Log((1 + Math.Sin(lat * Math.Pi / 180)) / (1 - Math.Sin(lat * Math.Pi / 180))) / 2);
}