88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.58 2001/03/22 03:59:50 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.59 2001/10/13 17:40:24 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -948,7 +948,7 @@ line_construct_pts(LINE *line, Point *pt1, Point *pt2)
948948 }
949949 else if (FPeq (pt1 -> y , pt2 -> y ))
950950 { /* horizontal */
951- /* use "x = C" */
951+ /* use "y = C" */
952952 line -> A = 0 ;
953953 line -> B = -1 ;
954954 line -> C = pt1 -> y ;
@@ -1376,6 +1376,9 @@ path_inter(PG_FUNCTION_ARGS)
13761376 LSEG seg1 ,
13771377 seg2 ;
13781378
1379+ if (p1 -> npts <= 0 || p2 -> npts <= 0 )
1380+ PG_RETURN_BOOL (false);
1381+
13791382 b1 .high .x = b1 .low .x = p1 -> p [0 ].x ;
13801383 b1 .high .y = b1 .low .y = p1 -> p [0 ].y ;
13811384 for (i = 1 ; i < p1 -> npts ; i ++ )
@@ -1398,12 +1401,34 @@ path_inter(PG_FUNCTION_ARGS)
13981401 PG_RETURN_BOOL (false);
13991402
14001403 /* pairwise check lseg intersections */
1401- for (i = 0 ; i < p1 -> npts - 1 ; i ++ )
1404+ for (i = 0 ; i < p1 -> npts ; i ++ )
14021405 {
1403- for (j = 0 ; j < p2 -> npts - 1 ; j ++ )
1406+ int iprev ;
1407+
1408+ if (i > 0 )
1409+ iprev = i - 1 ;
1410+ else
14041411 {
1405- statlseg_construct (& seg1 , & p1 -> p [i ], & p1 -> p [i + 1 ]);
1406- statlseg_construct (& seg2 , & p2 -> p [j ], & p2 -> p [j + 1 ]);
1412+ if (!p1 -> closed )
1413+ continue ;
1414+ iprev = p1 -> npts - 1 ; /* include the closure segment */
1415+ }
1416+
1417+ for (j = 0 ; j < p2 -> npts ; j ++ )
1418+ {
1419+ int jprev ;
1420+
1421+ if (j > 0 )
1422+ jprev = j - 1 ;
1423+ else
1424+ {
1425+ if (!p2 -> closed )
1426+ continue ;
1427+ jprev = p2 -> npts - 1 ; /* include the closure segment */
1428+ }
1429+
1430+ statlseg_construct (& seg1 , & p1 -> p [iprev ], & p1 -> p [i ]);
1431+ statlseg_construct (& seg2 , & p2 -> p [jprev ], & p2 -> p [j ]);
14071432 if (lseg_intersect_internal (& seg1 , & seg2 ))
14081433 PG_RETURN_BOOL (true);
14091434 }
@@ -1422,20 +1447,42 @@ path_distance(PG_FUNCTION_ARGS)
14221447{
14231448 PATH * p1 = PG_GETARG_PATH_P (0 );
14241449 PATH * p2 = PG_GETARG_PATH_P (1 );
1425- bool have_min = false;
14261450 float8 min = 0.0 ; /* initialize to keep compiler quiet */
1451+ bool have_min = false;
14271452 float8 tmp ;
14281453 int i ,
14291454 j ;
14301455 LSEG seg1 ,
14311456 seg2 ;
14321457
1433- for (i = 0 ; i < p1 -> npts - 1 ; i ++ )
1458+ for (i = 0 ; i < p1 -> npts ; i ++ )
14341459 {
1435- for (j = 0 ; j < p2 -> npts - 1 ; j ++ )
1460+ int iprev ;
1461+
1462+ if (i > 0 )
1463+ iprev = i - 1 ;
1464+ else
14361465 {
1437- statlseg_construct (& seg1 , & p1 -> p [i ], & p1 -> p [i + 1 ]);
1438- statlseg_construct (& seg2 , & p2 -> p [j ], & p2 -> p [j + 1 ]);
1466+ if (!p1 -> closed )
1467+ continue ;
1468+ iprev = p1 -> npts - 1 ; /* include the closure segment */
1469+ }
1470+
1471+ for (j = 0 ; j < p2 -> npts ; j ++ )
1472+ {
1473+ int jprev ;
1474+
1475+ if (j > 0 )
1476+ jprev = j - 1 ;
1477+ else
1478+ {
1479+ if (!p2 -> closed )
1480+ continue ;
1481+ jprev = p2 -> npts - 1 ; /* include the closure segment */
1482+ }
1483+
1484+ statlseg_construct (& seg1 , & p1 -> p [iprev ], & p1 -> p [i ]);
1485+ statlseg_construct (& seg2 , & p2 -> p [jprev ], & p2 -> p [j ]);
14391486
14401487 tmp = DatumGetFloat8 (DirectFunctionCall2 (lseg_distance ,
14411488 LsegPGetDatum (& seg1 ),
@@ -1463,12 +1510,24 @@ Datum
14631510path_length (PG_FUNCTION_ARGS )
14641511{
14651512 PATH * path = PG_GETARG_PATH_P (0 );
1466- float8 result ;
1513+ float8 result = 0.0 ;
14671514 int i ;
14681515
1469- result = 0.0 ;
1470- for (i = 0 ; i < (path -> npts - 1 ); i ++ )
1471- result += point_dt (& path -> p [i ], & path -> p [i + 1 ]);
1516+ for (i = 0 ; i < path -> npts ; i ++ )
1517+ {
1518+ int iprev ;
1519+
1520+ if (i > 0 )
1521+ iprev = i - 1 ;
1522+ else
1523+ {
1524+ if (!path -> closed )
1525+ continue ;
1526+ iprev = path -> npts - 1 ; /* include the closure segment */
1527+ }
1528+
1529+ result += point_dt (& path -> p [iprev ], & path -> p [i ]);
1530+ }
14721531
14731532 PG_RETURN_FLOAT8 (result );
14741533}
@@ -2133,17 +2192,18 @@ dist_ppath(PG_FUNCTION_ARGS)
21332192 Point * pt = PG_GETARG_POINT_P (0 );
21342193 PATH * path = PG_GETARG_PATH_P (1 );
21352194 float8 result = 0.0 ; /* keep compiler quiet */
2195+ bool have_min = false;
21362196 float8 tmp ;
21372197 int i ;
21382198 LSEG lseg ;
21392199
21402200 switch (path -> npts )
21412201 {
2142- /* no points in path? then result is undefined... */
21432202 case 0 :
2203+ /* no points in path? then result is undefined... */
21442204 PG_RETURN_NULL ();
2145- /* one point in path? then get distance between two points... */
21462205 case 1 :
2206+ /* one point in path? then get distance between two points... */
21472207 result = point_dt (pt , & path -> p [0 ]);
21482208 break ;
21492209 default :
@@ -2154,12 +2214,26 @@ dist_ppath(PG_FUNCTION_ARGS)
21542214 * the distance from a point to a path is the smallest
21552215 * distance from the point to any of its constituent segments.
21562216 */
2157- for (i = 0 ; i < path -> npts - 1 ; i ++ )
2217+ for (i = 0 ; i < path -> npts ; i ++ )
21582218 {
2159- statlseg_construct (& lseg , & path -> p [i ], & path -> p [i + 1 ]);
2219+ int iprev ;
2220+
2221+ if (i > 0 )
2222+ iprev = i - 1 ;
2223+ else
2224+ {
2225+ if (!path -> closed )
2226+ continue ;
2227+ iprev = path -> npts - 1 ; /* include the closure segment */
2228+ }
2229+
2230+ statlseg_construct (& lseg , & path -> p [iprev ], & path -> p [i ]);
21602231 tmp = dist_ps_internal (pt , & lseg );
2161- if (i == 0 || tmp < result )
2232+ if (!have_min || tmp < result )
2233+ {
21622234 result = tmp ;
2235+ have_min = true;
2236+ }
21632237 }
21642238 break ;
21652239 }
@@ -2824,8 +2898,6 @@ on_pb(PG_FUNCTION_ARGS)
28242898 * but not cross.
28252899 * (we can do p-in-p in lg(n), but it takes preprocessing)
28262900 */
2827- #define NEXT (A ) (((A)+1) % path->npts) /* cyclic "i+1" */
2828-
28292901Datum
28302902on_ppath (PG_FUNCTION_ARGS )
28312903{
0 commit comments