OpenLayers实现小车的轨迹查询的功能

支持实现的功能
  • 限制3天的时间跨度
  • 小车在运动中改变速度
  • 小车重新运动
  • 小车运动的点位支持打开详情信息

这是自己当时刚从后端切到前端时,实现的第一个功能,当时都没有接触过前后端分离的开发模式,更不知道react,抱着现学现做的态度做的.....,可能有需要的同学,做个参考吧。

import React, {Component} from 'react';
import {DatePicker, Input, Icon, Button, Table, Progress, Slider, notification} from 'antd';
import ol from 'openlayers';
import moment from 'moment';
import axios from 'axios';
import playback from '../../Images/playback.png';
import speedcar from '../../Images/car.png';
import move from '../../Images/move.png';
import direction from '../../Images/direction.png';
import stop from '../../Images/stop.png';
import daemarker from '../../Images/direction.png';
import './CarMove.less';
import 'openlayers/css/ol.css';

const RangePicker = DatePicker.RangePicker;

//地图上原先的vector
let prevVector;
//确定地图放缩级别
let zoomSize = [100, 200, 500, 1000, 2000, 8000, 14000, 20000, 25000, 50000, 100000, 200000, 500000, 1000000, 2000000];
let zoomlevel = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3];

class CarMove extends Component {

    constructor(props) {
        super(props);
        this.state = {
            columns: [],                   //table的表头信息
            DAENumber: '',                 //默认的编号
            DAEStatus: '',                 //默认的状态
            DEAAddress: '',                //默认的地址
            queryKeyWord: this.props.keyword === undefined ? '' : this.props.keyword,             //用户输入的查询关键字
            pathTableData: [],             //table中的数据
            scrollPathTableHeight: '',     //设置table出现滑动条的高度
            userChooseStartTime: this.props.starttime === undefined ? '' : this.props.starttime,  //用户选择的起始时间
            userChooseEndTime: this.props.endtime === undefined ? '' : this.props.endtime,        //用户选择的结束时间
            defaultShowBtnFlag: this.props.showBtnFlag === undefined ? false : this.props.showBtnFlag, //用户传入是否显示返回按钮
            defaultModeFlag: this.props.modeFlag === undefined ? false : this.props.modeFlag,     //区分用户进入方式
            tableBodyData: [],             //默认查询到的数据的总条数
            showAdjustSpeed: false,        //默认的调节小车行驶的进度条不显示
            carProgerss: 0,                //默认的小车在轨迹上行驶的进度
            canRefreshAnimation: true,     //默认小车的重新运动按钮可用
            mapCenterLongitude: 105.442574, //默认的地图显示中心的经度
            mapCenterLatitude: 28.871718,  //默认的地图显示中心的纬度
            mapUrl: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'//默认的在线地图的服务地址
        }
        this.map = null;                          //定义的地图容器句柄
        this.marker = null;                       //默认点击出现弹出框
        this.index = 0;                    //默认的小车在轨迹的位置
        this.defaultCarSpeed = 12;         //默认小车的行驶速度
    }

    //构造查询轨迹table的头信息
    // eslint-disable-next-line react/sort-comp
    generateTableHeaderData() {
        const columns = [
            {title: '采集时间', dataIndex: 'column0', key: '1', width: 150, align: 'center'},
            {title: '采集器序列号', dataIndex: 'column1', key: '2', width: 150, align: 'center'},
            {title: '位置', dataIndex: 'column2', key: '3', width: 180, align: 'center'}
        ];
        this.setState({
            columns: columns
        })
    }

    // 输入插叙的关键字
    userInputKeyWord = (e) => {
        this.setState({
            queryKeyWord: e.target.value
        })
    }

    //清空输入的查询关键词
    clearUserKeyWord = () => {
        this.setState({
            queryKeyWord: ''
        })
    }

    //用户选择查询的时间时
    userChangeQueryTime = (date, dateString) => {
        this.setState({
            userChooseStartTime: dateString[0],
            userChooseEndTime: dateString[1]
        })
    }

    //用户点击查询轨迹
    getPathDatas = () => {
        let mapData = [], tableData = [];
        let queryKey = this.state.queryKeyWord;
        //当用户选择的时间间隔超过三天的给出提示
        let startTime = this.state.userChooseStartTime;
        let endTime = this.state.userChooseEndTime;
        //把时间转化为毫秒,计算差值
        let time = new Date(endTime).getTime() - new Date(startTime).getTime();
        //必填项的校验
        if (queryKey === "" || queryKey == null) {
            notification.warn({
                message: '输入的车牌号或标签号不能为空',
                description: `请重新输入车牌号或者标签号进行查询`,
                duration: 3,
                placement: 'bottomRight'
            });
            return;
        }
        if (startTime === "" || endTime === "") {
            notification.warn({
                message: '请选择查询的时间段',
                description: `查询的时间段不能为空,请重新选择时间进行查询`,
                duration: 3,
                placement: 'bottomRight'
            });
            return;
        }
        if (time > 259200000) {
            notification.warn({
                message: '时间间隔不能超过三天',
                description: `查询的时间段不能超过三天,请重新选择时间进行查询`,
                duration: 3,
                placement: 'bottomRight'
            });
            return;
        }

        //数据请求的方法
        var url = "http://localhost:8080/getAllDaeInfo";
        axios.get(url).then(function (response) {
            console.log("response-------------->", response.data);
        }).catch(function (error) {
            console.log(error);
        });


        let enterTime, daeStatus, longitude, latitude, maxDistance = 0, distance = 0;
        let carPathData = new Array();
        //生成模拟数据
        for (let i = 0; i < 20; i++) {
            let time = Date.now() + i * 1000;
            let carPathDataItem = {};
            carPathDataItem.collectTime = time;
            carPathDataItem.devStatus = 0;
            carPathDataItem.devId = 'ts10001' + i;
            carPathDataItem.devAddr = 'XX市市测试区测试街道' + i;
            carPathDataItem.longitude = 107.4425790689 + Math.random() * (i + 1) / 500;
            carPathDataItem.latitude = 29.8717183035 + Math.random() * (i + 1) / 500;
            carPathData.push(carPathDataItem);
        }


        for (let i = 0; i < carPathData.length; i++) {
            enterTime = moment(carPathData[i].collectTime).format("YYYY-MM-DD HH:mm:ss");
            if (carPathData[i].devStatus === 0) {
                daeStatus = "离线";
            } else {
                daeStatus = "在线";
            }
            //计算经纬度之间最大的距离
            if (i < carPathData.length - 1) {
                distance = this.getDistance(carPathData[i].latitude, carPathData[i].longitude, carPathData[i + 1].latitude, carPathData[i + 1].longitude);
                if (distance > maxDistance) {
                    maxDistance = distance;
                }
            }
            //表格数据的构造
            tableData.push({
                key: `${i}`,
                column0: enterTime,
                column1: carPathData[i].devId,
                column2: carPathData[i].devAddr
            });
            longitude = carPathData[i].longitude;
            latitude = carPathData[i].latitude;
            //地图数据的构造
            mapData.push([longitude, latitude, carPathData[i].devId, daeStatus, carPathData[i].devAddr]);
        }
        if (mapData.length > 0) {
            let level = 13;
            //确定地图的放缩等级
            for (let i = 0; i < zoomSize.length; i++) {
                if (maxDistance > 100) {
                    if (maxDistance < zoomSize[i]) {
                        level = zoomlevel[i - 1];
                        break;
                    }
                } else {
                    if (maxDistance === 0) {
                        level = 5;
                        break;
                    } else {
                        level = 17;
                        break;
                    }
                }
            }
            this.setState({
                tableBodyData: tableData,
                canRefreshAnimation: true
            })
            //每次添加新的坐标点时清空原先的坐标点
            this.map.removeLayer(prevVector);
            //清空以移动的小车
            this.map.un('postcompose', this.moveFeature);
            //当用户打开弹出窗口的时候,点击查询的情况情况
            this.closeMapMarker();
            this.map.getView().setZoom(level);
            //重新设置地图的中心(不设置的话小车移动报错)
            this.map.getView().setCenter(ol.proj.transform([mapData[0][0], mapData[0][1]], 'EPSG:4326', 'EPSG:3857'));
            this.generateCarMoveOnMap(mapData);
        } else {
            this.setState({
                tableBodyData: tableData,
                carProgerss: 0,
                canRefreshAnimation: false
            })
            //每次添加新的坐标点时清空原先的坐标点
            this.map.removeLayer(prevVector);
            //清空以移动的小车
            this.map.un('postcompose', this.moveFeature);
            //当用户打开弹出窗口的时候,点击查询的情况情况
            this.closeMapMarker();
            //重新设置地图的中心(不设置的话小车移动报错)
            this.map.getView().setCenter(ol.proj.transform([this.state.mapCenterLongitude, this.state.mapCenterLatitude], 'EPSG:4326', 'EPSG:3857'));
            this.generateCarMoveOnMap(mapData);
            notification.info({
                message: '没有查询到轨迹信息',
                description: `根据你输入车牌号或者标签号以及时间没有查询到信息`,
                duration: 3
            });
        }
    }

    //计算经纬度之间的距离(单位米)
    getDistance = (lat1, lng1, lat2, lng2) => {
        let radLat1 = lat1 * Math.PI / 180.0;
        let radLat2 = lat2 * Math.PI / 180.0;
        let a = radLat1 - radLat2;
        let b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
        let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
            Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * 6378.137;// EARTH_RADIUS;
        s = Math.round(s * 10000) / 10;
        return s;
    }

    componentDidMount() {

        //设置表格默认滚动区域
        this.setState({
            scrollPathTableHeight: this.tableContrainer.clientHeight - 60
        });
        //监听窗口的放缩,动态的设置table出现出现滚动的高度
        window.onresize = () => {
            let tableContainer = this.tableContrainer;
            if (tableContainer) {
                let tableHeight = tableContainer.clientHeight - 60;
                this.setState({
                    scrollPathTableHeight: tableHeight
                })
            }
        }
        //调用构造table头信息的函数
        this.generateTableHeaderData();

        //生成地图层
        let raster = new ol.layer.Tile({source: new ol.source.XYZ({url: this.state.mapUrl})});
        //总地图
        this.map = new ol.Map({
            target: 'pathMapContainer', layers: [raster],
            view: new ol.View({
                center: ol.proj.transform([this.state.mapCenterLongitude, this.state.mapCenterLatitude], 'EPSG:4326', 'EPSG:3857'),
                //指定地图投影类型
                projection: 'EPSG:3857',
                //定义地图显示的层级
                zoom: 13, maxZoom: 18, minZoom: 5
            })
        });
        //用户打开坐标显示
        this.openMapMarker(this.map);
    }

    //构造轨迹回放动画
    generateCarMoveOnMap = (coordinate) => {
        let that = this;
        //标记层
        let layer = new ol.layer.Vector({
            source: new ol.source.Vector()
        });
        let styles = {
            //线路的样式
            'route': new ol.style.Style({stroke: new ol.style.Stroke({width: 5, color: "#66ACED"})}),
            //起点的样式
            'start': new ol.style.Style({image: new ol.style.Icon({scale: 0.75, src: direction})}),
            //起点的样式
            'end': new ol.style.Style({image: new ol.style.Icon({scale: 0.8, anchor: [0.5, 0.82], src: stop})}),
            //小车的样式
            'geoMarker': new ol.style.Style({image: new ol.style.Icon({scale: 0.65, anchor: [0.5, 0.8], src: move})}),
            //真实点的样式
            'point': new ol.style.Style({image: new ol.style.Icon({scale: 1, src: daemarker})})
        }

        let animating = false, now, speed;
        let routeCoords, routeLength, geoMarker;
        let startButton = document.getElementById('start-animation');
        let traversed = 0;      //走过的路程
        let elapsedTime = 0;    //用过的时间
        let retime = 0;         //保存上次运动所用的时间

        if (coordinate.length > 2) {
            let geometry = new ol.geom.LineString();
            let anchor;
            let minScale = 0.001;
            let lngValue, latValue, times;
            let lnglatArray = new Array();
            //构造坐标点之间的线路
            for (let i = 0; i < coordinate.length; i++) {
                //构造坐标点的时候构造路径
                if (i > 0) {
                    //构造坐标点之间的路径
                    lngValue = coordinate[i][0] - coordinate[i - 1][0];
                    latValue = coordinate[i][1] - coordinate[i - 1][1];
                    //有一种特殊的情况当相邻的两个坐标点重合,或者当两个坐标点非常近的时候
                    let zLength = Math.sqrt(lngValue * lngValue + latValue * latValue);
                    if (zLength === 0 || Math.round(zLength / minScale) === 0) {
                        geometry.appendCoordinate(ol.proj.transform([coordinate[i][0], coordinate[i][1]], 'EPSG:4326', 'EPSG:3857'));
                    } else {
                        times = Math.round(zLength / minScale);
                        let xminScale = lngValue / times;
                        let yminScale = latValue / times;
                        for (let j = 0; j < times; j++) {
                            lnglatArray[0] = coordinate[i - 1][0] + j * xminScale;
                            lnglatArray[1] = coordinate[i - 1][1] + j * yminScale;
                            // eslint-disable-next-line no-use-before-define
                            anchor = setAnchorStyle(geometry, lnglatArray);
                            layer.getSource().addFeature(anchor);
                        }
                    }
                }
            }

            //设置坐标点之间连线点的坐标
            // eslint-disable-next-line no-inner-declarations
            function setAnchorStyle(geometry, lnglatArray) {
                geometry.appendCoordinate(ol.proj.transform(lnglatArray, 'EPSG:4326', 'EPSG:3857'));
                let anchor = new ol.Feature({
                    geometry: new ol.geom.Point(ol.proj.transform(lnglatArray, 'EPSG:4326', 'EPSG:3857'))
                });
                return anchor;
            }

            //标记小车运动轨迹上真实的坐标点
            let reallyGeometry = new ol.geom.LineString();
            //从第二个点到倒数第二个点
            for (let i = 1; i < coordinate.length - 1; i++) {
                reallyGeometry.appendCoordinate(ol.proj.transform([coordinate[i][0], coordinate[i][1]], 'EPSG:4326', 'EPSG:3857'));
            }
            let reallyCoords = reallyGeometry.getCoordinates();
            let reallyPoint = new Array();
            for (let i = 0; i < reallyCoords.length; i++) {
                //构造小车运动的线路上真实经过的坐标点
                reallyPoint.push(new ol.Feature({
                    type: 'point', state: 0,
                    num: coordinate[i + 1][2],
                    status: coordinate[i + 1][3],
                    address: coordinate[i + 1][4],
                    geometry: new ol.geom.Point(reallyCoords[i])
                }));
            }

            routeCoords = geometry.getCoordinates();
            routeLength = routeCoords.length;

            //小车行走的线路
            let routeFeature = new ol.Feature({
                type: 'route', state: 1,
                geometry: geometry
            });
            //运动的小车
            geoMarker = new ol.Feature({
                type: 'geoMarker', state: 1,
                geometry: new ol.geom.Point(routeCoords[0])
            });
            //轨迹开始坐标
            let startMarker = new ol.Feature({
                type: 'start', state: 0,
                num: coordinate[0][2],
                status: coordinate[0][3],
                address: coordinate[0][4],
                geometry: new ol.geom.Point(routeCoords[0])
            });
            //轨迹终止坐标
            let endMarker = new ol.Feature({
                type: 'end', state: 0,
                num: coordinate[coordinate.length - 1][2],
                status: coordinate[coordinate.length - 1][3],
                address: coordinate[coordinate.length - 1][4],
                geometry: new ol.geom.Point(routeCoords[routeLength - 1])
            });

            //轨迹上所有的坐标的集合
            let vector = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: [routeFeature, ...reallyPoint, geoMarker, startMarker, endMarker]
                }),
                style: function (feature) {
                    if (animating && feature.get('type') === 'geoMarker') {
                        return null;
                    }
                    return styles[feature.get('type')];
                }
            });

            //保存上一次的layer
            prevVector = vector;
            //在地图上添加坐标的点集
            that.map.addLayer(vector);

            // eslint-disable-next-line no-use-before-define
            startButton.addEventListener('click', startAnimation, false);
            // eslint-disable-next-line no-use-before-define
            setTimeout(() => startAnimation(), 50);
        } else if (coordinate.length > 0 && coordinate.length < 3) {
            //当做标点小于3个大于0个的时候
            let geometry = new ol.geom.LineString();
            for (let i = 0; i < coordinate.length; i++) {
                geometry.appendCoordinate(ol.proj.transform([coordinate[i][0], coordinate[i][1]], 'EPSG:4326', 'EPSG:3857'));
            }
            routeCoords = geometry.getCoordinates();
            routeLength = routeCoords.length;

            //小车行走的线路
            let routeFeature = new ol.Feature({
                type: 'route', state: 1,
                geometry: geometry
            });
            //运动的小车
            geoMarker = new ol.Feature({
                type: 'geoMarker', state: 1,
                geometry: new ol.geom.Point(routeCoords[0])
            });
            //轨迹开始坐标
            let startMarker = new ol.Feature({
                type: 'start', state: 0,
                num: coordinate[0][2],
                status: coordinate[0][3],
                address: coordinate[0][4],
                geometry: new ol.geom.Point(routeCoords[0])
            });
            //轨迹终止坐标
            let endMarker = new ol.Feature({
                type: 'end', state: 0,
                num: coordinate[coordinate.length - 1][2],
                status: coordinate[coordinate.length - 1][3],
                address: coordinate[coordinate.length - 1][4],
                geometry: new ol.geom.Point(routeCoords[routeLength - 1])
            });

            //轨迹上所有的坐标的集合
            let vector = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: [routeFeature, geoMarker, startMarker, endMarker]
                }),
                style: function (feature) {
                    if (animating && feature.get('type') === 'geoMarker') {
                        return null;
                    }
                    return styles[feature.get('type')];
                }
            });

            //保存上一次的layer
            prevVector = vector;
            //在地图上添加坐标的点集
            that.map.addLayer(vector);

            // eslint-disable-next-line no-use-before-define
            startButton.addEventListener('click', startAnimation, false);
            // eslint-disable-next-line no-use-before-define
            setTimeout(() => startAnimation(), 50);
        }

        //小车运动函数
        this.moveFeature = function (event) {
            let vectorContext = event.vectorContext;
            let frameState = event.frameState;
            if (animating) {
                if (retime === 0) {
                    elapsedTime = frameState.time - now;
                } else {

                    elapsedTime = frameState.time - retime;
                }
                retime = frameState.time;
                let index = Math.round(that.defaultCarSpeed * elapsedTime / 1000);
                traversed += index;
                that.index = traversed;
                if (traversed >= routeLength) {
                    //当小车运动到终点的时候
                    // eslint-disable-next-line no-use-before-define
                    moveEnd(true);
                    return;
                }
                let currentPoint = new ol.geom.Point(routeCoords[traversed]);
                let feature = new ol.Feature(currentPoint);
                vectorContext.drawFeature(feature, styles.geoMarker);
            }
            //设置运动的进度条
            that.setState({
                carProgerss: Math.round((that.index + 1) / routeLength * 100)
            })
            that.map.render();
        };

        //开始小车的运动
        function startAnimation() {
            traversed = 0;      //走过的路程
            elapsedTime = 0;    //用过的时间
            retime = 0;         //保存上次运动所用的时间
            if (animating) {
                // eslint-disable-next-line no-use-before-define
                refreshAnimation();
            } else {
                animating = true;
                now = new Date().getTime();
                //speed = that.defaultCarSpeed;
                geoMarker.setStyle(null);
                that.map.on('postcompose', that.moveFeature);
                that.map.render();
            }
        }

        //当小车运动到终点
        function moveEnd(isend) {
            animating = false;
            let coord = isend ? routeCoords[routeLength - 1] : routeCoords[0];
            (geoMarker.getGeometry()).setCoordinates(coord);
            //防止出现问题当调用次函数的时在设置一下进度条为100%
            that.setState({
                carProgerss: 100
            })
            that.map.un('postcompose', that.moveFeature);
        }

        //小车重新运动
        function refreshAnimation() {
            if (that.state.carProgerss === 100) {
                that.setState({
                    carProgerss: 0
                })
            }
            animating = false;
            if (that.state.canRefreshAnimation) {
                startAnimation();
            }
        }
    }

    //显示调节小车运动速度
    adjustSpeed = () => {
        this.setState((prevState) => ({
            showAdjustSpeed: !prevState.showAdjustSpeed
        }))
    }

    //改变小车队的行驶速度
    setNewSpeed = (value) => {
        this.defaultCarSpeed = value + 4;
    }

    //关闭用户打开的显示框
    closeMapMarker = () => {
        this.marker.setPosition(undefined);
        return false;
    }

    //监听地图的点击事件
    openMapMarker = (map) => {
        let that = this;
        let element = that.alertContainer;
        that.marker = new ol.Overlay({
            element: element,
            positioning: 'bottom-center',
            stopEvent: true,
            offset: [-5, -24],
            autoPan: true,
            autoPanAnimation: {
                duration: 250
            }
        });
        map.addOverlay(that.marker);
        let dom = document.createElement('div');
        dom.setAttribute('id', 'closeAlert');
        that.alertContainer.appendChild(dom);
        map.on('click', function (event) {
            let feature = map.forEachFeatureAtPixel(event.pixel, function (feature) {
                return feature;
            })
            if (feature) {
                //点击地图上大的坐标点的时候出现弹出框
                if (feature.get("state") === 0) {
                    let coordinatePoint = feature.getGeometry().getCoordinates();
                    that.marker.setPosition(coordinatePoint);
                    //弹出框显示出来
                    element.style.display = "block";
                    dom.onclick = that.closeMapMarker;
                    that.setState({
                        DAENumber: feature.get("num"),
                        DAEStatus: feature.get("status"),
                        DEAAddress: feature.get("address")
                    })
                }
            }
        });
    }

    //返回上一级菜单
    goBackUpperLevel = () => {
        this.props.backPrevLavel(this.state.defaultModeFlag);
    }

    render() {
        let {queryKeyWord} = this.state;
        const suffix = queryKeyWord ? <Icon type="close-circle" onClick={this.clearUserKeyWord}/> : null;
        return (
            <div className="pathContainer">
                <div className="headerContainer">
                    <Input
                        placeholder="请输入车牌号进行查询"
                        suffix={suffix}
                        onChange={this.userInputKeyWord}
                        value={queryKeyWord}
                        className="userInputKeyWord"
                    />
                    <RangePicker
                        onChange={this.userChangeQueryTime}
                        format="YYYY-MM-DD HH:mm"
                        showTime
                        className="userSelectQueryTime"
                        value={this.state.userChooseStartTime ? [moment(this.state.userChooseStartTime), moment(this.state.userChooseEndTime)] : null}
                    />
                    <Button onClick={this.getPathDatas} icon="search" className="queryButton">查询轨迹</Button>
                </div>
                <div className="displayContainer">
                    <div className="displayLeftContainer">
                        <div id="pathMapContainer" className="pathMapContainer">
                            {this.state.defaultShowBtnFlag &&
                            <Button onClick={this.goBackUpperLevel} icon="left" className="goBack">返回</Button>}
                            <div className="alertContainer" ref={(box) => {
                                this.alertContainer = box
                            }}
                            ><br/>
                                <div className="alertItem">
                                    <span className="alertSpan">采集器编号:</span><span
                                        className="alertSpanValue"
                                    >{this.state.DAENumber}</span>
                                </div>
                                <div className="alertItem">
                                    <span className="alertSpan">采集器状态:</span><span
                                        className="alertSpanValue"
                                    >{this.state.DAEStatus}</span>
                                </div>
                                <div className="alertItem">
                                    <span className="alertSpan">采集器地址:</span><span
                                        className="alertSpanValue"
                                    >{this.state.DEAAddress}</span>
                                </div>
                                <div className="triangleDown"></div>
                            </div>
                            <div className="adjustSpeed">
                                <img src={playback} className="imgSize" id="start-animation"/>
                                <Progress percent={this.state.carProgerss} status="active" className="progress"/>
                                <img src={speedcar} className="carImgSize" onClick={this.adjustSpeed}/>
                                {this.state.showAdjustSpeed && <div className="adjustSlider">
                                    <Slider vertical min={1} defaultValue={this.defaultCarSpeed}
                                        className="sliderChoose" onChange={this.setNewSpeed}
                                    />
                                </div>}
                            </div>
                        </div>
                    </div>
                    <div className="displayRightContainer">
                        <div className="pathTitle">
                            <span className="spanTitle">车辆轨迹查询</span>
                        </div>
                        <div className="pathTable" ref={(box) => {
                            this.tableContrainer = box
                        }}
                        >
                            <Table
                                pagination={false}
                                columns={this.state.columns}
                                dataSource={this.state.tableBodyData}
                                scroll={{y: this.state.scrollPathTableHeight}}
                            />
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default CarMove;
复制代码
.pathContainer{
  width: 100%;
  height: calc(~'100% - 60px');
  margin-top: 60px;
}
.headerContainer{
  width: 100%;
  height: 40px;
  padding-top: 4px;
}
.displayContainer{
  width:100%;
  height: calc(~'100% - 40px');
}
.userInputKeyWord{
  width: 280px;
  margin-left: 10px;
}
.userSelectQueryTime{
  width: 280px;
  margin-left: 4px;
}
.queryButton{
  margin-left: 4px;
  width: 100px;
}
.displayLeftContainer{
  width: calc(~'100% - 480px');
  height: 100%;
  float: left;
}
.displayRightContainer{
  width: 480px;
  height: 100%;
  z-index: 1;
  float: right;
  background-color: rgb(236, 236, 236);
}
.pathTitle{
  width: 100%;
  height: 35px;
  padding: 7px;
}
.spanTitle{
  font-size: 14px;
  color: #4291E9;
  margin-left: 5px;
}
.pathTable{
  width: 100%;
  height: calc(~'100% - 35px');
}
.pathMapContainer{
  height: 100%;
  position: relative;
  .ol-zoom{
    left: calc(~'100% - 46px');
    top: calc(~'100% - 72px');
    padding: 0px;
    box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.15);
    .ol-zoom-in{
      height: 26px;
      width: 26px;
      background-color: rgb(255, 255, 255);
      font-size: 20px;
      color: rgb(150, 150, 150);
      cursor: pointer;
      overflow: hidden;
      ::selection{
        color: white !important;
      }

    }
    .ol-zoom-out{
      cursor: pointer;
      height: 26px;
      width: 26px;
      background-color: rgb(255, 255, 255);
      font-size: 20px;
      color: rgb(150, 150, 150);
      overflow: hidden;
    }
  }
  .ol-attribution{
    display: none;
  }

}
.goBack{
  position: absolute;
  top: 17px;
  left: 35px;
  z-index: 1;
  color: rgb(100, 173, 255);
}
.adjustSpeed{
  width: 500px;
  height: 40px;
  position: absolute;
  z-index: 1;
  bottom: 2.7%;
  border-radius: 5px;
  background-color: rgb(254, 254, 254);
  left: 50%;
  margin-left: -250px;
}
.imgSize{
  width: 35px;
  height: 35px;
  margin-top: 4px;
  margin-left: 5px;
  cursor: pointer;
}
.progress{
  width: 400px;
  margin-left: 4px;
  position: absolute;
  margin-top: 11px;
}
.carImgSize{
  width: 35px;
  height: 35px;
  position: absolute;
  cursor: pointer;
  margin-left: 414px;
  margin-top: 2px;
}
.adjustSlider{
  background-color: snow;
  width: 28px;
  height: 181px;
  position: absolute;
  margin-top: -229px;
  border-radius: 6px;
  margin-left: 456px;
  padding-bottom: 16px;
  padding-top: 5px;
}
.alertContainer{
  width: 190px;
  height: 120px;
  background-color:white;
  border-radius: 5px;
  display: none;
  border: 1px solid lightgrey;
  -moz-user-select: text;
  user-select: text;
}
#closeAlert{
  position: absolute;
  right: 5%;
  top: 3%;
  width: 15px;
  height: 15px;
  cursor: pointer;
  background: url('../../Images/loginout.png') no-repeat ;
}
.alertItem{
  width: 93.6%;
  white-space: normal;
  word-break: break-all;
  margin-left: 8px;
}
.alertSpan{
  font-family: 'Microsoft YaHei';
  font-size: 12px;
  color: #111111;
}
.alertSpanValue{
  font-family: 'Microsoft YaHei';
  font-size: 12px;
  margin-left: 7px;
}
.triangleDown{
  position: absolute;
  width: 0;
  height: 0;
  border-left: 15px solid transparent ;
  border-right: 15px solid transparent ;
  border-top: 20px solid white;
  left: 50%;
  margin-left: -10px;
  bottom: -13px;
}

复制代码

效果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue是一种流行的JavaScript框架,用于构建用户界面。OpenLayers是一个开源的JavaScript库,用于在web浏览器中显示交互式地图。结合Vue和OpenLayers,我们可以实现台风轨迹的可视化。 首先,我们需要获取台风的相关数据。可以从台风数据的API或其他数据源中获取实时或历史台风数据。数据通常包含台风的经纬度坐标和其他相关信息,如风力、风速等。 在Vue组件中,我们可以使用OpenLayers显示地图。首先,在Vue组件中引入OpenLayers库,并在Vue的生命周期钩子中初始化地图。可以使用OpenLayers的地图视图类(MapView)来设置地图的中心坐标和缩放级别。 接下来,我们需要将台风的轨迹数据添加到地图上。可以使用OpenLayers的矢量图层(Vector Layer)来添加台风轨迹。将每个台风点的经纬度坐标转换为OpenLayers的几何对象,并将其添加到矢量图层中。 为了使台风轨迹更具交互性,可以在每个台风点上添加弹出窗口,显示该点的详细信息。可以使用OpenLayers的弹出窗口类(Overlay)和交互类(Interaction)来实现这一功能。 最后,根据需求,可以添加其他地图元素,如底图切换、比例尺、图例等,以增强用户体验。 总之,使用Vue和OpenLayers,我们可以方便地将台风轨迹可视化,并提供交互功能。这种方式可以帮助用户更直观地了解台风的路径和特征,从而提高对台风的认知和应对能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值