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

Definition at line 1240 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(), POSTGIS_GEOS_VERSION, and text2cstring().

1241 {
1242 #if POSTGIS_GEOS_VERSION < 32
1243  lwpgerror("The GEOS version this PostGIS binary "
1244  "was compiled against (%d) doesn't support "
1245  "ST_OffsetCurve function "
1246  "(needs 3.2 or higher)",
1248  PG_RETURN_NULL(); /* never get here */
1249 #else
1250 
1251  GSERIALIZED *gser_input;
1252  GSERIALIZED *gser_result;
1253  LWGEOM *lwgeom_input;
1254  LWGEOM *lwgeom_result;
1255  double size;
1256  int quadsegs = 8; /* the default */
1257  int nargs;
1258 
1259  enum
1260  {
1261  JOIN_ROUND = 1,
1262  JOIN_MITRE = 2,
1263  JOIN_BEVEL = 3
1264  };
1265 
1266  static const double DEFAULT_MITRE_LIMIT = 5.0;
1267  static const int DEFAULT_JOIN_STYLE = JOIN_ROUND;
1268  double mitreLimit = DEFAULT_MITRE_LIMIT;
1269  int joinStyle = DEFAULT_JOIN_STYLE;
1270  char *param = NULL;
1271  char *paramstr = NULL;
1272 
1273  /* Read SQL arguments */
1274  nargs = PG_NARGS();
1275  gser_input = PG_GETARG_GSERIALIZED_P(0);
1276  size = PG_GETARG_FLOAT8(1);
1277 
1278  /* Check for a useable type */
1279  if ( gserialized_get_type(gser_input) != LINETYPE )
1280  {
1281  lwpgerror("ST_OffsetCurve only works with LineStrings");
1282  PG_RETURN_NULL();
1283  }
1284 
1285  /*
1286  * For distance == 0, just return the input.
1287  * Note that due to a bug, GEOS 3.3.0 would return EMPTY.
1288  * See http://trac.osgeo.org/geos/ticket/454
1289  */
1290  if ( size == 0 )
1291  PG_RETURN_POINTER(gser_input);
1292 
1293  /* Read the lwgeom, check for errors */
1294  lwgeom_input = lwgeom_from_gserialized(gser_input);
1295  if ( ! lwgeom_input )
1296  lwpgerror("ST_OffsetCurve: lwgeom_from_gserialized returned NULL");
1297 
1298  /* For empty inputs, just echo them back */
1299  if ( lwgeom_is_empty(lwgeom_input) )
1300  PG_RETURN_POINTER(gser_input);
1301 
1302  /* Process the optional arguments */
1303  if ( nargs > 2 )
1304  {
1305  text *wkttext = PG_GETARG_TEXT_P(2);
1306  paramstr = text2cstring(wkttext);
1307 
1308  POSTGIS_DEBUGF(3, "paramstr: %s", paramstr);
1309 
1310  for ( param=paramstr; ; param=NULL )
1311  {
1312  char *key, *val;
1313  param = strtok(param, " ");
1314  if ( param == NULL ) break;
1315  POSTGIS_DEBUGF(3, "Param: %s", param);
1316 
1317  key = param;
1318  val = strchr(key, '=');
1319  if ( val == NULL || *(val+1) == '\0' )
1320  {
1321  lwpgerror("ST_OffsetCurve: Missing value for buffer parameter %s", key);
1322  break;
1323  }
1324  *val = '\0';
1325  ++val;
1326 
1327  POSTGIS_DEBUGF(3, "Param: %s : %s", key, val);
1328 
1329  if ( !strcmp(key, "join") )
1330  {
1331  if ( !strcmp(val, "round") )
1332  {
1333  joinStyle = JOIN_ROUND;
1334  }
1335  else if ( !(strcmp(val, "mitre") && strcmp(val, "miter")) )
1336  {
1337  joinStyle = JOIN_MITRE;
1338  }
1339  else if ( ! strcmp(val, "bevel") )
1340  {
1341  joinStyle = JOIN_BEVEL;
1342  }
1343  else
1344  {
1345  lwpgerror("Invalid buffer end cap style: %s (accept: "
1346  "'round', 'mitre', 'miter' or 'bevel')", val);
1347  break;
1348  }
1349  }
1350  else if ( !strcmp(key, "mitre_limit") ||
1351  !strcmp(key, "miter_limit") )
1352  {
1353  /* mitreLimit is a float */
1354  mitreLimit = atof(val);
1355  }
1356  else if ( !strcmp(key, "quad_segs") )
1357  {
1358  /* quadrant segments is an int */
1359  quadsegs = atoi(val);
1360  }
1361  else
1362  {
1363  lwpgerror("Invalid buffer parameter: %s (accept: "
1364  "'join', 'mitre_limit', 'miter_limit and "
1365  "'quad_segs')", key);
1366  break;
1367  }
1368  }
1369  POSTGIS_DEBUGF(3, "joinStyle:%d mitreLimit:%g", joinStyle, mitreLimit);
1370  pfree(paramstr); /* alloc'ed in text2cstring */
1371  }
1372 
1373  lwgeom_result = lwgeom_offsetcurve(lwgeom_as_lwline(lwgeom_input), size, quadsegs, joinStyle, mitreLimit);
1374 
1375  if (lwgeom_result == NULL)
1376  lwpgerror("ST_OffsetCurve: lwgeom_offsetcurve returned NULL");
1377 
1378  gser_result = gserialized_from_lwgeom(lwgeom_result, 0, 0);
1379  lwgeom_free(lwgeom_input);
1380  lwgeom_free(lwgeom_result);
1381  PG_RETURN_POINTER(gser_result);
1382 
1383 #endif /* POSTGIS_GEOS_VERSION < 32 */
1384 }
#define LINETYPE
Definition: liblwgeom.h:71
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:55
#define POSTGIS_GEOS_VERSION
Definition: sqldefines.h:10
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1050
LWGEOM * lwgeom_offsetcurve(const LWLINE *lwline, double size, int quadsegs, int joinStyle, double mitreLimit)
char * text2cstring(const text *textptr)
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, int is_geodetic, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
Definition: g_serialized.c:906
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:89
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:1297

Here is the call graph for this function: