给定行数、列数和起点创建坐标网格

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"];

这有帮助吗?