¿Rotando una capa vectorial en QGIS con qgsAffine (u otro método)?

10

Me gustaría rotar un conjunto de puntos vectoriales en QGIS un número arbitrario de grados alrededor de un punto central (o punto arbitrario).

Esto es similar a una pregunta reciente sobre la creación de una cuadrícula regular ; se sugirió utilizar la herramienta "Transformación afín" (que supongo que significa el complemento) para rotar o desplazar una cuadrícula de puntos en un ángulo o distancia arbitrario. Sospecho que no entiendo cómo funciona y no he podido hacer que funcione.

Creo una cuadrícula regular de puntos en QGIS y me aseguro de que la zona UTM esté configurada correctamente tanto para la capa como para el proyecto, habilito la edición de la capa y luego abro el cuadro de diálogo del complemento (qgsAffine): Diálogo de transformación afín

Selecciono 'capa completa' y luego, queriendo rotar todo el campo de puntos en 15 °, pongo 15 en ambos cuadros de 'rotación' (que puede ser donde las cosas van mal). ¡La operación da como resultado la rotación de los puntos en algún lugar fuera del planeta!

¿Es esta la herramienta adecuada para el trabajo? Me gustaría rotar un conjunto de puntos sobre su centro común, idealmente.

Actualización : qgsAffine es solo un pensamiento; si podemos hacer esto en cualquier herramienta QGIS, ¡estaré feliz!

Actualización 2 : qgsAffine es utilizable SI conoce los números correctos para enchufar (vea la respuesta a continuación, ¡gracias Mike!). La hoja de cálculo / calculadora funciona bien, o aquí está la función R para obtener los números directamente:

## 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)
}

Entonces, para rotar una cuadrícula de puntos en el norte de Uganda (UTM 36N), se affine(578988, 419210, 30)obtiene:

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

... que, ingresado en el cuadro de diálogo qgsAffine, rota los puntos correctamente.

Simbamangu
fuente
buena adaptación R!
Mike T

Respuestas:

10

Puede hacer esto en PostGIS usando ST_Affine . La funcionalidad para rotar alrededor de un punto arbitrario se agregó a ST_Rotate para PostGIS 2.0.

Si tiene una versión anterior (como PostGIS 1.5, o incluso anterior), puede agregar estas funciones:

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.';

Vea ejemplos en ST_Rotate para tener una idea de cómo usarlo para rotar una geometría alrededor de un punto x , y , incluido el centroide (centro común).

Como a todos nos gustan las matemáticas, la matriz de transformación de las funciones anteriores se representa como:

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

Donde θ es la rotación en sentido antihorario sobre un origen, x0 es el Este / Longitud del punto de origen, y y0 es el Norte / Latitud. Esta matemática posiblemente podría adaptarse a cualquier herramienta de transformación afín.


Para usar la herramienta qgsAffine, debe comprender hacia dónde fluyen los valores de la matriz. También se requiere una buena plantilla de hoja de cálculo para hacer cálculos previos. El diálogo qgsAffine se ve así:

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

dónde:

  • a : cos (θ)
  • b : -sin (θ)
  • c : x0 - cos (θ) * x0 + sin (θ) * y0
  • d : pecado (θ)
  • e : cos (θ)
  • f : y0 - sin (θ) * x0 - cos (θ) * y0

Por ejemplo, si desea rotar un polígono 30 ° en el sentido de las agujas del reloj alrededor de 42 ° S, 174 ° E, estas son sus entradas en su hoja de cálculo:

  • x0 = 174
  • y0 = -42
  • θ = -30 grados o -0.523598776 radianes

Luego, copie / pegue los resultados de una hoja de cálculo en el cuadro de la derecha. Usando el orden de tabulación en el cuadro de diálogo:

  • a: 0.866025404
  • d: -0,5
  • c: 44.31157974
  • e: 0.866025404
  • b: 0.5
  • f: 81.37306696

qgsAffine

El mismo ejemplo de PostGIS se vería así:

SELECT ST_Rotate(geom, -30*pi()/180, 174.0, -42.0)
Mike T
fuente
Eso se ve bastante bien; si podemos hacer eso en Spatialite, calificaría como 'hacerlo en QGIS' ya que podemos ejecutar SQL en archivos de Spatialite a través de complementos QGIS; PostGIS sería otro paso completo en la instalación para usuarios en los que no quiero entrar. ¿Alguna idea de si alguna función para spaceialite también puede rotar alrededor de un centroide?
Simbamangu
aha, desmitifiqué qgsAffine, funciona como se esperaba ahora ... solo mucha copia / pegado de una hoja de cálculo
Mike T
Mike, ¡eso funciona bien! También intentaré hacer que esto funcione con Spatialite (PostGIS / spatialite parece hacer que estas operaciones sean mucho más fáciles), pero al menos ahora puedo hacer que qgsAffine funcione y, al menos, es un complemento sencillo.
Simbamangu
Traté de adaptarlo a JavaScript: verlo aquí , también jsfiddle
flackend
1
Al calcular la función de JavaScript anterior, pude calcular mis parámetros afines y rotar algunos vectores con éxito, pero esto no es tan fácil de usar: debe usar el complemento de captura de coordenadas para obtener las coordenadas del centro de rotación, luego calcular los parámetros de transformación y copiar y pegar de nuevo en QGis! Sería mucho más simple si el plugin hiciera los cálculos y los usuarios simplemente hicieran clic para ingresar las coordenadas del centro de rotación y definir un ángulo de rotación.
bradypus
2

Nunca llegué a ningún lugar tratando de rotar capas vectoriales usando qgsAffine y creo que no estoy solo. Esta pregunta surgió recientemente en el foro QGIS y se encontró una solución, usando OpenJump (gratis). Echa un vistazo a este hilo (hacia el final):

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

Por supuesto, también podría usar esta herramienta solo para hacer una rotación simple de sus datos.

nhopton
fuente