PostGIS  2.3.8dev-r@@SVN_REVISION@@

◆ ST_OffsetCurve()

Datum ST_OffsetCurve ( PG_FUNCTION_ARGS  )

Definition at line 1009 of file postgis/lwgeom_geos.c.

References geos_intersection(), gserialized_from_lwgeom(), gserialized_get_type(), LINETYPE, lwgeom_as_lwline(), lwgeom_free(), lwgeom_from_gserialized(), lwgeom_is_empty(), lwgeom_offsetcurve(), PG_FUNCTION_INFO_V1(), and text2cstring().

Referenced by ST_GeneratePoints().

1010 {
1011  GSERIALIZED *gser_input;
1012  GSERIALIZED *gser_result;
1013  LWGEOM *lwgeom_input;
1014  LWGEOM *lwgeom_result;
1015  double size;
1016  int quadsegs = 8; /* the default */
1017  int nargs;
1018 
1019  enum
1020  {
1021  JOIN_ROUND = 1,
1022  JOIN_MITRE = 2,
1023  JOIN_BEVEL = 3
1024  };
1025 
1026  static const double DEFAULT_MITRE_LIMIT = 5.0;
1027  static const int DEFAULT_JOIN_STYLE = JOIN_ROUND;
1028  double mitreLimit = DEFAULT_MITRE_LIMIT;
1029  int joinStyle = DEFAULT_JOIN_STYLE;
1030  char *param = NULL;
1031  char *paramstr = NULL;
1032 
1033  /* Read SQL arguments */
1034  nargs = PG_NARGS();
1035  gser_input = PG_GETARG_GSERIALIZED_P(0);
1036  size = PG_GETARG_FLOAT8(1);
1037 
1038  /* Check for a useable type */
1039  if ( gserialized_get_type(gser_input) != LINETYPE )
1040  {
1041  lwpgerror("ST_OffsetCurve only works with LineStrings");
1042  PG_RETURN_NULL();
1043  }
1044 
1045  /*
1046  * For distance == 0, just return the input.
1047  * Note that due to a bug, GEOS 3.3.0 would return EMPTY.
1048  * See http://trac.osgeo.org/geos/ticket/454
1049  */
1050  if ( size == 0 )
1051  PG_RETURN_POINTER(gser_input);
1052 
1053  /* Read the lwgeom, check for errors */
1054  lwgeom_input = lwgeom_from_gserialized(gser_input);
1055  if ( ! lwgeom_input )
1056  lwpgerror("ST_OffsetCurve: lwgeom_from_gserialized returned NULL");
1057 
1058  /* For empty inputs, just echo them back */
1059  if ( lwgeom_is_empty(lwgeom_input) )
1060  PG_RETURN_POINTER(gser_input);
1061 
1062  /* Process the optional arguments */
1063  if ( nargs > 2 )
1064  {
1065  text *wkttext = PG_GETARG_TEXT_P(2);
1066  paramstr = text2cstring(wkttext);
1067 
1068  POSTGIS_DEBUGF(3, "paramstr: %s", paramstr);
1069 
1070  for ( param=paramstr; ; param=NULL )
1071  {
1072  char *key, *val;
1073  param = strtok(param, " ");
1074  if ( param == NULL ) break;
1075  POSTGIS_DEBUGF(3, "Param: %s", param);
1076 
1077  key = param;
1078  val = strchr(key, '=');
1079  if ( val == NULL || *(val+1) == '\0' )
1080  {
1081  lwpgerror("ST_OffsetCurve: Missing value for buffer parameter %s", key);
1082  break;
1083  }
1084  *val = '\0';
1085  ++val;
1086 
1087  POSTGIS_DEBUGF(3, "Param: %s : %s", key, val);
1088 
1089  if ( !strcmp(key, "join") )
1090  {
1091  if ( !strcmp(val, "round") )
1092  {
1093  joinStyle = JOIN_ROUND;
1094  }
1095  else if ( !(strcmp(val, "mitre") && strcmp(val, "miter")) )
1096  {
1097  joinStyle = JOIN_MITRE;
1098  }
1099  else if ( ! strcmp(val, "bevel") )
1100  {
1101  joinStyle = JOIN_BEVEL;
1102  }
1103  else
1104  {
1105  lwpgerror("Invalid buffer end cap style: %s (accept: "
1106  "'round', 'mitre', 'miter' or 'bevel')", val);
1107  break;
1108  }
1109  }
1110  else if ( !strcmp(key, "mitre_limit") ||
1111  !strcmp(key, "miter_limit") )
1112  {
1113  /* mitreLimit is a float */
1114  mitreLimit = atof(val);
1115  }
1116  else if ( !strcmp(key, "quad_segs") )
1117  {
1118  /* quadrant segments is an int */
1119  quadsegs = atoi(val);
1120  }
1121  else
1122  {
1123  lwpgerror("Invalid buffer parameter: %s (accept: "
1124  "'join', 'mitre_limit', 'miter_limit and "
1125  "'quad_segs')", key);
1126  break;
1127  }
1128  }
1129  POSTGIS_DEBUGF(3, "joinStyle:%d mitreLimit:%g", joinStyle, mitreLimit);
1130  pfree(paramstr); /* alloc'ed in text2cstring */
1131  }
1132 
1133  lwgeom_result = lwgeom_offsetcurve(lwgeom_as_lwline(lwgeom_input), size, quadsegs, joinStyle, mitreLimit);
1134 
1135  if (lwgeom_result == NULL)
1136  lwpgerror("ST_OffsetCurve: lwgeom_offsetcurve returned NULL");
1137 
1138  gser_result = gserialized_from_lwgeom(lwgeom_result, 0);
1139  lwgeom_free(lwgeom_input);
1140  lwgeom_free(lwgeom_result);
1141  PG_RETURN_POINTER(gser_result);
1142 }
#define LINETYPE
Definition: liblwgeom.h:85
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Definition: g_serialized.c:69
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1063
LWGEOM * lwgeom_offsetcurve(const LWLINE *lwline, double size, int quadsegs, int joinStyle, double mitreLimit)
char * text2cstring(const text *textptr)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:102
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:1310
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
Definition: g_serialized.c:933
Here is the call graph for this function:
Here is the caller graph for this function: