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

这篇具有很好参考价值的文章主要介绍了解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文完整demo在下面。

大屏

在做大屏的时候,为了保证大屏完整的呈现在窗口中,一种简单的做法是大屏尺寸根据窗口尺寸做缩放调整,就像这样:
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
想实现上面这种效果,非常容易,监听window的resize事件,当window的resize事件触发时,根据此时window的尺寸与大屏的设计尺寸计算出一个缩放值,将大屏按照此缩放值进行transform:scale缩放。下面我用react简单做一个:
App.jsx

// App.jsx

import Screen from './components/Screen'

export default function(){
  return <Screen desginWidth={1920} desginHeight={1080}>
      <div>大屏区域</div>
	</Screen> 
}

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 < desginWidth / desginHeight) {
    return innerWidth / desginWidth
  }
  return innerHeight / desginHeight
}

// props: { designWidth:number, desginHeight:number }
export default (props) => {

  // 缩放值
  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 <div 
    style={{
      ...style, 
      width: `${props.desginWidth}px`,
      height: `${props.desginHeight}px`,
      transform:`translate(-50%, -50%) scale(${scale})`
    }}
  >
    {props.children}
  </div>
}

地图

大屏组件有了,接下来利用高德地图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 <div id='container' style={style}></div>
}

将地图组件安置到大屏里:
App.jsx

// App.jsx
import Screen from './components/Screen'
import Map from './components/Map'

export default function(){
  return <Screen desginWidth={1920} desginHeight={1080}>
      <Map />
   </Screen> 
}

到目前,效果是这样的:
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
接下来实现鼠标点击地图某点就在该点树立一个标记点的功能。监听地图点击事件,事件参数中会有鼠标点击点的经纬度,高德地图api提供了点标记功能,能根据经纬度在地图上树立标记点。
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
试试效果:
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
期望的效果是在鼠标点击处产生标记点,但是实际上标记点的位置离鼠标点击位置有很大的偏差。

产生问题的原因

下图这个是大屏缩放正好是1的情况【transform:scale(1) 】,这个五角星的像素坐标是(784,321)。
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
如果将窗口缩小,大屏也会跟着缩小:
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题比如上图这样,此时的大屏缩放变成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函数)作为标记点的经纬度。
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
试试效果:
解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题
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 < desginWidth / desginHeight) {
    return innerWidth / desginWidth
  }
  return innerHeight / desginHeight
}

// props: { designWidth:number, desginHeight:number }
export default (props) => {

  // 缩放值
  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 <div 
    style={{
      ...style, 
      width: `${props.desginWidth}px`,
      height: `${props.desginHeight}px`,
      transform:`translate(-50%, -50%) scale(${scale})`
    }}
  >
    <context.Provider value={{ scale }}>
      {props.children}
    </context.Provider>
  </div>
}

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 <div id='container' style={style}></div>
}

App.jsx:文章来源地址https://www.toymoban.com/news/detail-491235.html

import Screen from './components/Screen'
import Map from './components/Map'

export default function(){
  return <Screen desginWidth={1920} desginHeight={1080}>
      <Map />
  </Screen> 
}

到了这里,关于解决高德地图因被transform缩放导致获取鼠标点击地图某点的经纬度不准问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Echarts+高德地图,获取全国省市区,区域板块地图获取并高亮显示

    当用户选择省市区之后,可以看到对应区域的高亮显示。 如图: 之前用户选择的是江苏省,因此当前高亮显示的是江苏省地图板块,如果之前用户选择的是成都市,那么地图则会变成四川省的版图,高亮显示成都市,如下图: 可以继续下钻,选择区域高亮显示。 这里分享一个

    2024年02月16日
    浏览(49)
  • 高德API JS 高德地图获取多个坐标点的中心点

    我需要: 在地图上展示多个地点 地图缩放到合适的大小,要求刚好能显示全部点位 边缘留有一部分间隔。 做成如图所示这样。 经过一下午的研究,弄出来了。 需要以下这些 AMap 的类库: AMap.Bounds() 区域 AMap.LngLat() 点坐标(基础点位) AMap.setBounds() 设置地图区域,这会自动

    2024年02月07日
    浏览(59)
  • 高德地图根据经纬度获取地址信息

    主要是使用高德里面 地理编码与逆地理编码 的 getAddress 这个方法, 根据逆向地理编码:将地理坐标(经纬度)转换成地址描述信息,对应为AMap.Geocoder的getAddress方法。 具体使用的代码为 最后看效果 这是传的经纬度与解析出来的地理位置 如果需要正向解析将地理位置变成经

    2024年02月11日
    浏览(53)
  • 微信小程序使用高德地图获取当前定位

    1.在腾讯地图官网注册一个key(创建一个应用会自动生成一个key,详细步骤如图) 腾讯位置服务 - 立足生态,连接未来 注意点:开通webserviceAPI服务:控制台 -应用管理 - 我的应用 -添加key- 勾选WebServiceAPI - 保存 (小程序SDK需要用到webserviceAPI的部分服务,所以使用该功能的KEY需

    2024年02月06日
    浏览(64)
  • vue项目接入高德地图点击地图获取经纬度及省市区

    准备工作,可以先看官方的介绍,JSAPI结合Vue使用,这个不需要在main.js中引入 index.html中 index.vue的html部分 index.vue的script部分 index.vue的css部分 页面效果 逆解析经纬度得到的详细地址

    2024年02月16日
    浏览(53)
  • 小程序通过经纬度获取省市区(高德地图)

    在app.js文件中引入高德地图的js文件 获取当前定位   amap-wx.130.js文件

    2024年02月08日
    浏览(56)
  • uniapp h5获取用户地理位置信息(高德地图)

     使用uni.getLocation()先获取到当前位置信息的经纬度 H5端测试可以使用http,上线打包需要设置为https模式 谷歌浏览器可能会获取不到任何信息,因为谷歌浏览器位置信息是连接谷歌服务器获取的,国内用户可能获取位置信息失败 使用高德开发平台注册一个key 高德开发平台:高

    2024年02月13日
    浏览(45)
  • 高德地图的简单使用:点击标记获取经纬度和详细地址

    1. 先进入高德开发平台注册登录 2.进入地图 js Api 按照步骤申请key 3 使用npm安装依赖包 npm i @amap/amap-jsapi-loader --save 4. 高德api 都有说明 下面看下我实现的功能和代码 1. 初始化地图加载地图将自动定位到您所在城市并显示,点击地图实现了打点获取经纬度和详情地址。 2.输入提

    2024年02月12日
    浏览(80)
  • Java调用高德地图API根据详细地址获取经纬度

    访问高德开放平台https://lbs.amap.com/ 登录后,在控制台中创建一个应用,获取生成的应用key。这个key将用于访问高德地图API。   您可以使用Java中的 HttpURLConnection 或 HttpClient 等工具发送HTTP请求到高德地图API,并传递参数以获取经纬度信息。以下是一个使用 HttpURLConnection 的示例

    2024年02月05日
    浏览(55)
  • uniapp---- 微信小程序中获取当前地理位置(高德地图)

    1.在manifest.json中选择微信小程序配置,勾选上位置接口。 2.在manifest.json中选择源码视图,添加permission和requiredPrivateInfos 3.进入微信公众平台添加合法域名(不能少但是可以放在最后添加,调试期间可以打开开发者工具的不校验合法域名) 4.下载amap-wx.130.js,并且进行引用,

    2024年02月12日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包