leaflet结合PostGIS动态渲染矢量瓦片(附源码下载)

打印 上一主题 下一主题

主题 963|帖子 963|积分 2889

前言

leaflet 入门开发系列环境知识点相识:

内容概览

leaflet结合PostGIS动态渲染矢量瓦片
源代码demo下载
效果图如下:

具体实现思路:
根据前端舆图哀求的舆图当前级别以及行列号zxy(http://localhost:5000/tiles/quanguospot/spot/14/13345/7097),
后台接口python根据前端舆图传值过来的zxy,动态计算舆图当前级别z行列号对应的舆图范围extent(lonmin,latmin,lonmax,latmax),然后结合postgis动态生成矢量瓦片返回前端舆图渲染可视化。
postgis-stMvt

python 后台连接postgis 返回矢量切片
使用


  • 在tileOline.py中配置自己的postgis连接参数
    1. Dbpool = psycopg2.pool.SimpleConnectionPool(
    2.      1,
    3.      2000,
    4.      dbname='postgis_31_sample',
    5.      user='postgres',
    6.      host='localhost',
    7.      password='postgres',
    8.      port='5432')
    复制代码
  • 根据ZXY计算对应舆图范围Extent
  1. import math
  2. def tile2lat(ytile, zoom):
  3.   n = 2.0 ** zoom
  4.   lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
  5.   lat_deg = math.degrees(lat_rad)
  6.   return lat_deg
  7. def tile2lon(xtile, zoom):
  8.   n = 2.0 ** zoom
  9.   lon_deg = xtile / n * 360.0 - 180.0
  10.   return lon_deg
  11. def getLon(xtile, zoom):
  12.   a = []
  13.   a.append(tile2lon(xtile, zoom))
  14.   a.append(tile2lon(xtile+1, zoom))
  15.   return a
  16. def getLat(ytile, zoom):
  17.   a = []
  18.   a.append(tile2lat(ytile, zoom))
  19.   a.append(tile2lat(ytile+1, zoom))
  20.   return a
  21.   lons = Util.getLon(x, z)
  22.   lats = Util.getLat(y, z)
  23.   lonmin = str(lons[0])
  24.   lonmax = str(lons[1])
  25.   latmin = str(lats[1])
  26.   latmax = str(lats[0])
复制代码

  • 重要的查询语句
    1. // 传 source-layer 和 tableName参数动态获取
    2. query = "WITH mvtgeom AS(SELECT ST_AsMVTGeom(geom,ST_MakeEnvelope(%s,%s,%s,%s,4326),4096,64,true) AS geom FROM public." + tableName + \
    3.      " t where t.geom IS NOT NULL AND ST_Intersects(geom, ST_MakeEnvelope(%s,%s,%s,%s,4326))) SELECT ST_AsMVT(mvtgeom.*,'" + \
    4.      sourceLayer + "') FROM mvtgeom ;"
    5.   
    复制代码
  • postgis重要函数说明
  1.   (1) ST_AsMVTGeom:将一个图层中位于参数box2d范围内的一个几何图形的所有坐标转换为MapBox VectorTile坐标空间里的坐标。
  2.   ST_AsMVTGeom的官方文档API:http://postgis.net/docs/manual-3.0/ST_AsMVTGeom.html
  3.   函数各个参数的含义:
  4.   geom —— 被转换的几何图形信息。
  5.   bounds —— 某个矢量切片的范围对应的空间参考坐标系中的几何矩形框(没有缓冲区)。
  6.   extent —— 是按规范定义的矢量切片坐标空间中的某个矢量切片的范围。如果为NULL,则默认为4096(边长为4096个单位的正方形)。
  7.   buffer —— 矢量坐标空间中缓冲区的距离,位于该缓冲区的几何图形部位根据clip_geom参数被裁剪或保留。如果为NULL,则默认为256。
  8.   clip_geom —— 用于选择位于缓冲区的几何图形部位是被裁剪还是原样保留。如果为NULL,则默认为true。
  9.   注意:从3.0版本开始,可以在配置时选择Wagyu库来裁剪和验证MVT多边形。Wagyu库比默认的GEOS库更快且能产生更正确的结果,但是它可能会丢弃小的多边形。
  10.   (2) ST_AsMVT:ST_AsMVT聚合函数用于将基于MapBox VectorTile坐标空间的几何图形转换为MapBox VectorTile二进制矢量切片。
  11.   PostGIS生成MVT矢量切片的步骤是:
  12.   使用ST_AsMVTGeom函数将几何图形的所有坐标转换为MapBox VectorTile坐标空间里的坐标,这样就将基于空间坐标系的几何图形转换成了基于MVT坐标空间的几何图形。
  13.   使用ST_AsMVT函数将基于MVT坐标空间的几何图形转换为MVT二进制矢量切片。
  14.   ST_AsMVT的官方文档API:http://postgis.net/docs/manual-3.0/ST_AsMVT.html
  15.   函数各个参数的含义:
  16.   row —— 至少具有一个geometry列的行数据。
  17.   name —— 图层名字,默认为"default"。
  18.   extent —— 由MVT规范定义的屏幕空间(MVT坐标空间)中的矢量切片范围。
  19.   geom_name —— row参数的行数据中geometry列的列名,默认是第一个geometry类型的列。
  20.   feature_id_name —— 行数据中要素ID列的列名。如果未指定或为NULL,则第一个有效数据类型(smallint, integer, bigint)的列将作为要素ID列,其他的列作为要素属性列。
复制代码

  • leaflet矢量瓦片插件前端加载代码
    1.      var map = L.map('map',{renderer: L.canvas}).setView({ lat:23.56,lng:113.23 }, 14);
    2.      var positron = L.tileLayer('https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
    3.          opacity: 1
    4.      }).addTo(map);
    5. //设置图斑的样式
    6.      var vectorTileStyling = {
    7.          spot:{
    8.              color: '#ffd700',
    9.              fillColor: '#e6d933',
    10.              fillOpacity: 0.1,
    11.              fill: true,
    12.              opacity: 1,
    13.              weight: 3,
    14.              dashArray: '5',
    15.          }
    16.      }
    17.      var pbfUrl = "http://localhost:5000/tiles/quanguospot/spot/{z}/{x}/{y}";
    18.      var mapboxVectorTileOptions = {
    19.          rendererFactory: L.canvas.tile, //L.canvas.tile L.svg.tile
    20.          maxZoom: 20,
    21.          minZoom: 5,
    22.          vectorTileLayerStyles: vectorTileStyling
    23.      };
    24. var vectorGrid = L.vectorGrid.protobuf(pbfUrl, mapboxVectorTileOptions).addTo(map)
    复制代码
  • leaflet结合mapboxGL矢量瓦片前端加载代码
  1. var map = L.map('map', {maxZoom: 17}).setView([23.3759016568317, 113.22544097900392], 13);
  2. map.createPane("tileLayerZIndex");
  3. map.getPane("tileLayerZIndex").style.zIndex = 0;
  4. var positron = L.tileLayer('https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
  5.      opacity: 1,
  6.      pane: "tileLayerZIndex",
  7. }).addTo(map);
  8. var blankStyle = {
  9. version: 8,
  10. name: "BlankMap",
  11. sources: {},
  12. layers: [
  13. ]
  14. };
  15. var gl = L.mapboxGL({
  16.      accessToken: 'pk.eyJ1IjoiZ2lzeGlhb3dlaTEyMyIsImEiOiJja25zcTk4b3cweXZlMndwZjEyNzF1dXM2In0.V5daL_pyIbuSRN8K2PI80Q',
  17.      style: blankStyle
  18. }).addTo(map);
  19. gl.getMapboxMap().on('load', function() {
  20.         gl.getMapboxMap().addSource('myspot',{
  21.             'type':'vector',
  22.             'tiles':['http://localhost:5000/tiles/quanguospot/spot/{z}/{x}/{y}']
  23.         });
  24.         gl.getMapboxMap().addLayer({
  25.             'id': 'spot',//随意
  26.             'source': 'myspot',//和上面那个source保持一致
  27.             'source-layer':'spot',//图层名称。就是数据的名称
  28.             'type': 'fill',
  29.              'paint': {
  30.                      "fill-color": "#e6d933",  //读取数据里的properties下的value获取颜色
  31.                      'fill-opacity': 0.25,
  32.                      //"fill-outline-color" :"#e6d933",
  33.                      /*"line-dasharray":[2,4]*/
  34.              },
  35.              "maxzoom": 20,
  36.              "minzoom": 8,
  37.         });
  38.         gl.getMapboxMap().addLayer({
  39.             'id': 'spot_line',//随意
  40.             'source': 'myspot',//和上面那个source保持一致
  41.             'source-layer':'spot',//图层名称。就是数据的名称
  42.             'type': 'line',
  43.              'paint': {
  44.              "line-color": "#e6d933",
  45.              "line-width": 3,
  46.              "line-dasharray": [3,3]
  47.              },
  48.              "maxzoom": 20,
  49.              "minzoom": 8,
  50.         });
  51. });
复制代码
源码放在下面的【GIS之家的学习交流圈】
GIS之家的学习交流圈

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表