Home > Web Front-end > JS Tutorial > How does OpenLayer realize the movement of the car according to the path?

How does OpenLayer realize the movement of the car according to the path?

little bottle
Release: 2019-04-30 11:54:38
forward
3695 people have browsed it

This article mainly talks about realizing path motion on openlayer. Let's go with the editor to see how it is implemented. Interested friends can take a look.

1. Requirements Analysis

The function the customer needs is to enable the car to move according to the path on a Gis map. Why does it have to be Gis? (This is a customer-specified requirement. I am speechless. ). And the customer also said that the base map should be easy to replace, but what he wanted to use Gis to express was indoor geographical information. I couldn't use ready-made Gis interfaces such as Baidu and Amap.

In view of the above requirements, I have not learned too much about web gis frameworks. Because the customer's concept of Gis is that it can zoom in and out, and can do path planning, etc. So I chose ol and used his static pictures (choose this to meet the customer's need to flexibly update the base map) as a Gis base map to solve this problem.

Related tutorials: js video tutorial

2. Effect display

3. Pseudocode implementation

Because it is a technical verification code, it is a bit complicated, so only the key code is given. If you have any business needs, welcome to discuss together.

3.1 Implement path drawing

This step is relatively simple. It mainly uses Ol’s Draw object. Here is the code:


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);
    }
Copy after login

The key code lies in the monitoring of the drawend event. If it is a LineString situation, put this feature in a public variable to facilitate use when the path is running.

3.2 Decompose path data

This part is to obtain the path path of step 3.1, and then analyze it, because the linestring on 3.1 is a collection of multiple line segments, but the essence of movement is It is to change the coordinates of the icon so that its rapid and continuous changes form a moving effect. So here is a method for path subdivision, the code is as follows:

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;
    }
Copy after login

Some mathematical trigonometric functions and calculation methods are used. This method finally selects a coordinate set calculated based on the step size.

3.3 Use postcompose to achieve motion effects

The code is as follows:


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();
    }
Copy after login

This movement code is implemented using ol’s postcompose event , because the postcompose event will be triggered after the render method is executed, so it replaces the timer implementation. Among them, rotation calculates the slope of the moving icon and the direction of movement based on the two-point coordinates, which is more impactful for the display.

The above is the detailed content of How does OpenLayer realize the movement of the car according to the path?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:cnblogs.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template