How do I convert latitude and longitude to gisgeography world map pixel locations?
GitHub CoPilot suggested
function LatLonToPixelXY(float $latitude, float $longitude, int $mapWidth, int $mapHeight): array
{
$x = ($longitude + 180) * ($mapWidth / 360);
$y = ((-1 * $latitude) + 90) * ($mapHeight / 180);
return array((int)floor($x), (int)floor($y));
}
which is not very far off, but when I give it lat=34.3529 lon=62.2040 which is somewhere in Herat, Afghanistan, it gives me x=4709;y=1082; , and that pixel is somewhere in a nearby country Kazakhstan.. Suggestions?
<?php
declare(strict_types=1);
use function var_dump as d;
use function var_export as e;
function LatLonToPixelXY(float $latitude, float $longitude, int $mapWidth, int $mapHeight): array
{
$x = ($longitude + 180) * ($mapWidth / 360);
$y = ((-1 * $latitude) + 90) * ($mapHeight / 180);
return array((int)floor($x), (int)floor($y));
}
$map = file_get_contents('https://gisgeography.com/wp-content/uploads/2022/04/High-Resolution-World-Map.jpg');
$map = imagecreatefromstring($map);
$mapWidth = imagesx($map); // 7000
$mapHeight = imagesy($map); // 3500
// somewhere in Herat, Afghanistan:
$lat = 34.3529;
$lon = 62.2040;
list($x, $y) = LatLonToPixelXY($lat, $lon, $mapWidth, $mapHeight);
/*
I get:
array (
'x' => 4709,
'y' => 1082,
'lat' => 34.3529,
'lon' => 62.204,
)
Which is somewhere in the nearby country Kazakhstan
*/
$color = imagecolorallocate($map, 255, 0, 0);
imagefilledrectangle($map, $x - 2, $y - 2, $x + 2, $y + 2, $color);
$color = imagecolorallocate($map, 255, 255, 255);
imagestring($map, 4, $x, $y, "Herat, Afghanistan?", $color);
imagejpeg($map, "map.jpg", 100);
through Trial-and-error i've found
$y = ((-1 * $latitude) + 90) * ($mapHeight / 127);
to be closer, but it's still not accurate, running the code
$points_of_interest = array(
array(
"name" => "Eiffel Tower",
"lat" => 48.8584,
"lon" => 2.2945,
),
array(
"name" => "Statue of Liberty",
"lat" => 40.6892,
"lon" => -74.0445,
),
array(
"name" => "Big Ben",
"lat" => 51.5007,
"lon" => -0.1246,
),
);
$red = imagecolorallocate($map, 255, 0, 0);
$white = imagecolorallocate($map, 255, 255, 255);
foreach ($points_of_interest as $point) {
$lat = $point['lat'];
$lon = $point['lon'];
list($x, $y) = LatLonToPixelXY1($lat, $lon, $mapWidth, $mapHeight);
imagefilledrectangle($map, $x - 2, $y - 2, $x + 2, $y + 2, $red);
imagestring($map, 1, $x + 3, $y + 3, "algo1: " . $point['name'], $red);
$lat = $point['lat'];
$lon = $point['lon'];
list($x, $y) = LatLonToPixelXY2($lat, $lon, $mapWidth, $mapHeight);
imagefilledrectangle($map, $x - 2, $y - 2, $x + 2, $y + 2, $red);
imagestring($map, 1, $x + 3, $y + 3, "algo 2: " . $point['name'], $red);
d([
'name' => $point['name'],
'lat' => $lat,
'lon' => $lon,
'x' => $x,
'y' => $y,
//'point' => $point,
]);
}
it's an improvement, but it's still off..

