In the first step, we are taking each of the points and first applying a buffer of 20 feet to them:
ST_Buffer(the_geom, 20)
Then, we calculate the envelope of the buffer, providing us with a square around that buffered area. This is a quick and easy way to create a square geometry of a specified size from a point:
ST_Envelope(ST_Buffer(the_geom, 20))
Finally, we use ST_Rotate to rotate the geometry to the appropriate angle. Here is where the query becomes harder to read. The ST_Rotate function takes two arguments:
ST_Rotate(geometry to rotate, angle, origin around which to rotate)
The geometry we are using is the newly calculated geometry from the buffering and envelope creation. The angle is the one we calculate using ...