구글 지도를 한 번 놀고 나서 자동차를 도로에서 달리게 하는 것이 마치 우보에서 하는 것과 같다. 1부

당신이 우보에서 일하는 엔지니어라고 가정합시다.당신의 임무는 자동차가 목적지에 도착할 때 도로를 달리는 애니메이션을 설치하는 것입니다.그래서 React를 사용해야 합니다.어떻게 해요?

우리의 도구


이 안내서에서 Create React App withreact-google-maps를 사용할 것입니다. 이것은 구글 그래픽 라이브러리의 포장기이기 때문에 무엇을 해야 할지 알고 있습니다.npm install react-google-maps

기본 지도


기본 지도부터 시작합시다.구글 그래픽 라이브러리는 이렇게 초기화할 수 있다.
import React from 'react';
import { withGoogleMap, withScriptjs, GoogleMap } from 'react-google-maps'

class Map extends React.Component {
  render = () => {
    return (
      <GoogleMap
        defaultZoom={16}
        defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
        >
      </GoogleMap>
    )
  }
}

const MapComponent = withScriptjs(withGoogleMap(Map))

export default () => (
  <MapComponent
  googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
  loadingElement={<div style={{ height: `100%` }} />}
  containerElement={<div style={{ height: `400px`, width: '500px' }} />}
  mapElement={<div style={{ height: `100%` }} />}
  />
)
나는 어떻게 초기화하는지 상세하게 토론하지 않고 운동의 논리에 중점을 두려고 한다.만약 당신이 그것을 어떻게 설정하는지 배우고 싶다면, 당신은 read their guide 할 수 있다.
내가 사용하는 주요 도구는 react-google-maps로 구글 지도의 축소를 설치했다.축소가 높을수록 지면과 가까워진다defaultZoom. 이것은 지도의 주요 지리적 위치를 설정한다.
봉타카나 섬 (내가 사는 곳 가까이) 에 기본 지도를 한 장 실어야 한다.

위도와 경도


지도를 그리기 전에 우리는 위도와 경도를 알아야 한다.위도와 경도는 지리적 위치를 나타내는 단위다.위도수는 90에서 -90까지 가능하며 그중 0은 적도이고 경도수는 180에서 -180까지 가능하며 그중 0은 초급 자오선이다.
기본적으로 위도로 수직 위치를 제어하고 적도는 중심에 있으며 경도로 수평 위치를 제어하며 본초의 자오선은 중심에 있다.
구글 지도를 조작하기 위해서는 좌표가 어떻게 작동하는지 알 필요가 없다.구글은 거리를 측정하고 물체가 어디로 향하는지 계산하는 도구를 제공해 준다. 그들에게 좌표를 전달하기만 하면 된다.만약 당신이 깊이 파고드는 것에 흥미가 있다면, Wikipedia's article 에서 더 많은 내용을 읽을 수 있다.

표식


표지 지도의 위치를 표시하는데 일반적으로 우리가 모두 알고 있는 아이콘을 사용하여 위치를 표시한다.

태그는 위도와 논리를 알기 위해 특정 위치에 배치할 수 있습니다.우리는 섬 일주 중간에 다음과 같은 표시를 놓을 수 있다.
import React from 'react';
import { withGoogleMap, withScriptjs, GoogleMap, Marker } from 'react-google-maps'

class Map extends React.Component {
  render = () => {
    return (
      <GoogleMap
        defaultZoom={16}
        defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
        >
          <Marker position={{
            lat: 18.559024,
            lng: -68.388886,
          }} />
      </GoogleMap>
    )
  }
}

const MapComponent = withScriptjs(withGoogleMap(Map))

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

폴리선


다단선 구성 요소는 defaultCenter 속성(좌표 목록)을 바탕으로 지도에 선을 그립니다.우리는 두 개의 좌표로 직선을 그릴 수 있는데, 이것은 직선의 단점이다.
import React from "react";
import {
  withGoogleMap,
  withScriptjs,
  GoogleMap,
  Polyline
} from "react-google-maps";

class Map extends React.Component {
  path = [
    { lat: 18.55996, lng: -68.388832 },
    { lat: 18.558028, lng: -68.388971 }
  ];
  render = () => {
    return (
      <GoogleMap
        defaultZoom={16}
        defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
      >
        <Polyline path={this.path} options={{ strokeColor: "#FF0000 " }} />
      </GoogleMap>
    );
  };
}

const MapComponent = withScriptjs(withGoogleMap(Map));

export default () => (
  <MapComponent
    googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
    loadingElement={<div style={{ height: `100%` }} />}
    containerElement={<div style={{ height: `400px`, width: "500px" }} />}
    mapElement={<div style={{ height: `100%` }} />}
  />
);

우리는 방금 섬을 가로지르는 직선을 그렸다!하지만, 나는 운전할 때 이렇게 하는 것을 건의하지 않는다.
근데 라인은요?응, 나쁜 소식이 있어.커브가 없습니다.그것들은 단지 한 무더기의 직선일 뿐, 사람들에게 곡선이 있는 착각을 준다.만약 네가 충분히 확대한다면, 그것들은 항상 볼 수 있을 것이다.충분한 좌표를 추가해서 곡선을 그려봅시다.
import React from "react";
import {
  withGoogleMap,
  withScriptjs,
  GoogleMap,
  Polyline
} from "react-google-maps";

class Map extends React.Component {
  path = [
    { lat: 18.558908, lng: -68.389916 },
    { lat: 18.558853, lng: -68.389922 },
    { lat: 18.558375, lng: -68.389729 },
    { lat: 18.558032, lng: -68.389182 },
    { lat: 18.55805, lng: -68.388613 },
    { lat: 18.558256, lng: -68.388213 },
    { lat: 18.558744, lng: -68.387929 }
  ];
  render = () => {
    return (
      <GoogleMap
        defaultZoom={16}
        defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
      >
        <Polyline path={this.path} options={{ strokeColor: "#FF0000 " }} />
      </GoogleMap>
    );
  };
}

const MapComponent = withScriptjs(withGoogleMap(Map));

export default () => (
  <MapComponent
    googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
    loadingElement={<div style={{ height: `100%` }} />}
    containerElement={<div style={{ height: `400px`, width: "500px" }} />}
    mapElement={<div style={{ height: `100%` }} />}
  />
);

이게 네가 곡선을 그리는 방식이야!더 많은 좌표를 추가함으로써 우리는 선이 그렇게 눈에 띄지 않게 할 수 있다.

애니메이션 설정


이것이 바로 즐거움의 시작이다.path의 끝에 표시를 추가합니다.이것은 우리의 자동차와 그것이 전진하는 길을 대표할 것이다.
import React from "react";
import {
  withGoogleMap,
  withScriptjs,
  GoogleMap,
  Polyline,
  Marker
} from "react-google-maps";

class Map extends React.Component {
  path = [
    { lat: 18.558908, lng: -68.389916 },
    { lat: 18.558853, lng: -68.389922 },
    { lat: 18.558375, lng: -68.389729 },
    { lat: 18.558032, lng: -68.389182 },
    { lat: 18.55805, lng: -68.388613 },
    { lat: 18.558256, lng: -68.388213 },
    { lat: 18.558744, lng: -68.387929 }
  ];
  render = () => {
    return (
      <GoogleMap
        defaultZoom={16}
        defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
      >
        <Polyline path={this.path} options={{ strokeColor: "#FF0000 " }} />
        <Marker position={this.path[this.path.length - 1]} />
      </GoogleMap>
    );
  };
}

const MapComponent = withScriptjs(withGoogleMap(Map));

export default () => (
  <MapComponent
    googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
    loadingElement={<div style={{ height: `100%` }} />}
    containerElement={<div style={{ height: `400px`, width: "500px" }} />}
    mapElement={<div style={{ height: `100%` }} />}
  />
);

지금 우리는 애니메이션을 위해 논리를 준비해야 한다.우리는 일련의 직선이 있을 것이다. 우리는 차를 경로 안에 두어야 한다.우리는 논리를 네 단계로 나눌 수 있다.
  • 첫 번째 점과 각 좌표 사이의 거리를 계산합니다.이 가설 경로의 좌표는 질서정연하다.
  • 속도를 설정하고 자동차가 시간에 따라 운행하는 거리를 계산한다.
  • 계산 거리를 사용하면 우리는 완전한 경로를 사용하고 자동차가 지나가는 경로를 얻을 수 있다.
  • 자동차가 현재 있는 마지막 선에 애니메이션을 설정합니다.
  • 거리를 계산하다


    구글은 우리에게 두 좌표 사이의 거리를 계산하는 도구를 제공했다.이 함수는 path우리는 구성 요소를 설치하기 전에 이 절차를 실행할 수 있다.각 좌표와 경로의 첫 번째 요소 사이의 거리를 계산합니다.
      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)
      }
    
    

    속도를 설정하고 초당 거리를 계산합니다.


    이제 물리학에 들어갑니다.만약 우리가 물체가 초당 5m의 속도로 운동하기를 희망한다고 가정하자.이를 위해서는 초기 시간과 속도가 필요하다.우리 컨트롤러.1초마다 이 거리를 기록합니다.
      velocity = 5
      initialDate = new Date()
    
      getDistance = () => {
        // seconds between when the component loaded and now
        const differentInTime = (new Date() - this.initialDate) / 1000 // pass to seconds
        return differentInTime * this.velocity // d = v*t -- thanks Newton!
      }
    
      componentDidMount = () => {
        this.interval = window.setInterval(this.consoleDistance, 1000)
      }
    
      componentWillUnmount = () => {
        window.clearInterval(this.interval)
      }
    
      consoleDistance = () => {
        console.log(this.getDistance())
      }
    
    이 컨트롤러는우리 차의 속도처럼 초당 5씩 증가하는 숫자를 기록한다.
    우리들은 현재의 진전을 함께 두자.
    import React from 'react';
    import { withGoogleMap, withScriptjs, GoogleMap, Polyline, Marker } from 'react-google-maps'
    
    class Map extends React.Component {
      path = [
        { lat: 18.558908, lng: -68.389916 },
        { lat: 18.558853, lng: -68.389922 },
        { lat: 18.558375, lng: -68.389729 },
        { lat: 18.558032, lng: -68.389182 },
        { lat: 18.558050, lng: -68.388613 },
        { lat: 18.558256, lng: -68.388213 },
        { lat: 18.558744, lng: -68.387929 },
      ]
    
      velocity = 5
      initialDate = new Date()
    
      getDistance = () => {
        // seconds between when the component loaded and now
        const differentInTime = (new Date() - this.initialDate) / 1000 // pass to seconds
        return differentInTime * this.velocity // d = v*t -- thanks Newton!
      }
    
      componentDidMount = () => {
        this.interval = window.setInterval(this.consoleDistance, 1000)
      }
    
      componentWillUnmount = () => {
        window.clearInterval(this.interval)
      }
    
      consoleDistance = () => {
        console.log(this.getDistance())
      }
    
      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)
      }
    
      render = () => {
        return (
          <GoogleMap
            defaultZoom={16}
            defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
            >
              <Polyline path={this.path} options={{ strokeColor: "#FF0000 "}} />
              <Marker position={this.path[this.path.length - 1]} />
          </GoogleMap>
        )
      }
    }
    
    const MapComponent = withScriptjs(withGoogleMap(Map))
    
    export default () => (
      <MapComponent
      googleMapURL="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places"
      loadingElement={<div style={{ height: `100%` }} />}
      containerElement={<div style={{ height: `400px`, width: '500px' }} />}
      mapElement={<div style={{ height: `100%` }} />}
      />
    )
    
    

    실시간 렌더링 궤적


    지금 우리는 실시간으로 자동차를 렌더링해야 한다.우리는 일련의 직선이 있는데, 자동차는 두 직선 이내에 있을 것이다.따라서 우리는 일부 논리를 우리의 상태로 옮기고 초마다 갱신할 것이다.
    우선, 우리는 google.maps.geometry.spherical.computeDistanceBetween 상태를 추가하고 다단선과 표식이 이 상태를 따르도록 하겠습니다.
      state = {
        progress: [],
      }
    
      render = () => {
        return (
          <GoogleMap
            defaultZoom={16}
            defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
            >
              { this.state.progress && (
                <>
                  <Polyline path={this.state.progress} options={{ strokeColor: "#FF0000 "}} />
                  <Marker position={this.state.progress[this.state.progress.length - 1]} />
                </>
              )}
          </GoogleMap>
        )
      }
    }
    
    현재, 우리는 orprogressconsoleDistance로 변경하고, 자동차가 이미 통과한 경로 부분을 추출할 수 있다.
      componentDidMount = () => {
        this.interval = window.setInterval(this.moveObject, 1000)
      }
    
      moveObject = () => {
        const distance = this.getDistance()
        if (! distance) {
          return
        }
        const progress = this.path.filter(coordinates => coordinates.distance < distance)
        this.setState({ progress })
      }
    
    위에서 말한 바와 같이 우리는 다음과 같다.
    네가 주의한 바와 같이 자동차는 도약한다. 왜냐하면 우리는 이미 통과한 선을 추가하고 있지만, 자동차는 moveObject의 마지막 원소와 progress의 나머지 원소 사이에 있기 때문이다.따라서 애니메이션을 더욱 매끄럽게 하기 위해서 우리는 이 두 선의 진도를 알고 이 두 선의 좌표를 찾아야 한다.구글은 우리에게 이런 기능을 제공했다. 클릭this.path.google.maps.geometry.spherical.interpolate 기능을 완료하면 다음과 같은 이점이 있습니다.
      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 })
      }
    
    지금 매끄러워 보여요!
    우리의 결과는 다음과 같다.
    import React from 'react';
    import { withGoogleMap, withScriptjs, GoogleMap, Polyline, Marker } from 'react-google-maps'
    
    class Map extends React.Component {
      state = {
        progress: [],
      }
    
      path = [
        { lat: 18.558908, lng: -68.389916 },
        { lat: 18.558853, lng: -68.389922 },
        { lat: 18.558375, lng: -68.389729 },
        { lat: 18.558032, lng: -68.389182 },
        { lat: 18.558050, lng: -68.388613 },
        { lat: 18.558256, lng: -68.388213 },
        { lat: 18.558744, lng: -68.387929 },
      ]
    
      velocity = 5
      initialDate = new Date()
    
      getDistance = () => {
        // seconds between when the component loaded and now
        const differentInTime = (new Date() - this.initialDate) / 1000 // pass to seconds
        return differentInTime * this.velocity // d = v*t -- thanks Newton!
      }
    
      componentDidMount = () => {
        this.interval = window.setInterval(this.moveObject, 1000)
      }
    
      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)
      }
    
      render = () => {
        return (
          <GoogleMap
            defaultZoom={16}
            defaultCenter={{ lat: 18.559008, lng: -68.388881 }}
            >
              { this.state.progress && (
                <>
                  <Polyline path={this.state.progress} options={{ strokeColor: "#FF0000 "}} />
                  <Marker 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?v=3.exp&libraries=geometry,drawing,places"
      loadingElement={<div style={{ height: `100%` }} />}
      containerElement={<div style={{ height: `400px`, width: '500px' }} />}
      mapElement={<div style={{ height: `100%` }} />}
      />
    )
    
    
    이제 우리는 우리의 경로와 속도를 바꾸어 그것을 더욱 좋아지게 하기만 하면 된다.이것은 노선과 조종사에 달려 있다.
    100km/h의 속도에서 우리는 더 좋은 경로this의 놀라운 도구 생성을 사용한다.
    두 번째 부분에서, 우리는 자동차 아이콘을 사용자 정의하여 전진 방향을 향하게 할 것이다.
    만약 당신에게 무슨 문제가 있으면 저에게 알려주세요:D

    좋은 웹페이지 즐겨찾기