Реагировать js Google Map React- google-maps -api добавить StandaloneSearchBox - PullRequest
1 голос
/ 13 января 2020

Я хотел бы добавить StandaloneSearchBox, но я не могу добавить его, вот проблема, которую я получаю, это код, который я использую.

Я сделал, как показано в примере документации, но я Я не могу заставить его работать, и я не могу найти работающий пример.

Я разместил пример на CodeSanbox с тем же кодом, который я использую.

Ссылка: codesandbox

enter image description here

Код:

import React, { useState, useRef, useCallback } from "react";
import {
  LoadScript,
  GoogleMap,
  DrawingManager,
  Polygon,
  Marker,
  OverlayView,
  StandaloneSearchBox
} from "@react-google-maps/api";
import Switch from "@material-ui/core/Switch";

import Paper from "@material-ui/core/Paper";
import MenuItem from "@material-ui/core/MenuItem";
import MenuList from "@material-ui/core/MenuList";

import "./styles.css";
const libraries = ["drawing"];

const options = {
  drawingControl: true,
  drawingControlOptions: {
    drawingModes: ["polygon"]
  },
  polygonOptions: {
    fillColor: `#2196F3`,
    strokeColor: `#2196F3`,
    fillOpacity: 0.5,
    strokeWeight: 2,
    clickable: true,
    editable: true,
    draggable: true,
    zIndex: 1
  }
};

class LoadScriptOnlyIfNeeded extends LoadScript {
  componentDidMount() {
    const cleaningUp = true;
    const isBrowser = typeof document !== "undefined"; // require('@react-google-maps/api/src/utils/isbrowser')
    const isAlreadyLoaded =
      window.google &&
      window.google.maps &&
      document.querySelector("body.first-hit-completed"); // AJAX page loading system is adding this class the first time the app is loaded
    if (!isAlreadyLoaded && isBrowser) {
      // @ts-ignore
      if (window.google && !cleaningUp) {
        console.error("google api is already presented");
        return;
      }

      this.isCleaningUp().then(this.injectScript);
    }

    if (isAlreadyLoaded) {
      this.setState({ loaded: true });
    }
  }
}

const defaultPaths = [];

export default function Map({ apiKey, center, paths = defaultPaths, point }) {
  const [state, setState] = useState({
    drawingMode: "polygon",
    pointSelect: null,
    checkedA: true
  });

  const noDraw = () => {
    setState(function set(prevState) {
      return Object.assign({}, prevState, {
        drawingMode: "maker"
      });
    });
  };

  const onPolygonComplete = React.useCallback(
    function onPolygonComplete(poly) {
      const polyArray = poly.getPath().getArray();
      let paths = [];
      polyArray.forEach(function(path) {
        paths.push({ lat: path.lat(), lng: path.lng() });
      });
      console.log("onPolygonComplete", paths);
      point(paths);
      noDraw();
      poly.setMap(null);
    },
    [point]
  );

  // Define refs for Polygon instance and listeners
  const polygonRef = useRef(null);
  const listenersRef = useRef([]);

  // Call setPath with new edited path
  const onEdit = useCallback(() => {
    if (polygonRef.current) {
      const nextPath = polygonRef.current
        .getPath()
        .getArray()
        .map(latLng => {
          return { lat: latLng.lat(), lng: latLng.lng() };
        });
      console.log("nextPath", nextPath);
      //setPath(nextPath);
      point(nextPath);
    }
  }, [point]);

  // Bind refs to current Polygon and listeners
  const onLoad = useCallback(
    polygon => {
      polygonRef.current = polygon;
      const path = polygon.getPath();
      listenersRef.current.push(
        path.addListener("set_at", onEdit),
        path.addListener("insert_at", onEdit),
        path.addListener("remove_at", onEdit)
      );
    },
    [onEdit]
  );

  // Clean up refs
  const onUnmount = useCallback(() => {
    listenersRef.current.forEach(lis => lis.remove());
    polygonRef.current = null;
  }, []);

  const deletePoint = key => {
    let pp = paths.filter((_, i) => i !== key);
    point(pp);
    setState(function set(prevState) {
      return Object.assign({}, prevState, {
        pointSelect: null
      });
    });
  };

  console.log("Map", paths);

  const handleChange = name => event => {
    setState({ ...state, [name]: event.target.checked });
  };

  const onPlacesChanged = al => console.log(al);

  return (
    <div className="App">
      Hi Web!!
      <LoadScriptOnlyIfNeeded
        id="script-loader"
        googleMapsApiKey={apiKey}
        libraries={libraries}
        language="it"
        region="us"
      >
        <GoogleMap
          mapContainerClassName="App-map"
          center={center}
          zoom={18}
          version="weekly"
        >
          <StandaloneSearchBox
            onLoad={onLoad}
            onPlacesChanged={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>
          {state.checkedA && state.pointSelect !== null && (
            <OverlayView
              position={paths[state.pointSelect]}
              mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
            >
              <Paper>
                <MenuList>
                  <MenuItem disabled={true}>
                    Punto #{state.pointSelect}
                  </MenuItem>
                  <MenuItem onClick={() => deletePoint(state.pointSelect)}>
                    Elimina punto
                  </MenuItem>
                  <MenuItem>Modifica Punto</MenuItem>
                  <MenuItem
                    onClick={() => {
                      setState(function set(prevState) {
                        return Object.assign({}, prevState, {
                          pointSelect: null
                        });
                      });
                    }}
                  >
                    Annulla
                  </MenuItem>
                </MenuList>
              </Paper>
            </OverlayView>
          )}
          <div
            style={{
              backgroundColor: "#fff",
              borderRadius: 4,
              border: "1px solid #ccc",
              padding: 10,
              zIndex: 99999999,
              position: "absolute",
              top: "5px",
              right: "5px",
              width: "200px"
            }}
          >
            <b>Controls</b>
            <br />
            <br />
            <hr
              style={{
                //color: "#3794ff",
                backgroundColor: "#3794ff",
                height: 1
              }}
            />
            <Switch
              value="checkedA"
              inputProps={{ "aria-label": "secondary checkbox" }}
            />
            Show
            <br />
            <Switch
              checked={state.checkedA}
              value="checkedA"
              inputProps={{ "aria-label": "secondary checkbox" }}
              onChange={handleChange("checkedA")}
            />
            Show menu
          </div>
          {paths.length < 1 ? (
            <DrawingManager
              drawingMode={state.drawingMode}
              options={options}
              onPolygonComplete={onPolygonComplete}
            />
          ) : (
            <Polygon
              options={{
                fillColor: `#2196F3`,
                strokeColor: `#2196F3`,
                fillOpacity: 0.5,
                strokeWeight: 2
              }}
              // Make the Polygon editable / draggable
              editable
              draggable
              path={paths}
              // Event used when manipulating and adding points
              onMouseUp={onEdit}
              // Event used when dragging the whole Polygon
              onDragEnd={onEdit}
              onLoad={onLoad}
              onUnmount={onUnmount}
            />
          )}
          {paths.length > 0 &&
            paths.map((pos, key) => {
              return (
                <Marker
                  key={key}
                  label={"" + key}
                  position={pos}
                  onRightClick={pos => {
                    //let pp = paths.filter((_, i) => i !== key);
                    //point(pp);
                    console.log(key);
                    setState(function set(prevState) {
                      return Object.assign({}, prevState, {
                        pointSelect: key
                      });
                    });
                  }}
                  title={"[" + pos.lat + "," + pos.lng + "]"}
                  draggable
                  onDragEnd={pos => {
                    let obj = { lat: pos.latLng.lat(), lng: pos.latLng.lng() };
                    var copia = Object.assign([], paths);
                    copia[key] = obj;
                    point(copia);
                    if (state.pointSelect !== null)
                      setState(function set(prevState) {
                        return Object.assign({}, prevState, {
                          pointSelect: null
                        });
                      });
                  }}
                />
              );
            })}
        </GoogleMap>
      </LoadScriptOnlyIfNeeded>
    </div>
  );
}

1 Ответ

1 голос
/ 14 января 2020

@react-google-maps/api состояния документации, для StandaloneSearchBox компонента :

Пожалуйста, не забудьте включить «места» в библиотеку prop массива на <LoadingScript />

В вашем примере libraries переменная может быть обновлена ​​для загрузки библиотеки мест:

const libraries = ["drawing", "places"];

Пример

Минимальный пример демонстрирует, как использовать StandaloneSearchBox компонент:

export default function Map(props) {
  function handleLoad() {}

  function hanldePlacesChanged() {}

  return (
    <LoadScript id="script-loader" googleMapsApiKey="" libraries={["places"]}>
      <GoogleMap
        zoom={5}
        center={{ lat: -25.0270548, lng: 115.1824598 }}
        id="map"
      >
        <StandaloneSearchBox
          onLoad={handleLoad}
          onPlacesChanged={hanldePlacesChanged}
        >
          <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>
      </GoogleMap>
    </LoadScript>
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...