简体   繁体   中英

How to set start point in react-google-maps

I am working on an application I am using react-google-maps where I've integrated multiple stop functionality in my application. Now I want to set its starting point like, For example, I want to draw multiple stops from its starting point and it must be a marker with text (Start). I really tried but didn't able to resolve this solution, I will also attach an image of what I want to achieve.

图像预览

Code

import React, { useState } from "react";
import {
  GoogleMap,
  InfoWindow,
  Marker,
  Polyline,
} from "@react-google-maps/api";

function Map({ scheduledOrders }) {
  const [activeMarker, setActiveMarker] = useState(null);

  let markers =
    scheduledOrders !== undefined &&
    scheduledOrders &&
    scheduledOrders[0] &&
    scheduledOrders[0].map((item, index) => ({
      id: index + 1,
      name: item.customerName + " - " + item.customerAddress,
      position: {
        lat: Number(item && item.order_lat, 10),
        lng: Number(item && item.order_lng, 10),
      },
    }));


  console.log("@@@markser", markers);

  const handleActiveMarker = (marker) => {
    if (marker === activeMarker) {
      return;
    }
    setActiveMarker(marker);
  };

  const handleOnLoad = (map) => {
    const bounds = new window.google.maps.LatLngBounds();
    markers && markers.forEach(({ position }) => bounds.extend(position));
    map.fitBounds(bounds);
  };

  return (
    <GoogleMap
      onLoad={handleOnLoad}
      onClick={() => setActiveMarker(null)}
      mapContainerStyle={{ width: "100%", height: "88vh" }}
    >
      <Polyline
        path={
          scheduledOrders !== undefined &&
          scheduledOrders &&
          scheduledOrders[0] &&
          scheduledOrders[0].map((item) => ({
            lat: Number(item && item.order_lat, 10),
            lng: Number(item && item.order_lng, 10),
          }))
        }
        options={{
          strokeColor: "#07966B",
          strokeOpacity: 1,
          strokeWeight: 2,
          icons: [
            {
              icon: "hello",
              offset: "0",
              repeat: "10px",
            },
          ],
        }}
      />
      {markers &&
        markers.map(({ id, name, position }) => (
          <Marker
            key={id}
            position={position}
            onClick={() => handleActiveMarker(id)}
            label={{ text: `${id}`, color: "white" }}
          >
            {activeMarker === id ? (
              <InfoWindow onCloseClick={() => setActiveMarker(null)}>
                <div>{name}</div>
              </InfoWindow>
            ) : null}
          </Marker>
        ))}
    </GoogleMap>
  );
}

export default Map;

Your code appears to have the same coordinates for the start and end path of the polyline. To achieve your use case, I got 2 ways to solve this.

Here's the first, you need to first get the coordinates of your starting point and put it in a separate variable.Then you need to create a separate <Marker> object for this coordinate with the condition that it will check if the start coordinate variable has value. This will create a separate Marker object that you can customize. Next you only need to map all the middle(waypoint) coordinates in your markers variable.

Here's a sample code and a code snippet that I made. I just passed the scheduledOrders value from json file.

import React, { useState } from "react";
import {
  GoogleMap,
  InfoWindow,
  Marker,
  Polyline
} from "@react-google-maps/api";

import scheduledOrders from "./data.json";

function Map() {
  const [activeMarker, setActiveMarker] = useState(null);
  let startMarker = null;
  let wayptMarker = [];

//get the first point and put it in a startMarker variable then put the middle points in an array(wayptMarker)
  scheduledOrders.map((item, index, arr) => {
    if (index == 0 || index == arr.length - 1) {
      //Since the start and end point are the same, I only get the start point details in my startMarker variable
      if (index == 0) {
        startMarker = item;
      }
    } else {
      wayptMarker.push(item);
    }
  });

//put your startposition here
  let startPosition = {
    lat: startMarker.order_lat,
    lng: startMarker.order_lng
  };
//put your start name here
  let startName =
    startMarker.customerName + " - " + startMarker.customerAddress;


  let markers =
    scheduledOrders !== undefined &&
    scheduledOrders &&
    wayptMarker.map((item, index) => ({
      id: index + 1,
      name: item.customerName + " - " + item.customerAddress,
      position: {
        lat: Number(item && item.order_lat, 10),
        lng: Number(item && item.order_lng, 10)
      }
    }));


  console.log("@@@markser", scheduledOrders);

  const handleActiveMarker = marker => {
    if (marker === activeMarker) {
      return;
    }
    setActiveMarker(marker);
  };

  const handleOnLoad = map => {
    const bounds = new window.google.maps.LatLngBounds();
    markers && markers.forEach(({ position }) => bounds.extend(position));
    map.fitBounds(bounds);
  };

  return (
    <GoogleMap
      onLoad={handleOnLoad}
      onClick={() => setActiveMarker(null)}
      mapContainerStyle={{ width: "100%", height: "88vh" }}
    >
      <Polyline
        path={
          scheduledOrders !== undefined &&
          scheduledOrders &&
          scheduledOrders[0] &&
          scheduledOrders.map(item => ({
            lat: Number(item && item.order_lat, 10),
            lng: Number(item && item.order_lng, 10)
          }))
        }
        options={{
          strokeColor: "#07966B",
          strokeOpacity: 1,
          strokeWeight: 2,
          icons: [
            {
              icon: "hello",
              offset: "0",
              repeat: "10px"
            }
          ]
        }}
      />
     {/* I created a marker solely for startMArker where you can customize the  icon for this only marker */}
      {startMarker != null && (
        <Marker
          key="start"
          position={startPosition}
          onClick={() => handleActiveMarker("start")}
          label={{ text: `START`, color: "black" }}
          icon="http://maps.google.com/mapfiles/kml/shapes/arrow.png"
        >
          {activeMarker === "start" ? (
            <InfoWindow onCloseClick={() => setActiveMarker(null)}>
              <div>{startName}</div>
            </InfoWindow>
          ) : null}
        </Marker>
      )}
  {/* The following Marker object will only create markers for the middle points */}
      {markers &&
        markers.map(({ id, name, position }) => (
          <Marker
            key={id}
            position={position}
            onClick={() => handleActiveMarker(id)}
            label={{ text: `${id}`, color: "white" }}
          >
            {activeMarker === id ? (
              <InfoWindow onCloseClick={() => setActiveMarker(null)}>
                <div>{name}</div>
              </InfoWindow>
            ) : null}
          </Marker>
        ))}
    </GoogleMap>
  );
}

export default Map;

The second way is to simply just put the condition in your <Marker> object that will check if the markers that you are mapping is the first or the last then it will show a <Marker> object for the start and if not, a different <Marker> object that will show your waypoints.

Here's the sample code and code snippet below:

import React, { useState } from "react";
import {
  GoogleMap,
  InfoWindow,
  Marker,
  Polyline
} from "@react-google-maps/api";

import scheduledOrders from "./data.json";

function Map() {
  const [activeMarker, setActiveMarker] = useState(null);

  let markers =
    scheduledOrders !== undefined &&
    scheduledOrders &&
    scheduledOrders.map((item, index) => ({
      id: index + 1,
      name: item.customerName + " - " + item.customerAddress,
      position: {
        lat: Number(item && item.order_lat, 10),
        lng: Number(item && item.order_lng, 10)
      }
    }));

  console.log("@@@markser", scheduledOrders);

  const handleActiveMarker = marker => {
    if (marker === activeMarker) {
      return;
    }
    setActiveMarker(marker);
  };

  const handleOnLoad = map => {
    const bounds = new window.google.maps.LatLngBounds();
    markers && markers.forEach(({ position }) => bounds.extend(position));
    map.fitBounds(bounds);
  };

  return (
    <GoogleMap
      onLoad={handleOnLoad}
      onClick={() => setActiveMarker(null)}
      mapContainerStyle={{ width: "100%", height: "88vh" }}
    >
      <Polyline
        path={
          scheduledOrders !== undefined &&
          scheduledOrders &&
          scheduledOrders[0] &&
          scheduledOrders.map(item => ({
            lat: Number(item && item.order_lat, 10),
            lng: Number(item && item.order_lng, 10)
          }))
        }
        options={{
          strokeColor: "#07966B",
          strokeOpacity: 1,
          strokeWeight: 2,
          icons: [
            {
              icon: "hello",
              offset: "0",
              repeat: "10px"
            }
          ]
        }}
      />

      {/* The following Marker object will check if the index is the start or end */}
      {markers &&
        markers.map(({ id, name, position }, i, arr) => {
          if (i == 0 || i == arr.length)
            return (
              <Marker
                key="start"
                position={position}
                onClick={() => handleActiveMarker("start")}
                label={{ text: `START`, color: "black" }}
                icon="http://maps.google.com/mapfiles/kml/shapes/arrow.png"
              >
                {activeMarker === "start" ? (
                  <InfoWindow onCloseClick={() => setActiveMarker(null)}>
                    <div>This is the start</div>
                  </InfoWindow>
                ) : null}
              </Marker>
            );
          return (
            <Marker
              key={id}
              position={position}
              onClick={() => handleActiveMarker(id)}
              label={{ text: `${id - 1}`, color: "white" }}
            >
              {activeMarker === id ? (
                <InfoWindow onCloseClick={() => setActiveMarker(null)}>
                  <div>{name}</div>
                </InfoWindow>
              ) : null}
            </Marker>
          );
        })}
    </GoogleMap>
  );
}

export default Map;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM