How to convert latitude and longitude to gisgeography world map pixel locations?

96 Views Asked by At

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);

enter image description here

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,
    ]);
}

generates enter image description here

it's an improvement, but it's still off..

0

There are 0 best solutions below