PostGIS  2.5.0dev-r@@SVN_REVISION@@
Datum ST_OffsetCurve ( PG_FUNCTION_ARGS  )

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

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

1039 {
1040  GSERIALIZED *gser_input;
1041  GSERIALIZED *gser_result;
1042  LWGEOM *lwgeom_input;
1043  LWGEOM *lwgeom_result;
1044  double size;
1045  int quadsegs = 8; /* the default */
1046  int nargs;
1047 
1048  enum
1049  {
1050  JOIN_ROUND = 1,
1051  JOIN_MITRE = 2,
1052  JOIN_BEVEL = 3
1053  };
1054 
1055  static const double DEFAULT_MITRE_LIMIT = 5.0;
1056  static const int DEFAULT_JOIN_STYLE = JOIN_ROUND;
1057  double mitreLimit = DEFAULT_MITRE_LIMIT;
1058  int joinStyle = DEFAULT_JOIN_STYLE;
1059  char *param = NULL;
1060  char *paramstr = NULL;
1061 
1062  /* Read SQL arguments */
1063  nargs = PG_NARGS();
1064  gser_input = PG_GETARG_GSERIALIZED_P(0);
1065  size = PG_GETARG_FLOAT8(1);
1066 
1067  /* Check for a useable type */
1068  if ( gserialized_get_type(gser_input) != LINETYPE )
1069  {
1070  lwpgerror("ST_OffsetCurve only works with LineStrings");
1071  PG_RETURN_NULL();
1072  }
1073 
1074  /*
1075  * For distance == 0, just return the input.
1076  * Note that due to a bug, GEOS 3.3.0 would return EMPTY.
1077  * See http://trac.osgeo.org/geos/ticket/454
1078  */
1079  if ( size == 0 )
1080  PG_RETURN_POINTER(gser_input);
1081 
1082  /* Read the lwgeom, check for errors */
1083  lwgeom_input = lwgeom_from_gserialized(gser_input);
1084  if ( ! lwgeom_input )
1085  lwpgerror("ST_OffsetCurve: lwgeom_from_gserialized returned NULL");
1086 
1087  /* For empty inputs, just echo them back */
1088  if ( lwgeom_is_empty(lwgeom_input) )
1089  PG_RETURN_POINTER(gser_input);
1090 
1091  /* Process the optional arguments */
1092  if ( nargs > 2 )
1093  {
1094  text *wkttext = PG_GETARG_TEXT_P(2);
1095  paramstr = text2cstring(wkttext);
1096 
1097  POSTGIS_DEBUGF(3, "paramstr: %s", paramstr);
1098 
1099  for ( param=paramstr; ; param=NULL )
1100  {
1101  char *key, *val;
1102  param = strtok(param, " ");
1103  if (!param) break;
1104  POSTGIS_DEBUGF(3, "Param: %s", param);
1105 
1106  key = param;
1107  val = strchr(key, '=');
1108  if (!val || *(val + 1) == '\0')
1109  {
1110  lwpgerror("ST_OffsetCurve: Missing value for buffer parameter %s", key);
1111  break;
1112  }
1113  *val = '\0';
1114  ++val;
1115 
1116  POSTGIS_DEBUGF(3, "Param: %s : %s", key, val);
1117 
1118  if ( !strcmp(key, "join") )
1119  {
1120  if ( !strcmp(val, "round") )
1121  {
1122  joinStyle = JOIN_ROUND;
1123  }
1124  else if ( !(strcmp(val, "mitre") && strcmp(val, "miter")) )
1125  {
1126  joinStyle = JOIN_MITRE;
1127  }
1128  else if ( ! strcmp(val, "bevel") )
1129  {
1130  joinStyle = JOIN_BEVEL;
1131  }
1132  else
1133  {
1134  lwpgerror("Invalid buffer end cap style: %s (accept: "
1135  "'round', 'mitre', 'miter' or 'bevel')", val);
1136  break;
1137  }
1138  }
1139  else if ( !strcmp(key, "mitre_limit") ||
1140  !strcmp(key, "miter_limit") )
1141  {
1142  /* mitreLimit is a float */
1143  mitreLimit = atof(val);
1144  }
1145  else if ( !strcmp(key, "quad_segs") )
1146  {
1147  /* quadrant segments is an int */
1148  quadsegs = atoi(val);
1149  }
1150  else
1151  {
1152  lwpgerror("Invalid buffer parameter: %s (accept: "
1153  "'join', 'mitre_limit', 'miter_limit and "
1154  "'quad_segs')", key);
1155  break;
1156  }
1157  }
1158  POSTGIS_DEBUGF(3, "joinStyle:%d mitreLimit:%g", joinStyle, mitreLimit);
1159  pfree(paramstr); /* alloc'ed in text2cstring */
1160  }
1161 
1162  lwgeom_result = lwgeom_offsetcurve(lwgeom_as_lwline(lwgeom_input), size, quadsegs, joinStyle, mitreLimit);
1163 
1164  if (!lwgeom_result)
1165  lwpgerror("ST_OffsetCurve: lwgeom_offsetcurve returned NULL");
1166 
1167  gser_result = gserialized_from_lwgeom(lwgeom_result, 0);
1168  lwgeom_free(lwgeom_input);
1169  lwgeom_free(lwgeom_result);
1170  PG_RETURN_POINTER(gser_result);
1171 }
#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:86
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1137
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:169
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:1386
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.

Here is the call graph for this function: