mapbox开发整体流程大致如下
1.引入mapbox
以简单的一个html为例,首先引入mapbox-gl.js以及css文件,如果是在angular项目中,则需要安装对应的npm包。
2.添加地图
首先需要创建一个id假设为map的div容器,并指定宽高。
var map = new mapboxgl.Map({
// container id
container:'map',
// style location
style:'mapbox://styles/mapbox/streets-',
// starting position
center:[-74.50, 40],
zoom:9
});
这样就通过mapbox的Map类创建了一个基础地图,通常这些配置信息都从后台接口获取。
3.创建图层父类
充分利用面向对象思想,首先封装一个基础父类,由于我们大部分的都是点图层,type为symbol(只需要传入图层id和对应的图标),并可以设置默认值,如果是其他类型的图层,则单独在子类中创建,统一在父类里面添加到地图,此外,还包含诸如初始化过程(增加图层,增加图标),控制图层显示隐藏,创建销毁,图层设置数据源等方法。
如下:
constructor(id,layers,icon){
this.id=id
//如果layers不是个数组,则表示是普通点类型的layer
if(!(this.layers instanceof array)){
this.layers = [
{
id: layers,
type: "symbol",
layout: {...},
paint: {...},
source: {
type: "geojson",
data: {
type: "FeatureCollection",
features: []
}
}
}
];
}else{ //否则就是其他类型的layer
this.layers=layers
}
this.icon=icon
...
}
init(){...}
setVisible(){...}
destroy(){...}
setData(){}
4.创建图层子类
归纳有多少个图层,由于TypeScript不支持多层继承,因此建议每一个图层都独立创造一个类继承父类,根据业务不同重写父类的方法以及增加其他方法。
图层主要分为
- 基础图层,是构成地图基础的图像切片,通常包含大量数据——包括标注、建筑等。
- 叠加图层,例如点、线、面,通常包括GeoJSON之类的矢量数据,包含的信息更少,但通常我们都是与这些图层进行交互,可随意的用js进行更改。
例如创建一个厕所点图层toiletLayer类,
constructor(id,layers,icon){
super('toilet','','assets/img/1.png',)
}
addLayer(){...}
addImage(){...}
setVisible(){...}
initLayer(){...}
destroyLayer(){...}
setData(){}
...其他方法
再例如创建一个景区面图层ScenicLayer类,则需要在内部声明layer,type为fill
constructor(id,layers,icon){
super('scenic',[
{
id: 'tb_basis_info_polygon',
type: 'fill',
layout: {},
minzoom: 8,
maxzoom: 24,
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: []
}
},
paint: {
'fill-color': 'rgb(255,255,255)',
'fill-opacity': 0.08
}
}]
,'assets/img/1.png',)
}
addLayer(){...}
addImage(){...}
setVisible(){...}
initLayer(){...}
destroyLayer(){...}
setData(){}
...其他方法
source数据源和style属性会在后面提到。
5.地图加载完成后加载图层
map.on('load', function() {
map.addLayer(.....);
});
值得注意的是,当且仅当地图数据源加载之后(包括地图样式),地图引擎提供一个加载完成后的回调事件,通知地图加载完成,之后才可以进行加载图层等一系列业务操作。
6.给图层添加数据源
添加新图层时需要添加数据源,图层数据源包括type和url,因此,既支持远程数据源,也支持
从后台获取(通常用这种方式,灵活可拓展),这种方法通常是GeoJSON格式的数据。
标准的geojson数据格式如下:
const geoJson={
"type": "FeatureCollection",
"features": [
{
"type":"Feature",
"properties":{},
"geometry":{
"type":"Point",
"coordinates":[105.380859375,31.57853542647338]
}
}
]
}
其中,features里面是我们需要的要素信息,geometry里面是地理信息,properties则是一些名称等基本信息。可以在定义图层的时候,配置source,也可以用如下办法灵活改变数据源,如要设置刚才景点图层的数据源:
setData(){
this.map.getSource('tb_basis_info_polygon').setData(data)
}
可通过getSource(layerId)的方法获得这个layer的source,再重新赋值,但通常只赋值一次,因为这个操作消耗的性能很大,切忌频繁使用,有其他替代办法可以逐步增加或修改。
7.图层的样式设置
主要分为Layout和paint属性设置,用于明确图层如何渲染数据,就相当于css,同样是配置化。Layout属性指渲染位置和可见性,应用于渲染过程的早期阶段。paint指更精细的渲染样式,如不透明度、颜色等。不需要大量处理,在后期阶段进行渲染。例如:
map.addLayer({
id:'test',
type:'fill',
source:...,
layout:{
visibility:'visible'
},
paint:{
'fill-color':'rgba(61,153,80,0.55)'
}
});
即表示设置图层可见,设置面的填充色为rgba(61,153,80,0.55)。
8.图层的特殊表现形式
这部分通常是开发过程中最难的地方,拓展要求最多,例如聚合、
聚合列表、特殊的需要结合canvas等实现的功能
9.地图绑定事件
地图绑定一些鼠标移入、移出、点击、滚动缩放等事件,绑定的对象是map。
一方面可以对整个地图绑定
this.map.on('click',$event=>{
console.log($event)
})
```
也可以对某一个图层进行单独的事件绑定,如:
```
this.map.on('click','tb_basis_info_polygon',$event=>{
console.log($event)
})
这样只有在点击这个图层的时候才会触发,如果两者同时设置,则触发的规则和JS原生的冒泡事件一致。
10.创建地图上其他交互组件
如图例,地图上的弹出框,信息框,控制图层的树或者tab,指北针和放大缩小按钮这些基础组件大部分地图引擎自身包含,但需要定制UI,一些特殊的要求也需要重写逻辑,这些都应该单独作为组件。他们之间的交互,以及和地图的交互,我们目前用一套Rxjs的规范去实现组件间的通信。这部分不属于地图部分,先不做详细介绍。
11.参考
更多进阶知识 https://giser.xyz/mapbox-gl-js-cookbook/advance/