Как вызвать fitBounds и getBounds в реагирующей листовке?

Я не могу понять, как вызвать fitBounds() на карте Leaflet.

По сути, я пытаюсь отобразить несколько маркеров на карте и соответствующим образом настроить вид (увеличить, уменьшить, лететь и т. Д.). я также видел пример Как вы вызываете fitBounds() при использовании leaflet-react? и я пытался реализовать, но это не сработало. Вот мой код, который я пробовал.

import React, { createRef, Component } from "react";
import {
  Map,
  TileLayer,
  Marker,
  Popup
} from "react-leaflet";
import L from "leaflet";
import Header from "../Layout/Header";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography";
import "leaflet/dist/leaflet.css";

export class Mapp extends Component {
  constructor(props) {
    super(props);

    this.state = {
      map: [],
      open: false,
      bounds: null,
      center: [35.000074, 104.999927]
    };
    this.mapRef = createRef();
    this.groupRef = createRef();
  }

  toggleHiddden1() {
    this.setState({
      open: false
    });

  async componentDidMount() {
    try {
      await fetch(`https://coronaviva.herokuapp.com/api/1/infected/data/`, {
        method: "GET",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
          Authorization: "Bearer F9bQK456iUpJVZJLTZsMEKhhENqnGJ"
        }
      })
        .then(map => map.json())
        .then(map => {
          this.setState({
            map
          });
        });
    } catch (err) {
      console.log(err);
    }

    let mapInst = this.refs.map.leafletElement.fitBounds;
    console.log(mapInst);  // i tried this but this not working.
  }

  // centerUpdated(center) {
  //   this.center = center;
  // }
  // boundsUpdated(bounds) {
  //   this.bounds = bounds;
  // }

  render() {
    const { map } = this.state;

    const pointerIcon = new L.Icon({
      iconUrl:
        "https://icons.iconarchive.com/icons/paomedia/small-n-flat/512/map-marker-icon.png",
      iconAnchor: [25, 40],
      iconSize: [50, 50]
    });
    return (
      <div>
        <Header
          state={this.state}
          load={this.onChange}
          submit={this.handleSubmit}
        />
        <Map
          center={[51.9194, 19.1451]}
          style={{ height: "100vh", width: "auto" }}
          zoom={6}
          ref="map"
          bounceAtZoomLimits={true}
          maxBoundsViscosity={0.95}
          maxBounds={[
            [-180, -90],
            [180, 90]
          ]}
          className="map_map margin-zero map-padding"
        >
          {map.map(c => (
            <Marker
              position={[c.latitude, c.longitude]}
              icon={pointerIcon}
              onclick={this.toggleHiddden.bind(this)}
            >
              <Popup autoPan={false}>
                <Card className="carrr">
                  {c.location === "Israel" ? (
                    <img
                      className="image"
                      src="https://thehill.com/sites/default/files/styles/article_full/public/telaviv_skyline_09202018.jpg?itok=pxhk1Rtl"
                      alt="Contemplative Reptile"
                    />
                  ) : (
                    <img
                      className="image"
                      src="https://www.dwf.law/-/media/DWF/Images/Locations-Assets/Warsaw/Warsaw-700-x-388.ashx"
                      alt="Contemplative Reptile"
                    />
                  )}
                  <CardContent>
                    <Typography gutterBottom variant="h5" component="h2">
                      {c.location && <span> Place : {c.location} </span>}
                    </Typography>

                    <h6>Address : {c.address}</h6>
                    <p className="text-dark" style={{ marginTop: "-5px" }}>
                      {c.info && (
                        <span>
                          <strong> Info</strong>: {c.info}{" "}
                        </span>
                      )}
                    </p>

                    <p
                      color="textSecondary text-secondary"
                      component="p"
                      className="lodl"
                    >
                      PlaceType : {c.place_type}
                      <br></br>
                      {c.start_hour && (
                        <span>
                          Start Hour : {c.start_hour}{" "}
                          {c.start_hour > "12" ? "PM" : "AM"}
                        </span>
                      )}
                      <br></br>
                      {c.end_hour && (
                        <span>
                          End Hour : {c.end_hour}{" "}
                          {c.end_hour > "12" ? "PM" : "AM"}
                        </span>
                      )}
                    </p>
                  </CardContent>
                </Card>
              </Popup>
            </Marker>
          ))}

          <TileLayer
            noWrap={true}
            url="https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png"
            subdomains="1234"
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreepMap</a>  '
          />
        </Map>
      </div>
    );
  }
}

export default Mapp;

person Piotr    schedule 18.03.2020    source источник


Ответы (1)


У вас есть несколько ошибок в вашем коде:

  1. Вы не закрываете toggleHiddden1 с помощью }. Более того, вы называете это toggleHiddden в компоненте. Вы должны использовать одно имя для метода.

  2. экземпляр карты получен из
    let mapInst = this.mapRef.current.leafletElement;

    не от let mapInst = this.refs.map.leafletElement;

    Тогда вы можете позвонить fitBounds()

  3. Ссылка в wrapper карты реагирования-листовки должна быть ref={this.mapRef}, а не ref="map"

  4. Поместите ключ, когда вы зацикливаетесь на маркерах.

Просто использовал URL-адрес плитки карты openstreet, чтобы продемонстрировать демонстрацию.

Редактировать Чтобы одновременно использовать как fitBounds, так и getBounds для маркера, вам нужно обернуть цикл маркеров FeatureGroup и дать ему ссылку, а затем выполнить

let mapInst = this.mapRef.current.leafletElement;
const group = this.groupRef.current.leafletElement; //get native featureGroup instance
mapInst.fitBounds(group.getBounds());

внутри твоего componentDidMount

и тогда вы получите желаемый результат.

Демо

person kboul    schedule 18.03.2020
comment
Спасибо. это работает и как вызвать getbounds и flyto, если я ищу какое-то место, и оно летит в это конкретное место. @kboul - person Piotr; 18.03.2020
comment
Так же, как вы называете fitBounds. Используйте mapInst. Пожалуйста, примите ответ, если он вам помог. - person kboul; 18.03.2020
comment
как я могу использовать одновременно fitBounds и getBounds для маркера. Можете ли вы обновить свой codesanbox, тогда я приму ваш ответ? - person Piotr; 18.03.2020
comment
Я модифицировал демо. Взглянуть - person kboul; 18.03.2020
comment
Большое спасибо !! - person Piotr; 18.03.2020