Вращение векторного слоя в QGIS с помощью qgsAffine (или другого метода)?

10

Я хотел бы повернуть набор векторных точек в QGIS на произвольное количество градусов вокруг центральной точки (или произвольной точки).

Это похоже на недавний вопрос о создании регулярной сетки ; там было предложено использовать инструмент «Аффинная трансформация» (который, я полагаю, имел в виду плагин), чтобы вращать или сдвигать сетку точек на произвольный угол или расстояние. Я подозреваю, что не понимаю, как это работает, и не смог заставить его работать.

Я создаю регулярную сетку точек в QGIS и гарантирую, что зона UTM установлена ​​правильно как для слоя, так и для проекта, включаю редактирование для слоя, затем открываю диалоговое окно плагина (qgsAffine): Диалог аффинного преобразования

Я выбираю «весь слой» и затем, желая повернуть все поле точек на 15 °, помещаю 15 в оба поля «вращения» (которые могут быть там, где что-то идет не так). Результатом операции является вращение точек где-то вне планеты!

Это правильный инструмент для работы? Я хотел бы повернуть набор точек относительно их общего центра, в идеале.

Обновление : qgsAffine - просто мысль; если мы сможем сделать это в любом инструменте QGIS, я буду счастлив!

Обновление 2 : qgsAffine можно использовать, если вы знаете правильные номера для подключения (см. Ответ ниже, спасибо, Майк!). Электронная таблица / калькулятор работает нормально, или вот функция R, чтобы получить числа напрямую:

## Compute correct affine numbers for qgsAffine plugin
affine <- function(originX, originY, rotAngle) {
  A <- rotAngle * pi / 180
  scaleX <- scaleY <- cos(A)
  rotX <- sin(A)
  rotY <- -sin(A)
  transX <- originX - cos(A) * originX + sin(A) * originY
  transY <- originY - sin(A) * originX - cos(A) * originY
  aff <- data.frame(scaleX, scaleY, rotX, rotY, transX, transY)
  return(aff)
}

Итак, чтобы повернуть сетку точек в северной части Уганды (UTM 36N), affine(578988, 419210, 30)получим:

     scaleX    scaleY rotX rotY   transX    transY
1 0.8660254 0.8660254  0.5 -0.5 287174.7 -233330.5

... который, введенный в диалоге qgsAffine, корректно поворачивает точки.

Simbamangu
источник
хорошая адаптация R!
Майк Т

Ответы:

10

Вы можете сделать это в PostGIS, используя ST_Affine . Функциональность для поворота вокруг произвольной точки была добавлена ​​в ST_Rotate для PostGIS 2.0.

Если у вас есть более ранняя версия (например, PostGIS 1.5 или даже более ранняя), вы можете добавить эти функции:

CREATE OR REPLACE FUNCTION st_rotate(geometry, double precision, geometry)
  RETURNS geometry AS
'SELECT ST_Affine($1,  cos($2), -sin($2), 0,  sin($2),  cos($2), 0, 0, 0, 1, ST_X($3) - cos($2) * ST_X($3) + sin($2) * ST_Y($3), ST_Y($3) - sin($2) * ST_X($3) - cos($2) * ST_Y($3), 0)'
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;
COMMENT ON FUNCTION st_rotate(geometry, double precision, geometry) IS 'args: geomA, rotRadians, pointOrigin - Rotate a geometry rotRadians counter-clockwise about an origin.';

CREATE OR REPLACE FUNCTION st_rotate(geometry, double precision, double precision, double precision)
  RETURNS geometry AS
'SELECT ST_Affine($1,  cos($2), -sin($2), 0,  sin($2),  cos($2), 0, 0, 0, 1,    $3 - cos($2) * $3 + sin($2) * $4, $4 - sin($2) * $3 - cos($2) * $4, 0)'
  LANGUAGE sql IMMUTABLE STRICT
  COST 100;
COMMENT ON FUNCTION st_rotate(geometry, double precision, double precision, double precision) IS 'args: geomA, rotRadians, x0, y0 - Rotate a geometry rotRadians counter-clockwise about an origin.';

Посмотрите примеры в ST_Rotate, чтобы получить представление о том, как использовать его для поворота геометрии вокруг точки x , y , включая центроид (общий центр).

Поскольку нам всем нравится математика, матрица преобразования из вышеперечисленных функций представляется в виде:

[ cos(θ)  | -sin(θ)  ||  x0 - cos(θ) * x0 + sin(θ) * y0 ]
[ sin(θ)  |  cos(θ)  ||  y0 - sin(θ) * x0 - cos(θ) * y0 ]

Где θ - вращение против часовой стрелки вокруг начала координат, x0 - восток / долгота исходной точки, а y0 - север / широта. Эта математика может быть адаптирована к любому инструменту аффинного преобразования.


Чтобы использовать инструмент qgsAffine, вам нужно понять, куда попадают значения матрицы. Хороший шаблон электронной таблицы также необходим для выполнения предварительных расчетов. Диалог qgsAffine выглядит примерно так:

              X   Y
            +---+---+
      Scale | a | e |
            +---+---+
   Rotation | d | b |
            +---+---+
Translation | c | f |
            +---+---+

где:

  • a : cos (θ)
  • b : -син (θ)
  • c : x0 - cos (θ) * x0 + sin (θ) * y0
  • д : грех (θ)
  • е : соз (θ)
  • f : y0 - грех (θ) * x0 - cos (θ) * y0

Например, если вы хотите повернуть многоугольник на 30 ° по часовой стрелке примерно на 42 ° S, 174 ° E, введите свои данные в таблицу:

  • х0 = 174
  • у0 = -42
  • θ = -30 градусов или -0,523598776 радиан

Затем скопируйте / вставьте результаты из электронной таблицы в правое поле. Используя порядок табуляции в диалоговом окне:

  • а: 0,866025404
  • д: -0,5
  • с: 44,31157974
  • е: 0,866025404
  • б: 0,5
  • f: 81.37306696

qgsAffine

Тот же пример из PostGIS будет выглядеть примерно так:

SELECT ST_Rotate(geom, -30*pi()/180, 174.0, -42.0)
Майк Т
источник
Это выглядит довольно хорошо; если мы можем сделать это в Spatialite, это будет квалифицироваться как «делать это в QGIS», поскольку мы можем запускать SQL для файлов Spatialite через плагины QGIS; PostGIS станет еще одним целым этапом установки для пользователей, в которые я не хочу входить. Есть идеи, если какие-либо функции для пространственного объекта могут вращаться и вокруг центроида?
Симбамангу
ага, я демистифицировал qgsAffine, теперь работает как положено ... просто много копий / вставок из электронной таблицы
Mike T
Майк, это работает как раз правильно! Я собираюсь попытаться заставить эту работу также работать со Spatialite (PostGIS /atialite, кажется, значительно упрощает эти операции), но, по крайней мере, теперь я могу заставить работать qgsAffine, и это, по крайней мере, простой плагин.
Симбамангу
Я пытался адаптировать его к JavaScript: смотрите здесь , также jsfiddle
flackend
1
Вычисление функции javascript выше Я смог успешно рассчитать свои аффинные параметры и повернуть векторы сома, но это не так удобно: вам нужно использовать плагин захвата координат, чтобы получить координаты центра вращения, затем вычислить параметры преобразования и скопировать и вставить обратно в QGIS! Было бы намного проще, если бы плагин сам делал вычисления, а пользователи просто нажимали, чтобы ввести координаты центра вращения и определить угол поворота.
Брадип
2

Я никогда не пытался вращать векторные слои, используя qgsAffine, и я думаю, что я не одинок. Этот вопрос недавно возник на форуме QGIS, и было найдено решение с использованием (бесплатного) OpenJump. Посмотрите на эту ветку (ближе к концу):

http://forum.qgis.org/viewtopic.php?f=2&t=10126&sid=28473d53d244a4cd2a6f91887811ef02

Конечно, вы также можете использовать этот инструмент просто для ротации ваших данных.

nhopton
источник