28 #include "utils/array.h"
29 #include "utils/builtins.h"
30 #include "utils/elog.h"
31 #include "utils/geo_decls.h"
33 #include "../postgis_config.h"
36 #include "lwgeom_pg.h"
43 #define xstr(s) str(s)
50 Datum
ST_Area(PG_FUNCTION_ARGS);
137 size_t size = VARSIZE(geom);
138 PG_FREE_IF_COPY(geom, 0);
139 PG_RETURN_INT32(size);
151 size_t result_sz = strlen(lwresult) + 8;
156 snprintf(
result, result_sz,
"0:%s", lwresult);
161 snprintf(
result, result_sz,
"%s", lwresult);
167 summary = cstring_to_text(
result);
170 PG_FREE_IF_COPY(g, 0);
171 PG_RETURN_TEXT_P(summary);
177 char *ver = POSTGIS_VERSION;
178 text *
result = cstring_to_text(ver);
186 text *
result = cstring_to_text(ver);
194 text *
result = cstring_to_text(ver);
201 static char *rev =
xstr(POSTGIS_REVISION);
203 if (rev && rev[0] !=
'\0')
205 snprintf(ver, 32,
"%s", rev);
207 PG_RETURN_TEXT_P(cstring_to_text(ver));
209 else PG_RETURN_NULL();
215 char *ver = POSTGIS_BUILD_DATE;
216 text *
result = cstring_to_text(ver);
229 result = cstring_to_text(ver);
237 text *
result = cstring_to_text(ver);
252 PG_FREE_IF_COPY(geom, 0);
253 PG_RETURN_INT32(npoints);
267 PG_FREE_IF_COPY(geom, 0);
268 PG_RETURN_INT32(nrings);
287 PG_FREE_IF_COPY(geom, 0);
289 PG_RETURN_FLOAT8(area);
306 PG_FREE_IF_COPY(geom, 0);
307 PG_RETURN_FLOAT8(dist);
324 PG_FREE_IF_COPY(geom, 0);
325 PG_RETURN_FLOAT8(dist);
340 double perimeter = 0.0;
343 PG_FREE_IF_COPY(geom, 0);
344 PG_RETURN_FLOAT8(perimeter);
359 double perimeter = 0.0;
362 PG_FREE_IF_COPY(geom, 0);
363 PG_RETURN_FLOAT8(perimeter);
370 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
376 PG_RETURN_POINTER(pg_geom_in);
380 pg_geom_out = geometry_serialize(lwg_out);
384 PG_FREE_IF_COPY(pg_geom_in, 0);
385 PG_RETURN_POINTER(pg_geom_out);
392 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
395 double z = PG_NARGS() < 2 ? 0 : PG_GETARG_FLOAT8(1);
399 PG_RETURN_POINTER(pg_geom_in);
403 pg_geom_out = geometry_serialize(lwg_out);
407 PG_FREE_IF_COPY(pg_geom_in, 0);
408 PG_RETURN_POINTER(pg_geom_out);
415 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
418 double m = PG_NARGS() < 2 ? 0 : PG_GETARG_FLOAT8(1);
422 PG_RETURN_POINTER(pg_geom_in);
426 pg_geom_out = geometry_serialize(lwg_out);
430 PG_FREE_IF_COPY(pg_geom_in, 0);
431 PG_RETURN_POINTER(pg_geom_out);
438 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
441 double z = PG_NARGS() < 3 ? 0 : PG_GETARG_FLOAT8(1);
442 double m = PG_NARGS() < 3 ? 0 : PG_GETARG_FLOAT8(2);
446 PG_RETURN_POINTER(pg_geom_in);
450 pg_geom_out = geometry_serialize(lwg_out);
454 PG_FREE_IF_COPY(pg_geom_in, 0);
455 PG_RETURN_POINTER(pg_geom_out);
469 POSTGIS_DEBUG(2,
"LWGEOM_force_collection called");
478 PG_RETURN_POINTER(geom);
498 lwgeoms = palloc(
sizeof(
LWGEOM *));
503 result = geometry_serialize(lwgeom);
506 PG_FREE_IF_COPY(geom, 0);
507 PG_RETURN_POINTER(
result);
519 POSTGIS_DEBUG(2,
"LWGEOM_force_multi called");
537 PG_RETURN_POINTER(geom);
547 result = geometry_serialize(ogeom);
549 PG_FREE_IF_COPY(geom, 0);
551 PG_RETURN_POINTER(
result);
563 POSTGIS_DEBUG(2,
"LWGEOM_force_curve called");
570 result = geometry_serialize(ogeom);
572 PG_FREE_IF_COPY(geom, 0);
574 PG_RETURN_POINTER(
result);
588 POSTGIS_DEBUG(2,
"LWGEOM_force_sfs called");
591 if ((PG_NARGS() > 1) && (!PG_ARGISNULL(1)))
593 ver = PG_GETARG_TEXT_P(1);
595 if (!strncmp(VARDATA(ver),
"1.2", 3))
604 result = geometry_serialize(ogeom);
606 PG_FREE_IF_COPY(geom, 0);
608 PG_RETURN_POINTER(
result);
631 result = geometry_serialize(point);
636 PG_FREE_IF_COPY(geom1, 0);
637 PG_FREE_IF_COPY(geom2, 1);
638 PG_RETURN_POINTER(
result);
660 result = geometry_serialize(theline);
665 PG_FREE_IF_COPY(geom1, 0);
666 PG_FREE_IF_COPY(geom2, 1);
667 PG_RETURN_POINTER(
result);
689 result = geometry_serialize(theline);
694 PG_FREE_IF_COPY(geom1, 0);
695 PG_FREE_IF_COPY(geom2, 1);
696 PG_RETURN_POINTER(
result);
716 PG_FREE_IF_COPY(geom1, 0);
717 PG_FREE_IF_COPY(geom2, 1);
720 if (mindist < FLT_MAX)
721 PG_RETURN_FLOAT8(mindist);
737 double tolerance = PG_GETARG_FLOAT8(2);
743 elog(ERROR,
"Tolerance cannot be less than zero\n");
751 PG_RETURN_BOOL(
false);
756 PG_FREE_IF_COPY(geom1, 0);
757 PG_FREE_IF_COPY(geom2, 1);
760 PG_RETURN_BOOL(tolerance >= mindist);
774 double tolerance = PG_GETARG_FLOAT8(2);
780 elog(ERROR,
"Tolerance cannot be less than zero\n");
788 PG_FREE_IF_COPY(geom1, 0);
789 PG_FREE_IF_COPY(geom2, 1);
793 PG_RETURN_BOOL(tolerance >= maxdist);
813 PG_FREE_IF_COPY(geom1, 0);
814 PG_FREE_IF_COPY(geom2, 1);
818 PG_RETURN_FLOAT8(maxdist);
844 result = geometry_serialize(point);
850 PG_FREE_IF_COPY(geom1, 0);
851 PG_FREE_IF_COPY(geom2, 1);
852 PG_RETURN_POINTER(
result);
875 result = geometry_serialize(theline);
881 PG_FREE_IF_COPY(geom1, 0);
882 PG_FREE_IF_COPY(geom2, 1);
883 PG_RETURN_POINTER(
result);
906 result = geometry_serialize(theline);
912 PG_FREE_IF_COPY(geom1, 0);
913 PG_FREE_IF_COPY(geom2, 1);
914 PG_RETURN_POINTER(
result);
931 PG_FREE_IF_COPY(geom1, 0);
932 PG_FREE_IF_COPY(geom2, 1);
935 if (mindist < FLT_MAX)
936 PG_RETURN_FLOAT8(mindist);
954 PG_FREE_IF_COPY(geom1, 0);
955 PG_FREE_IF_COPY(geom2, 1);
958 PG_RETURN_BOOL(0.0 == mindist);
973 double tolerance = PG_GETARG_FLOAT8(2);
979 elog(ERROR,
"Tolerance cannot be less than zero\n");
987 PG_FREE_IF_COPY(geom1, 0);
988 PG_FREE_IF_COPY(geom2, 1);
992 PG_RETURN_BOOL(tolerance >= mindist);
1006 double tolerance = PG_GETARG_FLOAT8(2);
1012 elog(ERROR,
"Tolerance cannot be less than zero\n");
1019 PG_FREE_IF_COPY(geom1, 0);
1020 PG_FREE_IF_COPY(geom2, 1);
1024 PG_RETURN_BOOL(tolerance >= maxdist);
1045 PG_FREE_IF_COPY(geom1, 0);
1046 PG_FREE_IF_COPY(geom2, 1);
1050 PG_RETURN_FLOAT8(maxdist);
1062 POSTGIS_DEBUG(2,
"LWGEOM_longitude_shift called.");
1064 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
1074 ret = geometry_serialize(lwgeom);
1082 PG_RETURN_POINTER(ret);
1090 LWGEOM *lwgeom_in, *lwgeom_out;
1095 POSTGIS_DEBUG(2,
"ST_WrapX called.");
1097 gdatum = PG_GETARG_DATUM(0);
1098 cutx = PG_GETARG_FLOAT8(1);
1099 amount = PG_GETARG_FLOAT8(2);
1103 geom_in = ((
GSERIALIZED *)PG_DETOAST_DATUM(gdatum));
1107 geom_out = geometry_serialize(lwgeom_out);
1111 PG_FREE_IF_COPY(geom_in, 0);
1113 PG_RETURN_POINTER(geom_out);
1119 Datum datum_line, datum_point;
1121 LWGEOM *lwgeom_line, *lwgeom_point;
1128 POSTGIS_DEBUG(2,
"ST_Scroll called.");
1130 datum_line = PG_GETARG_DATUM(0);
1131 datum_point = PG_GETARG_DATUM(1);
1133 ser_line = ((
GSERIALIZED *)PG_DETOAST_DATUM(datum_line));
1137 lwpgerror(
"First argument must be a line");
1141 ser_point = ((
GSERIALIZED *)PG_DETOAST_DATUM(datum_point));
1145 lwpgerror(
"Second argument must be a point");
1149 lwpgerror(
"Second argument must be a non-empty point");
1158 ser_out = geometry_serialize(lwgeom_line);
1161 PG_FREE_IF_COPY(ser_line, 0);
1162 PG_FREE_IF_COPY(ser_point, 0);
1164 PG_RETURN_POINTER(ser_out);
1171 double cx = PG_GETARG_FLOAT8(1);
1172 double cy = PG_GETARG_FLOAT8(2);
1173 double rr = PG_GETARG_FLOAT8(3);
1178 geom = PG_GETARG_GSERIALIZED_P(0);
1183 PG_FREE_IF_COPY(geom, 0);
1190 PG_FREE_IF_COPY(geom, 0);
1191 PG_RETURN_BOOL(inside);
1205 LWGEOM *lwgeoms[2], *outlwg;
1206 uint32 type1, type2;
1210 POSTGIS_DEBUG(2,
"LWGEOM_collect called.");
1213 if (PG_ARGISNULL(0) && PG_ARGISNULL(1))
1217 if (PG_ARGISNULL(0))
1218 PG_RETURN_DATUM(PG_GETARG_DATUM(1));
1221 if (PG_ARGISNULL(1))
1222 PG_RETURN_DATUM(PG_GETARG_DATUM(0));
1224 gser1 = PG_GETARG_GSERIALIZED_P(0);
1225 gser2 = PG_GETARG_GSERIALIZED_P(1);
1229 "LWGEOM_collect(%s, %s): call",
1236 elog(ERROR,
"Cannot ST_Collect geometries with differing dimensionality.");
1245 type1 = lwgeoms[0]->
type;
1246 type2 = lwgeoms[1]->
type;
1253 POSTGIS_DEBUGF(3,
" outtype = %d", outtype);
1262 result = geometry_serialize(outlwg);
1267 PG_FREE_IF_COPY(gser1, 0);
1268 PG_FREE_IF_COPY(gser2, 1);
1270 PG_RETURN_POINTER(
result);
1289 LWGEOM **lwgeoms, *outlwg;
1295 ArrayIterator iterator;
1299 POSTGIS_DEBUG(2,
"LWGEOM_collect_garray called.");
1301 if (PG_ARGISNULL(0))
1305 array = PG_GETARG_ARRAYTYPE_P(0);
1306 nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1309 " array is %d-bytes in size, %ld w/out header",
1311 ARR_SIZE(array) - ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1313 POSTGIS_DEBUGF(3,
"LWGEOM_collect_garray: array has %d elements", nelems);
1323 lwgeoms = palloc(
sizeof(
LWGEOM *) * nelems);
1327 iterator = array_create_iterator(array, 0, NULL);
1329 while (array_iterate(iterator, &
value, &isnull))
1343 POSTGIS_DEBUGF(3,
"%s: geom %d deserialized", __func__,
count);
1351 if (lwgeoms[
count]->bbox)
1362 if (lwgeoms[
count]->bbox)
1389 array_free_iterator(iterator);
1391 POSTGIS_DEBUGF(3,
"LWGEOM_collect_garray: outtype = %d", outtype);
1402 result = geometry_serialize(outlwg);
1404 PG_RETURN_POINTER(
result);
1419 POSTGIS_DEBUG(2,
"LWGEOM_line_from_mpoint called");
1422 ingeom = PG_GETARG_GSERIALIZED_P(0);
1426 elog(ERROR,
"makeline: input must be a multipoint");
1434 PG_FREE_IF_COPY(ingeom, 0);
1435 elog(ERROR,
"makeline: lwline_from_lwmpoint returned NULL");
1441 PG_FREE_IF_COPY(ingeom, 0);
1444 PG_RETURN_POINTER(
result);
1463 ArrayIterator iterator;
1467 POSTGIS_DEBUGF(2,
"%s called", __func__);
1470 if (PG_ARGISNULL(0))
1474 array = PG_GETARG_ARRAYTYPE_P(0);
1477 nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1479 POSTGIS_DEBUGF(3,
"%s: array has %d elements", __func__, nelems);
1492 geoms = palloc(
sizeof(
LWGEOM *) * nelems);
1495 iterator = array_create_iterator(array, 0, NULL);
1497 while (array_iterate(iterator, &
value, &isnull))
1518 srid = geoms[ngeoms - 1]->
srid;
1524 POSTGIS_DEBUGF(3,
"%s: element %d deserialized", __func__, ngeoms);
1526 array_free_iterator(iterator);
1532 elog(NOTICE,
"No points or linestrings in input array");
1536 POSTGIS_DEBUGF(3,
"LWGEOM_makeline_garray: elements: %d", ngeoms);
1540 result = geometry_serialize(outlwg);
1542 PG_RETURN_POINTER(
result);
1557 POSTGIS_DEBUG(2,
"LWGEOM_makeline called.");
1560 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
1561 pglwg2 = PG_GETARG_GSERIALIZED_P(1);
1566 elog(ERROR,
"Input geometries must be points or lines");
1579 PG_FREE_IF_COPY(pglwg1, 0);
1580 PG_FREE_IF_COPY(pglwg2, 1);
1584 PG_RETURN_POINTER(
result);
1595 ArrayType *array = NULL;
1597 const LWLINE *shell = NULL;
1598 const LWLINE **holes = NULL;
1604 POSTGIS_DEBUG(2,
"LWGEOM_makepoly called.");
1607 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
1610 lwpgerror(
"Shell is not a line");
1617 array = PG_GETARG_ARRAYTYPE_P(1);
1618 nholes = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1620 for (i = 0; i < nholes; i++)
1622 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
1623 #pragma GCC diagnostic push
1624 #pragma GCC diagnostic ignored "-Wsign-compare"
1627 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
1628 #pragma GCC diagnostic pop
1631 offset += INTALIGN(VARSIZE(g));
1634 lwpgerror(
"Hole %d is not a line", i);
1646 PG_FREE_IF_COPY(pglwg1, 0);
1648 for (i = 0; i < nholes; i++)
1653 PG_RETURN_POINTER(
result);
1671 POSTGIS_DEBUG(2,
"LWGEOM_expand called.");
1677 PG_RETURN_POINTER(geom);
1684 PG_RETURN_POINTER(geom);
1687 if (PG_NARGS() == 2)
1690 double d = PG_GETARG_FLOAT8(1);
1695 double dx = PG_GETARG_FLOAT8(1);
1696 double dy = PG_GETARG_FLOAT8(2);
1697 double dz = PG_GETARG_FLOAT8(3);
1698 double dm = PG_GETARG_FLOAT8(4);
1720 PG_FREE_IF_COPY(geom, 0);
1722 PG_RETURN_POINTER(
result);
1729 GSERIALIZED *pg_lwgeom = PG_GETARG_GSERIALIZED_P(0);
1743 PG_FREE_IF_COPY(pg_lwgeom, 0);
1750 out->low.x = gbox.
xmin;
1751 out->low.y = gbox.
ymin;
1752 out->high.x = gbox.
xmax;
1753 out->high.y = gbox.
ymax;
1754 PG_RETURN_POINTER(out);
1767 int32_t srid = lwgeom->
srid;
1776 PG_RETURN_POINTER(geom);
1782 PG_RETURN_POINTER(geom);
1852 PG_FREE_IF_COPY(geom, 0);
1854 PG_RETURN_POINTER(
result);
1875 LWGEOM *inlwgeom, *outlwgeom;
1878 POSTGIS_DEBUG(2,
"LWGEOM_segmentize2d called");
1880 ingeom = PG_GETARG_GSERIALIZED_P(0);
1881 dist = PG_GETARG_FLOAT8(1);
1888 PG_RETURN_POINTER(ingeom);
1895 elog(ERROR,
"ST_Segmentize: invalid max_distance %g (must be >= 0)", dist);
1906 PG_RETURN_POINTER(ingeom);
1913 PG_FREE_IF_COPY(ingeom, 0);
1921 outgeom = geometry_serialize(outlwgeom);
1926 PG_FREE_IF_COPY(ingeom, 0);
1928 PG_RETURN_POINTER(outgeom);
1938 POSTGIS_DEBUG(2,
"LWGEOM_reverse called");
1940 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
1945 geom = geometry_serialize(lwgeom);
1947 PG_RETURN_POINTER(geom);
1957 POSTGIS_DEBUG(2,
"LWGEOM_force_clockwise_poly called");
1959 ingeom = PG_GETARG_GSERIALIZED_P_COPY(0);
1964 outgeom = geometry_serialize(lwgeom);
1967 PG_FREE_IF_COPY(ingeom, 0);
1968 PG_RETURN_POINTER(outgeom);
1978 PG_RETURN_POINTER(out);
1986 LWGEOM *lwgeom_in, *lwgeom_out;
1988 POSTGIS_DEBUG(2,
"ST_Normalize called");
1990 in = PG_GETARG_GSERIALIZED_P_COPY(0);
1993 POSTGIS_DEBUGF(3,
"Deserialized: %s",
lwgeom_summary(lwgeom_in, 0));
1996 POSTGIS_DEBUGF(3,
"Normalized: %s",
lwgeom_summary(lwgeom_out, 0));
1998 out = geometry_serialize(lwgeom_out);
2002 PG_FREE_IF_COPY(in, 0);
2004 PG_RETURN_POINTER(out);
2017 GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
2024 PG_FREE_IF_COPY(in, 0);
2025 PG_RETURN_INT16(ret);
2031 GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
2038 GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
2045 GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
2047 PG_FREE_IF_COPY(in, 0);
2048 PG_RETURN_BOOL(
res);
2055 GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
2057 PG_FREE_IF_COPY(in, 0);
2058 PG_RETURN_INT16(ret);
2076 double x1, y1, x2, y2;
2079 POSTGIS_DEBUG(2,
"ST_MakeEnvelope called");
2081 x1 = PG_GETARG_FLOAT8(0);
2082 y1 = PG_GETARG_FLOAT8(1);
2083 x2 = PG_GETARG_FLOAT8(2);
2084 y2 = PG_GETARG_FLOAT8(3);
2087 srid = PG_GETARG_INT32(4);
2095 PG_RETURN_POINTER(
result);
2105 uint32_t worldTileSize;
2106 double tileGeoSizeX, tileGeoSizeY;
2107 double boundsWidth, boundsHeight;
2108 double x1, y1, x2, y2;
2119 POSTGIS_DEBUG(2,
"ST_TileEnvelope called");
2121 zoom = PG_GETARG_INT32(0);
2122 x = PG_GETARG_INT32(1);
2123 y = PG_GETARG_INT32(2);
2125 bounds = PG_GETARG_GSERIALIZED_P(3);
2134 elog(ERROR,
"%s: Unable to compute bbox", __func__);
2139 margin = PG_NARGS() < 4 ? 0 : PG_GETARG_FLOAT8(4);
2142 elog(ERROR,
"%s: Margin must not be less than -50%%, margin=%f", __func__, margin);
2144 boundsWidth = bbox.
xmax - bbox.
xmin;
2145 boundsHeight = bbox.
ymax - bbox.
ymin;
2146 if (boundsWidth <= 0 || boundsHeight <= 0)
2147 elog(ERROR,
"%s: Geometric bounds are too small", __func__);
2149 if (zoom < 0 || zoom >= 32)
2150 elog(ERROR,
"%s: Invalid tile zoom value, %d", __func__, zoom);
2152 zoomu = (uint32_t)zoom;
2153 worldTileSize = 0x01u << (zoomu > 31 ? 31 : zoomu);
2155 if (
x < 0 || (uint32_t)
x >= worldTileSize)
2156 elog(ERROR,
"%s: Invalid tile x value, %d", __func__,
x);
2157 if (
y < 0 || (uint32_t)
y >= worldTileSize)
2158 elog(ERROR,
"%s: Invalid tile y value, %d", __func__,
y);
2160 tileGeoSizeX = boundsWidth / worldTileSize;
2161 tileGeoSizeY = boundsHeight / worldTileSize;
2168 if ((1 + margin * 2) > worldTileSize)
2175 x1 = bbox.
xmin + tileGeoSizeX * (
x - margin);
2176 x2 = bbox.
xmin + tileGeoSizeX * (
x + 1 + margin);
2179 y1 = bbox.
ymax - tileGeoSizeY * (
y + 1 + margin);
2180 y2 = bbox.
ymax - tileGeoSizeY * (
y - margin);
2183 if (y1 < bbox.
ymin) y1 = bbox.
ymin;
2184 if (y2 > bbox.
ymax) y2 = bbox.
ymax;
2190 srid, x1, y1, x2, y2))));
2197 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_HEADER(0);
2209 POSTGIS_DEBUG(2,
"LWGEOM_makepoint called");
2211 x = PG_GETARG_FLOAT8(0);
2212 y = PG_GETARG_FLOAT8(1);
2214 if (PG_NARGS() == 2)
2216 else if (PG_NARGS() == 3)
2218 z = PG_GETARG_FLOAT8(2);
2221 else if (PG_NARGS() == 4)
2223 z = PG_GETARG_FLOAT8(2);
2224 m = PG_GETARG_FLOAT8(3);
2229 elog(ERROR,
"LWGEOM_makepoint: unsupported number of args: %d", PG_NARGS());
2235 PG_RETURN_POINTER(
result);
2241 double x = PG_GETARG_FLOAT8(0);
2242 double y = PG_GETARG_FLOAT8(1);
2243 int srid = PG_GETARG_INT32(2);
2246 PG_RETURN_POINTER(
result);
2252 double x = PG_GETARG_FLOAT8(0);
2253 double y = PG_GETARG_FLOAT8(1);
2254 double z = PG_GETARG_FLOAT8(2);
2255 int srid = PG_GETARG_INT32(3);
2258 PG_RETURN_POINTER(
result);
2264 double x = PG_GETARG_FLOAT8(0);
2265 double y = PG_GETARG_FLOAT8(1);
2266 double m = PG_GETARG_FLOAT8(2);
2267 int srid = PG_GETARG_INT32(3);
2270 PG_RETURN_POINTER(
result);
2276 double x = PG_GETARG_FLOAT8(0);
2277 double y = PG_GETARG_FLOAT8(1);
2278 double z = PG_GETARG_FLOAT8(2);
2279 double m = PG_GETARG_FLOAT8(3);
2280 int srid = PG_GETARG_INT32(4);
2283 PG_RETURN_POINTER(
result);
2294 POSTGIS_DEBUG(2,
"LWGEOM_makepoint3dm called.");
2296 x = PG_GETARG_FLOAT8(0);
2297 y = PG_GETARG_FLOAT8(1);
2298 m = PG_GETARG_FLOAT8(2);
2303 PG_RETURN_POINTER(
result);
2312 uint32_t uwhere = 0;
2314 POSTGIS_DEBUGF(2,
"%s called.", __func__);
2316 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
2317 pglwg2 = PG_GETARG_GSERIALIZED_P(1);
2321 elog(ERROR,
"First argument must be a LINESTRING");
2327 elog(ERROR,
"Second argument must be a POINT");
2333 if (PG_NARGS() <= 2)
2339 int32 where = PG_GETARG_INT32(2);
2346 elog(ERROR,
"%s: Invalid offset", __func__);
2361 elog(ERROR,
"Point insert failed");
2368 PG_FREE_IF_COPY(pglwg1, 0);
2369 PG_FREE_IF_COPY(pglwg2, 1);
2372 PG_RETURN_POINTER(
result);
2382 POSTGIS_DEBUG(2,
"LWGEOM_removepoint called.");
2384 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
2385 which = PG_GETARG_INT32(1);
2389 elog(ERROR,
"First argument must be a LINESTRING");
2395 if (which < 0 || (uint32_t)which > line->
points->
npoints - 1)
2397 elog(ERROR,
"Point index out of range (%u..%u)", 0, line->
points->
npoints - 1);
2403 elog(ERROR,
"Can't remove points from a single segment line");
2414 PG_FREE_IF_COPY(pglwg1, 0);
2415 PG_RETURN_POINTER(
result);
2428 POSTGIS_DEBUG(2,
"LWGEOM_setpoint_linestring called.");
2431 pglwg1 = PG_GETARG_GSERIALIZED_P_COPY(0);
2433 which = PG_GETARG_INT32(1);
2434 pglwg2 = PG_GETARG_GSERIALIZED_P(2);
2441 elog(ERROR,
"Third argument must be a POINT");
2446 PG_FREE_IF_COPY(pglwg2, 2);
2453 elog(ERROR,
"First argument must be a LINESTRING");
2458 elog(ERROR,
"Line has no points");
2464 elog(ERROR,
"Geometry contains invalid coordinate");
2475 elog(ERROR,
"abs(Point index) out of range (-)(%u..%u)", 0, line->
points->
npoints - 1);
2489 PG_RETURN_POINTER(
result);
2522 geom = PG_GETARG_GSERIALIZED_P(0);
2526 PG_FREE_IF_COPY(geom, 0);
2527 lwpgerror(
"Argument must be POINT geometries");
2530 srid = lwpoint->
srid;
2533 PG_FREE_IF_COPY(geom, 0);
2534 lwpgerror(
"Error extracting point");
2538 PG_FREE_IF_COPY(geom, 0);
2541 geom = PG_GETARG_GSERIALIZED_P(1);
2545 PG_FREE_IF_COPY(geom, 1);
2546 lwpgerror(
"Argument must be POINT geometries");
2549 if (lwpoint->
srid != srid)
2551 PG_FREE_IF_COPY(geom, 1);
2552 lwpgerror(
"Operation on mixed SRID geometries");
2557 PG_FREE_IF_COPY(geom, 1);
2558 lwpgerror(
"Error extracting point");
2562 PG_FREE_IF_COPY(geom, 1);
2565 if ((p1.
x == p2.
x) && (p1.
y == p2.
y))
2576 PG_RETURN_FLOAT8(
result);
2592 LWGEOM *lwgeom1, *lwgeom2;
2595 geom1 = PG_GETARG_GSERIALIZED_P(0);
2597 azimuth = PG_GETARG_FLOAT8(2);
2602 lwpgerror(
"Argument must be POINT geometry");
2609 geom2 = geometry_serialize(lwgeom2);
2610 PG_RETURN_POINTER(geom2);
2625 LWPOINT *lwpoint1, *lwpoint2, *lwpoint3;
2626 LWGEOM *lwgeom1, *lwgeom2, *lwgeom3;
2629 geom1 = PG_GETARG_GSERIALIZED_P(0);
2630 geom2 = PG_GETARG_GSERIALIZED_P(1);
2638 if (!(lwpoint1 && lwpoint2))
2639 lwpgerror(
"Arguments must be POINT geometries");
2645 PG_RETURN_POINTER(geom2);
2649 geom3 = geometry_serialize(lwgeom3);
2651 PG_RETURN_POINTER(geom3);
2666 LWLINE *lwline1, *lwline2;
2667 LWGEOM *lwgeom1, *lwgeom2;
2668 double distance_forward, distance_backward;
2670 geom1 = PG_GETARG_GSERIALIZED_P(0);
2671 distance_forward = PG_GETARG_FLOAT8(1);
2672 distance_backward = PG_GETARG_FLOAT8(2);
2677 lwpgerror(
"Argument must be LINESTRING geometry");
2683 PG_RETURN_POINTER(geom1);
2685 lwline2 =
lwline_extend(lwline1, distance_forward, distance_backward);
2687 geom2 = geometry_serialize(lwgeom2);
2689 PG_RETURN_POINTER(geom2);
2714 int n_args = PG_NARGS();
2717 for (i = 0; i < n_args; i++)
2719 seri_geoms[i] = PG_GETARG_GSERIALIZED_P(i);
2742 if (srids[0] != srids[i])
2754 for (j = 0; j <= i; j++)
2755 PG_FREE_IF_COPY(seri_geoms[j], j);
2758 lwpgerror(
"Empty geometry");
2763 lwpgerror(
"Argument must be POINT geometries");
2768 lwpgerror(
"Operation on mixed SRID geometries");
2773 for (i = 0; i < n_args; i++)
2779 for (j = 0; j < n_args; j++)
2780 PG_FREE_IF_COPY(seri_geoms[j], j);
2781 lwpgerror(
"Error unserializing geometry");
2790 lwpgerror(
"Error extracting point");
2818 PG_RETURN_FLOAT8(
result);
2831 GSERIALIZED *pg_geom1 = PG_GETARG_GSERIALIZED_P(0);
2832 GSERIALIZED *pg_geom2 = PG_GETARG_GSERIALIZED_P(1);
2833 double dist = PG_GETARG_FLOAT8(2);
2842 elog(ERROR,
"optimistic_overlap: first arg isn't a polygon\n");
2848 elog(ERROR,
"optimistic_overlap: 2nd arg isn't a [multi-]polygon\n");
2855 g1_bvol.
xmin = g1_bvol.
xmin - dist;
2856 g1_bvol.
ymin = g1_bvol.
ymin - dist;
2857 g1_bvol.
xmax = g1_bvol.
xmax + dist;
2858 g1_bvol.
ymax = g1_bvol.
ymax + dist;
2863 PG_RETURN_BOOL(
false);
2871 DatumGetFloat8(DirectFunctionCall2(
ST_Distance, PointerGetDatum(pg_geom1), PointerGetDatum(pg_geom2)));
2873 PG_RETURN_BOOL(calc_dist < dist);
2880 GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P_COPY(0);
2885 affine.
afac = PG_GETARG_FLOAT8(1);
2886 affine.
bfac = PG_GETARG_FLOAT8(2);
2887 affine.
cfac = PG_GETARG_FLOAT8(3);
2888 affine.
dfac = PG_GETARG_FLOAT8(4);
2889 affine.
efac = PG_GETARG_FLOAT8(5);
2890 affine.
ffac = PG_GETARG_FLOAT8(6);
2891 affine.
gfac = PG_GETARG_FLOAT8(7);
2892 affine.
hfac = PG_GETARG_FLOAT8(8);
2893 affine.
ifac = PG_GETARG_FLOAT8(9);
2894 affine.
xoff = PG_GETARG_FLOAT8(10);
2895 affine.
yoff = PG_GETARG_FLOAT8(11);
2896 affine.
zoff = PG_GETARG_FLOAT8(12);
2898 POSTGIS_DEBUG(2,
"LWGEOM_affine called.");
2907 ret = geometry_serialize(lwgeom);
2911 PG_FREE_IF_COPY(geom, 0);
2913 PG_RETURN_POINTER(ret);
2924 if (PG_ARGISNULL(0))
2929 geom = PG_GETARG_GSERIALIZED_P(0);
2931 if (!PG_ARGISNULL(1))
2938 PG_RETURN_TEXT_P(geohash);
2945 if (PG_ARGISNULL(0))
2959 extype = PG_GETARG_INT32(1);
2964 elog(ERROR,
"ST_CollectionExtract: only point, linestring and polygon may be extracted");
2968 gser_in = PG_GETARG_GSERIALIZED_P(0);
2975 if (lwg_in->
type == extype || !extype)
2978 PG_RETURN_POINTER(gser_in);
2984 PG_RETURN_POINTER(geometry_serialize(lwg_out));
2990 gser_out = geometry_serialize(lwg_out);
2993 PG_RETURN_POINTER(gser_out);
3009 PG_FREE_IF_COPY(input, 0);
3013 output = geometry_serialize(lwoutput);
3016 PG_FREE_IF_COPY(input, 0);
3017 PG_RETURN_POINTER(output);
3024 GSERIALIZED *g_in = PG_GETARG_GSERIALIZED_P_COPY(0);
3027 LWGEOM *lwgeom_in = NULL;
3028 double tolerance = 0.0;
3033 PG_RETURN_POINTER(g_in);
3035 if (PG_NARGS() > 1 && !PG_ARGISNULL(1))
3036 tolerance = PG_GETARG_FLOAT8(1);
3043 PG_RETURN_POINTER(g_in);
3046 g_out = geometry_serialize(lwgeom_in);
3049 PG_RETURN_POINTER(g_out);
3056 GSERIALIZED *in = PG_GETARG_GSERIALIZED_P_COPY(0);
3061 out = geometry_serialize(lwgeom);
3064 PG_FREE_IF_COPY(in, 0);
3066 PG_RETURN_POINTER(out);
3072 if (n ==
'x' || n ==
'X')
3074 if (n ==
'y' || n ==
'Y')
3076 if (n ==
'z' || n ==
'Z')
3078 if (n ==
'm' || n ==
'M')
3080 lwpgerror(
"Invalid ordinate name '%c'. Expected x,y,z or m", n);
3094 ospec = PG_GETARG_CSTRING(1);
3095 if (strlen(ospec) != 2)
3098 "Invalid ordinate specification. "
3099 "Need two letters from the set (x,y,z,m). "
3107 in = PG_GETARG_GSERIALIZED_P_COPY(0);
3112 lwpgerror(
"Geometry does not have an M ordinate");
3117 lwpgerror(
"Geometry does not have a Z ordinate");
3123 PG_RETURN_POINTER(in);
3127 out = geometry_serialize(lwgeom);
3129 PG_FREE_IF_COPY(in, 0);
3130 PG_RETURN_POINTER(out);
3141 bool fits = PG_GETARG_BOOL(1);
3142 LWGEOM *lwgeom_out = NULL;
3154 GSERIALIZED *geom_in = PG_GETARG_GSERIALIZED_P(0);
3159 srid = lwgeom_in->
srid;
3190 geom_out = geometry_serialize(lwgeom_out);
3193 PG_RETURN_POINTER(geom_out);
3201 GSERIALIZED *geom_scale = PG_GETARG_GSERIALIZED_P(1);
3203 LWGEOM *lwg, *lwg_scale, *lwg_origin;
3204 LWPOINT *lwpt_scale, *lwpt_origin;
3207 bool translate =
false;
3217 PG_FREE_IF_COPY(geom_scale, 1);
3218 lwpgerror(
"Scale factor geometry parameter must be a point");
3223 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
3231 PG_FREE_IF_COPY(geom_scale, 1);
3232 PG_RETURN_POINTER(geom);
3245 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
3247 geom_origin = PG_GETARG_GSERIALIZED_P(2);
3257 PG_FREE_IF_COPY(geom_origin, 2);
3264 memset(&aff, 0,
sizeof(
AFFINE));
3268 aff.
xoff = -1 * origin.
x;
3269 aff.
yoff = -1 * origin.
y;
3270 aff.
zoff = -1 * origin.
z;
3286 ret = geometry_serialize(lwg);
3288 PG_FREE_IF_COPY(geom, 0);
3289 PG_FREE_IF_COPY(geom_scale, 1);
3290 PG_RETURN_POINTER(ret);
3297 if (PG_ARGISNULL(0))
3312 PG_RETURN_POINTER(ret);
3327 if (PG_ARGISNULL(0))
3329 if (PG_ARGISNULL(1))
3331 lwpgerror(
"Must specify precision");
3336 prec_x = PG_GETARG_INT32(1);
3338 prec_y = PG_ARGISNULL(2) ? prec_x : PG_GETARG_INT32(2);
3339 prec_z = PG_ARGISNULL(3) ? prec_x : PG_GETARG_INT32(3);
3340 prec_m = PG_ARGISNULL(4) ? prec_x : PG_GETARG_INT32(4);
3342 input = PG_GETARG_GSERIALIZED_P_COPY(0);
3348 result = geometry_serialize(g);
3350 PG_FREE_IF_COPY(input, 0);
3351 PG_RETURN_POINTER(
result);
3368 if (PG_NARGS() > 0 && !PG_ARGISNULL(0))
3370 geom_in = PG_GETARG_GSERIALIZED_P(0);
3377 if (PG_NARGS() > 1 && !PG_ARGISNULL(1))
3378 min = PG_GETARG_FLOAT8(1);
3383 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
3384 max = PG_GETARG_FLOAT8(2);
3389 if (PG_NARGS() > 3 && !PG_ARGISNULL(3) && PG_GETARG_BOOL(3))
3398 elog(ERROR,
"Min-value cannot be larger than Max value\n");
3408 elog(NOTICE,
"No M-value, No vertex removed\n");
3409 PG_RETURN_POINTER(geom_in);
3414 geom_out = geometry_serialize(lwgeom_out);
3416 PG_RETURN_POINTER(geom_out);
3424 LWGEOM *lwgeom, *lwresult;
3426 geom1 = PG_GETARG_GSERIALIZED_P(0);
3438 result = geometry_serialize(lwresult);
3443 PG_RETURN_POINTER(
result);
char result[OUT_DOUBLE_BUFFER_SIZE]
int gbox_merge(const GBOX *new_box, GBOX *merge_box)
Update the merged GBOX to be large enough to include itself and the new box.
void gbox_expand(GBOX *g, double d)
Move the box minimums down and the maximums up by the distance provided.
void gbox_init(GBOX *gbox)
Zero out all the entries in the GBOX.
void gbox_expand_xyzm(GBOX *g, double dx, double dy, double dz, double dm)
Move the box minimums down and the maximums up by the distances provided.
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
void gserialized_error_if_srid_mismatch(const GSERIALIZED *g1, const GSERIALIZED *g2, const char *funcname)
void gserialized_error_if_srid_mismatch_reference(const GSERIALIZED *g1, const int32_t srid2, const char *funcname)
int gserialized_has_bbox(const GSERIALIZED *g)
Check if a GSERIALIZED has a bounding box without deserializing first.
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
int gserialized_ndims(const GSERIALIZED *g)
Return the number of dimensions (2, 3, 4) in a geometry.
uint32_t gserialized_get_version(const GSERIALIZED *g)
Return the serialization version.
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or calculate it if necessary.
int gserialized_has_m(const GSERIALIZED *g)
Check if a GSERIALIZED has an M ordinate.
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
int gserialized_has_z(const GSERIALIZED *g)
Check if a GSERIALIZED has a Z ordinate.
uint64_t gserialized_get_sortable_hash(const GSERIALIZED *g)
Return a sortable key based on gserialized.
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2)
Return -1 if g1 is "less than" g2, 1 if g1 is "greater than" g2 and 0 if g1 and g2 are the "same".
int gserialized_datum_get_internals_p(Datum gsdatum, GBOX *gbox, lwflags_t *flags, uint8_t *type, int32_t *srid)
Peak into a GSERIALIZED datum to find its bounding box and some other metadata.
void lwgeom_refresh_bbox(LWGEOM *lwgeom)
Drop current bbox and calculate a fresh one.
int lwpoint_getPoint4d_p(const LWPOINT *point, POINT4D *out)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
uint32_t lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
LWPOINT * lwpoint_make4d(int32_t srid, double x, double y, double z, double m)
LWGEOM * lwgeom_closest_point(const LWGEOM *lw1, const LWGEOM *lw2)
double lwgeom_maxdistance2d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing max distance calculation.
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
LWPOINT * lwpoint_make2d(int32_t srid, double x, double y)
void lwmpoint_free(LWMPOINT *mpt)
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
void lwgeom_trim_bits_in_place(LWGEOM *geom, int32_t prec_x, int32_t prec_y, int32_t prec_z, int32_t prec_m)
Trim the bits of an LWGEOM in place, to optimize it for compression.
void lwpoint_free(LWPOINT *pt)
void lwgeom_longitude_shift(LWGEOM *lwgeom)
void lwgeom_free(LWGEOM *geom)
double lwgeom_maxdistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d max distance calculations and dfullywithin calculations.
LWGEOM * lwgeom_filter_m(LWGEOM *geom, double min, double max, int returnm)
LWPOINT * lwpoint_make3dm(int32_t srid, double x, double y, double m)
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
double lwgeom_perimeter_2d(const LWGEOM *geom)
lwvarlena_t * lwgeom_geohash(const LWGEOM *lwgeom, int precision)
Calculate the GeoHash (http://geohash.org) string for a geometry.
int lwpoint_inside_circle(const LWPOINT *p, double cx, double cy, double rad)
LWGEOM * lwgeom_segmentize2d(const LWGEOM *line, double dist)
LWGEOM * lwgeom_furthest_line_3d(LWGEOM *lw1, LWGEOM *lw2)
LWGEOM * lwgeom_closest_point_3d(const LWGEOM *lw1, const LWGEOM *lw2)
LWGEOM * lwmpoint_as_lwgeom(const LWMPOINT *obj)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
LWGEOM * lwgeom_force_sfs(LWGEOM *geom, int version)
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
int lwgeom_remove_repeated_points_in_place(LWGEOM *in, double tolerance)
LWGEOM * lwgeom_force_3dm(const LWGEOM *geom, double mval)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
LWGEOM * lwgeom_force_4d(const LWGEOM *geom, double zval, double mval)
double lwgeom_length(const LWGEOM *geom)
const char * lwgeom_version(void)
Return lwgeom version string (not to be freed)
LWGEOM * lwgeom_force_3dz(const LWGEOM *geom, double zval)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
int lwgeom_isfinite(const LWGEOM *lwgeom)
Check if a LWGEOM has any non-finite (NaN or Inf) coordinates.
#define FLAGS_GET_Z(flags)
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
void lwgeom_scale(LWGEOM *geom, const POINT4D *factors)
char * lwgeom_summary(const LWGEOM *lwgeom, int offset)
LWPOLY * lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4)
double lwgeom_area(const LWGEOM *geom)
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
LWPOINT * lwpoint_project(const LWPOINT *lwpoint1, double distance, double azimuth)
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
LWGEOM * lwgeom_homogenize(const LWGEOM *geom)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
LWGEOM * lwgeom_as_curve(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate CURVE* type.
LWCOLLECTION * lwcollection_extract(const LWCOLLECTION *col, uint32_t type)
LWGEOM * lwgeom_normalize(const LWGEOM *geom)
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
LWPOINT * lwpoint_make3dz(int32_t srid, double x, double y, double z)
double lwgeom_mindistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d min distance calculations and dwithin calculations.
void lwgeom_swap_ordinates(LWGEOM *in, LWORD o1, LWORD o2)
Swap ordinate values in every vertex of the geometry.
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
LWGEOM * lwgeom_closest_line(const LWGEOM *lw1, const LWGEOM *lw2)
LWGEOM * lwgeom_boundary(LWGEOM *lwgeom)
#define POLYHEDRALSURFACETYPE
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
LWPOINT * lwpoint_project_lwpoint(const LWPOINT *lwpoint1, const LWPOINT *lwpoint2, double distance)
double lwgeom_length_2d(const LWGEOM *geom)
uint32_t lwgeom_count_rings(const LWGEOM *geom)
Count the total number of rings in any LWGEOM.
double lwgeom_mindistance2d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing min distance calculation.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
#define FLAGS_GET_M(flags)
void lwgeom_force_clockwise(LWGEOM *lwgeom)
Force Right-hand-rule on LWGEOM polygons.
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
LWLINE * lwline_from_lwmpoint(int32_t srid, const LWMPOINT *mpoint)
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
void lwline_setPoint4d(LWLINE *line, uint32_t which, POINT4D *newpoint)
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE,...
LWMPOINT * lwmpoint_from_lwgeom(const LWGEOM *g)
LWGEOM * lwgeom_furthest_line(const LWGEOM *lw1, const LWGEOM *lw2)
void * lwalloc(size_t size)
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
double lwgeom_maxdistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling max distance calculations and dfullywithin calculations.
LWGEOM * lwgeom_wrapx(const LWGEOM *lwgeom, double cutx, double amount)
wrap geometry on given cut x value
void lwpoly_free(LWPOLY *poly)
#define LW_TRUE
Return types for functions with status returns.
double lwgeom_maxdistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d max distance calculation.
#define SRID_UNKNOWN
Unknown SRID value.
double lwgeom_perimeter(const LWGEOM *geom)
LWPOLY * lwpoly_from_lwlines(const LWLINE *shell, uint32_t nholes, const LWLINE **holes)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
LWLINE * lwline_extend(const LWLINE *line, double distance_forward, double distance_backward)
Extend the ends of a line.
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
LWGEOM * lwgeom_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
LWLINE * lwline_removepoint(LWLINE *line, uint32_t which)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
void lwline_free(LWLINE *line)
LWLINE * lwline_from_lwgeom_array(int32_t srid, uint32_t ngeoms, LWGEOM **geoms)
LWGEOM * lwgeom_closest_line_3d(const LWGEOM *lw1, const LWGEOM *lw2)
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
int lwline_add_lwpoint(LWLINE *line, LWPOINT *point, uint32_t where)
Add a LWPOINT to an LWLINE.
void lwgeom_drop_srid(LWGEOM *lwgeom)
void lwgeom_reverse_in_place(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
double lwgeom_mindistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d min distance calculation.
lwvarlena_t * lwgeom_to_wkt_varlena(const LWGEOM *geom, uint8_t variant, int precision)
enum LWORD_T LWORD
Ordinate names.
This library is the generic geometry handling section of PostGIS.
double lwline_length_2d(const LWLINE *line)
#define OUT_DEFAULT_DECIMAL_DIGITS
int lwline_is_empty(const LWLINE *line)
int ptarray_scroll_in_place(POINTARRAY *pa, const POINT4D *newbase)
char lwpoint_same2d(const LWPOINT *p1, const LWPOINT *p2)
Datum LWGEOM_FilterByM(PG_FUNCTION_ARGS)
Datum LWGEOM_isempty(PG_FUNCTION_ARGS)
Datum LWGEOM_perimeter2d_poly(PG_FUNCTION_ARGS)
Datum LWGEOM_force_3dm(PG_FUNCTION_ARGS)
Datum LWGEOM_force_2d(PG_FUNCTION_ARGS)
Datum ST_PointZM(PG_FUNCTION_ARGS)
Datum LWGEOM_makepoly(PG_FUNCTION_ARGS)
Datum LWGEOM_makepoint(PG_FUNCTION_ARGS)
Datum ST_3DIntersects(PG_FUNCTION_ARGS)
Datum LWGEOM_force_3dz(PG_FUNCTION_ARGS)
Datum LWGEOM_force_multi(PG_FUNCTION_ARGS)
Datum ST_Scroll(PG_FUNCTION_ARGS)
Datum LWGEOM_segmentize2d(PG_FUNCTION_ARGS)
Datum ST_PointM(PG_FUNCTION_ARGS)
Datum LWGEOM_dfullywithin3d(PG_FUNCTION_ARGS)
Datum ST_Area(PG_FUNCTION_ARGS)
Datum ST_CollectionHomogenize(PG_FUNCTION_ARGS)
Datum LWGEOM_shortestline3d(PG_FUNCTION_ARGS)
Datum postgis_lib_revision(PG_FUNCTION_ARGS)
Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS)
Datum LWGEOM_dfullywithin(PG_FUNCTION_ARGS)
Datum LWGEOM_removepoint(PG_FUNCTION_ARGS)
Datum LWGEOM_noop(PG_FUNCTION_ARGS)
Datum postgis_scripts_released(PG_FUNCTION_ARGS)
Datum geometry_project_direction(PG_FUNCTION_ARGS)
Datum LWGEOM_affine(PG_FUNCTION_ARGS)
Datum ST_RemoveRepeatedPoints(PG_FUNCTION_ARGS)
Datum ST_BoundingDiagonal(PG_FUNCTION_ARGS)
Datum LWGEOM_longitude_shift(PG_FUNCTION_ARGS)
Datum ST_PointZ(PG_FUNCTION_ARGS)
Datum ST_QuantizeCoordinates(PG_FUNCTION_ARGS)
Datum postgis_version(PG_FUNCTION_ARGS)
Datum postgis_liblwgeom_version(PG_FUNCTION_ARGS)
Datum LWGEOM_force_4d(PG_FUNCTION_ARGS)
Datum LWGEOM_nrings(PG_FUNCTION_ARGS)
Datum ST_Points(PG_FUNCTION_ARGS)
Datum LWGEOM_zmflag(PG_FUNCTION_ARGS)
Datum ST_GeoHash(PG_FUNCTION_ARGS)
Datum ST_TileEnvelope(PG_FUNCTION_ARGS)
Datum ST_IsCollection(PG_FUNCTION_ARGS)
Datum ST_3DDistance(PG_FUNCTION_ARGS)
Datum LWGEOM_mem_size(PG_FUNCTION_ARGS)
Datum postgis_svn_version(PG_FUNCTION_ARGS)
Datum LWGEOM_makeline(PG_FUNCTION_ARGS)
Datum LWGEOM_ndims(PG_FUNCTION_ARGS)
Datum ST_Scale(PG_FUNCTION_ARGS)
Datum LWGEOM_force_curve(PG_FUNCTION_ARGS)
Datum LWGEOM_setpoint_linestring(PG_FUNCTION_ARGS)
Datum LWGEOM_dwithin3d(PG_FUNCTION_ARGS)
Datum _ST_SortableHash(PG_FUNCTION_ARGS)
Datum LWGEOM_shortestline2d(PG_FUNCTION_ARGS)
Datum LWGEOM_perimeter_poly(PG_FUNCTION_ARGS)
Datum LWGEOM_envelope(PG_FUNCTION_ARGS)
Datum LWGEOM_force_collection(PG_FUNCTION_ARGS)
Datum ST_MakeEnvelope(PG_FUNCTION_ARGS)
Datum LWGEOM_force_clockwise_poly(PG_FUNCTION_ARGS)
Datum LWGEOM_hasm(PG_FUNCTION_ARGS)
Datum LWGEOM_to_BOX(PG_FUNCTION_ARGS)
Datum LWGEOM_azimuth(PG_FUNCTION_ARGS)
Datum ST_Normalize(PG_FUNCTION_ARGS)
Datum optimistic_overlap(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(LWGEOM_mem_size)
find the size of geometry
Datum ST_CollectionExtract(PG_FUNCTION_ARGS)
Datum LWGEOM_asEWKT(PG_FUNCTION_ARGS)
Datum LWGEOM_angle(PG_FUNCTION_ARGS)
Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS)
Datum postgis_lib_build_date(PG_FUNCTION_ARGS)
Datum ST_Point(PG_FUNCTION_ARGS)
Datum geometry_project_geometry(PG_FUNCTION_ARGS)
Datum boundary(PG_FUNCTION_ARGS)
Datum LWGEOM_line_from_mpoint(PG_FUNCTION_ARGS)
Datum LWGEOM_collect(PG_FUNCTION_ARGS)
Datum LWGEOM_collect_garray(PG_FUNCTION_ARGS)
Datum LWGEOM_hasBBOX(PG_FUNCTION_ARGS)
Datum LWGEOM_same(PG_FUNCTION_ARGS)
Datum ST_SwapOrdinates(PG_FUNCTION_ARGS)
Datum LWGEOM_reverse(PG_FUNCTION_ARGS)
Datum LWGEOM_hasz(PG_FUNCTION_ARGS)
Datum postgis_lib_version(PG_FUNCTION_ARGS)
Datum LWGEOM_addpoint(PG_FUNCTION_ARGS)
Datum LWGEOM_longestline2d(PG_FUNCTION_ARGS)
Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS)
Datum LWGEOM_force_sfs(PG_FUNCTION_ARGS)
Datum LWGEOM_length2d_linestring(PG_FUNCTION_ARGS)
Datum ST_FlipCoordinates(PG_FUNCTION_ARGS)
Datum LWGEOM_closestpoint(PG_FUNCTION_ARGS)
Datum LWGEOM_expand(PG_FUNCTION_ARGS)
Datum ST_Distance(PG_FUNCTION_ARGS)
Datum LWGEOM_longestline3d(PG_FUNCTION_ARGS)
Datum LWGEOM_length_linestring(PG_FUNCTION_ARGS)
Datum geometry_line_extend(PG_FUNCTION_ARGS)
static LWORD ordname2ordval(char n)
Datum LWGEOM_npoints(PG_FUNCTION_ARGS)
Datum ST_WrapX(PG_FUNCTION_ARGS)
Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS)
Datum LWGEOM_dwithin(PG_FUNCTION_ARGS)
Datum LWGEOM_mindistance3d(PG_FUNCTION_ARGS)
Datum postgis_libxml_version(PG_FUNCTION_ARGS)
Datum LWGEOM_maxdistance3d(PG_FUNCTION_ARGS)
Datum LWGEOM_closestpoint3d(PG_FUNCTION_ARGS)
Datum LWGEOM_summary(PG_FUNCTION_ARGS)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
static double distance(double x1, double y1, double x2, double y2)
#define POSTGIS_LIB_VERSION
#define POSTGIS_LIBXML2_VERSION