28 #include "utils/elog.h" 29 #include "utils/array.h" 30 #include "utils/geo_decls.h" 32 #include "../postgis_config.h" 34 #include "lwgeom_pg.h" 123 size_t size = VARSIZE(geom);
124 PG_FREE_IF_COPY(geom,0);
125 PG_RETURN_INT32(size);
142 mytext = cstring2text(result);
145 PG_FREE_IF_COPY(geom,0);
146 PG_RETURN_TEXT_P(mytext);
152 char *ver = POSTGIS_VERSION;
153 text *result = cstring2text(ver);
154 PG_RETURN_TEXT_P(result);
161 text *result = cstring2text(ver);
162 PG_RETURN_TEXT_P(result);
169 text *result = cstring2text(ver);
170 PG_RETURN_TEXT_P(result);
176 static int rev = POSTGIS_SVN_REVISION;
180 snprintf(ver, 32,
"%d", rev);
181 PG_RETURN_TEXT_P(cstring2text(ver));
190 char *ver = POSTGIS_BUILD_DATE;
191 text *result = cstring2text(ver);
192 PG_RETURN_TEXT_P(result);
204 result = cstring2text(ver);
205 PG_RETURN_TEXT_P(result);
211 PG_RETURN_BOOL(
TRUE);
217 #ifdef POSTGIS_AUTOCACHE_BBOX 218 PG_RETURN_BOOL(
TRUE);
220 PG_RETURN_BOOL(
FALSE);
229 text *result = cstring2text(ver);
230 PG_RETURN_TEXT_P(result);
244 PG_FREE_IF_COPY(geom, 0);
245 PG_RETURN_INT32(npoints);
259 PG_FREE_IF_COPY(geom, 0);
260 PG_RETURN_INT32(nrings);
276 POSTGIS_DEBUG(2,
"in LWGEOM_area_polygon");
281 PG_FREE_IF_COPY(geom, 0);
283 PG_RETURN_FLOAT8(area);
300 PG_FREE_IF_COPY(geom, 0);
301 PG_RETURN_FLOAT8(dist);
318 PG_FREE_IF_COPY(geom, 0);
319 PG_RETURN_FLOAT8(dist);
334 double perimeter = 0.0;
337 PG_FREE_IF_COPY(geom, 0);
338 PG_RETURN_FLOAT8(perimeter);
353 double perimeter = 0.0;
356 PG_FREE_IF_COPY(geom, 0);
357 PG_RETURN_FLOAT8(perimeter);
365 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
378 PG_FREE_IF_COPY(pg_geom_in, 0);
379 PG_RETURN_POINTER(pg_geom_out);
386 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
392 PG_RETURN_POINTER(pg_geom_in);
400 PG_FREE_IF_COPY(pg_geom_in, 0);
401 PG_RETURN_POINTER(pg_geom_out);
408 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
414 PG_RETURN_POINTER(pg_geom_in);
422 PG_FREE_IF_COPY(pg_geom_in, 0);
423 PG_RETURN_POINTER(pg_geom_out);
430 GSERIALIZED *pg_geom_in = PG_GETARG_GSERIALIZED_P(0);
436 PG_RETURN_POINTER(pg_geom_in);
444 PG_FREE_IF_COPY(pg_geom_in, 0);
445 PG_RETURN_POINTER(pg_geom_out);
459 POSTGIS_DEBUG(2,
"LWGEOM_force_collection called");
469 PG_RETURN_POINTER(geom);
489 lwgeoms = palloc(
sizeof(
LWGEOM*));
499 PG_FREE_IF_COPY(geom, 0);
500 PG_RETURN_POINTER(result);
512 POSTGIS_DEBUG(2,
"LWGEOM_force_multi called");
529 PG_RETURN_POINTER(geom);
541 PG_FREE_IF_COPY(geom, 0);
543 PG_RETURN_POINTER(result);
555 POSTGIS_DEBUG(2,
"LWGEOM_force_curve called");
564 PG_FREE_IF_COPY(geom, 0);
566 PG_RETURN_POINTER(result);
580 POSTGIS_DEBUG(2,
"LWGEOM_force_sfs called");
583 if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
585 ver = PG_GETARG_TEXT_P(1);
587 if ( ! strncmp(VARDATA(ver),
"1.2", 3))
598 PG_FREE_IF_COPY(geom, 0);
600 PG_RETURN_POINTER(result);
629 PG_FREE_IF_COPY(geom1, 0);
630 PG_FREE_IF_COPY(geom2, 1);
631 PG_RETURN_POINTER(result);
659 PG_FREE_IF_COPY(geom1, 0);
660 PG_FREE_IF_COPY(geom2, 1);
661 PG_RETURN_POINTER(result);
689 PG_FREE_IF_COPY(geom1, 0);
690 PG_FREE_IF_COPY(geom2, 1);
691 PG_RETURN_POINTER(result);
712 PG_FREE_IF_COPY(geom1, 0);
713 PG_FREE_IF_COPY(geom2, 1);
717 PG_RETURN_FLOAT8(mindist);
733 double tolerance = PG_GETARG_FLOAT8(2);
739 elog(ERROR,
"Tolerance cannot be less than zero\n");
747 PG_FREE_IF_COPY(geom1, 0);
748 PG_FREE_IF_COPY(geom2, 1);
751 PG_RETURN_BOOL(tolerance >= mindist);
765 double tolerance = PG_GETARG_FLOAT8(2);
771 elog(ERROR,
"Tolerance cannot be less than zero\n");
779 PG_FREE_IF_COPY(geom1, 0);
780 PG_FREE_IF_COPY(geom2, 1);
784 PG_RETURN_BOOL(tolerance >= maxdist);
805 PG_FREE_IF_COPY(geom1, 0);
806 PG_FREE_IF_COPY(geom2, 1);
810 PG_RETURN_FLOAT8(maxdist);
843 PG_FREE_IF_COPY(geom1, 0);
844 PG_FREE_IF_COPY(geom2, 1);
845 PG_RETURN_POINTER(result);
875 PG_FREE_IF_COPY(geom1, 0);
876 PG_FREE_IF_COPY(geom2, 1);
877 PG_RETURN_POINTER(result);
907 PG_FREE_IF_COPY(geom1, 0);
908 PG_FREE_IF_COPY(geom2, 1);
909 PG_RETURN_POINTER(result);
927 PG_FREE_IF_COPY(geom1, 0);
928 PG_FREE_IF_COPY(geom2, 1);
932 PG_RETURN_FLOAT8(mindist);
948 double tolerance = PG_GETARG_FLOAT8(2);
954 elog(ERROR,
"Tolerance cannot be less than zero\n");
962 PG_FREE_IF_COPY(geom1, 0);
963 PG_FREE_IF_COPY(geom2, 1);
967 PG_RETURN_BOOL(tolerance >= mindist);
981 double tolerance = PG_GETARG_FLOAT8(2);
987 elog(ERROR,
"Tolerance cannot be less than zero\n");
994 PG_FREE_IF_COPY(geom1, 0);
995 PG_FREE_IF_COPY(geom2, 1);
999 PG_RETURN_BOOL(tolerance >= maxdist);
1020 PG_FREE_IF_COPY(geom1, 0);
1021 PG_FREE_IF_COPY(geom2, 1);
1025 PG_RETURN_FLOAT8(maxdist);
1038 POSTGIS_DEBUG(2,
"LWGEOM_longitude_shift called.");
1040 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
1058 PG_RETURN_POINTER(ret);
1066 LWGEOM *lwgeom_in, *lwgeom_out;
1071 POSTGIS_DEBUG(2,
"ST_WrapX called.");
1073 gdatum = PG_GETARG_DATUM(0);
1074 cutx = PG_GETARG_FLOAT8(1);
1075 amount = PG_GETARG_FLOAT8(2);
1079 geom_in = ((
GSERIALIZED *)PG_DETOAST_DATUM(gdatum));
1087 PG_FREE_IF_COPY(geom_in, 0);
1089 PG_RETURN_POINTER(geom_out);
1096 double cx = PG_GETARG_FLOAT8(1);
1097 double cy = PG_GETARG_FLOAT8(2);
1098 double rr = PG_GETARG_FLOAT8(3);
1103 geom = PG_GETARG_GSERIALIZED_P(0);
1108 PG_FREE_IF_COPY(geom, 0);
1115 PG_FREE_IF_COPY(geom, 0);
1116 PG_RETURN_BOOL(inside);
1130 LWGEOM *lwgeoms[2], *outlwg;
1131 uint32 type1, type2;
1135 POSTGIS_DEBUG(2,
"LWGEOM_collect called.");
1138 if ( PG_ARGISNULL(0) && PG_ARGISNULL(1) )
1142 if (PG_ARGISNULL(0))
1143 PG_RETURN_DATUM(PG_GETARG_DATUM(1));
1146 if (PG_ARGISNULL(1))
1147 PG_RETURN_DATUM(PG_GETARG_DATUM(0));
1149 gser1 = PG_GETARG_GSERIALIZED_P(0);
1150 gser2 = PG_GETARG_GSERIALIZED_P(1);
1156 elog(ERROR,
"Cannot ST_Collect geometries with differing dimensionality.");
1166 type1 = lwgeoms[0]->
type;
1167 type2 = lwgeoms[1]->
type;
1174 POSTGIS_DEBUGF(3,
" outtype = %d", outtype);
1188 PG_FREE_IF_COPY(gser1, 0);
1189 PG_FREE_IF_COPY(gser2, 1);
1191 PG_RETURN_POINTER(result);
1211 LWGEOM **lwgeoms, *outlwg;
1217 ArrayIterator iterator;
1221 POSTGIS_DEBUG(2,
"LWGEOM_collect_garray called.");
1223 if ( PG_ARGISNULL(0) )
1227 array = PG_GETARG_ARRAYTYPE_P(0);
1228 nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1230 POSTGIS_DEBUGF(3,
" array is %d-bytes in size, %ld w/out header",
1231 ARR_SIZE(array), ARR_SIZE(array)-ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1233 POSTGIS_DEBUGF(3,
"LWGEOM_collect_garray: array has %d elements", nelems);
1243 lwgeoms = palloc(
sizeof(
LWGEOM*) * nelems);
1247 #if POSTGIS_PGSQL_VERSION >= 95 1248 iterator = array_create_iterator(array, 0, NULL);
1250 iterator = array_create_iterator(array, 0);
1253 while( array_iterate(iterator, &value, &isnull) )
1267 POSTGIS_DEBUGF(3,
"%s: geom %d deserialized", __func__, count);
1275 if ( lwgeoms[count]->bbox )
1288 if ( lwgeoms[count]->bbox )
1318 array_free_iterator(iterator);
1321 POSTGIS_DEBUGF(3,
"LWGEOM_collect_garray: outtype = %d", outtype);
1332 box, count, lwgeoms);
1336 PG_RETURN_POINTER(result);
1351 POSTGIS_DEBUG(2,
"LWGEOM_line_from_mpoint called");
1354 ingeom = PG_GETARG_GSERIALIZED_P(0);
1358 elog(ERROR,
"makeline: input must be a multipoint");
1366 PG_FREE_IF_COPY(ingeom, 0);
1367 elog(ERROR,
"makeline: lwline_from_lwmpoint returned NULL");
1373 PG_FREE_IF_COPY(ingeom, 0);
1376 PG_RETURN_POINTER(result);
1395 ArrayIterator iterator;
1399 POSTGIS_DEBUGF(2,
"%s called", __func__);
1402 if ( PG_ARGISNULL(0) )
1406 array = PG_GETARG_ARRAYTYPE_P(0);
1409 nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1411 POSTGIS_DEBUGF(3,
"%s: array has %d elements", __func__, nelems);
1425 geoms = palloc(
sizeof(
LWGEOM *) * nelems);
1428 #if POSTGIS_PGSQL_VERSION >= 95 1429 iterator = array_create_iterator(array, 0, NULL);
1431 iterator = array_create_iterator(array, 0);
1434 while( array_iterate(iterator, &value, &isnull) )
1456 srid = geoms[ngeoms-1]->
srid;
1464 POSTGIS_DEBUGF(3,
"%s: element %d deserialized", __func__, ngeoms);
1466 array_free_iterator(iterator);
1472 elog(NOTICE,
"No points or linestrings in input array");
1476 POSTGIS_DEBUGF(3,
"LWGEOM_makeline_garray: elements: %d", ngeoms);
1482 PG_RETURN_POINTER(result);
1497 POSTGIS_DEBUG(2,
"LWGEOM_makeline called.");
1500 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
1501 pglwg2 = PG_GETARG_GSERIALIZED_P(1);
1506 elog(ERROR,
"Input geometries must be points or lines");
1519 PG_FREE_IF_COPY(pglwg1, 0);
1520 PG_FREE_IF_COPY(pglwg2, 1);
1524 PG_RETURN_POINTER(result);
1535 ArrayType *array=NULL;
1537 const LWLINE *shell=NULL;
1538 const LWLINE **holes=NULL;
1544 POSTGIS_DEBUG(2,
"LWGEOM_makepoly called.");
1547 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
1550 lwpgerror(
"Shell is not a line");
1555 if ( PG_NARGS() > 1 )
1557 array = PG_GETARG_ARRAYTYPE_P(1);
1558 nholes = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1560 for (i=0; i<nholes; i++)
1564 offset += INTALIGN(VARSIZE(g));
1567 lwpgerror(
"Hole %d is not a line", i);
1579 PG_FREE_IF_COPY(pglwg1, 0);
1581 for (i=0; i<nholes; i++)
1586 PG_RETURN_POINTER(result);
1604 POSTGIS_DEBUG(2,
"LWGEOM_expand called.");
1610 PG_RETURN_POINTER(geom);
1617 PG_RETURN_POINTER(geom);
1620 if (PG_NARGS() == 2)
1623 double d = PG_GETARG_FLOAT8(1);
1628 double dx = PG_GETARG_FLOAT8(1);
1629 double dy = PG_GETARG_FLOAT8(2);
1630 double dz = PG_GETARG_FLOAT8(3);
1631 double dm = PG_GETARG_FLOAT8(4);
1653 PG_FREE_IF_COPY(geom, 0);
1655 PG_RETURN_POINTER(result);
1662 GSERIALIZED *pg_lwgeom = PG_GETARG_GSERIALIZED_P(0);
1676 PG_FREE_IF_COPY(pg_lwgeom, 0);
1683 out->low.x = gbox.
xmin;
1684 out->low.y = gbox.
ymin;
1685 out->high.x = gbox.
xmax;
1686 out->high.y = gbox.
ymax;
1687 PG_RETURN_POINTER(out);
1700 int srid = lwgeom->
srid;
1710 PG_RETURN_POINTER(geom);
1716 PG_RETURN_POINTER(geom);
1786 PG_FREE_IF_COPY(geom, 0);
1788 PG_RETURN_POINTER(result);
1799 PG_FREE_IF_COPY(geom, 0);
1800 PG_RETURN_BOOL(empty);
1815 LWGEOM *inlwgeom, *outlwgeom;
1818 POSTGIS_DEBUG(2,
"LWGEOM_segmentize2d called");
1820 ingeom = PG_GETARG_GSERIALIZED_P(0);
1821 dist = PG_GETARG_FLOAT8(1);
1831 PG_RETURN_POINTER(ingeom);
1837 elog(ERROR,
"ST_Segmentize: invalid max_distance %g (must be >= 0)", dist);
1848 PG_RETURN_POINTER(ingeom);
1852 if ( ! outlwgeom ) {
1854 PG_FREE_IF_COPY(ingeom, 0);
1859 if ( inlwgeom->
bbox )
1867 PG_FREE_IF_COPY(ingeom, 0);
1869 PG_RETURN_POINTER(outgeom);
1879 POSTGIS_DEBUG(2,
"LWGEOM_reverse called");
1881 geom = PG_GETARG_GSERIALIZED_P_COPY(0);
1888 PG_RETURN_POINTER(geom);
1898 POSTGIS_DEBUG(2,
"LWGEOM_force_clockwise_poly called");
1900 ingeom = PG_GETARG_GSERIALIZED_P_COPY(0);
1908 PG_FREE_IF_COPY(ingeom, 0);
1909 PG_RETURN_POINTER(outgeom);
1919 POSTGIS_DEBUG(2,
"LWGEOM_noop called");
1921 in = PG_GETARG_GSERIALIZED_P(0);
1925 POSTGIS_DEBUGF(3,
"Deserialized: %s",
lwgeom_summary(lwgeom, 0));
1930 PG_FREE_IF_COPY(in, 0);
1932 PG_RETURN_POINTER(out);
1940 LWGEOM *lwgeom_in, *lwgeom_out;
1942 POSTGIS_DEBUG(2,
"ST_Normalize called");
1944 in = PG_GETARG_GSERIALIZED_P_COPY(0);
1947 POSTGIS_DEBUGF(3,
"Deserialized: %s",
lwgeom_summary(lwgeom_in, 0));
1950 POSTGIS_DEBUGF(3,
"Normalized: %s",
lwgeom_summary(lwgeom_out, 0));
1956 PG_FREE_IF_COPY(in, 0);
1958 PG_RETURN_POINTER(out);
1975 in = PG_GETARG_GSERIALIZED_P(0);
1978 PG_FREE_IF_COPY(in, 0);
1979 PG_RETURN_INT16(ret);
2002 PG_FREE_IF_COPY(in, 0);
2003 PG_RETURN_BOOL(res);
2013 in = PG_GETARG_GSERIALIZED_P(0);
2015 PG_FREE_IF_COPY(in, 0);
2016 PG_RETURN_INT16(ret);
2030 PG_FREE_IF_COPY(g1, 0);
2031 PG_FREE_IF_COPY(g2, 1);
2032 PG_RETURN_BOOL(
FALSE);
2037 PG_FREE_IF_COPY(g1, 0);
2038 PG_FREE_IF_COPY(g2, 1);
2039 PG_RETURN_BOOL(
FALSE);
2052 PG_FREE_IF_COPY(g1, 0);
2053 PG_FREE_IF_COPY(g2, 1);
2055 PG_RETURN_BOOL(result);
2063 double x1, y1, x2, y2;
2066 POSTGIS_DEBUG(2,
"ST_MakeEnvelope called");
2068 x1 = PG_GETARG_FLOAT8(0);
2069 y1 = PG_GETARG_FLOAT8(1);
2070 x2 = PG_GETARG_FLOAT8(2);
2071 y2 = PG_GETARG_FLOAT8(3);
2072 if ( PG_NARGS() > 4 ) {
2073 srid = PG_GETARG_INT32(4);
2081 PG_RETURN_POINTER(result);
2093 size = VARHDRSZ + 8 + 32 + 4;
2095 geom = PG_GETARG_GSERIALIZED_P_SLICE(0, 0, size);
2108 POSTGIS_DEBUG(2,
"LWGEOM_makepoint called");
2110 x = PG_GETARG_FLOAT8(0);
2111 y = PG_GETARG_FLOAT8(1);
2114 else if ( PG_NARGS() == 3 )
2116 z = PG_GETARG_FLOAT8(2);
2119 else if ( PG_NARGS() == 4 )
2121 z = PG_GETARG_FLOAT8(2);
2122 m = PG_GETARG_FLOAT8(3);
2127 elog(ERROR,
"LWGEOM_makepoint: unsupported number of args: %d",
2134 PG_RETURN_POINTER(result);
2144 POSTGIS_DEBUG(2,
"LWGEOM_makepoint3dm called.");
2146 x = PG_GETARG_FLOAT8(0);
2147 y = PG_GETARG_FLOAT8(1);
2148 m = PG_GETARG_FLOAT8(2);
2153 PG_RETURN_POINTER(result);
2164 POSTGIS_DEBUGF(2,
"%s called.", __func__);
2166 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
2167 pglwg2 = PG_GETARG_GSERIALIZED_P(1);
2169 if ( PG_NARGS() > 2 )
2171 where = PG_GETARG_INT32(2);
2176 elog(ERROR,
"First argument must be a LINESTRING");
2182 elog(ERROR,
"Second argument must be a POINT");
2191 elog(ERROR,
"Invalid offset");
2201 elog(ERROR,
"Point insert failed");
2208 PG_FREE_IF_COPY(pglwg1, 0);
2209 PG_FREE_IF_COPY(pglwg2, 1);
2212 PG_RETURN_POINTER(result);
2223 POSTGIS_DEBUG(2,
"LWGEOM_removepoint called.");
2225 pglwg1 = PG_GETARG_GSERIALIZED_P(0);
2226 which = PG_GETARG_INT32(1);
2230 elog(ERROR,
"First argument must be a LINESTRING");
2238 elog(ERROR,
"Point index out of range (%d..%d)", 0, line->
points->
npoints-1);
2244 elog(ERROR,
"Can't remove points from a single segment line");
2255 PG_FREE_IF_COPY(pglwg1, 0);
2256 PG_RETURN_POINTER(result);
2269 POSTGIS_DEBUG(2,
"LWGEOM_setpoint_linestring called.");
2272 pglwg1 = PG_GETARG_GSERIALIZED_P_COPY(0);
2274 which = PG_GETARG_INT32(1);
2275 pglwg2 = PG_GETARG_GSERIALIZED_P(2);
2283 elog(ERROR,
"Third argument must be a POINT");
2288 PG_FREE_IF_COPY(pglwg2, 2);
2294 elog(ERROR,
"First argument must be a LINESTRING");
2303 elog(ERROR,
"abs(Point index) out of range (-)(%d..%d)", 0, line->
points->
npoints-1);
2317 PG_RETURN_POINTER(result);
2330 POSTGIS_DEBUG(2,
"LWGEOM_asEWKT called.");
2332 geom = PG_GETARG_GSERIALIZED_P(0);
2340 result = cstring2text(wkt);
2344 PG_FREE_IF_COPY(geom, 0);
2345 PG_RETURN_TEXT_P(result);
2364 geom = PG_GETARG_GSERIALIZED_P(0);
2368 PG_FREE_IF_COPY(geom, 0);
2369 lwpgerror(
"Argument must be POINT geometries");
2372 srid = lwpoint->
srid;
2375 PG_FREE_IF_COPY(geom, 0);
2376 lwpgerror(
"Error extracting point");
2380 PG_FREE_IF_COPY(geom, 0);
2383 geom = PG_GETARG_GSERIALIZED_P(1);
2387 PG_FREE_IF_COPY(geom, 1);
2388 lwpgerror(
"Argument must be POINT geometries");
2391 if ( lwpoint->
srid != srid )
2393 PG_FREE_IF_COPY(geom, 1);
2394 lwpgerror(
"Operation on mixed SRID geometries");
2399 PG_FREE_IF_COPY(geom, 1);
2400 lwpgerror(
"Error extracting point");
2404 PG_FREE_IF_COPY(geom, 1);
2407 if ( (p1.
x == p2.
x) && (p1.
y == p2.
y) )
2418 PG_RETURN_FLOAT8(result);
2431 GSERIALIZED *pg_geom1 = PG_GETARG_GSERIALIZED_P(0);
2432 GSERIALIZED *pg_geom2 = PG_GETARG_GSERIALIZED_P(1);
2433 double dist = PG_GETARG_FLOAT8(2);
2444 elog(ERROR,
"optimistic_overlap: first arg isn't a polygon\n");
2450 elog(ERROR,
"optimistic_overlap: 2nd arg isn't a [multi-]polygon\n");
2457 g1_bvol.
xmin = g1_bvol.
xmin - dist;
2458 g1_bvol.
ymin = g1_bvol.
ymin - dist;
2459 g1_bvol.
xmax = g1_bvol.
xmax + dist;
2460 g1_bvol.
ymax = g1_bvol.
ymax + dist;
2467 PG_RETURN_BOOL(
FALSE);
2474 calc_dist = DatumGetFloat8 ( DirectFunctionCall2(
LWGEOM_mindistance2d, PointerGetDatum( pg_geom1 ), PointerGetDatum( pg_geom2 )));
2476 PG_RETURN_BOOL(calc_dist < dist);
2489 affine.
afac = PG_GETARG_FLOAT8(1);
2490 affine.
bfac = PG_GETARG_FLOAT8(2);
2491 affine.
cfac = PG_GETARG_FLOAT8(3);
2492 affine.
dfac = PG_GETARG_FLOAT8(4);
2493 affine.
efac = PG_GETARG_FLOAT8(5);
2494 affine.
ffac = PG_GETARG_FLOAT8(6);
2495 affine.
gfac = PG_GETARG_FLOAT8(7);
2496 affine.
hfac = PG_GETARG_FLOAT8(8);
2497 affine.
ifac = PG_GETARG_FLOAT8(9);
2498 affine.
xoff = PG_GETARG_FLOAT8(10);
2499 affine.
yoff = PG_GETARG_FLOAT8(11);
2500 affine.
zoff = PG_GETARG_FLOAT8(12);
2502 POSTGIS_DEBUG(2,
"LWGEOM_affine called.");
2516 PG_FREE_IF_COPY(geom, 0);
2518 PG_RETURN_POINTER(ret);
2527 char *geohash = NULL;
2528 text *result = NULL;
2530 if ( PG_ARGISNULL(0) )
2535 geom = PG_GETARG_GSERIALIZED_P(0);
2537 if ( ! PG_ARGISNULL(1) )
2539 precision = PG_GETARG_INT32(1);
2547 result = cstring2text(geohash);
2550 PG_RETURN_TEXT_P(result);
2560 int type = PG_GETARG_INT32(1);
2561 int lwgeom_type = lwgeom->
type;
2567 elog(ERROR,
"ST_CollectionExtract: only point, linestring and polygon may be extracted");
2575 if(lwgeom_type == type)
2578 PG_RETURN_POINTER(input);
2602 PG_RETURN_POINTER(output);
2619 PG_FREE_IF_COPY(input, 0);
2625 PG_FREE_IF_COPY(input, 0);
2626 PG_RETURN_POINTER(output);
2636 LWGEOM *lwgeom_in = NULL;
2637 LWGEOM *lwgeom_out = NULL;
2638 double tolerance = 0.0;
2642 PG_RETURN_POINTER(g_in);
2644 if ( PG_NARGS() > 1 && ! PG_ARGISNULL(1) )
2645 tolerance = PG_GETARG_FLOAT8(1);
2651 if (lwgeom_in->
bbox)
2659 if ( lwgeom_out != lwgeom_in )
2666 PG_FREE_IF_COPY(g_in, 0);
2667 PG_RETURN_POINTER(g_out);
2674 GSERIALIZED *in = PG_GETARG_GSERIALIZED_P_COPY(0);
2682 PG_FREE_IF_COPY(in, 0);
2684 PG_RETURN_POINTER(out);
2689 if ( n ==
'x' || n ==
'X' )
return LWORD_X;
2690 if ( n ==
'y' || n ==
'Y' )
return LWORD_Y;
2691 if ( n ==
'z' || n ==
'Z' )
return LWORD_Z;
2692 if ( n ==
'm' || n ==
'M' )
return LWORD_M;
2693 lwpgerror(
"Invalid ordinate name '%c'. Expected x,y,z or m", n);
2707 ospec = PG_GETARG_CSTRING(1);
2708 if ( strlen(ospec) != 2 )
2710 lwpgerror(
"Invalid ordinate specification. " 2711 "Need two letters from the set (x,y,z,m). " 2718 in = PG_GETARG_GSERIALIZED_P_COPY(0);
2723 lwpgerror(
"Geometry does not have an M ordinate");
2728 lwpgerror(
"Geometry does not have a Z ordinate");
2733 if ( o1 == o2 ) PG_RETURN_POINTER(in);
2739 PG_FREE_IF_COPY(in, 0);
2740 PG_RETURN_POINTER(out);
2750 GSERIALIZED *geom_in = PG_GETARG_GSERIALIZED_P(0);
2752 bool fits = PG_GETARG_BOOL(1);
2758 int srid = lwgeom_in->
srid;
2764 lwgeom_in->
bbox = NULL;
2790 PG_FREE_IF_COPY(geom_in, 0);
2795 PG_RETURN_POINTER(geom_out);
2802 GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P_COPY(0);
2811 if ( lwpoint == NULL )
2815 PG_FREE_IF_COPY(geom1, 0);
2816 PG_FREE_IF_COPY(geom2, 1);
2817 lwpgerror(
"Scale factor geometry parameter must be a point");
2825 PG_FREE_IF_COPY(geom2, 1);
2826 PG_RETURN_POINTER(geom1);
2840 PG_FREE_IF_COPY(geom1, 0);
2841 PG_FREE_IF_COPY(geom2, 1);
2843 PG_RETURN_POINTER(ret);
2850 if (PG_ARGISNULL(0))
2865 PG_RETURN_POINTER(ret);
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box)
Read the bounding box off a serialization and calculate one if it is not already there.
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Datum LWGEOM_mem_size(PG_FUNCTION_ARGS)
double lwgeom_mindistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d min distance calculations and dwithin calculations.
Datum LWGEOM_collect_garray(PG_FUNCTION_ARGS)
Datum ST_FlipCoordinates(PG_FUNCTION_ARGS)
Datum LWGEOM_npoints(PG_FUNCTION_ARGS)
Datum LWGEOM_force_multi(PG_FUNCTION_ARGS)
Datum LWGEOM_length2d_linestring(PG_FUNCTION_ARGS)
Datum LWGEOM_expand(PG_FUNCTION_ARGS)
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.
int lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
LWGEOM * lwgeom_closest_point(const LWGEOM *lw1, const LWGEOM *lw2)
Datum LWGEOM_maxdistance3d(PG_FUNCTION_ARGS)
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM can contain sub-geometries or not.
LWCOLLECTION * lwcollection_extract(LWCOLLECTION *col, int type)
Takes a potentially heterogeneous collection and returns a homogeneous collection consisting only of ...
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Datum ST_CollectionHomogenize(PG_FUNCTION_ARGS)
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Datum LWGEOM_to_BOX(PG_FUNCTION_ARGS)
Datum LWGEOM_force_2d(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
double lwgeom_maxdistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling max distance calculations and dfyllywithin calculations.
Datum LWGEOM_longestline2d(PG_FUNCTION_ARGS)
Datum ST_BoundingDiagonal(PG_FUNCTION_ARGS)
double lwgeom_mindistance2d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling min distance calculations and dwithin calculations.
LWGEOM * lwgeom_force_4d(const LWGEOM *geom)
void gbox_expand(GBOX *g, double d)
Move the box minimums down and the maximums up by the distance provided.
double lwgeom_mindistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d min distance calculation.
Datum LWGEOM_shortestline3d(PG_FUNCTION_ARGS)
int gserialized_has_m(const GSERIALIZED *gser)
Check if a GSERIALIZED has an M ordinate.
Datum LWGEOM_maxdistance2d_linestring(PG_FUNCTION_ARGS)
Datum LWGEOM_noop(PG_FUNCTION_ARGS)
Datum ST_WrapX(PG_FUNCTION_ARGS)
LWPOINT * lwpoint_make2d(int srid, double x, double y)
Datum area(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_force_3dz(const LWGEOM *geom)
Datum LWGEOM_makepoly(PG_FUNCTION_ARGS)
Datum LWGEOM_setpoint_linestring(PG_FUNCTION_ARGS)
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
void lwpoint_free(LWPOINT *pt)
void lwgeom_free(LWGEOM *geom)
Datum LWGEOM_removepoint(PG_FUNCTION_ARGS)
Datum LWGEOM_perimeter_poly(PG_FUNCTION_ARGS)
Datum postgis_lib_build_date(PG_FUNCTION_ARGS)
Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS)
void lwline_free(LWLINE *line)
LWGEOM * lwgeom_wrapx(const LWGEOM *lwgeom, double cutx, double amount)
wrap geometry on given cut x value
void lwgeom_scale(LWGEOM *geom, const POINT4D *factors)
Datum LWGEOM_shortestline2d(PG_FUNCTION_ARGS)
Datum LWGEOM_mindistance3d(PG_FUNCTION_ARGS)
int gserialized_ndims(const GSERIALIZED *gser)
Return the number of dimensions (2, 3, 4) in a geometry.
void lwgeom_swap_ordinates(LWGEOM *in, LWORD o1, LWORD o2)
Swap ordinate values in every vertex of the geometry.
#define FLAGS_GET_ZM(flags)
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Datum ST_Normalize(PG_FUNCTION_ARGS)
Datum LWGEOM_closestpoint(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_closest_line_3d(const LWGEOM *lw1, const LWGEOM *lw2)
Datum ST_RemoveRepeatedPoints(PG_FUNCTION_ARGS)
#define POSTGIS_LIB_VERSION
Datum postgis_liblwgeom_version(PG_FUNCTION_ARGS)
#define POLYHEDRALSURFACETYPE
LWMPOINT * lwmpoint_from_lwgeom(const LWGEOM *g)
int lwpoint_inside_circle(const LWPOINT *p, double cx, double cy, double rad)
Datum LWGEOM_perimeter2d_poly(PG_FUNCTION_ARGS)
Datum LWGEOM_hasBBOX(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Datum LWGEOM_length_linestring(PG_FUNCTION_ARGS)
void error_if_srid_mismatch(int srid1, int srid2)
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
Datum ST_CollectionExtract(PG_FUNCTION_ARGS)
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
int gserialized_has_bbox(const GSERIALIZED *gser)
Check if a GSERIALIZED has a bounding box without deserializing first.
LWGEOM * lwgeom_furthest_line_3d(LWGEOM *lw1, LWGEOM *lw2)
LWGEOM * lwgeom_force_sfs(LWGEOM *geom, int version)
double lwgeom_length_2d(const LWGEOM *geom)
int gserialized_has_z(const GSERIALIZED *gser)
Check if a GSERIALIZED has a Z ordinate.
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Datum LWGEOM_summary(PG_FUNCTION_ARGS)
void lwline_setPoint4d(LWLINE *line, uint32_t which, POINT4D *newpoint)
Datum LWGEOM_line_from_mpoint(PG_FUNCTION_ARGS)
Datum ST_Points(PG_FUNCTION_ARGS)
Datum LWGEOM_affine(PG_FUNCTION_ARGS)
void lwgeom_longitude_shift(LWGEOM *lwgeom)
double lwgeom_perimeter(const LWGEOM *geom)
Datum LWGEOM_closestpoint3d(PG_FUNCTION_ARGS)
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.
Datum ST_SwapOrdinates(PG_FUNCTION_ARGS)
Datum postgis_svn_version(PG_FUNCTION_ARGS)
double lwgeom_maxdistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
Function handling 3d max distance calculations and dfullywithin calculations.
LWGEOM * lwgeom_closest_point_3d(const LWGEOM *lw1, const LWGEOM *lw2)
LWPOINT * lwpoint_make3dm(int srid, double x, double y, double m)
Datum ST_IsCollection(PG_FUNCTION_ARGS)
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...
Datum postgis_lib_version(PG_FUNCTION_ARGS)
LWPOLY * lwpoly_construct_envelope(int srid, double x1, double y1, double x2, double y2)
void lwgeom_force_clockwise(LWGEOM *lwgeom)
Ensure the outer ring is clockwise oriented and all inner rings are counter-clockwise.
void lwmpoint_free(LWMPOINT *mpt)
Datum postgis_version(PG_FUNCTION_ARGS)
Datum postgis_scripts_released(PG_FUNCTION_ARGS)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Datum LWGEOM_dwithin(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_homogenize(const LWGEOM *geom)
Datum ST_MakeEnvelope(PG_FUNCTION_ARGS)
Datum LWGEOM_longestline3d(PG_FUNCTION_ARGS)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
void gbox_init(GBOX *gbox)
Zero out all the entries in the GBOX.
Datum postgis_uses_stats(PG_FUNCTION_ARGS)
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, then a duplicate point will not be added.
Datum LWGEOM_azimuth(PG_FUNCTION_ARGS)
Datum LWGEOM_force_3dm(PG_FUNCTION_ARGS)
LWPOLY * lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
void lwpoly_free(LWPOLY *poly)
static LWORD ordname2ordval(char n)
const char * lwgeom_version(void)
Return lwgeom version string (not to be freed)
#define LW_TRUE
Return types for functions with status returns.
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
LWLINE * lwline_from_lwmpoint(int srid, const LWMPOINT *mpoint)
#define SRID_UNKNOWN
Unknown SRID value.
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Datum LWGEOM_segmentize2d(PG_FUNCTION_ARGS)
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
LWPOINT * lwpoint_make3dz(int srid, double x, double y, double z)
double lwgeom_maxdistance2d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initialazing max distance calculation.
Datum ST_GeoHash(PG_FUNCTION_ARGS)
Datum ST_Scale(PG_FUNCTION_ARGS)
Datum LWGEOM_reverse(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_furthest_line(const LWGEOM *lw1, const LWGEOM *lw2)
enum LWORD_T LWORD
Ordinate names.
Datum LWGEOM_same(PG_FUNCTION_ARGS)
Datum LWGEOM_force_sfs(PG_FUNCTION_ARGS)
Datum LWGEOM_force_clockwise_poly(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_normalize(const LWGEOM *geom)
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Datum LWGEOM_addpoint(PG_FUNCTION_ARGS)
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
LWGEOM * lwgeom_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Datum LWGEOM_force_curve(PG_FUNCTION_ARGS)
Datum LWGEOM_force_collection(PG_FUNCTION_ARGS)
Datum LWGEOM_hasz(PG_FUNCTION_ARGS)
Datum LWGEOM_force_3dz(PG_FUNCTION_ARGS)
Datum LWGEOM_force_4d(PG_FUNCTION_ARGS)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
#define POSTGIS_LIBXML2_VERSION
Datum LWGEOM_dwithin3d(PG_FUNCTION_ARGS)
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Datum LWGEOM_collect(PG_FUNCTION_ARGS)
int lwgeom_count_rings(const LWGEOM *geom)
Count the total number of rings in any LWGEOM.
PG_FUNCTION_INFO_V1(LWGEOM_mem_size)
find the size of geometry
Datum LWGEOM_dfullywithin3d(PG_FUNCTION_ARGS)
Datum LWGEOM_zmflag(PG_FUNCTION_ARGS)
Datum LWGEOM_dfullywithin(PG_FUNCTION_ARGS)
Datum LWGEOM_isempty(PG_FUNCTION_ARGS)
int gserialized_get_zm(const GSERIALIZED *gser)
Return a number indicating presence of Z and M coordinates.
double lwgeom_perimeter_2d(const LWGEOM *geom)
void lwgeom_reverse(LWGEOM *lwgeom)
Reverse vertex order of LWGEOM.
LWPOLY * lwpoly_from_lwlines(const LWLINE *shell, uint32_t nholes, const LWLINE **holes)
LWLINE * lwline_from_lwgeom_array(int srid, uint32_t ngeoms, LWGEOM **geoms)
Datum optimistic_overlap(PG_FUNCTION_ARGS)
char * lwgeom_geohash(const LWGEOM *lwgeom, int precision)
Calculate the GeoHash (http://geohash.org) string for a geometry.
Datum LWGEOM_hasm(PG_FUNCTION_ARGS)
void lwgeom_drop_srid(LWGEOM *lwgeom)
LWPOINT * lwpoint_make4d(int srid, double x, double y, double z, double m)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum LWGEOM_area_polygon(PG_FUNCTION_ARGS)
double lwgeom_area(const LWGEOM *geom)
Datum postgis_libxml_version(PG_FUNCTION_ARGS)
double lwgeom_length(const LWGEOM *geom)
LWGEOM * lwgeom_segmentize2d(LWGEOM *line, double dist)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
double lwgeom_mindistance2d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initialazing min distance calculation.
#define FLAGS_GET_M(flags)
Datum LWGEOM_longitude_shift(PG_FUNCTION_ARGS)
Datum LWGEOM_mindistance2d(PG_FUNCTION_ARGS)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
void lwgeom_set_srid(LWGEOM *geom, int srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
LWGEOM * lwgeom_force_3dm(const LWGEOM *geom)
Datum LWGEOM_ndims(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Remove repeated points!
double lwgeom_maxdistance3d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing 3d max distance calculation.
LWGEOM * lwgeom_closest_line(const LWGEOM *lw1, const LWGEOM *lw2)
LWGEOM * lwgeom_as_curve(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate CURVE* type.
Datum LWGEOM_asEWKT(PG_FUNCTION_ARGS)
void * lwalloc(size_t size)
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
int lwline_add_lwpoint(LWLINE *line, LWPOINT *point, int where)
Add a LWPOINT to an LWLINE.
int lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Datum LWGEOM_nrings(PG_FUNCTION_ARGS)
Datum LWGEOM_makeline(PG_FUNCTION_ARGS)
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
LWLINE * lwline_removepoint(LWLINE *line, uint32_t which)
Datum LWGEOM_inside_circle_point(PG_FUNCTION_ARGS)
char * lwgeom_summary(const LWGEOM *lwgeom, int offset)
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Datum LWGEOM_makepoint(PG_FUNCTION_ARGS)
Datum LWGEOM_makepoint3dm(PG_FUNCTION_ARGS)
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
LWPOLY * lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4)
Datum postgis_autocache_bbox(PG_FUNCTION_ARGS)
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
This library is the generic geometry handling section of PostGIS.
Datum LWGEOM_envelope(PG_FUNCTION_ARGS)
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
LWGEOM * lwmpoint_as_lwgeom(const LWMPOINT *obj)