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

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

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

1311 {
1312 #if POSTGIS_GEOS_VERSION < 32
1313  lwerror("The GEOS version this PostGIS binary "
1314  "was compiled against (%d) doesn't support "
1315  "ST_OffsetCurve function "
1316  "(needs 3.2 or higher)",
1318  PG_RETURN_NULL(); /* never get here */
1319 #else
1320 
1321  GSERIALIZED *gser_input;
1322  GSERIALIZED *gser_result;
1323  LWGEOM *lwgeom_input;
1324  LWGEOM *lwgeom_result;
1325  double size;
1326  int quadsegs = 8; /* the default */
1327  int nargs;
1328 
1329  enum
1330  {
1331  JOIN_ROUND = 1,
1332  JOIN_MITRE = 2,
1333  JOIN_BEVEL = 3
1334  };
1335 
1336  static const double DEFAULT_MITRE_LIMIT = 5.0;
1337  static const int DEFAULT_JOIN_STYLE = JOIN_ROUND;
1338  double mitreLimit = DEFAULT_MITRE_LIMIT;
1339  int joinStyle = DEFAULT_JOIN_STYLE;
1340  char *param = NULL;
1341  char *paramstr = NULL;
1342 
1343  /* Read SQL arguments */
1344  nargs = PG_NARGS();
1345  gser_input = (GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
1346  size = PG_GETARG_FLOAT8(1);
1347 
1348  /* Check for a useable type */
1349  if ( gserialized_get_type(gser_input) != LINETYPE )
1350  {
1351  lwerror("ST_OffsetCurve only works with LineStrings");
1352  PG_RETURN_NULL();
1353  }
1354 
1355  /*
1356  * For distance == 0, just return the input.
1357  * Note that due to a bug, GEOS 3.3.0 would return EMPTY.
1358  * See http://trac.osgeo.org/geos/ticket/454
1359  */
1360  if ( size == 0 )
1361  PG_RETURN_POINTER(gser_input);
1362 
1363  /* Read the lwgeom, check for errors */
1364  lwgeom_input = lwgeom_from_gserialized(gser_input);
1365  if ( ! lwgeom_input )
1366  lwerror("ST_OffsetCurve: lwgeom_from_gserialized returned NULL");
1367 
1368  /* For empty inputs, just echo them back */
1369  if ( lwgeom_is_empty(lwgeom_input) )
1370  PG_RETURN_POINTER(gser_input);
1371 
1372  /* Process the optional arguments */
1373  if ( nargs > 2 )
1374  {
1375  text *wkttext = PG_GETARG_TEXT_P(2);
1376  paramstr = text2cstring(wkttext);
1377 
1378  POSTGIS_DEBUGF(3, "paramstr: %s", paramstr);
1379 
1380  for ( param=paramstr; ; param=NULL )
1381  {
1382  char *key, *val;
1383  param = strtok(param, " ");
1384  if ( param == NULL ) break;
1385  POSTGIS_DEBUGF(3, "Param: %s", param);
1386 
1387  key = param;
1388  val = strchr(key, '=');
1389  if ( val == NULL || *(val+1) == '\0' )
1390  {
1391  lwerror("ST_OffsetCurve: Missing value for buffer parameter %s", key);
1392  break;
1393  }
1394  *val = '\0';
1395  ++val;
1396 
1397  POSTGIS_DEBUGF(3, "Param: %s : %s", key, val);
1398 
1399  if ( !strcmp(key, "join") )
1400  {
1401  if ( !strcmp(val, "round") )
1402  {
1403  joinStyle = JOIN_ROUND;
1404  }
1405  else if ( !(strcmp(val, "mitre") && strcmp(val, "miter")) )
1406  {
1407  joinStyle = JOIN_MITRE;
1408  }
1409  else if ( ! strcmp(val, "bevel") )
1410  {
1411  joinStyle = JOIN_BEVEL;
1412  }
1413  else
1414  {
1415  lwerror("Invalid buffer end cap style: %s (accept: "
1416  "'round', 'mitre', 'miter' or 'bevel')", val);
1417  break;
1418  }
1419  }
1420  else if ( !strcmp(key, "mitre_limit") ||
1421  !strcmp(key, "miter_limit") )
1422  {
1423  /* mitreLimit is a float */
1424  mitreLimit = atof(val);
1425  }
1426  else if ( !strcmp(key, "quad_segs") )
1427  {
1428  /* quadrant segments is an int */
1429  quadsegs = atoi(val);
1430  }
1431  else
1432  {
1433  lwerror("Invalid buffer parameter: %s (accept: "
1434  "'join', 'mitre_limit', 'miter_limit and "
1435  "'quad_segs')", key);
1436  break;
1437  }
1438  }
1439  POSTGIS_DEBUGF(3, "joinStyle:%d mitreLimit:%g", joinStyle, mitreLimit);
1440  pfree(paramstr); /* alloc'ed in text2cstring */
1441  }
1442 
1443  lwgeom_result = lwgeom_offsetcurve(lwgeom_as_lwline(lwgeom_input), size, quadsegs, joinStyle, mitreLimit);
1444 
1445  if (lwgeom_result == NULL)
1446  lwerror("ST_OffsetCurve: lwgeom_offsetcurve returned NULL");
1447 
1448  gser_result = gserialized_from_lwgeom(lwgeom_result, 0, 0);
1449  lwgeom_free(lwgeom_input);
1450  lwgeom_free(lwgeom_result);
1451  PG_RETURN_POINTER(gser_result);
1452 
1453 #endif /* POSTGIS_GEOS_VERSION < 32 */
1454 }
#define LINETYPE
Definition: liblwgeom.h:61
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:56
#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:1006
LWGEOM * lwgeom_offsetcurve(const LWLINE *lwline, double size, int quadsegs, int joinStyle, double mitreLimit)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
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:908
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:1229

Here is the call graph for this function: