前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >maptalks 开发手册-入门篇

maptalks 开发手册-入门篇

作者头像
用针戳左手中指指头
发布2022-05-11 13:52:24
3.3K0
发布2022-05-11 13:52:24
举报
文章被收录于专栏:学习计划

为何使用maptalks

做过地图的小伙伴们都知道,每个地图框架产商都与自家的地图资源进行绑定,如非常受欢迎的mapBox、高德、百度、腾讯等,你必须注册他们产品,获取key,然后调用的api,才能进行地图的相关操作,虽然带来了便利, 但同时这也存在这限制。

那么有人可能要问,那这么方便,就用他们的,就不用自己开发了不是,为什么还用其他的呢?

这个问题很好,做产品,最好的做法就是由开发自己掌控,能做什么,能做到什么程度,一切都由开发把握,这才是一个完好的自主产品。说到自主,作为中国人也是有亲身体会的,作物基因专利、光刻机、软件等等,由外国掌控核心技术,作为使用者的我们只能认栽吃瘪,maptalks是我们国人开源的一个地图框架,可以自定义我们的地图资源,不用第三方支持,而且也集成了很多插件,想three、echarts、热力图,支持我们的开发需求。这不是宣传,我就我个人的一些观点。​

API

https://maptalks.org/maptalks.js/api/0.x/Map.html

初始化

首先需要安装maptalks

npm install maptalks

和其他框架的差不多,了解就行; 哦,还有一个点,出现跨域的问题,需要设置crossOrigin: undefined

代码语言:javascript
复制
<template>
  <div id="map" class="container"></div>
</template>

<script>
// 引入样式和组件
import 'maptalks/dist/maptalks.css';
import * as maptalks from 'maptalks';

export default {
  data() {
    return {
      // 地图引擎
      mapEngine: null,
      // 倾斜度
      pitch: 50,
      // toolbar
      // 旋转
      whirl: null,
      // 放大/缩小
      zoom: 14,
      // 轴承
      bearing: 0,
      // 屏幕坐标
      containerPoint: {x: null, y: null},
      // 地图坐标
      coordinatePoint: {x: null, y: null}
    }
  },
  mounted() {
    const _t = this
    this.$nextTick(() => {
      const map = new maptalks.Map('map', {
        // 默认中心点点位
        center: [118.13245430046891, 24.495713873147764],
        // 缩放层级
        zoom: _t.zoom,
        // 倾斜度
        pitch: _t.pitch,
        // 最小缩放层级
        minZoom: 1,
        // 最大缩放层级
        maxZoom: 18,
        // baseLayer 表示基础图层,它可以添加多个,逗号隔开
        baseLayer: new maptalks.TileLayer('base', {
          // 出现跨域问题,要设置这个,一定是undefined
          crossOrigin: undefined,
          // 电子地图图层
          urlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
          subdomains: ['a', 'b', 'c', 'd'],
          attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
        })
      });
    });

  }
}
</script>

<style lang="scss">
.container {
  width: 100%;
  height: 100%
}
</style>

Symbol 属性

这个属性是用来设置样式的,是它的一个规则,之后我们的用的功能都与这个有关系,所以这里提前的了解,下面是它的文档说明:

https://github.com/maptalks/maptalks.js/wiki/Symbol-Reference

创建图层

创建图层的方式有两种:

  1. 在创建地图实例的同时创建图层: 2个参数,必填参数为第一个(id),第二个参数是options,是它的图层属性设置,一般默认就行,后面也可以通过图层对象进行设置。
代码语言:javascript
复制
 const map = new maptalks.Map('map', {
        // 默认中心点点位
        center: [118.13245430046891, 24.495713873147764],
        // 缩放层级
        zoom: _t.zoom,
        // 倾斜度
        pitch: _t.pitch,
        // 最小缩放层级
        minZoom: 1,
        // 最大缩放层级
        maxZoom: 18,
        // baseLayer 表示基础图层,它可以添加多个,逗号隔开
        baseLayer: new maptalks.TileLayer('base', {
          // 电子地图图层
          urlTemplate: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
          subdomains: ['a', 'b', 'c', 'd'],
          attribution: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/">CARTO</a>'
        }),
        layers: [
          // 创建矢量图层 v
          // new maptalks.VectorLayer('v', 几何图形列表(geometries), 可选参数配置(options))
          new maptalks.VectorLayer('v')
        ]
      });
  1. 创建图层实例,然后添加到map实例中 注意:这里用了一个方法addTo(map)这个方法对所有组件通用,意思就是,下面我们介绍的工具、组件等添加到地图上,都是用这个方法。
代码语言:javascript
复制
new maptalks.VectorLayer('v').addTo(map)

放大缩小等工具

在地图初始化时,我们也可以添加一些我们的工具:

它提供了new maptalks.control.Toolbar让我们去实例一个工具栏,格式:

代码语言:javascript
复制
// 工具栏实例化
      new maptalks.control.Toolbar({
        items: [
          {
              // 显示名称
            item: '放大',
              // 点击时间
            click: () => {
              map.setZoom(_t.zoom += 1)
            }
          }
        ]
      }).addTo(map);

这里我简单了列了items里的属性,它其实共有4个属性:position、vertical、reverseMenu、items,详细可以去看:Maptalks/docs/api/0.x/control.Toolbar.html,也可以从源码角度去看,在源码里它是有默认配置的,比如下面这个:

代码语言:javascript
复制
var options$s = {
  'height': 28,
  'vertical': false,
  'position': 'top-right',
  'reverseMenu': false,
  'items': {}
};

缩放工具它有提供现成的组件:

代码语言:javascript
复制
  /**
     * 增加缩放工具
     * @param map
     */
    addZoomTool(map) {
      new maptalks.control.Zoom({
        // 工具位置
        position: 'top-left',
        // 是否是以线段条方式展示
        slider: false,
        // 是否显示缩放级别文本框
        zoomLevel: true
      }).addTo(map);
    },

我们也可以自定义创建:

代码语言:javascript
复制
 new maptalks.control.Toolbar({
        items: [
          {
            item: '放大',
            click: () => {
              map.setZoom(_t.zoom += 1)
            }
          },
          {
            item: '缩小',
            click: () => {
              map.setZoom(_t.zoom -= 1)
            }
          },
          {
            item: '旋转',
            click: () => {
              map.setBearing(_t.bearing -= 50)
            }
          },
          {
            item: '重置',
            click: () => {
              _t.mapDataReset(map)
            }
          },
          {
            item: '锁定',
            click: (t) => {
              if (t.target.item === '锁定') {
                map.setOptions({
                  // 可拖动
                  draggable: false,
                  // 平移
                  dragPan: false,
                  // 旋转
                  dragRotate: false,
                  // 间距
                  dragPitch: false,
                  // 滚动缩放
                  scrollWheelZoom: false,
                  // 点击 缩放
                  touchZoom: false,
                  // 双击缩放
                  doubleClickZoom: false
                })
                t.target.item = '取消锁定'
              } else {
                map.setOptions({
                  // 可拖动
                  draggable: true,
                  // 平移
                  dragPan: true,
                  // 旋转
                  dragRotate: true,
                  // 间距
                  dragPitch: true,
                  // 滚动缩放
                  scrollWheelZoom: true,
                  // 点击 缩放
                  touchZoom: true,
                  // 双击缩放
                  doubleClickZoom: true
                })
                t.target.item = '锁定'
              }
            }
          }
        ]
      }).addTo(map);

效果如下:

绘制区域面(几何图形)

首先我们要知道它有2个概念:Geometry  Polygon,polygon继承Geometry,两个可以看做一个东西;

并且,绘制面需要VectorLayer图层上进行绘制。

它画面的原理是,两点定义一条直线,多个点连成多条线,近大远小,远看就是曲线,那么面就是连接了开始和结束的点,使之闭环,加上颜色就是一个面。

好,下载可以找一个数据来测试一下:地图选择器 (aliyun.com)

上面下载一个geojson的数据,名称随便,这里就说一下怎么用它的方法:

​ 首先要清除怎么添加几何面,使用layer.addGeometry(geometry),addGeometry支持单个,也支持数组,那么就是说,我们可以传入的参数可以是:Polygon、MultiPolygon、Geometry、MultiGeometry,或者他们数组。

代码语言:javascript
复制
const geoJson = require( '@/mock/xiamen.json')


  /**
    * 根据geojson画区域面
    * @param geoJson geoJson数据
    * @param layer 需要话的图层
    */
drawAreaPolygon(geoJson, layer) {
    const _t = this
    const geometry = maptalks.GeoJSON.toGeometry(geoJson)
    if (geometry) {
        geometry.forEach(g => {
            g.setSymbol({
                // 线色
                lineColor: '#34495e',
                // 线宽
                lineWidth: 1,
                // 填充色
                polygonFill: 'rgb(135,196,240)',
                // 不透明度
                polygonOpacity: 0.2
            })
        })
    }
    layer.addGeometry(geometry)
},

maptalks.GeoJSON.toGeometry(geoJson) 获取到的是一个MultiPolygon数组对象

效果如下:

好像这个JSON的数据不是很准确,这个不重要,重要的是我们已经将面画出来了,还需要一些交互。

面的交互(事件监听)

上面我们画出了面,但是只能看,而且没有任何交互,用户体验非常非常的,额…是没有用户体验,现在我们来加一下事件,实现鼠标移动、点击等的交互。

Geometry Polygon 提供了监听事件on和js的一样,这个没什么好说的,下面我就以geoJson创建的面为例:

代码语言:javascript
复制
 drawAreaPolygon(geoJson, layer) {
        const _t = this
        const geometry = maptalks.GeoJSON.toGeometry(geoJson)
          if (geometry) {
              geometry.forEach(g => {
                  g.setSymbol({
                      // 线色
                      lineColor: '#34495e',
                      // 线宽
                      lineWidth: 1,
                      // 填充色
                      polygonFill: 'rgb(135,196,240)',
                      // 不透明度
                      polygonOpacity: 0.2
                  })
                  // 设置信息框
                  g.setInfoWindow({
                      title    : g.properties.name,
                      content  : '<br style="color:#f00">中心点:' + g.properties.center + ' </br>行政区划:' + g.properties.adcode + ' </br>父级行政区划:' + g.properties.parent.adcode + '</div>'
                  })
                  // 鼠标交互事件监听
                  g.on('mouseenter', function (e) {
                      e.target.updateSymbol({
                          polygonFill: '#f00'
                      });
                  }).on('mouseout', function (e) {
                      e.target.updateSymbol({
                          polygonFill: 'rgb(135,196,240)'
                      });
                  }).on('click', function (e) {
                      e.target.openInfoWindow(e.coordinate)
                  })
              })
          }
          layer.addGeometry(geometry)
      },

效果如下:

它在鼠标点击位置显示了弹框

基础的操作现在有了,也比较常用,可是你觉得你还需要右键菜单,菜单啊,这个,可以,它也提供了这些东西的设置,下面再来一个简单例子:

代码语言:javascript
复制
 drawAreaPolygon(geoJson, layer) {
            const _t = this
            const geometry = maptalks.GeoJSON.toGeometry(geoJson)
            if (geometry) {
                geometry.forEach(g => {
                    g.setSymbol({
                        // 线色
                        lineColor: '#34495e',
                        // 线宽
                        lineWidth: 1,
                        // 填充色
                        polygonFill: 'rgb(135,196,240)',
                        // 不透明度
                        polygonOpacity: 0.2
                    })
                    // 设置信息框
                    g.setInfoWindow({
                        title: g.properties.name,
                        content: '<br style="color:#f00">中心点:' + g.properties.center + ' </br>行政区划:' + g.properties.adcode + ' </br>父级行政区划:' + g.properties.parent.adcode + '</div>'
                    })
                    // 设置右键菜单
                    g.setMenu({
                        width: 160,
                        custom: false,
                        items: [
                            { item: '菜单一', click: function() { alert('Query Clicked!'); return false } },
                            '-',
                            { item: '菜单二', click: function() { alert('Edit Clicked!') } },
                            { item: '菜单三', click: function() { alert('About Clicked!') } }
                        ]
                    })
                    // 鼠标交互事件监听
                    g.on('mouseenter', function(e) {
                        e.target.updateSymbol({
                            polygonFill: '#f00'
                        })
                    }).on('mouseout', function(e) {
                        e.target.updateSymbol({
                            polygonFill: 'rgb(135,196,240)'
                        })
                    }).on('click', function(e) {
                        e.target.openInfoWindow(e.coordinate)
                    })
                })
            }
            layer.addGeometry(geometry)
        },

这里的菜单有一个返回值,如果返回false,菜单就不会关闭。

效果如下:

绘制mark

绘制mark没有Polygon 那么复杂,它只要一个坐标点就行,然后在指定坐标出绘制一个图标,

它有一个addTo方法,可以添加到任何一个图层

代码语言:javascript
复制
drawMark(centerPointList, layer) {
            if (!centerPointList) {
                console.log('无区域中心点数据')
                return
            }
            const info = { content: '', width: 150, minHeight: 100 }
            const result = []
            // 这里 d 的数据格式是数组,如:[-0.113049, 51.498568]
            centerPointList.forEach(d => {
                if (!d.info) {
                    d.info = info
                }
                // 设有高度、高亮的mark
                const mark = new maptalks.Marker(d.center, {
                    // 设置了这个属性,会替换默认的图标
                    // symbol: {
                        // markerFile: 'foo.png',
                        // textName: d.name
                    // },
                    properties: {
                        // 高度设置
                        altitude: 50
                    }
                }).addTo(layer)
                mark.setInfoWindow({
                    title: d.name,
                    content: '<div>' + d.adcode + '</div>',
                    // autoPan: true,
                    width: d.info.width,
                    minHeight: d.info.minHeight,
                    // 'custom': false,
                    // 点击打开和关闭
                    // autoOpenOn: 'click',
                    // autoCloseOn: 'click'
                })

                // 没有高度的mark
                // new maptalks.Marker(d).updateSymbol({
                //   markerOpacity: 0.5,
                //   markerFill: '#bbb'
                // }).addTo(layer)

                mark.setZIndex(1000)
                result.push(mark)
            })
            return result
        },

这里的centerPointList是geoJson里的properties属性;

绘制三维图形注意点

这里有一个关键点是,要绘制三维的mark,需要设置图层layer启用高度绘制如下:

代码语言:javascript
复制
layer.setOptions({
        // 启用高度绘制
        enableAltitude: true,
        altitudeProperty: 'altitude',
        // 绘制高度线
        drawAltitude: {
         // 这里是绘制高度线的宽度,可以理解为Z,那么要透明,这里设置为0
          lineWidth: 1,
          lineColor: '#000'
        }
      })

锁定视角

当启用锁定后,我们所观看到的视图,只会是我们设定好的区域,这块区域默认是地图初始化时设定的center

代码语言:javascript
复制
 lockView() {
     const extent = this.map.getExtent()
     this.map.setMaxExtent(extent)
 },
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为何使用maptalks
  • API
  • 初始化
  • Symbol 属性
  • 创建图层
  • 放大缩小等工具
  • 绘制区域面(几何图形)
    • 面的交互(事件监听)
    • 绘制mark
      • 绘制三维图形注意点
      • 锁定视角
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档