Создать координатную сетку с учетом количества строк, столбцов и начальной точки

Мне нужна помощь с экстраполяцией пары широта / долгота в квадратную сетку. Сетка 200х200 ячеек. Каждая ячейка 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;
 }

1 ответ

Решение

Существует быстрый способ решить эту проблему, признав, что 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 пары координат:

// SW уголок

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

// NE угол

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

По другому примеру выберут верхнюю ячейку NE. Его 4 пары координат:

// SW уголок

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

// NE угол

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

Это помогает?

Другие вопросы по тегам