带有反应传单的自定义标记图标
Posted
技术标签:
【中文标题】带有反应传单的自定义标记图标【英文标题】:custom marker icon with react-leaflet 【发布时间】:2018-05-23 06:10:49 【问题描述】:我尝试了我在网络上找到的所有东西,*** 和 Github,但仍然无法成功。
我想使用自定义图标制作自定义标记,但使用下面的代码时,我总是遇到错误:'TypeError: options.icon.createIcon is not a function'
这是我的代码(文件夹路径没有错误,一切都在 src/js 或 src/img 中)
图标.js
import L from 'leaflet';
const iconPerson = L.Icon.extend(
options:
iconUrl: require('../img/marker-pin-person.svg'),
iconRetinaUrl: require('../img/marker-pin-person.svg'),
iconAnchor: null,
popupAnchor: null,
shadowUrl: null,
shadowSize: null,
shadowAnchor: null,
iconSize: new L.Point(60, 75),
className: 'leaflet-div-icon'
);
export iconPerson ;
MarkerPinPerson
import React from 'react';
import Marker from 'react-leaflet';
import iconPerson from './Icons';
export default class MarkerPinPerson extends React.Component
render()
return (
<Marker
position=this.props.markerPosition
icon= iconPerson
>
</Marker>
);
真的在寻求您的帮助!
【问题讨论】:
【参考方案1】:我终于找到了 Icon.js 文件的正确代码:
import L from 'leaflet';
const iconPerson = new L.Icon(
iconUrl: require('../img/marker-pin-person.svg'),
iconRetinaUrl: require('../img/marker-pin-person.svg'),
iconAnchor: null,
popupAnchor: null,
shadowUrl: null,
shadowSize: null,
shadowAnchor: null,
iconSize: new L.Point(60, 75),
className: 'leaflet-div-icon'
);
export iconPerson ;
【讨论】:
没有require
就无法渲染,这正是我所需要的。
我不会使用 leaflet-div-icon
类。它将呈现带边框的白色背景。【参考方案2】:
我是在试图弄清楚如何呈现自定义图标服务器端(使用 react-leaflet-universal)时被带到这里的。我想我会发布这个,以防将来有人出于同样的原因发现自己在这里。就像在 react-leaflet-markercluster 的情况下一样,我可以通过在返回函数中要求传单来实现此功能,例如:
<Map center=this.props.center
zoom=zoom
className=leafletMapContainerClassName
scrollWheelZoom=false
maxZoom=18
preferCanvas=false
>
() =>
const MarkerClusterGroup = require('react-leaflet-markercluster').default;
const L = require('leaflet');
const myIcon = L.icon(
iconUrl: require('../assets/marker.svg'),
iconSize: [64,64],
iconAnchor: [32, 64],
popupAnchor: null,
shadowUrl: null,
shadowSize: null,
shadowAnchor: null
);
return (
<React.Fragment>
<TileLayer
url="https://s.tile.openstreetmap.org/z/x/y.png"
attribution=''
setParams=true
/>
<MarkerClusterGroup>
coordArray.map(item =>
return (
<Marker icon=myIcon key=item.toString() position=[item.lat, item.lng]>
item.title && <Popup>
<span>item.title</span>
</Popup>
</Marker>
)
)
</MarkerClusterGroup>
</React.Fragment>
);
</Map>
【讨论】:
我如何以这种方式使用 react-icon?【参考方案3】:你不需要使用require。而不是给 iconUrl = "../assets/name" 您只需要导入您的 png 或 svg 然后您可以将源提供给您的 iconUrl。看下面的例子:
//首先导入你的图片或svg
import heart from "../../images/other/love.svg";
// 为你的图标提供来源
let loveIcon = L.icon(
iconUrl: heart,
iconRetinaUrl: heart,
iconAnchor: [5, 55],
popupAnchor: [10, -44],
iconSize: [25, 55],
);
// 只需将其添加到您的地图中
L.marker([28, 50],
icon: loveIcon,
).addTo(map);
【讨论】:
对我来说,它使用iconUrl: heart.src
在 next.js v11.1.0 上工作,否则它会将一个对象放入 img src。【参考方案4】:
您可以组织不同的文件,并更改 Svg 组件属性,如颜色、高度宽度等...
-
我们将创建一个函数 React 组件,注意我们必须将 ...props 中的一个 spreat 传递给 svg 文件,这样我们可以在执行时间上更改它:
import React from "react";
export default function PinMoto(props)
return (
//its a SVG example, it`s by half, or corrupted, to not occupy large caracter space here, use your SVG file here...
<svg viewBox="0 0 26 34" fill="none" xmlns="http://www.w3.org/2000/svg" ...props>
<path d="M13 0C6.0974 0 0.481453 5.83195 0.481453 13C0.481453 15.1519 0.999529 17.2855 1.98441 19.1779L12.3154 33.5811C12.4529 33.8397 12.715 34 13 34C13.285 34 13.547 33.8397 13.6846 33.5811L24.0194 19.1715C25.0005 17.2855 25.5185 15.1518 25.5185 12.9999C25.5185 5.83195 19.9026 0 13 0Z" fill="#DC462D" ...props/>
<g clip-Path="url(#clip0)">
<path d="M19.0012 12.7109C17.3488 12.7109 16.0023 14.1322 16.0023 15.8763C16.0023 17.6204 17.3453 19.0417 19.0012 19.0417C20.6535 19.0417 22 17.6242 22 15.8763C22 14.1285 20.6535 12.7109 19.0012 12.7109ZM19.0012 18.2513C17.7602 18.2513 16.7512 17.1863 16.7512 15.8763C16.7512 14.5663 17.7602 13.5013 19.0012 13.5013C20.2422 13.5013 21.2512 14.5663 21.2512 15.8763C21.2512 17.1863 20.2422 18.2513 19.0012 18.2513Z" fill="white" />
</g>
<defs>
<clippath id="clip0">
<rect fill="white" transform="translate(4 4)" />
</clippath>
</defs>
</svg>);
-
在另一个文件 Utils.js 中导入这个组件,在这个文件中我们可以找到一个函数,它返回一个实时修改的 React svg 组件:
import PinMoto from '../svg_pins/PinMoto'
import ReactDOM from 'react'
import renderToStaticMarkup from 'react-dom/server'
import divIcon from 'leaflet'
export const getRequiredSVGPinByCategory = (category, myStyle) =>
let pin
switch (category)
case 'motorcycle':
pin = <PinMoto ...myStyle/>
break;
case 'truck':
pin = <PinCaminhao ...myStyle/>
break;
default:
//pin = <PinPadrao ...myStyle/>
break;
const iconMarkup = renderToStaticMarkup(
pin
)
const customMarketIcon = divIcon(
html: iconMarkup
)
return customMarketIcon
-
在包含 MapContainer 的主文件中,我们可以这样使用:
import MapContainer, TileLayer, Marker, Popup from "react-leaflet";
import "leaflet/dist/leaflet.css";
import L from 'leaflet';
import getRequiredSVGPinByCategory from '../../utils/util'
//your jsx and codes...
<MapContainer
center=[-20.268589, -40.290479]
zoom=10
scrollWheelZoom=true
style=height: 500, width: '100%'>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://s.tile.openstreetmap.org/z/x/y.png"/>
<Marker position=[-20.268589, -40.290479]
icon= getRequiredSVGPinByCategory('motorcycle', fill: 'orange' ) >
</Marker>
</MapContainer>
//...
希望对大家有用。
【讨论】:
【参考方案5】:我也遇到了同样的问题。 这是我的工作解决方案:
`import L from 'leaflet';
import marker from '../assets/placer.svg';
const myIcon = new L.Icon(
iconUrl: marker,
iconRetinaUrl: marker,
popupAnchor: [-0, -0],
iconSize: [32,45],
);`
【讨论】:
以上是关于带有反应传单的自定义标记图标的主要内容,如果未能解决你的问题,请参考以下文章
带有自定义图块的传单地图上的标记位置随着更高的缩放级别而变化