首页 > 解决方案 > 如何在 react-leaflet 中调用 fitBounds 和 getBounds?

问题描述

我无法弄清楚如何在 Leaflet 地图上调用 fitBounds()。

基本上,我试图在地图上显示多个标记并相应地调整视图(放大、缩小、飞到等)。我还看到了一些例子,当使用 Leaflet-react 时如何调用 fitBounds()?我试图实施,但没有奏效。这是我尝试过的代码。

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;

标签: javascriptreactjsleafletmaterial-uireact-leaflet

解决方案


您的代码中有几个错误:

  1. 你不要toggleHiddden1}. 此外,您toggleHiddden在组件中调用它。您应该为该方法使用一个名称。

  2. 地图实例源自
    let mapInst = this.mapRef.current.leafletElement;

    不是来自 let mapInst = this.refs.map.leafletElement;

    然后你可以打电话fitBounds()

  3. react-leaflet Map 包装器中的 ref 应该是ref={this.mapRef}而不是ref="map"

  4. 在标记上循环时放置一个键。

只是使用了一个openstreet地图图块url来演示演示。

编辑 要同时使用 fitBounds 和 getBounds 作为标记,您需要用 a 包裹标记循环FeatureGroup并给它一个 ref,然后执行

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

在你的里面componentDidMount

然后你会得到想要的结果。

演示


推荐阅读