使用qgsAffine(或其他方法)在QGIS中旋转矢量层?


10

我想围绕中心点(或任意点)将QGIS中的一组矢量点旋转任意角度。

这类似于最近关于创建规则网格的问题 ; 建议在那里使用“仿射变换”工具(我认为是插件)来旋转或移动任意角度或距离的点网格。我怀疑我不了解它是如何工作的,并且无法使其正常工作。

我在QGIS中创建了规则的点网格,并确保为图层和项目都正确设置了UTM区域,对图层进行编辑,然后打开插件对话框(qgsAffine): 仿射变换对话框

我选择“整个图层”,然后将点的整个字段旋转15°,在两个“旋转”框中都放入15(这可能是问题所在)。该操作导致将点旋转到不在行星上!

这是工作的正确工具吗?理想情况下,我想围绕它们的共同中心旋转一组点。

更新:qgsAffine只是一个想法;如果我们可以在任何 QGIS工具中做到这一点,我将很高兴!

更新2:如果您知道要插入的正确数字,则qgsAffine可用(请参阅下面的答案,谢谢Mike!)。电子表格/计算器可以正常工作,或者使用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对话框中,可以正确旋转点。


不错的R适应!
Mike T

Answers:


10

您可以使用ST_Affine在PostGIS中执行此操作。用于PostGIS 2.0的ST_Rotate已添加了绕任意点旋转的功能。

如果您使用的是较早的版本(例如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上的示例,以了解如何使用它围绕xy点(包括质心(公共中心))旋转几何的想法。

因为我们都喜欢数学,所以上述函数的转换矩阵表示为:

[ 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:-sin(θ)
  • c:x0-cos(θ)* x0 + sin(θ)* y0
  • d:正弦(θ)
  • e:cos(θ)
  • f:y0-sin(θ)* x0-cos(θ)* y0

例如,如果您想绕42°S,174°E顺时针旋转多边形30°,这是您对电子表格的输入:

  • x0 = 174
  • y0 = -42
  • θ = -30度或-0.523598776弧度

然后,将结果从电子表格复制/粘贴到右侧框中。在对话框中使用制表符顺序:

  • 一个:0.866025404
  • d:-0.5
  • c:44.31157974
  • e:0.866025404
  • b:0.5
  • 传真:81.37306696

qgsAffine

来自PostGIS的相同示例如下所示:

SELECT ST_Rotate(geom, -30*pi()/180, 174.0, -42.0)

看起来不错;如果我们能够在Spatialite中做到这一点,就可以称为“在QGIS中做到”,因为我们可以通过QGIS插件在Spatialite文件上运行SQL;对于我不想接触的用户,PostGIS将是安装的又一整步。是否知道spacespaceite的任何功能也可以围绕质心旋转?
Simbamangu 2012年

啊哈,我揭开了qgsAffine的神秘面纱,现在可以按预期工作了……不过只是从电子表格中进行了大量复制/粘贴
Mike T

迈克,那很好!我也将尝试使用Spatialite进行此工作(PostGIS / spatialite似乎使这些操作非常容易),但至少现在我可以使qgsAffine正常工作,并且至少是一个简单的插件。
Simbamangu 2012年

我试图使其适应JavaScript:在这里也可以看到jsfiddle
flackend 2012年

1
通过计算上面的javascript函数,我能够成功计算出仿射参数并成功旋转som向量,但这并不是那么用户友好:您必须使用Coordinate capture插件获取旋转中心坐标,然后计算转换参数并将其复制并粘贴回QGis!如果插件本身进行了计算,并且用户只需单击以输入旋转中心坐标并定义旋转角度,那就简单得多。
bradypus 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.