PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ ST_Scale()

Datum ST_Scale ( PG_FUNCTION_ARGS  )

Definition at line 2919 of file lwgeom_functions_basic.c.

References AFFINE::afac, AFFINE::efac, dumpnode::geom, 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, PG_FUNCTION_INFO_V1(), ST_Points(), POINT4D::x, AFFINE::xoff, POINT4D::y, AFFINE::yoff, POINT4D::z, and AFFINE::zoff.

Referenced by ST_BoundingDiagonal().

2920 {
2921  GSERIALIZED *geom;
2922  GSERIALIZED *geom_scale = PG_GETARG_GSERIALIZED_P(1);
2923  GSERIALIZED *geom_origin = NULL;
2924  LWGEOM *lwg, *lwg_scale, *lwg_origin;
2925  LWPOINT *lwpt_scale, *lwpt_origin;
2926  POINT4D origin;
2927  POINT4D factors;
2928  bool translate = false;
2929  GSERIALIZED *ret;
2930  AFFINE aff;
2931 
2932  /* Make sure we have a valid scale input */
2933  lwg_scale = lwgeom_from_gserialized(geom_scale);
2934  lwpt_scale = lwgeom_as_lwpoint(lwg_scale);
2935  if (!lwpt_scale)
2936  {
2937  lwgeom_free(lwg_scale);
2938  PG_FREE_IF_COPY(geom_scale, 1);
2939  lwpgerror("Scale factor geometry parameter must be a point");
2940  PG_RETURN_NULL();
2941  }
2942 
2943  /* Geom Will be modified in place, so take a copy */
2944  geom = PG_GETARG_GSERIALIZED_P_COPY(0);
2945  lwg = lwgeom_from_gserialized(geom);
2946 
2947  /* Empty point, return input untouched */
2948  if (lwgeom_is_empty(lwg))
2949  {
2950  lwgeom_free(lwg_scale);
2951  lwgeom_free(lwg);
2952  PG_FREE_IF_COPY(geom_scale, 1);
2953  PG_RETURN_POINTER(geom);
2954  }
2955 
2956  /* Once we read the scale data into local static point, we can */
2957  /* free the lwgeom */
2958  lwpoint_getPoint4d_p(lwpt_scale, &factors);
2959  if (!lwgeom_has_z(lwg_scale)) factors.z = 1.0;
2960  if (!lwgeom_has_m(lwg_scale)) factors.m = 1.0;
2961  lwgeom_free(lwg_scale);
2962 
2963  /* Do we have the optional false origin? */
2964  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
2965  {
2966  geom_origin = PG_GETARG_GSERIALIZED_P(2);
2967  lwg_origin = lwgeom_from_gserialized(geom_origin);
2968  lwpt_origin = lwgeom_as_lwpoint(lwg_origin);
2969  if (lwpt_origin)
2970  {
2971  lwpoint_getPoint4d_p(lwpt_origin, &origin);
2972  translate = true;
2973  }
2974  /* Free the false origin inputs */
2975  lwgeom_free(lwg_origin);
2976  PG_FREE_IF_COPY(geom_origin, 2);
2977  }
2978 
2979  /* If we have false origin, translate to it before scaling */
2980  if (translate)
2981  {
2982  /* Initialize affine */
2983  memset(&aff, 0, sizeof(AFFINE));
2984  /* Set rotation/scale/sheer matrix to no-op */
2985  aff.afac = aff.efac = aff.ifac = 1.0;
2986  /* Strip false origin from all coordinates */
2987  aff.xoff = -1 * origin.x;
2988  aff.yoff = -1 * origin.y;
2989  aff.zoff = -1 * origin.z;
2990  lwgeom_affine(lwg, &aff);
2991  }
2992 
2993  lwgeom_scale(lwg, &factors);
2994 
2995  /* Return to original origin after scaling */
2996  if (translate)
2997  {
2998  aff.xoff *= -1;
2999  aff.yoff *= -1;
3000  aff.zoff *= -1;
3001  lwgeom_affine(lwg, &aff);
3002  }
3003 
3004  /* Cleanup and return */
3005  ret = geometry_serialize(lwg);
3006  lwgeom_free(lwg);
3007  PG_FREE_IF_COPY(geom, 0);
3008  PG_FREE_IF_COPY(geom_scale, 1);
3009  PG_RETURN_POINTER(ret);
3010 }
double x
Definition: liblwgeom.h:354
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwinline.h:100
double m
Definition: liblwgeom.h:354
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1128
void lwgeom_scale(LWGEOM *geom, const POINT4D *factors)
Definition: lwgeom.c:1961
double zoff
Definition: liblwgeom.h:272
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:914
double ifac
Definition: liblwgeom.h:272
double xoff
Definition: liblwgeom.h:272
double afac
Definition: liblwgeom.h:272
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:172
LWGEOM * geom
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
Definition: lwpoint.c:57
double z
Definition: liblwgeom.h:354
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double efac
Definition: liblwgeom.h:272
double yoff
Definition: liblwgeom.h:272
double y
Definition: liblwgeom.h:354
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:921
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition: lwgeom.c:1910
Here is the call graph for this function:
Here is the caller graph for this function: