⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geo_ops.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
int4path_npoints(PATH *path){	if (!PointerIsValid(path))		return 0;	return path->npts;}	/* path_npoints() */PATH *path_close(PATH *path){	PATH	   *result;	if (!PointerIsValid(path))		return NULL;	result = path_copy(path);	result->closed = TRUE;	return result;}	/* path_close() */PATH *path_open(PATH *path){	PATH	   *result;	if (!PointerIsValid(path))		return NULL;	result = path_copy(path);	result->closed = FALSE;	return result;}	/* path_open() */static PATH *path_copy(PATH *path){	PATH	   *result;	int			size;	size = offsetof(PATH, p[0]) +(sizeof(path->p[0]) * path->npts);	result = palloc(size);	memmove((char *) result, (char *) path, size);	return result;}	/* path_copy() *//* path_inter - *		Does p1 intersect p2 at any point? *		Use bounding boxes for a quick (O(n)) check, then do a *		O(n^2) iterative edge check. */boolpath_inter(PATH *p1, PATH *p2){	BOX			b1,				b2;	int			i,				j;	LSEG		seg1,				seg2;	b1.high.x = b1.low.x = p1->p[0].x;	b1.high.y = b1.low.y = p1->p[0].y;	for (i = 1; i < p1->npts; i++)	{		b1.high.x = Max(p1->p[i].x, b1.high.x);		b1.high.y = Max(p1->p[i].y, b1.high.y);		b1.low.x = Min(p1->p[i].x, b1.low.x);		b1.low.y = Min(p1->p[i].y, b1.low.y);	}	b2.high.x = b2.low.x = p2->p[0].x;	b2.high.y = b2.low.y = p2->p[0].y;	for (i = 1; i < p2->npts; i++)	{		b2.high.x = Max(p2->p[i].x, b2.high.x);		b2.high.y = Max(p2->p[i].y, b2.high.y);		b2.low.x = Min(p2->p[i].x, b2.low.x);		b2.low.y = Min(p2->p[i].y, b2.low.y);	}	if (!box_overlap(&b1, &b2))		return FALSE;	/* pairwise check lseg intersections */	for (i = 0; i < p1->npts - 1; i++)	{		for (j = 0; j < p2->npts - 1; j++)		{			statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);			statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);			if (lseg_intersect(&seg1, &seg2))				return TRUE;		}	}	/* if we dropped through, no two segs intersected */	return FALSE;}	/* path_inter() *//* path_distance() * This essentially does a cartesian product of the lsegs in the *	two paths, and finds the min distance between any two lsegs */double *path_distance(PATH *p1, PATH *p2){	double	   *min = NULL,			   *tmp;	int			i,				j;	LSEG		seg1,				seg2;/*	statlseg_construct(&seg1, &p1->p[0], &p1->p[1]);	statlseg_construct(&seg2, &p2->p[0], &p2->p[1]);	min = lseg_distance(&seg1, &seg2);*/	for (i = 0; i < p1->npts - 1; i++)		for (j = 0; j < p2->npts - 1; j++)		{			statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);			statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);			tmp = lseg_distance(&seg1, &seg2);			if ((min == NULL) || (*min < *tmp))			{				if (min != NULL)					pfree(min);				min = tmp;			}			else				pfree(tmp);		}	return min;}	/* path_distance() *//*---------------------------------------------------------- *	"Arithmetic" operations. *---------------------------------------------------------*/double *path_length(PATH *path){	double	   *result;	int			i;	result = palloc(sizeof(double));	*result = 0;	for (i = 0; i < (path->npts - 1); i++)		*result += point_dt(&path->p[i], &path->p[i + 1]);	return result;}	/* path_length() */#ifdef NOT_USEDdoublepath_ln(PATH *path){	double		result;	int			i;	result = 0;	for (i = 0; i < (path->npts - 1); i++)		result += point_dt(&path->p[i], &path->p[i + 1]);	return result;}	/* path_ln() */#endif/*********************************************************************** ** **		Routines for 2D points. ** ***********************************************************************//*---------------------------------------------------------- *	String to point, point to string conversion. *		External format: *				"(x,y)" *				"x,y" *---------------------------------------------------------*/Point *point_in(char *str){	Point	   *point;	double		x,				y;	char	   *s;	if (!PointerIsValid(str))		elog(ERROR, "Bad (null) point external representation");	if (!pair_decode(str, &x, &y, &s) || (strlen(s) > 0))		elog(ERROR, "Bad point external representation '%s'", str);	point = palloc(sizeof(Point));	point->x = x;	point->y = y;	return point;}	/* point_in() */char *point_out(Point *pt){	if (!PointerIsValid(pt))		return NULL;	return path_encode(-1, 1, pt);}	/* point_out() */static Point *point_construct(double x, double y){	Point	   *result = palloc(sizeof(Point));	result->x = x;	result->y = y;	return result;}static Point *point_copy(Point *pt){	Point	   *result;	if (!PointerIsValid(pt))		return NULL;	result = palloc(sizeof(Point));	result->x = pt->x;	result->y = pt->y;	return result;}/*---------------------------------------------------------- *	Relational operators for Points. *		Since we do have a sense of coordinates being *		"equal" to a given accuracy (point_vert, point_horiz), *		the other ops must preserve that sense.  This means *		that results may, strictly speaking, be a lie (unless *		EPSILON = 0.0). *---------------------------------------------------------*/boolpoint_left(Point *pt1, Point *pt2){	return FPlt(pt1->x, pt2->x);}boolpoint_right(Point *pt1, Point *pt2){	return FPgt(pt1->x, pt2->x);}boolpoint_above(Point *pt1, Point *pt2){	return FPgt(pt1->y, pt2->y);}boolpoint_below(Point *pt1, Point *pt2){	return FPlt(pt1->y, pt2->y);}boolpoint_vert(Point *pt1, Point *pt2){	return FPeq(pt1->x, pt2->x);}boolpoint_horiz(Point *pt1, Point *pt2){	return FPeq(pt1->y, pt2->y);}boolpoint_eq(Point *pt1, Point *pt2){	return point_horiz(pt1, pt2) && point_vert(pt1, pt2);}boolpoint_ne(Point *pt1, Point *pt2){	return !point_eq(pt1, pt2);}/*---------------------------------------------------------- *	"Arithmetic" operators on points. *---------------------------------------------------------*/int32pointdist(Point *p1, Point *p2){	int32		result;	result = point_dt(p1, p2);	return result;}double *point_distance(Point *pt1, Point *pt2){	double	   *result = palloc(sizeof(double));	*result = HYPOT(pt1->x - pt2->x, pt1->y - pt2->y);	return result;}doublepoint_dt(Point *pt1, Point *pt2){#ifdef GEODEBUG	printf("point_dt- segment (%f,%f),(%f,%f) length is %f\n",		   pt1->x, pt1->y, pt2->x, pt2->y, HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));#endif	return HYPOT(pt1->x - pt2->x, pt1->y - pt2->y);}double *point_slope(Point *pt1, Point *pt2){	double	   *result = palloc(sizeof(double));	if (point_vert(pt1, pt2))		*result = (double) DBL_MAX;	else		*result = (pt1->y - pt2->y) / (pt1->x - pt1->x);	return result;}doublepoint_sl(Point *pt1, Point *pt2){	return (point_vert(pt1, pt2)			? (double) DBL_MAX			: (pt1->y - pt2->y) / (pt1->x - pt2->x));}/*********************************************************************** ** **		Routines for 2D line segments. ** ***********************************************************************//*---------------------------------------------------------- *	String to lseg, lseg to string conversion. *		External forms: "[(x1, y1), (x2, y2)]" *						"(x1, y1), (x2, y2)" *						"x1, y1, x2, y2" *		closed form ok	"((x1, y1), (x2, y2))" *		(old form)		"(x1, y1, x2, y2)" *---------------------------------------------------------*/LSEG *lseg_in(char *str){	LSEG	   *lseg;	int			isopen;	char	   *s;	if (!PointerIsValid(str))		elog(ERROR, " Bad (null) lseg external representation", NULL);	lseg = palloc(sizeof(LSEG));	if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0])))		|| (*s != '\0'))		elog(ERROR, "Bad lseg external representation '%s'", str);#ifdef NOT_USED	lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);#endif	return lseg;}	/* lseg_in() */char *lseg_out(LSEG *ls){	if (!PointerIsValid(ls))		return NULL;	return path_encode(FALSE, 2, (Point *) &(ls->p[0]));}	/* lseg_out() *//* lseg_construct - *		form a LSEG from two Points. */LSEG *lseg_construct(Point *pt1, Point *pt2){	LSEG	   *result = palloc(sizeof(LSEG));	result->p[0].x = pt1->x;	result->p[0].y = pt1->y;	result->p[1].x = pt2->x;	result->p[1].y = pt2->y;#ifdef NOT_USED	result->m = point_sl(pt1, pt2);#endif	return result;}/* like lseg_construct, but assume space already allocated */static voidstatlseg_construct(LSEG *lseg, Point *pt1, Point *pt2){	lseg->p[0].x = pt1->x;	lseg->p[0].y = pt1->y;	lseg->p[1].x = pt2->x;	lseg->p[1].y = pt2->y;#ifdef NOT_USED	lseg->m = point_sl(pt1, pt2);#endif}double *lseg_length(LSEG *lseg){	double	   *result;	if (!PointerIsValid(lseg))		return NULL;	result = point_distance(&lseg->p[0], &lseg->p[1]);	return result;}	/* lseg_length() *//*---------------------------------------------------------- *	Relative position routines. *---------------------------------------------------------*//* **  find intersection of the two lines, and see if it falls on **  both segments. */boollseg_intersect(LSEG *l1, LSEG *l2){	LINE	   *ln;	Point	   *interpt;	bool		retval;	ln = line_construct_pp(&l2->p[0], &l2->p[1]);	interpt = interpt_sl(l1, ln);	if (interpt != NULL && on_ps(interpt, l2))	/* interpt on l1 and l2 */		retval = TRUE;	else		retval = FALSE;	if (interpt != NULL)		pfree(interpt);	pfree(ln);	return retval;}boollseg_parallel(LSEG *l1, LSEG *l2){#ifdef NOT_USED	return FPeq(l1->m, l2->m);#endif	return (FPeq(point_sl(&(l1->p[0]), &(l1->p[1])),				 point_sl(&(l2->p[0]), &(l2->p[1]))));}	/* lseg_parallel() *//* lseg_perp() * Determine if two line segments are perpendicular. * * This code did not get the correct answer for *	'((0,0),(0,1))'::lseg ?-| '((0,0),(1,0))'::lseg * So, modified it to check explicitly for slope of vertical line *	returned by point_sl() and the results seem better. * - thomas 1998-01-31 */boollseg_perp(LSEG *l1, LSEG *l2){	double		m1,				m2;	m1 = point_sl(&(l1->p[0]), &(l1->p[1]));	m2 = point_sl(&(l2->p[0]), &(l2->p[1]));#ifdef GEODEBUG	printf("lseg_perp- slopes are %g and %g\n", m1, m2);#endif	if (FPzero(m1))		return FPeq(m2, DBL_MAX);	else if (FPzero(m2))		return FPeq(m1, DBL_MAX);	return FPeq(m1 / m2, -1.0);}	/* lseg_perp() */boollseg_vertical(LSEG *lseg){	return FPeq(lseg->p[0].x, lseg->p[1].x);}boollseg_horizontal(LSEG *lseg){	return FPeq(lseg->p[0].y, lseg->p[1].y);}boollseg_eq(LSEG *l1, LSEG *l2){	return (FPeq(l1->p[0].x, l2->p[0].x) &&			FPeq(l1->p[1].y, l2->p[1].y) &&			FPeq(l1->p[0].x, l2->p[0].x) &&			FPeq(l1->p[1].y, l2->p[1].y));}	/* lseg_eq() */boollseg_ne(LSEG *l1, LSEG *l2){	return (!FPeq(l1->p[0].x, l2->p[0].x) ||			!FPeq(l1->p[1].y, l2->p[1].y) ||			!FPeq(l1->p[0].x, l2->p[0].x) ||			!FPeq(l1->p[1].y, l2->p[1].y));}	/* lseg_ne() */boollseg_lt(LSEG *l1, LSEG *l2){	return FPlt(point_dt(&l1->p[0], &l1->p[1]), point_dt(&l2->p[0], &l2->p[1]));}	/* lseg_lt() */boollseg_le(LSEG *l1, LSEG *l2){	return FPle(point_dt(&l1->p[0], &l1->p[1]), point_dt(&l2->p[0], &l2->p[1]));}	/* lseg_le() */boollseg_gt(LSEG *l1, LSEG *l2){	return FPgt(point_dt(&l1->p[0], &l1->p[1]), point_dt(&l2->p[0], &l2->p[1]));}	/* lseg_gt() */boollseg_ge(LSEG *l1, LSEG *l2){	return FPge(point_dt(&l1->p[0], &l1->p[1]), point_dt(&l2->p[0], &l2->p[1]));}	/* lseg_ge() *//*---------------------------------------------------------- *	Line arithmetic routines. *---------------------------------------------------------*//* lseg_distance - *		If two segments don't intersect, then the closest *		point will be from one of the endpoints to the other *		segment. */double *lseg_distance(LSEG *l1, LSEG *l2){	double	   *result = palloc(sizeof(double));	*result = lseg_dt(l1, l2);	return result;}/* lseg_dt() * Distance between two line segments. * Must check both sets of endpoints to ensure minimum distance is found. * - thomas 1998-02-01 */static doublelseg_dt(LSEG *l1, LSEG *l2){	double	   *d,				result;	if (lseg_intersect(l1, l2))		return 0.0;	d = dist_ps(&l1->p[0], l2);	result = *d;	pfree(d);	d = dist_ps(&l1->p[1], l2);	result = Min(result, *d);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -