基于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>
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