PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ ST_Scale()

Datum ST_Scale ( PG_FUNCTION_ARGS  )

Definition at line 3198 of file lwgeom_functions_basic.c.

3199 {
3200  GSERIALIZED *geom;
3201  GSERIALIZED *geom_scale = PG_GETARG_GSERIALIZED_P(1);
3202  GSERIALIZED *geom_origin = NULL;
3203  LWGEOM *lwg, *lwg_scale, *lwg_origin;
3204  LWPOINT *lwpt_scale, *lwpt_origin;
3205  POINT4D origin;
3206  POINT4D factors;
3207  bool translate = false;
3208  GSERIALIZED *ret;
3209  AFFINE aff;
3210 
3211  /* Make sure we have a valid scale input */
3212  lwg_scale = lwgeom_from_gserialized(geom_scale);
3213  lwpt_scale = lwgeom_as_lwpoint(lwg_scale);
3214  if (!lwpt_scale)
3215  {
3216  lwgeom_free(lwg_scale);
3217  PG_FREE_IF_COPY(geom_scale, 1);
3218  lwpgerror("Scale factor geometry parameter must be a point");
3219  PG_RETURN_NULL();
3220  }
3221 
3222  /* Geom Will be modified in place, so take a copy */
3223  geom = PG_GETARG_GSERIALIZED_P_COPY(0);
3224  lwg = lwgeom_from_gserialized(geom);
3225 
3226  /* Empty point, return input untouched */
3227  if (lwgeom_is_empty(lwg))
3228  {
3229  lwgeom_free(lwg_scale);
3230  lwgeom_free(lwg);
3231  PG_FREE_IF_COPY(geom_scale, 1);
3232  PG_RETURN_POINTER(geom);
3233  }
3234 
3235  /* Once we read the scale data into local static point, we can */
3236  /* free the lwgeom */
3237  lwpoint_getPoint4d_p(lwpt_scale, &factors);
3238  if (!lwgeom_has_z(lwg_scale))
3239  factors.z = 1.0;
3240  if (!lwgeom_has_m(lwg_scale))
3241  factors.m = 1.0;
3242  lwgeom_free(lwg_scale);
3243 
3244  /* Do we have the optional false origin? */
3245  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
3246  {
3247  geom_origin = PG_GETARG_GSERIALIZED_P(2);
3248  lwg_origin = lwgeom_from_gserialized(geom_origin);
3249  lwpt_origin = lwgeom_as_lwpoint(lwg_origin);
3250  if (lwpt_origin)
3251  {
3252  lwpoint_getPoint4d_p(lwpt_origin, &origin);
3253  translate = true;
3254  }
3255  /* Free the false origin inputs */
3256  lwgeom_free(lwg_origin);
3257  PG_FREE_IF_COPY(geom_origin, 2);
3258  }
3259 
3260  /* If we have false origin, translate to it before scaling */
3261  if (translate)
3262  {
3263  /* Initialize affine */
3264  memset(&aff, 0, sizeof(AFFINE));
3265  /* Set rotation/scale/sheer matrix to no-op */
3266  aff.afac = aff.efac = aff.ifac = 1.0;
3267  /* Strip false origin from all coordinates */
3268  aff.xoff = -1 * origin.x;
3269  aff.yoff = -1 * origin.y;
3270  aff.zoff = -1 * origin.z;
3271  lwgeom_affine(lwg, &aff);
3272  }
3273 
3274  lwgeom_scale(lwg, &factors);
3275 
3276  /* Return to original origin after scaling */
3277  if (translate)
3278  {
3279  aff.xoff *= -1;
3280  aff.yoff *= -1;
3281  aff.zoff *= -1;
3282  lwgeom_affine(lwg, &aff);
3283  }
3284 
3285  /* Cleanup and return */
3286  ret = geometry_serialize(lwg);
3287  lwgeom_free(lwg);
3288  PG_FREE_IF_COPY(geom, 0);
3289  PG_FREE_IF_COPY(geom_scale, 1);
3290  PG_RETURN_POINTER(ret);
3291 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition: lwpoint.c:57
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:934
void lwgeom_scale(LWGEOM *geom, const POINT4D *factors)
Definition: lwgeom.c:2051
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition: lwgeom.c:1997
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:941
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:203
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwinline.h:131
double zoff
Definition: liblwgeom.h:332
double ifac
Definition: liblwgeom.h:332
double xoff
Definition: liblwgeom.h:332
double afac
Definition: liblwgeom.h:332
double efac
Definition: liblwgeom.h:332
double yoff
Definition: liblwgeom.h:332
double m
Definition: liblwgeom.h:414
double x
Definition: liblwgeom.h:414
double z
Definition: liblwgeom.h:414
double y
Definition: liblwgeom.h:414

References AFFINE::afac, AFFINE::efac, 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: