Maplibre GL JS

Maplibre GL JS

Demo 项目:Gearinger/gear-maplibre: Based on MaplibreJS, providing data loading, display and editing features. (github.com)

开始

创建空白底图

 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
// 创建空白图层样式,用于地图初始化
const blankStyle: StyleSpecification = {
    version: 8,
    name: "BlankMap",
    sources: {},
    glyphs:"",
    layers: [
        {
            id: "background",
            type: "background",
            paint: {
                // 'background-color': '#08294A' /* 背景颜色 */
                "background-color": "rgba(255, 255, 255, 0)" /* 背景颜色-透明 */,
            },
        },
    ],
};
// 初始化地图
var map = new Map({
    container: "map", // container id
    // style: "https://demotiles.maplibre.org/style.json", // style URL
    style: "https://api.maptiler.com/maps/streets/style.json?key=get_your_own_OpIi9ZULNHzrESv6T2vL",
    // style: blankStyle,
    center: [113.46, 22.88], // starting position [lng, lat]
    zoom: 9, // starting zoom
});

添加注记

注意:添加注记需要配置字体,上面的空白样式没有配置字体。配置方式见 【字体问题】

 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
// 添加 source
map.addSource("testGeoJson", {
    type: "geojson",
    data: "./data/smallGeoJSON.geojson"
});
// 从 source 中获取并添加 fill 面图层
map.addLayer({
    id: "testGeoJson",
    type: "fill",
    source: "testGeoJson",
    layout: {},
    paint: {
        "fill-color": "#088",
        "fill-opacity": 0.8,
        "fill-outline-color": "red",
    },
});
// 从 source 中获取并添加 symbol 注记图层
map.addLayer({
    id: "testGeoJsonAnno",
    type: "symbol",
    source: "testGeoJson",
    layout: {
        // 注记使用 name 字段(也可以采用 formmater 格式)
        "text-field": "{name}"
    },
});
// 缩放到全图
map.fitBounds(map.getBounds());

点击获取要素

1
2
3
4
5
6
7
// 点击地图时,获取点击位置的要素
map.on("click", (e) => {
    console.log(e);
    // 返回的是要素列表,因为存在缓冲距离,可能选中多个要素
    let features = map.queryRenderedFeatures(e.point, {});
    console.log(features);
});

添加 GeoJSON 数据

 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
/**
 * 添加geojson数据到地图上
 */
export function addTestGeoJson(map: Map) {
    map.addSource("testGeoJson", {
        type: "geojson",
        // data: "http://192.168.10.95:8999/geoserver/nansha/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=nansha%3Afield&maxFeatures=40000&outputFormat=application%2Fjson",
        data: "./data/smallGeoJSON.geojson"
    });
    map.addLayer({
        id: "testGeoJson",
        type: "fill",
        source: "testGeoJson",
        layout: {},
        paint: {
            "fill-color": "#088",
            "fill-opacity": 0.8,
            "fill-outline-color": "red",
        },
    });
    map.addLayer({
        id: "testGeoJsonAnno",
        type: "symbol",
        source: "testGeoJson",
        layout: {
            "text-field": "{name}"
        },
    });

    map.fitBounds(map.getBounds());
}

添加 FlatGeoBuf 数据

 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
36
37
/**
 * 将 FlatGeoBuf 数据添加到地图上
 * @param fgb FlatGeobuf
 * @param map 地图
 */
export async function addFlatGeoBuf(fgb: any, map: Map) {
    const fc = { type: "FeatureCollection", features: [] as any[] };
let i = 0;

for await (const f of geojson.deserialize(
    fgb,
    undefined,
    undefined
) as AsyncGenerator<any>) {
    fc.features.push({ ...f, id: i });
i += 1;
}

map.addSource("counties", {
    type: "geojson",
    data: fc,
});
map.addLayer({
    id: "counties-fill",
    type: "fill",
    source: "counties",
    paint: {
        "fill-color": "#0000FF",
        "fill-opacity": [
            "case",
            ["boolean", ["feature-state", "hover"], false],
            1,
            0.5,
        ],
    },
});
}

添加 PBF 数据

可采用 postgis 创建切片底图服务

1
2
3
4
5
6
SELECT st_asmvt(geom) FROM ( 
    SELECT st_asmvtgeom(geom, st_transform(st_tileenvelope(#{z}, #{x}, #{y}), 4326), 4096, 0, false), state 
        FROM table_name
        WHERE geom is not null 
        and ST_Intersects(geom, st_transform(st_tileenvelope(#{z}, #{x}, #{y}), 4326)) 
        ) AS geom

获取的数据格式为 byte[]

 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
/**
 * 添加pbf数据到地图上
 */
export function addPbfLayer(map: Map) {
    map.addSource("pbfLayer", {
        type: "vector",
        tiles: ["http://127.0.0.1:9005/business/field/pbfLayer/field/1/{z}/{x}/{y}"],
    });
    map.addLayer({
        id: "pbfLayer",
        type: "fill",
        source: "pbfLayer",
        "source-layer": "default",
        "paint": {
            "fill-color": [
                "match",
                ["get", "name"],
                ["0403020000"],
                "#CDEBF2",
                ["0206000000"],
                "#F8CDD0",
                ["0201000000"],
                "#92D050",
                "#F39F72",
            ]
        }
    });
    map.fitBounds(map.getBounds());
    // console.log(map);
}

Marker

1
2
3
var marker = new Marker()
.setLngLat(new LngLat(113, 23))
.addTo(map);
1
2
3
4
5
6
// 将 marker 标记更换成任意 html 元素
let htmlEle = document.createElement('div');
htmlEle.innerHTML = "some text in div";
var marker = new Marker({ element: htmlEle })
.setLngLat(new LngLat(113, 23))
.addTo(map);
1
2
3
4
5
6
var marker = new Marker({ color: "#ff0000" })
// 设置标记位置
.setLngLat(new LngLat(113, 23))
// 添加弹出框
.setPopup(new Popup().setHTML("popup content!"))
.addTo(map);

插件

名称 作用 地址
mapbox-gl-draw 绘制、编辑、裁剪、旋转…… https://github.com/mapbox/mapbox-gl-draw
mapbox-gl-utils 部分地图操作的简化 https://github.com/stevage/map-gl-utils
maplibre-gl-export 导出地图 https://github.com/watergis/maplibre-gl-export
mapbox-gl-geocoder 搜索定位 https://github.com/mapbox/mapbox-gl-geocoder
mapbox-gl-legend 图例 https://github.com/watergis/mapbox-gl-legend
mapbox-gl-layer-groups 图层组 https://github.com/mapbox/mapbox-gl-layer-groups
mapbox-gl-inspect 开发过程中用来查看要素的属性信息 https://github.com/lukasmartinelli/mapbox-gl-inspect
maplibre-gl-compare 地图对比 https://github.com/maplibre/maplibre-gl-compare

其他

字体问题

protobuf 格式的字体文件,组织格式如下

1
2
3
4
5
6
7
# 文件目录结构
- glyphs
	- 字体名
		- 0-255.pbf
        - 256-511.pbf
        - 512-767.pbf
        - ...
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// map 的配置
const blankStyle: StyleSpecification = {
    version: 8,
    name: "BlankMap",
    sources: {},
    // 此处使用的是静态文件目录。也可换成静态服务代理。fontstack 为字体文件夹名称,range 为切片的层级(对应 pbf 文件名)
    glyphs:"./glyphs/{fontstack}/{range}.pbf",
    layers: [
        {
            id: "background",
            type: "background",
            paint: {
                // 'background-color': '#08294A' /* 背景颜色 */
                "background-color": "rgba(255, 255, 255, 0)" /* 背景颜色-透明 */,
            },
        },
    ],
};

protobuf 格式的字体文件获取方式:

方式一

使用以下地址,上传字体文件,得到 protobuf 文件

sdf-glyph-tool (protomaps.github.io)

源仓库:protomaps/sdf-glyph-tool: Tiny web page to create Signed Distance Field fonts for Mapbox GL, MapLibre GL, etc (github.com)

方式二

使用此项目 mapbox/node-fontnik: Fonts ⇢ protobuf-encoded SDF glyphs (github.com)

将tff文件转为 protobuf 格式

注意:需要 64 bit OS X or 64 bit Linux 环境

1、下载node-fontnik:https://github.com/mapbox/node-fontnik/archive/master.zip

2、下载需要的字体文件ttf

3、进入bin目录,执行命令:./build-glyphs ttf文件 输出目录

Licensed under CC BY-NC-SA 4.0
Comments
  • Latest
  • Oldest
  • Hottest
No comment yet.
Powered by Waline v2.15.8
Gear(夕照)的博客。记录开发、生活,以及一些不足为道的思考……