给定行数、列数和起点创建坐标网格
Create coordinate grid given number of rows, columns and starting point
我需要一些帮助来将 lat/lon 对外推到方形网格。网格是 200x200 个单元格。每个单元格为 1NM*1NM。起始 lat/lon 对是网格的西南角。
例如,第0列和第0行应该是前四个坐标对,以构成第一个1NM*1NM的网格单元。第 0 列第 1 行应该是接下来的四个坐标对,以使下一个网格单元格位于第一个网格单元格之上。 200行后,移动到下一列等
我尝试使用以下 PHP 代码进行此操作,但我似乎无法正确推断数据。
<?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;
}
有一个解决这个问题的捷径,即认识到 1NM 是 "equal to" 1/60 度。我说 "equal to" 是因为这是一个古老的定义,没有经过非常精确的现代测量,但仍然有用。
坐标随着您向 N 和 E 移动而增加。这意味着向东移动 1 海里或向北移动 1 海里(对应于您的 1 海里网格),您只需将相应坐标增加 1/60 度。
例如,如果您从
开始
//西南坐标对(起点)
$lat = 38.883672;
$lon = -105.698848;
向北移动 1 海里(1 个方格)
$lat[1] = 38.883672 + .016667; // 38.900339
向东移动 1NM(1 个方格)
$lon[1] = -105.698848 + .016667; // -105.682181
因此,使用它,您只需递增即可轻松构建 200x200 的网格。
右上角的网格坐标为:
向北移动 200 海里(200 个方格)
$lat[1] = 38.883672 + .016667*200; // 42.217072
向东移动 200NM(200 方格)
$lon[1] = -105.698848 + .016667*200; // -102.365448
此外,如果您想构建网格,最好将其存储在二维数组中,如下所示:
<?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);
}
现在,如果您更喜欢使用自己的方法来计算偏移量,您只需修改 extrapolate()
函数即可。
编辑:应要求添加。
一旦你有了上面的数组,你就可以选择每个单元格周围的坐标,如下所示。例如,将选择底部的 SW 单元格。它的4个坐标对是:
// 西南角
$coords[0][0]["lat"];
$coords[0][0]["lon"];
// 西北角
$coords[0][1]["lat"];
$coords[0][1]["lon"];
// 东南角
$coords[1][0]["lat"];
$coords[1][0]["lon"];
// 东北角
$coords[1][1]["lat"];
$coords[1][1]["lon"];
再举一个例子,会选择最上面的网元小区。它的4个坐标对是:
// 西南角
$coords[198][198]["lat"];
$coords[198][198]["lon"];
// 西北角
$coords[198][199]["lat"];
$coords[198][199]["lon"];
// 东南角
$coords[199][198]["lat"];
$coords[199][198]["lon"];
// 东北角
$coords[199][199]["lat"];
$coords[199][199]["lon"];
这有帮助吗?
我需要一些帮助来将 lat/lon 对外推到方形网格。网格是 200x200 个单元格。每个单元格为 1NM*1NM。起始 lat/lon 对是网格的西南角。
例如,第0列和第0行应该是前四个坐标对,以构成第一个1NM*1NM的网格单元。第 0 列第 1 行应该是接下来的四个坐标对,以使下一个网格单元格位于第一个网格单元格之上。 200行后,移动到下一列等
我尝试使用以下 PHP 代码进行此操作,但我似乎无法正确推断数据。
<?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;
}
有一个解决这个问题的捷径,即认识到 1NM 是 "equal to" 1/60 度。我说 "equal to" 是因为这是一个古老的定义,没有经过非常精确的现代测量,但仍然有用。
坐标随着您向 N 和 E 移动而增加。这意味着向东移动 1 海里或向北移动 1 海里(对应于您的 1 海里网格),您只需将相应坐标增加 1/60 度。
例如,如果您从
开始//西南坐标对(起点)
$lat = 38.883672;
$lon = -105.698848;
向北移动 1 海里(1 个方格)
$lat[1] = 38.883672 + .016667; // 38.900339
向东移动 1NM(1 个方格)
$lon[1] = -105.698848 + .016667; // -105.682181
因此,使用它,您只需递增即可轻松构建 200x200 的网格。
右上角的网格坐标为:
向北移动 200 海里(200 个方格)
$lat[1] = 38.883672 + .016667*200; // 42.217072
向东移动 200NM(200 方格)
$lon[1] = -105.698848 + .016667*200; // -102.365448
此外,如果您想构建网格,最好将其存储在二维数组中,如下所示:
<?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);
}
现在,如果您更喜欢使用自己的方法来计算偏移量,您只需修改 extrapolate()
函数即可。
编辑:应要求添加。
一旦你有了上面的数组,你就可以选择每个单元格周围的坐标,如下所示。例如,将选择底部的 SW 单元格。它的4个坐标对是:
// 西南角
$coords[0][0]["lat"];
$coords[0][0]["lon"];
// 西北角
$coords[0][1]["lat"];
$coords[0][1]["lon"];
// 东南角
$coords[1][0]["lat"];
$coords[1][0]["lon"];
// 东北角
$coords[1][1]["lat"];
$coords[1][1]["lon"];
再举一个例子,会选择最上面的网元小区。它的4个坐标对是:
// 西南角
$coords[198][198]["lat"];
$coords[198][198]["lon"];
// 西北角
$coords[198][199]["lat"];
$coords[198][199]["lon"];
// 东南角
$coords[199][198]["lat"];
$coords[199][198]["lon"];
// 东北角
$coords[199][199]["lat"];
$coords[199][199]["lon"];
这有帮助吗?