Rotazione di un livello vettoriale in QGIS con qgsAffine (o altro metodo)?


10

Vorrei ruotare una serie di punti vettoriali in QGIS di un numero arbitrario di gradi attorno a un punto centrale (o punto arbitrario).

Questo è simile a una recente domanda sulla creazione di una griglia regolare ; è stato suggerito di utilizzare lo strumento "Trasformazione affine" (che presumo significasse il plugin) per ruotare o spostare una griglia di punti di un angolo o distanza arbitraria. Sospetto di non capire come funziona e non sono stato in grado di farlo funzionare.

Creo una griglia regolare di punti in QGIS e mi assicuro che la zona UTM sia impostata correttamente sia per il livello che per il progetto, abilito la modifica per il livello, quindi apro la finestra di dialogo del plugin (qgsAffine): Finestra di dialogo Trasformazione affine

Seleziono 'intero strato' e quindi, volendo ruotare l'intero campo di punti di 15 °, inserisco 15 in entrambe le caselle 'rotazione' (che possono essere dove le cose vanno male). L'operazione comporta la rotazione dei punti da qualche parte fuori dal pianeta!

È questo lo strumento giusto per il lavoro? Vorrei ruotare una serie di punti sul loro centro comune, idealmente.

Aggiornamento : qgsAffine è solo un pensiero; se riusciamo a farlo in qualsiasi strumento QGIS, saremo felici!

Aggiornamento 2 : qgsAffine è utilizzabile SE conosci i numeri giusti da collegare (vedi risposta sotto, grazie Mike!). Foglio di calcolo / calcolatrice funziona bene, oppure ecco la funzione R per ottenere direttamente i numeri:

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

Quindi, per ruotare una griglia di punti nell'Uganda settentrionale (UTM 36N), si affine(578988, 419210, 30)ottiene:

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

... che, inserito nella finestra di dialogo qgsAffine, ruota correttamente i punti.


bel adattamento R!
Mike T

Risposte:


10

Puoi farlo in PostGIS usando ST_Affine . La funzionalità per ruotare attorno a un punto arbitrario è stata aggiunta a ST_Rotate per PostGIS 2.0.

Se hai una versione precedente (come PostGIS 1.5 o anche precedente), puoi aggiungere queste funzioni:

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

Vedi esempi su ST_Rotate per avere un'idea su come usarlo per ruotare una geometria attorno ad un punto x , y , incluso il centroide (centro comune).

Poiché a tutti noi piace la matematica, la matrice di trasformazione delle funzioni sopra è rappresentata come:

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

Dove θ è la rotazione in senso antiorario attorno a un'origine, x0 è la direzione est / longitudine del punto di origine e y0 è la direzione nord / latitudine. Questa matematica potrebbe eventualmente essere adattata a qualsiasi strumento di trasformazione affine.


Per utilizzare lo strumento qgsAffine, è necessario capire dove fluiscono i valori della matrice. Per eseguire i pre-calcoli è necessario anche un buon modello di foglio di calcolo. La finestra di dialogo qgsAffine è simile alla seguente:

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

dove:

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

Ad esempio, se vuoi ruotare un poligono di 30 ° in senso orario attorno a 42 ° S, 174 ° E, ecco i tuoi input al foglio di calcolo:

  • x0 = 174
  • y0 = -42
  • θ = -30 gradi o -0,523598776 radianti

Quindi, copia / incolla i risultati da un foglio di calcolo nella casella a destra. Utilizzando l'ordine delle schede nella finestra di dialogo:

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

qgsAffine

Lo stesso esempio di PostGIS sarebbe simile a:

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

Sembra piuttosto buono; se riusciamo a farlo in Spatialite si qualificherebbe come "farlo in QGIS" poiché possiamo eseguire SQL su file Spatialite tramite plugin QGIS; PostGIS rappresenterebbe un altro passo nell'installazione per gli utenti a cui non voglio partecipare. Qualche idea se qualche funzione per la spazialite può ruotare anche attorno a un centroide?
Simbamangu,

aha, ho demistificato qgsAffine, funziona come previsto ora ... solo un sacco di copia / incolla da un foglio di calcolo però
Mike T

Mike, funziona perfettamente! Proverò anche a far funzionare questo con Spatialite (PostGIS / spatialite sembra rendere queste operazioni molto più facili) ma almeno ora posso far funzionare qgsAffine e, almeno, è un plugin semplice.
Simbamangu,

Ho provato ad adattarlo a JavaScript: vederlo qui , anche jsfiddle
flackend,

1
Calcolo della funzione javascript sopra Sono stato in grado di calcolare i miei parametri affini e ruotare con successo alcuni vettori, ma questo non è così facile da usare: devi usare il plug-in di acquisizione Coordinate per ottenere le coordinate del centro di rotazione, quindi calcolare i parametri di trasformazione e copiare e incollare di nuovo in QGis! Sarebbe molto più semplice se il plugin stesso eseguisse i calcoli e gli utenti facessero semplicemente clic per inserire le coordinate del centro di rotazione e definire un angolo di rotazione.
Bradipo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.