Geolocation JavaScript


var locator = function () {
  var _logger;
 
  /* Public Methods
   *******************************************************************/
 
  this.attachLogger = function (logger) {
    _logger = logger;
    _logger.log('attached logger');
  };
 
  this.resolveLocation = function (successCallback, failCallback) {
    _resolveLocation(successCallback, failCallback);
  };
 
  this.getLocationDetails = function (
    latitude,
    longitude,
    successCallback,
    failCallback,
  ) {
    _googleReverseGeocode(latitude, longitude, successCallback, failCallback);
  };
 
  this.getFirstGeocodedAddress = function (
    results,
    successCallback,
    failCallback,
  ) {
    _getFirstGeocodedAddress(results, successCallback, failCallback);
  };
 
  /* Private Methods
   *******************************************************************/
 
  /// Looks up the user’s location using HTML gelocation if available.
  /// If the user denies access or it’s not available, it falls back to
  /// Google’s geolocation API. If this isn't available or fails, the
  /// failure callback is called.
  var _resolveLocation = function (successCallback, failCallback) {
    // HTML5 geolocation
    if (navigator.geolocation) {
      _log('HTML5 geolocation available');
 
      navigator.geolocation.getCurrentPosition(
        function (position) {
          _log('HTML5 geolocation success');
          successCallback({
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
          });
        },
 
        // Revert to Google if user denies access
        function () {
          _log('HTML5 geolocation failed, reverting to Google');
          _googleLocation(successCallback, failCallback);
        },
      );
    } else {
      _log('HTML5 geolocation unavailable, reverting to Google');
      _googleLocation(successCallback, failCallback);
    }
  };
 
  /// Looks up the user’s location using the Google geocoding API.
  var _googleLocation = function (successCallback, failCallback) {
    if (_canUseGoogle()) {
      _log('Google geolocation available');
      var location = google.loader.ClientLocation;
 
      if (location) {
        _log('Google geolocation success');
        successCallback({
          latitude: location.latitude,
          longitude: location.longitude,
        });
      } else {
        _log('Google geolocation failure');
        failCallback();
      }
    } else {
      _log('Google geolocation unavailable');
      failCallback();
    }
  };
 
  /// Reverse gecodes a LatLng using the Google geocoder.
  var _googleReverseGeocode = function (
    latitude,
    longitude,
    successCallback,
    failCallback,
  ) {
    _log('Reverse geocoding');
    var geocoder = new google.maps.Geocoder();
 
    if (geocoder) {
      _log('Reverse geocoding available');
      var latLng = new google.maps.LatLng(latitude, longitude);
      geocoder.geocode({ latLng: latLng }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          _log('Reverse geocoding success');
          successCallback(results);
        } else {
          _log('Reverse geocoding failure');
          failCallback(status);
        }
      });
    } else {
      _log('Reverse geocoding unavailable');
    }
  };
 
  // Gets the first formatted address from a list of geocoded results.
  var _getFirstGeocodedAddress = function (
    results,
    successCallback,
    failCallback,
  ) {
    _log('Getting geocoded address');
    var address = results[0].formatted_address;
    if (address) {
      _log('Getting geocoded address success');
      successCallback(address);
    } else {
      _log('Getting geocoded address failure');
      failCallback();
    }
  };
 
  // Check to see whether the google.loader.ClientLocation is available.
  var _canUseGoogle = function () {
    return (
      typeof google == 'object' && google.loader && google.loader.ClientLocation
    );
  };
 
  var _log = function (message) {
    if (_logger) {
      _logger.log(message);
    }
  };
};