@@ -36,6 +36,7 @@ PG_FUNCTION_INFO_V1(g_spherekey_penalty);
36
36
PG_FUNCTION_INFO_V1 (g_spherekey_picksplit );
37
37
PG_FUNCTION_INFO_V1 (g_spoint3_penalty );
38
38
PG_FUNCTION_INFO_V1 (g_spoint3_picksplit );
39
+ PG_FUNCTION_INFO_V1 (g_spoint_distance );
39
40
PG_FUNCTION_INFO_V1 (g_spoint3_distance );
40
41
PG_FUNCTION_INFO_V1 (g_spoint3_fetch );
41
42
@@ -681,6 +682,10 @@ g_spoint3_consistent(PG_FUNCTION_ARGS)
681
682
PG_RETURN_BOOL (false);
682
683
}
683
684
685
+ static double distance_vector_point_3d (Vector3D * v , double x , double y , double z ) {
686
+ return acos ( (v -> x * x + v -> y * y + v -> z * z ) / sqrt ( x * x + y * y + z * z ) ); // as v has length=1 by design
687
+ }
688
+
684
689
Datum
685
690
g_spoint3_distance (PG_FUNCTION_ARGS )
686
691
{
@@ -1672,6 +1677,127 @@ fallbackSplit(Box3D *boxes, OffsetNumber maxoff, GIST_SPLITVEC *v)
1672
1677
v -> spl_ldatum_exists = v -> spl_rdatum_exists = false;
1673
1678
}
1674
1679
1680
+
1681
+ Datum
1682
+ g_spoint_distance (PG_FUNCTION_ARGS )
1683
+ {
1684
+ GISTENTRY * entry = (GISTENTRY * ) PG_GETARG_POINTER (0 );
1685
+ StrategyNumber strategy = (StrategyNumber ) PG_GETARG_UINT16 (2 );
1686
+ Box3D * box = (Box3D * ) DatumGetPointer (entry -> key );
1687
+ double retval ;
1688
+ SPoint * point = (SPoint * ) PG_GETARG_POINTER (1 );
1689
+ Vector3D v_point , v_low , v_high ;
1690
+
1691
+ switch (strategy )
1692
+ {
1693
+ case 17 :
1694
+ // Prepare data for calculation
1695
+ spoint_vector3d (& v_point , point );
1696
+ v_low .x = (double )box -> low .coord [0 ] / MAXCVALUE ;
1697
+ v_low .y = (double )box -> low .coord [1 ] / MAXCVALUE ;
1698
+ v_low .z = (double )box -> low .coord [2 ] / MAXCVALUE ;
1699
+ v_high .x = (double )box -> high .coord [0 ] / MAXCVALUE ;
1700
+ v_high .y = (double )box -> high .coord [1 ] / MAXCVALUE ;
1701
+ v_high .z = (double )box -> high .coord [2 ] / MAXCVALUE ;
1702
+ // a box splits space into 27 subspaces (6+12+8+1) with different distance calculation
1703
+ if (v_point .x < v_low .x ) {
1704
+ if (v_point .y < v_low .y ) {
1705
+ if (v_point .z < v_low .z ) {
1706
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_low .y , v_low .z ); //point2point distance
1707
+ } else if (v_point .z < v_high .z ) {
1708
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_low .y , v_point .z ); //point2line distance
1709
+ } else {
1710
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_low .y , v_high .z ); //point2point distance
1711
+ }
1712
+ } else if (v_point .y < v_high .y ) {
1713
+ if (v_point .z < v_low .z ) {
1714
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_point .y , v_low .z ); //point2line distance
1715
+ } else if (v_point .z < v_high .z ) {
1716
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_point .y , v_point .z ); //point2plane distance
1717
+ } else {
1718
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_point .y , v_high .z ); //point2line distance
1719
+ }
1720
+ } else {
1721
+ if (v_point .z < v_low .z ) {
1722
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_high .y , v_low .z ); //point2point distance
1723
+ } else if (v_point .z < v_high .z ) {
1724
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_high .y , v_point .z ); //point2line distance
1725
+ } else {
1726
+ retval = distance_vector_point_3d (& v_point , v_low .x , v_high .y , v_high .z ); //point2point distance
1727
+ }
1728
+ }
1729
+ } else if (v_point .x < v_high .x ) {
1730
+ if (v_point .y < v_low .y ) {
1731
+ if (v_point .z < v_low .z ) {
1732
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_low .y , v_low .z ); //p2line distance
1733
+ } else if (v_point .z < v_high .z ) {
1734
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_low .y , v_point .z ); //point2plane distance
1735
+ } else {
1736
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_low .y , v_high .z ); //point2line distance
1737
+ }
1738
+ } else if (v_point .y < v_high .y ) {
1739
+ if (v_point .z < v_low .z ) {
1740
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_point .y , v_low .z ); //point2plane distance
1741
+ } else if (v_point .z < v_high .z ) {
1742
+ retval = 0 ; // inside cube
1743
+ } else {
1744
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_point .y , v_high .z ); //point2plane distance
1745
+ }
1746
+ } else {
1747
+ if (v_point .z < v_low .z ) {
1748
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_high .y , v_low .z ); //point2line distance
1749
+ } else if (v_point .z < v_high .z ) {
1750
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_high .y , v_point .z ); //point2plane distance
1751
+ } else {
1752
+ retval = distance_vector_point_3d (& v_point , v_point .x , v_high .y , v_high .z ); //point2line distance
1753
+ }
1754
+ }
1755
+ } else {
1756
+ if (v_point .y < v_low .y ) {
1757
+ if (v_point .z < v_low .z ) {
1758
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_low .y , v_low .z ); //p2p distance
1759
+ } else if (v_point .z < v_high .z ) {
1760
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_low .y , v_point .z ); //point2line distance
1761
+ } else {
1762
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_low .y , v_high .z ); //point2point distance
1763
+ }
1764
+ } else if (v_point .y < v_high .y ) {
1765
+ if (v_point .z < v_low .z ) {
1766
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_point .y , v_low .z ); //point2line distance
1767
+ } else if (v_point .z < v_high .z ) {
1768
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_point .y , v_point .z ); //point2plane distance
1769
+ } else {
1770
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_point .y , v_high .z ); //point2line distance
1771
+ }
1772
+ } else {
1773
+ if (v_point .z < v_low .z ) {
1774
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_high .y , v_low .z ); //point2point distance
1775
+ } else if (v_point .z < v_high .z ) {
1776
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_high .y , v_point .z ); //point2line distance
1777
+ } else {
1778
+ retval = distance_vector_point_3d (& v_point , v_high .x , v_high .y , v_high .z ); //point2point distance
1779
+ }
1780
+ }
1781
+ }
1782
+
1783
+ elog (DEBUG1 , "distance (%lg,%lg,%lg %lg,%lg,%lg) <-> (%lg,%lg) = %lg" ,
1784
+ v_low .x , v_low .y , v_low .z ,
1785
+ v_high .x , v_high .y , v_high .z ,
1786
+ point -> lng , point -> lat ,
1787
+ retval
1788
+ );
1789
+ break ;
1790
+
1791
+ default :
1792
+ elog (ERROR , "unrecognized cube strategy number: %d" , strategy );
1793
+ retval = 0 ; /* keep compiler quiet */
1794
+ break ;
1795
+ }
1796
+ PG_RETURN_FLOAT8 (retval );
1797
+ }
1798
+
1799
+
1800
+
1675
1801
/*
1676
1802
* Represents information about an entry that can be placed to either group
1677
1803
* without affecting overlap over selected axis ("common entry").
0 commit comments