PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ containsproperly()

Datum containsproperly ( PG_FUNCTION_ARGS  )

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

References PrepGeomCache::argnum, covers(), error_if_srid_mismatch(), errorIfGeometryCollection(), FALSE, gbox_contains_2d(), GetPrepGeomCache(), gserialized_get_gbox_p(), gserialized_get_srid(), gserialized_is_empty(), HANDLE_GEOS_ERROR, lwgeom_geos_error(), PG_FUNCTION_INFO_V1(), POSTGIS2GEOS(), and PrepGeomCache::prepared_geom.

Referenced by contains().

1940 {
1941  GSERIALIZED * geom1;
1942  GSERIALIZED * geom2;
1943  char result;
1944  GBOX box1, box2;
1945  PrepGeomCache * prep_cache;
1946 
1947  geom1 = PG_GETARG_GSERIALIZED_P(0);
1948  geom2 = PG_GETARG_GSERIALIZED_P(1);
1949 
1950  errorIfGeometryCollection(geom1,geom2);
1952 
1953  /* A.ContainsProperly(Empty) == FALSE */
1954  if ( gserialized_is_empty(geom1) || gserialized_is_empty(geom2) )
1955  PG_RETURN_BOOL(false);
1956 
1957  /*
1958  * short-circuit: if geom2 bounding box is not completely inside
1959  * geom1 bounding box we can prematurely return FALSE.
1960  */
1961  if ( gserialized_get_gbox_p(geom1, &box1) &&
1962  gserialized_get_gbox_p(geom2, &box2) )
1963  {
1964  if ( ! gbox_contains_2d(&box1, &box2) )
1965  PG_RETURN_BOOL(FALSE);
1966  }
1967 
1968  initGEOS(lwpgnotice, lwgeom_geos_error);
1969 
1970  prep_cache = GetPrepGeomCache( fcinfo, geom1, 0 );
1971 
1972  if ( prep_cache && prep_cache->prepared_geom && prep_cache->argnum == 1 )
1973  {
1974  GEOSGeometry *g = (GEOSGeometry *)POSTGIS2GEOS(geom2);
1975  if ( 0 == g ) /* exception thrown at construction */
1976  {
1977  HANDLE_GEOS_ERROR("First argument geometry could not be converted to GEOS");
1978  PG_RETURN_NULL();
1979  }
1980  result = GEOSPreparedContainsProperly( prep_cache->prepared_geom, g);
1981  GEOSGeom_destroy(g);
1982  }
1983  else
1984  {
1985  GEOSGeometry *g2;
1986  GEOSGeometry *g1;
1987 
1988  g1 = (GEOSGeometry *)POSTGIS2GEOS(geom1);
1989  if ( 0 == g1 ) /* exception thrown at construction */
1990  {
1991  HANDLE_GEOS_ERROR("First argument geometry could not be converted to GEOS");
1992  PG_RETURN_NULL();
1993  }
1994  g2 = (GEOSGeometry *)POSTGIS2GEOS(geom2);
1995  if ( 0 == g2 ) /* exception thrown at construction */
1996  {
1997  HANDLE_GEOS_ERROR("Second argument geometry could not be converted to GEOS");
1998  GEOSGeom_destroy(g1);
1999  PG_RETURN_NULL();
2000  }
2001  result = GEOSRelatePattern( g1, g2, "T**FF*FF*" );
2002  GEOSGeom_destroy(g1);
2003  GEOSGeom_destroy(g2);
2004  }
2005 
2006  if (result == 2)
2007  {
2008  HANDLE_GEOS_ERROR("GEOSContains");
2009  PG_RETURN_NULL(); /* never get here */
2010  }
2011 
2012  PG_FREE_IF_COPY(geom1, 0);
2013  PG_FREE_IF_COPY(geom2, 1);
2014 
2015  PG_RETURN_BOOL(result);
2016 }
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.
Definition: g_serialized.c:642
PrepGeomCache * GetPrepGeomCache(FunctionCallInfo fcinfo, GSERIALIZED *g1, GSERIALIZED *g2)
Given a couple potential geometries and a function call context, return a prepared structure for one ...
const GEOSPreparedGeometry * prepared_geom
int gbox_contains_2d(const GBOX *g1, const GBOX *g2)
Return LW_TRUE if the first GBOX contains the second on the 2d plane, LW_FALSE otherwise.
Definition: g_box.c:351
void error_if_srid_mismatch(int srid1, int srid2)
Definition: lwutil.c:371
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
Definition: g_serialized.c:179
void lwgeom_geos_error(const char *fmt,...)
#define FALSE
Definition: dbfopen.c:168
GEOSGeometry * POSTGIS2GEOS(GSERIALIZED *pglwgeom)
#define HANDLE_GEOS_ERROR(label)
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)...
Definition: g_serialized.c:100
void errorIfGeometryCollection(GSERIALIZED *g1, GSERIALIZED *g2)
Throws an ereport ERROR if either geometry is a COLLECTIONTYPE.
Here is the call graph for this function:
Here is the caller graph for this function: