# All files / lib geocoder.js

77.78% Statements 35/45
37.5% Branches 6/16
85% Functions 17/20
77.78% Lines 35/45

    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
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133

    2x

    2x
    28x
    28x

    2x
    5x

    5x
    5x

    5x

    5x

    2x
    2x

    2x
    2x

    2x

    2x
    2x

    3x

    3x

    2x
    5x
    5x

    2x
    7x
    7x

    7x

    7x

    7x

    7x
    7x

    7x

    7x
    7x

    7x

    2x
     'use strict';

    var BPromise = require('bluebird');

    /**
    * Constructor
    * @param <object> geocoder  Geocoder Adapter
    * @param <object> formatter Formatter adapter or null
    */
    var Geocoder = function (geocoder, formatter) {
      this._geocoder = geocoder;
      this._formatter = formatter;
    };

    /**
    * Geocode a value (address or ip)
    * @param <string>   value    Value to geocoder (address or IP)
    * @param <function> callback Callback method
    */
    Geocoder.prototype.geocode = function (value, callback) {
      return BPromise.resolve()
        .bind(this)
        .then(function() {
          return BPromise.fromCallback(function(callback) {
            this._geocoder.geocode(value, callback);
          }.bind(this));
        })
        .then(function(data) {
          return this._filter(value, data);
        })
        .then(function(data) {
          return this._format(data);
        })
        .asCallback(callback);
    };

    /**
    * Reverse geocoding
    * @param {lat:<number>,lon:<number>}  lat: Latitude, lon: Longitude
    * @param {function} callback Callback method
    */
    Geocoder.prototype.reverse = function(query, callback) {
      return BPromise.resolve()
        .bind(this)
        .then(function() {
          return BPromise.fromCallback(function(callback) {
            this._geocoder.reverse(query, callback);
          }.bind(this));
        })
        .then(function(data) {
          return this._format(data);
        })
        .asCallback(callback);
    };

    /**
    * Batch geocode
    * @param <array>    values    array of Values to geocode (address or IP)
    * @param <function> callback
    *
    * @return promise
    */
    Geocoder.prototype.batchGeocode = function(values, callback) {
      return BPromise.resolve(values)
        .bind(this)
        .map(function(value) {
          return this.geocode(value)
            .then(function(value) {
              return {
                error: null,
                value: value
              };
            })
            .catch(function(error) {
              return {
                error: error,
                value: null
              };
            });
        })
        .asCallback(callback);
    };

    Geocoder.prototype._filter = function (value, data) {
      Eif (!data || !data.length) {
        return data;
      }

      if (value.minConfidence) {
        data = data.filter(function(geocodedAddress) {
          if (geocodedAddress.extra && geocodedAddress.extra.confidence) {
            return geocodedAddress.extra.confidence >= value.minConfidence;
          }
        });
      }

      return data;
    };

    Geocoder.prototype._format = function (data) {
      var _this = this;
      return BPromise.resolve()
        .bind(this)
        .then(function() {
          Iif (!data) {
            return data;
          }

          var _raw = data.raw;

          data = data.map(function(result) {
            result.provider = _this._geocoder.name;

            return result;
          });

          data.raw = _raw;
          Object.defineProperty(data,'raw',{configurable:false, enumerable:false, writable:false});

          return data;
        })
        .then(function(data) {
          var _data = data;
          Iif (this._formatter && this._formatter !== 'undefined') {
            _data = this._formatter.format(_data);
          }

          return _data;
        });
    };

    module.exports = Geocoder;