CircleMarker 的自定义形状(或更好的方法)
Custom shape of CircleMarker (or better approach)
我正在处理具有超过 2000
个标记坐标的数据集。
出于性能原因,我决定使用 preferCanvas
属性将这些标记添加到 canvas,它与 CircleMarker
配合使用效果很好,它是矢量图层类别下的唯一标记.
但是 CircleMarker
形状可以改变吗?
这是一个代码片段:
const HeatMap = ({ markers }) => {
return (
<Map
center={[50.3785, 14.9706]}
zoom={1}
preferCanvas={true}
style={{ height: "400px", marginTop: "30px", marginBottom: "30px" }}
>
<TileLayer url={map_url} />
{ markers.map((i) => (
<CircleMarker
key={i.id}
center={[i.lat, i.lon]}
stroke={false}
radius={4}
fillOpacity={0.8}
>
<Tooltip>{i.details}</Tooltip>
</CircleMarker>
))}
</Map>
);
};
更新:
所以我决定创建一个自定义标记组件来扩展 react-leaflet
的 Path
组件,例如 CircleMarker
:
import {
CircleMarker as LeafletCircleMarker,
Canvas as LeafletCanvas,
} from "leaflet";
import { withLeaflet, Path } from "react-leaflet";
const myRenderer = (layer) => LeafletCanvas({ padding: 0.5 });
class CustomMarker extends Path {
createLeafletElement(props) {
const enhancedProps = {
...props,
renderer: myRenderer
};
const el = new LeafletCircleMarker(
props.center,
this.getOptions(enhancedProps)
);
this.contextValue = { ...props.leaflet, popupContainer: el };
debugger;
return el;
}
updateLeafletElement(fromProps, toProps) {
if (toProps.center !== fromProps.center) {
this.leafletElement.setLatLng(toProps.center);
}
if (toProps.radius !== fromProps.radius) {
this.leafletElement.setRadius(toProps.radius);
}
}
}
export default withLeaflet(CustomMarker);
我认为最初我应该使用像 Canvas
这样的基本 Leaflet
渲染器,但我得到的是 Uncaught Error: The provided object is not a Layer.
还有其他人实现过类似的东西吗?
好的,所以在阅读 SO 答案后,我设法为 react-leaflet
实现了类似的东西。目前只是使用了leaflet的Canvas
_updateCircle
方法的代码,但对于不同的shape来说是一个开始
import {
CircleMarker as LeafletCircleMarker,
Canvas as LeafletCanvas,
} from "leaflet";
import { withLeaflet, Path } from "react-leaflet";
LeafletCanvas.include({
_updateCustomMarker: function (layer) {
if (!this._drawing || layer._empty()) {
return;
}
var p = layer._point,
ctx = this._ctx,
r = Math.max(Math.round(layer._radius), 1),
s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
if (s !== 1) {
ctx.save();
ctx.scale(1, s);
}
ctx.beginPath();
ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
if (s !== 1) {
ctx.restore();
}
this._fillStroke(ctx, layer);
},
});
class CustomMarker extends Path {
createLeafletElement(props) {
const MyMarker = LeafletCircleMarker.extend({
_updatePath: function () {
this._renderer._updateCustomMarker(this);
},
});
const el = new MyMarker(props.center, this.getOptions(props));
this.contextValue = { ...props.leaflet, popupContainer: el };
return el;
}
updateLeafletElement(fromProps, toProps) {
if (toProps.center !== fromProps.center) {
this.leafletElement.setLatLng(toProps.center);
}
if (toProps.radius !== fromProps.radius) {
this.leafletElement.setRadius(toProps.radius);
}
}
}
export default withLeaflet(CustomMarker);
希望我的回答可以帮助到其他人。
我正在处理具有超过 2000
个标记坐标的数据集。
出于性能原因,我决定使用 preferCanvas
属性将这些标记添加到 canvas,它与 CircleMarker
配合使用效果很好,它是矢量图层类别下的唯一标记.
但是 CircleMarker
形状可以改变吗?
这是一个代码片段:
const HeatMap = ({ markers }) => {
return (
<Map
center={[50.3785, 14.9706]}
zoom={1}
preferCanvas={true}
style={{ height: "400px", marginTop: "30px", marginBottom: "30px" }}
>
<TileLayer url={map_url} />
{ markers.map((i) => (
<CircleMarker
key={i.id}
center={[i.lat, i.lon]}
stroke={false}
radius={4}
fillOpacity={0.8}
>
<Tooltip>{i.details}</Tooltip>
</CircleMarker>
))}
</Map>
);
};
更新:
所以我决定创建一个自定义标记组件来扩展 react-leaflet
的 Path
组件,例如 CircleMarker
:
import {
CircleMarker as LeafletCircleMarker,
Canvas as LeafletCanvas,
} from "leaflet";
import { withLeaflet, Path } from "react-leaflet";
const myRenderer = (layer) => LeafletCanvas({ padding: 0.5 });
class CustomMarker extends Path {
createLeafletElement(props) {
const enhancedProps = {
...props,
renderer: myRenderer
};
const el = new LeafletCircleMarker(
props.center,
this.getOptions(enhancedProps)
);
this.contextValue = { ...props.leaflet, popupContainer: el };
debugger;
return el;
}
updateLeafletElement(fromProps, toProps) {
if (toProps.center !== fromProps.center) {
this.leafletElement.setLatLng(toProps.center);
}
if (toProps.radius !== fromProps.radius) {
this.leafletElement.setRadius(toProps.radius);
}
}
}
export default withLeaflet(CustomMarker);
我认为最初我应该使用像 Canvas
这样的基本 Leaflet
渲染器,但我得到的是 Uncaught Error: The provided object is not a Layer.
还有其他人实现过类似的东西吗?
好的,所以在阅读 react-leaflet
实现了类似的东西。目前只是使用了leaflet的Canvas
_updateCircle
方法的代码,但对于不同的shape来说是一个开始
import {
CircleMarker as LeafletCircleMarker,
Canvas as LeafletCanvas,
} from "leaflet";
import { withLeaflet, Path } from "react-leaflet";
LeafletCanvas.include({
_updateCustomMarker: function (layer) {
if (!this._drawing || layer._empty()) {
return;
}
var p = layer._point,
ctx = this._ctx,
r = Math.max(Math.round(layer._radius), 1),
s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
if (s !== 1) {
ctx.save();
ctx.scale(1, s);
}
ctx.beginPath();
ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
if (s !== 1) {
ctx.restore();
}
this._fillStroke(ctx, layer);
},
});
class CustomMarker extends Path {
createLeafletElement(props) {
const MyMarker = LeafletCircleMarker.extend({
_updatePath: function () {
this._renderer._updateCustomMarker(this);
},
});
const el = new MyMarker(props.center, this.getOptions(props));
this.contextValue = { ...props.leaflet, popupContainer: el };
return el;
}
updateLeafletElement(fromProps, toProps) {
if (toProps.center !== fromProps.center) {
this.leafletElement.setLatLng(toProps.center);
}
if (toProps.radius !== fromProps.radius) {
this.leafletElement.setRadius(toProps.radius);
}
}
}
export default withLeaflet(CustomMarker);
希望我的回答可以帮助到其他人。