简体   繁体   中英

Fit the map view of an Image Overlay to the size of the container Leaflet

I am using React Leaflet to create a custom map.

The card (Image Overlay) is currently being rendered, but it does not fill the container in which the card is placed.

The size of the container is set strictly and I would like the map to fill the container as much as possible. All attempts to resize with CSS failed.

Live example: https://codesandbox.io/s/dark-worker-8qbzfr

My code:

import "./styles.css";
import { MapContainer, ImageOverlay } from "react-leaflet";
import "leaflet/dist/leaflet.css";

const M = ({ width, height, zoom, center }) => {
  const wh = [width, 500];
  const origin = [0, 0];
  const bounds = [origin, wh];

  return (
    <div style={{ width: "1100px", height: "600px" }}>
      <MapContainer
        style={{ height: "100%", minHeight: "100%" }}
        bounds={zoom ? undefined : bounds}
        boundsOptions={{
          padding: [0, 0]
        }}
        maxBounds={bounds}
        zoom={center ? zoom : undefined}
        center={zoom ? center : undefined}
      >
        <ImageOverlay
          url="../ptichnikDraw.png"
          bounds={bounds}
          className="map_main"
        />
      </MapContainer>
    </div>
  );
};

const App = () => {
  return (
    <div
      style={{
        display: "flex",
        justifyContent: "center"
      }}
    >
      <M width={1500} height={500} center={[0, 0]} />
    </div>
  );
};

export default App;

Using the default Leaflet JavaScript library you can use map.invalidateSize(). Don't know how that would work in React but maybe you can figure that one out using the documentation.

You want your "card" (the <ImageOverlay> ) to fill the initial map container/viewport.

You will not be able to do so using (only) CSS, but with Leaflet map options and methods, which are exposed by React Leaflet wrapper:

  1. Use the Leaflet map whenReady option (exposed as a prop of <MapContainer> ) to attach a callback that is executed once the map is initialized

Runs the given function fn when the map gets initialized

  1. While not explicitly documented, that callback receives a load event argument, which target property is the newly instantiated Leaflet map

Fired when the map is initialized

  1. Call the fitBounds() map method on that instance, with the same bounds as your Image Overlay, to have the map view be adjusted accordingly

Sets a map view that contains the given geographical bounds with the maximum zoom level possible.

  1. Important: make sure to set the map zoomSnap option to value 0 , otherwise the fitBounds will be modified so that the final zoom is a multiple of zoomSnap (default to 1, ie integer zoom levels)

Forces the map's zoom level to always be a multiple of this, particularly right after a fitBounds() or a pinch-zoom. By default, the zoom level snaps to the nearest integer; lower values (eg 0.5 or 0.1 ) allow for greater granularity. A value of 0 means the zoom level will not be snapped after fitBounds or a pinch-zoom.

const M = ({ width, height, zoom, center }) => {
  const wh = [width, 500];
  const origin = [0, 0];
  const bounds = [origin, wh];

  return (
    <div style={{ width: "1100px", height: "600px" }}>
      <MapContainer
        style={{ height: "100%", minHeight: "100%" }}
        bounds={zoom ? undefined : bounds}
        boundsOptions={{
          padding: [0, 0]
        }}
        maxBounds={bounds}
        zoom={center ? zoom : undefined}
        center={zoom ? center : undefined}
        zoomSnap={0} // Important to disable snap after fitBounds
        whenReady={(e) => e.target.fitBounds(bounds)} // Have the map adjust its view to the same bounds as the Image Overlay
      >
        <ImageOverlay
          url="../ptichnikDraw.png"
          bounds={bounds}
          className="map_main"
        />
      </MapContainer>
    </div>
  );
};

Updated CodeSandbox: https://codesandbox.io/s/pedantic-tree-lz1o9q

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