0

我需要一些帮助来将纬度/经度对推断为方形网格。网格是 200x200 单元格。每个单元格为 1NM*1NM。起始纬度/经度对是网格的西南角。

例如,第 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;
 }
4

1 回答 1

0

通过识别 1NM“等于”1/60 度,有一个捷径可以解决这个问题。我说“等于”是因为这是一个古老的定义,它没有在非常精确的现代测量中幸存下来,但仍然有用。

当您移动 N 和 E 时,坐标会增加。这意味着向东移动 1NM 或向北移动 1NM(对应于您的 1NM 网格),您只需将 1/60 度数添加到相应的坐标。

例如,如果您从

// 西南坐标对(起点)

$lat = 38.883672;
$lon = -105.698848;

向北移动 1NM(1 个方格)

$lat[1] = 38.883672 + .016667; // 38.900339

向东移动 1NM(1 个方格)

$lon[1] = -105.698848 + .016667; // -105.682181

因此,使用它,您只需递增即可轻松构建 200x200 的网格。

右上角的网格角将具有坐标:

向北移动 200NM(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"];

// SE 角

$coords[1][0]["lat"];
$coords[1][0]["lon"];

// 东北角

$coords[1][1]["lat"];
$coords[1][1]["lon"];

通过另一个示例将选择顶部的 NE 单元。它的 4 个坐标对是:

// 西南角

$coords[198][198]["lat"];
$coords[198][198]["lon"];

// 西北角

$coords[198][199]["lat"];
$coords[198][199]["lon"];

// SE 角

$coords[199][198]["lat"];
$coords[199][198]["lon"];

// 东北角

$coords[199][199]["lat"];
$coords[199][199]["lon"];

这有帮助吗?

于 2018-10-05T01:12:52.143 回答