React Leaflet - 标记图像无法加载

6

问题

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

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

marker broken image

根据React Router的文档,该标记应如下所示:

correct marker

经检查,包含标记图像的<img>标签的src属性应为https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png。但是,经检查,我的<img>src属性是看起来无意义的乱码:

gibberish link

复制问题

我已创建了一个包含我的代码的新sandbox:

Edit on Code Sandbox

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

  1. npx create-react-app leaflet-test

  2. cd leaflet-test/

  3. npm i leaflet react-leaflet

  4. Open the project in code editor. Go to App.js and use the following code:

    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>
      );
    }
    
  5. npm start

我不确定我在React中是否正确设置了Leaflet,或者这是来自Leaflet或React Leaflet的错误。提前致谢!


1
也许这个线程能帮到你,好消息是这不是你的错,而且这似乎是一个常见的问题。https://github.com/PaulLeCam/react-leaflet/issues/453 - FoundingBox
非常感谢:D我从那个问题线程中找到了解决方法。 - AnsonH
没问题,很高兴你找到了解决方案 :) - FoundingBox
3个回答

8

我曾遇到相同的问题,但最近发现了解决方法,我们只需要将一个图标属性传递给标记组件。

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


<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>

在 CodeSandBox 上查看我的解决方案


8
感谢FoundingBox的评论,这是React Leaflet的一个bug。
已经有GitHub issue thread关于这个bug,这条评论建议以下解决方案:

好吧。问题是由于在组件中导入了leaflet CSS而引起的。 我现在只链接到CDN托管的leaflet.css文件就可以了, 但如果能够通过create-react-app webpack配置来解决这个问题就更好了。

换句话说,以下是一步一步的指南:
  1. Remove import "leaflet/dist/leaflet.css"; from App.js. Do NOT import the Leaflet CSS from the node modules in any JS files.

  2. Go to public/index.html and include the CDN hosted leaflet.css by pasting the following code in the <head> section of the HTML file:

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
      integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
      crossorigin=""/>
    

    (Note: This link uses v1.7.1 of Leaflet. Visit Leaflet's documentation to find the code of linking the latest version of Leaflet)


1
最新的react-leaflet版本的解决方案。谢谢兄弟! - undefined

4

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

请参阅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'),
});

我还专门为这种情况制作了一个插件: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';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接