GIS动态矢量切片(MVT——MapBox Vector Tile)

GIS动态矢量切片

前言

有关矢量切片以及MVT(MapBox Vector Tile)自行搜索了解,不再赘述。
接口格式 http://domain:port/map/vector/tile/{z}/{x}/{y},其中z代表缩放层级,x、y代表当前行列号
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

一、方法

采用postgis的函数ST_AsMVTST_AsMVTGeomST_TileEnvelope函数,实现此功能。
简单讲 ST_TileEnvelope 函数用于计算行列并返回对应的矩形范围,ST_AsMVTGeom返回图层中对应行的坐标,ST_AsMVT返回二进制的Mapbox Vector Tile数据。

函数解释

ST_AsMVT:返回一个二进制Mapbox Vector Tile

二、环境

Postresql 12.x + Postgis + Spring Boot

三、实现

MapBoxVectorTile

package com.osgeo.vectortile.domain;


import lombok.Data;

@Data
public class MapBoxVectorTile {
    private byte[] tile;
}

MapBoxVectorTileMapper

package com.osgeo.vectortile.mapper;

import com.baomidou.mybatisplus.annotation.SqlParser;
import com.osgeo.vectortile.domain.MapBoxVectorTile;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface MapBoxVectorTileMapper {
    @SqlParser(filter=true)
    MapBoxVectorTile vectorTitle2(@Param("z") Integer z, @Param("x") Integer x, @Param("y") Integer y, @Param("dpi") Integer dpi);
}

MapBoxVectorTileMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.osgeo.vectortile.mapper.MapBoxVectorTileMapper">

    <resultMap type="com.osgeo.vectortile.domain.MapBoxVectorTile" id="MapBoxVectorTileResult">
        <result property="tile" column="tile"/>
    </resultMap>
    <select id="vectorTitle2" resultMap="MapBoxVectorTileResult">
        SELECT ST_AsMVT(tiletable.*, 'gb_title', #{dpi}) as tile
        FROM (SELECT id,
                     project_name                                                                               as name,
                     approval_year                                                                              as "year",
                     build_address                                                                              as poi,
                     dept_id                                                                                    as dept,
                     ST_AsMVTGeom(geo_rangeline, ST_Transform(ST_TileEnvelope(#{z}, #{x}, #{y}), 4326), #{dpi}) as geom
              from (select *
                    from gbt_project_info
                    where 1 = 1
                      and ST_Intersects(ST_Transform(ST_TileEnvelope(#{z}, #{x}, #{y}), 4326),
                                        geo_rangeline)) ta) as tiletable
        where tiletable.geom is not null;
    </select>
</mapper>

MapBoxVectorTileServiceImpl

package com.osgeo.vectortile.service.impl;

import com.osgeo.vectortile.mapper.MapBoxVectorTileMapper;
import com.osgeo.vectortile.service.MapBoxVectorTileService;
import com.osgeo.vectortile.utils.MapBoxVectorTileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MapBoxVectorTileServiceImpl implements MapBoxVectorTileService {
    @Autowired
    MapBoxVectorTileMapper mapper;

    @Override
    public byte[] vectorTitle(Integer z, Integer x, Integer y) {
        Integer dpi = MapBoxVectorTileUtil.zoom2dpi(z);
        return mapper.vectorTitle2(z, x, y, dpi).getTile();
    }
}

package com.osgeo.vectortile.utils;

import com.osgeo.vectortile.domain.TileBox;

import java.util.HashMap;
import java.util.Map;

public class MapBoxVectorTileUtil {
    private static Map<Integer, Integer> map;

    static {
        map = new HashMap<>();
        map.put(1, 2);
        map.put(2, 2);
        map.put(3, 2);
        map.put(5, 2);
        map.put(6, 2);
        map.put(7, 512);
        map.put(8, 512);
        map.put(9, 1024);
        map.put(10, 1024);
        map.put(11, 1024);
        map.put(12, 1024);
        map.put(13, 2048);
        map.put(14, 2048);
        map.put(15, 4096);
        map.put(16, 4096);
        map.put(17, 4096);
        map.put(18, 4096);
        map.put(19, 4096);
        map.put(20, 4096);
    }

    public static Integer zoom2dpi(Integer z) {
        return map.containsKey(z) ? map.get(z) : 2048;
    }
}

MapBoxVectorTileService

package com.osgeo.vectortile.service;

public interface MapBoxVectorTileService {
    byte[] vectorTitle(Integer z, Integer x, Integer y);
}

MapBoxVectorTileController

package com.osgeo.vectortile.controller;

import com.osgeo.vectortile.service.MapBoxVectorTileService;
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;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

@RestController
@RequestMapping("/map/vector/tile")
public class MapBoxVectorTileController {

    @Autowired
    MapBoxVectorTileService service;
    
    @GetMapping("/new/{z}/{x}/{y}")
    public void vectorTitle2(@PathVariable("z")Integer z, @PathVariable("x") Integer x, @PathVariable("y") Integer y, HttpServletResponse response){
        response.setContentType("application/x-protobuf;type=mapbox-vector;chartset=UTF-8");
        byte[] tile = service.vectorTitle2(z, x, y);
        // 输出文件流
        OutputStream os = null;
        InputStream is = null;
        try {
            is = new ByteArrayInputStream(tile);
            os = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes, 0, len);
            }
            os.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
### 回答1: GDAL(Geospatial Data Abstraction Library)是一个开源库,可用于处理地理空间数据。而Mapbox Vector Tiles(MVT)是一种用于高效渲染和交互式使用的矢量切片格式。下面是关于如何使用GDAL生成Mapbox Vector Tiles矢量切片的简要步骤。 首先,确保你已经安装了GDAL,并且可以在命令行中运行相关命令。 1. 将你的矢量数据转换为PGS(PostGIS)格式,这是一个常用的空间数据库。 例如,可以使用ogr2ogr命令将Shapefile数据转换为PGS格式: ``` ogr2ogr -f PostgreSQL PG:"dbname=your_db user=your_user" your_data.shp ``` 2. 创建一个新的数据库表,用来存储切片数据。 ``` psql -d your_db -U your_user -c "CREATE TABLE your_table AS SELECT * FROM your_data" ``` 3. 利用GDAL的ogr2ogr命令将数据导出为MVT格式。 ``` ogr2ogr -f MVT your_output.mbtiles PG:"dbname=your_db user=your_user" -sql "SELECT * FROM your_table" -dsco FORMAT=MVT ``` 4. 完成上述步骤后,你将得到一个包含Mapbox Vector Tiles的MBTiles文件(your_output.mbtiles),其中包含了你的矢量数据切片。 使用GDAL生成Mapbox Vector Tiles矢量切片的思路是将矢量数据先转换为PGS格式的空间数据库,然后导出为MVT格式。通过这种方式,你可以使用GDAL的强大功能来处理和转换地理空间数据,并方便地生成适用于Mapbox矢量切片。 ### 回答2: GDAL是一个开源的地理数据抽象库,它可以处理和转换各种地理空间数据格式。为了生成Mapbox矢量切片,我们可以使用GDAL的一些工具和功能。 首先,我们需要确保已经安装了GDAL库和相关的依赖项。然后,我们可以使用GDAL的命令行工具或API来执行下面的步骤。 1. 准备数据:将原始矢量数据准备好,可以是常见的矢量数据格式,如Shapefile、GeoJSON或GPKG等。 2. 转换到GeoPackage格式:使用gdal_translate命令将原始数据转换为GeoPackage格式(如果原始数据不是GeoPackage格式)。例如,可以使用以下命令: ```shell gdal_translate -f GPKG input.shp output.gpkg ``` 3. 切片生成:使用gdal2tiles.py或gdal2mbtiles.py命令生成Mapbox矢量切片。这两个命令可以将栅格数据或矢量数据转换为切片。在这种情况下,我们使用gdal2mbtiles.py来生成矢量切片。例如,可以使用以下命令: ```shell gdal2mbtiles.py -l layer_name input.gpkg output.mbtiles ``` 这将生成一个包含矢量切片的MBTiles文件。 4. 导入到Mapbox Studio:将生成的MBTiles文件导入到Mapbox Studio中,以便进一步处理和发布。在Mapbox Studio中,可以编辑样式、添加图层等。 通过以上步骤,我们可以使用GDAL转换和生成Mapbox矢量切片。GDAL提供了很多功能和选项,使得在处理地理空间数据时非常灵活和强大。 ### 回答3: GDAL是一个开源的地理数据抽象库,支持各种格式的地理数据读取、写入和转换。要使用GDAL生成Mapbox Vector Tiles(MVT矢量切片,需要安装GDAL软件包并了解如何使用其命令行工具。 首先,确保安装了最新版本的GDAL库。你可以从GDAL官方网站上下载并安装适合你操作系统的版本。 在安装完成后,使用命令行工具进入你的地理数据存储路径。然后,运行以下命令来生成MVT矢量切片: ``` ogr2ogr -f MVT output_directory input_data.geojson ``` 上述命令中,`output_directory`是你希望生成矢量切片的输出目录,`input_data.geojson`是你的输入地理数据文件的路径。请确保输入数据文件是GeoJSON格式。 运行上述命令后,GDAL会将输入的地理数据文件转换为MVT格式的矢量切片,并将其保存到指定的输出目录中。 需要注意的是,GDAL的`ogr2ogr`工具提供了多种选项和参数,可用于自定义矢量切片的生成过程。你可以查看GDAL的文档以了解更多详细信息,并根据你的需求进行调整。 总结起来,要用GDAL生成Mapbox Vector Tiles矢量切片,需要安装GDAL库并使用`ogr2ogr`命令行工具进行转换操作。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值