Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I would like to rotate a set of vector points in QGIS an arbitrary number of degrees around a central point (or arbitrary point).

This is similar to a recent question about creating a regular grid; it was suggested there to use the "Affine Transformation" tool (which I assume meant the plugin) to rotate or shift a grid of points an arbitrary angle or distance. I suspect I'm not understanding how it works, and haven't been able to get it to work.

I create a regular grid of points in QGIS, and ensure that the UTM zone is set correctly for both layer and project, enable editing for the layer, then open the plugin dialog (qgsAffine): Affine Transformation dialog

I select 'whole layer' and then, wanting to rotate the entire field of points by 15°, put 15 in both 'rotation' boxes (which may be where things are going wrong). The operation results in rotating the points somewhere off-planet!

Is this the right tool for the job? I would like to rotate a set of points about their common centre, ideally.

Update: qgsAffine is just a thought; if we can do this in any QGIS tool I'll be happy!

Update 2: qgsAffine is usable IF you know the right numbers to plug in (see answer below, thanks Mike!). Spreadsheet / calculator works fine, or here's the R function to get the numbers directly:

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

So, to rotate a grid of points in northern Uganda (UTM 36N), affine(578988, 419210, 30) gives:

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

... which, entered into the qgsAffine dialog, correctly rotates the points.

share|improve this question
    
nice R adaptation! –  Mike T Mar 19 '12 at 11:23
add comment

2 Answers 2

up vote 5 down vote accepted
+50

You can do this in PostGIS using ST_Affine. The functionality to rotate around an arbitrary point was added to ST_Rotate for PostGIS 2.0.

If you have an earlier version (like PostGIS 1.5, or even earlier), you can add these functions:

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

See examples at ST_Rotate to get an idea on how to use it to rotate a geometry around an x, y point, including the centroid (common centre).

Because we all like math, the transformation matrix from the above functions is represented as:

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

Where θ is the counter-clockwise rotation about an origin, x0 is the Easting/Longitude of the origin point, and y0 is the Northing/Latitude. This math could possibly be adapted to any affine transformation tool.


To use the qgsAffine tool, you need to understand where the values of the matrix flow to. A good spreadsheet template is also required to do pre-calculations. The qgsAffine dialog looks something like this:

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

where:

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

For example, if you want to rotate a polygon 30° clockwise around 42°S, 174°E, here are your inputs to your spreadsheet:

  • x0 = 174
  • y0 = -42
  • θ=-30 degrees or -0.523598776 radians

Then, copy/paste the results from a spreadsheet to the right box. Using the tab order in the from the dialog:

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

qgsAffine

The same example from PostGIS would look something like:

SELECT ST_Rotate(geom, -30*pi()/180, 174.0, -42.0)
share|improve this answer
    
That's looking pretty good; if we can do that in Spatialite it'd qualify as 'doing it in QGIS' since we can run SQL on Spatialite files through QGIS plugins; PostGIS would be another whole step in installation for users that I don't want to get into. Any idea if any functions for spatialite can rotate around a centroid as well? –  Simbamangu Mar 19 '12 at 5:50
    
aha, I demystified qgsAffine, works as expected now ... just lots of copy/pasting from a spreadsheet though –  Mike T Mar 19 '12 at 8:23
    
Mike, that works just right! I'm going to try to make this work with Spatialite, too (PostGIS / spatialite seem to make these operations sooo much easier) but at least now I can get qgsAffine working and it, at least, is a straightforward plugin. –  Simbamangu Mar 19 '12 at 9:12
    
I tried to adapt it to JavaScript: see it here, also jsfiddle –  flackend Jul 31 '12 at 17:28
1  
Calculating the javascript function above I was able to calculate my affine parameters and rotate som vectors successfully, but this is not so user-friendly: you have to use Coordinate capture plugin to get rotation center coordinates, then calculate the transformation parameters and copy&paste back to QGis! It wuold be be far simpler if the plugin itself did the calculations and users just click to enter the rotation center coordinates and define a rotation angle. –  bradypus Sep 9 '12 at 13:28
add comment

I've never got anywhere trying to rotate vector layers using qgsAffine and I think I'm not alone. This question came up on the QGIS forum recently and a solution was found, using (free) OpenJump. Have a look at this thread (towards the end):

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

Of course you could also use this tool just to do a simple rotation of your data.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.