JavaScript
常用 Api 实现
数组 Api 实现
实现 Promise
浏览器缓存
命令行参数
工作小技巧
面试题收录
webpack介绍
webpack实战
webpack拓展
如何优雅的解决端口被占用
树在工作面试中的应用
从0搭建vue
AST团队分享
eslint 工作流
Vue 源码分析
cli 开发
vscode 开发记录
Chrome 开发记录
mapbox
网站渲染流程
fs文件系统
服务器的配置
Linux命令
http笔记
https笔记
HTTP认证方式
mysql
redis
nginx
git子模块
GitHub
中文版
(opens new window)
英文版
(opens new window)
底图渲染
-
初次渲染地图很简单,按照官网的配置
-
我们需要一个地图渲染容器,需要用到 mapbox-gl 库,有时候你可能需要准备一个开发者 token,那我们开始吧
-
首先我们实例化一个 Map 类,在 mapbox-gl 里面有个 Map 类,该类接受一个 options 配置对象作为初始化地图的条件
import mapboxgl from 'mapbox-gl';
const options = {
container: '底图容器',
style: '您的底图json',
center: [108.5, 38],
zoom: 3.9,
bearing: 0,
pitch: 0,
doubleClickZoom: false,
dragRotate: false,
const map = new mapboxgl.Map(options);
1
2
3
4
5
6
7
8
9
10
11
12
13
添加控制器
-
实例 map 的方法,map.addControl()
-
接受两个参数,
要添加的控制器
和
添加的位置
('top-left' , 'top-right' , 'bottom-left' , and 'bottom-right' 。默认为 'top-right' )
map.addControl(new mapboxgl.NavigationControl(), 'top-left');
const scale = new mapboxgl.ScaleControl({
maxWidth: 80,
unit: 'imperial'
map.addControl(scale)
scale.setUnit('metric')
1
2
3
4
5
6
7
8
9
10
添加/移除标记
-
在 mapbox-gl 类中有 Marker 类,专门用来处理标记
-
该类接受两个参数,element 和 options
-
只是添加一个标记,但是添加到哪就需要你来设置了
-
移除标记就是移除该类的实例
let marker = null;
function addMarker(LngLat, el, options) {
if (marker) {
marker.remove();
marker = new mapboxgl.Marker(el, options).setLngLat(LngLat).addTo(map);
1
2
3
4
5
6
7
8
地图移动
flyTo 地图飞行
-
对地图中心、缩放级别、方位角和倾斜度做任意组合改变, 使其沿着一条曲线动态地变化并引发飞行效果。 该动态转换能够无缝引入缩放和平移,使用户即使在穿越了很长的距离后也能保持方位角不变
-
接收两个参数,
options
和
传递的其他属性
-
options.curve
[number] (default 1.42):缩放曲线效果
-
options.speed
[number] (default 1.2):飞行速度
-
options.center
:飞行后的中心点,类似于初始化地图的 center
-
options.zoom
:飞行后缩放级别
map.flyTo({
center: [108.5, 38],
zoom: 10,
speed: 5,
curve: 1,
easing(t) {
return t;
});
1
2
3
4
5
6
7
8
9
jumpTo 跳跃
-
地图移动的方法之一
-
参数和 flyTo 一样,
options
和
传递的其他属性
-
options.center
(LngLatLike) : 目的地中心。
-
options.zoom
(number) : 目的地的缩放级别。
-
options.bearing
(number) : 目的地的方位角(bearing,rotation),按照逆时针偏离正北方的度数计算。
-
options.pitch
(number) : 目的地的倾斜度(pitch,tilt),单位为度。
-
options.around
(LngLatLike) : zoom 指定之后, around 将决定缩放中心(默认为地图中心)。
easeTo 动态转换
Layer 和 Source
-
Layer 是图层,Source 是数据源
-
Layer 和 Source 需要相辅相成,一个负责界面呈现,一个是数据
-
Source 支持:vector、raster、geojson、image、video。
-
geojson 处理各种矢量类型,包括集合
-
vector 主要解决矢量瓦片
-
raster 解决目前常用的栅格化瓦片
-
video 的加入使得功能更加的现代化
-
mapbox 在 style 里面,为 source 定义了一个 type 属性,来说明这些类型。
-
Layer 分为:background、fill、line、symbol、raster、circle,除了 background 类型的 layer 不需要绑定 source 之外。其他的都需要有 source。
-
fill 只负责填充
-
line 只负责线条
-
symbol 处理 sprite 图,文字等
-
raster 只负责图片
-
circle 负责点
-
Filter 设置展示的过滤条件,定制化显示
添加/删除 Layer
-
有这么一个需求,我输入一个经纬度或者一个别的什么条件来查到这个点在地图上的位置,并且根据这个区域的 admincode 或者别的什么条件圈出该区逇范围
-
如下图,左边是效果,右边是该区域的数据,原地图是没有那个紫色的边框的,我们要查出来后给该区域添加上
-
那么我么需要用到 addLayer 方法,添加 layer,但是我们需要获取到底图的数据
-
queryRenderedFeatures(),查询渲染后的功能信息,该返回一个 GeoJSON Feature Object 数据,表明满足查询参数的可见要素。
传送门
(opens new window)
-
我们使用该方法传递 layerId,获取到我们要的数据
-
开始添加 layer,map.addLayer() 接收一个配置对象,配置对象规则如下
-
样式的 layer 属性将列出该样式中所有可用的图层。图层类型由
type
属性规定,且指定方式必须为 background, fill, line, symbol, raster, circle, fill-extrusion
-
除了 background 类型的图层,其它每一个图层都需要参考一个数据源。 图层从数据源获取数据,选择性地筛选要素,然后定义为这些要素添加样式的方式。
-
具体信息查看
这里
(opens new window)
-
我们的代码最终如下
drawLine(admincode) {
let _layer = map.getLayer('data_town_polygon')
if (_layer) {
map.removeLayer(_layer.id)
map.removeSource(_layer.source)
const layer = {
id: 'data_town_polygon',
type: 'line',
source: {
type: 'vector',
tiles: ['http://10.125.214.22:8080/data/town/{z}/{x}/{y}.pbf']
'source-layer': 'town_polygon',
'layout':{
visibility:'visible'
'paint': {
'line-color': '#4D2EA5',
'line-width': 5,
'line-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1, 0.6
filter: ['==', 'admincode', admincode]
map.addLayer(layer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
地图事件
on -> load 事件
on -> click 事件
-
鼠标单击事件,对原生的 click 做了很好的封装
-
比如说我们可以,获取到经纬度,点信息,我们可以根据点信息获取 feature 信息
this.map.on('click', async (ev: any) => {
if (this.isMouseGet) {
const features: any[] = this.map.queryRenderedFeatures(ev.point);
console.log(features, 'sss');
if (!features.length) return this.$message.warning('未获取到该区域的数据');
await this.drawLine(features[0].properties['admin_code']);
const areaInfo: any = {};
Object.entries(features[0].properties).forEach((item: any) => {
areaInfo[toHump(item[0])] = item[1];
});
this.info = areaInfo;
this.$refs.dialog.handleDialogOpen(this.info);