基于postgis函数计算矢量切片并通过mapbox和arcgis js 3.x加载:https://www.pianshen.com/article/90461612366/
https://github.com/xiaopaoge/postgis-stMvt
原理:
1. 首先在前端依赖js类库算法将当前的地图范围(extent)和缩放级别(extent)自动计算出列号(x)、行号(y)、级别(z)。会计算出多个瓦片坐标(z,x,y)。
2.将这些瓦片坐标当做实参({z}、{x}、{y})依次循环传入到后台的服务(后台对应着三个形参)
3.将瓦片坐标转换为经纬度,因为只有这样才能依靠经纬度(4326)或平面坐标(3857)范围查询对应数据库的数据。
4.将查询出的数据转换为mvt格式(实际是一个二进制流格式数据)。
SELECT ST_AsMVT(tile,'lines',4096,'geom') tile
FROM(SELECT fs_name,ST_AsMVTGeom(geom,ST_Transform(ST_MakeEnvelope(%s,%s,%s,%s, 4326),3857),4096, 256, true) AS geom
FROM public.pipesectionmpa_4326_3857 ) AS tile;
5. 依次返回给前端,前端将数据绘制到地图上。另外,可以根据match对某个字段值进行分值设色。
但是并不能。。
源码1:
<!DOCTYPE html> <html> <head> <meta charset='utf-8' /> <title>Display a map</title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.41.0/mapbox-gl.js'></script>; <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.41.0/mapbox-gl.css' rel='stylesheet' /> <style> body { margin:0; padding:0; } #map { position:absolute; top:0; bottom:0; width:100%; } </style> </head> <body> <div id='map'></div> <script> //使用注册Mapbox时候后台自动生成的token mapboxgl.accessToken = ‘yourToken’; var map = new mapboxgl.Map({ container: 'map', // 放置的div的id style: 'mapbox://styles/mapbox/streets-v9', center: [116.466, 40.035],// 地图显示中心点位置 zoom: 8,// 开始的缩放级别 maxZoom: 16 }); map.on('load', function() { //访问本地的服务器 var bjroad_tile_source = { type: 'vector', tiles: [ 'http://localhost:8000/tiles-bjroad3857-vector/{z}/{x}/{y}.pbf' ], maxzoom: 14 }; var usa_tile_source = { type: 'vector', tiles: [ 'http://localhost:8000/tile-usa4326-vector/{z}/{x}/{y}.pbf' ], maxzoom: 14 }; //注意:这里的'source-layer'要与mbtiles数据集中所使用的图层名称(id)保持一致! var bjroad_polygon_layer = { 'id': 'bjroad_polygon_id', 'type': 'fill', 'source': 'bjroad_tile_source', 'source-layer': 'BJ_LN_3857', 'paint': { "fill-color": "#00ffff", "fill-opacity": 1, "fill-outline-color": "#ff0000" } }; var bjroad_normal_line_layer = { 'id': 'bjroad_normal_line_id', 'type': 'line', 'source': 'bjroad_tile_source', 'source-layer': 'BJ_LN_3857', 'layout': { 'line-join': 'round', 'line-cap': 'round' }, 'paint': { "line-color": "#0000ff", "line-width": 1 } }; var usa_polygon_layer = { 'id': 'usa_polygon_id', 'type': 'fill', 'source': 'usa_tile_source', 'source-layer': 'usa4326', 'paint': { "fill-color": "#00ffff", "fill-opacity": 1, "fill-outline-color": "#ff0000" } }; var usa_normal_line_layer = { 'id': 'usa_normal_line_id', 'type': 'line', 'source': 'usa_tile_source', 'source-layer': 'usa4326', 'layout': { 'line-join': 'round', 'line-cap': 'round' }, 'paint': { "line-color": "#0000ff", "line-width": 1 } }; map.addSource('bjroad_tile_source', bjroad_tile_source); map.addSource('usa_tile_source', usa_tile_source); //map.addLayer(bjroad_polygon_layer); map.addLayer(bjroad_normal_line_layer); map.addLayer(usa_normal_line_layer); }); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset='utf-8' /> <title>Add a third party vector tile source</title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <script src='mapbox-gl.js'></script> <link href='mapbox-gl.css' rel='stylesheet' /> <style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; } </style> </head> <body> <div id='map'></div> <script> mapboxgl.accessToken = undenfined; var tileset = 'mapbox.streets'; var map = new mapboxgl.Map({ container: 'map', zoom: 12, center: [109.898625809072612, 19.106708155556731], style: 'mapbox://styles/mapbox/light-v9', hash: false }); map.on('load', function loaded() { map.addSource('custom-go-vector-tile-source', { type: 'vector', tiles: ['http://localhost:8081/tiles/{z}/{x}/{y}'] }); map.addLayer({ id: 'background', type: 'background', paint: { 'background-color': 'white' } }); map.addLayer({ "id": "custom-go-vector-tile-layer", "type": "circle", "source": "custom-go-vector-tile-source", "source-layer": "points", paint: { 'circle-radius': { stops: [ [8, 0.1], [11, 0.5], [15, 3], [20, 20] ] }, 'circle-color': '#e74c3c', 'circle-opacity': 1 } }); }); </script> </body> </html>
参考:Node+JavaScript Go+JavaScript:https://github.com/vicapow/go-vtile-example
(小贴士:sql中‘points’的字符串与渲染中mapbox里的source-layer一致)
SELECT ST_AsMVT(tile,'points') tile FROM( SELECT ST_AsMVTGeom(geom,ST_MakeEnvelope(100,10,125,22, 4326),4096, 0, true) AS geom FROM grid20180322 ) AS tile where tile.geom is not null
>>基于PostGIS动态矢量切片实践:https://zhuanlan.zhihu.com/p/349849542 https://blog.crunchydata.com/blog/dynamic-vector-tiles-from-postgis