在并排组件内限制对 React 中的 Leaflet TileLayers 的访问

Restricted access to Leaflet TileLayers in React inside a side-by-side component

在显示地图的 React 应用程序上,我使用 leaflet-side-by-side plugin (I followed the answer to ) 制作了一个并排比较器,它自己运行良好。

但是,有些地图不是免费的,我想限制对它们的访问(并阻止对这些图块的请求)。现在,我已经做到了,除非您输入正确的密码,否则磁贴不会显示。 所以基本上,我需要在渲染后更新锁定的 TileLayer。当我使用 react-leaflet 时,我只是在密码匹配时使用 setUrl 来更新 TileLayer :

const LockedLayer = ({ lockedUrl, attribution }) => {
  const pwd = Config.PWD;
  const [inputPwd, setInputPwd] = useState(null);

  const tileLayerRef = useRef(null);

  useEffect(() => {
    if (pwd === inputPwd) {
      tileLayerRef.current.setUrl(lockedUrl);
    }
  });

  return <TileLayer attribution={attribution} url="" ref={tileLayerRef} />;
};

效果很好。

但对于并排传单,我需要使用本机传单,其行为不同。应用于由 L.tileLayer 创建的 TileLayer 的相同代码没有效果,即使 URL 已正确更新,尽管图层发生变化,地图也不会更新其内容(因为它在钩子内,我假设)。就像我提到的,我在添加自己的层之前从一个线程复制粘贴了代码,它看起来像:

import "leaflet-side-by-side";
...

const Map = () => {
  useEffect(() => {
    const map = L.map("map").setView([51.505, -0.09], 13);

    const osmLayer = L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", { attribution: 'OSM' }).addTo(map);

    const lockedLayer = LeafletLockedLayer(
      "PROTECTED_URL", { attribution: 'credits'}
    ).addTo(map);

    L.control.sideBySide(lockedLayer, osmLayer).addTo(map);
  }, []);

  return <div id="map" />;
};
const LeafletLockedLayer = ({ lockedUrl, attribution }) => {
  const pwd = Config.PWD;
  const [inputPwd, setInputPwd] = useState(null);

  const tileLayer = L.tileLayer("", { attribution: attribution });

  useEffect(() => {
    if (pwd === inputPwd) {
      tileLayer.setUrl(lockedUrl);
    }
  });

  return tileLayer;
};

到目前为止我已经尝试失败:

我正在寻找的是一种更新和重绘并排传单中的层的方法,另一种限制对某些层的访问的方法,或者允许我的插件的替代方法使用反应传单。

提前感谢任何想法!

在尝试了不同的配置之后,我认为让图层再次触发其请求的唯一方法 post-update 是在 useEffect 中的地图旁边创建它。我写的 LeafletLockedLayer 不能在 useEffect 中使用(因为它使用了钩子),但是解决这个问题的一个简单方法是用 [=15] 临时替换它自己的 useEffect =]/setInterval。虽然我宁愿不使用那些,但我没有时间寻找更好的解决方案,而且读取密码所需的时间比加载磁贴要短。

这是一个工作 LeafletLockedLayer 可以在与地图相同的 useEffect 内创建:

const LeafletLockedLayer = ({ lockedUrl, attribution }) => {
  const storedPwd = Config.layersPwd;
  let pwd = null;

  const tileLayer = L.tileLayer("", { attribution: attribution });

  const interval = setInterval(() => updateLayer(), 100);
  const updateLayer = () => {
    if (pwd === storedPwd) {
      tileLayer.setUrl(lockedUrl);
      clearInterval(interval);
    }
  };

  return tileLayer;
};