gpt4 book ai didi

reactjs - 响应式设计中的传单坐标到纬度

转载 作者:行者123 更新时间:2023-12-04 09:25:44 32 4
gpt4 key购买 nike

我有一个 Leaflet 响应式 map ,我在 React 中使用它。我的 map 是一个自定义平面图,它在 svg 中。我已经使用“ImageOverlay”设置了 map ,一切正常。现在我的问题只有在我使用点 (x, y) 坐标并将其转换为 lat, lng 时才会发生. lat, lng正在根据屏幕尺寸变化。我需要一个固定的 lat, lng各自的屏幕尺寸,以便我可以显示标记。目前,如果我根据屏幕尺寸显示标记,则标记位置会显示在不同的位置。 所以我的问题是如何获得lat, lng与屏幕尺寸无关? 这是我的代码:

L.CRS.Simple = L.extend({}, L.CRS, {
projection: L.Projection.LonLat,
transformation: new L.Transformation(1, 0, 1, 0)
});

const mapHeight = 400;
const mapWidth = 100;
const svgImageWidth = 2245;
const svgImageHeight = 1587;

const initState = {
mapBounds: [[0, 0], [1000, 1000]],
mapMarkerPosition: [40.751, -74.17],
mapZoom: 4,
mapCenter: [40.74400563300867, -74.1680145263672],
xCoordinate: "",
yCoordinate: "",
coordinates: { x: 292, y: 89 }
};

export default function App() {
const mapRef = useRef(null);
const [state, setState] = useState(initState);

function getBoundsUnproject(map) {
const southWest = map.unproject([0, svgImageHeight], 6);
const northEast = map.unproject([svgImageWidth, 0], 6);
const bounds = new L.LatLngBounds(southWest, northEast);
map.setMaxBounds(bounds);
return { bounds };
}

React.useEffect(() => {
const map = mapRef.current.leafletElement;
if (map) {
const { bounds } = getBoundsUnproject(map);
console.log("bounds", bounds);
map.fitBounds(bounds);

const centerLatLng = map.getCenter();
console.log("center", centerLatLng);

const customCoordinates = state.coordinates;
// console.log("customCoordinates", customCoordinates);
const point = L.point(customCoordinates.x, customCoordinates.y);
const customCoordinatesLatLng = map.containerPointToLatLng(point);
console.log("customCoordinatesLatLng", customCoordinatesLatLng);

setState(prevState => ({
...prevState,
mapBounds: [
[bounds._northEast.lat, bounds._northEast.lng],
[bounds._southWest.lat, bounds._southWest.lng]
],
mapMarkerPosition: [
customCoordinatesLatLng.lat,
customCoordinatesLatLng.lng
]
}));
}
}, [state.coordinates]);

function handleChange(event) {
const name = event.target.name;
const value = event.target.value;

if (isNaN(value)) {
return;
}

setState(prevState => ({
...prevState,
[name]: value
}));
}

function handleClick() {
setState(prevState => ({
...prevState,
coordinates: { x: state.xCoordinate, y: state.yCoordinate }
}));
}

return (
<div className="container-fluid">
<div className="row justify-content-center mt-5">
<div className="col-md-6">
<div className="row justify-content-center">
<div className="col-md-4">
<input
style={{ width: "100%" }}
type="text"
value={state.xCoordinate}
onChange={handleChange}
name="xCoordinate"
placeholder="x coordinate (default: 292)"
/>
</div>
<div className="col-md-4">
<input
style={{ width: "100%" }}
type="text"
value={state.yCoordinate}
onChange={handleChange}
name="yCoordinate"
placeholder="y coordinate (default: 89)"
/>
</div>
<div className="col-md-2">
<button onClick={handleClick}>Submit</button>
</div>
</div>
</div>
</div>
<div className="row justify-content-center mt-5 mb-5">
<div className="col-6">
<LeafletMap
ref={mapRef}
crs={L.CRS.Simple}
center={state.mapCenter}
zoom={state.mapZoom}
minZoom={state.mapZoom}
style={{ height: `${mapHeight}px`, width: `${mapWidth}%` }}
>
<ImageOverlay
bounds={state.mapBounds}
url={"image-url"}
>
<Marker
position={state.mapMarkerPosition}
icon={customMarkerIcon}
/>
</ImageOverlay>
</LeafletMap>
</div>
</div>
</div>
);
}


如果有人指出我做错了什么,那会很有帮助。
谢谢。

最佳答案

问题是 map.containerPointToLatLng() ,顾名思义,假设您给它的 Point 是相对于 map 的容器坐标,即它的左上角。
但是由于我们通常通过其中心(和缩放)指定 map View ,因此左上角的容器可能会根据其大小显示不同的经纬度位置。并且由于您将其大小(宽度)设置为其父元素的 100%,如果您有响应式设计,则此大小可能会随屏幕大小/方向而变化。
当容器左上角显示不同的纬度位置时,map.containerPointToLatLng 也会不同。
一个可能的解决方案是在计算转化率的方式上保持一致。您很可能实际上希望您的标记相对于您的 SVG 平面图而不是 map 容器进行定位。在这种情况下,只需按照与平面图边界相同的方式计算您的标记坐标,即使用 map.unproject()

关于reactjs - 响应式设计中的传单坐标到纬度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63018557/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com