index.tsx 8.84 KB
import React, { useState, useEffect, useRef } from 'react';
import {message, Input, Button} from 'antd';
import AMapLoader from "@amap/amap-jsapi-loader";
import {getPointsData, getPointsDataMock} from '../../api';
import useUpdateEffect from '../useUpdateEffect';
import PlayBackPicker from '../PlayBackPicker';
import './style.less';

interface searchParams<T>{
    trid?:number | undefined;
    date:Array<T>
}
interface DateParams {
    startTime?: number;
    endTime?:number;
    trid?:number;
}
function MapContent(props:any) {
    const { trackParams, id} = props;
    const trid = useRef<number | undefined>(undefined);
    const date = useRef<Array<number | null>>([]);
    const [searchParams, setSearchParams] = useState<searchParams<number | null>>({trid: trid.current, date: date.current});
    //地图
    const map = useRef<any>(null);
    const amapCopy = useRef<any>(null);
    const marker = useRef<Array<any>>([]);
    const [tracksFilter, setTracksFilter] = useState<Array<any>>([]);
    useEffect(() => {
        initMap();    
        return () => {
        };
    }, []);
    useEffect(() => {
        if (!trackParams) return;
        let dateParams ={} as DateParams;
        const {trid, date} = searchParams;
        if (trid) {
            dateParams.trid = trid; 
        }   
        if (date[0] && date[1]) {
            dateParams.startTime = date[0];
            dateParams.endTime = date[1];
        }
        getPointsData({...trackParams, ...dateParams}).then(res => {
            const {data: {data: tracksData}}=res;
            if (res.data.errcode === 20000) {
                message.warning('请选择24小时以内的时间段');
                return;
            } 
            const { tracks }= tracksData;
            let tracksFilterData:Array<any> = [];
                tracks?.forEach((item:any, index:any) => {
                let tracksArr:Array<Array<number>> = [];
                item.startPoint && tracksArr.unshift(item?.startPoint?.location.split(',').map(Number));
                const points = filterPoint(item?.points);
                tracksArr.push(...points);
                item.endPoint && tracksArr.push(item?.endPoint?.location.split(',').map(Number));
                tracksArr.length && tracksFilterData.push(tracksArr);
            });
            setTracksFilter(tracksFilterData);
            mapPlayBack(tracksFilterData);
        }).catch((e) => {
            message.error('此时间段没有你想要的数据!');
        });
    }, [searchParams, trackParams]);

    /**
     * @description: 地图轨迹展示
     * @param {*}
     * @return {*}
     */
    const mapPlayBack = (tracksData:Array<any>) => {
        amapCopy.current.plugin('AMap.MoveAnimation', () => {
            map.current = new amapCopy.current.Map(id, { //设置地图容器id
                viewMode: "3D", //是否为3D地图模式
                resizeEnable: true,
                zoom: 8, //初始化地图级别
                // center: tracksData[0][0], //初始化地图中心点位置
            });
            tracksData.forEach(tracks => {
                //
                const markerItem = new amapCopy.current.Marker({
                    map: map.current,
                    position: tracks[0], //轨迹起点
                    icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
                    offset: new amapCopy.current.Pixel(-13, -26),
                });
                const polyline = new amapCopy.current.Polyline({
                    map: map.current,
                    path: tracks,
                    showDir: true,
                    strokeColor: "#28F", //线颜色
                    // strokeOpacity: 1,     //线透明度
                    strokeWeight: 8, //线宽
                    lineJoin: 'round',
                    strokeStyle: "solid" //线样式
                });
                marker.current.push(markerItem);
                map.current.add(markerItem);
                map.current.add(polyline);
                const passedPolyline = new amapCopy.current.Polyline({
                    map: map.current,
                    strokeColor: "#AF5", //线颜色
                    strokeWeight: 6, //线宽
                });
                markerItem.on('moving', (e:any) => {
                    passedPolyline.setPath(e.passedPath);
                    map.current.setCenter(e.target.getPosition(), true);
                });
            });
            map.current.setFitView();
        });                
     };
    /**
     * @description: 过滤坐标点
     * @param {Array} points
     * @return {*}
     */
    const filterPoint= (points:Array<any>):Array<any> => {
        if (!points.length) return [];
        const arr = points.map((item) => {
            const {location }= item;
            const locationarr = location.split(',').map(Number);
            return locationarr;
        });
        return arr;
    };

    /**
     * @description: 开始回放
     * @param {*}
     * @return {*}
     */
    const startAnimation = () => {
        console.log(1);
        tracksFilter.forEach((item, index) => {
            marker.current[index].moveAlong(item, {
                 // 每一段的时长
                 duration: 200, //可根据实际采集时间间隔设置
                 // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
                 autoRotation: true,
            });
        });
    };

    /**
     * @description: 暂停动画
     * @param {*}
     * @return {*}
     */        
    const pauseAnimation = () => {
        const {current} = marker;
        current.forEach((item, index) => {
            current[index].pauseMove();
        });
    }; 
    /**
     * @description: 继续动画
     * @param {*}
     * @return {*}
     */    
    const resumeAnimation = () => {
        const {current} = marker;
        current.length && current.forEach((item, index) => {
            current[index].resumeMove();
        });
    };
    /**
     * @description: 停止动画
     * @param {*}
     * @return {*}
     */    
    const stopAnimation = () => {
        const {current} = marker;
        current.forEach((item, index) => {
            current[index].stopMove();
        });
    };
    /**
     * @description: 初始化地图
     */
    const initMap = () => {
        AMapLoader.load({
            key: "cff67340b4badf3492b476c18c073b69", // 申请好的Web端开发者Key,首次调用 load 时必填
            version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
            plugins: ["AMap.Geolocation", "AMap.AutoComplete", "AMap.PlaceSearch"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then((AMap) => {
            amapCopy.current = AMap;
            map.current = new AMap.Map(id, { //设置地图容器id
                viewMode: "3D", //是否为3D地图模式
                resizeEnable: true,
                zoom: 10, //初始化地图级别
                center: [104.06, 30.67], //初始化地图中心点位置
            });
        }).catch(e => {
            console.log('e', e);
        });
    };
    
    /**
     * @description: 手动获取时间
     * @param {*}
     * @return {*}
     */
    const handelDate = (val:Array<any>) => {
        date.current = val;
    };
    return (
      <div className="map_box">
        <div className="right_top">
          <div className="top_input">
            <Input
              placeholder="轨迹ID"
              onBlur={(event) => {
                    trid.current = parseInt(event.target.value, 10);
                }}
            />
          </div>
          <PlayBackPicker
            handelDate={handelDate}
          />
          <div>
            <Button
              className="back_btn" 
              type="primary"
              onClick={() => {
                    setSearchParams({trid: trid.current, date: date.current});
                    if (!trackParams)message.warning('请在列表中选择终端!');
                }}
            >
              查询
            </Button>
          </div>
        </div>
        <div id={id} className="map_main" />
        {
            tracksFilter.length? (
              <div className="play_back_btn_box">
                <div className="btn_item">
                  <Button type="primary" className="play_back_btn" onClick={startAnimation}>开始回放</Button>
                  <Button type="primary" className="play_back_btn" onClick={pauseAnimation}>暂停回放</Button>
                </div>
                <div className="btn_item">
                  <Button type="primary" className="play_back_btn" onClick={resumeAnimation}>继续回放</Button>
                  <Button type="primary" className="play_back_btn" onClick={stopAnimation}>停止回放</Button>
                </div>
              </div>
            ):null
        }
        
      </div>
    );
}
export default MapContent;