解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题 | 您所在的位置:网站首页 › 如何设置高德地图定位准确 › 解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题 |
本文完整demo在下面。 大屏在做大屏的时候,为了保证大屏完整的呈现在窗口中,一种简单的做法是大屏尺寸根据窗口尺寸做缩放调整,就像这样: Screen.jsx // Screen.jsx import { useState, useEffect } from "react" // 大屏容器样式 const style = { position: "absolute", left: "50%", top: "50%", backgroundColor: 'red' } // 生成一个防抖函数 function debounce(callback, time){ let timer = null return function(...arg){ if(timer) clearTimeout(timer) timer = setTimeout(() => { callback(...arg) }, time) } } // 计算缩放值 function calculate(desginWidth, desginHeight){ const { innerWidth, innerHeight } = window if(innerWidth / innerHeight // 缩放值 const [scale, setScale] = useState(1) // 组件首次加载时执行的逻辑 useEffect(() => { // 当窗口触发resize事件时的回调函数 const resizeHandler = debounce(() => { setScale(calculate(props.desginWidth, props.desginHeight)) }, 300) // 注册窗口的resize事件 window.addEventListener('resize', resizeHandler) resizeHandler() // 当组件卸载时移除之前窗口注册的resize事件 return () => { window.removeEventListener('resize', resizeHandler) } }, []) return ...style, width: `${props.desginWidth}px`, height: `${props.desginHeight}px`, transform:`translate(-50%, -50%) scale(${scale})` }} > {props.children} } 地图大屏组件有了,接下来利用高德地图api封装一个地图组件: Map.jsx // Map.jsx import AMapLoader from '@amap/amap-jsapi-loader' import { useRef } from 'react' const style = { width: "100%", height: "100%" } export default () => { const map = useRef(null) AMapLoader.load({ key: "2a49071d959081b738749e17f8207278", }).then(() => { const {AMap} = window // 创建一个地图 map.current = new AMap.Map('container', { center: [105.602725,37.076636], }) }) return return 1080}> }到目前,效果是这样的: 下图这个是大屏缩放正好是1的情况【transform:scale(1) 】,这个五角星的像素坐标是(784,321)。 鼠标点击点的经纬度应该来自大屏缩放为1的情况【transform: scale(1)】的像素坐标。所以你需要将得到的像素坐标除以缩放值后再转换成经纬度,再根据该经纬度立标记点,具体实施步骤见下面的实施解决方案。 实施解决方案通过点击地图事件的事件参数除了能拿到点击地图点的经纬度外,还可以拿到点击地图点的像素坐标,将像素坐标除以大屏目前的缩放值会得到一个新的坐标,将这个新的坐标转换成对应的经纬度(通过地图实例身上的containerToLngLat函数)作为标记点的经纬度。 Screen.jsx: import { useState, useEffect, createContext } from "react" export const context = createContext({ scale: 1 }) // 大屏容器样式 const style = { position: "absolute", left: "50%", top: "50%", backgroundColor: 'red' } // 生成一个防抖函数 function debounce(callback, time){ let timer = null return function(...arg){ if(timer) clearTimeout(timer) timer = setTimeout(() => { callback(...arg) }, time) } } // 计算缩放值 function calculate(desginWidth, desginHeight){ const { innerWidth, innerHeight } = window if(innerWidth / innerHeight // 缩放值 const [scale, setScale] = useState(1) // 组件首次加载时执行的逻辑 useEffect(() => { // 当窗口触发resize事件时的回调函数 const resizeHandler = debounce(() => { setScale(calculate(props.desginWidth, props.desginHeight)) }, 300) // 注册窗口的resize事件 window.addEventListener('resize', resizeHandler) resizeHandler() // 当组件卸载时移除之前窗口注册的resize事件 return () => { window.removeEventListener('resize', resizeHandler) } }, []) return ...style, width: `${props.desginWidth}px`, height: `${props.desginHeight}px`, transform:`translate(-50%, -50%) scale(${scale})` }} > scale }}> {props.children} }Map.jsx: import AMapLoader from '@amap/amap-jsapi-loader' import { useRef, useContext } from 'react' import { context } from '../components/Screen' const style = { width: "100%", height: "100%", } export default () => { const map = useRef(null) const {scale} = useContext(context) AMapLoader.load({ key: "2a49071d959081b738749e17f8207278", }).then(() => { const {AMap} = window // 创建一个地图 map.current = new AMap.Map('container', { center: [105.602725,37.076636], }) //监听点击地图事件 map.current.on('click', function(e) { // 鼠标点击地图点的像素坐标 const {x, y} = e.pixel // 像素坐标除以大屏缩放值得到一个新的坐标 const pixel2 = new AMap.Pixel(x / scale, y / scale) // 新的坐标转换成对应的经纬度 const {lng, lat} = map.current.containerToLngLat(pixel2) // 创建点标记 const marker = new AMap.Marker({ position: new AMap.LngLat(lng,lat), title: "一个标记点" }) // 将点标记添加到地图上 map.current.add(marker) }) }) return return 1080}> } |
CopyRight 2018-2019 实验室设备网 版权所有 |