I'm trying to convert an Open Street Maps latitude/longitude into a pixel position. I found this example in java. When I convert the code to Delphi, the X result is correct, but the Y result is slightly out.
Java Code:
double lon = -89.08805;
double lat = 30.6393;
double zoom = 6; // 6.5156731549786215 would be possible too
double lon_rad = Math.toRadians(lon);
double lat_rad = Math.toRadians(lat);
double n = Math.pow(2.0, zoom);
double tileX = ((lon + 180) / 360) * n;
double tileY = (1 - (Math.log(Math.tan(lat_rad) + 1.0/Math.cos(lat_rad)) / Math.PI)) * n / 2.0;
System.out.println("tileX = "+tileX+" tileY = "+tileY);
Delphi Code:
function LatLngToTilePixels(Lat, Lng: Double; ZoomLevel: Integer): TPointF;
var
lon_rad, lat_rad, n: Double;
TileX, TileY: Double;
begin
lon_rad := DegToRad(Lng);
lat_rad := DegToRad(Lat);
n := Power(2.0, ZoomLevel);
Result.X := ((Lng + 180) / 360) * n;
Result.Y := (1 - (Math.Log10(Math.tan(lat_rad) + 1.0/cos(lat_rad)) / PI)) * n / 2.0;
end;
The results, using the inputs given in the example (lat=30.6393, lng=-89.08805, zoom=6) are:
JAVA:
tileX = 16.162124444444444
tileY = 26.273150713795616
Delphi:
tileX=16.1621244444444
tileY = 29.5128609563099 <--- wrong result
I have a feeling that the problem may be the math.log call. JAVA uses log, but Delphi uses log10. I have tried log2, but the result is even worse.
You use logarithms of different bases:
Java: base e
, i.e. the natural logarithm, see Math.log(double)
Delphi: Obviously base 10
You can use the following formula to calculate the logarithm to a base that is not supported:
log_a(b) = log_x(b) / log_x(a)
AFAIK there is a Ln
function in delphi, that calculates the natural logarithm, at least it's listed here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With