java发布矢量瓦片

java发布矢量瓦片,第1张

本文采用 CC BY-SA 4.0 协议 ,转载请注明原始链接: https://blog.wowtools.org/2022/04/28/2022-04-28-mapbox-gl-tutorial-8/

引入springboot和giscat的maven依赖


    giscat-vector-mvt
    org.wowtools
    1.2.0-STABLE

编写Controller,为了节约篇幅,这里把SpringBootApplication也写在同一个类中了

import org.locationtech.jts.geom.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.wowtools.giscat.vector.pojo.Feature;
import org.wowtools.giscat.vector.pojo.FeatureCollection;
import org.wowtools.giscat.vector.pojo.converter.GeoJsonFeatureConverter;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Map;

/**
 * 用springboot起一个web服务演示矢量瓦片的使用
 *
 * @author liuyu
 * @date 2022/4/26
 */
@SpringBootApplication
@RestController()
@RequestMapping("/tile")
@CrossOrigin
public class WebDemo {
    public static void main(String[] args) {
        SpringApplication.run(WebDemo.class, args);
    }

    /**
     * 测试数据,中国省份
     * 数据来源
     * https://datav.aliyun.com/portal/school/atlas/area_selector
     */
    private static final FeatureCollection areaFeatureCollection;//面数据
    private static final FeatureCollection lineFeatureCollection;//线数据
    private static final FeatureCollection pointFeatureCollection;//点数据

    private static final GeometryFactory geometryFactory = new GeometryFactory();


    private static final String vtContentType = "application/octet-stream";

    @RequestMapping("/{z}/{x}/{y}")
    public void getTile(@PathVariable int z, @PathVariable int x, @PathVariable int y, HttpServletResponse response) {
        //构造一个MvtBuilder对象
        MvtBuilder mvtBuilder = new MvtBuilder(z, x, y, geometryFactory);

        //向mvt中添加layer
        MvtLayer layer = mvtBuilder.getOrCreateLayer("省区域");
        //向layer中添加feature
        for (Feature feature : areaFeatureCollection.getFeatures()) {
            //这里简单地从内存中取数据并判断其是否与瓦片有交集,实际运用中可从数据库查询,例如postgis的ST_intersects函数
            if (mvtBuilder.getBbox().envIntersects(feature.getGeometry())) {
                layer.addFeature(feature);
            }
        }

        //如法炮制添加layer
        layer = mvtBuilder.getOrCreateLayer("省边界");
        for (Feature feature : lineFeatureCollection.getFeatures()) {
            if (mvtBuilder.getBbox().envIntersects(feature.getGeometry())) {
                layer.addFeature(feature);
            }
        }

        //如法炮制添加layer
        layer = mvtBuilder.getOrCreateLayer("省会位置");
        for (Feature feature : pointFeatureCollection.getFeatures()) {
            if (mvtBuilder.getBbox().envIntersects(feature.getGeometry())) {
                layer.addFeature(feature);
            }
        }

        //数据添加完毕,转为
        byte[] bytes = mvtBuilder.toBytes();
        exportByte(bytes, vtContentType, response);
    }

    //将bytes写进HttpServletResponse
    private void exportByte(byte[] bytes, String contentType, HttpServletResponse response) {
        response.setContentType(contentType);
        try (OutputStream os = response.getOutputStream()) {
            os.write(bytes);
            os.flush();
        } catch (org.apache.catalina.connector.ClientAbortException e) {
            //地图移动时客户端主动取消, 产生异常"你的主机中的软件中止了一个已建立的连接",无需处理
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

完整的服务端代码在这里
启动后,我们便成功发布了一个矢量瓦片服务http://localhost:8080/tile/{z}/{x}/{y}

新建一个空白地图,然后添加刚才发布的服务为数据源,再添加图层即可:

// 新建一个空白地图
const map = new mapboxgl.Map({
    container: 'map',
    style: {
        "version": 8,
        "sources": {},
        "layers": []
    },
    center: [102.712251, 25.040609],
    zoom: 4
});
map.on('load', function () {
    //添加刚才发布的mvt数据源
    map.addSource('tile', {
        "type": "vector",
        "tiles": [
            'http://localhost:8080/tile/{z}/{x}/{y}'
        ],
        "minZoom": 1,
        "maxZoom": 22
    })
    //添加各图层
    map.addLayer({
        "id": "area-layer",
        "type": "fill",
        "source": "tile",// 上一步添加的数据源id
        "source-layer": "省区域",// source-layer和mvt服务中的图层名对应
        "layout": {"visibility": "visible"},
        "paint": {"fill-color": '#51bbd6', "fill-opacity": 0.3, "fill-outline-color": '#0000ff'}
    })

    map.addLayer({
        "id": "point-layer",
        "source": 'tile',
        "source-layer": "省会位置",
        "type": "circle",
        "paint": {
            "circle-color": "#FF00FF",
            "circle-radius": 5
        }
    });

    map.addLayer({
        "id": "route",
        "type": "line",
        "source": 'tile',
        "source-layer": "省边界",
        "layout": {
            "line-join": "round",
            "line-cap": "round"
        },
        "paint": {
            "line-color": "#FF0000",
            "line-width": 3
        }
    });

    //矢量瓦片图层可以被点击
    map.on('click', 'area-layer', (e) => {
        console.log(e.features[0])
    })
})

完整的前端代码在这里

展现效果如下:

 本文采用 CC BY-SA 4.0 协议 ,转载请注明原始链接: https://blog.wowtools.org/2022/04/28/2022-04-28-mapbox-gl-tutorial-8/

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/797846.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存