PostGIS  2.5.2dev-r@@SVN_REVISION@@

◆ ST_Scale()

Datum ST_Scale ( PG_FUNCTION_ARGS  )

Definition at line 2920 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().

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