]> granicus.if.org Git - postgis/commitdiff
Enhance ST_Rotate by adding offset origin parameters (#1251) from mwtoews
authorPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 1 Feb 2012 21:27:01 +0000 (21:27 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 1 Feb 2012 21:27:01 +0000 (21:27 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9006 b70326c6-7e19-0410-871a-916f4a2858ee

doc/reference_editor.xml
postgis/postgis.sql.in.c
regress/affine.sql
regress/affine_expected

index 5577c5cdcd794d11bac13952205bc2853438c5ae..15a1721d55760bd42bd2e1a69e6bdd2a9ffbc2c0 100644 (file)
@@ -143,11 +143,11 @@ z' = z </programlisting> This method is a subcase of the 3D method
                <title>Examples</title>
 
                <programlisting>
---Rotate a 3d line 180 degrees about the z axis.  Note this is long-hand for doing ST_RotateZ();
+--Rotate a 3d line 180 degrees about the z axis.  Note this is long-hand for doing ST_Rotate();
  SELECT ST_AsEWKT(ST_Affine(the_geom,  cos(pi()), -sin(pi()), 0,  sin(pi()), cos(pi()), 0,  0, 0, 1,  0, 0, 0)) As using_affine,
-        ST_AsEWKT(ST_RotateZ(the_geom, pi())) As using_rotatez
+        ST_AsEWKT(ST_Rotate(the_geom, pi())) As using_rotate
        FROM (SELECT ST_GeomFromEWKT('LINESTRING(1 2 3, 1 4 3)') As the_geom) As foo;
-               using_affine         |        using_rotatez
+        using_affine         |        using_rotate
 -----------------------------+-----------------------------
  LINESTRING(-1 -2 3,-1 -4 3) | LINESTRING(-1 -2 3,-1 -4 3)
 (1 row)
@@ -155,11 +155,10 @@ z' = z </programlisting> This method is a subcase of the 3D method
 --Rotate a 3d line 180 degrees in both the x and z axis
 SELECT ST_AsEWKT(ST_Affine(the_geom, cos(pi()), -sin(pi()), 0, sin(pi()), cos(pi()), -sin(pi()), 0, sin(pi()), cos(pi()), 0, 0, 0))
        FROM (SELECT ST_GeomFromEWKT('LINESTRING(1 2 3, 1 4 3)') As the_geom) As foo;
-                  st_asewkt
+           st_asewkt
 -------------------------------
  LINESTRING(-1 -2 -3,-1 -4 -3)
 (1 row)
-
                </programlisting>
          </refsection>
 
@@ -825,7 +824,7 @@ LINESTRING(1 2,1 10) | LINESTRING(1 10,1 2)
          <refnamediv>
                <refname>ST_Rotate</refname>
 
-               <refpurpose>This is a synonym for ST_RotateZ</refpurpose>
+               <refpurpose>Rotate a geometry rotRadians counter-clockwise about an origin.</refpurpose>
          </refnamediv>
 
          <refsynopsisdiv>
@@ -833,17 +832,35 @@ LINESTRING(1 2,1 10) | LINESTRING(1 10,1 2)
                  <funcprototype>
                        <funcdef>geometry <function>ST_Rotate</function></funcdef>
                        <paramdef><type>geometry</type> <parameter>geomA</parameter></paramdef>
-                       <paramdef><type>float</type> <parameter>rotZRadians</parameter></paramdef>
+                       <paramdef><type>float</type> <parameter>rotRadians</parameter></paramdef>
                  </funcprototype>
+
+                 <funcprototype>
+                        <funcdef>geometry <function>ST_Rotate</function></funcdef>
+                        <paramdef><type>geometry</type> <parameter>geomA</parameter></paramdef>
+                        <paramdef><type>float</type> <parameter>rotRadians</parameter></paramdef>
+                        <paramdef><type>float</type> <parameter>x0</parameter></paramdef>
+                        <paramdef><type>float</type> <parameter>y0</parameter></paramdef>
+                  </funcprototype>
+
+                 <funcprototype>
+                        <funcdef>geometry <function>ST_Rotate</function></funcdef>
+                        <paramdef><type>geometry</type> <parameter>geomA</parameter></paramdef>
+                        <paramdef><type>float</type> <parameter>rotRadians</parameter></paramdef>
+                        <paramdef><type>geometry</type> <parameter>pointOrigin</parameter></paramdef>
+                  </funcprototype>
                </funcsynopsis>
          </refsynopsisdiv>
 
          <refsection>
                <title>Description</title>
 
-               <para>This is a synonym for ST_RotateZ..  Rotates geometry rotZRadians about the Z-axis.</para>
+               <para>Rotates geometry rotRadians counter-clockwise about the origin. The rotation origin can be
+                       specified either as a POINT geometry, or as x and y coordinates. If the origin is not
+                       specified, the geometry is rotated about POINT(0 0).</para>
 
                <para>Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced.</para>
+               <para>Enhanced: 2.0.0 additional parameters for specifying the origin of rotation were added.</para>
                <para>Availability: 1.1.2. Name changed from Rotate to ST_Rotate in 1.2.2</para>
                <para>&Z_support;</para>
                <para>&curve_support;</para>
@@ -856,7 +873,29 @@ LINESTRING(1 2,1 10) | LINESTRING(1 10,1 2)
          <refsection>
                <title>Examples</title>
 
-               <programlisting></programlisting>
+               <programlisting>
+--Rotate 180 degrees
+SELECT ST_AsEWKT(ST_Rotate('LINESTRING (50 160, 50 50, 100 50)', pi()));
+               st_asewkt
+---------------------------------------
+ LINESTRING(-50 -160,-50 -50,-100 -50)
+(1 row)
+
+--Rotate 30 degrees counter-clockwise at x=50, y=160
+SELECT ST_AsEWKT(ST_Rotate('LINESTRING (50 160, 50 50, 100 50)', pi()/6, 50, 160));
+                                 st_asewkt
+---------------------------------------------------------------------------
+ LINESTRING(50 160,105 64.7372055837117,148.301270189222 89.7372055837117)
+(1 row)
+
+--Rotate 60 degrees clockwise from centroid
+SELECT ST_AsEWKT(ST_Rotate(geom, -pi()/3, ST_Centroid(geom)))
+FROM (SELECT 'LINESTRING (50 160, 50 50, 100 50)'::geometry AS geom) AS foo;
+                           st_asewkt
+--------------------------------------------------------------
+ LINESTRING(116.4225 130.6721,21.1597 75.6721,46.1597 32.3708)
+(1 row)
+               </programlisting>
          </refsection>
 
          <!-- Optionally add a "See Also" section -->
@@ -998,6 +1037,7 @@ SELECT ST_AsEWKT(ST_RotateX(ST_GeomFromEWKT('LINESTRING(1 2 3, 1 1 1)'), pi()/2)
 
                <para>Rotate a geometry geomA - rotRadians about the Z axis.</para>
 
+               <note><para>This is a synonym for ST_Rotate</para></note>
                <note><para><code>ST_RotateZ(geomA,  rotRadians)</code>
                        is short-hand for <code>SELECT ST_Affine(geomA,  cos(rotRadians), -sin(rotRadians), 0,  sin(rotRadians), cos(rotRadians), 0,  0, 0, 1,  0, 0, 0)</code>.</para></note>
 
index 01dad6f296d0baf31752eba36fd4038f6b5f8aab..5db961d93a10cab9e7b924c0aaf14f578c7cca0c 100644 (file)
@@ -115,6 +115,33 @@ CREATE CAST (geometry AS geometry) WITH FUNCTION geometry(geometry, integer, boo
 \r
 -------------------------------------------------------------------\r
 --  BOX3D TYPE\r
+-- Point coordinate data access\r
+-------------------------------------------\r
+-- PostGIS equivalent function: X(geometry)\r
+CREATE OR REPLACE FUNCTION ST_X(geometry)\r
+       RETURNS float8\r
+       AS 'MODULE_PATHNAME','LWGEOM_x_point'\r
+       LANGUAGE 'C' IMMUTABLE STRICT;\r
+\r
+-- PostGIS equivalent function: Y(geometry)\r
+CREATE OR REPLACE FUNCTION ST_Y(geometry)\r
+       RETURNS float8\r
+       AS 'MODULE_PATHNAME','LWGEOM_y_point'\r
+       LANGUAGE 'C' IMMUTABLE STRICT;\r
+\r
+-- Availability: 1.2.2\r
+CREATE OR REPLACE FUNCTION ST_Z(geometry)\r
+       RETURNS float8\r
+       AS 'MODULE_PATHNAME','LWGEOM_z_point'\r
+       LANGUAGE 'C' IMMUTABLE STRICT;\r
+\r
+-- Availability: 1.2.2\r
+CREATE OR REPLACE FUNCTION ST_M(geometry)\r
+       RETURNS float8\r
+       AS 'MODULE_PATHNAME','LWGEOM_m_point'\r
+       LANGUAGE 'C' IMMUTABLE STRICT;\r
+\r
+-------------------------------------------\r
 -------------------------------------------------------------------\r
 \r
 CREATE OR REPLACE FUNCTION box3d_in(cstring)\r
@@ -679,15 +706,27 @@ CREATE OR REPLACE FUNCTION ST_Affine(geometry,float8,float8,float8,float8,float8
        LANGUAGE 'SQL' IMMUTABLE STRICT;\r
 \r
 -- Availability: 1.2.2\r
-CREATE OR REPLACE FUNCTION ST_RotateZ(geometry,float8)\r
+CREATE OR REPLACE FUNCTION ST_Rotate(geometry,float8)\r
        RETURNS geometry\r
        AS 'SELECT ST_Affine($1,  cos($2), -sin($2), 0,  sin($2), cos($2), 0,  0, 0, 1,  0, 0, 0)'\r
        LANGUAGE 'SQL' IMMUTABLE STRICT;\r
 \r
+-- Availability: 2.0.0\r
+CREATE OR REPLACE FUNCTION ST_Rotate(geometry,float8,float8,float8)\r
+       RETURNS geometry\r
+       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)'\r
+       LANGUAGE 'SQL' IMMUTABLE STRICT;\r
+\r
+-- Availability: 2.0.0\r
+CREATE OR REPLACE FUNCTION ST_Rotate(geometry,float8,geometry)\r
+       RETURNS geometry\r
+       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)'\r
+       LANGUAGE 'sql' IMMUTABLE STRICT;\r
+\r
 -- Availability: 1.2.2\r
-CREATE OR REPLACE FUNCTION ST_Rotate(geometry,float8)\r
+CREATE OR REPLACE FUNCTION ST_RotateZ(geometry,float8)\r
        RETURNS geometry\r
-       AS 'SELECT ST_RotateZ($1, $2)'\r
+       AS 'SELECT ST_Rotate($1, $2)'\r
        LANGUAGE 'SQL' IMMUTABLE STRICT;\r
 \r
 -- Availability: 1.2.2\r
@@ -3464,30 +3503,6 @@ CREATE OR REPLACE FUNCTION ST_PatchN(geometry, integer)
        '\r
        LANGUAGE 'SQL' IMMUTABLE STRICT;\r
 \r
--- PostGIS equivalent function: X(geometry)\r
-CREATE OR REPLACE FUNCTION ST_X(geometry)\r
-       RETURNS float8\r
-       AS 'MODULE_PATHNAME','LWGEOM_x_point'\r
-       LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
--- PostGIS equivalent function: Y(geometry)\r
-CREATE OR REPLACE FUNCTION ST_Y(geometry)\r
-       RETURNS float8\r
-       AS 'MODULE_PATHNAME','LWGEOM_y_point'\r
-       LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
--- Availability: 1.2.2\r
-CREATE OR REPLACE FUNCTION ST_Z(geometry)\r
-       RETURNS float8\r
-       AS 'MODULE_PATHNAME','LWGEOM_z_point'\r
-       LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
--- Availability: 1.2.2\r
-CREATE OR REPLACE FUNCTION ST_M(geometry)\r
-       RETURNS float8\r
-       AS 'MODULE_PATHNAME','LWGEOM_m_point'\r
-       LANGUAGE 'C' IMMUTABLE STRICT;\r
-\r
 -- PostGIS equivalent function of old StartPoint(geometry))\r
 CREATE OR REPLACE FUNCTION ST_StartPoint(geometry)\r
        RETURNS geometry\r
@@ -4626,7 +4641,7 @@ $BODY$
                                -- Compute the midpoint\r
                                p1 = ST_line_interpolate_point(l1,0.5);\r
                                -- Rotate the line 90 degrees around the midpoint (perpendicular bisector)\r
-                               l1 = ST_Translate(ST_Rotate(ST_Translate(l1,-ST_X(p1),-ST_Y(p1)),pi()/2),ST_X(p1),ST_Y(p1));\r
+                               l1 = ST_Rotate(l1,pi()/2,p1);\r
                                --  Compute the azimuth of the bisector\r
                                a1 = ST_Azimuth(ST_PointN(l1,1),ST_PointN(l1,2));\r
                                --  Extend the line in each direction the new computed distance to insure they will intersect\r
@@ -4636,7 +4651,7 @@ $BODY$
                                -- Repeat for the line from the point to the other diameter point\r
                                l2 = ST_Makeline(ST_PointN(ring,idx2),ST_PointN(ring,k));\r
                                p2 = ST_Line_interpolate_point(l2,0.5);\r
-                               l2 = ST_Translate(ST_Rotate(ST_Translate(l2,-ST_X(p2),-ST_Y(p2)),pi()/2),ST_X(p2),ST_Y(p2));\r
+                               l2 = ST_Rotate(l2,pi()/2,p2);\r
                                a2 = ST_Azimuth(ST_PointN(l2,1),ST_PointN(l2,2));\r
                                l2 = ST_AddPoint(l2,ST_Makepoint(ST_X(ST_PointN(l2,2))+sin(a2)*dist,ST_Y(ST_PointN(l2,2))+cos(a2)*dist),-1);\r
                                l2 = ST_AddPoint(l2,ST_Makepoint(ST_X(ST_PointN(l2,1))-sin(a2)*dist,ST_Y(ST_PointN(l2,1))-cos(a2)*dist),0);\r
index e1f18d2189ea3022889cbd3448644e6827ac065d..1d5ef099963db96bcc9df3032c9f375238faf98c 100644 (file)
@@ -9,6 +9,12 @@ select 'ST_Scale', ST_asewkt(ST_Scale('POINT(1 1)'::geometry, 5, 5));
 select 'ST_Scale', ST_asewkt(ST_Scale('POINT(1 1)'::geometry, 3, 2));
 select 'ST_Scale', ST_asewkt(ST_Scale('POINT(10 20 -5)'::geometry, 4, 2, -8));
 
+-- ST_Rotate
+select 'ST_Rotate', ST_asewkt(ST_SnapToGrid(ST_Rotate('POINT(1 1)'::geometry, pi()/2, 10.0, 20.0), 0.1));
+select 'ST_Rotate', ST_asewkt(ST_SnapToGrid(ST_Rotate('POINT(1 1)'::geometry, -pi()/2, -1.0, 2.0), 0.1));
+select 'ST_Rotate', ST_asewkt(ST_SnapToGrid(ST_Rotate('POINT(1 1)'::geometry, pi()/2, 'POINT(10 10)'::geometry), 0.1));
+select 'ST_Rotate', ST_asewkt(ST_SnapToGrid(ST_Rotate('POINT(1 1)'::geometry, pi()/2, ST_Centroid('LINESTRING(0 0, 1 0)'::geometry)), 0.1));
+
 -- ST_RotateZ
 select 'ST_RotateZ', ST_asewkt(ST_SnapToGrid(ST_RotateZ('POINT(1 1)'::geometry, pi()), 0.1));
 select 'ST_RotateZ', ST_asewkt(ST_SnapToGrid(ST_RotateZ('POINT(1 1)'::geometry, pi()/2), 0.1));
index 5e918b9a37210453a1d776451c7b5d337f04cccf..639d06983af9a3fd88f956b1aeb5b7a58768a1b8 100644 (file)
@@ -3,6 +3,10 @@ ST_Translate|POINT(-3 -7 3)
 ST_Scale|POINT(5 5)
 ST_Scale|POINT(3 2)
 ST_Scale|POINT(40 40 40)
+ST_Rotate|POINT(29 11)
+ST_Rotate|POINT(-2 0)
+ST_Rotate|POINT(19 1)
+ST_Rotate|POINT(-0.5 0.5)
 ST_RotateZ|POINT(-1 -1)
 ST_RotateZ|POINT(-1 1)
 ST_RotateZ|POINT(1 -1)