Openlayers+Geoservser(三) vue3使用总结
1.简介
Openlayers 是一个专为Web GIS客户端开发提供的JavaScript 类库包,用于实现标准格式发布的地图数据访问。简单的说就是像百度地图、高德地图一样的前端控件。
GeoServer 是基于 Java 的软件GIS地理信息服务器。我们知道地图这些坐标信息需要存储管理,如果这些信息用数据库存储,还需要专门去写一套后台管理去做增删改出,会浪费很大的精力。使用第三方成熟的服务架构就能为我们后续开发节省很多宝贵时间。
2.背景
一般我们使用Openlayers加载天地图的影像、信息等数据。而剩下一些私有点位、面积、线数据,我们可以存放到Geoserver中。
本次案例使用天地图加载某市影像图、然后加载标注信息(包含城市名称、交通线路等信息)、城市边界和各区边界(结合Geoserver存储边界面积点位信息)
3.下载Geoserver和运行
首先我们要到官网下载一个Geoserver包。运行jar包,然后访问本地端口http://127.0.0.1:8080/Geoserver/
账户密码默认是admin、geoserver
4.发布图层
有3个概念需要理解
工作空间-类似idea中包名,通常把某省、某市一类数据归类在这个工作空间,工作空间和图层有绑定关系
数据仓库,我们把地理信息点位数据存储到数据库中,类似数据仓库就是Geoserver对数据存储的位置
图层,对点位数据转化为对外提供服务能力,转化为(图片、JSON数据等)
创建图层、数据仓库。其中要备注名称信息,中文部分是为了方便我们维护数据时候能够快捷看明白是什么数据,英文名称是前端使用openlayers请求参数。分别为叫标题、数据名称等,需要注意命名规范,以免数据多的时候难以辨认。
4.1工作空间
首先需要创建一个工作空间
工作区是由一个名字和一个名称空间URI(统一资源标识符)定义。URI是类似于URL,除了的URI不必指向Web上的实际位置,并且只需要一个唯一的标识符。对于工作空间的URI,建议使用与项目相关联的URL .
4.2创建数据仓库
首先我们要准备一份城市边界信息shp文件上传到Geoserver并且发布图层,该数据需要各位自行到网上搜索一般都有。https://download.csdn.net/download/T0620514/85786075
①对应工作空间
②数据源名称(英文),起名方式这个最好和添加的数据信息保持一致
③说明(中文备注方便查阅)
④上传shp数据
⑤数据格式,一般选UTF-8,也根据你数据源格式选择,不然返回JSON数据中包含中文信息可能会乱码
4.3发布图层
①就是请求图层参数,这里很重要,使用openlayers加载图层url需要填写相对应信息参数
②中文备注为了便于检索信息
⑥和⑦需要点一下,不然没法发布,强制计算一些参数。
然后点击发布
4.4预览
我们可以在图层预览中看到我们发布的图层信息,Geoserver前端使用openlayer加载数据。
可以看到城市区域边界
4.5小结
数据图层通过Geoserver发布后,我们可以获取图片、JSON数据等多种方式图层信息,Geoserver内置预览是以wms数据形式加载图层信息。
根据加载方式不同有以下几种方式
WMS:一张图片加载
WMTS:切边图片加载
JSON:接口返回数据
5.代码加载
5.1核心代码
接下来使用代码加载图层信息,vue3核心代码(自己注意去掉多余的import)
<div class="map_container">
<div id="map" style="width: 100%;height: 100%;"></div>
</div>
import { reactive, ref ,onMounted ,watch} from 'vue';
import { Map, View,Feature } from "ol";//地图,视图
import TileLayer from "ol/layer/Tile"; //可以理解为图层
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import { Stroke, Style,Text,Fill,Circle } from "ol/style";
import {Point} from "ol/geom";
import Icon from 'ol/style/Icon';
import WMTSTileGrid from "ol/tilegrid/WMTS";
import WMTS from "ol/source/WMTS";
import GeoJSON from "ol/format/GeoJSON"
import { defaults as defaultControls} from 'ol/control'
import Select from "ol/interaction/Select";
import Overlay from 'ol/Overlay'
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile';
import { createXYZ } from "ol/tilegrid";
import MVT from "ol/format/MVT"
import Projection from "ol/proj/Projection"
import Tile from "ol/layer/Tile"
import {
getTopLeft,
getWidth,
} from "ol/extent.js";
import * as olProj from "ol/proj";
function initMap() {
let webKey = "";// TODO 个人天地图密匙
let wmtsUrl_1 = "http://t0.tianditu.gov.cn/img_c/wmts?tk="; // 矢量底图
let wmtsUrl_2 = "http://t0.tianditu.gov.cn/cia_c/wmts?tk="; // 矢量注记
let proj = "EPSG:4326";
let projection = olProj.get(proj);
projection.setExtent([-180, -90, 180, 90]);
let projectionExtent = projection.getExtent();
let size = getWidth(projectionExtent) / 256;
let resolutions = new Array(18);
let matrixIds = new Array(18);
for (let z = 1; z < 19; ++z) {
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = z;
}
// 1.天地图影像图
let baseLayer = new TileLayer({
id: 'map',
title: "天地图",
source: new WMTS({
url : wmtsUrl_1 + webKey,
layer: "img",
matrixSet: "c",
format: "tiles",
style: "default",
projection: projection,
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds,
}),
wrapX: true,
})
});
// 2.标注信息图层
let baseInfoLayer = new TileLayer({
id: "baseInfoLayer",
opacity: 1,
source: new WMTS({
url: wmtsUrl_2 + webKey,
layer: "cia",
matrixSet: "c",
format: "tiles",
style: "default",
projection: projection,
tileGrid: new WMTSTileGrid({
origin: getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds,
}),
wrapX: true,
}),
});
// 3.1 加载XX市边界信息
let vectorSource = new VectorSource({
format: new GeoJSON(),
loader: function (extent, resolution, projection) { //加载函数
let url = 'http://{ //todo Geoserver IP}/Geoserver/{ //todo 工作空间}/ows?service=WFS&' +
'version=1.0.0&request=GetFeature&typename={ //todo 图层名称}&' +
'outputFormat=application/json'
fetch(url, {
method: 'GET',
}).then(function (response) {
return response.json();
}).then(function (json) {
let features = new GeoJSON().readFeatures(json);
if (features.length > 0) {
vectorSource.clear();
vectorSource.addFeatures(features);
}
});
},
projection: 'EPSG:4326'
});
let boundaryLayer = new VectorLayer({
id: "boundaryLayer",
title: 'boundaryLayer',
source : vectorSource,
style: new Style({
stroke: new Stroke({
color: '#00e1ff',
width: 3,
}),
}),
})
myMap.value = new Map({
// 设置地图图层。baseLayer-地图,boundaryLayer-XX市边界线,baseInfoLayer-城市地理基础信息标签
layers: [
baseLayer,boundaryLayer,baseInfoLayer
],
// size: [400,document.body.offsetWidth-500],
// 设置显示地图的视图
view: new View({
projection: "EPSG:4326", //
center: [113.382391, 22.521113],
// 缩放
zoom: 11,
// 最大缩放
maxZoom: 18,
// 最小缩放
minZoom: 1
}),
// 让id为map的div作为地图的容器
target: "map",
// 关闭组件
controls: defaultControls({
zoom: false,
rotate: false,
attribution: false
})
});
showRightDetail.value = false
myMap.value.setSize( [document.body.offsetWidth-500 , document.body.offsetHeight-107])
myMap.value.addLayer(rangelayer);
}
图层名称要对应上
5.2细节代码
其中重点部分需要修改的参数为GEOSERVER-IP、图层名称、工作空间内容替换
// 3.1 加载XX市边界信息
let vectorSource = new VectorSource({
format: new GeoJSON(),
loader: function (extent, resolution, projection) { //加载函数
let url = 'http://{GEOSERVER-IP}/Geoserver/{工作空间}/ows?service=WFS&' +
'version=1.0.0&request=GetFeature&typename={图层名称}&' +
'outputFormat=application/json'
fetch(url, {
method: 'GET',
}).then(function (response) {
return response.json();
}).then(function (json) {
let features = new GeoJSON().readFeatures(json);
if (features.length > 0) {
vectorSource.clear();
vectorSource.addFeatures(features);
}
});
},
projection: 'EPSG:4326'
});
let boundaryLayer = new VectorLayer({
id: "boundaryLayer",
title: 'boundaryLayer',
source : vectorSource,
style: new Style({
stroke: new Stroke({
color: '#00e1ff',
width: 3,
}),
}),
})
实际上城市边界加载使用接口请求加载,返回的JSON数据获取到特征点,加入图层中
let features = new GeoJSON().readFeatures(json);
if (features.length > 0) {
vectorSource.clear();
vectorSource.addFeatures(features);