微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

反应谷歌地图车辆实时跟踪

如何解决反应谷歌地图车辆实时跟踪

我试图通过从 api 端点获取数据来移动带有 deviceid 的选定标记。在第一次渲染时,我正在获取最后 1 分钟的坐标数据并将坐标推送到一个声明为 Path 的空数组中,每 30 秒后我运行一个 setinterval 函数,该函数每 30 秒获取最后 30 秒的数据并推送路径数组中的坐标。这是可以提供一些想法的代码

import {
  withGoogleMap,withScriptjs,GoogleMap,polyline,Marker
} from "react-google-maps";
const mapStyles = require("./mapStyles.json");


const Map = ({deviceid}) =>  {
  const [progress,setProgress]= useState()  
  const path= []

  const getinitialPositions = async () => {
    let from = new Date()
    let milliseconds = Date.parse(from)
    milliseconds = milliseconds - (1* 60 * 1000)
    from = new Date(milliseconds).toISOString()
    console.log(from)
    const to = new Date().toISOString()
    console.log(to)
    const response = await fetch(`/api/positions/?deviceid=${37}&from=${from}&to=${to}`,{
      headers: {
        'Accept': 'application/json' 
      }
    })
      const items = await response.json()
    
      console.log(items)
      items.map( item => { 
        path.push({lat: item.latitude,lng: item.longitude})
        return path
      })   
      console.log(path)
  };

  const getPositions30Seconds = async () => {
    let from = new Date()
    let milliseconds = Date.parse(from)
    milliseconds = milliseconds - (0.5* 60 * 1000)
    from = new Date(milliseconds).toISOString()
    console.log(from)
    const to = new Date().toISOString()
    console.log(to)
    const response = await fetch(`/api/positions/?deviceid=14&from=${from}&to=${to}`,{
      headers: {
        'Accept': 'application/json' 
      }
    })
      const items = await response.json()
      console.log(items)
      items.map( item => { 
        path.push({lat: item.latitude,lng: item.longitude})
        return path
      })   
      console.log(path)
  };

  useEffect (() => {
    const interval = window.setInterval(getPositions30Seconds,30000)
    return () => {
      window.clearInterval(interval)
    }
  },[]);

  useEffect(()=>{
    getinitialPositions()  
  },[])
  
    const icon = {
        url: '/images/icon/car.png',scaledSize: new window.google.maps.Size(30,30),anchor: { x: 10,y: 10 }
      };
      return (
        <GoogleMap
          defaultZoom={4}
          defaultCenter={path[path.length-1]}
          defaultOptions={{ styles: mapStyles,fullscreenControl: false,mapTypeControl: false,streetViewControl: false}}
        >
        {progress && (
          <>
            <polyline
              path={progress}
              options={{ strokeColor: "light" }}
            />
            
            <Marker
              icon={icon}  
              position={progress[progress.length - 1]}  
            />

          </>
        )}
    
        </GoogleMap>
      );
    };


const MapComponent = withScriptjs(withGoogleMap(Map))

export default () => (
  <MapComponent
    googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLEMAP_KEY}&v=3.exp&libraries=geometry,drawing,places`}
    loadingElement={<div style={{ height: `100%` }} />}
    containerElement={<div style={{ height: `100%`,width: '100%' }} />}
    mapElement={<div style={{ height: `100%` }} />}
  />
)

我想像下面提到的具有静态路径数组数据的类组件一样使用这个路径数组。

import React from "react";
import {
  withGoogleMap,Marker
} from "react-google-maps";
const mapStyles = require("./mapStyles.json");

class Map extends React.Component {
  state = {
    progress: [],selectedMarker: false
  };

  path = [
    { lat: 28.539533333333335,lng: 77.05334444444445},{lat: 28.539581666666667,lng: 77.05323333333334},{lat: 28.539614999999998,lng: 77.05313333333334},{lat: 28.539766666666665,lng: 77.05258166666667},{lat: 28.539884444444443,lng: 77.05252666666667},{lat: 28.542425,lng: 77.05253666666667},{lat: 28.544408333333333,lng: 77.05254333333333},{lat: 28.544445,lng: 77.052655},{lat: 28.544383333333332,lng: 77.05419333333333},{lat: 28.544439999999998,lng: 77.05512},{lat: 28.544561666666667,lng: 77.055295},{lat: 28.546363333333336,lng: 77.05680833333334},{lat: 28.54712166666667,lng: 77.05741277777777},{lat: 28.547226666666667,lng: 77.05737},{lat: 28.54752166666667,lng: 77.05704},{lat: 28.547706666666667,lng: 77.05692833333333},{lat: 28.548081666666665,lng: 77.05644666666666},{lat: 28.548235000000002,lng: 77.05629},{lat: 28.548571666666668,lng: 77.05574333333333},{lat: 28.548655,lng: 77.05571166666667},{lat: 28.548745,lng: 77.05563666666667},{lat:28.55049,lng: 77.05438},{lat: 28.550714999999997,lng: 77.05413666666666},{lat: 28.55175,lng: 77.05356833333333},{lat: 28.553496666666668,lng: 77.05223166666667},{lat: 28.553915,lng: 77.05173833333333 }
];

  veLocity = 50;
  initialDate = new Date();

  getdistance = () => {
    // seconds between when the component loaded and Now
    const differentInTime = (new Date() - this.initialDate) / 8000; // pass to seconds
    return differentInTime * this.veLocity; 
  };

  componentDidMount = () => {
    this.interval = window.setInterval(this.moveObject,100);
  };

  handleClick = (marker,event) => {
    // console.log({ marker })
    this.setState({ selectedMarker: marker })
  }

  componentwillUnmount = () => {
    window.clearInterval(this.interval);
  };

  moveObject = () => {
    const distance = this.getdistance();
     if (!distance) {
      return;
    }

    let progress = this.path.filter(
      coordinates => coordinates.distance < distance
    );

    const nextLine = this.path.find(
      coordinates => coordinates.distance > distance
    );
    if (!nextLine) {
      this.setState({ progress });
      return; // it's the end!
    }
    const lastLine = progress[progress.length - 1];

    const lastLineLatLng = new window.google.maps.LatLng(
      lastLine.lat,lastLine.lng
    );

    const nextLineLatLng = new window.google.maps.LatLng(
      nextLine.lat,nextLine.lng
    );

    // distance of this line
    const totaldistance = nextLine.distance - lastLine.distance;
    const percentage = (distance - lastLine.distance) / totaldistance;

    const position = window.google.maps.geometry.spherical.interpolate(
      lastLineLatLng,nextLineLatLng,percentage
    );

    progress = progress.concat(position);
    this.setState({ progress });
  };

  componentwillMount = () => {
    this.path = this.path.map((coordinates,i,array) => {
      if (i === 0) {
        return { ...coordinates,distance: 0 }; // it begins here!
      }
      const { lat: lat1,lng: lng1 } = coordinates;
      const latLong1 = new window.google.maps.LatLng(lat1,lng1);

      const { lat: lat2,lng: lng2 } = array[0];
      const latLong2 = new window.google.maps.LatLng(lat2,lng2);

      // in meters:
      const distance = window.google.maps.geometry.spherical.computedistanceBetween(
        latLong1,latLong2
      );

      return { ...coordinates,distance };
    });

    console.log(this.path);
  };

  componentDidUpdate = () => {
    const distance = this.getdistance();
    if (!distance) {
      return;
    }

    let progress = this.path.filter(
      coordinates => coordinates.distance < distance
    );

    const nextLine = this.path.find(
      coordinates => coordinates.distance > distance
    );

    let point1,point2;

    if (nextLine) {
      point1 = progress[progress.length - 1];
      point2 = nextLine;
    } else {
      // it's the end,so use the latest 2
      point1 = progress[progress.length - 2];
      point2 = progress[progress.length - 1];
    }

    const point1LatLng = new window.google.maps.LatLng(point1.lat,point1.lng);
    const point2LatLng = new window.google.maps.LatLng(point2.lat,point2.lng);

    const angle = window.google.maps.geometry.spherical.computeheading(
      point1LatLng,point2LatLng
    );
    const actualAngle = angle - 35;

    const markerUrl =
    '/images/icon/car.png'
    const item = document.querySelector(`[src="${markerUrl}"]`);

    if (item) {
      // when it hasn't loaded,it's null
      item.style.transform = `rotate(${actualAngle}deg)`;
    }
  };

  render = () => {
    const icon = {
        url: '/images/icon/car.png',scaledSize: new window.google.maps.Size(35,35),y: 10 }
      };
    return (
        <GoogleMap
          defaultZoom={18}
          defaultCenter={{lat: 28.539766666666665,lng: 77.05258166666667}}
          defaultOptions={{ 
              styles: mapStyles,streetViewControl: false,}}
        >
        {this.state.progress && (
          <>
            <polyline
              path={this.state.progress}
              options={{ strokeColor: "gray" }}
            />
            
            <Marker
              icon={icon}  
              position={this.state.progress[this.state.progress.length - 1]}  
            />

          </>
        )}
      </GoogleMap>
    );
  };
}

const MapComponent = withScriptjs(withGoogleMap(Map));

export default () => (
    <MapComponent
    googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLEMAP_KEY}&v=3.exp&libraries=geometry,width: '100%' }} />}
    mapElement={<div style={{ height: `100%` }} />}
    />
  )

它工作正常(使用静态数据)并且标记平滑移动,但是。我想为每个点击的设备动态实现这一点。我发布这个是因为我被卡住了,因为我是新来的反应。我发现钩子有点容易,所以尝试使用功能组件但没有做到。卡住了 5 天,现在我很无助。有人帮我实现这个魅力。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。