点击地图时如何获取选中瓦片的角坐标并绘制其边框?
解决方案
你已经能获取点击位置对应的瓦片坐标,接下来只需要将瓦片坐标转换为对应的经纬度边界,就能直接用L.rectangle绘制瓦片边缘的矩形了。下面提供两种实现方式:
方式一:基于瓦片编号计算经纬度边界
先实现一个将瓦片x/y编号、缩放级别转换为经纬度边界的函数,再整合到点击事件中:
- 瓦片坐标转边界的函数
function tileToBounds(xtile, ytile, zoom) { // 计算单个瓦片的经度跨度 const lonSpan = 360 / Math.pow(2, zoom); // 瓦片西南、东北经度 const west = xtile * lonSpan - 180; const east = (xtile + 1) * lonSpan - 180; // 反推瓦片的纬度范围 const southRad = Math.PI - 2 * Math.PI * (ytile + 1) / Math.pow(2, zoom); const northRad = Math.PI - 2 * Math.PI * ytile / Math.pow(2, zoom); const south = (180 / Math.PI) * Math.atan(0.5 * (Math.exp(southRad) - Math.exp(-southRad))); const north = (180 / Math.PI) * Math.atan(0.5 * (Math.exp(northRad) - Math.exp(-northRad))); // 返回Leaflet所需的bounds格式:[[西南纬度, 西南经度], [东北纬度, 东北经度]] return [[south, west], [north, east]]; }
- 整合到点击事件
function MyTestFunc1(latlng, zoom) { var xtile = parseInt(Math.floor((latlng.lng + 180) / 360 * Math.pow(2, zoom))); var ytile = parseInt(Math.floor((1 - Math.log(Math.tan(latlng.lat * Math.PI / 180) + 1 / Math.cos(latlng.lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom))); return { xtile, ytile, zoom }; } map.on('click', function(e) { const tileInfo = MyTestFunc1(e.latlng.wrap(), map.getZoom()); const tileBounds = tileToBounds(tileInfo.xtile, tileInfo.ytile, tileInfo.zoom); // 绘制瓦片边缘矩形 L.rectangle(tileBounds, {color: "#ff7800", weight: 2}).addTo(map); // 可选:将地图视野定位到该瓦片 // map.fitBounds(tileBounds); });
方式二:利用Leaflet容器坐标直接推导(更简便)
不需要手动计算瓦片编号,直接通过点击点的容器坐标推导瓦片边界,代码更简洁:
map.on('click', function(e) { const zoom = map.getZoom(); const tileSize = map.getTileSize(); // 将点击点经纬度转为容器坐标 const clickPoint = map.latLngToContainerPoint(e.latlng); // 计算当前瓦片的左上角容器坐标 const tileTopLeft = L.point( Math.floor(clickPoint.x / tileSize) * tileSize, Math.floor(clickPoint.y / tileSize) * tileSize ); // 瓦片右下角容器坐标 const tileBottomRight = tileTopLeft.add(tileSize); // 转换为经纬度坐标 const sw = map.containerPointToLatLng(tileBottomRight); const ne = map.containerPointToLatLng(tileTopLeft); // 绘制矩形 L.rectangle([sw, ne], {color: "#ff7800", weight: 2}).addTo(map); });
内容的提问来源于stack exchange,提问作者WayMax
相关产品推荐
相关产品推荐

