All files / lib/geocoder yandexgeocoder.js

80.39% Statements 41/51
59.09% Branches 13/22
100% Functions 9/9
80.39% Lines 41/51
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 134 135 136 137 138 139 140    2x 2x             2x 7x     2x     48x 48x   94x 11x 11x     83x 36x   36x     47x     48x       2x 2x   2x                             4x         4x         4x           4x         4x                 4x           2x             2x 4x         4x   4x 2x     2x   2x 2x     2x 2x                   2x 2x 2x   2x   2x       2x  
'use strict';
 
var util = require('util');
var AbstractGeocoder = require('./abstractgeocoder');
 
/**
 * Constructor
 * @param <object> httpAdapter Http Adapter
 * @param <object> options     Options (language, clientId, apiKey)
 */
var YandexGeocoder = function YandexGeocoder(httpAdapter, options) {
  YandexGeocoder.super_.call(this, httpAdapter, options);
};
 
util.inherits(YandexGeocoder, AbstractGeocoder);
 
function _findKey(result, wantedKey) {
  var val = null;
  Object.keys(result).every(function(key) {
 
  if (key === wantedKey) {
    val = result[key];
    return false;
  }
 
  if (typeof result[key] === 'object') {
    val = _findKey(result[key], wantedKey);
 
    return val === null ? true : false;
  }
 
  return true;
  });
 
  return val;
}
 
function _formatResult(result) {
  var position = result.GeoObject.Point.pos.split(' ');
  result = result.GeoObject.metaDataProperty.GeocoderMetaData.AddressDetails;
 
  return {
    'latitude' : parseFloat(position[1]),
    'longitude' : parseFloat(position[0]),
    'city' : _findKey(result, 'LocalityName'),
    'state' : _findKey(result, 'AdministrativeAreaName'),
    'streetName': _findKey(result, 'ThoroughfareName'),
    'streetNumber' : _findKey(result, 'PremiseNumber'),
    'countryCode' : _findKey(result, 'CountryNameCode'),
    'country' : _findKey(result, 'CountryName')
  };
}
 
function _processOptionsToParams(params, options){
 
  //language (language_region, ex: `ru_RU`, `uk_UA`)
  Iif (options.language) {
    params.lang = options.language;
  }
 
  //results count (default 10)
  Iif (options.results) {
    params.results = options.results;
  }
 
  //skip count (default 0)
  Iif (options.skip) {
    params.skip = options.skip;
  }
 
  //Type of toponym (only for reverse geocoding)
  //could be `house`, `street`, `metro`, `district`, `locality`
  Iif (options.kind) {
    params.kind = options.kind;
  }
 
  //BBox (ex: `[[lat: 1.0, lng:2.0],[lat: 1.1, lng:2.2]]`)
  Iif (options.bbox) {
    if (options.bbox.length === 2){
      params.kind = options.bbox[0].lng + ',' + options.bbox[0].lat;
      params.kind = params.kind + '~';
      params.kind = params.kind + options.bbox[1].lng + ',' + options.bbox[1].lat;
    }
  }
 
  //Limit search in bbox (1) or not limit (0)
  Iif (options.rspn) {
    params.rspn = options.rspn;
  }
}
 
// Yandex geocoding API endpoint
YandexGeocoder.prototype._endpoint = 'https://geocode-maps.yandex.ru/1.x/';
 
/**
* Geocode
* @param <string>   value    Value to geocode (Address)
* @param <function> callback Callback method
*/
YandexGeocoder.prototype._geocode = function(value, callback) {
  var params = {
    geocode : value,
    format: 'json'
  };
 
  _processOptionsToParams(params, this.options);
 
  this.httpAdapter.get(this._endpoint, params, function(err, result) {
    Iif (err) {
      return callback(err);
    } else {
      var results = [];
 
      result.response.GeoObjectCollection.featureMember.forEach(function(geopoint) {
        results.push(_formatResult(geopoint));
      });
 
      results.raw = result;
      callback(false, results);
    }
  });
};
 
/**
 * Reverse geocoding
 * @param {lat:<number>,lon:<number>}  lat: Latitude, lon: Longitude
 * @param <function> callback Callback method
 */
YandexGeocoder.prototype._reverse = function (query, callback) {
  var lat = query.lat;
  var lng = query.lon;
 
  var value = lng + ',' + lat;
 
  this._geocode(value, callback);
};
 
 
module.exports = YandexGeocoder;