带有react-google-maps API的Google地图 [英] Google map with react-google-maps API

查看:53
本文介绍了带有react-google-maps API的Google地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是地图的新手,我需要实现一条路线并获取距离.我正在使用react-google-map s API,并且发现了这种显示地图和路线的方法.

I'm new with maps and I need to implement a route and also get the distance. I'm using react-google-maps API and I have found this way to show the map, and the route.

这是我第一次构建这样的组件,但是现在我不知道如何访问类组件外部的数据.基本上,我想将搜索框(坐标)中的数据添加到DirectionService.route中的原点,并获取距离.您知道我该如何访问这些数据吗?

It is the first time that I build a component like this and now I don't know how to access the data that is outside the class component. Basically, I would like to add the data from the search box (coordinates) to the origin in the DirectionService.route, and also to get the distance. Do you know how can I access that data?

我一直在阅读不赞成使用componentWillMount的方法,但这是我使其工作的唯一途径,如果您有任何建议,我将很乐意尝试.

I've been reading that componentWillMount is being deprecated but it is the only way that I made it work, if you have any suggestions I'll be happy to try.

import React from 'react'
import  { compose, withProps, lifecycle } from 'recompose'
import {withScriptjs, withGoogleMap, GoogleMap, DirectionsRenderer} from 'react-google-maps'
const {
  StandaloneSearchBox
} = require("react-google-maps/lib/components/places/StandaloneSearchBox");

const DirectionsComponent = compose(
  withProps({
    googleMapURL: "https://maps.googleapis.com/maps/api/js?key='yourkey'&libraries=geometry,drawing,places",
    loadingElement: <div style={{ height: `400px` }} />,
    containerElement: <div style={{ width: `100%` }} />,
    mapElement: <div style={{height: `600px`, width: `600px` }}  />,
  }),
  
  withScriptjs,
  withGoogleMap,
  lifecycle({
    componentWillMount() {
      const refs = {};

      this.setState({
        places: [],
        onSearchBoxMounted: ref => {
          refs.searchBox = ref;
        },
        onPlacesChanged: () => {
          const places = refs.searchBox.getPlaces();
          console.log(places)

          this.setState({
            places
          });
        }
      });
    },

    componentDidMount() { 
      const google = window.google
      const DirectionsService = new google.maps.DirectionsService();

      DirectionsService.route({
        origin: new google.maps.LatLng(41.3851, -2.1734),
        destination: new google.maps.LatLng(40.4165, -3.70256),
        travelMode: google.maps.TravelMode.DRIVING,
      }, (result, status) => {
        console.log(result)
        if (status === google.maps.DirectionsStatus.OK) {
          this.setState({
            directions: {...result},
            markers: true
          })
          const distance = result.routes[0].legs[0].distance['text']
          console.log(distance)
        } else {
          console.error(`error fetching directions ${result}`);
        }
      });
    }
  })
)(props =>
  <div data-standalone-searchbox="">
    <StandaloneSearchBox
      ref={props.onSearchBoxMounted}
      bounds={props.bounds}
      onPlacesChanged={props.onPlacesChanged}
    >
      <input
        type="text"
        placeholder="Enter your destination"
        style={{
          boxSizing: `border-box`,
          border: `1px solid transparent`,
          width: `240px`,
          height: `32px`,
          padding: `0 12px`,
          borderRadius: `3px`,
          boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
          fontSize: `14px`,
          outline: `none`,
          textOverflow: `ellipses`
        }}
      />
    </StandaloneSearchBox>
    <ol>
      {props.places.map(
        ({ place_id, formatted_address, geometry: { location } }) => (
          <li key={place_id}>
            {formatted_address}
            {" at "}
            ({location.lat()}, {location.lng()})
          </li>
        )
      )}
    </ol>

  <GoogleMap defaultZoom={3}>
    {props.directions && <DirectionsRenderer directions={props.directions} suppressMarkers={props.markers} />}
  </GoogleMap>
</div>
  
);

class MyMapComponent extends React.PureComponent {
  constructor(props) {
    super(props)
    console.log(props)
    this.state = {

    }
  }
  

render() {
    return (
      <div>
        
        <DirectionsComponent/>
      </div>
      
    )
  }
}
export default MyMapComponent

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

推荐答案

首先,请删除问题中的API密钥,以后请勿在公共站点发布该API密钥以对其进行保护.

First of, please remove the API key in your question and don't post it in public sites in the future to protect it.

我成功编码了您的用例,但我使用了 @ react-google-maps/api ,因为这是对(严重缺乏维护的)react-google-maps库的完整重写.然后,我使用了 OnLoad 回调,而不是 componentWillMount ,该回调在地图实例加载后调用.

I successfully coded your use case but I used the @react-google-maps/api since this is a complete re-write of the (sadly unmaintained) react-google-maps library. Then instead of componentWillMount I used the OnLoad callback used which is called when the map instance has loaded.

请在此处中查看有效的示例代码和代码带有以下嵌入式注释的代码段:

Please see the working sample code here and code snippet with inline comments below:

Index.js

import React, { Component } from "react";
import { render } from "react-dom";
import { LoadScript } from "@react-google-maps/api";
import Map from "./Map";
import "./style.css";

const lib = ["places"];
const key = ""; // PUT GMAP API KEY HERE
class App extends React.Component {
  render() {
    return (
      <LoadScript googleMapsApiKey={key} libraries={lib}>
        <Map />
      </LoadScript>
    );
  }
}

render(<App />, document.getElementById("root"));

Map.js

/*global google*/
import ReactDOM from "react-dom";
import React from "react";

import {
  GoogleMap,
  StandaloneSearchBox,
  DirectionsRenderer
} from "@react-google-maps/api";

const defaultLocation = { lat: 40.756795, lng: -73.954298 };
let destination = { lat: 41.756795, lng: -78.954298 };
let origin = { lat: 40.756795, lng: -73.954298 };
let directionsService;
class Map extends React.Component {
  state = {
    directions: null,
    bounds: null
  };

  onMapLoad = map => {
    directionsService = new google.maps.DirectionsService();
    //load default origin and destination
    this.changeDirection(origin, destination);
  };

  //function that is called when SearchBox has loaded and assigned ref to this.searchbox  to get the searchbox object
  onSBLoad = ref => {
    this.searchBox = ref;
  };

  onPlacesChanged = () => {
    //pass the new place location as the origin
    this.changeDirection(
      this.searchBox.getPlaces()[0].geometry.location,
      destination
    );
  };

  //function that is calling the directions service
  changeDirection = (origin, destination) => {
    directionsService.route(
      {
        origin: origin,
        destination: destination,
        travelMode: google.maps.TravelMode.DRIVING
      },
      (result, status) => {
        if (status === google.maps.DirectionsStatus.OK) {
          //changing the state of directions to the result of direction service
          this.setState({
            directions: result
          });
        } else {
          console.error(`error fetching directions ${result}`);
        }
      }
    );
  };

  render() {
    return (
      <div>
        <div id="searchbox">
          <StandaloneSearchBox
            onLoad={this.onSBLoad}
            onPlacesChanged={this.onPlacesChanged}
          >
            <input
              type="text"
              placeholder="Customized your placeholder"
              style={{
                boxSizing: `border-box`,
                border: `1px solid transparent`,
                width: `240px`,
                height: `32px`,
                padding: `0 12px`,
                borderRadius: `3px`,
                boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
                fontSize: `14px`,
                outline: `none`,
                textOverflow: `ellipses`,
                position: "absolute",
                left: "50%",
                marginLeft: "-120px"
              }}
            />
          </StandaloneSearchBox>
        </div>
        <br />
        <div>
          <GoogleMap
            center={defaultLocation}
            zoom={5}
            onLoad={map => this.onMapLoad(map)}
            mapContainerStyle={{ height: "400px", width: "800px" }}
          >
            {this.state.directions !== null && (
              <DirectionsRenderer directions={this.state.directions} />
            )}
          </GoogleMap>
        </div>
      </div>
    );
  }
}

export default Map;

这篇关于带有react-google-maps API的Google地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆