postgresql实现数据动态地图切片服务

根据鼠标的缩放动态加载渲染服务信息。

代码实现:

1.controller层:

java 复制代码
package com.mxpt.map.controller;

import com.mxpt.map.service.IVectorTilesService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 地图切片服务
 *
 * @author mxpt
 */
@Api(tags = "地图切片服务")
@RestController
@RequestMapping("/vector-tiles")
public class VectorTilesController {
    @Autowired
    IVectorTilesService iVectorTilesService;

    /**
     * 查询工程地图服务
     *
     * @param engrId
     * @param spatialFid
     * @param z
     * @param x
     * @param y
     * @return
     */
    @ApiOperation("查询工程地图服务")
    @GetMapping("/engineering/{engrId}/{spatialFid}/{z}/{x}/{y}")
    public byte[] getEngineeringLayer(@PathVariable Integer engrId, @PathVariable String spatialFid, @PathVariable Integer z, @PathVariable Integer x, @PathVariable Integer y) {
        return iVectorTilesService.getEngineeringLayer(engrId, spatialFid, z, x, y);
    }
}

2.service层:

java 复制代码
package com.mxpt.map.service;

/**
 * 切片服务
 */
public interface IVectorTilesService {

    byte[] getEngineeringLayer(Integer engrId, String spatialFid, Integer z, Integer x, Integer y);
}
java 复制代码
package com.mxpt.map.service.impl;

import com.mxpt.map.domain.vo.VectorTiles;
import com.mxpt.map.mapper.VectorTilesMapper;
import com.mxpt.map.service.IVectorTilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 切片服务服务层
 *
 * @author chen
 */
@Service
public class VectorTilesServiceImpl implements IVectorTilesService {

    @Autowired
    VectorTilesMapper vectorTilesMapper;

    /**
     * 查询工程空间图层服务
     *
     * @param engrId
     * @param spatialFid
     * @param z
     * @param x
     * @param y
     * @return
     */
    @Override
    public byte[] getEngineeringLayer(Integer engrId, String spatialFid, Integer z, Integer x, Integer y) {

        byte[] result = new byte[0];
        switch (spatialFid) {
            case "wata":
                result = getWataLayer(engrId, z, x, y);
                break;
            case "rivl":
                result = getRivlLayer(engrId, z, x, y);
                break;
            case "node":
                result = getNodeLayer(engrId, z, x, y);
                break;
            case "unit":
                result = getUnitLayer(engrId, z, x, y);
                break;
            case "topology":
                result = getTopologyLayer(engrId, z, x, y);
                break;
            case "2dnode":
                result = get2dNodeLayer(engrId, z, x, y);
                break;
            case "2dcell":
                result = get2dCellLayer(engrId, z, x, y);
                break;
            case "2dside":
                result = get2dSideLayer(engrId, z, x, y);
                break;
            //model_engineering_spatial_1driver-一维河道
            case "1driver":
                result = get1driverLayer(engrId, z, x, y);
                break;
            //model_engineering_spatial_1dsections-一维断面
            case "1dsections":
                result = get1dsectionsLayer(engrId, z, x, y);
                break;
            //model_engineering_spatial_bound-范围
            case "bound":
                result = getBoundLayer(engrId, z, x, y);
                break;
            /*******************城市内涝管网相关边界数据的添加************************/
            //1、子汇水区(面):2dsubcatchment
            //model_engineering_spatial_2dsubcatchment
            case "2dsubcatchment":
                result = get2dsubcatchmentLayer(engrId, z, x, y);
                break;
            //2、管道(线):2dlinkline
            //model_engineering_spatial_2dlinkline
            case "2dlinkline":
                result = get2dlinklineLayer(engrId, z, x, y);
                break;
            //3、连接节点(点):2dlinknode
            //model_engineering_spatial_2dlinknode
            case "2dlinknode":
                result = get2dlinknodeLayer(engrId, z, x, y);
                break;
            //4、蓄水节点(点):2dpondednode
            //model_engineering_spatial_2dpondednode
            case "2dpondednode":
                result = get2dpondednodeLayer(engrId, z, x, y);
                break;
            //5、泵站(线):2dpump
            //model_engineering_spatial_2dpump
            case "2dpump":
                result = get2dpumpLayer(engrId, z, x, y);
                break;
            //6、排放口(点):2dtidegate
            //model_engineering_spatial_2dtidegate
            case "2dtidegate":
                result = get2dtidegateLayer(engrId, z, x, y);
                break;
            //7、水厂用户基本信息表:model_engineering_spatial_wfctpl
            case "wfctpl":
                result = getWfctplLayer(engrId, z, x, y);
                break;
            default:
                break;
        }

        return result;
    }

    /**
     * 查询小流域图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] getWataLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getWataLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询2d节点图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] get2dNodeLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dNodeLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询2d单元图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] get2dCellLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dCellLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询2d边元图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] get2dSideLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dSideLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    private byte[] get1driverLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get1driverLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    private byte[] get1dsectionsLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get1dsectionsLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    private byte[] getBoundLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getBoundLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }


    //1、子汇水区(面):2dsubcatchment
    //model_engineering_spatial_2dsubcatchment
    private byte[] get2dsubcatchmentLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dsubcatchmentLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    //2、管道(线):2dlinkline
    //model_engineering_spatial_2dlinkline
    private byte[] get2dlinklineLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dlinklineLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    //3、连接节点(点):2dlinknode
    //model_engineering_spatial_2dlinknode
    private byte[] get2dlinknodeLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dlinknodeLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    //4、蓄水节点(点):2dpondednode
    //model_engineering_spatial_2dpondednode
    private byte[] get2dpondednodeLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dpondednodeLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    //5、泵站(线):2dpump
    //model_engineering_spatial_2dpump
    private byte[] get2dpumpLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dpumpLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    //6、排放口(点):2dtidegate
    //model_engineering_spatial_2dtidegate
    private byte[] get2dtidegateLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.get2dtidegateLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    private byte[] getWfctplLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getWfctplLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询河道图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] getRivlLayer(Integer engrId, Integer z, Integer x, Integer y) {

        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getRivlLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询节点图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] getNodeLayer(Integer engrId, Integer z, Integer x, Integer y) {

        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getNodeLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询计算单元图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] getUnitLayer(Integer engrId, Integer z, Integer x, Integer y) {
        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getUnitLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    /**
     * 查询拓扑图层
     *
     * @param engrId
     * @param z
     * @param x
     * @param y
     * @return
     */
    private byte[] getTopologyLayer(Integer engrId, Integer z, Integer x, Integer y) {

        List<Double> extent = xyz2prj4326BBox(z, x, y);
        VectorTiles vectorTiles = vectorTilesMapper.getTopologyLayer(engrId, extent.get(0), extent.get(1), extent.get(2), extent.get(3));
        return vectorTiles.getMvt();
    }

    public static List<Double> xyz2prj4326BBox(int z, int x, int y) {
        List<Double> bbox = new ArrayList<>();
        double n = Math.pow(2, z);
        double lon_min = (x / n) * 360.0 - 180.0;
        double lat_min = 90.0 - (((y + 1) / n) * 360.0);
        double lon_max = ((x + 1) / n) * 360.0 - 180.0;
        double lat_max = 90.0 - ((y / n) * 360.0);
        bbox.add(lon_min);
        bbox.add(lat_min);
        bbox.add(lon_max);
        bbox.add(lat_max);
        return bbox;
    }
}

3.mybatis

java 复制代码
    <select id="getRivlLayer" resultType="com.mxpt.map.domain.vo.VectorTiles">
        SELECT st_asmvt(filtergeom, 'rivl', 4096, 'geom') AS mvt
        FROM (
                 SELECT st_asmvtgeom(geom, ST_MakeEnvelope(cast(#{lonMin} as double precision),
                                                           cast(#{latMin} as double precision),
                                                           cast(#{lonMax} as double precision),
                                                           cast(#{latMax} as double precision), 4326), 4096, 32,
                                     TRUE) AS geom,
                        rvcd
                 FROM model_engineering_spatial_rivl
                 WHERE geom &amp;&amp; ST_MakeEnvelope ( cast(#{lonMin} as double precision)
                     , cast (#{latMin} as double precision)
                     , cast (#{lonMax} as double precision)
                     , cast (#{latMax} as double precision)
                     , 4326 )
                   AND engr_id = cast (#{engrId} as integer)
             ) AS filtergeom
    </select>
相关推荐
咩咩啃树皮7 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny7 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹7 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
爱写代码的森7 小时前
鸿蒙三方库 | harmony-utils之ImageUtil图片保存到本地详解
服务器·华为·harmonyos·鸿蒙·huawei
阳光是sunny7 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
鱟鲥鳚7 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
小林ixn8 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker8 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜8 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康9 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端