| 49 | == An Example == |
| 50 | |
| 51 | {{{ |
| 52 | #!c |
| 53 | PG_FUNCTION_INFO_V1(LWGEOM_shortestline2d); |
| 54 | Datum LWGEOM_shortestline2d(PG_FUNCTION_ARGS) |
| 55 | { |
| 56 | PG_LWGEOM *result; |
| 57 | /* Detoast the actual PgSQL varlena structures, in our case PG_LWGEOM (soon to be GSERIALIZED) */ |
| 58 | PG_LWGEOM *geom1 = (PG_LWGEOM*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); |
| 59 | PG_LWGEOM *geom2 = (PG_LWGEOM*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); |
| 60 | /* Build LWGEOM from the varlena (soon to be with lwgeom_from_gserialized) */ |
| 61 | LWGEOM *lwgeom1 = pglwgeom_deserialize(geom1); |
| 62 | LWGEOM *lwgeom2 = pglwgeom_deserialize(geom2); |
| 63 | LWGEOM *theline; |
| 64 | |
| 65 | |
| 66 | if (lwgeom1->srid != lwgeom2->srid) |
| 67 | { |
| 68 | elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n"); |
| 69 | PG_RETURN_NULL(); |
| 70 | } |
| 71 | |
| 72 | theline = lw_dist2d_distanceline(lwgeom1, lwgeom2, lwgeom1->srid, DIST_MIN); |
| 73 | if (lwgeom_is_empty(theline)) |
| 74 | PG_RETURN_NULL(); |
| 75 | |
| 76 | /* Serialize the result back down from LWGEOM, but don't return right away */ |
| 77 | result = pglwgeom_serialize(theline); |
| 78 | /* First free the LWGEOMs you used */ |
| 79 | lwgeom_free(lwgeom1); |
| 80 | lwgeom_free(lwgeom2); |
| 81 | |
| 82 | /* Then call free_if_copy on the *varlena* structures you originally get as arguments */ |
| 83 | PG_FREE_IF_COPY(geom1, 0); |
| 84 | PG_FREE_IF_COPY(geom2, 1); |
| 85 | |
| 86 | /* And now return */ |
| 87 | PG_RETURN_POINTER(result); |
| 88 | } |
| 89 | }}} |