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>
相关推荐
想唱rap11 小时前
线程池以及读写问题
服务器·数据库·c++·mysql·ubuntu
码云之上11 小时前
从一个截图函数到一个 npm 包——pdf-snapshot 的诞生记
前端·node.js·github
Mr_Xuhhh12 小时前
从理论到实践:深入理解算法的时间与空间复杂度
java·开发语言·算法
望眼欲穿的程序猿12 小时前
Vscode Clangd 无法索引 C++17 或者以上标准
java·c++·vscode
带刺的坐椅12 小时前
Spring-AI 与 Solon-AI 深度对比分析报告
java·spring·ai·llm·solon·spring-ai·solon-ai
码事漫谈12 小时前
AI提效,到底能强到什么程度?
前端·后端
IT_陈寒12 小时前
React hooks依赖数组这个坑差点把我埋了
前端·人工智能·后端
爱码少年12 小时前
JAVA获取客户端真实IP地址经典写法与Lambda写法对比
java
做个文艺程序员12 小时前
Spring AI + Qwen3.5 实现多步 Agent:从工具调用到自主任务拆解的踩坑全记录
java·人工智能·spring
gentle_ice12 小时前
初入社会的我该何去何从
java