[postgis-tickets] r14613 - #75, Enhancement to PIP short circuit
Daniel Baston
dbaston at gmail.com
Thu Jan 21 15:03:31 PST 2016
Author: dbaston
Date: 2016-01-21 15:03:31 -0800 (Thu, 21 Jan 2016)
New Revision: 14613
Modified:
trunk/postgis/lwgeom_geos.c
trunk/regress/regress_ogc.sql
trunk/regress/regress_ogc_expected
Log:
#75, Enhancement to PIP short circuit
Modified: trunk/postgis/lwgeom_geos.c
===================================================================
--- trunk/postgis/lwgeom_geos.c 2016-01-20 12:18:14 UTC (rev 14612)
+++ trunk/postgis/lwgeom_geos.c 2016-01-21 23:03:31 UTC (rev 14613)
@@ -119,7 +119,49 @@
PG_RETURN_POINTER(result);
}
+static char
+is_poly(const GSERIALIZED* g)
+{
+ int type = gserialized_get_type(g);
+ return type == POLYGONTYPE || type == MULTIPOLYGONTYPE;
+}
+static char
+is_point(const GSERIALIZED* g)
+{
+ int type = gserialized_get_type(g);
+ return type == POINTTYPE || type == MULTIPOINTTYPE;
+}
+
+/* utility function that checks a LWPOINT and a GSERIALIZED poly against
+ * a cache. Serialized poly may be a multipart.
+ */
+static int
+pip_short_circuit(RTREE_POLY_CACHE* poly_cache, LWPOINT* point, GSERIALIZED* gpoly)
+{
+ int result;
+
+ if ( poly_cache && poly_cache->ringIndices )
+ {
+ result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCounts, point);
+ }
+ else
+ {
+ LWGEOM* poly = lwgeom_from_gserialized(gpoly);
+ if ( lwgeom_get_type(poly) == POLYGONTYPE )
+ {
+ result = point_in_polygon(lwgeom_as_lwpoly(poly), point);
+ }
+ else
+ {
+ result = point_in_multipolygon(lwgeom_as_lwmpoly(poly), point);
+ }
+ lwgeom_free(poly);
+ }
+
+ return result;
+}
+
/**
* @brief Compute the Hausdorff distance thanks to the corresponding GEOS function
* @example hausdorffdistance {@link #hausdorffdistance} - SELECT st_hausdorffdistance(
@@ -1663,10 +1705,6 @@
GSERIALIZED *geom2;
GEOSGeometry *g1, *g2;
GBOX box1, box2;
- int type1, type2;
- LWGEOM *lwgeom;
- LWPOINT *point;
- RTREE_POLY_CACHE *poly_cache;
int result;
PrepGeomCache *prep_cache;
@@ -1699,48 +1737,60 @@
** short-circuit 2: if geom2 is a point and geom1 is a polygon
** call the point-in-polygon function.
*/
- type1 = gserialized_get_type(geom1);
- type2 = gserialized_get_type(geom2);
- if ((type1 == POLYGONTYPE || type1 == MULTIPOLYGONTYPE) && type2 == POINTTYPE)
+ if (is_poly(geom1) && is_point(geom2))
{
+ GSERIALIZED* gpoly = is_poly(geom1) ? geom1 : geom2;
+ GSERIALIZED* gpoint = is_point(geom1) ? geom1 : geom2;
+ RTREE_POLY_CACHE* cache = GetRtreeCache(fcinfo, gpoly);
+ int retval;
+
POSTGIS_DEBUG(3, "Point in Polygon test requested...short-circuiting.");
- lwgeom = lwgeom_from_gserialized(geom1);
- point = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2));
+ if (gserialized_get_type(gpoint) == POINTTYPE)
+ {
+ LWGEOM* point = lwgeom_from_gserialized(gpoint);
+ int pip_result = pip_short_circuit(cache, lwgeom_as_lwpoint(point), gpoly);
+ lwgeom_free(point);
- POSTGIS_DEBUGF(3, "Precall point_in_multipolygon_rtree %p, %p", lwgeom, point);
+ retval = (pip_result == 1); /* completely inside */
+ }
+ else if (gserialized_get_type(gpoint) == MULTIPOINTTYPE)
+ {
+ LWMPOINT* mpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gpoint));
+ uint32_t i;
+ int found_completely_inside = LW_FALSE;
- poly_cache = GetRtreeCache(fcinfo, geom1);
+ retval = LW_TRUE;
+ for (i = 0; i < mpoint->ngeoms; i++)
+ {
+ /* We need to find at least one point that's completely inside the
+ * polygons (pip_result == 1). As long as we have one point that's
+ * completely inside, we can have as many as we want on the boundary
+ * itself. (pip_result == 0)
+ */
+ int pip_result = pip_short_circuit(cache, mpoint->geoms[i], gpoly);
+ if (pip_result == 1)
+ found_completely_inside = LW_TRUE;
- if ( poly_cache && poly_cache->ringIndices )
- {
- result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCounts, point);
+ if (pip_result == -1) /* completely outside */
+ {
+ retval = LW_FALSE;
+ break;
+ }
+ }
+
+ retval = retval && found_completely_inside;
+ lwmpoint_free(mpoint);
}
- else if ( type1 == POLYGONTYPE )
- {
- result = point_in_polygon((LWPOLY*)lwgeom, point);
- }
- else if ( type1 == MULTIPOLYGONTYPE )
- {
- result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
- }
else
{
- /* Gulp! Should not be here... */
- elog(ERROR,"Type isn't poly or multipoly!");
+ /* Never get here */
+ elog(ERROR,"Type isn't point or multipoint!");
PG_RETURN_NULL();
}
- lwgeom_free(lwgeom);
- lwpoint_free(point);
+
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
- if ( result == 1 ) /* completely inside */
- {
- PG_RETURN_BOOL(TRUE);
- }
- else
- {
- PG_RETURN_BOOL(FALSE);
- }
+ PG_RETURN_BOOL(retval);
}
else
{
@@ -1888,10 +1938,6 @@
GSERIALIZED *geom2;
int result;
GBOX box1, box2;
- int type1, type2;
- LWGEOM *lwgeom;
- LWPOINT *point;
- RTREE_POLY_CACHE *poly_cache;
PrepGeomCache *prep_cache;
geom1 = PG_GETARG_GSERIALIZED_P(0);
@@ -1920,50 +1966,50 @@
* short-circuit 2: if geom2 is a point and geom1 is a polygon
* call the point-in-polygon function.
*/
- type1 = gserialized_get_type(geom1);
- type2 = gserialized_get_type(geom2);
- if ((type1 == POLYGONTYPE || type1 == MULTIPOLYGONTYPE) && type2 == POINTTYPE)
+ if (is_poly(geom1) && is_point(geom2))
{
+ GSERIALIZED* gpoly = is_poly(geom1) ? geom1 : geom2;
+ GSERIALIZED* gpoint = is_point(geom1) ? geom1 : geom2;
+ RTREE_POLY_CACHE* cache = GetRtreeCache(fcinfo, gpoly);
+ int retval;
+
POSTGIS_DEBUG(3, "Point in Polygon test requested...short-circuiting.");
+ if (gserialized_get_type(gpoint) == POINTTYPE)
+ {
+ LWGEOM* point = lwgeom_from_gserialized(gpoint);
+ int pip_result = pip_short_circuit(cache, lwgeom_as_lwpoint(point), gpoly);
+ lwgeom_free(point);
- lwgeom = lwgeom_from_gserialized(geom1);
- point = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2));
+ retval = (pip_result != -1); /* not outside */
+ }
+ else if (gserialized_get_type(gpoint) == MULTIPOINTTYPE)
+ {
+ LWMPOINT* mpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gpoint));
+ uint32_t i;
- POSTGIS_DEBUGF(3, "Precall point_in_multipolygon_rtree %p, %p", lwgeom, point);
+ retval = LW_TRUE;
+ for (i = 0; i < mpoint->ngeoms; i++)
+ {
+ int pip_result = pip_short_circuit(cache, mpoint->geoms[i], gpoly);
+ if (pip_result == -1)
+ {
+ retval = LW_FALSE;
+ break;
+ }
+ }
- poly_cache = GetRtreeCache(fcinfo, geom1);
-
- if ( poly_cache && poly_cache->ringIndices )
- {
- result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCounts, point);
+ lwmpoint_free(mpoint);
}
- else if ( type1 == POLYGONTYPE )
- {
- result = point_in_polygon((LWPOLY*)lwgeom, point);
- }
- else if ( type1 == MULTIPOLYGONTYPE )
- {
- result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
- }
else
{
- /* Gulp! Should not be here... */
- elog(ERROR,"Type isn't poly or multipoly!");
+ /* Never get here */
+ elog(ERROR,"Type isn't point or multipoint!");
PG_RETURN_NULL();
}
- lwgeom_free(lwgeom);
- lwpoint_free(point);
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
- if ( result != -1 ) /* not outside */
- {
- PG_RETURN_BOOL(TRUE);
- }
- else
- {
- PG_RETURN_BOOL(FALSE);
- }
+ PG_RETURN_BOOL(retval);
}
else
{
@@ -2041,10 +2087,6 @@
GEOSGeometry *g1, *g2;
int result;
GBOX box1, box2;
- LWGEOM *lwgeom;
- LWPOINT *point;
- int type1, type2;
- RTREE_POLY_CACHE *poly_cache;
char *patt = "**F**F***";
geom1 = PG_GETARG_GSERIALIZED_P(0);
@@ -2075,49 +2117,55 @@
* short-circuit 2: if geom1 is a point and geom2 is a polygon
* call the point-in-polygon function.
*/
- type1 = gserialized_get_type(geom1);
- type2 = gserialized_get_type(geom2);
- if ((type2 == POLYGONTYPE || type2 == MULTIPOLYGONTYPE) && type1 == POINTTYPE)
+ if (is_point(geom1) && is_poly(geom2))
{
+ GSERIALIZED* gpoly = is_poly(geom1) ? geom1 : geom2;
+ GSERIALIZED* gpoint = is_point(geom1) ? geom1 : geom2;
+ RTREE_POLY_CACHE* cache = GetRtreeCache(fcinfo, gpoly);
+ int retval;
+
POSTGIS_DEBUG(3, "Point in Polygon test requested...short-circuiting.");
+ if (gserialized_get_type(gpoint) == POINTTYPE)
+ {
+ LWGEOM* point = lwgeom_from_gserialized(gpoint);
+ int pip_result = pip_short_circuit(cache, lwgeom_as_lwpoint(point), gpoly);
+ lwgeom_free(point);
- point = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom1));
- lwgeom = lwgeom_from_gserialized(geom2);
+ retval = (pip_result != -1); /* not outside */
+ }
+ else if (gserialized_get_type(gpoint) == MULTIPOINTTYPE)
+ {
+ LWMPOINT* mpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gpoint));
+ uint32_t i;
- poly_cache = GetRtreeCache(fcinfo, geom2);
+ retval = LW_TRUE;
+ for (i = 0; i < mpoint->ngeoms; i++)
+ {
+ int pip_result = pip_short_circuit(cache, mpoint->geoms[i], gpoly);
+ if (pip_result == -1)
+ {
+ retval = LW_FALSE;
+ break;
+ }
+ }
- if ( poly_cache && poly_cache->ringIndices )
- {
- result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCounts, point);
+ lwmpoint_free(mpoint);
}
- else if ( type2 == POLYGONTYPE )
- {
- result = point_in_polygon((LWPOLY*)lwgeom, point);
- }
- else if ( type2 == MULTIPOLYGONTYPE )
- {
- result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
- }
else
{
- /* Gulp! Should not be here... */
- elog(ERROR,"Type isn't poly or multipoly!");
+ /* Never get here */
+ elog(ERROR,"Type isn't point or multipoint!");
PG_RETURN_NULL();
}
- lwgeom_free(lwgeom);
- lwpoint_free(point);
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
- if ( result != -1 ) /* not outside */
- {
- PG_RETURN_BOOL(TRUE);
- }
- else
- {
- PG_RETURN_BOOL(FALSE);
- }
+ PG_RETURN_BOOL(retval);
}
+ else
+ {
+ POSTGIS_DEBUGF(3, "CoveredBy: type1: %d, type2: %d", type1, type2);
+ }
initGEOS(lwpgnotice, lwgeom_geos_error);
@@ -2223,19 +2271,13 @@
PG_RETURN_BOOL(result);
}
-
PG_FUNCTION_INFO_V1(geos_intersects);
Datum geos_intersects(PG_FUNCTION_ARGS)
{
GSERIALIZED *geom1;
GSERIALIZED *geom2;
- GSERIALIZED *serialized_poly;
int result;
GBOX box1, box2;
- int type1, type2, polytype;
- LWPOINT *point;
- LWGEOM *lwgeom;
- RTREE_POLY_CACHE *poly_cache;
PrepGeomCache *prep_cache;
geom1 = PG_GETARG_GSERIALIZED_P(0);
@@ -2265,61 +2307,50 @@
* short-circuit 2: if the geoms are a point and a polygon,
* call the point_outside_polygon function.
*/
- type1 = gserialized_get_type(geom1);
- type2 = gserialized_get_type(geom2);
- if ( (type1 == POINTTYPE && (type2 == POLYGONTYPE || type2 == MULTIPOLYGONTYPE)) ||
- (type2 == POINTTYPE && (type1 == POLYGONTYPE || type1 == MULTIPOLYGONTYPE)))
+ if ((is_point(geom1) && is_poly(geom2)) || (is_poly(geom1) && is_point(geom2)))
{
+ GSERIALIZED* gpoly = is_poly(geom1) ? geom1 : geom2;
+ GSERIALIZED* gpoint = is_point(geom1) ? geom1 : geom2;
+ RTREE_POLY_CACHE* cache = GetRtreeCache(fcinfo, gpoly);
+ int retval;
+
POSTGIS_DEBUG(3, "Point in Polygon test requested...short-circuiting.");
+ if (gserialized_get_type(gpoint) == POINTTYPE)
+ {
+ LWGEOM* point = lwgeom_from_gserialized(gpoint);
+ int pip_result = pip_short_circuit(cache, lwgeom_as_lwpoint(point), gpoly);
+ lwgeom_free(point);
- if ( type1 == POINTTYPE )
- {
- point = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom1));
- lwgeom = lwgeom_from_gserialized(geom2);
- serialized_poly = geom2;
- polytype = type2;
+ retval = (pip_result != -1); /* not outside */
}
- else
+ else if (gserialized_get_type(gpoint) == MULTIPOINTTYPE)
{
- point = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2));
- lwgeom = lwgeom_from_gserialized(geom1);
- serialized_poly = geom1;
- polytype = type1;
- }
+ LWMPOINT* mpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gpoint));
+ uint32_t i;
- poly_cache = GetRtreeCache(fcinfo, serialized_poly);
+ retval = LW_FALSE;
+ for (i = 0; i < mpoint->ngeoms; i++)
+ {
+ int pip_result = pip_short_circuit(cache, mpoint->geoms[i], gpoly);
+ if (pip_result != -1) /* not outside */
+ {
+ retval = LW_TRUE;
+ break;
+ }
+ }
- if ( poly_cache && poly_cache->ringIndices )
- {
- result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCounts, point);
+ lwmpoint_free(mpoint);
}
- else if ( polytype == POLYGONTYPE )
- {
- result = point_in_polygon((LWPOLY*)lwgeom, point);
- }
- else if ( polytype == MULTIPOLYGONTYPE )
- {
- result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
- }
else
{
- /* Gulp! Should not be here... */
- elog(ERROR,"Type isn't poly or multipoly!");
+ /* Never get here */
+ elog(ERROR,"Type isn't point or multipoint!");
PG_RETURN_NULL();
}
- lwgeom_free(lwgeom);
- lwpoint_free(point);
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
- if ( result != -1 ) /* not outside */
- {
- PG_RETURN_BOOL(TRUE);
- }
- else
- {
- PG_RETURN_BOOL(FALSE);
- }
+ PG_RETURN_BOOL(retval);
}
initGEOS(lwpgnotice, lwgeom_geos_error);
@@ -2409,7 +2440,7 @@
* geom1 bounding box we can prematurely return FALSE.
*/
if ( gserialized_get_gbox_p(geom1, &box1) &&
- gserialized_get_gbox_p(geom2, &box2) )
+ gserialized_get_gbox_p(geom2, &box2) )
{
if ( gbox_overlaps_2d(&box1, &box2) == LW_FALSE )
{
Modified: trunk/regress/regress_ogc.sql
===================================================================
--- trunk/regress/regress_ogc.sql 2016-01-20 12:18:14 UTC (rev 14612)
+++ trunk/regress/regress_ogc.sql 2016-01-21 23:03:31 UTC (rev 14613)
@@ -30,6 +30,15 @@
SELECT 'within105', ST_within(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
-- PIP - repeated vertex
SELECT 'within106', ST_within(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
+-- PIP - multipoint within polygon
+SELECT 'within107', ST_within('MULTIPOINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'within108', ST_within('MULTIPOINT(5 5, 5 7)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint on vertices of polygon
+SELECT 'within109', ST_within('MULTIPOINT(0 0, 10 10)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint partly outside of polygon
+SELECT 'within110', ST_within('MULTIPOINT(5 5, 15 7)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint not fully within polygon (but at least one point still fully within, so "within" passes)
+SELECT 'within111', ST_within('MULTIPOINT(5 5, 10 10)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
-- PIP - point within polygon
SELECT 'disjoint100', ST_disjoint('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
-- PIP - point on polygon vertex
@@ -72,6 +81,25 @@
SELECT 'intersects105', ST_intersects(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
-- PIP - repeated vertex
SELECT 'intersects106', ST_intersects(ST_GeomFromText('POINT(521543 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
+-- PIP - multipoint on polygon vertex
+SELECT 'intersects111', ST_Intersects('MULTIPOINT ((0 0))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint outside polygon
+SELECT 'intersects112', ST_intersects('MULTIPOINT ((-1 0))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint on polygon edge
+SELECT 'intersects113', ST_intersects('MULTIPOINT ((0 5))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'intersects114', ST_intersects('MULTIPOINT ((0 5), (0 8))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint in line with polygon edge
+SELECT 'intersects115', ST_intersects('MULTIPOINT ((0 12))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint vertically aligned with polygon vertex
+SELECT 'intersects116', ST_intersects(ST_GeomFromText('MULTIPOINT ((521513 5377804))', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
+-- PIP - repeated vertex
+SELECT 'intersects117', ST_intersects(ST_GeomFromText('MULTIPOINT ((521543 5377804))', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
+-- PIP - multipoint within polygon
+SELECT 'intersects118', ST_intersects('MULTIPOINT ((5 5))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'intersects119', ST_intersects('MULTIPOINT ((5 5), (7 7))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+-- PIP - multipoint partially within polygon
+SELECT 'intersects120', ST_intersects('MULTIPOINT ((5 5), (15 5))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'intersects121', ST_intersects('MULTIPOINT ((15 5), (5 5))'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
-- PIP - point within polygon
SELECT 'intersects150', ST_intersects('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
-- PIP - point on polygon vertex
@@ -100,11 +128,29 @@
SELECT 'contains105', ST_contains(ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631), ST_GeomFromText('POINT(521513 5377804)', 32631));
-- PIP - repeated vertex
SELECT 'contains106', ST_contains(ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631), ST_GeomFromText('POINT(521513 5377804)', 32631));
+-- PIP - multipoint within polygon
+SELECT 'contains110', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((5 5))'::geometry);
+-- PIP - multipoint on vertex of polygon
+SELECT 'contains111', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((0 0))'::geometry);
+SELECT 'contains112', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((0 0), (10 0))'::geometry);
+-- PIP - multipoint outside polygon
+SELECT 'contains113', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((-1 0))'::geometry);
+-- PIP - multipoint partially outside polygon
+SELECT 'contains114', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((-1 0), (5 5))'::geometry);
+SELECT 'contains115', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((5 5), (-1 0))'::geometry);
+-- PIP - point on edge of polygon
+SELECT 'contains116', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((0 5))'::geometry);
+-- PIP - point in line with polygon edge
+SELECT 'contains117', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((0 12))'::geometry);
+-- PIP - multipoint within polygon
+SELECT 'contains118', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((5 5), (7 7))'::geometry);
+-- PIP - point on edge of polygon and within
+SELECT 'contains119', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'MULTIPOINT ((0 5), (5 5))'::geometry);
-- moved here from regress.sql
select 'within119', ST_within('LINESTRING(-1 -1, -1 101, 101 101, 101 -1)'::GEOMETRY,'BOX3D(0 0, 100 100)'::BOX3D);
select 'within120', ST_within('LINESTRING(-1 -1, -1 100, 101 100, 101 -1)'::GEOMETRY,'BOX3D(0 0, 100 100)'::BOX3D);
-SELECT 'contains110', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'LINESTRING(1 10, 9 10, 9 8)'::geometry);
-SELECT 'contains111', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'LINESTRING(1 10, 10 10, 10 8)'::geometry);
+SELECT 'contains120', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'LINESTRING(1 10, 9 10, 9 8)'::geometry);
+SELECT 'contains121', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'LINESTRING(1 10, 10 10, 10 8)'::geometry);
SELECT 'within130', ST_Within('LINESTRING(1 10, 9 10, 9 8)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
SELECT 'within131', ST_Within('LINESTRING(1 10, 10 10, 10 8)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
SELECT 'overlaps', ST_overlaps('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry,'POINT(5 5)'::geometry);
Modified: trunk/regress/regress_ogc_expected
===================================================================
--- trunk/regress/regress_ogc_expected 2016-01-20 12:18:14 UTC (rev 14612)
+++ trunk/regress/regress_ogc_expected 2016-01-21 23:03:31 UTC (rev 14613)
@@ -16,6 +16,11 @@
within104|f
within105|t
within106|t
+within107|t
+within108|t
+within109|f
+within110|f
+within111|t
disjoint100|f
disjoint101|f
disjoint102|t
@@ -37,6 +42,17 @@
intersects104|f
intersects105|t
intersects106|f
+intersects111|t
+intersects112|f
+intersects113|t
+intersects114|t
+intersects115|f
+intersects116|t
+intersects117|f
+intersects118|t
+intersects119|t
+intersects120|t
+intersects121|t
intersects150|t
intersects151|t
intersects152|f
@@ -51,10 +67,20 @@
contains104|f
contains105|t
contains106|t
+contains110|t
+contains111|f
+contains112|f
+contains113|f
+contains114|f
+contains115|f
+contains116|f
+contains117|f
+contains118|t
+contains119|t
within119|f
within120|f
-contains110|t
-contains111|f
+contains120|t
+contains121|f
within130|t
within131|f
overlaps|f
More information about the postgis-tickets
mailing list