本文采用 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/
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)