How to call fitBounds and getBounds in react-leaflet?

我怕爱的太早我们不能终老 提交于 2021-01-29 09:32:48

问题


I cannot figure out how to call fitBounds() on the Leaflet map.

Basically, I am trying to display multiple markers on the map and have the view adjust accordingly (zoom in, zoom out, fly to, etc.). i also saw some example How do you call fitBounds() when using leaflet-react? and i tried to implement but it did not work. Here is my code that i tried.

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;

回答1:


You have several errors in your code:

  1. You do not close toggleHiddden1 with an }. Moreover you call it as toggleHiddden in the component. You should use one name for the method.

  2. the map instance is derived from
    let mapInst = this.mapRef.current.leafletElement;

    not from let mapInst = this.refs.map.leafletElement;

    Then you can call fitBounds()

  3. The ref in the react-leaflet Map wrpapper should be ref={this.mapRef} and not ref="map"

  4. Place a key when you looping over the markers.

Just used an openstreet map tiles url to be able to demonstrate the demo.

Edit To use both fitBounds and getBounds at the same time for a marker you need to wrap your markers loop with a FeatureGroup and give it a ref, then do

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

inside your componentDidMount

and then you will get the desired result.

Demo



来源:https://stackoverflow.com/questions/60734165/how-to-call-fitbounds-and-getbounds-in-react-leaflet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!