Leaflet中的标记图标未显示

10
我为您准备了一个非常简单的React / Leaflet演示,但标记图标根本没有显示。 完整的运行代码在这里
这是我的componentDidMount方法中的内容:
componentDidMount() {
this.map = L.map("map-id", {
  center: [37.98, 23.72],
  zoom: 12,
  zoomControl: true
});

const mapboxAccessToken =
  "pk.eyJ1IjoibXBlcmRpa2VhcyIsImEiOiJjazZpMjZjMW4wOXJzM2ttc2hrcTJrNG9nIn0.naHhlYnc4czWUjX0-icY7Q";
L.tileLayer(
  "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}",
  {
    attribution:
      'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    maxZoom: 25,
    id: "mapbox/streets-v11",
    accessToken: mapboxAccessToken
  }
).addTo(this.map);

L.marker([37.98, 23.72])
  .addTo(this.map)
  .bindPopup("a marker")
  .openPopup();
}

基本上,弹出窗口是可见的,但标记图标本身不可见。即,这是我所看到的内容:enter image description here

在我的机器上,图标以base64表示,但显然因为格式不正确而无法显示:<img src='data:image/png;base64, ... GgIwYdwAAAAASUVORK5CYII=")marker-icon.png'。在浏览器调试器中删除后缀")marker-icon.png可以使图标显示出来,但我不知道它来自哪里。此外,图标周围有一个空方框,可能表示缺少的阴影。 - Qwertie
相关问题:https://github.com/PaulLeCam/react-leaflet/issues/453 - Qwertie
7个回答

27
我正在使用react-leaflet。这是我的做法。

我正在使用react-leaflet。这是我的做法。

import markerIconPng from "leaflet/dist/images/marker-icon.png"
import {Icon} from 'leaflet'

然后,在MapContainer内部:

<Marker position={[lat, lng]} icon={new Icon({iconUrl: markerIconPng, iconSize: [25, 41], iconAnchor: [12, 41]})} />

2
很好!!!!!!!!!!!!!!!!!!!!! - entropyfeverone
4
我正在使用Next.js,这个方法对我几乎有效。它需要一个特定的路径而不是导入的图像。假设您的图标是marker-icon.png。将其放置在静态目录下,例如public,并使用new Icon({ iconUrl : '/marker-icon.png' ... }) - superk
最佳答案。您可以导入任何标记图标以代替默认图标。 - Abdulrahman Ali

7

我接受这个答案,因为它在 webpack 中引导我找到了正确的解决方案(https://dev59.com/ornoa4cB1Zd3GeqPLzGM#60188233)。 - Marcus Junius Brutus

4

这是最终对我有用的方法(我使用的是 webpack):

const defaultIcon = new L.icon({
  iconUrl: require('../node_modules/leaflet/dist/images/marker-icon.png'); // your path may vary ...
  iconSize: [8, 8],
  iconAnchor: [2, 2],
  popupAnchor: [0, -2]
});

generateMarkers().forEach( c=> {
   L.marker(c, {icon: defaultIcon}).addTo(this.map).bindPopup('a marker; yeah').openPopup();
}

3

在调用render函数之前,请在index.js文件中先引入此代码。

import markerIcon from "../node_modules/leaflet/dist/images/marker-icon.png";
L.Marker.prototype.setIcon(L.icon({
  iconUrl:markerIcon
}))

在Vue 3,ES6中,这很顺畅地运行。 - Paranoid Android

2
仅供参考,这是由于Webpack试图在不同的文件夹中包含在Leaflet CSS中指定的标记图标图像文件作为静态资产,可能会进行文件重命名(例如用于指纹);所有这些都会干扰Leaflet算法,该算法仅将该图像用作指向其实际CSS图像文件夹的指针,因此在Webpack构建步骤之后可能完全缺失。

请参阅https://github.com/Leaflet/Leaflet/issues/4968中的详细信息。

我专门制作了一个Leaflet插件来解决这个问题:https://github.com/ghybs/leaflet-defaulticon-compatibility

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

不幸的是,在CodeSandbox(甚至在StackBlitz中)它仍然无法正常工作,因为后者无法处理这些静态资产。只需尝试使用Leaflet图层控件即可看到,它使用非常简单的CSS背景图像,在CodeSandbox中也缺失。

但是在您自己的环境中,一切都应该正常。

CodeSandbox中的演示:https://codesandbox.io/s/elegant-swirles-yzsql

以及在StackBlitz中(相同的静态资产问题):https://stackblitz.com/edit/react-vqgtxd?file=index.js


1

我想一个简单的方法就是更改图片路径:

L.Icon.Default.imagePath='images/'

我正在使用React,所以我将文件夹/node_modules/leaflet/dist/images复制到了/public


0
 L.Icon.Default.imagePath='/path_to_your_images';
    var icon = L.icon({
        iconUrl: 'marker-icon.png',
        shadowUrl: 'marker-shadow.png',

        iconSize:     [25, 41],
        shadowSize:   [30, 65],
        iconAnchor:   [12, 41],
        shadowAnchor: [7, 65]
    });

这个解决方案对我很有效!


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