基于Vue3和OpenLayers的WebGIS示例程序

筆記參考教程來源于B站UP主znlgis的視頻合集:https://space.bilibili.com/161342702,直播使用的源碼地址:https://github.com/OpenGisToolbox

Demo合集分為5大部分,分別是:基礎環境搭建、項目搭建、GeoServer Rest API引入、OpenLayers API簡介、圖層樹組織,這個教程合集主要是使用了前端內容,后端內容涉及較少。

該Demo功能需求為:基于GeoServer REST API,以地圖展示和服務管理為核心,實現一張圖的原型/示范,主要是實現地圖展示(樹狀展示各種地圖服務,并以地圖形式展示)和服務管理(樹狀管理地圖服務,包括添加、刪除、修改、查看等基礎操作)。該合集需要掌握的基礎內容包括:HTML+CSS+JS基礎、DOM基礎、VUE3基礎、Element Plus和OpenLayers、VUE3-OpenLayers等前端框架基礎。

1 基礎環境搭建

為了解決跨域問題,可以修改GeoServer配置或通過Nginx配置,UP主znlgis介紹了使用主流的Nginx。我在之前的學習筆記中,記錄了如何在Ubuntu中安裝配置GeoServer、Nginx、Postgis等,這里使用Docker Desktop直接在windows中安裝。

1.1 Docker安裝PostGIS、GeoServer、Nginx

使用Docker Desktop安裝PostGIS、GeoServer、Nginx,可以通過Docker Desktop直接進行可視化操作,拉取后運行。

當然,安裝PostGIS也可以參考官網等:https://hub.docker.com/r/postgis/postgis,使用如下代碼:

# 安裝Postgis,拉取鏡像
docker pull postgis/postgis
# 運行容器
docker run --name postgis \#容器名稱-e POSTGRES_USER=postgres \# 數據庫用戶名-e POSTGRES_PASSWORD=postgres \#密碼-e POSTGRES_DB=mydatabase \#創建的數據庫-p 5432:5432 \#端口-v D:/Programs/DockerData/PostGIS:/var/lib/postgresql/data \#持久化數據,掛載到本地D:/Programs/DockerData/PostGIS文件夾-d postgis/postgis:latest#使用 postgis/postgis 鏡像的最新版本(latest 標簽)以后臺模式(-d)運行容器

安裝GeoServer如下,結合znlgis視頻與參考網址:https://docs.geoserver.org/latest/en/user/installation/docker.html,此外,在GeoServer安裝過程中設置了容器間訪問,安裝完成后訪問地址:http://localhost:8765/geoserver,確保能正確使用。

#拉取鏡像,我這里拉取的穩定版本,不是最新版本
docker pull docke:r.osgeo.org/geoserver:2.26.x
#首次運行,初始化了默認的樣例數據
docker run -p 8765:8080 --name geoserver\#由于端口沖突,修改了端口--link postgis:postgis \#將 GeoServer 容器鏈接到名為 postgis 的 PostGIS 容器-e SAMPLE_DATA=true \#啟用示例數據-e GEOSERVER_ADMIN_PASSWORD=geoserver \# GeoServer 管理員密碼-e GEOSERVER_DATA_DIR=/opt/geoserver_data/data_dir \#環境變量,GeoServer 數據目錄-e GEOWEBCACHE_CACHE_DIR=/opt/geoserver_data/data_dir/gwc \#環境變量,GeoWebCache 緩存目錄-v D:/Programs/DockerData/geoserver:/opt/geoserver_data \#持久化 GeoServer 數據-v D:/Programs/DockerData/geoserver/data_dir/gwc:/opt/geoserver_data/data_dir/gwc \#持久化 GeoWebCache 緩存數據-d docker.osgeo.org/geoserver:2.26.x #在后臺運行容器,使用 GeoServer 的 2.26.x 版本鏡像# 非首次運行,不用再啟用樣例數據
docker run --name geoserver -p 8765:8080 --link postgis:postgis -e GEOSERVER_ADMIN_PASSWORD=geoserver -e GEOSERVER_DATA_DIR=/opt/geoserver_data/data_dir -e GEOWEBCACHE_CACHE_DIR=/opt/geoserver_data/data_dir/gwc -v D:/Programs/DockerData/geoserver:/opt/geoserver_data -v D:/Programs/DockerData/geoserver/data_dir/gwc:/opt/geoserver_data/gwc -d docker.osgeo.org/geoserver:2.26.x

docker安裝Nginx代碼如下,首先拉取鏡像;然后查看默認的 Nginx 配置文件內容,在要掛載的路徑下,新建一個nginx.conf文件,并將輸出的內容復制到該文件中;然后啟動 Nginx 容器、掛載配置文件;在后續再修改配置文件。

#拉取鏡像
docker pull nginx#查看默認的 Nginx 配置文件,--rm表示容器退出后自動刪除,--entrypoint=cat指定容器啟動時運行cat命令查看文件內容,使用 Nginx 鏡像,查看特定文件路徑。這個命令運行輸出nginx.conf文件的內容。
docker run --rm --entrypoint=cat nginx /etc/nginx/nginx.conf#啟動 Nginx 容器、掛載配置文件,這里的:ro表示以只讀模式掛載,
docker run --name nginx -v D:/Programs/DockerData/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -p 8080:80 -d nginx

此外,還需要安裝vue、nvm和node.js,在先前其他內容的學習中已經做過相關的分享筆記,就不再贅述。

1.2 實驗數據

原教程使用的樣例數據來源于網站:https://www.poi86.com/,該網站數據存在一定的錯誤/誤差,但完全可以用來搭建一個Demo;也可以使用其他數據。我這里下載了北京市水系數據,首先將該數據使用PostGIS導入數據庫,然后使用QGIS生成了一個geoserver能夠使用的樣式文件,最后將postgis數據庫連接到geoserver,設置樣式并預覽。

(1)postgis導入數據

我這里下載的北京市水系數據,將數據導入postgis數據庫。由于使用的docker安裝的postgis,可以先查看容器列表:docker ps,接著進入某個docker容器,這里進入的postgis容器:docker exec -it postgis /bin/bash,這里的exec表示在運行的容器中執行的命令;-it表示使用交互模式執行命令,并為容器分配偽終端;postgis表示要進入的容器名稱;/bin/bash表示在容器中啟動bash

由于導入數據需要使用GDAL包,首先查看GDAL是否安裝:ogrinfo --versiongdalinfo --version,如果容器中沒有GDAL,先安裝GDAL。

# 由于沒有安裝sudo命令,所以在代碼前面沒有加上sudo獲取管理員權限
apt-get update
apt-get install -y gdal-bin
# gdal-bin 是GDAL的二進制文件包,這里使用參數-y表示在安裝過程中自動確認所有提示,避免手動輸入確認信息。

接下來將北京水系的geojson文件拷貝到容器中,這里的docker cp用于在宿主機和容器之間復制文件或目錄。我這里直接使用 Windows 風格的路徑,按照網上的教程等,建議使用WSL路徑或者PowerShell風格路徑,WSL路徑就是將D:/改為/mnt/d/,PowerShell風格是在本地路徑上加引號。以下代碼將本地路徑D:/Programs/DockerData/PostGIS/Data/下的文件復制到容器的/opt/文件夾下。

docker cp D:/Programs/DockerData/PostGIS/Data/BeijingWater.geojson postgis:/opt/BeijingWater.geojson

最后使用GDAL的**ogr2ogr**函數將文件導入數據庫,這里雖然寫的是postgresql數據庫,其實是postgis拓展;引號中的內容為PG數據庫的連接信息,指定服務器地址、用戶名、數據庫名稱、密碼。

#進入容器
docker exec -it postgis bash
#使用ogr2ogr函數
ogr2ogr -f PostgreSQL PG:"host=localhost user=postgres dbname=mydatabase password=postgres" /opt/BeijingWater.geojson
# 查看是否已經導入,先切換到 postgres 用戶,再查看數據庫中的表
su - postgres
psql
# 查看所有的數據庫 \l
#切換到特定數據庫 
\c mydatabase
# 查看所有的表
\dt

這里的110000便是加載到數據庫的文件,該文件在網站下載時的名稱為110000.geojson,我重命名為BeijingWater.geojson,但是導入后名稱仍為110000。我這里在數據庫中將表重命名:ALTER TABLE "110000" RENAME TO BeijingWater;

(2)QGIS生成樣式文件

打開QGIS,導入GeoJson文件,隨意設置一個自己喜歡的樣式,將樣式導出為SLD文件格式。

(3)數據導入GeoServer

盡管在創建過程中,使用--link 在容器之間建立了網絡連接,使得 GeoServer 容器可以通過主機名訪問 PostGIS 容器,但不會自動配置 GeoServer 來使用 PostGIS 數據庫。因此,還需要手動配置 GeoServer 使用 PostGIS 數據庫。首先創建新的工作空間,設置工作空間的相關信息、啟用相關的服務服務并保存。

新建存儲倉庫,矢量數據源選擇PostGIS,然后編輯存儲倉庫的基本信息、連接參數,需要注意的是這里的host填寫容器名,而不是localhost

點擊數據->樣式,添加使用QGIS創建的樣式,驗證無誤后保存。

發布新導入的圖層,編輯圖層基本信息、設置投影、設置邊框、設置發布的樣式等。這里由于編碼原因等,沒有正確顯示中文的樣式標注名稱。

如果遇到樣式文件(SLD)的中文標注沒有正確顯示,通常是由于字符編碼或字體配置不正確導致的。我這里使用的UTF-8編碼,應該是無誤的;問題應該是出在字體,應該需要給Docker容器中的GeoServer添加中文字體。但是我沒有修改,感覺使用Docker安裝的geoserver存在問題,服務器狀態中顯示可用字體26個,但是查看可用字體時彈出:哎呀出錯了,抱歉,服務器上發生了意想不到的事情;我在Ubuntu系統中安裝的geoserver有519種字體,因此可能JVM可用字體是與安裝環境有關。等以后需要設置字體或有時間,我再來解決一下這個問題。

最后預覽圖層,無誤即可。

2 項目搭建

原視頻教程使用的vue.js、webpack、vue-cli等搭建的項目,我在這里直接使用的vite搭建的項目。

項目搭建第一步是創建vue項目,首先使用PowerShell導航到項目路徑,然后創建項目,設置相關信息;安裝相關依賴,最后啟用項目查看。

# cd到路徑
cd D:\WebLearn
# 搭建項目
npm create vue@latest
#執行如下命令
cd znlgis_dome
npm install #安裝項目依賴
npm run format#格式檢查,格式化代碼,可以不運行
npm run dev#啟動項目#安裝項目依賴前可以先查看鏡像
npm config get registry
#淘寶鏡像
npm config set registry https://registry.npmmirror.com/

項目中主要使用其他框架包括 element-plus、vue3-openlayers。我們可以將element-plus、vue3-openlayers等進行全局安裝,也可以在某個項目中單獨安裝,我沒有全局安裝。

# 全局安裝,直接在powershell中運行代碼
npm install -g element-plus
# 項目中安裝
npm install element-plus

這里還需要安裝vue3-openlayershttps://vue3openlayers.netlify.app/,該庫提供了大量的組件,例如 ol-mapol-viewol-tile-layer 等。其中,ol-map 是所有其他組件的主要容器。

# 項目中安裝 vue3-openlayers 及依賴
npm i ol ol-ext ol-contextmenu
npm i vue3-openlayers 
# 安裝完成后,可以使用npm list查看驗證

在官網提供了一個在線預覽:https://vue3openlayers.netlify.app/playground.html,我們也可以直接參考在線預覽提供的代碼。

此外,還需要安裝axios用于 發送 HTTP 請求,安裝 Base64 編碼和解碼。

npm install axiosnpm install base-64
#TS需要執行如下
npm i --save-dev @types/base-64

項目搭建的第二步是初始化一些頁面,設置一些相關內容,作為一個簡單的示例。視頻教程使用的JS,我這里使用的TS,可能一些具體的細節與視頻教程存在差異。首先在main.js或main.ts文件中引入所需要的組件,原視頻教程添加如下代碼:

import { Map, Layers, Sources } from 'vue3-openlayers'app.use(Map)
app.use(Layers)
app.use(Sources)

原教程提供的源碼參考中使用了如下代碼:

import OpenLayersMap from 'vue3-openlayers'app.use(OpenLayersMap)

src/components文件夾下新建組件OLMap.vue,參考視頻教程與在線預覽提供的代碼, loadTilesWhileAnimatingloadTilesWhileInteracting 是 OpenLayers 的 ol/View 組件的兩個屬性,用于控制地圖瓦片的加載行為,可以顯著在地圖動畫或用戶交互時 提升交互體驗。

<template><ol-map:loadTilesWhileAnimating="true":loadTilesWhileInteracting="true"style="width: 100%; height: 100%; position: fixed"><ol-viewref="view":center="center":rotation="rotation":zoom="zoom":projection="projection"/><ol-tile-layer><!--加載發布的服務 --><ol-source-tile-wmsurl="http://localhost:8765/geoserver/PostGIS/wms?service=WMS&version=1.1.0&request=GetMap&layers=PostGIS%3Abeijingwater&bbox=115.47742462158203%2C39.44697189331055%2C117.440673828125%2C40.9804801940918&width=768&height=599&srs=EPSG%3A4326&styles=&format=application/openlayers"layer="PostGIS:beijingwater"serverType="geoserver"/></ol-tile-layer></ol-map>
</template><script setup lang="ts">
import { ref } from 'vue'const center = ref([116.37, 40.26])
const projection = ref('EPSG:4326')
const zoom = ref(9)
const rotation = ref(0)</script>

最后修改根組件:

<script setup lang="ts">
import OLMap from './components/OLMap.vue'
</script><template><OLMap />
</template><style scoped></style>

3 GeoServer REST API

GeoServer REST API 簡介

GeoServer官方用戶手冊提供了 REST API 的相關介紹:https://docs.geoserver.org/stable/en/user/rest/index.html#rest。官方文檔指出 REST 是 使用的 Swagger 2.0 ,這里我先去了解了一下什么是Swaggerhttps://swagger.org.cn/docs/specification/2-0/what-is-swagger/,簡單來說 Swagger就是一個API文檔生成工具,用于描述、生成、展示和測試 RESTful Web 服務的規范。

那么什么是RESTful Web 服務呢?這里我詢問了一下常用的AI工具,得到了如下答復:

RESTful Web 服務是一種基于 REST(Representational State Transfer,表述性狀態轉移) 架構原則設計的 Web 服務。REST 是一種軟件架構風格,通常用于構建分布式網絡應用和服務;它通過 HTTP 協議提供簡潔、可擴展和易于理解的 API。在 RESTful Web 服務中,每個資源都有一個唯一的 URI(統一資源標識符),并且通過標準的 HTTP 方法(如 GET、POST、PUT、DELETE)來執行獲取、創建、更新、刪除操作。

而這里的API(Application Programming Interface,應用程序接口) 是一種允許不同程序之間進行通信的接口;它定義了程序之間如何交互,包括請求和響應的格式、數據類型、操作方法等。API 的類型多種多樣,包括 Web API、庫和框架 API、操作系統 API、遠程過程調用(RPC)API、WebSocket API 和數據庫 API 等。Web API 是一種通過 HTTP 協議在網絡上提供服務的 API,其中 RESTful API 是最常見的一種。

為了更好的理解,可以用生活中的例子理解 RESTful Web 服務API。在餐廳中,API就是店小二或者中間人,將前端點菜信息等傳達到后端廚房,再將后端廚房生產的食物等送到前端餐廳的用戶手中; RESTful Web 服務就是智能餐廳的點單系統,我們不用找某個具體的服務員,直接掃桌子上的二維碼發送請求等, RESTful Web 服務就像是一個智能虛擬服務員,接收請求后,并通過標準的 HTTP 方法(比如 GET、POST)與后端(廚房)進行通信,廚房也可以通過該系統將食物已做好等信息發送給顧客。

理解了什么是 RESTful Web服務和API之后,就很容易理解 GeoServer REST API了。簡單來說:GeoServer REST API 是 GeoServer 提供的一個 RESTful 接口,允許客戶端通過簡單的 HTTP 調用檢索有關 GeoServer 實例的信息并進行配置更改,支持通過 HTTP 的 GET 方法讀取信息,以及通過 PUT、POSTDELETE 方法進行寫入操作。

如下圖所示(截圖不全,詳情見:https://docs.geoserver.org/stable/en/user/rest/index.html#rest),API有不少端點,常用的幾個包括:工作區(Workspaces)用來管理 GeoServer 中的工作區;數據存儲(Datastores)用來配置和管理數據存儲;圖層(Layers)用來創建、更新和刪除圖層;樣式(Styles)用來上傳和管理樣式文件;服務設置(Services Settings)用來配置 WMS、WFS、WCS 和 WMTS 等服務;安全設置(Security)用來管理用戶、用戶組和角色。

內容為瀏覽器機翻

我們還可以查看原始的REST配置API參考部分:https://docs.geoserver.org/stable/en/user/rest/api/index.html#rest-api,這里提供了API 詳細信息、全局設置等內容。在API詳細信息中,介紹了常見的狀態代碼以及他們的含義、文件格式的表示。

瀏覽器翻譯

瀏覽器翻譯

官方手冊中也提供了一些應用案例、端口可以控制的圖層格式等信息。

使用Apifox快速生成與GeoServer REST API交互的JavaScript代碼

GeoServer REST API 不是特別標準,因此一些API管理工具可能無法引入,UP主znlgis使用了Apifox。Apifox是一款集API文檔管理、接口調試、Mock服務、自動化測試等功能于一體的API管理平臺,旨在為開發者和測試人員提供高效的一站式解決方案;融合了Postman、Swagger、Mock、JMeter等工具的優勢,能夠極大地提升團隊協作和API開發的效率;該軟件從官網免費下載即可,下載安裝后,打開軟件,導入數據。

Layers為例,復制鏈接。

粘貼鏈接到Apifox,點擊繼續。

彈出導入預覽界面,點擊確定導入。

接口導入成功:

接下來可以使用Apifox對具體的接口生成JavaScript代碼片段,作為參考。

這里生成的代碼片段僅作為參考,后續還需要根據生成的代碼片段,修改、編寫為一個完整的JavaScript文件。

解決跨域問題

解決跨域問題,可以修改GeoServer配置文件、使用Nginx、前端在vue.config.js中配置代理等方法,原視頻中在前面Docker安裝了Nginx但其實并沒有使用,而是前端代理解決了跨域問題。我使用的TS,因此修改vue.config.ts文件,代碼如下所示:

import { defineConfig } from 'vite' 定義Vite配置
import vue from '@vitejs/plugin-vue' 導入VUE插件以支持Vue.js開發
import base64 from 'base-64' 使用base64編碼便于在http請求中使用Basic認證const AUTH = { user: 'admin', pass: 'geoserver' } 定義對象包括用戶名和密碼
const AUTH_BASE64 = base64.encode(`${AUTH.user}:${AUTH.pass}`)拼接用戶名和編碼,并使用Base64編碼export default defineConfig({plugins: [vue()], 配置Vite插件,使用的VUE插件server: { 配置開發服務器相關設置proxy: {定義代理,用于將前端開發服務器的請求轉發到GeoServer REST API'/geoserver': {首先定義代理的路徑前綴,當請求路徑/geoserver開頭時觸發代理target: 'http://127.0.0.1:8766/geoserver',代理的目標地址,我一開始用的8765端口,后來換了9866127.0.0.1表示本地服務器headers: {代理請求添加自定義的 HTTP 頭部'Content-Type': 'application/json',設置請求的 Content-Type 為 application/jsonAccept: 'application/json',設置請求的 Accept 為 application/json,接收 JSON 格式的響應Authorization: `Basic ${AUTH_BASE64}`, 設置請求的Authorization頭部,使用定義的AUTH_BASE64進行Basic認證},changeOrigin: true, 允許跨域請求時改變請求的源rewrite: (path) => path.replace(/^\/geoserver/, ''),定義一個函數重寫請求路徑,將路徑中的 /geoserver 前綴移除,以便正確轉發到 GeoServer REST API},},},
})

上述配置信息中,配置了插件、代理規則等解決跨域問題、處理認證信息,將前端服務器的請求轉到GeoServer REST API,代理的路徑前綴是 /geoserver,當請求路徑以 /geoserver 開頭時,會觸發代理;代理的目標地址是 http://127.0.0.1:8766/geoserver,這是 GeoServer REST API 地址;使用了 base-64 庫對用戶名和密碼進行 Base64 編碼。

封裝REST API相關接口的調用

教程中主要封裝了about、Layers、LayersGroups 相關接口,參考Apifox提供的代碼片段定義了兩個類:About和Layers。我個人感覺Apifox提供的代碼貌似看不看都行,學習就是比著葫蘆畫瓢的過程,直接先把znlgis的代碼搞懂,后續再遇到就比著葫蘆畫瓢唄。原教程中主要是調用了GET相關的接口,原教程提供的Layers.js文件內容如下:

import axios from "axios";  使用 axios 庫來發送 HTTP 請求 定義Layers類
export default class Layers {異步方法,使用axios.get發送GET請求到GeoServer REST APIasync getLayers() { try-catch塊捕捉錯誤,請求成功返回響應數據;否則打印錯誤信息try {const response = await axios.get('/geoserver/rest/layers');if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}};async getLayerGroups() {try {const response = await axios.get(`/geoserver/rest/layergroups`);if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}};我使用的TS,所以直接將圖層組名稱顯式定義為了字符串layerGroupName: stringasync getLayerGroup(layerGroupName) {try {const response = await axios.get(`/geoserver/rest/layergroups/${layerGroupName}`);if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}};
}

上述代碼定義了3個異步方法,用于從 GeoServer 的 REST API 獲取圖層和圖層組的信息,分別用于獲取圖層信息、獲取圖層組信息、根據圖層組名稱獲取特定圖層組詳細信息。在代碼中,原教程使用的console.err 而不是 console.error,但是我在網上搜console.err 并不是 JavaScript 的正確方法,可能是作者搞錯了。

About.js文件內容如下所示,定義了4個函數來獲取GeoServer 的清單信息、狀態信息、系統狀態信息、版本號信息。

import axios from "axios";export default class About {async getManifest() {try {const response = await axios.get('/geoserver/rest/about/manifest');if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}}async getStatus() {try {const response = await axios.get('/geoserver/rest/about/status');if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}};async getSystemStatus() {try {const response = await axios.get('/geoserver/rest/about/system-status');if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}};async getVersion() {try {const response = await axios.get('/geoserver/rest/about/version');if (response.status === 200) {return response.data;} else {console.err(JSON.stringify(response));}} catch (error) {console.err(error);throw error;}};
}

此外,定義了一個名為 GeoServerRestApi 的類,它封裝了對 GeoServer REST API 的訪問,通過組合 AboutLayers 類來提供對 GeoServer 的基本信息和圖層管理功能的訪問,GeoServerRestApi.js代碼如下:

import About from './About.js'
import Layers from "./Layers.js";export default class GeoServerRestApi {/*** Represents information about the GeoServer.* @type {any}*/about;/*** Represents the layers in the GeoServer.* @type {any}*/layers;在構造函數中分別創建About和Layers的實例constructor() {this.about = new About();this.layers = new Layers();}
}

4 OpenLayers簡介

這一部分文本內容主要來源于UP主 znlgis 視頻與其Github分享https://github.com/OpenGisToolbox,我們可以結合OpenLayers官網(https://openlayers.org/)及官網相關文檔(https://openlayers.org/en/latest/apidoc/)來進行理解。

下面是UP主 znlgis 提供的openlayers基礎知識簡介內容:

地圖(Map)

OpenLayers 的核心部件是 Map(ol.Map)。它被呈現到對象 target 容器(例如,網頁上的 div 元素)。所有地圖的屬性可以在構造時進行配置。ol/Map 類是 OpenLayers API 中的核心組件之一,它負責創建和管理整個地圖實例。

視圖(View)

ol.View 負責地圖的中心點,放大,投影之類的設置。一個 ol.View 實例包含投影 projection,該投影決定中心 center 的坐標系以及分辨率的單位,如果沒有指定,默認的投影是球墨卡托(EPSG:3857),以米為地圖單位。 放大 zoom 選項是一種方便的方式來指定地圖的分辨率,可用的縮放級別由 maxZoom(默認值為 28)、zoomFactor(默認值為 2)、maxResolution(默認由投影在 256×256 像素瓦片的有效程度來計算)決定。起始縮放級別 0,以每像素 maxResolution 的單位為分辨率,后續的縮放級別是通過 zoomFactor 區分之前的縮放級別的分辨率來計算的,直到縮放級別達到 maxZoom。

圖層(Layer)

一個圖層是資源中數據的可視化顯示,OpenLayers 包含幾種基本圖層類型,在實際中多使用第一個與第三個。

  • ol.layer.Tile 用于顯示瓦片資源,這些瓦片提供了預渲染,并且由特定分辨率的縮放級別組織的瓦片圖片網格組成。
  • ol.layer.Image 用于顯示支持渲染服務的圖片,這些圖片可用于任意范圍和分辨率。
  • ol.layer.Vector 用于顯示在客戶端渲染的矢量數據。
  • ol.layer.VectorTile 用于顯示在客戶端渲染的矢量瓦片數據。
  • ol.layer.WebGLTile 用于提供預渲染、平鋪的瓦片圖像,按特定分辨率的縮放級別組織。

數據源(Source)

OpenLayers 使用 ol.source.Source 子類獲取遠程數據圖層,包含免費的和商業的地圖瓦片服務,如 OpenStreetMap、Bing、OGC 資源(WMS 與 WMTS)、矢量數據(GeoJSON 格式、 KML 格式…)等。當資源(source)與地圖視圖(view)的坐標系相同時,無需再次設置投影projection(默認與view坐標系一致),只有在資源與視圖的投影不同的情況下,才需要在資源中明確指定 projection 屬性來表示要素緩存的投影。

CSDN @Dawn_www

控件(Control)

控件是一個可見的小部件,其 DOM 元素位于屏幕上的固定位置。 它們可以涉及用戶輸入(按鈕),或者僅提供信息; 位置是使用 CSS 確定的。 默認情況下,它們放置在 CSS 類名為 ol-overlay container-stop event 的容器中,但可以使用任何外部 DOM 元素。在Openlayers中多數Controls直接可以在地圖上添加,比如 Navigation(導航欄)。第二類是需要放在Div元素中才能用。第三類需要放置在panel(面板)中的操作類似于網頁HTML中button按鈕,需要點擊或綁定才能起作用。最后一類就是自定義類型的。

交互(Interaction)

Interaction是用來控制地圖的,和控件一樣的作用。不過它們的區別是控件觸發都是一些可見的 HTML元素觸發,如按鈕、鏈接等,而交互功能不可見的,如鼠標雙擊、滾輪滑動,手機設備的手指縮放等。

幾何(Geoms)

OpenLayers中的Geoms實際上指的是Geometry(幾何對象),它是地圖要素(Features)的核心部分,表示了空間數據的具體形狀和位置。在OpenLayers中并沒有直接名為Geoms的模塊或類,而是通過ol/geom模塊提供了一系列幾何類型,如點(Point)、線(LineString)、多邊形(Polygon)、多點集合(MultiPoint)、多線串(MultiLineString)、多邊形集合(MultiPolygon)等。幾何對象不僅用于構造要素,還可以用于各種空間分析和交互操作,如計算面積、長度、進行交集、緩沖區分析等。同時,它們也是OpenLayers中渲染的基礎數據結構。

覆蓋物(Overlay)

Overlay這個組件在Openlayers 項目中是經常要用到的,使用的場景通常是作為彈窗,顯示某點或者某區域的信息。它不是根據屏幕位置固定的,而是與地理坐標相關聯,因此平移地圖將移動 Overlay。常用的大致有三類,彈窗、標注、文本信息。每個覆蓋物都會生成對應的HTML元素,所以我們也可以使用css來修改去樣式。一個覆蓋物最少需要一個元素,當數據量大時,元素節點過多會導致頁面加載卡頓,不流暢。大數據量的繪制圖還是使用圖層最好。

樣式(Style)

OpenLayers 提供了一種強大且靈活的方式來自定義地圖上的矢量要素(如點、線、面)的樣式,這些樣式是通過 ol/style 模塊中的 ol.style.Style 類和其他相關子類(如 ol.style.Icon、ol.style.Stroke、ol.style.Fill、ol.style.Text 等)來實現的。

格式(Formats)

OpenLayers中的Formats主要用于處理地理空間數據的讀寫和解析,它包含了多種格式支持,比如WKT(Well-Known Text)、GeoJSON、KML、GML等。這些格式類允許開發者在客戶端將地圖要素轉換為特定格式的字符串或者從字符串反序列化為地圖要素。

第三方插件

OpennLayers也提供了第三方插件來拓展OpenLayers,網址為:https://openlayers.org/3rd-party/。在第三方插件中提供了vue3-openlayers,使用vue3-openlayers 還需要引入 ol、ol-ext、ol-contextmenu

ol-ext 是 OpenLayers 的擴展庫,提供了額外的功能和控件,用于增強 OpenLayers 的功能,例如一些高級的地圖操作工具、額外的圖層類型支持等;ol-contextmenu 是一個為 OpenLayers 設計的右鍵菜單插件,允許開發者為地圖添加自定義的右鍵菜單功能,提供了 openclosebeforeopen 等事件,開發者可以在這些事件中實現自定義邏輯。

5 圖層樹組織

Up主znlgis原教程提供的代碼比較簡單,僅僅包含了一個子組件DomeMap.vue,原教程提供的代碼如下所示:

<template><Map.OlMap id="map" ref="mapRef" :controls="[]"><Map.OlViewref="view":center="center":projection="projection":zoom="zoom"/><Layers.OlLayerGroup v-for="group in dynamicLayerGroupList" :key="group.name" :title="group.name":visible="group.visible"><Layers.OlTileLayer v-for="layer in group.layers" :key="layer.name" :title="layer.name" :visible="layer.visible"><Sources.OlSourceTileWms :layers="layer.name" :url="layer.url"/></Layers.OlTileLayer></Layers.OlLayerGroup><Layers.OlTileLayer v-for="layer in dynamicLayerList" :key="layer.name" :title="layer.name":visible="layer.visible"><Sources.OlSourceTileWms :layers="layer.name" :url="layer.url"/></Layers.OlTileLayer><MapControls.OlLayerswitcherControl :collapsed="false"/><MapControls.OlZoomControl/><MapControls.OlContextMenuControl/><MapControls.OlScalelineControl/></Map.OlMap>
</template><script lang="ts" setup>
import {onMounted, ref} from "vue";
import type MapRef from "ol/Map";
import {Layers, Map, MapControls, Sources} from "vue3-openlayers";
import GeoServerRestApi from '../geoserver/GeoServerRestApi';const center = ref([40, 40]);
const projection = ref("EPSG:4326");
const zoom = ref(0);
const dynamicLayerList = ref([]);
const dynamicLayerGroupList = ref([]);
const mapRef = ref<MapRef | null>(null);onMounted(async () => {try {let geoServerRestApi = new GeoServerRestApi();let layers = await geoServerRestApi.layers.getLayers();let layerList = layers.layers.layer;layerList.forEach((layer: any) => {let layerName = layer.name;if (layerName === 'ne:countries') {dynamicLayerList.value.push({name: layerName,url: `/geoserver/wms`,visible: true,});} else {dynamicLayerList.value.push({name: layerName,url: `/geoserver/wms`,visible: false,});}});let groups = await geoServerRestApi.layers.getLayerGroups();for (let group of groups.layerGroups.layerGroup) {let groupName = group.name;let groupLayers = await geoServerRestApi.layers.getLayerGroup(groupName);let layerGroups = {name: groupName,layers: [],visible: false,};groupLayers.layerGroup.publishables.published.forEach((layer: any) => {if (layer["@type"] !== "layer") return;layerGroups.layers.push({name: layer.name,url: `/geoserver/wms`,visible: false,});});dynamicLayerGroupList.value.push(layerGroups);}} catch (error) {console.error("Failed to load layers:", error);}
});
</script><style scoped>
#map {width: 100%;height: 100%;position: absolute;top: 0;left: 0;
}
</style>

代碼中使用了let聲明變量,但是這些變量都沒有被重新復制,因此我們也可以將let修改為constlet:聲明一個變量后,允許變量的值被重新賦值;const:聲明一個常量,一旦賦值后,其值不能被重新賦值)。在VS Code中可以使用快捷鍵Ctrl+D多光標選擇,一次將let改為const。

需要注意的是,由于GeoServer國家樣例數據是錯誤的,因此我將上述代碼中默認加載的圖層ne:countries修改為了ne:populated_places。最后修改App.vue

<script setup>
import DemoMap from './components/DemoMap.vue'
</script><template><DemoMap/>
</template>

啟動項目,結果圖如下所示,可以看到加載出了點坐標數據。我這里手動將PostGIS工作空間中的數據移動到了最前面,并打開了圖層,可以看到北京水系也被加載到了頁面中;頁面右側的圖層列表就是圖層樹組織

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77753.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77753.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77753.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UBUS 通信接口的使用——添加一個object對象(ubus call)

1&#xff0c;引入 ubus提供了一種多進程通信的機制。存在一個守護進程ubusd&#xff0c;所以進程都注冊到ubusd&#xff0c;ubusd進行消息的接收、分發管理。 ubus對多線程支持的不好&#xff0c;例如在多個線程中去請求同一個服務&#xff0c;就有可能出現不可預知的結果。 …

【Python魔法方法(特殊方法)】

在 Python 中&#xff0c;許多運算符都可以進行重載&#xff0c;以下是一些常見運算符及其對應的魔法方法&#xff08;特殊方法&#xff09;&#xff1a; 算術運算符 加法 &#xff1a;__add__ 用于定義對象相加的行為。例如&#xff0c;當你對兩個自定義類的實例使用 運算符…

(三十二)Android開發中AppCompatActivity和Activity之間的詳細區別

在 Android 開發中&#xff0c;AppCompatActivity 和 Activity 是兩個核心類&#xff0c;用于創建和管理應用程序的用戶界面。盡管它們功能上有重疊&#xff0c;但它們之間存在顯著的區別。本文將詳細講解 AppCompatActivity 和 Activity 的區別&#xff0c;并結合代碼示例和具…

【 C++核心知識點面試準備:從內存管理到STL與模板 】

一、動態內存管理&#xff1a;new/delete與底層原理 核心問題1&#xff1a;new/delete vs malloc/free 區別對比&#xff1a; 特性new/deletemalloc/free類型安全自動推導類型&#xff0c;無需轉型返回void*&#xff0c;需強制轉型生命周期自動調用構造/析構函數需手動初始化…

軟考高項(信息系統項目管理師)第 4 版全章節核心考點解析(第4版課程精華版)

一、核心輸入輸出速記體系&#xff08;力揚老師獨家口訣&#xff09; &#xff08;一&#xff09;規劃階段萬能輸入&#xff08;4 要素&#xff09; 口訣&#xff1a;章程計劃&#xff0c;組織事業 ? 精準對應&#xff08;ITTO 核心輸入&#xff09;&#xff1a; 章程&#…

ASP.NET CORE部署IIS的三種方式

ASP.NET Core 部署方式對比 本文檔對比了三種常見的 ASP.NET Core 應用&#xff08;如你的 DingTalkApproval 項目&#xff09;部署到 Windows 10 上 IIS 服務器的方式&#xff1a;dotnet publish&#xff08;手動部署&#xff09;、Web Deploy&#xff08;直接發布到 IIS&…

基于共享上下文和自主協作的 RD Agent 生態系統

在llmangentmcp這個框架中&#xff1a; LLM&#xff1a; 依然是智能體的“大腦”&#xff0c;賦予它們理解、推理、生成和規劃的能力&#xff0c;并且也用于處理和利用共享上下文。Agent&#xff1a; 具備特定 R&D 職能的自主單元&#xff0c;它們感知共享上下文&#xff0…

zephyr架構下Bluetooth advertising接口

目錄 概述 1 函數接口 2 主要函數介紹 2.1 bt_le_adv_start函數 2.1.1 函數功能介紹 2.1.2 典型使用示例 2.1.3 廣播間隔 2.1.4 注意事項 2.2 bt_le_adv_stop 函數 2.2.1 函數功能 2.2.2 使用方法介紹 2.2.3 實際應用示例 2.2.4 關鍵注意事項 2.2.5 常見問題解決 …

8、HTTPD服務--ab壓力測試

一、ab壓力測試 # ab ‐c 100 ‐n 1000 http://vedio.linux.com/index.html 2 This is ApacheBench, Version 2.3 <$Revision: 1430300 $> 3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 4 Licensed to The Apache Software Foundation,…

E2E 測試

以下是關于端到端(E2E)測試的基本知識總結: 一、E2E 測試核心認知 1. 定義與價值定位 "模擬真實用戶在完整應用環境中的操作流程"核心價值: 驗證跨系統/模塊的集成功能檢測用戶流程中的關鍵路徑保障核心業務場景的可用性測試金字塔定位:單元測試(70%) → 集…

python之數字類型的操作

Python數據類型與操作符完全指南&#xff1a;詳解各類數據操作技巧 目錄 數字類型 字符串 列表 元組 字典 集合 布爾 通用操作符 注意事項 1. 數字類型&#xff08;int, float, complex&#xff09; 數字類型是Python中最基礎的數據類型&#xff0c;支持多種數學運算…

基于Spring Boot+Vue 網上書城管理系統設計與實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

從拒絕采樣到強化學習,大語言模型推理極簡新路徑!

大語言模型&#xff08;LLMs&#xff09;的推理能力是當下研究熱點&#xff0c;強化學習在其復雜推理任務微調中廣泛應用。這篇論文深入剖析了相關算法&#xff0c;發現簡單的拒絕采樣基線方法表現驚人&#xff0c;還提出了新算法。快來一探究竟&#xff0c;看看這些發現如何顛…

測試——BUG篇

1. 軟件測試的生命周期 軟件測試貫穿于軟件的整個生命周期&#xff0c;針對這句話我們?起來看?下軟件測試是如何貫穿軟件的整個生命周期。 軟件測試的?命周期是指測試流程&#xff0c;這個流程是按照?定順序執?的?系列特定的步驟&#xff0c;去保證產品質量符合需求。在…

【Hive入門】Hive函數:內置函數與UDF開發

Apache Hive作為Hadoop生態系統中的重要組件&#xff0c;為大數據分析提供了強大的SQL-like查詢能力。Hive不僅支持豐富的內置函數&#xff0c;還允許用戶開發自定義函數&#xff08;UDF&#xff09;以滿足特定需求。本文將深入探討Hive的內置函數&#xff08;包括數學函數、字…

關于匯編語言與程序設計——子程序設計

學習目標&#xff1a; 編程實現兩個數&#xff1a;#8888H 和 #79H 的乘除運算。 一、實驗要求 能夠熟練掌握算術運算匯編指令的使用&#xff1b;熟練掌握子程序設計的基本方法&#xff1b;熟練掌握程序的調試方法。 二、實驗設計 1.整體思路 乘法&#xff1a;將單字節的乘數…

AWS SQS 隊列策略配置指南:常見錯誤與解決方案

在 AWS 云服務中,Simple Queue Service (SQS) 是一種完全托管的消息隊列服務,廣泛應用于分布式系統組件間的解耦。為了確保隊列的安全訪問,正確配置隊列策略至關重要。本文將詳細介紹 SQS 隊列策略的配置方法,常見錯誤及其解決方案。 SQS 隊列策略基礎 SQS 隊列策略是基于…

Webshell管理工具的流量特征

目錄 一、常見Webshell工具流量特征 1. ??中國菜刀&#xff08;Chopper&#xff09;?? 2. ??冰蝎&#xff08;Behinder&#xff09;?? 3. ??哥斯拉&#xff08;Godzilla&#xff09;?? 4. ??蟻劍&#xff08;AntSword&#xff09;?? 5. ??C99 Shell??…

【每日八股】復習 MySQL Day3:鎖

文章目錄 昨日內容復習MySQL 使用 B 樹作為索引的優勢是什么&#xff1f;索引有哪幾種&#xff1f;什么是最左匹配原則&#xff1f;索引區分度&#xff1f;聯合索引如何排序&#xff1f;使用索引有哪些缺陷&#xff1f;什么時候需要建立索引&#xff0c;什么時候不需要&#xf…

Arkts完成數據請求http以及使用axios第三方庫

import http from ohos.net.http Entry Component struct HttpPage {State message: string Hello Worldbuild() {Column({space:20}) {Row(){Button(發送http請求).onClick(()>{let httpRequest http.createHttp();httpRequest.request(https://zzgoodqc.cn/index.php/in…