如何使用最新版本的 react-leaflet 将嵌套在传单地图中的图块添加到 canvas?

How to add tiles nested in leaflet map to canvas with latest version of react-leaflet?

我正在尝试在 canvas 上添加地图并使用 react-leaflet 库 v3.X 将图块放在那里。目前,图块在 HTML 中显示为 <img>。在最新版本的 react-leaflet 中,没有 Map 对象,只有 MapContainer 对象。所以我无法将 属性 preferCanvas=true 添加到 MapContainer。值得注意的是,在旧版本的 react-leaflet 中,有带有 preferCanvas 选项的 Map 对象,但后来被删除了。我认为存在另一种将地图添加到 canvas 的方法。请帮忙。

import React, { useState, useEffect, useRef } from "react";
import { MapContainer as LeafletMap, TileLayer } from "react-leaflet";

// some code skipped
return (
<LeafletMap
  preferCanvas={true} // не работает
  center={[51.65, 103.72]}
  zoom={14}
  maxZoom={16}
  attributionControl={true}
  zoomControl={true}
  doubleClickZoom={false}
  scrollWheelZoom={true}
  dragging={true}
  animate={true}
  easeLinearity={0.35}
  whenReady={(map) => {
    setMapReady(true);
  }}
>
  <TileLayer
    url="https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}"
    id="mapbox/outdoors-v11"
  />
</LeafletMap>
  );
}

preferCanvas 从未打算将 tilelayer 瓦片渲染为 canvas 元素。 From the docs:

Whether Paths should be rendered on a Canvas renderer. By default, all Paths are rendered in a SVG renderer.

你想做的事情并没有写在传单中,但并不少见。与其从头开始 完全 构建它,看起来有人已经构建 L.TileLayer.Canvas for vanilla leaflet. So all we need to do is bring it into react-leaflet. You can follow these docs on the react-leaflet website 来创建一个自定义的 react-leaflet 组件,该组件是从 L.TileLayer.Canvas:

import { createLayerComponent } from "@react-leaflet/core";
import L from "leaflet";
import "tilelayer-canvas";

const createLayer = (props, context) => {
  const instance = L.tileLayer.canvas(props.url, { ...props });

  return { instance, context };
};

const updateLayer = (instance, props, prevProps) => {
  // you may not need all of these
  //or you may need others I didn't include here:
  if (prevProps.url !== props.url) {
    if (instance.setUrl) instance.setUrl(props.url);
  }
  if (prevProps.opacity !== props.opacity) {
    if (instance.setOpacity) instance.setOpacity(props.opacity);
  }
  if (prevProps.zIndex !== props.zIndex) {
    if (instance.setZIndex) instance.setZIndex(props.zIndex);
  }
};

const TilelayerCanvas = createLayerComponent(createLayer, updateLayer);

export default TilelayerCanvas;

现在在您的地图中:

import TilelayerCanvas from "./TilelayerCanvas";

const Map = (props) => {
  return (
    <MapContainer ... >
      <TilelayerCanvas url="the_url" attribution="some_attribution" />
    </MapContainer>
  );
};

export default Map;

Working codesandbox

如果您检查开发者工具,您会看到图块呈现为 canvas 元素而不是 img 元素。