java - 如果给出纬度,经度和方位角,如何检查两点相交?
问题描述
我有两种类型的站点,例如站点 A 和站点 B。每个站点都有自己的纬度、经度和方位角。
我需要检查站点 A 在以下情况下是否与 B 相交。
- 如果站点 A 正在寻找 B
- 如果第一步是真的,画一个三角形的 +35 度和 -35 度的方位角 A 和 B 的距离。例如,假设站点 A 和 B 之间的距离为 5 公里。那么三角形将是 5 公里,地点 A 和 B 的角度为 +35 度和 -35 度。
- 需要检查站点 A 和站点 B 的三角形是否相互交叉。
我有以下数据:
+----------+-----------+--------------+----------+-----------+--------------+
|source_lat|source_long|source_azimuth|target_lat|target_long|target_azimuth|
+----------+-----------+--------------+----------+-----------+--------------+
|18.3965 |74.7274 |20 |18.431 |74.7778 |245 |
|18.3965 |74.7274 |320 |18.44394 |74.72676 |170 |
|18.45306 |74.67871 |70 |18.44394 |74.72676 |170 |
|18.45306 |74.67871 |160 |18.44394 |74.72676 |170 |
|18.45306 |74.67871 |150 |18.44394 |74.72676 |170 |
|18.3965 |74.7274 |20 |18.40797 |74.65001 |70 |
|18.3965 |74.7274 |260 |18.45008 |74.81401 |270 |
|18.45306 |74.67871 |70 |18.51339 |74.70244 |90 |
|18.3965 |74.7274 |260 |18.44394 |74.72676 |170 |
|18.3965 |74.7274 |320 |18.44394 |74.72676 |170 |
|18.45306 |74.67871 |280 |18.40797 |74.65001 |30 |
|18.45306 |74.67871 |290 |18.40797 |74.65001 |30 |
+----------+-----------+--------------+----------+-----------+--------------+
这里我使用 scala 编程,我使用下面的代码来计算距离和方位。
/*
* That function takes lat and long of site A and Site B
* @return concate of distance and bearing like
* suppose distance is 2 (KM) and bearing is 120 then return 2_120.
* later i split that above string by underscore "_" to get distance and bearing.
*/
private val AVERAGE_RADIUS_OF_EARTH_KM = 6371
def calculateDistanceInKilometer(userLat1: String,userLong1: String, wareHouseLat1:String,wareHouseLong1 : String): Option[String] = {
if ((userLat1 != null) && (userLong1 != null) && (wareHouseLat1 != null) && (wareHouseLong1 != null)) {
val latDistance = Math.toRadians(userLat1.toDouble - wareHouseLat1.toDouble)
val lngDistance = Math.toRadians(userLong1.toDouble - wareHouseLong1.toDouble)
val sinLat = Math.sin(latDistance / 2)
val sinLng = Math.sin(lngDistance / 2)
val a = sinLat * sinLat +
(Math.cos(Math.toRadians(userLat1.toDouble)) *
Math.cos(Math.toRadians(wareHouseLat1.toDouble)) *
sinLng * sinLng)
val c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
var lat1 = Math.toRadians(userLat1.toDouble)
var lng1 = Math.toRadians(userLong1.toDouble)
var lat2 = Math.toRadians(wareHouseLat1.toDouble)
var lng2 = Math.toRadians(wareHouseLong1.toDouble)
//Source//Source
val dLon = lng2 - lng1
val y = Math.sin(dLon) * Math.cos(lat2)
val x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon)
var brng = Math.toDegrees(Math.atan2(y, x))
brng = (brng + 360) % 360
val distance = (AVERAGE_RADIUS_OF_EARTH_KM * c).toDouble
val final_data = distance.toString + "_" + brng.toString
Some(final_data)
}else{
None
}
}
在得到距离和方位之后,我已经分裂并得到了距离和方位。并给出列名作为距离,azimuth_between。
现在我已经习惯了以下逻辑来检查天气站点 A 和站点 B 相互交叉,就像
//.withColumn("matched",expr("case when ((target_azimuth <= (azimuth_between + 270) and target_azimuth >= (azimuth_between + 90)) or ((target_azimuth+360) <= (azimuth_between + 270) and (target_azimuth+360) >= (azimuth_between + 90))) then 'intersect' else 'Not intersect'"))
case when ((target_azimuth <= (azimuth_between + 270) and target_azimuth >= (azimuth_between + 90)) or ((target_azimuth+360) <= (azimuth_between + 270) and (target_azimuth+360) >= (azimuth_between + 90))) then 'intersect' else 'Not intersect'
上面的代码给出了正确的天气站点 A 与站点 B 相交,但它不限于距离(获取两个站点 a 和站点 b 之间的距离),必须仅在距离内检查。有时站点 A 在 10 公里、20 公里后与站点 B 相交,但必须与实际距离相交。
请检查我们是否可以在 Java、Scala、Mysql、PostGresSql 等中解决这个问题。
解决方案
推荐阅读
- python - 如何在 ffmpeg-python 中使用“最短”参数
- html - 在 R Shiny 中设置相对链接/锚点
- python - 如何在 Atoti 中动态过滤向量?
- json - 使用 Google 表格作为 JSON 端点的 Google 表格发布到 Web 问题
- python - 如何使方法 JSON 可序列化以在自定义 Pyspark 转换器中使用
- angular - 一个 svg 图片文件在 Palette 中渲染成功,但在 Angular 和 GoJS 中却没有
- mysql - 存储过程中查询不使用主索引,速度很慢
- c# - 如何更改 netstandard 2.0 库使用的 Newtonsoft.Json 的版本
- wmi - 设计电压参数是什么意思
- android - collectionGroup 查询可以选择父文档的所有内部文档吗