-- create table\r
CREATE TABLE knn_recheck_geom(gid serial primary key, geom geometry);\r
INSERT INTO knn_recheck_geom(gid,geom)\r
-SELECT ROW_NUMBER() OVER(ORDER BY x,y) AS gid, ST_Point(x*0.777,y*0.777) As geom\r
-FROM generate_series(-100,100, 1) AS x CROSS JOIN generate_series(-300,10000,10) As y;\r
+SELECT ROW_NUMBER() OVER(ORDER BY x,y) AS gid, ST_Point(x*0.777,y*0.887) As geom\r
+FROM generate_series(-100,1000, 7) AS x CROSS JOIN generate_series(-300,1000,9) As y;\r
\r
INSERT INTO knn_recheck_geom(gid, geom)\r
-SELECT 500000, 'LINESTRING(100 300, -10 700, 400 123, -300 10000)'::geometry;\r
-\r
+SELECT 500000 + i, ST_Translate('LINESTRING(-100 300, 500 700, 400 123, 500 10000, 1 1)'::geometry, i*2000,0)\r
+FROM generate_series(0,10) i;\r
\r
INSERT INTO knn_recheck_geom(gid, geom)\r
-SELECT 500001, 'POLYGON((100 3000, -10 700, 400 123, 405 124, 100 3000))'::geometry;\r
+SELECT 500100 + i, ST_Translate('POLYGON((100 800, 100 700, 400 123, 405 124, 100 800))'::geometry,0,i*2000)\r
+FROM generate_series(0,3) i;\r
+\r
\r
INSERT INTO knn_recheck_geom(gid,geom)\r
-SELECT 600000 + ROW_NUMBER() OVER(ORDER BY gid) AS gid, ST_Buffer(geom,1000,2) As geom\r
+SELECT 600000 + ROW_NUMBER() OVER(ORDER BY gid) AS gid, ST_Translate(ST_Buffer(geom,8,15),100,300) As geom\r
FROM knn_recheck_geom\r
-WHERE gid IN(1000, 10000, 2000, 40000);\r
+WHERE gid IN(1000, 10000, 2000,3000);\r
\r
\r
-- without index order should match st_distance order --\r
-- point check\r
-SELECT gid, ST_Distance( 'POINT(200 1000)'::geometry, geom)::numeric(10,2)\r
+\r
+SELECT '#1' As t, gid, ST_Distance( 'POINT(-305 998.5)'::geometry, geom)::numeric(10,2)\r
FROM knn_recheck_geom\r
-ORDER BY 'POINT(200 1000)'::geometry <-> geom LIMIT 5;\r
+ORDER BY 'POINT(-305 998.5)'::geometry <-> geom LIMIT 5;\r
\r
-- linestring check\r
-SELECT gid, ST_Distance( 'LINESTRING(200 100, -10 600)'::geometry, geom)::numeric(10,2)\r
+SELECT '#2' As t, gid, ST_Distance( 'MULTILINESTRING((-95 -300, 100 200, 100 323),(-50 2000, 30 6000))'::geometry, geom)::numeric(12,4)\r
FROM knn_recheck_geom\r
-ORDER BY 'LINESTRING(200 100, -10 600)'::geometry <-> geom LIMIT 5;\r
+ORDER BY 'MULTILINESTRING((-95 -300, 100 200, 100 323),(-50 2000, 30 6000))'::geometry <-> geom LIMIT 5;\r
\r
-- lateral check before index\r
-SELECT a.gid, b.gid As match, RANK() OVER(PARTITION BY a.gid ORDER BY ST_Distance(a.geom, b.geom) ) As true_rn, b.rn As knn_rn\r
+SELECT '#3' As t, a.gid, b.gid As match, ST_Distance(a.geom, b.geom)::numeric(15,4) As true_rn, b.knn_dist::numeric(15,4)\r
FROM knn_recheck_geom As a \r
LEFT JOIN \r
- LATERAL ( SELECT gid, geom, RANK() OVER(ORDER BY a.geom <-> g.geom) As rn \r
+ LATERAL ( SELECT gid, geom, a.geom <-> g.geom As knn_dist\r
FROM knn_recheck_geom As g WHERE a.gid <> g.gid ORDER BY a.geom <-> g.geom LIMIT 5) As b ON true\r
- WHERE a.gid IN(50000,50001,70000,61000)\r
-ORDER BY a.gid, b.rn;\r
+ WHERE a.gid IN(1,500101,500003)\r
+ORDER BY a.gid, true_rn;\r
\r
-- create index and repeat\r
CREATE INDEX idx_knn_recheck_geom_gist ON knn_recheck_geom USING gist(geom);\r
+vacuum analyze knn_recheck_geom;\r
\r
set enable_seqscan = false;\r
--- point check after index\r
-SELECT gid, ST_Distance( 'POINT(200 1000)'::geometry, geom)::numeric(10,2)\r
+SELECT '#1' As t, gid, ST_Distance( 'POINT(-305 998.5)'::geometry, geom)::numeric(10,2)\r
FROM knn_recheck_geom\r
-ORDER BY 'POINT(200 1000)'::geometry <-> geom LIMIT 5;\r
+ORDER BY 'POINT(-305 998.5)'::geometry <-> geom LIMIT 5;\r
\r
--- lateral check after index - currently is wrong\r
-SELECT a.gid, b.gid As match, RANK() OVER(PARTITION BY a.gid ORDER BY ST_Distance(a.geom, b.geom) ) As true_rn, b.rn As knn_rn\r
+-- linestring check\r
+SELECT '#2' As t, gid, ST_Distance( 'MULTILINESTRING((-95 -300, 100 200, 100 323),(-50 2000, 30 6000))'::geometry, geom)::numeric(12,4)\r
+FROM knn_recheck_geom\r
+ORDER BY 'MULTILINESTRING((-95 -300, 100 200, 100 323),(-50 2000, 30 6000))'::geometry <-> geom LIMIT 5;\r
+\r
+-- lateral check before index\r
+SELECT '#3' As t, a.gid, b.gid As match, ST_Distance(a.geom, b.geom)::numeric(15,4) As true_rn, b.knn_dist::numeric(15,4)\r
FROM knn_recheck_geom As a \r
LEFT JOIN \r
- LATERAL ( SELECT gid, geom, RANK() OVER(ORDER BY a.geom <-> g.geom) As rn \r
+ LATERAL ( SELECT gid, geom, a.geom <-> g.geom As knn_dist\r
FROM knn_recheck_geom As g WHERE a.gid <> g.gid ORDER BY a.geom <-> g.geom LIMIT 5) As b ON true\r
- WHERE a.gid IN(50000,50001,70000,61000)\r
-ORDER BY a.gid, b.rn;\r
+ WHERE a.gid IN(1,500101,500003)\r
+ORDER BY a.gid, true_rn;\r
\r
DROP TABLE knn_recheck_geom;\r
\r
-- geography tests\r
DELETE FROM spatial_ref_sys where srid = 4326;\r
-INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","proj4text") VALUES (4326,'EPSG',4326,'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ');\r
+INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","proj4text") \r
+ VALUES (4326,'EPSG',4326,'+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ');\r
-- create table\r
CREATE TABLE knn_recheck_geog(gid serial primary key, geog geography);\r
INSERT INTO knn_recheck_geog(gid,geog)\r
FROM generate_series(-100,100, 1) AS x CROSS JOIN generate_series(-90,90,1) As y;\r
\r
INSERT INTO knn_recheck_geog(gid, geog)\r
-SELECT 500000, 'LINESTRING(-95 -10, -11 65, 5 10, -70 60)'::geography;\r
+SELECT 500000, 'LINESTRING(-95 -10, -93 -10.5, -90 -10.6, -95 -10.5, -95 -10)'::geography;\r
\r
INSERT INTO knn_recheck_geog(gid, geog)\r
SELECT 500001, 'POLYGON((-95 10, -95.6 10.5, -95.9 10.75, -95 10))'::geography;\r
WHERE gid IN(1000, 10000, 2000, 2614, 40000);\r
\r
\r
-SELECT gid, RANK() OVER(ORDER BY ST_Distance( 'POINT(95 10)'::geography, geog,false) )\r
+SELECT '#1g' As t, gid, ST_Distance( 'POINT(-95 -10)'::geography, geog, false)::numeric(12,4) ,\r
+ ('POINT(-95 -10)'::geography <-> geog )::numeric(12,4)\r
FROM knn_recheck_geog\r
-ORDER BY 'POINT(95 10)'::geography <-> geog LIMIT 5;\r
+ORDER BY 'POINT(-95 -10)'::geography <-> geog LIMIT 5;\r
\r
-SELECT gid, RANK() OVER(ORDER BY ST_Distance( 'POINT(-95 -10)'::geography, geog, false) )\r
+SELECT '#2g' As t, gid, ST_Distance( 'LINESTRING(75 10, 75 12, 80 20)'::geography, geog, false)::numeric(12,4),\r
+ ('LINESTRING(75 10, 75 12, 80 20)'::geography <-> geog)::numeric(12,4) As knn_dist\r
FROM knn_recheck_geog\r
-ORDER BY 'POINT(-95 -10)'::geography <-> geog LIMIT 5;\r
+ORDER BY 'LINESTRING(75 10, 75 12, 80 20)'::geography <-> geog LIMIT 5;\r
\r
-- lateral check before index\r
-SELECT a.gid, ARRAY(SELECT gid\r
+SELECT '#3g' As t, a.gid, ARRAY(SELECT gid\r
FROM knn_recheck_geog As g WHERE a.gid <> g.gid ORDER BY ST_Distance(a.geog, g.geog, false) LIMIT 5) = ARRAY(SELECT gid\r
FROM knn_recheck_geog As g WHERE a.gid <> g.gid ORDER BY a.geog <-> g.geog LIMIT 5) As dist_order_agree\r
FROM knn_recheck_geog As a \r
\r
-- create index and repeat\r
CREATE INDEX idx_knn_recheck_geog_gist ON knn_recheck_geog USING gist(geog);\r
+vacuum analyze knn_recheck_geog;\r
+set enable_seqscan = false;\r
\r
-SELECT gid\r
+SELECT '#1g' As t, gid, ST_Distance( 'POINT(-95 -10)'::geography, geog, false)::numeric(12,4) ,\r
+ ('POINT(-95 -10)'::geography <-> geog )::numeric(12,4)\r
FROM knn_recheck_geog\r
-ORDER BY 'POINT(95 10)'::geography <-> geog LIMIT 5;\r
+ORDER BY 'POINT(-95 -10)'::geography <-> geog LIMIT 5;\r
\r
-SELECT gid\r
+SELECT '#2g' As t, gid, ST_Distance( 'LINESTRING(75 10, 75 12, 80 20)'::geography, geog, false)::numeric(12,4),\r
+ ('LINESTRING(75 10, 75 12, 80 20)'::geography <-> geog)::numeric(12,4) As knn_dist\r
FROM knn_recheck_geog\r
-ORDER BY 'POINT(-95 -10)'::geography <-> geog LIMIT 5;\r
+ORDER BY 'LINESTRING(75 10, 75 12, 80 20)'::geography <-> geog LIMIT 5;\r
\r
--- check after index\r
-set enable_seqscan = false; --sometimes doesn't want to use index\r
-SELECT a.gid, ARRAY(SELECT gid\r
+SELECT '#3g' As t, a.gid, ARRAY(SELECT gid\r
FROM knn_recheck_geog As g WHERE a.gid <> g.gid ORDER BY ST_Distance(a.geog, g.geog, false) LIMIT 5) = ARRAY(SELECT gid\r
FROM knn_recheck_geog As g WHERE a.gid <> g.gid ORDER BY a.geog <-> g.geog LIMIT 5) As dist_order_agree\r
FROM knn_recheck_geog As a \r
--\r
DELETE FROM spatial_ref_sys WHERE srid = 4326;\r
\r
+--now the nd operator tests\r
+-- create table and load\r
+CREATE TABLE knn_recheck_geom_nd(gid serial primary key, geom geometry);\r
+INSERT INTO knn_recheck_geom_nd(gid,geom)\r
+SELECT ROW_NUMBER() OVER(ORDER BY x,y) AS gid, ST_MakePoint(x*0.777,y*0.887,z*1.05) As geom\r
+FROM generate_series(-100,1000, 7) AS x , \r
+ generate_series(-300,1000,9) As y,\r
+ generate_series(1005,10000,5555) As z ;\r
+\r
+ -- 3d lines\r
+INSERT INTO knn_recheck_geom_nd(gid, geom)\r
+SELECT 500000 + i, ST_Translate('LINESTRING(-100 300 500, 500 700 600, 400 123 0, 500 10000 -1234, 1 1 5000)'::geometry, i*2000,0)\r
+FROM generate_series(0,10) i;\r
+\r
+\r
+-- 3d polygons\r
+INSERT INTO knn_recheck_geom_nd(gid, geom)\r
+SELECT 500100 + i, ST_Translate('POLYGON((100 800 5678, 100 700 5678, 400 123 5678, 405 124 5678, 100 800 5678))'::geometry,0,i*2000)\r
+FROM generate_series(0,3) i;\r
+\r
+-- polyhedral surface --\r
+INSERT INTO knn_recheck_geom_nd(gid,geom)\r
+SELECT 600000 + row_number() over(), ST_Translate(the_geom,100, 450,1000) As the_geom\r
+ FROM (VALUES ( ST_GeomFromText(\r
+'PolyhedralSurface( \r
+((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)), \r
+((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)), ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)), ((1 1 0, 1 1 1, 1 0 1, 1 0 0, 1 1 0)), \r
+((0 1 0, 0 1 1, 1 1 1, 1 1 0, 0 1 0)), ((0 0 1, 1 0 1, 1 1 1, 0 1 1, 0 0 1)) \r
+)') ) ,\r
+( ST_GeomFromText(\r
+'PolyhedralSurface( \r
+((0 0 0, 0 0 1, 0 1 1, 0 1 0, 0 0 0)), \r
+((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)) )') ) )\r
+As foo(the_geom) ;\r
+\r
+-- without index order should match st_3ddistance order --\r
+-- point check\r
+\r
+SELECT '#1nd-3' As t, gid, ST_3DDistance( 'POINT(-305 998.5 1000)'::geometry, geom)::numeric(12,4) As dist3d,\r
+('POINT(-305 998.5 1000)'::geometry <<->> geom)::numeric(12,4) As dist_knn\r
+FROM knn_recheck_geom_nd\r
+ORDER BY 'POINT(-305 998.5 1000)'::geometry <<->> geom LIMIT 5;\r
+\r
+-- linestring check \r
+SELECT '#2nd-3' As t, gid, ST_3DDistance( 'MULTILINESTRING((-95 -300 5000, 105 451 1000, 100 323 200),(-50 2000 456, 30 6000 789))'::geometry::geometry, geom)::numeric(12,4),\r
+ ('MULTILINESTRING((-95 -300 5000, 105 451 1000, 100 323 200),(-50 2000 456, 30 6000 789))'::geometry <<->> geom)::numeric(12,4) As knn_dist\r
+FROM knn_recheck_geom_nd\r
+ORDER BY 'MULTILINESTRING((-95 -300 5000, 105 451 1000, 100 323 200),(-50 2000 456, 30 6000 789))'::geometry <<->> geom LIMIT 5;\r
+\r
+-- TODO: add index tests\r
+\r
+DROP TABLE knn_recheck_geom_nd;\r
+\r