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>
相关推荐
FRing036 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
秋天的怀念_David6 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
excel6 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放6 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友
用户3721574261357 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java
风骏时光牛马7 小时前
面向复杂场景的大模型应用落地与能力优化实践
前端
小小善后师7 小时前
我做了个病历归档小程序,被 AI 识别的"最后一公里"狠狠上了一课
前端
小嘉丶学长7 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
字节探索7 小时前
Spring Boot 接口幂等性设计:从唯一索引到 Redis+Lua 的工程实践
java·spring boot