ホームページ >ウェブフロントエンド >jsチュートリアル >OpenLayerは経路に応じた車の動きをどのように実現しているのでしょうか?

OpenLayerは経路に応じた車の動きをどのように実現しているのでしょうか?

little bottle
little bottle転載
2019-04-30 11:53:333617ブラウズ

この記事では、openlayer 上でのパスモーションの実現について主に説明します。どのように実装されているかをエディターと一緒に見てみましょう。興味のある友人は見てください。

1. 要件分析

顧客が必要とする機能は、GIS マップ上の経路に従って車を移動できるようにすることですが、なぜ Gis でなければならないのでしょうか? (これは顧客です) -指定された要件。言葉を失います。)。また、お客様からは、ベースとなる地図は簡単に置き換えられるはずだが、Gisで表現したいのは屋内の地理情報であり、BaiduやAmapなどの既製のGisインターフェースは使えなかったとのことでした。

上記の要件を考慮すると、私は Web GIS フレームワークについてあまり勉強していません。なぜなら、顧客の Gis のコンセプトは、ズームインおよびズームアウトができ、経路計画などができることだからです。そこで私は ol を選択し、この問題を解決するために彼の静止画像 (ベース マップを柔軟に更新するという顧客のニーズを満たすためにこれを選択) を Gis ベース マップとして使用しました。

関連チュートリアル: js ビデオ チュートリアル

2. エフェクトの表示

3. 疑似コードの実装

技術的な検証コードなので少し複雑なので、キーコードのみ記載します。ビジネス上のご要望がございましたら、ぜひ一緒にご相談ください。

3.1 パス描画の実装

このステップは比較的単純です。主に 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.2 パスデータの分解

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;
    }

いくつかの数学的な三角関数と計算方法が使用されます。この方法では、ステップ サイズに基づいて計算された座標セットが最終的に選択されます。

3.3 postcompose を使用してモーション効果を実現する

コードは次のとおりです:


tracerun(){
        if(!this.traceLine) return;
        this.traceCroods = this.cutTrace();
        this.now = new Date().getTime();
        this.map.on(&#39;postcompose&#39;, 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(&#39;postcompose&#39;, 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 + &#39;  &#39; + dy + &#39;  &#39; + 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: &#39;Car&#39;,
                    fill: new Fill({
                        color: &#39;red&#39;
                    }),
                    offsetY: -20
                })
            });  
            vCxt.drawFeature(anchor, style);
            //this.map.getView().setCenter(bCrood);
        }
        this.map.render();
    }

この動きのコードは、ol の postcompose イベントを使用して実装されています。 postcompose イベントは render メソッドの実行後にトリガーされるため、タイマーの実装が置き換えられます。このうち、回転は 2 点座標を基に移動するアイコンの傾きや移動方向を計算するため、表示への影響が大きくなります。

以上がOpenLayerは経路に応じた車の動きをどのように実現しているのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。