CircleMarker的自定义形状(或更好的方法)

问题描述 投票:0回答:1

我正在使用具有超过2000个标记坐标的数据集。

出于性能原因,我决定使用preferCanvas道具将这些标记添加到画布,并且它与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-leafletPath组件,例如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);

并且我认为起初我应该使用像Leaflet这样的基本Canvas渲染器,但是我得到了Uncaught Error: The provided object is not a Layer.

其他人是否实施了类似的措施?

reactjs leaflet react-leaflet
1个回答
0
投票

好吧,在阅读了this后,我设法为react-leaflet实现了类似的功能。当前,它仅使用传单的Canvas _updateCircle方法的代码,但这是不同形状的开始。

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

我希望我的回答可以帮助其他人。

© www.soinside.com 2019 - 2024. All rights reserved.