我是地图新手,我需要实现一条路线并获得距离。我正在使用react-google-mapsAPI,我已经找到了显示地图和路线的方法。
这是我第一次构建这样的组件,现在我不知道如何访问类组件之外的数据。基本上,我想将搜索框中的数据(坐标(添加到DirectionService.route中的原点,并获取距离。你知道我怎样才能访问这些数据吗?
我一直在读到组件WillMount被弃用的消息,但这是我让它工作的唯一方法,如果你有任何建议,我很乐意尝试。
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密钥,以后不要在公共网站上发布以保护它。
我成功地编写了您的用例,但我使用了@react谷歌地图/api,因为这是对(遗憾的是未维护的(react谷歌映射库的完全重写。然后,我使用了OnLoad
回调,而不是componentWillMount
,该回调是在加载映射实例时调用的。
请参阅此处的工作示例代码和下面带有内联注释的代码片段:
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;