這篇文章運(yùn)用簡單易懂的例子給大家介紹怎么在OpenLayer中實(shí)現(xiàn)小車按路徑運(yùn)動(dòng),代碼非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的木壘哈薩克網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
客戶需要的功能就是能在一張Gis圖上實(shí)現(xiàn)小車根據(jù)路徑進(jìn)行移動(dòng),為什么一定要Gis呢(這是客戶指定需求,無語一該)。并且客戶還說底圖要很容易更換,但他想要用Gis表現(xiàn)的卻是室內(nèi)的地理信息,我也沒辦法用baidu, 高德等現(xiàn)成的Gis接口。
針對上述需求,我沒有去了解過多的web gis框架。因?yàn)榭蛻魧is的概念就是能放大,縮小,可以做路徑規(guī)劃等。所以我就選擇ol,利用他的靜態(tài)圖片(選擇這個(gè)是為滿足客戶靈活更新底圖的需求)做Gis底圖的功能來解決此問題。
相關(guān)教程:js視頻教程

由于是技術(shù)驗(yàn)證代碼, 有些雜亂,現(xiàn)只給出關(guān)鍵性代碼。如有業(yè)務(wù)需要?dú)g迎共同討論。
此步驟還是相對簡單的,主要用到Ol的Draw對象,代碼哪下:
draw(type){
this.stopdraw();
this._draw = new Draw({
source: this.layer.getSource(),
type: type == 'Icon' ? 'Point' : type
});
this._draw.on('drawend', (event)=>{
if(type == 'LineString'){
this.traceLine = event.feature;
}
if(type != 'Icon') return;
let f = event.feature;
f.setStyle(new Style({
image: new Icon({
src: '/content/battery.gif'
}),
text: new Text({
text: 'new item',
fill: new Fill({
color: "red"
})
})
}));
f.type = 'battery';
});
this.map.addInteraction(this._draw);
this._snap = new Snap({source: this.layer.getSource()});
this.map.addInteraction(this._snap);
}關(guān)鍵代碼在于drawend事件的監(jiān)聽,如果是LineString情況,就將此feature放在一個(gè)共公變量,方便路徑運(yùn)行時(shí)使用。
此部分就是獲取到3.1步驟的路徑路徑,然后進(jìn)行解析,因?yàn)?.1上的linestring是多個(gè)線段的集合,但運(yùn)動(dòng)其本質(zhì)就是改變圖標(biāo)的坐標(biāo),使其快速且連續(xù)的變化就形成了移動(dòng)效果。所以這里有一個(gè)方法進(jìn)行路徑細(xì)分,代碼如下:
cutTrace(){
let traceCroods = this.traceLine.getGeometry().getCoordinates();
let len = traceCroods.length;
let destCroods = [];
for(let i = 0; i < len - 1; ++i){
let bPoint = traceCroods[i];
let ePoint = traceCroods[i+1];
let bevelling = Math.sqrt(Math.pow(ePoint[0] - bPoint[0], 2)
+ Math.pow(ePoint[1] - bPoint[1], 2) );
let cosA = (ePoint[0] - bPoint[0]) / bevelling;
let sinA = (ePoint[1] - bPoint[1]) / bevelling;
let curStep = 0;
let step = 5;
destCroods.push(new Point([bPoint[0], bPoint[1]]));
do{
curStep++;
let nextPoint;
if(curStep * step >= bevelling){
nextPoint = new Point([ePoint[0], ePoint[1]]);
}else{
nextPoint = new Point([
cosA * curStep * step + bPoint[0]
,
sinA * curStep * step + bPoint[1]
]);
}
destCroods.push(nextPoint);
}while(curStep * step < bevelling);
}
return destCroods;
}其中用到了一些數(shù)學(xué)上的三角函數(shù)和計(jì)算方法。此方法最終選一個(gè)根據(jù)步長計(jì)算后的坐標(biāo)集合。
代碼如下:
tracerun(){
if(!this.traceLine) return;
this.traceCroods = this.cutTrace();
this.now = new Date().getTime();
this.map.on('postcompose', this.moveFeature.bind(this));
this.map.render();
}
moveFeature(event){
let vCxt = event.vectorContext;
let fState = event.frameState;
let elapsedTime = fState.time - this.now;
let index = Math.round(300 * elapsedTime / 1000);
let len = this.traceCroods.length;
if(index >= len){
//stop
this.map.un('postcompose', this.moveFeature);
return;
}
let dx, dy, rotation;
if(this.traceCroods[index] && this.traceCroods[index + 1]){
let isRigth = false;
let bCrood = this.traceCroods[index].getCoordinates();
let eCrood = this.traceCroods[index + 1].getCoordinates();
if(bCrood[0] < eCrood[0]){
//左->右
isRigth = true
}
dx = bCrood[0] - eCrood[0];
dy = bCrood[1] - eCrood[1];
rotation = Math.atan2(dy,dx);
if(rotation > (Math.PI / 2)){
//修正
rotation = Math.PI - rotation;
}else if(rotation < -1 * (Math.PI / 2)){
rotation = -1 * Math.PI - rotation;
}else{
rotation = -rotation;
}
console.log(dx + ' ' + dy + ' ' + rotation);
let curPoint = this.traceCroods[index];
var anchor = new Feature(curPoint);
let style = new Style({
image: new Icon({
img: isRigth ? this.carRight : this.carImg,
imgSize: [32,32],
rotateWithView: false,
rotation: rotation
}),
text: new Text({
text: 'Car',
fill: new Fill({
color: 'red'
}),
offsetY: -20
})
});
vCxt.drawFeature(anchor, style);
//this.map.getView().setCenter(bCrood);
}
this.map.render();
}此移動(dòng)代碼的是用ol的postcompose事件進(jìn)行實(shí)現(xiàn)的,因?yàn)閞ender方法執(zhí)行完成后會(huì)觸發(fā)postcompose事件,所以就代替了定時(shí)器的的實(shí)現(xiàn)方案。其中rotation根據(jù)兩點(diǎn)坐標(biāo)計(jì)算出移動(dòng)圖標(biāo)的斜度、以及移動(dòng)的方向等,更為影響的展示。
關(guān)于怎么在OpenLayer中實(shí)現(xiàn)小車按路徑運(yùn)動(dòng)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
網(wǎng)站名稱:怎么在OpenLayer中實(shí)現(xiàn)小車按路徑運(yùn)動(dòng)
轉(zhuǎn)載來源:http://www.jinyejixie.com/article28/ijdijp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊、搜索引擎優(yōu)化、定制開發(fā)、手機(jī)網(wǎng)站建設(shè)、App設(shè)計(jì)、小程序開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)