Geolocation to calculate geodesic distances using google maps js (solved)


#1

Earlier I used the $cordovaGeolocation to get the user position so that I could calculate the distance using google maps js v3. It was working until recently. The code in the controller was:

LabResource.get().$promise.then(function(response) {
      $ionicLoading.hide();
      $scope.data.labs = response.labs;
      for (var i = 0; i < $scope.data.labs.length; i++) {
        from = new google.maps.LatLng(currentLocation.lat, currentLocation.lng);
        to = new google.maps.LatLng(lat, lng);
        dist = google.maps.geometry.spherical.computeDistanceBetween(from, to);
        km = (dist/1000).toFixed(1);
        console.log(km);
        $scope.data.labs[i].distance = parseFloat(km);
      }
});

Used the following code in app.js to broadcast the currentLocation so that it would be available to the controller

.run(function($cordovaGeolocation, $rootScope) {
  // Obtaining the user's location
  var posOptions = { timeout: 30000, enableHighAccuracy: true, maximumAge: 100000 };
  $cordovaGeolocation.getCurrentPosition(posOptions).then(function(position) {
    latlng = {'lat': position.coords.latitude, 'lng': postion.coords.longitude};
    $rootScope.$broadcast('currentLocation', { currentLocation: latlng });
    $rootScope.currentLocation = latlng;
  }, function(errror) {
    console.log('Got Error: '+error);
  });
  $rootScope.$digest();
})

Since the $cordovaGeolocation stopped working I made the switch to html5 navigator function. Added the following service

.factory('GeolocationService', [
  '$q',
  function($q) {
    return {
      getLocation: function(){
        var q = $q.defer();
        navigator.geolocation.getCurrentPosition(function(position) {
          latlng = {
            'lat': position.coords.latitude,
            'lng': position.coords.longitude
          };
          q.resolve(latlng);
        }, function(error) {
          console.log('Got error!');
          console.log(error);
          latlng = null;
          q.reject('Failed to get coordinates of surrent position');
        });
        return q.promise;
      }
    };
  }
])

Now I can get the user’s currentLocation using the service

GeolocationService.getLocation().then(function(result) {
  currentLocation = result;
});

What would be the best way to pass the currentLocation variable to the LabResource Controller so that I can compute the distance b/w two POIs. Polluting the rootscope by broadcasting doesn’t seem to be a good idea.
I have not advanced enough to understand the passing of variables between the service and a controller. I tried placing the controller withing the service function, but that didn’t help as well. I know its very simple and basic but I am stumped.


#2

I finally solved it by calling the LabResource Service from within the GeolocationService. But the crucial mistake was in the code block for calculating the distance. I was passing on unknow variables (lat, lng) to the from variable. I had to pass the individual resource (lab’s) lat and lng values to the from variable.

The successful code block was finally:

GeolocationService.getLocation().then(function(position) {
      $ionicLoading.show({
        template: '<ion-spinner></ion-spinner> Getting the list of labs'
      });

      // Getting the list of labs
      LabResource.get().$promise.then(function(response) {
        $ionicLoading.hide();
        $scope.data.labs = response.labs;
        for (var i = 0; i < $scope.data.labs.length; i++) {
          lat = $scope.data.labs[i].latitude;
          lng = $scope.data.labs[i].longitude;
          from = new google.maps.LatLng(position.lat, position.lng);
          to = new google.maps.LatLng(lat, lng);
          dist = google.maps.geometry.spherical.computeDistanceBetween(from, to);
          km = (dist/1000).toFixed(1);
          console.log(km);
          $scope.data.labs[i].distance = parseFloat(km);
        }
      });
    });

Also note that the geometry library has to be loaded alongwith the google maps js refernce in the index.html file like so:

<script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false&libraries=geometry"></script>

I am marking the post as solved.


#3

Can you provide a codepen?
I am working on similar kind of a thing and would be really helpful if I got some help.