# All files / lib/geocoder geocodiogeocoder.js

45% Statements 18/40
28.57% Branches 4/14
33.33% Functions 2/6
45% Lines 18/40

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    1042x
    2x
    2x

    2x

    6x

    5x

    1x

    4x
    4x

    2x

    2x

    2x

    2x
    1x
    1x

    1x

    1x

    2x
     var querystring = require('querystring'),
      util = require('util'),
      AbstractGeocoder = require('./abstractgeocoder');

    /**
     * Constructor
     */
    var GeocodioGeocoder = function GeocodioGeocoder(httpAdapter, apiKey) {

      GeocodioGeocoder.super_.call(this, httpAdapter);

      if (!apiKey || apiKey == 'undefined') {

        throw new Error(this.constructor.name + ' needs an apiKey');
      }

      this.apiKey = apiKey;
      this._endpoint = 'http://api.geocod.io/v1';
    };

    util.inherits(GeocodioGeocoder, AbstractGeocoder);

    /**
     * Geocode
     * @param <string>   value    Value to geocode (Address)
     * @param <function> callback Callback method
     */
    GeocodioGeocoder.prototype._geocode = function (value, callback) {
      var _this = this;
      this.httpAdapter.get(this._endpoint + '/geocode', {
        'q': value,
        'api_key': querystring.unescape(this.apiKey)
      }, function (err, result) {
        if (err) {
          return callback(err);
        }
        if (result.error) {
          return callback(new Error('Status is ' + result.error), {raw: result});
        }

        var results = [];

        var locations = result.results;

        for (var i = 0; i < locations.length; i++) {
          results.push(_this._formatResult(locations[i]));
        }

        results.raw = result;
        callback(false, results);
      });
    };

    GeocodioGeocoder.prototype._formatResult = function (result) {
      var accuracy = (result.accuracy < 1) ? result.accuracy - 0.1 : 1;
      return {
        'latitude': result.location.lat,
        'longitude': result.location.lng,
        'country': null,
        'city': result.address_components.city,
        'state': result.address_components.state,
        'zipcode': result.address_components.zip,
        'streetName': result.address_components.formatted_street,
        'streetNumber': result.address_components.number,
        'countryCode': null,
        'extra': {
          confidence: accuracy || 0
        }
      };
    };

    /**
     * Reverse geocoding
     * @param {lat:<number>,lon:<number>}  lat: Latitude, lon: Longitude
     * @param <function> callback Callback method
     */
    GeocodioGeocoder.prototype._reverse = function (query, callback) {
      var lat = query.lat;
      var lng = query.lon;

      var _this = this;

      this.httpAdapter.get(this._endpoint + '/reverse', {
        'q': lat + ',' + lng,
        'api_key': querystring.unescape(this.apiKey)
      }, function (err, result) {
        if (err) {
          return callback(err);
        }

        var results = [];
        var locations = result.results;

        for (var i = 0; i < locations.length; i++) {
          results.push(_this._formatResult(locations[i]));
        }

        results.raw = result;
        callback(false, results);
      });
    };

    module.exports = GeocodioGeocoder;