Программный интерфейс

Показывать:
/**
 * Объекты для доступа к геокодерам Яндекс, Google и sypexgeo<br />
 * &copy; Evgeniy Malyarov http://www.oknosoft.ru 2014-2016<br />
 * Created 16.04.2016
 *
 * @module geocoding
 */

/**
 * ### Данные геолокации
 * Объект предоставляет доступ к функциям _геокодирования браузера_, а так же - геокодерам _Яндекс_ и _Гугл_
 *
 * @class IPInfo
 * @static
 * @menuorder 60
 * @tooltip Данные геолокации
 */
function IPInfo(){

  var _yageocoder,
    _ggeocoder,
    _ipgeo,
    _addr = "",
    _parts;

  /**
   * Геокодер карт Яндекс
   * @class YaGeocoder
   * @static
   */
  function YaGeocoder(){

    /**
     * Выполняет прямое или обратное геокодирование
     * @method geocode
     * @param attr {Object}
     * @return {Promise.<T>}
     */
    this.geocode = function (attr) {
      //http://geocode-maps.yandex.ru/1.x/?geocode=%D0%A7%D0%B5%D0%BB%D1%8F%D0%B1%D0%B8%D0%BD%D1%81%D0%BA,+%D0%9F%D0%BB%D0%B5%D1%85%D0%B0%D0%BD%D0%BE%D0%B2%D0%B0+%D1%83%D0%BB%D0%B8%D1%86%D0%B0,+%D0%B4%D0%BE%D0%BC+32&format=json&sco=latlong
      //http://geocode-maps.yandex.ru/1.x/?geocode=61.4080273,55.1550362&format=json&lang=ru_RU

      return Promise.resolve(false);
    }
  }



  this.__define({

    ipgeo: {
      value: function () {
        return $p.ajax.get("//api.sypexgeo.net/")
          .then(function (req) {
            return JSON.parse(req.response);
          })
          .catch($p.record_log);
      }
    },

    /**
     * Объект [геокодера yandex](https://tech.yandex.ru/maps/doc/geocoder/desc/concepts/input_params-docpage/)
     * @property yageocoder
     * @for IPInfo
     * @type YaGeocoder
     */
    yageocoder: {
      get : function(){

        if(!_yageocoder)
          _yageocoder = new YaGeocoder();
        return _yageocoder;
      },
      enumerable : false,
      configurable : false
    },

    /**
     * Объект [геокодера google](https://developers.google.com/maps/documentation/geocoding/?hl=ru#GeocodingRequests)
     * @property ggeocoder
     * @for IPInfo
     * @type {google.maps.Geocoder}
     */
    ggeocoder: {
      get : function(){
        return _ggeocoder;
      },
      enumerable : false,
      configurable : false
    },

    /**
     * Адрес геолокации пользователя программы
     * @property addr
     * @for IPInfo
     * @type String
     */
    addr: {
      get : function(){
        return _addr;
      }
    },

    parts: {
      get : function(){
        return _parts;
      }
    },

    /**
     * Выполняет синтаксический разбор частей адреса
     */
    components: {
      value : function(v, components){
        var i, c, j, street = "", street0 = "", locality = "";
        for(i in components){
          c = components[i];
          //street_number,route,locality,administrative_area_level_2,administrative_area_level_1,country,sublocality_level_1
          for(j in c.types){
            switch(c.types[j]){
              case "route":
                if(c.short_name.indexOf("Unnamed")==-1){
                  street = c.short_name + (street ? (" " + street) : "");
                  street0 = c.long_name.replace("улица", "").trim();
                }
                break;
              case "administrative_area_level_1":
                v.region = c.long_name;
                break;
              case "administrative_area_level_2":
                v.city = c.short_name;
                v.city_long = c.long_name;
                break;
              case "locality":
                locality = (locality ? (locality + " ") : "") + c.short_name;
                break;
              case "street_number":
                street = (street ? (street + " ") : "") + c.short_name;
                break;
              case "postal_code":
                v.postal_code = c.short_name;
                break;
              default:
                break;
            }
          }
        }
        if(v.region && v.region == v.city_long)
          if(v.city.indexOf(locality) == -1)
            v.city = locality;
          else
            v.city = "";
        else if(locality){
          if(v.city.indexOf(locality) == -1 && v.region.indexOf(locality) == -1)
            street = locality + ", " + street;
        }

        // если в адресе есть подстрока - не переписываем
        if(!v.street || v.street.indexOf(street0)==-1)
          v.street = street;

        return v;
      }
    },

    /**
     * Функция обратного вызова для карт Google
     */
    location_callback: {
      value: function(){

        _ggeocoder = new google.maps.Geocoder();

        $p.eve.callEvent("geo_google_ready");

        if(navigator.geolocation)
          navigator.geolocation.getCurrentPosition(function(position){
            
            /**
             * Географическая широта геолокации пользователя программы
             * @property latitude
             * @for IPInfo
             * @type Number
             */
            $p.ipinfo.latitude = position.coords.latitude;

            /**
             * Географическая долгота геолокации пользователя программы
             * @property longitude
             * @for IPInfo
             * @type Number
             */
            $p.ipinfo.longitude = position.coords.longitude;

            var latlng = new google.maps.LatLng($p.ipinfo.latitude, $p.ipinfo.longitude);

            _ggeocoder.geocode({'latLng': latlng}, function(results, status) {
              if (status == google.maps.GeocoderStatus.OK){
                if(!results[1] || results[0].address_components.length >= results[1].address_components.length)
                  _parts = results[0];
                else
                  _parts = results[1];
                _addr = _parts.formatted_address;

                $p.eve.callEvent("geo_current_position", [$p.ipinfo.components({}, _parts.address_components)]);
              }
            });

          }, $p.record_log, {
            timeout: 30000
          }
        );
      }
    }
  });
  
}