解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题 您所在的位置:网站首页 如何设置高德地图定位准确 解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题

解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题

2024-07-15 01:23| 来源: 网络整理| 查看: 265

本文完整demo在下面。

大屏

在做大屏的时候,为了保证大屏完整的呈现在窗口中,一种简单的做法是大屏尺寸根据窗口尺寸做缩放调整,就像这样: 大屏跟随屏幕尺寸变化缩放演示 想实现上面这种效果,非常容易,监听window的resize事件,当window的resize事件触发时,根据此时window的尺寸与大屏的设计尺寸计算出一个缩放值,将大屏按照此缩放值进行transform:scale缩放。下面我用react简单做一个: App.jsx

// App.jsx import Screen from './components/Screen' export default function(){ return 1080}> 大屏区域 }

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}> }

到目前,效果是这样的: 地图效果 接下来实现鼠标点击地图某点就在该点树立一个标记点的功能。监听地图点击事件,事件参数中会有鼠标点击点的经纬度,高德地图api提供了点标记功能,能根据经纬度在地图上树立标记点。 在这里插入图片描述 试试效果: 请添加图片描述 期望的效果是在鼠标点击处产生标记点,但是实际上标记点的位置离鼠标点击位置有很大的偏差。

产生问题的原因

下图这个是大屏缩放正好是1的情况【transform:scale(1) 】,这个五角星的像素坐标是(784,321)。 在这里插入图片描述 如果将窗口缩小,大屏也会跟着缩小: 在这里插入图片描述比如上图这样,此时的大屏缩放变成0.8286792452830188的情况【transform: scale(0.8286792452830188)】,五角星的像素坐标是(652,266)。你会发现像素坐标除以缩放值得到的是大屏缩放为1的情况【transform:scale(1)】的像素坐标,比如652除以0.8286792452830188得到的786,266除以0.8286792452830188得到320(计算结果有轻微偏差,因为有小数除不尽,以及我测量的也不是很准确导致)。

鼠标点击点的经纬度应该来自大屏缩放为1的情况【transform: scale(1)】的像素坐标。所以你需要将得到的像素坐标除以缩放值后再转换成经纬度,再根据该经纬度立标记点,具体实施步骤见下面的实施解决方案。

实施解决方案

通过点击地图事件的事件参数除了能拿到点击地图点的经纬度外,还可以拿到点击地图点的像素坐标,将像素坐标除以大屏目前的缩放值会得到一个新的坐标,将这个新的坐标转换成对应的经纬度(通过地图实例身上的containerToLngLat函数)作为标记点的经纬度。 在这里插入图片描述 试试效果: 请添加图片描述 nice

完整demo / - - App.jsx - components - Screen.jsx - Map.jsx - node_modules - package.json

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 实验室设备网 版权所有