@@ -36,6 +36,7 @@ PG_FUNCTION_INFO_V1(g_spherekey_penalty);
3636PG_FUNCTION_INFO_V1 (g_spherekey_picksplit );
3737PG_FUNCTION_INFO_V1 (g_spoint3_penalty );
3838PG_FUNCTION_INFO_V1 (g_spoint3_picksplit );
39+ PG_FUNCTION_INFO_V1 (g_spoint_distance );
3940PG_FUNCTION_INFO_V1 (g_spoint3_distance );
4041PG_FUNCTION_INFO_V1 (g_spoint3_fetch );
4142
@@ -681,6 +682,10 @@ g_spoint3_consistent(PG_FUNCTION_ARGS)
681682PG_RETURN_BOOL (false);
682683}
683684
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+
684689Datum
685690g_spoint3_distance (PG_FUNCTION_ARGS )
686691{
@@ -1672,6 +1677,127 @@ fallbackSplit(Box3D *boxes, OffsetNumber maxoff, GIST_SPLITVEC *v)
16721677v -> spl_ldatum_exists = v -> spl_rdatum_exists = false;
16731678}
16741679
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+
16751801/*
16761802 * Represents information about an entry that can be placed to either group
16771803 * without affecting overlap over selected axis ("common entry").