reactjs - 在并排组件内限制对 React 中的 Leaflet TileLayers 的访问
问题描述
在一个显示地图的 React 应用程序上,我使用Leaflet-side-by-side插件(我按照这个线程的答案)做了一个并排比较器,它本身就可以正常工作。
但是,有些地图不是免费的,我想限制对它们的访问(并阻止对这些图块的请求)。现在,我已经做到了,除非您输入正确的密码,否则瓷砖不会显示。所以基本上,我需要在渲染后更新锁定的 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;
};
到目前为止,我没有成功地尝试过:
- 使用 map.invalidateSize() 强制更新
- 使用类似于 LockedLayer 的组件,但使用 L.tileLayer 而不是
- 使用 setTimeout 渲染地图(很高兴这不是解决方案)
- 只有解锁后才将 TileLayer 添加到地图中(它永远不会出现)
我正在寻找的是一种并排更新和重绘传单中的图层的方法,另一种限制对某些图层的访问的方法,或者是允许我使用 react-leaflet 的插件的替代方法。
提前感谢您的任何想法!
解决方案
在尝试了不同的配置之后,我认为让图层在更新后再次触发其请求的唯一方法是在useEffect
. 我写的LeafletLockedLayer
不能在里面使用useEffect
(因为它使用了钩子),但是一个简单的解决方法是useEffect
用一个临时的替换它自己的setTimeout
/ 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;
};
推荐阅读
- javascript - 去除 DFS 算法 cytoscape JS 中发现的边缘
- php - FPDF 错误:一些数据已经输出,无法发送 PDF 文件(输出开始于 C:\xampp\htdocs\movie\form.php:15)
- dc.js - DC 图表中的动态颜色
- python - 在填充函数中编辑字典(迭代函数)以自动填充视图,喜欢
- php - 我如何为 switch 语句中的输入赋予不同的名称,用于显示不同类型的问题
- python - 使用 Selenium 和 Python 在网页中滚动以获取数据
- c - 使用 scanf() 进行动态矩阵初始化
- javascript - Angular:如何从不同模板的输入为特定组件中的变量赋值
- jquery - Ajax 成功数据未附加到输入值
- android - 无法从应用程序中删除旧图标 - 为什么?