Commit 2f3f798c authored by Darafei Praliaskouski's avatar Darafei Praliaskouski

GiST and SP-GiST n-D indexes (based on GIDX) with overlaps, contains, within, and equals operators

Patch by Esteban Zimányi and Arthur Lesuisse from Université Libre de Bruxelles (ULB)

Closes https://github.com/postgis/postgis/pull/327
Closes https://github.com/postgis/postgis/pull/293
Closes #4230



git-svn-id: http://svn.osgeo.org/postgis/trunk@17001 b70326c6-7e19-0410-871a-916f4a2858ee
parent eced793c
Pipeline #36176462 passed with stage
in 33 minutes and 35 seconds
......@@ -9,8 +9,7 @@ env:
- tag=pg11-geos37-gdal23-proj52
- tag=pg10-geos36-gdal23-proj49
- tag=pg96-geos36-gdal22-proj49
- tag=pg95-geos36-gdal22-proj49
- tag=pg94-geos35-gdal111-proj48
- tag=pg95-geos35-gdal111-proj48
matrix:
allow_failures:
......
......@@ -2,33 +2,39 @@ PostGIS 3.0.0
2019/xx/xx
* Breaking Changes *
- #3888, Raster support now available as a separate extension
(Sandro Santilli)
(Sandro Santilli)
- #3807, Extension library files no longer include the minor version.
Use New configure switch --with-library-minor-version
if you need the old behavior (Regina Obe)
Use New configure switch --with-library-minor-version
if you need the old behavior (Regina Obe)
- #4230, ND box operators (overlaps, contains, within, equals) now don't look on
dimentions that aren't present in both operands.
Please REINDEX your ND indexes after upgrade.
* New Features *
- #2902, postgis_geos_noop (Sandro Santilli)
- #4128, ST_AsMVT support for Feature ID (Stepan Kuzmin)
- #4230, SP-GiST and GiST support for ND box operators overlaps, contains,
within, equals (Esteban Zimányi and Arthur Lesuisse from Université
Libre de Bruxelles (ULB), Darafei Praliaskouski)
* Enhancements and fixes *
- #4153, ST_Segmentize now splits segments proportionally (Darafei
Praliaskouski).
Praliaskouski).
- #4162, ST_DWithin documentation examples for storing geometry and
radius in table (Darafei Praliaskouski, github user Boscop).
radius in table (Darafei Praliaskouski, github user Boscop).
- #4161, MVT: Drop geometries smaller than the resolution (Raúl Marín)
- #4176, ST_Intersects supports GEOMETRYCOLLECTION (Darafei Praliaskouski)
- #4181, St_AsMVTGeom: Avoid type changes due to validation (Raúl Marín)
- #4183, St_AsMVTGeom: Drop invalid geometries after simplification (Raúl Marín)
- #4188, Avoid division by zero in kmeans (Raúl Marín)
- #4188, Avoid division by zero in KMeans (Raúl Marín)
- #4189, Fix undefined behaviour in SADFWrite (Raúl Marín)
- #4191, Fix undefined behaviour in ptarray_clone_deep (Raúl Marín)
- #4211, Fix ST_Subdivide for minimal exterior ring with minimal hole (Darafei
Praliaskouski)
Praliaskouski)
- #3457, Fix raster envelope shortcut in ST_Clip (Sai-bot)
- #4215, Use floating point compare in ST_DumpAsPolygons (Darafei Praliaskouski)
- #4155, Support for GEOMETRYCOLLECTION, POLYGON, TIN, TRIANGLE in
ST_LocateBetween and ST_LocateBetweenElevations (Darafei Praliaskouski)
ST_LocateBetween and ST_LocateBetweenElevations (Darafei Praliaskouski)
- #2767, Documentation for AddRasterConstraint optional parameters (Sunveer Singh)
PostGIS 2.5.0
......@@ -39,9 +45,9 @@ PostgreSQL 9.4 - PostgreSQL 12 (in development)
GEOS >= 3.5
* New Features *
- #1847, spgist 2d and 3d support for PG 11+
(Esteban Zimányi and Arthur Lesuisse from Université Libre de Bruxelles (ULB),
Darafei Praliaskouski)
- #1847, SP-GiST 2D and 3D support for PostgreSQL 11+ (Esteban Zimányi and
Arthur Lesuisse from Université Libre de Bruxelles (ULB), Darafei
Praliaskouski)
- #4056, ST_FilterByM (Nicklas Avén)
- #4050, ST_ChaikinSmoothing (Nicklas Avén)
- #3989, ST_Buffer single sided option (Stephen Knox)
......@@ -62,7 +68,7 @@ GEOS >= 3.5
* Breaking Changes *
- #4054, ST_SimplifyVW changed from > tolerance to >= tolerance
- #3885, version number removed from address_standardize lib file
(Regina Obe)
(Regina Obe)
- #3893, raster support functions can only be loaded in the same schema
with core PostGIS functions. (Sandro Santilli)
- #4035, remove dummy pgis_abs type from aggregate/collect routines.
......
......@@ -483,9 +483,9 @@ if test "x$LIBLWGEOM_ONLY" = "xno"; then
PGSQL_SHAREDIR=`"$PG_CONFIG" --sharedir`
AC_MSG_RESULT([checking PostgreSQL version... $PGSQL_FULL_VERSION])
dnl Ensure that we are using PostgreSQL >= 9.4
if test $POSTGIS_PGSQL_VERSION -lt 94; then
AC_MSG_ERROR([PostGIS requires PostgreSQL >= 9.4])
dnl Ensure that we are using PostgreSQL >= 9.5
if test $POSTGIS_PGSQL_VERSION -lt 95; then
AC_MSG_ERROR([PostGIS requires PostgreSQL >= 9.5])
fi
HAVE_BRIN=no
......
......@@ -26,15 +26,15 @@ typedef struct
#define GIDX_MAX_SIZE 36
#define GIDX_MAX_DIM 4
/*
* This macro is based on PG_FREE_IF_COPY, except that it accepts two pointers.
* See PG_FREE_IF_COPY comment in src/include/fmgr.h in postgres source code
* for more details.
*/
#define POSTGIS_FREE_IF_COPY_P(ptrsrc, ptrori) \
do { \
if ((Pointer) (ptrsrc) != (Pointer) (ptrori)) \
do \
{ \
if ((Pointer)(ptrsrc) != (Pointer)(ptrori)) \
pfree(ptrsrc); \
} while (0)
......@@ -51,7 +51,6 @@ typedef struct
float xmin, xmax, ymin, ymax;
} BOX2DF;
/*********************************************************************************
** GIDX support functions.
**
......@@ -61,7 +60,7 @@ typedef struct
*/
/* allocate a new gidx object on the heap */
GIDX* gidx_new(int ndims) ;
GIDX *gidx_new(int ndims);
/* Increase the size of a GIDX */
void gidx_expand(GIDX *a, float d);
......@@ -70,7 +69,7 @@ void gidx_expand(GIDX *a, float d);
bool gidx_is_unknown(const GIDX *a);
/* Generate human readable form for GIDX. */
char* gidx_to_string(GIDX *a) ;
char *gidx_to_string(GIDX *a);
/* typedef to correct array-bounds checking for casts to GIDX - do not
use this ANYWHERE except in the casts below */
......@@ -79,24 +78,24 @@ typedef float _gidx_float_array[sizeof(float) * 2 * 4];
/* Returns number of dimensions for this GIDX */
#define GIDX_NDIMS(gidx) ((VARSIZE((gidx)) - VARHDRSZ) / (2 * sizeof(float)))
/* Minimum accessor. */
#define GIDX_GET_MIN(gidx, dimension) (*((_gidx_float_array *)(&(gidx)->c)))[2*(dimension)]
#define GIDX_GET_MIN(gidx, dimension) (*((_gidx_float_array *)(&(gidx)->c)))[2 * (dimension)]
/* Maximum accessor. */
#define GIDX_GET_MAX(gidx, dimension) (*((_gidx_float_array *)(&(gidx)->c)))[2*(dimension)+1]
#define GIDX_GET_MAX(gidx, dimension) (*((_gidx_float_array *)(&(gidx)->c)))[2 * (dimension) + 1]
/* Minimum setter. */
#define GIDX_SET_MIN(gidx, dimension, value) ((gidx)->c[2*(dimension)] = (value))
#define GIDX_SET_MIN(gidx, dimension, value) ((gidx)->c[2 * (dimension)] = (value))
/* Maximum setter. */
#define GIDX_SET_MAX(gidx, dimension, value) ((gidx)->c[2*(dimension)+1] = (value))
#define GIDX_SET_MAX(gidx, dimension, value) ((gidx)->c[2 * (dimension) + 1] = (value))
/* Returns the size required to store a GIDX of requested dimension */
#define GIDX_SIZE(dimensions) (sizeof(int32) + 2*(dimensions)*sizeof(float))
#define GIDX_SIZE(dimensions) (sizeof(int32) + 2 * (dimensions) * sizeof(float))
/* Allocate a copy of the box */
BOX2DF* box2df_copy(BOX2DF *b);
BOX2DF *box2df_copy(BOX2DF *b);
/* Grow the first argument to contain the second */
void box2df_merge(BOX2DF *b_union, BOX2DF *b_new);
/* Allocate a copy of the box */
GIDX* gidx_copy(GIDX *b);
GIDX *gidx_copy(GIDX *b);
/* Grow the first argument to contain the second */
void gidx_merge(GIDX **b_union, GIDX *b_new);
......@@ -122,16 +121,14 @@ int gserialized_datum_get_gidx_p(Datum gserialized_datum, GIDX *gidx);
/* Pull out the gidx bounding box from an already de-toasted geography */
int gserialized_get_gidx_p(const GSERIALIZED *g, GIDX *gidx);
/* Copy a new bounding box into an existing gserialized */
GSERIALIZED* gserialized_set_gidx(GSERIALIZED *g, GIDX *gidx);
GSERIALIZED *gserialized_set_gidx(GSERIALIZED *g, GIDX *gidx);
/* Given two datums, do they overlap? Computed very fast using embedded boxes. */
/* int gserialized_datum_overlaps(Datum gs1, Datum gs2); */
/* Remove the box from a disk serialization */
GSERIALIZED* gserialized_drop_gidx(GSERIALIZED *g);
GSERIALIZED *gserialized_drop_gidx(GSERIALIZED *g);
bool box2df_contains(const BOX2DF *a, const BOX2DF *b);
void box2df_set_empty(BOX2DF *a);
void box2df_set_finite(BOX2DF *a);
void box2df_validate(BOX2DF *b);
......@@ -146,7 +143,9 @@ bool box2df_below(const BOX2DF *a, const BOX2DF *b);
bool box2df_above(const BOX2DF *a, const BOX2DF *b);
bool box2df_overabove(const BOX2DF *a, const BOX2DF *b);
void gidx_validate(GIDX *b);
void gidx_set_unknown(GIDX *a);
bool gidx_overlaps(GIDX *a, GIDX *b);
bool gidx_equals(GIDX *a, GIDX *b);
bool gidx_contains(GIDX *a, GIDX *b);
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df);
......@@ -61,7 +61,7 @@ BRIN_OBJ= brin_2d.o brin_nd.o brin_common.o
endif
ifeq (@HAVE_SPGIST@,yes)
SPGIST_OBJ= gserialized_spgist_2d.o gserialized_spgist_3d.o
SPGIST_OBJ= gserialized_spgist_2d.o gserialized_spgist_3d.o gserialized_spgist_nd.o
endif
ifeq (@HAVE_PROTOBUF@,yes)
......
This diff is collapsed.
......@@ -28,6 +28,7 @@
#include "fmgr.h"
#include "utils/elog.h"
#include "utils/geo_decls.h"
#include "gserialized_spgist_3d.h"
#include "../postgis_config.h"
#include "lwgeom_pg.h"
......
......@@ -824,6 +824,48 @@ CREATE OPERATOR &&& (
JOIN = gserialized_gist_joinsel_nd
);
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_contains_nd(geometry, geometry)
RETURNS boolean
AS 'MODULE_PATHNAME' ,'gserialized_contains'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
-- Availability: 2.5.0
CREATE OPERATOR ~~ (
LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_contains_nd,
COMMUTATOR = '@@',
RESTRICT = gserialized_gist_sel_nd,
JOIN = gserialized_gist_joinsel_nd
);
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_within_nd(geometry, geometry)
RETURNS boolean
AS 'MODULE_PATHNAME' ,'gserialized_within'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
-- Availability: 2.5.0
CREATE OPERATOR @@ (
LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_within_nd,
COMMUTATOR = '~~',
RESTRICT = gserialized_gist_sel_nd,
JOIN = gserialized_gist_joinsel_nd
);
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_same_nd(geometry, geometry)
RETURNS boolean
AS 'MODULE_PATHNAME' ,'gserialized_same'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL;
-- Availability: 2.5.0
CREATE OPERATOR ~~= (
LEFTARG = geometry, RIGHTARG = geometry, PROCEDURE = geometry_same_nd,
COMMUTATOR = '~~=',
RESTRICT = gserialized_gist_sel_nd,
JOIN = gserialized_gist_joinsel_nd
);
-- Availability: 2.2.0
CREATE OR REPLACE FUNCTION geometry_distance_centroid_nd(geometry,geometry)
RETURNS float8
......@@ -866,9 +908,12 @@ CREATE OPERATOR CLASS gist_geometry_ops_nd
FOR TYPE geometry USING GIST AS
STORAGE gidx,
OPERATOR 3 &&& ,
-- OPERATOR 6 ~= ,
-- OPERATOR 7 ~ ,
-- OPERATOR 8 @ ,
-- Availability: 2.5.0
OPERATOR 6 ~~= ,
-- Availability: 2.5.0
OPERATOR 7 ~~ ,
-- Availability: 2.5.0
OPERATOR 8 @@ ,
-- Availability: 2.2.0
OPERATOR 13 <<->> FOR ORDER BY pg_catalog.float_ops,
#if POSTGIS_PGSQL_VERSION >= 95
......
......@@ -163,4 +163,107 @@ CREATE OPERATOR CLASS spgist_geometry_ops_3d
FUNCTION 4 geometry_spgist_inner_consistent_3d(internal, internal),
FUNCTION 5 geometry_spgist_leaf_consistent_3d(internal, internal),
FUNCTION 6 geometry_spgist_compress_3d(internal);
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
-- SP-GiST ND Support Functions
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
-- Geometry
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_spgist_config_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_config_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_spgist_choose_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_choose_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_spgist_picksplit_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_picksplit_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_spgist_inner_consistent_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_inner_consistent_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_spgist_leaf_consistent_nd(internal, internal)
RETURNS bool
AS 'MODULE_PATHNAME' ,'gserialized_spgist_leaf_consistent_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geometry_spgist_compress_nd(internal)
RETURNS internal
AS 'MODULE_PATHNAME' ,'gserialized_spgist_compress_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OPERATOR CLASS spgist_geometry_ops_nd
FOR TYPE geometry USING SPGIST AS
OPERATOR 3 &&& ,
OPERATOR 6 ~~= ,
OPERATOR 7 ~~ ,
OPERATOR 8 @@ ,
FUNCTION 1 geometry_spgist_config_nd(internal, internal),
FUNCTION 2 geometry_spgist_choose_nd(internal, internal),
FUNCTION 3 geometry_spgist_picksplit_nd(internal, internal),
FUNCTION 4 geometry_spgist_inner_consistent_nd(internal, internal),
FUNCTION 5 geometry_spgist_leaf_consistent_nd(internal, internal),
FUNCTION 6 geometry_spgist_compress_nd(internal);
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
-- Geography
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geography_spgist_config_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_config_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geography_spgist_choose_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_choose_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geography_spgist_picksplit_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_picksplit_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geography_spgist_inner_consistent_nd(internal, internal)
RETURNS void
AS 'MODULE_PATHNAME' ,'gserialized_spgist_inner_consistent_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geography_spgist_leaf_consistent_nd(internal, internal)
RETURNS bool
AS 'MODULE_PATHNAME' ,'gserialized_spgist_leaf_consistent_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OR REPLACE FUNCTION geography_spgist_compress_nd(internal)
RETURNS internal
AS 'MODULE_PATHNAME' ,'gserialized_spgist_compress_nd'
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
-- Availability: 2.5.0
CREATE OPERATOR CLASS spgist_geography_ops_nd
DEFAULT FOR TYPE geography USING SPGIST AS
OPERATOR 3 && ,
-- OPERATOR 6 ~= ,
-- OPERATOR 7 ~ ,
-- OPERATOR 8 @ ,
FUNCTION 1 geography_spgist_config_nd(internal, internal),
FUNCTION 2 geography_spgist_choose_nd(internal, internal),
FUNCTION 3 geography_spgist_picksplit_nd(internal, internal),
FUNCTION 4 geography_spgist_inner_consistent_nd(internal, internal),
FUNCTION 5 geography_spgist_leaf_consistent_nd(internal, internal),
FUNCTION 6 geography_spgist_compress_nd(internal);
#endif
......@@ -233,7 +233,9 @@ endif
ifeq ($(HAVE_SPGIST),yes)
TESTS += \
regress_spgist_index_2d \
regress_spgist_index_3d
regress_spgist_index_3d \
regress_spgist_index_nd #\
# regress_gist_index_nd
endif
ifeq ($(HAVE_PROTOBUF),yes)
......
......@@ -115,30 +115,121 @@ select 'ndov7', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry &&&
-- &&& with mixed dimensions
WITH v(i,g) AS ( VALUES
(1,'POINT(0 0)'::geometry), -- true, infinite M range
(2,'POINTZ(0 0 1)'), -- true, infinite M range
(3,'POINTZ(0 0 0)'), -- true, infinite M range
(4,'POINTM(0 0 1)'), -- true, fully defined overlap
(5,'POINTZM(0 0 0 1)'), -- true, fully defined overlap
(6,'POINTZM(0 0 1 0)'), -- false, M out of range
(7,'LINESTRINGM(-1 0 2,1 0 3)'), -- false, M out of range
(8,'LINESTRINGZ(-1 0 2,1 0 3)') -- true, infinite M range
(1,'POINT(0 0)'::geometry), -- true for {1,2,3,4,5,6,7,8,9}
(2,'POINTZ(0 0 1)'), -- true for {1,2,4,6,7}
(3,'POINTZ(0 0 0)'), -- true for {1,3,4,5,7}
(4,'POINTM(0 0 1)'), -- true for {1,2,3,4,5,8}
(5,'POINTZM(0 0 0 1)'), -- true for {1,3,4,5}
(6,'POINTZM(0 0 1 0)'), -- true for {1,2,6}
(7,'LINESTRINGM(-1 0 2,1 0 3)'), -- true for {1,2,3,7,8,9}
(8,'LINESTRINGZ(-1 0 2,1 0 3)'), -- true for {1,4,7,8,9}
(9,'LINESTRINGZM(-1 0 2 2,1 0 3 3)') -- true for {1,7,8,9}
)
SELECT 'ndovm1', array_agg(i) FROM v WHERE g &&& 'POINTM(0 0 1)'::geometry
ORDER BY 1;
SELECT 'ndovm', v1.i, array_agg(v2.i) FROM v v1, v v2 WHERE v1.g &&& v2.g
group by v1.i
ORDER BY 2;
-- nd contains ~~
select 'ndcont1', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(3 3 3 5)'::geometry; -- f
select 'ndcont2', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(3 3 5 3)'::geometry; -- f
select 'ndcont3', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(3 5 3 3)'::geometry; -- f
select 'ndcont4', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(5 3 3 3)'::geometry; -- f
select 'ndcont5', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(3 3 3 3)'::geometry; -- t
select 'ndcont6', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(2 4 2 4)'::geometry; -- t
select 'ndcont7', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~
'POINT(4 2 4 2)'::geometry; -- t
-- ~~ with mixed dimensions
WITH v(i,g) AS ( VALUES
(1,'POINT(0 0)'::geometry),
(2,'POINTZ(0 0 1)'),
(3,'POINTZ(0 0 0)'),
(4,'POINTM(0 0 1)'),
(5,'POINTZM(0 0 0 1)'),
(6,'POINTZM(0 0 1 0)'),
(7,'LINESTRINGM(-1 0 2,1 0 3)'),
(8,'LINESTRINGZ(-1 0 2,1 0 3)'),
(9,'LINESTRINGZM(-1 0 2 2,1 0 3 3)')
)
SELECT 'ndcontm', v1.i, array_agg(v2.i) FROM v v1, v v2 WHERE v1.g ~~ v2.g
group by v1.i
ORDER BY 2;
-- nd within @@
select 'ndwithin1', 'POINT(3 3 3 5)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- f
select 'ndwithin2', 'POINT(3 3 5 3)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- f
select 'ndwithin3', 'POINT(3 5 3 3)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- f
select 'ndwithin4', 'POINT(5 3 3 3)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- f
select 'ndwithin5', 'POINT(3 3 3 3)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- t
select 'ndwithin6', 'POINT(2 4 2 4)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- t
select 'ndwithin7', 'POINT(4 2 4 2)'::geometry @@
'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry; -- t
-- @@ with mixed dimensions
WITH v(i,g) AS ( VALUES
(1,'POINT(0 0)'::geometry),
(2,'POINTZ(0 0 1)'),
(3,'POINTZ(0 0 0)'),
(4,'POINTM(0 0 1)'),
(5,'POINTZM(0 0 0 1)'),
(6,'POINTZM(0 0 1 0)'),
(7,'LINESTRINGM(-1 0 2,1 0 3)'),
(8,'LINESTRINGZ(-1 0 2,1 0 3)'),
(9,'LINESTRINGZM(-1 0 2 2,1 0 3 3)')
)
SELECT 'ndwithinm', v1.i, array_agg(v2.i) FROM v v1, v v2 WHERE v1.g @@ v2.g
group by v1.i
ORDER BY 2;
-- nd same ~~=
select 'ndsame1', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'POINT(3 3 3 3)'::geometry; -- f
select 'ndsame2', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'LINESTRING(2 2 2 2, 4 4 4 5)'::geometry; -- f
select 'ndsame3', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'LINESTRING(2 2 2 2, 4 4 5 4)'::geometry; -- f
select 'ndsame4', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'LINESTRING(2 2 2 2, 4 5 4 4)'::geometry; -- f
select 'ndsame5', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'LINESTRING(2 2 2 2, 5 4 4 4)'::geometry; -- f
select 'ndsame6', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'LINESTRING(4 4 4 4, 2 2 2 2)'::geometry; -- t
select 'ndsame7', 'LINESTRING(2 2 2 2, 4 4 4 4)'::geometry ~~=
'LINESTRING(2 2 2 4, 2 2 4 2, 2 4 2 2, 4 2 2 2)'::geometry; -- t
-- ~~= with mixed dimensions
WITH v(i,g) AS ( VALUES
(1,'POINT(0 0)'::geometry), -- true, infinite Z range
(2,'POINTZ(0 0 1)'), -- true, fully defined overlap
(3,'POINTZ(0 0 0)'), -- false, Z out of range
(4,'POINTM(0 0 0)'), -- true, infinite Z range
(5,'POINTZM(0 0 0 1)'), -- false, Z out of range
(6,'POINTZM(0 0 1 0)'), -- true, fully defined overlap
(7,'LINESTRINGM(-1 0 2,1 0 3)'), -- true, infinite Z range
(8,'LINESTRINGZ(-1 0 2,1 0 3)') -- false, Z out of range
(1,'POINT(0 0)'::geometry),
(2,'POINTZ(0 0 1)'),
(3,'POINTZ(0 0 0)'),
(4,'POINTM(0 0 1)'),
(5,'POINTZM(0 0 0 1)'),
(6,'POINTZM(0 0 1 0)'),
(7,'LINESTRINGM(-1 0 2,1 0 3)'),
(8,'LINESTRINGZ(-1 0 2,1 0 3)'),
(9,'LINESTRINGZM(-1 0 2 2,1 0 3 3)')
)
SELECT 'ndovm2', array_agg(i) FROM v WHERE g &&& 'POINTZ(0 0 1)'::geometry
ORDER BY 1;
SELECT 'ndsamem', v1.i, array_agg(v2.i) FROM v v1, v v2 WHERE v1.g ~~= v2.g
group by v1.i
ORDER BY 2;
-- GROUP BY on empty
SELECT '#3777', ST_AsText(geom), count(*)
......
......@@ -54,8 +54,63 @@ ndov4|f
ndov5|t
ndov6|t
ndov7|t
ndovm1|{1,2,3,4,5,8}
ndovm2|{1,2,4,6,7}
ndovm|1|{1,2,3,4,5,6,7,8,9}
ndovm|2|{1,2,4,6,7}
ndovm|3|{1,3,4,5,7}
ndovm|4|{1,2,3,4,5,8}
ndovm|5|{1,3,4,5}
ndovm|6|{1,2,6}
ndovm|7|{1,2,3,7,8,9}
ndovm|8|{1,4,7,8,9}
ndovm|9|{1,7,8,9}
ndcont1|f
ndcont2|f
ndcont3|f
ndcont4|f
ndcont5|t
ndcont6|t
ndcont7|t
ndcontm|1|{1,2,3,4,5,6}
ndcontm|2|{1,2,4,6}
ndcontm|3|{1,3,4,5}
ndcontm|4|{1,2,3,4,5}
ndcontm|5|{1,3,4,5}
ndcontm|6|{1,2,6}
ndcontm|7|{1,2,3,7,8,9}
ndcontm|8|{1,4,7,8,9}
ndcontm|9|{1,7,8,9}
ndwithin1|f
ndwithin2|f
ndwithin3|f
ndwithin4|f
ndwithin5|t
ndwithin6|t
ndwithin7|t
ndwithinm|1|{1,2,3,4,5,6,7,8,9}
ndwithinm|2|{1,2,4,6,7}
ndwithinm|3|{1,3,4,5,7}
ndwithinm|4|{1,2,3,4,5,8}
ndwithinm|5|{1,3,4,5}
ndwithinm|6|{1,2,6}
ndwithinm|7|{7,8,9}
ndwithinm|8|{7,8,9}
ndwithinm|9|{7,8,9}
ndsame1|f
ndsame2|f
ndsame3|f
ndsame4|f
ndsame5|f
ndsame6|t
ndsame7|t
ndsamem|1|{1,2,3,4,5,6}
ndsamem|2|{1,2,4,6}
ndsamem|3|{1,3,4,5}
ndsamem|4|{1,2,3,4,5}
ndsamem|5|{1,3,4,5}
ndsamem|6|{1,2,6}
ndsamem|7|{7,8,9}
ndsamem|8|{7,8,9}
ndsamem|9|{7,8,9}
#3777|GEOMETRYCOLLECTION EMPTY|1
#3777|LINESTRING(0 0,0 1)|1
#3777|POINT EMPTY|1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment