传单中未显示标记图标

marker icon isn't showing in Leaflet

我整理了一个非常简单的 React / Leaflet 演示,但标记图标根本没有显示。 完整的 运行 代码是 here.

这是我的 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();
}

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

尝试添加图标:

const myIcon = L.icon({
   iconUrl: 'myIcon.png',
   // ...
});

L.marker([37.98, 23.72], {icon: myIcon})
  .addTo(this.map)

也许您对默认设置有一些问题:https://leafletjs.com/reference-1.6.0.html#icon-default

以下是最终对我有用的方法(我使用的是 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();
}

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

详见https://github.com/Leaflet/Leaflet/issues/4968

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

Retrieve all Leaflet Default Icon options from CSS, in particular all icon images URL's, to improve compatibility with bundlers and frameworks that modify URL's in CSS.

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

但在您自己的环境中应该没问题。

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

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

我正在使用 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]})} />

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

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

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

在调用渲染函数之前将其包含在 index.js 文件中。

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