* New Features *
+ - #3062, Allow passing M factor to ST_Scale (Sandro Santilli / Boundless)
- #3139, ST_BoundingDiagonal (Sandro Santilli / Boundless)
- #3129, ST_IsValidTrajectory (Sandro Santilli / Boundless)
- #3128, ST_ClosestPointOfApproach (Sandro Santilli / Boundless)
<paramdef><type>float</type> <parameter>XFactor</parameter></paramdef>
<paramdef><type>float</type> <parameter>YFactor</parameter></paramdef>
</funcprototype>
+
+ <funcprototype>
+ <funcdef>geometry <function>ST_Scale</function></funcdef>
+ <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
+ <paramdef><type>geometry</type> <parameter>factor</parameter></paramdef>
+ </funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<note><para><code>ST_Scale(geomA, XFactor, YFactor, ZFactor)</code>
is short-hand for <code>ST_Affine(geomA, XFactor, 0, 0, 0, YFactor, 0, 0, 0, ZFactor, 0, 0, 0)</code>.</para></note>
+ <para>
+The version taking a geometry as the <varname>factor</varname> parameter
+allows passing a 2d, 3dm, 3dz or 4d point to set scaling factor for all
+supported dimensions. Missing dimensions in the <varname>factor</varname>
+point are equivalant to no scaling the corresponding dimension.
+ </para>
+
<note><para>Prior to 1.3.4, this function crashes if used with geometries that contain CURVES. This is fixed in 1.3.4+</para></note>
<para>Availability: 1.1.0.</para>
<para>Enhanced: 2.0.0 support for Polyhedral surfaces, Triangles and TIN was introduced.</para>
+ <para>Enhanced: 2.2.0 support for scaling all dimension (geometry parameter) was introduced.</para>
<para>&P_support;</para>
<para>&Z_support;</para>
<para>&curve_support;</para>
<para>&T_support;</para>
+ <para>&M_support;</para>
</refsection>
PG_RETURN_POINTER(geom_out);
}
+
+Datum ST_Scale(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(ST_Scale);
+Datum ST_Scale(PG_FUNCTION_ARGS)
+{
+ GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P_COPY(0); /* will be modified */
+ GSERIALIZED *geom2 = PG_GETARG_GSERIALIZED_P(1);
+ GSERIALIZED *ret;
+ LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1);
+ LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2);
+ LWPOINT *lwpoint;
+ POINT4D factors;
+
+ lwpoint = lwgeom_as_lwpoint(lwgeom2);
+ if ( lwpoint == NULL )
+ {
+ lwgeom_free(lwgeom1);
+ lwgeom_free(lwgeom2);
+ PG_FREE_IF_COPY(geom1, 0);
+ PG_FREE_IF_COPY(geom2, 1);
+ lwpgerror("Scale factor geometry parameter must be a point");
+ PG_RETURN_NULL();
+ }
+ if ( ! lwpoint->point->npoints )
+ {
+ /* empty point, return input untouched */
+ lwgeom_free(lwgeom1);
+ lwgeom_free(lwgeom2);
+ PG_FREE_IF_COPY(geom2, 1);
+ PG_RETURN_POINTER(geom1);
+ }
+ getPoint4d_p(lwpoint->point, 0, &factors);
+ if ( ! FLAGS_GET_Z(lwpoint->flags ) ) factors.z = 1;
+ if ( ! FLAGS_GET_M(lwpoint->flags ) ) factors.m = 1;
+
+ lwgeom_scale(lwgeom1, &factors);
+
+ /* Construct GSERIALIZED */
+ ret = geometry_serialize(lwgeom1);
+
+ /* Cleanup */
+ lwgeom_free(lwgeom1);
+ lwgeom_free(lwgeom2);
+ PG_FREE_IF_COPY(geom1, 0);
+ PG_FREE_IF_COPY(geom2, 1);
+
+ PG_RETURN_POINTER(ret);
+}
AS 'SELECT ST_Translate($1, $2, $3, 0)'
LANGUAGE 'sql' IMMUTABLE STRICT;
+-- Availability: 2.2.0
+CREATE OR REPLACE FUNCTION ST_Scale(geometry,geometry)
+ RETURNS geometry
+ AS 'MODULE_PATHNAME', 'ST_Scale'
+ LANGUAGE 'c' IMMUTABLE STRICT;
+
-- Availability: 1.2.2
CREATE OR REPLACE FUNCTION ST_Scale(geometry,float8,float8,float8)
RETURNS geometry
AS 'SELECT ST_Affine($1, $2, 0, 0, 0, $3, 0, 0, 0, $4, 0, 0, 0)'
+ --AS 'SELECT ST_Scale($1, ST_Point($2, $3, $4))'
LANGUAGE 'sql' IMMUTABLE STRICT;
-- Availability: 1.2.2
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));
+SELECT 'ST_ScaleBOX', p && ST_Scale(p,ST_MakePoint(-10,1)) FROM (
+ select 'POINT(1 1)'::geometry p ) foo;
+select 'ST_ScaleM1', ST_asewkt(ST_Scale('POINT(10 20 -5 3)'::geometry, ST_MakePoint(4, 2, -8)));
+select 'ST_ScaleM2', ST_asewkt(ST_Scale('POINT(-2 -1 3 2)'::geometry, ST_MakePointM(-2, 3, 4)));
+select 'ST_ScaleM3', ST_asewkt(ST_Scale('POINT(10 20 -5 3)'::geometry, ST_MakePoint(-3, 2, -1, 3)));
-- ST_Rotate
select 'ST_Rotate', ST_asewkt(ST_SnapToGrid(ST_Rotate('POINT(1 1)'::geometry, pi()/2, 10.0, 20.0), 0.1));
ST_Scale|POINT(5 5)
ST_Scale|POINT(3 2)
ST_Scale|POINT(40 40 40)
+ST_ScaleBOX|f
+ST_ScaleM1|POINT(40 40 40 3)
+ST_ScaleM2|POINT(4 -3 3 8)
+ST_ScaleM3|POINT(-30 40 5 9)
ST_Rotate|POINT(29 11)
ST_Rotate|POINT(-2 0)
ST_Rotate|POINT(19 1)