Search code examples
phpjsonangulartypescripthttpclient

Angular httpClient get users from an Array of JSON using Longitude Latitude Haversine formula


I have list of users in a JSON file

[
  {
      "id": 1,
      "first_name": "Maurise",
      "last_name": "Shieldon",
      "latitude": 34.003135,
      "longitude": -117.7228641
  },
  {
      "id": 2,
      "first_name": "Bendix",
      "last_name": "Halgarth",
      "latitude": -2.9623869,
      "longitude": 104.7399789
  },
  {
      "id": 3,
      "first_name": "Meghan",
      "last_name": "Southall",
      "latitude": "15.45033",
      "longitude": "44.12768"
  },
  {
      "id": 4,
      "first_name": "Sidnee",
      "last_name": "Silwood",
      "latitude": -26.94087,
      "longitude": 29.24905
  },
  {
      "id": 5,
      "first_name": "Rosita",
      "last_name": "Ferrulli",
      "latitude": 33.5719791,
      "longitude": -84.3396421
  }]

I am using Haversine formula to calculate distance so that i can only get users of certain LAT and LONG values this method is in my api.service.ts class.

   getDistanceFromLatLon(lat1: number, lon1: number, lat2: number, lon2: number): number {
    var deg2Rad = deg => {
      return deg * Math.PI / 180;
    }
    var r = 3959; // Radius of the earth in miles
    var dLat = deg2Rad(lat2 - lat1);
    var dLon = deg2Rad(lon2 - lon1);
    var a =
      Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.cos(deg2Rad(lat1)) * Math.cos(deg2Rad(lat2)) *
      Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = r * c; // Distance in miles
    return d;
  }

Then in my app.component.ts file i can call JSON Array which gives me list of all users in data.json file from my list of users above.

getUsers() {
this.httpClient.get('/assets/users.json').pipe(map(data => data as Array<Users>))
      .subscribe(result => { console.log(result)}

After i receive list of all users from my JSON file. I am trying to run the JSON result Array through the getDistanceFromLatLon method so that only users with LONDON_LAT and LONDON_LONG can displayed


 //Latitude and longitude of London
  LONDON_LAT = 51.509865;
  LONDON_LONG = -0.118092;
  miles;

const distance = this.apiService.getDistanceFromLatLon(result['latitude'], result['longitude'], 
this.LONDON_LAT, this.LONDON_LONG);
        if (distance <= this.miles) {
          this.UsersByRadius = result;
        }
      });
}

After compiling through the .getDistanceFromLatLon my this.UsersByRadius = result is empty and i am not getting any users. I am basically trying to replicate this PHP application in my angular app. Any help will be much appreciated.


Solution

    1. Angular SPA are usually generated client-side. So all the mathematical calculations (a single division operation has a heavy overhead, not to mention all the trig functions) will be heavy overload when dealing with large array sets. You should consider doing it server-side.

    2. You are retreiving an array. So you need to loop through each of them to call the function.

    getUsers() {
      this.httpClient.get('/assets/users.json').pipe(
        map(data => data as Array<Users>)
      ).subscribe(result => { 
        console.log(result);
        result.forEach(item => {
          const distance = this.apiService.getDistanceFromLatLon(item['latitude'], item['longitude'], this.LONDON_LAT, this.LONDON_LONG);
          if (distance <= this.miles) {
            this.UsersByRadius.push({
              id: item['id'],   
              first_name: item['first_name'],
              last_name: item['last_name'],   
              latitude: item['latitude'],   
              longitude: item['longitute'],
              city: 'London'
            });
          }
        });
      });
    }