MapLibre GL JS 是一个 TypeScript 库,它使用 WebGL 从浏览器中的矢量瓦片渲染交互式地图。
举个官网的栗子:
在react中使用对初始化地图进行简单封装:
1import maplibregl from 'maplibre-gl'
2import React, { useEffect, useState } from 'react'
3
4interface Props {
5 initStyle: string
6 onMapLoaded: (by: maplibregl.Map) => void
7}
8
9const Index: React.FC<Props> = ({ onMapLoaded, initStyle }) => {
10 const [mapLoading, setMapLoading] = useState(true)
11
12 useEffect(() => {
13 const map = new maplibregl.Map({
14 container: 'map', // container id
15 style: initStyle || 'https://demotiles.maplibre.org/style.json', // style URL
16 center: [0, 0], // starting position [lng, lat]
17 zoom: 1, // starting zoom
18 })
19
20 map.on('load', () => {
21 onMapLoaded(map)
22 setMapLoading(false)
23 })
24 }, [])
25
26 return (
27 <>
28 {mapLoading ? (
29 <div id="map" className="w-full h-full flex items-center justify-center">
30 Loading...
31 </div>
32 ) : (
33 <div id="map" className="w-full h-full"></div>
34 )}
35 </>
36 )
37}
38export default Index
39
一些常用的API
1map.addLayer({
2 id: 'points-of-interest',
3 source: {
4 type: 'vector',
5 url: 'https://demotiles.maplibre.org/tiles/tiles.json'
6 },
7 'source-layer': 'poi_label',
8 type: 'circle',
9 paint: {
10 // MapLibre Style Specification paint properties
11 },
12 layout: {
13 // MapLibre Style Specification layout properties
14 }
15});
1{
2 id: 'town_fillLayer',
3 type: 'fill',
4 source: 'caec8e3ae4ade',
5 'source-layer': 'jjyzq_yjxzq_cq_poly',
6 filter: showNames.includes('全部')
7 ? [
8 'all',
9 ['>=', ['get', 'code'], Number(`${code}000`)],
10 ['<=', ['get', 'code'], Number(`${Number(code) + 1}000`)],
11 ]
12 : [
13 'all',
14 ['>=', ['get', 'code'], Number(`${code}000`)],
15 ['<=', ['get', 'code'], Number(`${Number(code) + 1}000`)],
16 ['in', ['get', 'name'], showNames],
17 ],
18 paint: {
19 'fill-color': color,
20 },
21 metadata: {
22 beforeId: 'admin_cn',
23 },
24 },
source.add
事件。1map.addSource('my-data', {
2 "type": "geojson",
3 "data": {
4 "type": "Feature",
5 "geometry": {
6 "type": "Point",
7 "coordinates": [-77.0323, 38.9131]
8 },
9 "properties": {
10 "title": "Mapbox DC",
11 "marker-symbol": "monument"
12 }
13 }
14});
1map.addSprite('sprite-two', 'http://example.com/sprite-two');
1// fly with default options to null island
2map.flyTo({center: [0, 0], zoom: 9});
3// using flyTo options
4map.flyTo({
5 center: [0, 0],
6 zoom: 9,
7 speed: 0.2,
8 curve: 1,
9 easing(t) {
10 return t;
11 }
12});
1let popup = new Popup({offset: popupOffsets, className: 'my-class'})
2 .setLngLat(e.lngLat)
3 .setHTML("<h1>Hello World!</h1>")
4 .setMaxWidth("300px")
5 .addTo(map);
1let marker = new Marker({
2 color: "#FFFFFF",
3 draggable: true
4 }).setLngLat([30.5, 50.5])
5 .addTo(map);
1//使用draw.create监听绘制
2_map.on('draw.create', async (e) => {
3 if (getSelect() === 'drawGrid') {
4 drawCreateHandler(true)
5 getValueByDraw(_map)
6 }
7 })
8
9//通过changeMode实现连续绘制
10const drawCreateHandler = (isSelect: boolean) => {
11 if (isSelect) {
12 setTimeout(() => {
13 drawRef.current.changeMode(DrawModes.FREEHAND_POLYGON)
14 }, 50)
15 } else {
16 try {
17 drawRef.current.deleteAll()
18 } catch (error) {
19 console.log(error)
20 }
21 }
22 }
补充:添加source时,可通过clusterRadius来控制显示点的密度