'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.fetchWMTSLayerStyles = exports.getWMTSCapabilities = exports.defaultServicesOptions = undefined;

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _extends2 = require('babel-runtime/helpers/extends');

var _extends3 = _interopRequireDefault(_extends2);

var _assign = require('lodash/assign');

var _assign2 = _interopRequireDefault(_assign);

var _methodsUtil = require('../../../_util/methods-util');

var _index = require('./index');

var _topTileExtent = require('../../util/topTileExtent');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

/**
 * @文件说明: Services.WMTS - WMTS服务
 * @创建人: pjtools@vip.qq.com
 * @创建时间: 2020-03-25 16:58:54
 */

var defaultServicesOptions = exports.defaultServicesOptions = {
  // 版本号
  version: null,
  // 图层名标识
  layerName: null,
  // 图层矩阵集名
  layerMatrixSet: null,
  // 图层样式名
  styleName: null,
  // 图片格式，可选值：[ image/tile | image/png | image/jpeg ]
  format: null,
  // 顶级金字塔内部计算方式
  units: null
};

/**
 * 解析标准WMTS类型服务Capabilities信息
 */
var getWMTSCapabilities = exports.getWMTSCapabilities = function getWMTSCapabilities(capabilities, options, GeoGlobe) {
  try {
    var opts = {};
    // 图层标识
    var defaultLayer = capabilities.contents.layers && capabilities.contents.layers[0];
    var defaultLayerName = defaultLayer.identifier;
    opts.layerName = !(0, _methodsUtil.isEmpty)(options.layerName) ? options.layerName : defaultLayerName;
    // 图片格式
    opts.formats = defaultLayer.formats;
    opts.format = !(0, _methodsUtil.isEmpty)(options.format) && opts.formats.indexOf(options.format) !== -1 ? options.format : 'image/png';
    // 矩阵集名称
    var matrixSet = capabilities.contents.tileMatrixSets;
    var defaultMatrixSet = matrixSet[defaultLayer.tileMatrixSetLinks[0].tileMatrixSet];
    opts.matrixSet = !(0, _methodsUtil.isEmpty)(options.layerMatrixSet) ? options.layerMatrixSet : defaultMatrixSet.identifier;
    // 图层样式名称
    var defaultStyleName = defaultLayer.styles[0].identifier;
    opts.styleName = !(0, _methodsUtil.isEmpty)(options.styleName) ? options.styleName : defaultStyleName;
    // 版本号
    var version = capabilities.serviceIdentification.serviceTypeVersion;
    opts.version = !(0, _methodsUtil.isEmpty)(options.version) && options.version === '1.0.0' ? options.version : version;
    // 瓦片层级信息
    var tileMatrix = defaultMatrixSet.matrixIds;
    var zoom = [];
    var tileMatrixs = [];
    tileMatrix.forEach(function (item) {
      var currentZoom = parseInt(item.identifier, 10);
      zoom.push(currentZoom);
      tileMatrixs.push({
        identifier: currentZoom,
        scale: Number(item.scaleDenominator),
        tileWidth: Number(item.tileWidth),
        tileHeight: Number(item.tileHeight),
        matrixWidth: Number(item.matrixWidth),
        matrixHeight: Number(item.matrixHeight)
      });
    });
    opts.tileSize = tileMatrixs[0].tileWidth || 256;
    opts.tileMatrixs = tileMatrixs;
    opts.zoom = zoom;
    // CRS
    opts.crs = defaultMatrixSet.supportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3');
    // 金字塔顶级范围
    var topLeftCorner = tileMatrix[0].topLeftCorner.lng < 0 ? [tileMatrix[0].topLeftCorner.lng, tileMatrix[0].topLeftCorner.lat] : [tileMatrix[0].topLeftCorner.lat, tileMatrix[0].topLeftCorner.lng];
    var result = (0, _topTileExtent.topTileExtentToWMTS)(GeoGlobe, {
      identifier: Number(tileMatrix[0].identifier),
      scaleDenominator: tileMatrix[0].scaleDenominator,
      topLeftCorner: topLeftCorner,
      tileSize: opts.tileSize,
      matrixWidth: tileMatrix[0].matrixWidth,
      matrixHeight: tileMatrix[0].matrixHeight,
      units: !(0, _methodsUtil.isEmpty)(options.units) && ['degrees', 'm'].indexOf(options.units) !== -1 ? options.units : 'm'
    });
    opts.topTileExtent = result.topTileExtent;
    opts.zoomOffset = result.zoomOffset;
    opts.zoom = opts.zoom.map(function (zoom) {
      return zoom + opts.zoomOffset;
    });
    opts.minZoom = opts.zoom[0];
    opts.maxZoom = opts.zoom[opts.zoom.length - 1];
    return opts;
  } catch (e) {
    return null;
  }
};

/**
 * 解析WMTS类型的服务地址获取图层服务数据信息
 */
var fetchWMTSCapabilities = function fetchWMTSCapabilities(own, url, options) {
  var GeoGlobe = own.exports.GeoGlobe;

  var isProxyUrl = (0, _methodsUtil.isBooleanFlase)(options.proxy) ? false : true;

  return new Promise(function (resolve, reject) {
    var capabilitiesUrl = '' + url + (url.indexOf('?') === -1 ? '?' : '&') + 'SERVICE=WMTS&REQUEST=GetCapabilities';
    isProxyUrl && (capabilitiesUrl = '' + own.proxyURL + capabilitiesUrl);

    // 请求图层数据信息
    var errorMsg = 'WMTS\u670D\u52A1\u5730\u5740[ ' + url + ' ]\u6570\u636E\u89E3\u6790\u5931\u8D25.';
    GeoGlobe.Request.GET({
      url: capabilitiesUrl,
      success: function success(data) {
        var opts = {};
        try {
          // 获取WMTS服务的Capabilities信息
          var capabilities = !data.responseXML || !data.responseXML.documentElement ? data.responseText : data.responseXML;
          capabilities = new GeoGlobe.Format.WMTSCapabilities.v1_0_0().read(capabilities);
          var wmtsOpts = getWMTSCapabilities(capabilities, options, GeoGlobe);
          if (wmtsOpts) {
            opts = (0, _assign2['default'])({}, opts, wmtsOpts);
            var defaultLayer = capabilities.contents.layers && capabilities.contents.layers[0];
            // 矩形范围
            var bounding = defaultLayer.bounds;
            var defaultBounds = [[Number(bounding._sw.lng), Number(bounding._sw.lat)], [Number(bounding._ne.lng), Number(bounding._ne.lat)]];
            opts.tileBBox = defaultBounds;
          } else {
            console.error(errorMsg);
            reject();
          }
        } catch (e) {
          console.error(errorMsg);
          reject();
        }
        resolve(opts);
      },
      failure: function failure() {
        console.error(errorMsg);
        reject();
      }
    });
  });
};

/**
 * 解析WMTS类型的服务地址获取图层样式信息
 */
var fetchWMTSLayerStyles = exports.fetchWMTSLayerStyles = function fetchWMTSLayerStyles(own, id, url, layerOptions, options) {
  var isProxyUrl = (0, _methodsUtil.isBooleanFlase)(options.proxy) ? false : true;
  // 构建数据源
  var source = (0, _index.getServicesLayerSource)(options);
  // 拼接数据源的WMTS服务地址
  var params = {};
  params.SERVICE = 'WMTS';
  params.REQUEST = 'GetTile';
  params.VERSION = layerOptions.version;
  params.LAYER = layerOptions.layerName;
  params.STYLE = layerOptions.styleName;
  params.TILEMATRIXSET = layerOptions.matrixSet;
  params.FORMAT = layerOptions.format;
  params.TILEMATRIX = '{z}';
  params.TILEROW = '{y}';
  params.TILECOL = '{x}';
  var wmtsUrl = '';
  Object.keys(params).map(function (key, idx) {
    if (idx !== 0) {
      wmtsUrl += '&';
    }
    wmtsUrl += encodeURIComponent(key) + '=' + params[key];
  });
  wmtsUrl = '' + url + (url.indexOf('?') === -1 ? '?' : '&') + wmtsUrl;
  isProxyUrl && (wmtsUrl = '' + own.proxyURL + wmtsUrl);
  // 设定服务源
  source.tileSize = options.tileSize || layerOptions.tileSize || source.defaultTileSize;
  source.tiles = [wmtsUrl];
  source.zoomOffset = !(0, _methodsUtil.isEmpty)(options.zoomOffset) ? options.zoomOffset : !(0, _methodsUtil.isEmpty)(layerOptions.zoomOffset) ? layerOptions.zoomOffset : 0;
  // 构建图层
  var layer = (0, _index.getServicesBaseLayer)(options);
  layer.id = id;
  layer.source = source;
  layer.minzoom = (0, _methodsUtil.isEmpty)(layer.minzoom) || layer.minzoom < layerOptions.minZoom ? layerOptions.minZoom : layer.minzoom;
  layer.maxzoom = (0, _methodsUtil.isEmpty)(layer.maxzoom) || layer.maxzoom > layerOptions.maxZoom + 1 ? layerOptions.maxZoom + 1 : layer.maxzoom;
  layer.metadata = (0, _assign2['default'])({}, layer.metadata, (0, _extends3['default'])({
    serviceType: 'WMTS',
    serviceName: options.name || '',
    zoomOffset: source.zoomOffset || 0
  }, layerOptions));
  return layer;
};

var WMTS = function () {
  function WMTS(iMapApi) {
    (0, _classCallCheck3['default'])(this, WMTS);

    this.iMapApi = iMapApi;
    this.exports = iMapApi && iMapApi.exports ? iMapApi.exports : {};
    this.proxyURL = iMapApi.proxyURL || '';
    this.options = (0, _extends3['default'])({}, _index.defaultServicesSourceOptions, _index.defaultServicesLayerOptions, defaultServicesOptions);
  }

  /**
   * 获取解析WMTS服务的图层对象
   * @param {String} id 图层Id名称
   * @param {String} name 图层Name名
   * @param {String} url 服务地址
   * @param {Object} options 解析服务的参数选项
   */


  (0, _createClass3['default'])(WMTS, [{
    key: 'getLayer',
    value: function () {
      var _ref = (0, _asyncToGenerator3['default'])( /*#__PURE__*/_regenerator2['default'].mark(function _callee(id) {
        var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
        var url = arguments[2];
        var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
        var opts, layerOptions;
        return _regenerator2['default'].wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                opts = (0, _assign2['default'])(this.options, options);
                // 获取服务信息

                _context.next = 3;
                return fetchWMTSCapabilities(this, url, opts);

              case 3:
                layerOptions = _context.sent;
                return _context.abrupt('return', fetchWMTSLayerStyles(this, id, url, layerOptions, (0, _extends3['default'])({}, opts, { name: name })));

              case 5:
              case 'end':
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      function getLayer(_x3) {
        return _ref.apply(this, arguments);
      }

      return getLayer;
    }()
  }]);
  return WMTS;
}();

exports['default'] = WMTS;