PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ ST_OffsetCurve()

Datum ST_OffsetCurve ( PG_FUNCTION_ARGS  )

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

1085 {
1086  GSERIALIZED *gser_input;
1087  GSERIALIZED *gser_result;
1088  LWGEOM *lwgeom_input;
1089  LWGEOM *lwgeom_result;
1090  double size;
1091  int quadsegs = 8; /* the default */
1092  int nargs;
1093 
1094  enum
1095  {
1096  JOIN_ROUND = 1,
1097  JOIN_MITRE = 2,
1098  JOIN_BEVEL = 3
1099  };
1100 
1101  static const double DEFAULT_MITRE_LIMIT = 5.0;
1102  static const int DEFAULT_JOIN_STYLE = JOIN_ROUND;
1103  double mitreLimit = DEFAULT_MITRE_LIMIT;
1104  int joinStyle = DEFAULT_JOIN_STYLE;
1105  char *param = NULL;
1106  char *paramstr = NULL;
1107 
1108  /* Read SQL arguments */
1109  nargs = PG_NARGS();
1110  gser_input = PG_GETARG_GSERIALIZED_P(0);
1111  size = PG_GETARG_FLOAT8(1);
1112 
1113  /* Check for a useable type */
1114  if ( gserialized_get_type(gser_input) != LINETYPE )
1115  {
1116  lwpgerror("ST_OffsetCurve only works with LineStrings");
1117  PG_RETURN_NULL();
1118  }
1119 
1120  /*
1121  * For distance == 0, just return the input.
1122  * Note that due to a bug, GEOS 3.3.0 would return EMPTY.
1123  * See http://trac.osgeo.org/geos/ticket/454
1124  */
1125  if ( size == 0 )
1126  PG_RETURN_POINTER(gser_input);
1127 
1128  /* Read the lwgeom, check for errors */
1129  lwgeom_input = lwgeom_from_gserialized(gser_input);
1130  if ( ! lwgeom_input )
1131  lwpgerror("ST_OffsetCurve: lwgeom_from_gserialized returned NULL");
1132 
1133  /* For empty inputs, just echo them back */
1134  if ( lwgeom_is_empty(lwgeom_input) )
1135  PG_RETURN_POINTER(gser_input);
1136 
1137  /* Process the optional arguments */
1138  if ( nargs > 2 )
1139  {
1140  text *wkttext = PG_GETARG_TEXT_P(2);
1141  paramstr = text2cstring(wkttext);
1142 
1143  POSTGIS_DEBUGF(3, "paramstr: %s", paramstr);
1144 
1145  for ( param=paramstr; ; param=NULL )
1146  {
1147  char *key, *val;
1148  param = strtok(param, " ");
1149  if ( param == NULL ) break;
1150  POSTGIS_DEBUGF(3, "Param: %s", param);
1151 
1152  key = param;
1153  val = strchr(key, '=');
1154  if ( val == NULL || *(val+1) == '\0' )
1155  {
1156  lwpgerror("ST_OffsetCurve: Missing value for buffer parameter %s", key);
1157  break;
1158  }
1159  *val = '\0';
1160  ++val;
1161 
1162  POSTGIS_DEBUGF(3, "Param: %s : %s", key, val);
1163 
1164  if ( !strcmp(key, "join") )
1165  {
1166  if ( !strcmp(val, "round") )
1167  {
1168  joinStyle = JOIN_ROUND;
1169  }
1170  else if ( !(strcmp(val, "mitre") && strcmp(val, "miter")) )
1171  {
1172  joinStyle = JOIN_MITRE;
1173  }
1174  else if ( ! strcmp(val, "bevel") )
1175  {
1176  joinStyle = JOIN_BEVEL;
1177  }
1178  else
1179  {
1180  lwpgerror("Invalid buffer end cap style: %s (accept: "
1181  "'round', 'mitre', 'miter' or 'bevel')", val);
1182  break;
1183  }
1184  }
1185  else if ( !strcmp(key, "mitre_limit") ||
1186  !strcmp(key, "miter_limit") )
1187  {
1188  /* mitreLimit is a float */
1189  mitreLimit = atof(val);
1190  }
1191  else if ( !strcmp(key, "quad_segs") )
1192  {
1193  /* quadrant segments is an int */
1194  quadsegs = atoi(val);
1195  }
1196  else
1197  {
1198  lwpgerror("Invalid buffer parameter: %s (accept: "
1199  "'join', 'mitre_limit', 'miter_limit and "
1200  "'quad_segs')", key);
1201  break;
1202  }
1203  }
1204  POSTGIS_DEBUGF(3, "joinStyle:%d mitreLimit:%g", joinStyle, mitreLimit);
1205  pfree(paramstr); /* alloc'ed in text2cstring */
1206  }
1207 
1208  lwgeom_result = lwgeom_offsetcurve(lwgeom_as_lwline(lwgeom_input), size, quadsegs, joinStyle, mitreLimit);
1209 
1210  if (lwgeom_result == NULL)
1211  lwpgerror("ST_OffsetCurve: lwgeom_offsetcurve returned NULL");
1212 
1213  gser_result = gserialized_from_lwgeom(lwgeom_result, 0);
1214  lwgeom_free(lwgeom_input);
1215  lwgeom_free(lwgeom_result);
1216  PG_RETURN_POINTER(gser_result);
1217 }
#define LINETYPE
Definition: liblwgeom.h:86
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:1099
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:138
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:1346
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
Here is the call graph for this function:
Here is the caller graph for this function: