    /**
     * 通过TileMatrixSetId来获取EPSG号码
     * @param {String} tileMatrixSetId tileMatrixSetId
     * @return {String} EPSG号码
     * */
    import {
      RendererType,
      SymbolType,
      UrlServerType,
      WMTSCorporation
    } from '../../../base/enum'
    import { defaultValue } from '../../../util'
    import { Color } from '../../../base'

    function getEPSGFromTileMatrixSetId(tileMatrixSetId) {
      if (!tileMatrixSetId) return 'EPSG:4326'
      let epsg = tileMatrixSetId
      if (tileMatrixSetId.indexOf('EPSG:4326') > -1) {
        epsg = 'EPSG:4326'
      } else if (tileMatrixSetId.indexOf('EPSG:4490') > -1) {
        epsg = 'EPSG:4490'
      } else if (tileMatrixSetId.indexOf('EPSG:4610') > -1) {
        epsg = 'EPSG:4610'
      } else if (tileMatrixSetId.indexOf('EPSG:3857') > -1) {
        epsg = 'EPSG:3857'
      }
      return epsg
    }

    /**
     * 检查url对应的服务类型
     * @param {String} url 服务地址
     * @return {String} 服务类型
     * */
    function getUrlType(url) {
      let type = undefined

      // 天地图正则
      const tdtReg = new RegExp(
        '^http://t[0-6].tianditu.gov.cn/[a-z]{3}_[w|c]{1}/wmts$'
      )
      // igs2.0的http服务正则
      const igsHttp2 = new RegExp(
        '^http://[0-9.a-zA-Z]+:[0-9]{1,5}/igs/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // igs2.0的https服务正则
      const igsHttps2 = new RegExp(
        '^https://[0-9.a-zA-Z]+:[0-9]{1,5}/igs/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // igs2.0的http服务没有端口号的正则
      const igsHttpNoPort2 = new RegExp(
        '^http://[0-9.a-zA-Z]+/igs/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // igs2.0的https服务没有端口号的正则
      const igsHttpsNoPort2 = new RegExp(
        '^https://[0-9.a-zA-Z]+/igs/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // arcgis的http服务正则
      const arcgisHttp = new RegExp(
        '^http://[0-9.a-zA-Z]+:[0-9]{1,5}/arcgis/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // arcgis的https服务正则
      const arcgisHttps = new RegExp(
        '^https://[0-9.a-zA-Z]+:[0-9]{1,5}/arcgis/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // arcgis的http服务没有端口号的正则
      const arcgisHttpNoPort = new RegExp(
        '^http://[0-9.a-zA-Z]+/arcgis/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      // arcgis的https服务没有端口号的正则
      const arcgisHttpsNoPort = new RegExp(
        '^https://[0-9.a-zA-Z]+/arcgis/rest/services/[一-龟\\w/:_]+/WMTSServer$'
      )
      if (tdtReg.test(url)) {
        type = UrlServerType.tdt
      } else if (
        igsHttp2.test(url) ||
        igsHttps2.test(url) ||
        igsHttpNoPort2.test(url) ||
        igsHttpsNoPort2.test(url)
      ) {
        type = UrlServerType.igs_2
      } else if (
        arcgisHttp.test(url) ||
        arcgisHttps.test(url) ||
        arcgisHttpNoPort.test(url) ||
        arcgisHttpsNoPort.test(url)
      ) {
        type = UrlServerType.igs_2
      }

      return type
    }

    /**
     * 是否为4326坐标系
     * @param {SpatialReference} spatialReference 坐标系对象
     * @return {Boolean} 是否为4326坐标系
     * */
    function is4326(spatialReference) {
      if (
        String(spatialReference.wkid) === '4326' ||
        String(spatialReference.wkid) === '4214' ||
        String(spatialReference.wkid) === '4490' ||
        String(spatialReference.wkid) === '4610'
      ) {
        return true
      }
      return false
    }

    /**
     * 是否为自定义坐标系
     * @param {SpatialReference} spatialReference 坐标系对象
     * @return {Boolean} 是否为自定义坐标系
     * */
    function isCustomSP(spatialReference) {
      if (
        String(spatialReference.wkid) !== '4326' &&
        String(spatialReference.wkid) !== '4214' &&
        String(spatialReference.wkid) !== '4490' &&
        String(spatialReference.wkid) !== '4610' &&
        String(spatialReference.wkid) !== '3857' &&
        String(spatialReference.wkid) !== '900913'
      ) {
        return true
      }
      return false
    }

    /**
     * 根据比例尺显示或隐藏图层
     * @private
     * @param {BaseView} view 地图视图对象
     * @param {BaseLayer} layer 基础图层对象
     * */
    function showLayerByScale(view, layer) {
      let _scale = view.scale
      // 不在比例尺范围内，隐藏图层
      if (!view.scale) {
        _scale = view.getScale()
      }
      if (layer.maxScale && layer.minScale && layer.minScale < layer.maxScale) {
        if (_scale >= layer.minScale && _scale <= layer.maxScale) {
          layer.visible = true
        } else {
          layer.visible = false
        }
      } else if (layer.maxScale) {
        if (_scale > layer.maxScale) {
          layer.visible = false
        } else {
          layer.visible = true
        }
      } else if (layer.minScale) {
        if (_scale < layer.minScale) {
          layer.visible = false
        } else {
          layer.visible = true
        }
      }
    }

    /**
     * 将IGS的符号构造参数转为前端的符号构造参数
     * @private
     * @param {Object} symbol IGS的符号构造参数
     * @return {Object} symbol 前端的符号构造参数
     * */
    function formatIGSSymbol(symbol) {
      symbol = defaultValue(symbol, {})
      switch (symbol.type) {
        case SymbolType.simpleMarker:
        case SymbolType.simpleFill:
          if (symbol.color) {
            symbol.color = new Color(
              symbol.color[0],
              symbol.color[1],
              symbol.color[2],
              symbol.color[3] / 255
            )
          }
          if (symbol.outline && symbol.outline.color) {
            symbol.outline.color = new Color(
              symbol.outline.color[0],
              symbol.outline.color[1],
              symbol.outline.color[2],
              symbol.outline.color[3] / 255
            )
          }
          break
        case SymbolType.simpleLine:
          if (symbol.color) {
            symbol.color = new Color(
              symbol.color[0],
              symbol.color[1],
              symbol.color[2],
              symbol.color[3] / 255
            )
          }
          break
        case SymbolType.pictureMarker:
          if (symbol.color) {
            symbol.color = new Color(
              symbol.color[0],
              symbol.color[1],
              symbol.color[2],
              symbol.color[3] / 255
            )
          }
          if (!symbol.url) {
            symbol.url = symbol.imageData
          }
          break
        case SymbolType.pictureFill:
          if (symbol.outline && symbol.outline.color) {
            symbol.outline.color = new Color(
              symbol.outline.color[0],
              symbol.outline.color[1],
              symbol.outline.color[2],
              symbol.outline.color[3] / 255
            )
          }
          if (!symbol.url) {
            symbol.url = symbol.imageData
          }
          break
        case SymbolType.text:
          if (symbol.color) {
            symbol.color = new Color(
              symbol.color[0],
              symbol.color[1],
              symbol.color[2],
              symbol.color[3] / 255
            )
          }
          if (symbol.backgroundColor) {
            symbol.backgroundColor = new Color(
              symbol.backgroundColor[0],
              symbol.backgroundColor[1],
              symbol.backgroundColor[2],
              symbol.backgroundColor[3] / 255
            )
          }
          if (symbol.borderLineColor) {
            symbol.borderLineColor = new Color(
              symbol.borderLineColor[0],
              symbol.borderLineColor[1],
              symbol.borderLineColor[2],
              symbol.borderLineColor[3] / 255
            )
          }
          if (symbol.haloColor) {
            symbol.haloColor = new Color(
              symbol.haloColor[0],
              symbol.haloColor[1],
              symbol.haloColor[2],
              symbol.haloColor[3] / 255
            )
          }
          break
        default:
          break
      }
      return symbol
    }

    /**
     * 将IGS的渲染器构造参数转为前端的渲染器构造参数
     * @private
     * @param {Object} renderer IGS的渲染器构造参数
     * @return {Object} renderer 前端的渲染器构造参数
     * */
    function formatIGSRenderer(renderer) {
      renderer = defaultValue(renderer, {})
      switch (renderer.type) {
        case RendererType.simple:
          renderer.symbol = formatIGSSymbol(renderer.symbol)
          break
        case RendererType.uniqueValue:
          renderer.defaultSymbol = formatIGSSymbol(renderer.defaultSymbol)
          for (let i = 0; i < renderer.uniqueValueInfos.length; i++) {
            renderer.uniqueValueInfos[i].symbol = formatIGSSymbol(
              renderer.uniqueValueInfos[i].symbol
            )
          }
          break
        case RendererType.classBreak:
          renderer.defaultSymbol = formatIGSSymbol(renderer.defaultSymbol)
          for (let i = 0; i < renderer.classBreakInfos.length; i++) {
            renderer.classBreakInfos[i].symbol = formatIGSSymbol(
              renderer.classBreakInfos[i].symbol
            )
          }
          if (renderer.classBreakInfos.length > 0) {
            renderer.classBreakInfos[0].minValue = renderer.minValue
            renderer.classBreakInfos[0].maxValue =
              renderer.classBreakInfos[0].classMaxValue
            for (let i = 1; i < renderer.classBreakInfos.length; i++) {
              renderer.classBreakInfos[i].minValue =
                renderer.classBreakInfos[i - 1].classMaxValue
              renderer.classBreakInfos[i].maxValue =
                renderer.classBreakInfos[i].classMaxValue
            }
          }
          break
        default:
          break
      }
      return renderer
    }

    /**
     * 从ogc的ows:SupportedCRS标签上解析出epsg号
     * @private
     * @param {string} supportedCRS
     * @return {Number} EPSG编号
     */
    function getEPSGCodeFromOGCSupportedCRSString(supportedCRS) {
      let epsgCode = 4326
      let pos = -1
      // 1.查找字符串中是否含有EPSG::,如果有则EPSG::后面的即为epsg号。
      pos = supportedCRS.search('EPSG::')
      if (pos > -1) {
        epsgCode = parseInt(supportedCRS.substring(pos + 'EPSG::'.length))
      } else {
        // 2.查找字符串中是否同时含有EPSG:和3857,如果有则表明,对应的epsg号为3857
        pos = supportedCRS.search('EPSG:')
        if (pos > -1 && supportedCRS.search('3857') > 0) {
          epsgCode = 3857
        } else {
          // 3.查找字符串中是否含有"OGC:2:84"或"OGC:1.3:CRS84"，如果有则epsg号为3857
          pos = supportedCRS.search('OGC:2:84')
          if (pos < 0) {
            pos = supportedCRS.search('OGC:1.3:CRS84')
          }

          if (pos > -1) {
            epsgCode = 4326
          }
        }
      }

      // 4.将web墨卡托的epsg号统一为3857.
      if (epsgCode === 3867 || epsgCode === 900913 || epsgCode === 102100) {
        epsgCode = 3857
      }

      return epsgCode
    }

    /**
     * @summary
     *    该函数支持MapGIS IGServer 发布的JWD,MKT瓦片只有一个矩阵集(老版本,地调局原来有用),
     支持MapGIS IGServer 发布的JWD 三个矩阵集,MKT 的两个矩阵集(新版本,该版本MapGIS发布的WMTS可以再Arcmap 和ArcGIS Server发布的WMTS完美叠加,ArcGIS Online中和地图完美叠加)
     支持ArcGIS Server   发布的JWD,MKT瓦片
     支持天地图(全国)    JWD，MKT两种
     支持GeoServer       JWD,MKT两种
     各个厂家以及MapGIS IGServer发布的老版本和新版本之间关于1逻辑单位代表多少毫米的理解如下:
     服务名              坐标系          矩阵集个数/名称           1逻辑单位代表多少毫米      1像素等于多少毫米
     IGServer老服务      JWD             一个矩阵集                111194872.221777			    25.4/96
     IGServer老服务      MKT             一个矩阵集                1000						          25.4/96
     IGServer新服务      JWD      3个(EPSG:4326_XXXX_028mm_GB)     111319490.79327358        0.28
     IGServer新服务      JWD      3个(EPSG:4326_XXXX_arcgis_GB)    111194872.221777			    0.28
     IGServer新服务      JWD      3个(EPSG:4326_XXXX_dpi96_GB)     111319490.79327358		    25.4/96
     IGServer新服务      MKT      2个(GoogleMapsCompatible_GB)     1000						          0.28
     IGServer新服务      MKT      2个(EPSG:3857_XXXX_dpi96_GB)     1000						          25.4/96

     ArcGIS Server       JWD      2个(default028mm)				        111194872.221777			  25.4000508/96(0.28的比例尺反算96DPI的比例尺后,用96DPI的计算,这种情况下1英寸等于25.4000508毫米)
     ArcGIS Server       JWD      2个(native)					            111194872.221777			  25.4000508/96
     ArcGIS Server       MKT      3个(default028mm)				        1000						        25.4000508/96(0.28的比例尺反算96DPI的比例尺后,用96DPI的计算,这种情况下1英寸等于25.4000508毫米)
     ArcGIS Server       MKT      3个(native)					            1000						        25.4000508/96
     ArcGIS Server       MKT      3个(GoogleMapsCompatible)		    1000						        0.28

     GeoServer           JWD             一个矩阵集                111319490.79327358 		  0.28
     GeoServer			      MKT             一个矩阵集                1000						        0.28

     tianditu            JWD             一个矩阵集                111319490.79327358 		  25.4/96
     tianditu			      MKT             一个矩阵集                1000						        25.4/96
     *
     */
    function getTileResolution(
      identifier,
      corporationType,
      dScale,
      spatialReference
    ) {
      const ARCGIS_METERPERUNIT = 111194872.221777
      const MAPGIS_OLD_METERPERUNIT = ARCGIS_METERPERUNIT
      const GEOSERVER_METERPERUNIT = 111319490.79327358
      const MAPGIS_METERPERUNIT = GEOSERVER_METERPERUNIT
      const OTHER_METERPERUNIT = GEOSERVER_METERPERUNIT
      let szTmp = ''
      const szWellKnownScaleSetName = ''
      let nPos = -1
      let nMapGISType = 0 // 0是国标标准的0.28,1是Arcgis0.28,2是96dpi,3是GoogleMapsCompatible(OGC MKT 0.28)
      let nArcGISTyep = 0 // 0是default0.28,1是nativeTileMatrixSet,2是GoogleMapsCompatible(OGC MKT 0.28),3其它
      let nOtherType = 0 // 0是国标的96DPI(严格的标准),1可能是用ArcGIS发布的但是基地址又不能判断出是ArcGIS的情况(吉威广西: http://121.40.62.120:8066/ime-server/rest/gxyx/wmts?service=wmts&request=GetCapabilities)
      let dMMPerPix = 25.4 / 96 // 一个像素等于多少毫米
      let dScaleEx = 0
      let dConst = 1000

      // 不支持获取WellKnownScaleSet名称。
      // szWellKnownScaleSetName = pMatrixSet->matriSet.szWellKnownScaleSetName;

      if (corporationType === WMTSCorporation.corporationZD) {
        // 新版本2016-1-27之后 MapGIS IGServer发布的JWD有三个矩阵集: 如下
        // EPSG:4326_武汉1~12级_028mm_GB
        // EPSG:4326_武汉1~12级_arcgis_GB
        // EPSG:4326_武汉1~12级_dpi96_GB
        // MKT数据有2个矩阵集
        // GoogleMapsCompatible_GB
        // EPSG:3857_WH_MKT_1~16级_dpi96_GB

        nPos = identifier.lastIndexOf('_GB')

        if (nPos > 0) {
          szTmp = identifier.slice(0, identifier.length - 3)
          nPos = szTmp.lastIndexOf('_')
          if (nPos > 0) {
            // 028mm_GB,arcgis_GB,dpi96_GB三种
            szTmp = szTmp.slice(nPos + 1)
          }

          if (szTmp === '028mm') nMapGISType = 0
          else if (szTmp === 'arcgis') nMapGISType = 1
          else if (szTmp === 'dpi96') nMapGISType = 2
          else if (szTmp === 'GoogleMapsCompatible') nMapGISType = 3

          if (spatialReference.isGeographic) {
            if (nMapGISType === 0) {
              // 标准的国标
              dConst = MAPGIS_METERPERUNIT
              dMMPerPix = 0.28
            } else if (nMapGISType === 1) {
              // ArcGIS的0.28
              dMMPerPix = 0.28
              dConst = ARCGIS_METERPERUNIT
            } else if (nMapGISType === 2) {
              dConst = MAPGIS_METERPERUNIT
              dMMPerPix = 25.4 / 96
            }
          } else {
            if (nMapGISType === 0) {
              // 标准的国标
              dMMPerPix = 0.28
            } else if (nMapGISType === 1) {
              // ArcGIS的0.28
              dMMPerPix = 0.28
            } else if (nMapGISType === 2) {
              dMMPerPix = 25.4 / 96
            } else if (nMapGISType === 3) {
              dMMPerPix = 0.28
            }
          }
        } // 老版本
        else {
          if (spatialReference.isGeographic) {
            dConst = MAPGIS_OLD_METERPERUNIT
            dMMPerPix = 25.4 / 96
          } else {
            dMMPerPix = 25.4 / 96
          }
        }
      } else if (
        corporationType === WMTSCorporation.corporationArcGIS
      ) {
        // http://portal.smartxspace.com/arcgis/rest/services/wuhan_base/MapServer/WMTS/1.0.0/WMTSCapabilities.xml
        // 修改说明：ArcGIS的部分WMTS服务的dpi为0.28，但其矩阵集名称为default，原有写法会造成该类服务无法显示。
        // 修改人：马原野 2018-12-26
        if (identifier.includes('default')) nArcGISTyep = 0
        else if (identifier.includes('native')) nArcGISTyep = 1
        else if (identifier.includes('GoogleMapsCompatible')) nArcGISTyep = 2
        else nArcGISTyep = 3
        if (spatialReference.isGeographic) {
          if (nArcGISTyep === 0) {
            dScaleEx = (dScale * 0.28 * 96) / 25.4 // 反算96DPI对应的比例尺,直接用0.28对应的比例尺不准确
            dScale = dScaleEx
            dConst = ARCGIS_METERPERUNIT
            dMMPerPix = 25.4000508 / 96
          } else if (nArcGISTyep === 1) {
            dConst = ARCGIS_METERPERUNIT
            dMMPerPix = 25.4000508 / 96
          }
        } else {
          if (nArcGISTyep === 0) {
            dScaleEx = (dScale * 0.28 * 96) / 25.4 // 反算96DPI对应的比例尺,直接用0.28对应的比例尺不准确
            dScale = dScaleEx
            dMMPerPix = 25.4000508 / 96
          } else if (nArcGISTyep === 1) {
            dMMPerPix = 25.4000508 / 96
          } else if (nArcGISTyep === 2) {
            dMMPerPix = 0.28
          }
        }
      } else if (
        corporationType === WMTSCorporation.corporationGeoServer
      ) {
        if (spatialReference.isGeographic) {
          dConst = GEOSERVER_METERPERUNIT
          dMMPerPix = 0.28
        } else {
          dMMPerPix = 0.28
        }
      } else if (corporationType === WMTSCorporation.corporationTianDiTu) {
        if (spatialReference.isGeographic) {
          dConst = OTHER_METERPERUNIT
          dMMPerPix = 25.4 / 96
        } else {
          dMMPerPix = 25.4 / 96
        }
      }
      // 修改说明：修订bug7584 对吉威发布的类似于ArcGIS规则的WMTS的支持.本质需要按照ArcGIS方式计算
      //           其它厂商发布的WMTS认为都是严格按照国家标准执行(都只处理一个矩阵级,且认为是96DPI,一度等于多少米为111319490.79327358)
      // 修改人： 潘明敏 2016-04-14
      else {
        // 对于其它厂家发布的WMTS原则上认为是严格执行国家标准(关键参数同天地图)
        // 但是对于吉威发布的WMTS特殊处理下,吉威发布的WMTS有两套标准
        // 1.http:// 121.40.62.120:8066/ime-server/rest/gxyx/wmts?service=wmts&request=GetCapabilities  其实内部比例尺是符合ArcGIS的标准发布,包含了default028mm矩阵集,计算时需要用ArcGIS的计算方法才能对
        // 2.http://www.mapgx.com/ime-server/rest/tdtgx_vec/wmts/wmts?service=wmts&request=getcapabilities 符合国家标准执行，使用国家标准的参数计算即可
        if (identifier.includes('028')) nOtherType = 1

        // 修改说明：某些服务szWellKnownScaleSetName中含有"GoogleMapsCompatible"关键词，计算时需要用ArcGIS的计算方法。
        // 如：中国地质调查局西安地质调查中心发布的服务，url:http://219.144.130.58:6400/getcapabilities?Theme=HillShade  bug[12561]
        // 修改人：马原野 2019-07-20
        if (szWellKnownScaleSetName.includes('GoogleMapsCompatible')) {
          nOtherType = 1
        }

        // 修改说明：szWellKnownScaleSetName中含有"GoogleMapsCompatible"关键词，计算时也需要用ArcGIS的计算方法。
        // 修改恩：王必聪 2019-07-26
        if (szWellKnownScaleSetName.includes('GoogleCRS84Quad')) nOtherType = 1

        if (spatialReference.isGeographic) {
          if (nOtherType === 1) {
            dScaleEx = (dScale * 0.28 * 96) / 25.4 // 反算96DPI对应的比例尺,直接用0.28对应的比例尺不准确
            dScale = dScaleEx
            dConst = ARCGIS_METERPERUNIT
            dMMPerPix = 25.4000508 / 96
          } else {
            dConst = OTHER_METERPERUNIT
            dMMPerPix = 25.4 / 96
          }
        } else {
          if (nOtherType === 1) {
            dScaleEx = (dScale * 0.28 * 96) / 25.4 // 反算96DPI对应的比例尺,直接用0.28对应的比例尺不准确
            dScale = dScaleEx
            dMMPerPix = 25.4000508 / 96
          } else dMMPerPix = 25.4 / 96
        }
      }
      return (dScale * dMMPerPix) / dConst
    }

    /**
     * 根据url获取发布服务的公司
     * @param {String} url 服务基地址
     * @return {WMTSCorporation} 公司代码
     * */
    function initCorporationType(url) {
      if (url === undefined) {
        return WMTSCorporation.none
      }

      // 对于MapGIS发布的WMTS,基地址有两种写法,故只用WMTSServer来判断
      // http://192.168.10.44:6163/igs/rest/ogc/WMTSServer(IGserver发布的)
      // http://219.142.81.86/igserver/ogc/kvp/TAS10E52H50E002021/WMTSServer (中国地调局国家地质资料馆里面有用)
      // 修改说明：<天地图服务升级，服务域名变化>
      // 修改人：ldf 2018-12-26
      if (url.search('WMTSServer') > 0) {
        return WMTSCorporation.corporationZD
      } else if (url.search('arcgis/rest/services') > 0) {
        return WMTSCorporation.corporationArcGIS
      } else if (url.search('geoserver') > 0) {
        return WMTSCorporation.corporationGeoServer
      } else if (
        url.search('tianditu.com') > 0 ||
        url.search('tianditu.gov.cn') > 0
      ) {
        return WMTSCorporation.corporationTianDiTu
      } else {
        return WMTSCorporation.corporationOther
      }
    }

    export {
      getEPSGFromTileMatrixSetId,
      getUrlType,
      is4326,
      isCustomSP,
      showLayerByScale,
      formatIGSSymbol,
      formatIGSRenderer,
      getEPSGCodeFromOGCSupportedCRSString,
      initCorporationType,
      getTileResolution
    }