golang通过基于三角函数的算法计算当前坐标距离另外两个坐标连成线后距离这条线的距离

func main() {
	//实际场景可用于临近水域预警功能,临近水域预警距离为100米,检测当前坐标是否临近水域坐标,如果临近100米以内,随后对用户发出预警。水域数据内有多个坐标, 循环使用当前坐标与水域数据内的a与b坐标进行检测是否在100米以内,不符合则继续使用当前坐标与水域数据内的b与c坐标进行检测,依次往下类推,直至检测出符合100米以内坐标
	//坐标系,高德gcj02

	//point为当前坐标
	point := &Point{Lat: 34.771526, Lng: 113.724931}
	linePoint1 := &Point{Lat: 34.774073, Lng: 113.724346}
	linePoint2 := &Point{Lat: 34.770851, Lng: 113.72661}


	//三个坐标在一条直线上
	//point := &Point{Lat: 34.77410889653855, Lng: 113.72487674087613}
	//linePoint1 := &Point{Lat: 34.774095, Lng: 113.724346}
	//linePoint2 := &Point{Lat: 34.774121, Lng: 113.725339}

	// 计算点到线的距离
	distance := CalculateDistanceToLine(point, linePoint1, linePoint2)
	fmt.Printf("Distance: %.2f meters\n", distance)

}

//通过基于三角函数的算法计算当前坐标距离另外两个坐标连成线后距离这条线的距离
func CalculateDistanceToLine(point, linePoint1, linePoint2 *Point) float64 {
	if CalculateDistance(point, linePoint1) > 280 && CalculateDistance(point, linePoint2) > 280{
		return 0
	}
	// 计算点到线段起点的向量和线段方向的向量
	startToP := &Point{Lat: point.Lat - linePoint1.Lat, Lng: point.Lng - linePoint1.Lng}
	lineDirection := &Point{Lat: linePoint2.Lat - linePoint1.Lat, Lng: linePoint2.Lng - linePoint1.Lng}

	// 计算线段长度平方
	lineLength := lineDirection.Lat*lineDirection.Lat + lineDirection.Lng*lineDirection.Lng

	// 如果线段长度为 0,返回点到线段起点的距离
	if lineLength == 0 {
		return CalculateDistance(point, linePoint1)
	}

	// 计算点到线段的投影长度
	ratio := (startToP.Lat*lineDirection.Lat + startToP.Lng*lineDirection.Lng) / lineLength

	// 如果点在线段的延长线上
	if ratio < 0 {
		return CalculateDistance(point, linePoint1)
	} else if ratio > 1 { // 如果点在线段的另一端延长线上
		return CalculateDistance(point, linePoint2)
	} else {
		// 如果点在线段中间
		// 计算点到线段的垂线长度
		projectionPoint := &Point{Lat: linePoint1.Lat + ratio*lineDirection.Lat, Lng: linePoint1.Lng + ratio*lineDirection.Lng}
		distance := CalculateDistance(point, projectionPoint)
		return distance
	}
}
func CalculateDistance(p1, p2 *Point) float64 {
	earthRadius := 6371000.0 // 地球半径,单位为米
	lat1, lng1 := p1.Lat*math.Pi/180.0, p1.Lng*math.Pi/180.0
	lat2, lng2 := p2.Lat*math.Pi/180.0, p2.Lng*math.Pi/180.0
	dlat := lat2 - lat1
	dlng := lng2 - lng1
	a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Cos(lat1)*math.Cos(lat2)*math.Sin(dlng/2)*math.Sin(dlng/2)
	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
	return earthRadius * c
}


在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值