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
}
golang通过基于三角函数的算法计算当前坐标距离另外两个坐标连成线后距离这条线的距离
于 2023-07-06 13:52:37 首次发布