-1

I am building a simple project that if a user clicks a button it should show directions from the user's location to the destination which I mark. Here is my code. I have just implemented some parts but I did not understand how to implement DirectionsRenderer and could not learn from articles, docs. Now I have no idea what to do. Can anyone explain me in a easier way? Thank you!

  GoogleMap,
  withGoogleMap,
  withScriptjs,
  DirectionsRenderer,
} from 'react-google-maps';

import Marker from 'react-google-maps/lib/components/Marker';
function Map() {
  return (
    <div className='App'>
      <GoogleMap
        defaultZoom={10}
        defaultCenter={{ lat: 51.507351, lng: -0.127758 }}
      >
        <Marker position={{ lat: 51.4666, lng: -0.213 }} />
      </GoogleMap>
    </div>
  );
}
const DirectionsService = new window.google.maps.DirectionsService();
DirectionsService.route({
  origin: new window.google.maps.LatLng(41.85073, -87.65126),
  destination: new window.google.maps.LatLng(41.85258, -87.65141),
  travelMode: window.google.maps.TravelMode.DRIVING,
});
const WrappedMap = withScriptjs(withGoogleMap(Map));

function App() {
  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <WrappedMap
        googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=${process.env.REACT_APP_MAP_KEY}`}
        loadingElement={<div style={{ height: `100%` }} />}
        containerElement={<div style={{ height: `100%` }} />}
        mapElement={<div style={{ height: `100%` }} />}
      />
    </div>
  );
}

export default App;

Dilshod Sh
  • 264
  • 2
  • 11

1 Answers1

0

Here are the steps I made to achieve your use-case:

  1. Use the browser's HTML5 Geolocation feature to get the user's current position inside the componentDidMount.
  2. Then use state variables to hold the value of the current location. You also put the value of the user current location state to center parameter of your GoogleMap object so that the map will show the area of the map where the user is. This will be used as the origion of your Directions service. 3.Also use another state to hold the user current location. This is to be used as state to put a marker in the user current location.
  3. Call a function inside the onClick parameter of your GoogleMap object. Then use another state variable that will hold the value of the clicked coordinates. This will be used as the destination of the Directions Service.
  4. Put a button on top of your map div and call a function inside its OnClick parameter.The function will call the GoogleMaps directionsService and will calculate a route between your origin and destination. If there's a route, you use another state variable to hold the result of the Directions service.
  5. Use the DirectionsRenderer object inside the GoogleMap object to display the polyline of the route.

Here's the sample code (Note: Make sure to put your API key in the index.js for the sample to work) and the code snippet below:

/*global google*/
import React, { Component } from 'react';
import Button from 'react-bootstrap/Button';
import {
  withGoogleMap,
  Marker,
  GoogleMap,
  DirectionsRenderer
} from 'react-google-maps';
class Map extends Component {
  state = {
    directions: null,
    markerPos: null,
    centerMarker: null,
    currentLocation: null
  };

  componentDidMount = () => {
    navigator?.geolocation.getCurrentPosition(
      ({ coords: { latitude: lat, longitude: lng } }) => {
        const pos = { lat, lng };
        this.setState({ currentLocation: pos, centerMarker: pos });
      }
    );
  };

  onMapClick = e => {
    this.setState({ markerPos: e.latLng });
  };

  getDirections = () => {
    const directionsService = new google.maps.DirectionsService();

    const origin = this.state.currentLocation;
    const destination = this.state.markerPos;

    if (origin !== null && destination !== null) {
      directionsService.route(
        {
          origin: origin,
          destination: destination,
          travelMode: google.maps.TravelMode.DRIVING
        },
        (result, status) => {
          if (status === google.maps.DirectionsStatus.OK) {
            this.setState({
              directions: result
            });
          } else {
            console.error(`error fetching directions ${result}`);
          }
        }
      );
    } else {
      console.log('Please mark your destination in the map first!');
    }
  };

  render() {
    const GoogleMapExample = withGoogleMap(props => (
      <GoogleMap
        defaultCenter={{ lat: 40.756795, lng: -73.954298 }}
        defaultZoom={13}
        center={this.state.currentLocation}
        onClick={this.onMapClick}
      >
        {this.state.centerMarker !== null && (
          <Marker position={this.state.centerMarker} label={'userloc'} />
        )}
        {this.state.markerPos !== null && (
          <Marker position={this.state.markerPos} />
        )}
        {this.state.directions !== null && (
          <DirectionsRenderer
            directions={this.state.directions}
            defaultOptions={{
              suppressMarkers: true
            }}
          />
        )}
      </GoogleMap>
    ));

    return (
      <div>
        <Button onClick={this.getDirections}>Get Direction</Button>
        <GoogleMapExample
          containerElement={<div style={{ height: `500px`, width: '500px' }} />}
          mapElement={<div style={{ height: `100%` }} />}
        />
      </div>
    );
  }
}

export default Map;
Pagemag
  • 2,779
  • 1
  • 7
  • 17