React Leaflet - 标记图像无法加载

Ans*_*onH 6 javascript leaflet reactjs react-leaflet

问题

我在我的 React 项目中使用leaflet v1.7.1react-leaflet v3.0.5 。

当我尝试React Router 的“Setup”文档页面中的设置示例时,标记图标变成了损坏的图像,如下图红色圆圈所示:

标记损坏的图像

从 React Router 的文档来看,标记应该是这样的:

正确的标记

经检查,保存标记图像的标签src的属性应为。然而,经过检查, my的属性看起来是乱码:<img>https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png<img>src

乱码链接

复制

我创建了一个新的沙箱,其中包含我的代码:

在代码沙箱上编辑

或者,按照以下步骤复制问题:

  1. npx create-react-app leaflet-test

  2. cd leaflet-test/

  3. npm i leaflet react-leaflet

  4. 在代码编辑器中打开项目。转到App.js并使用以下代码:

    import React from "react";
    import "./App.css";
    import "leaflet/dist/leaflet.css";
    import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
    
    const styles = {
      mapRoot: {
        height: 400,
      },
    };
    
    export default function App() {
      return (
        <MapContainer
          style={styles.mapRoot}
          center={[51.505, -0.09]}
          zoom={13}
          scrollWheelZoom={false}
        >
          <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
          <Marker position={[51.505, -0.09]}>
            <Popup>
              A pretty CSS3 popup. <br /> Easily customizable.
            </Popup>
          </Marker>
        </MapContainer>
      );
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. npm start

我不确定是我在 React 中错误地设置了 Leaflet,还是 Leaflet 或 React Leaflet 的错误。提前致谢!

小智 9

我遇到了相同的问题,但最近发现了这个解决方案,我们需要做的就是将图标道具传递给标记组件。

import marker from '../../Assets/icons/Location.svg';
import { Icon } from 'leaflet'
const myIcon = new Icon({
 iconUrl: marker,
 iconSize: [32,32]
})

Run Code Online (Sandbox Code Playgroud)
<MapContainer center={value} zoom={13} scrollWheelZoom={false}>
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <Marker position={value} icon={myIcon}>
        <Popup>
        Location :{data}
        </Popup>
      </Marker>
    </MapContainer>
Run Code Online (Sandbox Code Playgroud)

在 CodeSandBox 上检查我的解决方案


Ans*_*onH 8

感谢FoundingBox的评论,事实证明这是 React Leaflet 的一个 bug。

已经有一个 关于此错误的GitHub 问题线程,该评论建议了以下解决方案:

好的。事实证明,问题是由于在组件的导入中包含传单 CSS 引起的。

我现在刚刚添加了一个指向 CDN 托管的 leaflet.css 文件的链接,并且工作正常,但如果可以对其进行修补以与 create-react-app webpack 配置一起使用,那就太好了。

换句话说,这是分步指南:

  1. import "leaflet/dist/leaflet.css";从......中去除App.js。不要从任何 JS 文件中的节点模块导入 Leaflet CSS。

  2. public/index.html通过将以下代码粘贴到<head>HTML 文件的部分中,转到并包含 CDN 托管的 leaflet.css:

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
      integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
      crossorigin=""/>
    
    Run Code Online (Sandbox Code Playgroud)

    (注:本链接使用的是Leaflet v1.7.1版本,请访问Leaflet的文档,找到链接最新版本Leaflet的代码)


ghy*_*ybs 5

作为参考,这是由于 webpack 在 CSS 中重写了 URL,而 Leaflet 使用它来检测其图标图像的路径。

请参阅传单问题#4968中的详细信息。

通过 CDN 使用 Leaflet 时,Leaflet CSS 不会受到干扰,因此它可以正常工作。

您仍然可以通过 webpack 使用它,但您应该仅使用自定义图标,或者明确告诉 Leaflet 在哪里可以找到其默认图标的图像:

import L from 'leaflet';
delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});
Run Code Online (Sandbox Code Playgroud)

我还专门为这种情况制作了一个插件:leaflet-defaulticon-compatibility

从 CSS 检索所有 Leaflet 默认图标选项,特别是所有图标图像 URL,以提高与修改 CSS 中 URL 的捆绑器和框架的兼容性。

import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css'; // Re-uses images from ~leaflet package
import * as L from 'leaflet';
import 'leaflet-defaulticon-compatibility';
Run Code Online (Sandbox Code Playgroud)