Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Math functions in JAVA and Delphi give different results

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.

like image 271
norgepaul Avatar asked Dec 26 '22 05:12

norgepaul


1 Answers

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.

like image 66
fabian Avatar answered Dec 28 '22 05:12

fabian