首页 > 解决方案 > 如果给出纬度,经度和方位角,如何检查两点相交?

问题描述

我有两种类型的站点,例如站点 A 和站点 B。每个站点都有自己的纬度、经度和方位角。

我需要检查站点 A 在以下情况下是否与 B 相交。

  1. 如果站点 A 正在寻找 B
  2. 如果第一步是真的,画一个三角形的 +35 度和 -35 度的方位角 A 和 B 的距离。例如,假设站点 A 和 B 之间的距离为 5 公里。那么三角形将是 5 公里,地点 A 和 B 的角度为 +35 度和 -35 度。
  3. 需要检查站点 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 等中解决这个问题。

标签: javascalageospatialpolygonintersection

解决方案


推荐阅读