這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

專案效果
我們今天要實作的是一個路徑規劃的功能,有兩個輸入框,輸入起點終點,然后查詢,得到規劃的路徑,效果如下:


我們會用到以下庫:
-
Axios:用于發送請求,請求高德地圖的地理編碼API
-
Jquery:也用于發送請求
-
Cesium:地圖框架
-
Vue:前端框架
前期準備
路徑規劃目前我們沒有路網資料,所以自己做不了(后面可以出一期),因此我們可以請求百度地圖的api,但前提是我們有起點和終點的經緯度,沒有人會用經緯度來導航吧?因此我們還需要進行地理編碼,把中文轉化具體的地理位置(經緯度),這里我們用了高德的api,最后我們地圖需要切片資料,默認會用Cesium自帶的資源,因此也要注冊一個cesium的賬號,來獲取token,如果用了自己的底圖資源也可不用,為了演示的方便,我們還是申請一下,因為cesium還是自帶了很多的資源,便于后期的學習,
- 注冊Cesium.ion獲取token
- 注冊高德地圖Api,獲取key
- 注冊百度地圖Api,獲取key
注冊cesium ion
Access Tokens | Cesium ion,注冊后獲取token:

注冊高德地圖API
記得選擇Web服務,里面是包括地理編碼api的,然后會給你個key

注冊百度地圖API
注意下選擇服務端就行,里面服務包括了路徑規劃,之所以用百度而不用高德是因為,高德的路徑規劃回傳的沒有經緯度,后面就沒辦法繪制線段了,

代碼時間
1. 專案結構:
一個Demo.html檔案和public檔案夾(里面放置cesium下載的內容:)

下載cesium庫Downloads – Cesium,并放在public檔案夾中

2. Html參考我們檔案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Hello World!</title>
<!-- 引入jquery、cesium、axios、vue. -->
<script src="https://www.cnblogs.com/smileZAZ/archive/2023/02/09/public/Cesium-1.100/Build/Cesium/Cesium.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>
<style>
<!-- 引入cesium的css檔案. -->
@import url(public/Cesium-1.100/Build/Cesium/Widgets/widgets.css);
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#input1 {
position: absolute;
top: 10px;
left: 10px;
}
#input2 {
position: absolute;
top: 10px;
left: 200px;
}
#navibutton {
position: absolute;
top: 10px;
left: 400px;
}
</style>
</head>
<body>
<!-- id為app的div作為vue可操作的容器. -->
<div id="app">
<!-- id為cesiumContainer的div作為地圖的容器. -->
<div id="cesiumContainer"></div>
<!-- 在vue中通過@click給按鈕系結點擊事件函式. -->
<button id="navibutton" @click="search">導航</button>
<!-- 在vue中通過v-model給輸入框系結回應式的變數,這個變數在data里申明. -->
<input id="input1" v-model="input1" placeholder="請輸入起點地點名稱">
<input id="input2" v-model="input2" placeholder="請輸入終點地點名稱">
</div>
</body>
</html>
3. 使用vue管理頁面
我們看看這段代碼,首先我們通過決議賦值,從vue中獲取了createApp函式,這個函式是承載了所有我們后面的操作,并通過mount系結了id為app的元素,因為要做到回應式,其實vue是通過虛擬dom來對app元素里面的內容進行操作,比如回應式更新我們的input,新建元素等等,
const { createApp } = Vue
var viewer,
cesiumKey = '這里寫你自己申請的token',
aMapKey = '這里寫你自己申請的key'',
baiduKey = '這里寫你自己申請的key'
createApp({
data() {
return {
input1: '北京',
input2: '上海',
}
},
}).mount('#app')
在vue中,我們所有的函式都寫在methods里面,如下所示:
我們寫了一個createMap函式,初始化了一個cesium地圖,并在mounted里面用this.createMap()呼叫,因為vue的生命周期mounted里才會獲取到dom,更多可以去了解一下vue的生命周期,
createApp({
data() {
return {
input1: '北京',
input2: '上海',
}
},
methods: {
createMap() {
Cesium.Ion.defaultAccessToken = cesiumKey;
// 傳入id,初始化地圖
viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false,
imageryProvider: new Cesium.UrlTemplateImageryProvider({ url: " http://webrd02.is.autonavi.com/appmaptile? lang=zh_cn&size = 1&scale = 1&style = 8&x = {x} &y = {y} &z ={z} ", })
});
viewer.bottomContainer.style.display = "none";//隱藏bottomContainer
var imageList = viewer.baseLayerPicker.viewModel.imageryProviderViewModels;
//使用第4個(索引為3,內容為ESRI世界影像)imageryProvider作為默認的地形資料提供者
//以免使用默認的BING服務,有時刷不出影像的情況
viewer.baseLayerPicker.viewModel.selectedImagery = imageList[3];
//加入中文注記
//增加一個圖層:天地圖全球影像中文注記服務
var imageLabelCn = new Cesium.ImageryLayer(new Cesium.WebMapTileServiceImageryProvider({
url: 'http://t0.tianditu.com/cia_w/wmts?tk=a2ca005a710864da5d797e35e0f45b3b',
layer: 'cia',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
maximumLevel: 18
}));
viewer.scene.imageryLayers.add(imageLabelCn);
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(110, 30, 15000000.0), // 設定位置
orientation: {
heading: Cesium.Math.toRadians(0.0), // 方向
pitch: Cesium.Math.toRadians(-90.0),// 傾斜角度
roll: 0
}
});
},
mounted() {
this.createMap()
},
}).mount('#app')
4. 地理編碼
使用axios.js請求高德地圖的地理編碼,獲取文本位置的經緯度坐標
async getAddress(loc) {
const response = await axios.get(`https://restapi.amap.com/v3/geocode/geo?address=${loc}&key=${aMapKey}`)
return response.data.geocodes[0].location
},
async getRoad(loc, loc2) {
const response = await axios.get(`https://restapi.amap.com/v3/direction/driving?origin=${loc}&destination=${loc2}&key=${aMapKey}`)
return response
},
5. 路徑規劃
getJsonpPosition函式是根據起點終點的經緯度進行路徑規劃,并以jsonp的格式回傳,這種方法可以解決百度地圖api跨域的問題
然后當點擊按鈕的時候會呼叫search函式,獲取input的值,然后地理編碼變成經緯度,再呼叫getJsonpPosition獲取到線段的經緯度陣列,最后用createpolyline繪制路徑,
getJsonpPosition(start, end) {
$.ajax(
{
url: `https://api.map.baidu.com/direction/v2/driving?origin=${start}&destination=${end}&ak=${baiduKey}`,//GET請求
type: "get",
dataType: "jsonp",
async: false,
jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回呼函式名的引數名(一般默認為:callback)
success: (response) => {
console.log(response);
let resArr = []
if (response.status == 0) {
const res = response.result.routes[0].steps.map((item) => {
const stringArr = item.path.split(';')
stringArr.map((x) => {
numArr = x.split(',')
resArr.push(...numArr)
})
})
resArr = resArr.map((item) => {
return Number(item)
})
console.log(resArr)
this.createpolyline(resArr, viewer)
}
}
}
)
},
async search() {
console.log(this.input1, this.input2,)
if (this.input1 == '' || this.input2 == '') {
alert('輸入框不能為空!')
return
}
const data = https://www.cnblogs.com/smileZAZ/archive/2023/02/09/await this.getAddress(this.input1)
const data2 = await this.getAddress(this.input2)
const data_1 = data.split(',')
const data_2 = data2.split(',')
data_1.reverse()
const data_string1 = data_1.join(',')
data_2.reverse()
const data_string2 = data_2.join(',')
console.log(data_string1, data_string2,)
this.getJsonpPosition(data_string1, data_string2)
},
createpolyline(positons, viewer, color = "#ff0") {
const polyline = viewer.entities.add({
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(positons),
clampToGround: true,
width: 6,
material: Cesium.Color.fromCssColorString(color),
clampToGround: true
}
});
// 視圖定位到線段
viewer.flyTo(polyline)
return polyline;
},
總結
這個專案其實還有很多完善的地方,比如點擊按鈕發送請求有一段時間,應該加一個loading的動效,界面過于樸素等等,
代碼我已經上傳到Gitte:gitee.com/z129812/ces…
本文轉載于:
https://juejin.cn/post/7177326285336051772
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/543462.html
標籤:其他
上一篇:js物件的理解
下一篇:PC移動端面試題
