この記事では、openlayer 上でのパスモーションの実現について主に説明します。どのように実装されているかをエディターと一緒に見てみましょう。興味のある友人は見てください。
顧客が必要とする機能は、GIS マップ上の経路に従って車を移動できるようにすることですが、なぜ Gis でなければならないのでしょうか? (これは顧客です) -指定された要件。言葉を失います。)。また、お客様からは、ベースとなる地図は簡単に置き換えられるはずだが、Gisで表現したいのは屋内の地理情報であり、BaiduやAmapなどの既製のGisインターフェースは使えなかったとのことでした。
上記の要件を考慮すると、私は Web GIS フレームワークについてあまり勉強していません。なぜなら、顧客の Gis のコンセプトは、ズームインおよびズームアウトができ、経路計画などができることだからです。そこで私は ol を選択し、この問題を解決するために彼の静止画像 (ベース マップを柔軟に更新するという顧客のニーズを満たすためにこれを選択) を Gis ベース マップとして使用しました。
関連チュートリアル: js ビデオ チュートリアル
技術的な検証コードなので少し複雑なので、キーコードのみ記載します。ビジネス上のご要望がございましたら、ぜひ一緒にご相談ください。
このステップは比較的単純です。主に 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); }
重要なコードは、drawend イベントの監視にあります。LineString 状況の場合は、この機能をパブリック変数に入れて、パスの実行時に簡単に使用できるようにします。
3.1の線列は複数の線分の集合体であるため、この部分ではステップ3.1のパスパスを取得して解析します。動きの本質は、アイコンの座標を変更して、その急速かつ継続的な変化が動きのある効果を形成することです。ここではパスを細分する方法を示します。コードは次のとおりです。
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; }
いくつかの数学的な三角関数と計算方法が使用されます。この方法では、ステップ サイズに基づいて計算された座標セットが最終的に選択されます。
コードは次のとおりです:
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(); }
この動きのコードは、ol の postcompose イベントを使用して実装されています。 postcompose イベントは render メソッドの実行後にトリガーされるため、タイマーの実装が置き換えられます。このうち、回転は 2 点座標を基に移動するアイコンの傾きや移動方向を計算するため、表示への影響が大きくなります。
以上がOpenLayerは経路に応じた車の動きをどのように実現しているのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。