I need some help with extrapolating a lat/lon pair to a square grid. The grid is 200x200 cells. Each cell is 1NM*1NM. The starting lat/lon pair is the southwest corner of the grid.
For example, column 0 and row 0 should be the first four coordinate pairs to make the first grid cell that is 1NM*1NM. Column 0 row 1 should be the next four coordinate pairs to make the next grid cell above the first one. After 200 rows, move to the next column, etc.
I have attempted this using the following PHP code, but I can't seem to extrapolate the data correctly.
<?php
header('Content-Type:text/plain');
// southwest coordinate pair (starting point)
$lat = 38.883672;
$lon = -105.698848;
for($col = 0; $col < 200; $col++) {
$startLat = $startLat2 = 0;
$startLon = $startLon2 = 0;
if($col > 0) {
$lat = Extrapolate($lat, $lon, 1.0, 90)[0];
$lon = Extrapolate($lat, $lon, 1.0, 90)[1];
}
$debug = sprintf("%s,%s\r\n", $lat, $lon);
for($row = 0; $row < 200; $row++) {
if($row == 0) {
$startLat = Extrapolate($lat, $lon, 1.0, 360)[0];
$startLon = Extrapolate($lat, $lon, 1.0, 360)[1];
$startLat2 = Extrapolate($lat, $lon, 1.0, 90)[0];
$startLon2 = Extrapolate($lat, $lon, 1.0, 90)[1];
$nextLat = $startLat;
$nextLon = $startLon;
$nextLat2 = $startLat2;
$nextLon2 = $startLon2;
$debug .= sprintf("%s,%s\r\n", $startLat, $startLon);
$debug .= sprintf("%s,%s\r\n", $startLat2, $startLon2);
}
else {
$nextLat = Extrapolate($nextLat, $nextLon, 1.0, 360)[0];
$nextLon = Extrapolate($nextLat, $nextLon, 1.0, 360)[1];
$nextLat2 = Extrapolate($nextLat2, $nextLon2, 1.0, 90)[0];
$nextLon2 = Extrapolate($nextLat2, $nextLon2, 1.0, 90)[1];
$debug .= sprintf("%s,%s\r\n", $nextLat, $nextLon);
$debug .= sprintf("%s,%s\r\n", $nextLat2, $nextLon2);
}
}
echo $debug;
}
function Extrapolate($lat1,$long1,$d,$angle)
{
# Earth Radious in KM
$R = 6378.14;
# Degree to Radian
$latitude1 = $lat1 * (M_PI/180);
$longitude1 = $long1 * (M_PI/180);
$brng = $angle * (M_PI/180);
# Distance to NM
$d *= 1.85200;
$latitude2 = asin(sin($latitude1)*cos($d/$R) + cos($latitude1)*sin($d/$R)*cos($brng));
$longitude2 = $longitude1 + atan2(sin($brng)*sin($d/$R)*cos($latitude1),cos($d/$R)-sin($latitude1)*sin($latitude2));
# back to degrees
$latitude2 = $latitude2 * (180/M_PI);
$longitude2 = $longitude2 * (180/M_PI);
$lat2 = round ($latitude2,6);
$long2 = round ($longitude2,6);
// Push in array and get back
$coords[0] = $lat2;
$coords[1] = $long2;
return $coords;
}
There is a shortcut way to solve this by recognising that the 1NM is "equal to" 1/60 of a degree. I say "equal to" because that is an old definition that has not survived very accurate modern measurements, but nevertheless is still useful.
Coordinates increase as you move N and E. This means to move 1NM East or 1NM North (corresponding to your 1NM grid), you only have to add 1/60 of a degree to the respective coordinate.
For example, if you start at
// southwest coordinate pair (starting point)
$lat = 38.883672;
$lon = -105.698848;
Move 1NM North (1 grid square)
$lat[1] = 38.883672 + .016667; // 38.900339
Move 1NM East (1 grid square)
$lon[1] = -105.698848 + .016667; // -105.682181
So using this you can easily build a grid 200x200 by just incrementing.
The top right hand grid corner would have coordinates:
Move 200NM North (200 grid squares)
$lat[1] = 38.883672 + .016667*200; // 42.217072
Move 200NM East (200 grid square)
$lon[1] = -105.698848 + .016667*200; // -102.365448
Also if you want to build a grid, this is best stored in a 2 dimensional array like as below:
<?php
//header('Content-Type:text/plain');
// southwest coordinate pair (starting point)
$lat = 38.883672;
$lon = -105.698848;
for ($col=0; $col< 200; $col++){
echo PHP_EOL."Grid values for col ".$col.PHP_EOL;
for ($row=0; $row< 200; $row++){
$newCoords = extrapolate($lat,$lon,$row,$col);
$coords[$col][$row]["lat"] = $newCoords["lat"];
$coords[$col][$row]["lon"] = $newCoords["lon"];
echo "Row ".$row." = ".$coords[$col][$row]["lat"]." , ";
echo $coords[$col][$row]["lon"].PHP_EOL;
}
}
function extrapolate($lat,$lon,$row,$col){
$newCoords["lat"] = round($lat + (1/60)*$row,6);
$newCoords["lon"] = round($lon + (1/60)*$col,6);
return ($newCoords);
}
Now if you prefer to use your own method to calculate the offsets you can just modify the extrapolate()
function.
EDIT: Add this at request.
Once you have the array above you can pick the coordinates surrounding each cell as follows. By example will will pick the bottom SW cell. Its 4 coordinate pairs are:
// SW corner
$coords[0][0]["lat"];
$coords[0][0]["lon"];
// NW corner
$coords[0][1]["lat"];
$coords[0][1]["lon"];
// SE corner
$coords[1][0]["lat"];
$coords[1][0]["lon"];
// NE corner
$coords[1][1]["lat"];
$coords[1][1]["lon"];
By another example will will pick the top NE cell. Its 4 coordinate pairs are:
// SW corner
$coords[198][198]["lat"];
$coords[198][198]["lon"];
// NW corner
$coords[198][199]["lat"];
$coords[198][199]["lon"];
// SE corner
$coords[199][198]["lat"];
$coords[199][198]["lon"];
// NE corner
$coords[199][199]["lat"];
$coords[199][199]["lon"];
Does this help?