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

📄 geo_ops.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	PG_RETURN_POINT_P(point);}Datumpoint_out(PG_FUNCTION_ARGS){	Point	   *pt = PG_GETARG_POINT_P(0);	PG_RETURN_CSTRING(path_encode(-1, 1, pt));}/* *		point_recv			- converts external binary format to point */Datumpoint_recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	Point	   *point;	point = (Point *) palloc(sizeof(Point));	point->x = pq_getmsgfloat8(buf);	point->y = pq_getmsgfloat8(buf);	PG_RETURN_POINT_P(point);}/* *		point_send			- converts point to binary format */Datumpoint_send(PG_FUNCTION_ARGS){	Point	   *pt = PG_GETARG_POINT_P(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendfloat8(&buf, pt->x);	pq_sendfloat8(&buf, pt->y);	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}static Point *point_construct(double x, double y){	Point	   *result = (Point *) 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 = (Point *) 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). *---------------------------------------------------------*/Datumpoint_left(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPlt(pt1->x, pt2->x));}Datumpoint_right(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPgt(pt1->x, pt2->x));}Datumpoint_above(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPgt(pt1->y, pt2->y));}Datumpoint_below(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPlt(pt1->y, pt2->y));}Datumpoint_vert(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPeq(pt1->x, pt2->x));}Datumpoint_horiz(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPeq(pt1->y, pt2->y));}Datumpoint_eq(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));}Datumpoint_ne(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_BOOL(FPne(pt1->x, pt2->x) || FPne(pt1->y, pt2->y));}/*---------------------------------------------------------- *	"Arithmetic" operators on points. *---------------------------------------------------------*/Datumpoint_distance(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_FLOAT8(HYPOT(pt1->x - pt2->x, pt1->y - pt2->y));}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);}Datumpoint_slope(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	PG_RETURN_FLOAT8(point_sl(pt1, pt2));}doublepoint_sl(Point *pt1, Point *pt2){	return (FPeq(pt1->x, pt2->x)			? (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)" *---------------------------------------------------------*/Datumlseg_in(PG_FUNCTION_ARGS){	char	   *str = PG_GETARG_CSTRING(0);	LSEG	   *lseg;	int			isopen;	char	   *s;	lseg = (LSEG *) palloc(sizeof(LSEG));	if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0])))		|| (*s != '\0'))		ereport(ERROR,				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),				 errmsg("invalid input syntax for type lseg: \"%s\"", str)));#ifdef NOT_USED	lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);#endif	PG_RETURN_LSEG_P(lseg);}Datumlseg_out(PG_FUNCTION_ARGS){	LSEG	   *ls = PG_GETARG_LSEG_P(0);	PG_RETURN_CSTRING(path_encode(FALSE, 2, (Point *) &(ls->p[0])));}/* *		lseg_recv			- converts external binary format to lseg */Datumlseg_recv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);	LSEG	   *lseg;	lseg = (LSEG *) palloc(sizeof(LSEG));	lseg->p[0].x = pq_getmsgfloat8(buf);	lseg->p[0].y = pq_getmsgfloat8(buf);	lseg->p[1].x = pq_getmsgfloat8(buf);	lseg->p[1].y = pq_getmsgfloat8(buf);#ifdef NOT_USED	lseg->m = point_sl(&lseg->p[0], &lseg->p[1]);#endif	PG_RETURN_LSEG_P(lseg);}/* *		lseg_send			- converts lseg to binary format */Datumlseg_send(PG_FUNCTION_ARGS){	LSEG	   *ls = PG_GETARG_LSEG_P(0);	StringInfoData buf;	pq_begintypsend(&buf);	pq_sendfloat8(&buf, ls->p[0].x);	pq_sendfloat8(&buf, ls->p[0].y);	pq_sendfloat8(&buf, ls->p[1].x);	pq_sendfloat8(&buf, ls->p[1].y);	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/* lseg_construct - *		form a LSEG from two Points. */Datumlseg_construct(PG_FUNCTION_ARGS){	Point	   *pt1 = PG_GETARG_POINT_P(0);	Point	   *pt2 = PG_GETARG_POINT_P(1);	LSEG	   *result = (LSEG *) 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	PG_RETURN_LSEG_P(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}Datumlseg_length(PG_FUNCTION_ARGS){	LSEG	   *lseg = PG_GETARG_LSEG_P(0);	PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1]));}/*---------------------------------------------------------- *	Relative position routines. *---------------------------------------------------------*//* **  find intersection of the two lines, and see if it falls on **  both segments. */Datumlseg_intersect(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(lseg_intersect_internal(l1, l2));}static boollseg_intersect_internal(LSEG *l1, LSEG *l2){	LINE		ln;	Point	   *interpt;	bool		retval;	line_construct_pts(&ln, &l2->p[0], &l2->p[1]);	interpt = interpt_sl(l1, &ln);	if (interpt != NULL && on_ps_internal(interpt, l2))		retval = true;			/* interpt on l1 and l2 */	else		retval = false;	return retval;}Datumlseg_parallel(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);#ifdef NOT_USED	PG_RETURN_BOOL(FPeq(l1->m, l2->m));#endif	PG_RETURN_BOOL(FPeq(point_sl(&l1->p[0], &l1->p[1]),						point_sl(&l2->p[0], &l2->p[1])));}/* 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 */Datumlseg_perp(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	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))		PG_RETURN_BOOL(FPeq(m2, DBL_MAX));	else if (FPzero(m2))		PG_RETURN_BOOL(FPeq(m1, DBL_MAX));	PG_RETURN_BOOL(FPeq(m1 / m2, -1.0));}Datumlseg_vertical(PG_FUNCTION_ARGS){	LSEG	   *lseg = PG_GETARG_LSEG_P(0);	PG_RETURN_BOOL(FPeq(lseg->p[0].x, lseg->p[1].x));}Datumlseg_horizontal(PG_FUNCTION_ARGS){	LSEG	   *lseg = PG_GETARG_LSEG_P(0);	PG_RETURN_BOOL(FPeq(lseg->p[0].y, lseg->p[1].y));}Datumlseg_eq(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(FPeq(l1->p[0].x, l2->p[0].x) &&				   FPeq(l1->p[0].y, l2->p[0].y) &&				   FPeq(l1->p[1].x, l2->p[1].x) &&				   FPeq(l1->p[1].y, l2->p[1].y));}Datumlseg_ne(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(!FPeq(l1->p[0].x, l2->p[0].x) ||				   !FPeq(l1->p[0].y, l2->p[0].y) ||				   !FPeq(l1->p[1].x, l2->p[1].x) ||				   !FPeq(l1->p[1].y, l2->p[1].y));}Datumlseg_lt(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1]),						point_dt(&l2->p[0], &l2->p[1])));}Datumlseg_le(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1]),						point_dt(&l2->p[0], &l2->p[1])));}Datumlseg_gt(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1]),						point_dt(&l2->p[0], &l2->p[1])));}Datumlseg_ge(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1]),						point_dt(&l2->p[0], &l2->p[1])));}/*---------------------------------------------------------- *	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. */Datumlseg_distance(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	PG_RETURN_FLOAT8(lseg_dt(l1, l2));}/* 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		result,				d;	if (lseg_intersect_internal(l1, l2))		return 0.0;	d = dist_ps_internal(&l1->p[0], l2);	result = d;	d = dist_ps_internal(&l1->p[1], l2);	result = Min(result, d);	d = dist_ps_internal(&l2->p[0], l1);	result = Min(result, d);	d = dist_ps_internal(&l2->p[1], l1);	result = Min(result, d);	return result;}Datumlseg_center(PG_FUNCTION_ARGS){	LSEG	   *lseg = PG_GETARG_LSEG_P(0);	Point	   *result;	result = (Point *) palloc(sizeof(Point));	result->x = (lseg->p[0].x + lseg->p[1].x) / 2.0;	result->y = (lseg->p[0].y + lseg->p[1].y) / 2.0;	PG_RETURN_POINT_P(result);}/* lseg_interpt - *		Find the intersection point of two segments (if any). */Datumlseg_interpt(PG_FUNCTION_ARGS){	LSEG	   *l1 = PG_GETARG_LSEG_P(0);	LSEG	   *l2 = PG_GETARG_LSEG_P(1);	Point	   *result;	LINE		tmp1,				tmp2;	/*	 * Find the intersection of the appropriate lines, if any.	 */	line_construct_pts(&tmp1, &l1->p[0], &l1->p[1]);	line_construct_pts(&tmp2, &l2->p[0], &l2->p[1]);	result = line_interpt_internal(&tmp1, &tmp2);	if (!PointerIsValid(result))		PG_RETURN_NULL();	/*	 * If the line intersection point isn't within l1 (or equivalently l2),	 * there is no valid segment intersection point at all.	 */	if (!on_ps_internal(result, l1) ||		!on_ps_internal(result, l2))		PG_RETURN_NULL();	/*	 * If there is an intersection, then check explicitly for matching	 * endpoints since there may be rounding effects with annoying lsb	 * residue. - tgl 1997-07-09	 */	if ((FPeq(l1->p[0].x, l2->p[0].x) && FPeq(l1->p[0].y, l2->p[0].y)) ||		(FPeq(l1->p[0].x, l2->p[1].x) && FPeq(l1->p[0].y, l2->p[1].y)))	{		result->x = l1->p[0].x;		result->y = l1->p[0].y;	}	else if ((FPeq(l1->p[1].x, l2->p[0].x) && FPeq(l1->p[1].y, l2->p[0].y)) ||			 (FPeq(l1->p[1].x, l2->p[1].x) && FPeq(l1->p[1].y, l2->p[1].y)))	{		result->x = l1->p[1].x;		result->y = l1->p[1].y;	}	PG_RETURN_POINT_P(result);}/*********************************************************************** ** **		Routines for position comparisons of differently-typed **				2D objects. ** ***********************************************************************//*--------------------------------------------------------------------- *		dist_

⌨️ 快捷键说明

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