Faire pivoter une couche vectorielle dans QGIS avec qgsAffine (ou une autre méthode)?


10

Je voudrais faire pivoter un ensemble de points vectoriels dans QGIS d'un nombre arbitraire de degrés autour d'un point central (ou point arbitraire).

Ceci est similaire à une question récente sur la création d'une grille régulière ; il a été suggéré d'utiliser l'outil "Transformation affine" (qui, je suppose, signifiait le plugin) pour faire pivoter ou déplacer une grille de points d'un angle ou d'une distance arbitraire. Je soupçonne que je ne comprends pas comment cela fonctionne et que je n'ai pas réussi à le faire fonctionner.

Je crée une grille régulière de points dans QGIS et je m'assure que la zone UTM est correctement définie pour la couche et le projet, j'active l'édition pour la couche, puis j'ouvre la boîte de dialogue du plugin (qgsAffine): Boîte de dialogue Transformation affine

Je sélectionne «calque entier», puis, voulant faire pivoter tout le champ de points de 15 °, j'en place 15 dans les deux cases «rotation» (qui peuvent être là où les choses tournent mal). L'opération entraîne la rotation des points quelque part hors de la planète!

Est-ce le bon outil pour le travail? Je voudrais faire pivoter un ensemble de points autour de leur centre commun, idéalement.

Mise à jour : qgsAffine n'est qu'une pensée; si nous pouvons le faire dans n'importe quel outil QGIS, je serai heureux!

Mise à jour 2 : qgsAffine est utilisable SI vous connaissez les bons numéros à brancher (voir réponse ci-dessous, merci Mike!). La feuille de calcul / calculatrice fonctionne bien, ou voici la fonction R pour obtenir les chiffres directement:

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

Ainsi, faire pivoter une grille de points dans le nord de l'Ouganda (UTM 36N), affine(578988, 419210, 30)donne:

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

... qui, entré dans la boîte de dialogue qgsAffine, fait pivoter correctement les points.


belle adaptation R!
Mike T

Réponses:


10

Vous pouvez le faire dans PostGIS en utilisant ST_Affine . La fonctionnalité de rotation autour d'un point arbitraire a été ajoutée à ST_Rotate pour PostGIS 2.0.

Si vous avez une version antérieure (comme PostGIS 1.5, ou même antérieure), vous pouvez ajouter ces fonctions:

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

Voir les exemples à ST_Rotate pour avoir une idée sur la façon de l'utiliser pour faire pivoter une géométrie autour d'un point x , y , y compris le centroïde (centre commun).

Parce que nous aimons tous les mathématiques, la matrice de transformation des fonctions ci-dessus est représentée comme suit:

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

θ est la rotation dans le sens antihoraire autour d'une origine, x0 est l'abscisse / longitude du point d'origine et y0 est l'ordonnée / latitude. Ces mathématiques pourraient éventuellement être adaptées à tout outil de transformation affine.


Pour utiliser l'outil qgsAffine, vous devez comprendre où vont les valeurs de la matrice. Un bon modèle de feuille de calcul est également requis pour effectuer les pré-calculs. La boîte de dialogue qgsAffine ressemble à ceci:

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

où:

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

Par exemple, si vous souhaitez faire pivoter un polygone de 30 ° dans le sens des aiguilles d'une montre autour de 42 ° S, 174 ° E, voici vos entrées dans votre feuille de calcul:

  • x0 = 174
  • y0 = -42
  • θ = -30 degrés ou -0,523598776 radians

Ensuite, copiez / collez les résultats d'une feuille de calcul dans la case de droite. En utilisant l'ordre de tabulation dans la boîte de dialogue:

  • un: 0,866025404
  • d: -0,5
  • c: 44.31157974
  • e: 0,866025404
  • b: 0,5
  • f: 81.37306696

qgsAffine

Le même exemple de PostGIS ressemblerait à ceci:

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

Cela semble assez bon; si nous pouvons le faire dans Spatialite, ce serait qualifié de «le faire dans QGIS» puisque nous pouvons exécuter SQL sur des fichiers Spatialite via des plugins QGIS; PostGIS serait une autre étape complète de l'installation pour les utilisateurs dans lesquels je ne veux pas entrer. Une idée si des fonctions de spatialite peuvent également tourner autour d'un centroïde?
Simbamangu

aha, j'ai démystifié qgsAffine, fonctionne comme prévu maintenant ... juste beaucoup de copier / coller à partir d'une feuille de calcul
Mike T

Mike, ça marche bien! Je vais également essayer de faire fonctionner cela avec Spatialite (PostGIS / spatialite semble rendre ces opérations beaucoup plus faciles) mais au moins maintenant je peux faire fonctionner qgsAffine et c'est, au moins, un plugin simple.
Simbamangu

J'ai essayé de l'adapter à JavaScript: voyez-le ici , aussi jsfiddle
flackend

1
En calculant la fonction javascript ci-dessus, j'ai pu calculer mes paramètres affines et faire pivoter certains vecteurs avec succès, mais ce n'est pas si convivial: vous devez utiliser le plug-in de capture de coordonnées pour obtenir les coordonnées du centre de rotation, puis calculer les paramètres de transformation et copier et coller à QGis! Ce serait beaucoup plus simple si le plugin lui-même faisait les calculs et que les utilisateurs cliquaient simplement pour entrer les coordonnées du centre de rotation et définir un angle de rotation.
bradypus

2

Je n'ai jamais essayé de faire pivoter les couches vectorielles à l'aide de qgsAffine et je pense que je ne suis pas seul. Cette question a été posée récemment sur le forum QGIS et une solution a été trouvée, en utilisant (gratuitement) OpenJump. Jetez un oeil à ce fil (vers la fin):

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

Bien sûr, vous pouvez également utiliser cet outil juste pour faire une simple rotation de vos données.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.