maptalks Development Manual - Getting Started

Why use maptalks

Friends who have done maps know that each map framework manufacturer binds its own map resources, such as the very popular mapBox, AutoNavi, Baidu, Tencent, etc. You must register their products, obtain the key, and then The related operations of the map can only be performed by calling the API. Although it brings convenience, it also has this limitation.

Then some people may ask, it is so convenient, just use theirs, so you don’t need to develop it yourself, why use other ones?

This question is very good. The best way to make a product is to let the development itself control what can be done and to what extent it can be achieved. Everything is controlled by the development. This is a complete independent product. When it comes to independence, as a Chinese, I also have personal experience. Crop gene patents, lithography machines, software, etc., are controlled by foreign countries. As users, we can only admit that we are poor. Maptalks is an open source map of our country. The framework can customize our map resources without third-party support, and also integrates many plug-ins, such as three, echarts, and heat maps, to support our development needs. This is not propaganda, just some of my personal views.

API

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

initialization

First you need to install maptalks

npm install maptalks

It is similar to other frameworks, as long as you understand it;
oh, there is another point, there is a cross-domain problem, you need to setcrossOrigin: undefined

<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 property

This attribute is used to set the style, and it is a rule of it. The functions we use later are all related to this, so here is an advance understanding. The following is its documentation:

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

create layers

There are two ways to create layers:

  1. Create a layer while creating a map instance:
    2 parameters, the required parameter is the first (id), the second parameter is options, which is its layer attribute setting, generally the default is fine, and you can also pass the layer later The object is set.
 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. Create a layer instance, and then add it to the map instance
    . Note : A method is used here. addTo(map)This method is common to all components, which means that the tools and components we introduce below are added to the map using this method.
new maptalks.VectorLayer('v').addTo(map)

Tools such as zoom in and zoom out

When the map is initialized, we can also add some of our tools:

It provides new maptalks.control.Toolbarlet's go instantiate a toolbar, format:

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

Here I simply listed itemsthe attributes in it. It actually has 4 attributes: position, vertical, reverseMenu, items. For details, you can go to: Maptalks/docs/api/0.x/control.Toolbar.html, or from the source code From a perspective, it has a default configuration in the source code, such as the following:

var options$s = {
    
    
  'height': 28,
  'vertical': false,
  'position': 'top-right',
  'reverseMenu': false,
  'items': {
    
    }
};

Scaling tool It provides ready-made components:

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

We can also create custom:

 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);

The effect is as follows:

image-20211023122104588

Draw Area Faces (Geometry)

First of all, we need to know that it has two concepts: Geometry Polygon, polygon inherits Geometry, and the two can be regarded as one thing;

Also, the drawing surface needs VectorLayerto be drawn on a layer.

The principle of its picture is that two points define a straight line, and multiple points are connected to form multiple lines. The near side is larger and the far side is smaller, and it looks like a curve from a distance. Then the surface is the point that connects the start and end points, making it a closed loop. Adding color is one face.

Ok, download and find a data to test: map selector (aliyun.com)

Download a geojson data above, the name is random, here is how to use it:

​ First of all, we need to clear how to add geometric surfaces, use layer.addGeometry(geometry), addGeometry supports a single, and also supports an array, that is to say, the parameters we can pass in can be: Polygon, MultiPolygon, Geometry, MultiGeometry, or their arrays.

  1. Polygon

    const optiosn = {
          
          
        visible: true,
        editable: true,
        cursor: 'pointer',
        shadowBlur: 0,
        // 阴影
        shadowColor: 'red',
        draggable: false,
        dragShadow: true,
        drawOnAxis: null,
        enableAltitude: true,
        symbol: {
          
          
            // 线色
            lineColor: '#34495e',
            // 线宽
            lineWidth: 1,
            // 填充色
            polygonFill: 'rgb(135,196,240)',
            // 不透明度
            polygonOpacity: 0.2
        }
    }
    const polygon = new maptalks.Polygon(data, options)
    
    
    new maptalks.VectorLayer('v').addGeometry(polygon).addTo(_t.mapEngine)
    
    

    This method is relatively low-level, because the data it passes in datais a set of coordinates, and the format is as follows:

    There are 3 layers of packages, which is really uncomfortable. Moreover, our data is generally obtained through GeoJSON, so to use this method, we have to obtain it from the JSON object. I used this method at the beginning, which is quite uncomfortable.

     [
         [
             [121.55074604278596, 31.242008515751614],
             [121.55074604278596, 31.23914637638951],
             [121.55349262481711, 31.23914637638951],
             [121.55349262481711, 31.24134802974913],
             [121.5518618417361, 31.241384723537074],
             [121.55074604278596, 31.242008515751614]
         ]
     ]
    
    1. MultiPolygon

      maptalks provides a GeoJSON tool class, which can be better compatible with geoJson. This tool is calledGeoJSON

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) gets an MultiPolygonarray object

The effect is as follows:

It seems that the JSON data is not very accurate, this is not important, what is important is that we have already drawn the surface, and some interaction is needed.

image-20211023123531130

Surface interaction (event monitoring)

We drew the surface above, but it can only be viewed, and there is no interaction. The user experience is very, very bad, uh... there is no user experience. Now let's add events to realize the interaction of mouse movement and click.

Geometry Polygon provides the onsame monitoring events as js. There is nothing to say about this. Let me take the surface created by geoJson as an example:

 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)
      },

The effect is as follows:

It shows the popup at the mouse click position

image-20211023152155901

The basic operations are available now, and they are more commonly used, but you think you still need the right-click menu, the menu, this, yes, it also provides the settings of these things, here is another simple example:

 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)
        },

The menu here has a return value, if it returns false, the menu will not be closed.

The effect is as follows:

image-20211023152301838

draw mark

Drawing a mark is not as complicated as a Polygon. It only needs one coordinate point, and then draws an icon at the specified coordinates.

It has a addTomethod that can be added to any layer

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
        },

Here centerPointListis the properties attribute in geoJson;

Points to note when drawing 3D graphics

A key point here is that to draw a three-dimensional mark, you need to set the layer layer to enable height drawing as follows:

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

lock view

When the lock is enabled, the view we see will only be the area we set. This area is set by default when the map is initialized.center

 lockView() {
    
    
     const extent = this.map.getExtent()
     this.map.setMaxExtent(extent)
 },

Guess you like

Origin blog.csdn.net/qq_28911061/article/details/122515814