PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ ST_Scale()

Datum ST_Scale ( PG_FUNCTION_ARGS  )

Definition at line 2955 of file lwgeom_functions_basic.c.

2956{
2957 GSERIALIZED *geom;
2958 GSERIALIZED *geom_scale = PG_GETARG_GSERIALIZED_P(1);
2959 GSERIALIZED *geom_origin = NULL;
2960 LWGEOM *lwg, *lwg_scale, *lwg_origin;
2961 LWPOINT *lwpt_scale, *lwpt_origin;
2962 POINT4D origin;
2963 POINT4D factors;
2964 bool translate = false;
2965 GSERIALIZED *ret;
2966 AFFINE aff;
2967
2968 /* Make sure we have a valid scale input */
2969 lwg_scale = lwgeom_from_gserialized(geom_scale);
2970 lwpt_scale = lwgeom_as_lwpoint(lwg_scale);
2971 if (!lwpt_scale)
2972 {
2973 lwgeom_free(lwg_scale);
2974 PG_FREE_IF_COPY(geom_scale, 1);
2975 lwpgerror("Scale factor geometry parameter must be a point");
2976 PG_RETURN_NULL();
2977 }
2978
2979 /* Geom Will be modified in place, so take a copy */
2980 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
2981 lwg = lwgeom_from_gserialized(geom);
2982
2983 /* Empty point, return input untouched */
2984 if (lwgeom_is_empty(lwg))
2985 {
2986 lwgeom_free(lwg_scale);
2987 lwgeom_free(lwg);
2988 PG_FREE_IF_COPY(geom_scale, 1);
2989 PG_RETURN_POINTER(geom);
2990 }
2991
2992 /* Once we read the scale data into local static point, we can */
2993 /* free the lwgeom */
2994 lwpoint_getPoint4d_p(lwpt_scale, &factors);
2995 if (!lwgeom_has_z(lwg_scale))
2996 factors.z = 1.0;
2997 if (!lwgeom_has_m(lwg_scale))
2998 factors.m = 1.0;
2999 lwgeom_free(lwg_scale);
3000
3001 /* Do we have the optional false origin? */
3002 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
3003 {
3004 geom_origin = PG_GETARG_GSERIALIZED_P(2);
3005 lwg_origin = lwgeom_from_gserialized(geom_origin);
3006 lwpt_origin = lwgeom_as_lwpoint(lwg_origin);
3007 if (lwpt_origin)
3008 {
3009 lwpoint_getPoint4d_p(lwpt_origin, &origin);
3010 translate = true;
3011 }
3012 /* Free the false origin inputs */
3013 lwgeom_free(lwg_origin);
3014 PG_FREE_IF_COPY(geom_origin, 2);
3015 }
3016
3017 /* If we have false origin, translate to it before scaling */
3018 if (translate)
3019 {
3020 /* Initialize affine */
3021 memset(&aff, 0, sizeof(AFFINE));
3022 /* Set rotation/scale/sheer matrix to no-op */
3023 aff.afac = aff.efac = aff.ifac = 1.0;
3024 /* Strip false origin from all coordinates */
3025 aff.xoff = -1 * origin.x;
3026 aff.yoff = -1 * origin.y;
3027 aff.zoff = -1 * origin.z;
3028 lwgeom_affine(lwg, &aff);
3029 }
3030
3031 lwgeom_scale(lwg, &factors);
3032
3033 /* Return to original origin after scaling */
3034 if (translate)
3035 {
3036 aff.xoff *= -1;
3037 aff.yoff *= -1;
3038 aff.zoff *= -1;
3039 lwgeom_affine(lwg, &aff);
3040 }
3041
3042 /* Cleanup and return */
3043 ret = geometry_serialize(lwg);
3044 lwgeom_free(lwg);
3045 PG_FREE_IF_COPY(geom, 0);
3046 PG_FREE_IF_COPY(geom_scale, 1);
3047 PG_RETURN_POINTER(ret);
3048}
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition lwpoint.c:57
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:916
void lwgeom_scale(LWGEOM *geom, const POINT4D *factors)
Definition lwgeom.c:2029
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition lwgeom.c:1975
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition lwgeom.c:923
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition lwinline.h:121
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:193
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double zoff
Definition liblwgeom.h:318
double ifac
Definition liblwgeom.h:318
double xoff
Definition liblwgeom.h:318
double afac
Definition liblwgeom.h:318
double efac
Definition liblwgeom.h:318
double yoff
Definition liblwgeom.h:318
double m
Definition liblwgeom.h:400
double x
Definition liblwgeom.h:400
double z
Definition liblwgeom.h:400
double y
Definition liblwgeom.h:400

References AFFINE::afac, AFFINE::efac, geometry_serialize(), AFFINE::ifac, lwgeom_affine(), lwgeom_as_lwpoint(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_has_m(), lwgeom_has_z(), lwgeom_is_empty(), lwgeom_scale(), lwpoint_getPoint4d_p(), POINT4D::m, POINT4D::x, AFFINE::xoff, POINT4D::y, AFFINE::yoff, POINT4D::z, and AFFINE::zoff.

Here is the call graph for this function: