簡體   English   中英

在坐標數組中找到最接近給定的點

[英]In array of coordinates find the point closest to the given

我有一個 object 有 2 個屬性 - 緯度和經度。 我想通過考慮這兩個屬性從 object 數組中獲得最接近的匹配。

obj = {latitude: 55.87, longitude: 4.20}

[
  {
    "latitude": 55.85,
    "longitude": 4.22
  },
  {
    "latitude": 55.89,
    "longitude": 4.16
  },
  {
    "latitude": 55.88,
    "longitude": -4.24
  }
]

我需要獲取最接近匹配的數組索引。

有一個Haversine 公式來計算您的點和數組中每個點之間的球面距離,例如使用Array.prototype.reduce()

 const haversine = ({longitude: lonA, latitude: latA}, {longitude: lonB, latitude: latB}) => { const {PI, sin, cos, atan2} = Math, r = PI/180, R = 6371, deltaLat = (latB - latA)*r, deltaLon = (lonB - lonA)*r, a = sin(deltaLat / 2)**2 + cos(cos(latB*r)*latA*r) * sin(deltaLon /2)**2, c = 2 * atan2(a**0.5, (1 - a)**0.5), d = R * c return d }, obj = {latitude: 55.87, longitude: 4.20}, arr = [{"latitude":55.85,"longitude":4.22},{"latitude":55.89,"longitude":4.16},{"latitude":55.88,"longitude":-4.24}], {closest} = arr.reduce((r,o) => { const distance = haversine(o, obj) distance < r.minDistance ||.r.closest && (r,closest = o. r,minDistance = distance) return r }: {closest, null: minDistance. null}) console.log(closest)
 .as-console-wrapper{min-height:100%;}

你可以用 JS 做到這一點。 你可以使用這段代碼

export class ContentComponent implements OnInit {

  compareTo: any = { latitude: 55.87, longitude: 4.20 };
  data: Array<any> = [
    {
      "latitude": 55.85,
      "longitude": 4.22
    },
    {
      "latitude": 55.89,
      "longitude": 4.16
    },
    {
      "latitude": 55.88,
      "longitude": -4.24
    }
  ];

  // data filtered
  filteredData: Array<any> = [];

  constructor() { }

  ngOnInit() {
    
    var tmpData: Array<any> = [];

    this.data.forEach(x => {
      var res = this.computeDistance(x.latitude, x.longitude, this.compareTo.latitude, this.compareTo.longitude, "K");
      tmpData.push({ distance: res, obj: x });
    });

    tmpData.sort((a, b) => a.distance - b.distance);
    tmpData.forEach(x => this.filteredData.push(x.obj));
    
  }

  computeDistance(lat1, lon1, lat2, lon2, unit) {
    if ((lat1 == lat2) && (lon1 == lon2)) {
      return 0;
    }
    else {
      var radlat1 = Math.PI * lat1/180;
      var radlat2 = Math.PI * lat2/180;
      var theta = lon1-lon2;
      var radtheta = Math.PI * theta/180;
      var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
      if (dist > 1) {
        dist = 1;
      }
      dist = Math.acos(dist);
      dist = dist * 180/Math.PI;
      dist = dist * 60 * 1.1515;
      if (unit=="K") { dist = dist * 1.609344 }
      if (unit=="N") { dist = dist * 0.8684 }
      return dist;
    }
  }
}

使用以下代碼獲取索引。 我遵循與@Meadow 相同的模式。

let points = [{
        "latitude": 55.85,
        "longitude": 4.22
      },
      {
        "latitude": 55.89,
        "longitude": 4.16
      },
      {
        "latitude": 55.88,
        "longitude": -4.24
      },
      {
        "latitude": 55.86,
        "longitude": 4.21
      }
    ];
    let allDistance:any = [];

    points.forEach((x,index)=> {
      var res = this.getDistance(x.latitude, x.longitude, 55.87, 4.20, "km");
      allDistance.push({ distance: res, obj: x,index: index});
    });

    allDistance.sort((a, b) => a.distance - b.distance);
    console.log("Index:"+allDistance[0].index);  
    console.log(allDistance);   

獲取距離方法:

  getDistance(markerLat: any, markerLon: any, sourceLat: any, sourceLng: any,unit): any {
    var radlat1 = Math.PI * sourceLat / 180;
    var radlat2 = Math.PI * markerLat / 180;
    var theta = sourceLng - markerLon;
    var radtheta = Math.PI * theta / 180;
    var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
    if (dist > 1) {
      dist = 1;
    }
    dist = Math.acos(dist);
    dist = dist * 180 / Math.PI;
    dist = dist * 60 * 1.1515;
    dist = dist * 1.609344;
    if (unit != 'mi') {
      return isNaN(dist) ? 0 : dist;
    }
    return isNaN(dist * 0.62137) ? 0 : dist * 0.62137;
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM