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>
相关推荐
Cosolar2 小时前
LlamaIndex索引类型全解析:原理与实战指南
运维·服务器
小雨下雨的雨4 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
方便面不加香菜5 小时前
Linux--基础IO(一)
linux·运维·服务器
xieliyu.6 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
明夜之约6 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee6 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Jinkxs6 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
辣机小司6 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
ZC跨境爬虫7 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
fangdengfu1237 小时前
ES分析系统各个服务日志占用量
java·前端·elasticsearch