如何编写 maptalks plugin

908 阅读3分钟

前面写过 maptalks plugin ( ArcGISTileLayer ),有读者留言说文章写得太精简,根据文章给出的核心代码没办法写出一个完整的 plugin ( 文中有完整 demo 地址,可能太隐蔽 ),这篇文章具体地说下 plugin 如何编写,并实现一个 plugin ( WMTSTileLayer )。

学习一个新东西,最好的方式就是找官方文档。这里介绍一种捷径( 个人认为 ),直接模仿已有的插件编写。打开官网 plugins 页面[1],找一个 plugin,如 maptalks.e3.js,下面参考 maptalks.e3.js 写一个 WMTSTileLayer

1、基本结构

以 maptalks.e3.js 为基本版本,通过对比其他插件,去掉具体业务代码,得到一个 WMTSTileLayer 的基本框架如下:

/*!
 * 版本申明
 * maptalks.wmts v0.1.0
 * LICENSE : MIT
 */
/*!
 * 依赖申明
 * requires maptalks@^0.39.0 
 */
// UMD 固定写法
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('maptalks')) :typeof define === 'function' && define.amd ? define(['exports', 'maptalks'], factory) :(factory((global.maptalks = global.maptalks || {}), global.maptalks));}(this, (function (exports, maptalks) {
  'use strict';
  
  // 定义layer
  var WMTSTileLayer = function (_TileLayer) {
    // 构造函数
    function WMTSTileLayer(id, options) {
      
    }
    // 图层导出为 JSON
    WMTSTileLayer.prototype.toJSON = function toJSON() {
      
    };
    // 图层导入 
    WMTSTileLayer.prototype.fromJSON = function fromJSON(layerJSON) {
      
    };
    return WMTSTileLayer;
  }(maptalks.TileLayer);

  // 注册图层
  WMTSTileLayer.registerJSONType('WMTSTileLayer');
  
  // 导出整个类,外界调用入口
  exports.WMTSTileLayer = WMTSTileLayer;

  Object.defineProperty(exports, '__esModule', { value: true });
    
  // 一些打印信息
  typeof console !== 'undefined' && console.log('maptalks.wmts v0.1.0, requires maptalks@^0.39.0.');
    
})));

2、WMTS 服务

网上搜索 WMTS 服务接口说明[2],得到参数说明如下:

参数名称 参数个数 参数类型和值
service 1个(必选) 字符类型,服务类型标识值为“WMTS”
request 1个(必选) 字符类型,请求的操作值为“GetTile”
version 1个(必选) 字符类型,值为请求的WMTS的版本号
layer 1个(必选) 字符类型,值为请求的图层名称
style 1个(必选) 字符类型,值为请求图层的渲染样式
format 1个(必选) 字符类型,值为瓦片地图的输出格式
tileMatrixSet 1个(必选) 字符类型,瓦片矩阵数据集,其值在服务的元数据文档中指定
tileMatrix 1个(必选) 字符类型,瓦片矩阵,其值在服务的元数据文档中指定
tileRow 1个(必选) 整型类型,值为大于0的整数,表示瓦片矩阵的行号
tileCol 1个(必选) 整型类型,值为大于0的整数,表示瓦片矩阵的列号
Other sample dimensions 0或1个(可选) 字符类型,其他允许的参数

拿到参数说明后,接下来就是具体代码实现。WMTS 服务是切片服务,相比 WMS 而言,牺牲定制地图的灵活性来提升性能,那么具体的代码实现可以参考官方的 WMTSTileLayer[3],具体实现代码如下:

/*!
 * 版本申明
 * maptalks.wmts v0.1.0
 * LICENSE : MIT
 */
/*!
 * 依赖申明
 * requires maptalks@^0.39.0 
 */
// UMD 固定写法
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('maptalks')) :typeof define === 'function' && define.amd ? define(['exports', 'maptalks'], factory) :(factory((global.maptalks = global.maptalks || {}), global.maptalks));}(this, (function (exports, maptalks) {
  'use strict';
  
 // 参数大小写配置
  var options$v2 = {
    uppercase: false
  };
  // 参数默认值
  var defaultWmtsParams = {
    service: 'WMTS',
    request: 'GetTile',
    layer: '',
    tilematrixset: '',
    format: 'image/png',
    version: '1.0.0'
  };
    
  // 定义layer
  var WMTSTileLayer = function (_TileLayer) {
     // 继承
     _inherits(WMTSTileLayer, _TileLayer);
    // 构造函数,mixins 参数
    function WMTSTileLayer(id, options) {
      var _this;
      _this = _TileLayer.call(this, id) || this;
      var wmtsParams = extend({}, defaultWmtsParams);
      for (var p in options) {
        if (!(p in _this.options)) {
          wmtsParams[p] = options[p];
        }
      }
      // 改写 url
      var url = options.urlTemplate;
      options.urlTemplate = url + getParamString(wmtsParams, url, this.options.uppercase) + '&tileMatrix={z}&tileRow={y}&tileCol={x}';
        
      _this.setOptions(options);
      _this.setZIndex(options.zIndex);
      return _this;
    }
    // 图层导出为 JSON
    WMTSTileLayer.prototype.toJSON = function toJSON() {
      return {
        'type': 'WMTSTileLayer',
        'id': this.getId(),
        'options': this.config()
      };
    };
    // 图层导入 
    WMTSTileLayer.prototype.fromJSON = function fromJSON(layerJSON) {
      if (!layerJSON || layerJSON['type'] !== 'WMTSTileLayer') {
        return null;
      }
      return new WMTSTileLayer(layerJSON['id'], layerJSON['options']);
    };
    return WMTSTileLayer;
  }(maptalks.TileLayer);

  // 注册图层
  WMTSTileLayer.registerJSONType('WMTSTileLayer');
  
  // 导出整个类,外界调用入口
  exports.WMTSTileLayer = WMTSTileLayer;

  Object.defineProperty(exports, '__esModule', { value: true });
    
  // 一些打印信息
  typeof console !== 'undefined' && console.log('maptalks.wmts v0.1.0, requires maptalks@^0.39.0.');
    
})));

3、试一试,加载天地图 WMTS 服务[4]

var map = new maptalks.Map('map', {
    center: [105.08052356963802, 36.04231948670001],
    zoom: 4,
    minZoom:1,
    maxZoom:18,
    spatialReference:{
        projection:'EPSG:4326'
    },
    baseLayer: new maptalks.WMTSTileLayer('base', {
        tileSystem : [1, -1, -180, 90],
        layer:'vec',
        tilematrixset:'c',
        format:'tiles',
        urlTemplate:'http://t{s}.tianditu.com/vec_c/wmts?tk=de0dc270a51aaca3dd4e64d4f8c81ff6',
        subdomains:['1', '2', '3', '4', '5'],
        attribution : '&copy; <a target="_blank" href="http://www.tianditu.cn">Tianditu</a>'
    }),
    layers : [
        new maptalks.WMTSTileLayer('road', {
            layer:'cva',
            tilematrixset:'c',
            format:'tiles',
            urlTemplate:'http://t{s}.tianditu.com/cva_c/wmts?tk=de0dc270a51aaca3dd4e64d4f8c81ff6',
            subdomains:['1', '2', '3', '4', '5'],
            opacity:1
        })
    ]
});
[1] http://maptalks.org/plugins.html
[2] http://tdt.fuzhou.gov.cn/help/apipfs/3.htm
[3] https://github.com/maptalks/maptalks.js/blob/master/src/layer/tile/WMSTileLayer.js
[4] http://maptalks.org/examples/en/tilelayer-projection/wms/#tilelayer-projection_wms