在并排组件内限制对 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;
};
到目前为止我已经尝试失败:
- 使用 map.invalidateSize() 强制更新
- 使用类似于 LockedLayer 的组件,但使用 L.tileLayer 而不是
- 使用 setTimeout 渲染地图(很高兴这不是解决方案)
- 仅在解锁时将 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;
};
在显示地图的 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;
};
到目前为止我已经尝试失败:
- 使用 map.invalidateSize() 强制更新
- 使用类似于 LockedLayer 的组件,但使用 L.tileLayer 而不是
- 使用 setTimeout 渲染地图(很高兴这不是解决方案)
- 仅在解锁时将 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;
};