7、高德地图(定位、复位功能)

  1. 组件jsx文件
import React, { useEffect, useRef, useState } from 'react';
import './index.less';

import { webMercator2LngLat, getCoordinateCommon } from '@/util/transformUtil';

import icon_punch_locate from '@/asset/image/informationization/afterSalesPunch/icon_punch_locate.png';

const Map = (props) => {
  const mapRef = useRef(null);
  const [position, setPosition] = useState(null);

  //初始化地图
  const initMap = () => {
    mapRef.current = new window.AMap.Map('map-container', {
      resizeEnable: true, //是否监控地图容器尺寸变化
      zoom: 15 //初始化地图层级
    });
    mapRef.current.on('click', getLnglat);
    // 在地图界面添加缩放控件
    window.AMap.plugin(['AMap.ToolBar'], () => {
      mapRef.current.addControl(new window.AMap.ToolBar());
    });
    getCoordinateCommon((coordinate) => {
      const [x, y] = coordinate.split(',');
      const [lng, lat] = webMercator2LngLat(x, y);
      mapRef.current.clearMap();
      const marker = new window.AMap.Marker({
        icon: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
        position: [lng, lat]
      });
      marker.setMap(mapRef.current);
      mapRef.current.setCenter(new window.AMap.LngLat(lng, lat));

      getAddressByPosition(lng, lat);
    });
  };
  //获取地图坐标
  const getLnglat = (e) => {
    mapRef.current.clearMap();
    const x = e.lnglat.getLng();
    const y = e.lnglat.getLat();
    const marker = new window.AMap.Marker({
      icon: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
      position: [x, y]
    });
    marker.setMap(mapRef.current);
    mapRef.current.setCenter(new window.AMap.LngLat(x, y));
    // getAddressByPosition(x, y);
  };
  //根据坐标获取位置名称,调用高德API
  const getAddressByPosition = (lng, lat) => {
    const geocoder = new window.AMap.Geocoder();
    geocoder.getAddress(new window.AMap.LngLat(lng, lat), (status, result) => {
      if (String(status) === 'complete') {
        const address = result.regeocode.formattedAddress;
        setPosition(address);
      }
    });
  };

  useEffect(() => {
    initMap();
  }, []);
  return (
    <div className="map-wrapper">
      <div id="map-container"></div>
      <div className="map-input">
        <div>
          <img src={icon_punch_locate} />
          <span>{position}</span>
        </div>
        <span
          className="re-locate"
          onClick={() => {
            initMap();
          }}>
          重新定位
        </span>
      </div>
    </div>
  );
};
export default Map;
  1. transformUtil文件
const myBrowser= () => {
    const ua = navigator.userAgent;
    const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
        iphone = ua.match(/(Android);?[\s\/]+([\d.]+)?/),
        chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/),
        safari =
            webview ||
            ua.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/),
        webview =
            !chrome && ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
        miniprogram = ua.toLowerCase().includes("miniprogram"),
        weixinpage = ua.toLowerCase().includes("micromessenger"),
        dingTalk = ua.toLowerCase().includes("dingtalk"),
        wxWork = ua.toLowerCase().includes("wxwork")

    if (dingTalk) {
        return "dingtalk"
    }
    if (wxWork) {
        return 'wxWork'
    }

    if (miniprogram && weixinpage) {
        return "miniprogram";
    }
    if (!weixinpage && android) {
        return "android";
    }
    if (!weixinpage && webview) {
        return "iOS";
    }
    if (weixinpage) {
        return "wxcommon"
    }
    return "web";
}
/**
 * 高德定位
 */
const positionByGaode = (callback) => {
  let that=this
    window.AMap.plugin('AMap.Geolocation', () => {
        const geolocation = new window.AMap.Geolocation({
          // 是否使用高精度定位,默认:true
          enableHighAccuracy: true,
          // 设置定位超时时间,默认:无穷大
          timeout: 10000,
          // 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
          buttonOffset: new window.AMap.Pixel(10, 20),
          //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
          zoomToAccuracy: true,
          //  定位按钮的排放位置,  RB表示右下
          buttonPosition: 'RB'
        });
        if (window.AMap.UA.ios) { 
          //使用远程定位,见 remogeo.js
           let remoGeo = new window.RemoGeoLocation(); 
          //替换方法
          navigator.geolocation.getCurrentPosition = function () {
              return remoGeo.getCurrentPosition.apply(remoGeo, arguments); 
          }; 
          //替换方法 
          navigator.geolocation.watchPosition = function() { 
              return remoGeo.watchPosition.apply(remoGeo, arguments);
           };
       }
        geolocation.getCurrentPosition((status, data) => {
            if(status == 'complete'){
                const { position: { lng, lat  } } = data;
                callback&&typeof callback === 'function' && callback(lng, lat);
            }else{
              console.log(data)
              callback&&typeof callback === 'function' && callback('', '');
            }
        });
    });
}
// 经纬度转墨卡托平面坐标
const lngLat2WebMercator = (lng, lat) => {
  const earthRad = 6378137.0;
  const x = ((lng * Math.PI) / 180) * earthRad;
  const a = (lat * Math.PI) / 180;
  const y =
    (earthRad / 2) * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
  return [x, y];
};
// 平面坐标转换经纬度
  const webMercator2LngLat = (x, y) => {
    let lng = (x / 20037508.34) * 180;
    let lat = (y / 20037508.34) * 180;
    lat =
      (180 / Math.PI) *
      (2 * Math.atan(Math.exp((lat * Math.PI) / 180)) - Math.PI / 2);
    return [lng, lat]; //[114.32894001591471, 30.58574800385281]
  };
  /**
 * 通用的获取位置坐标的方法,返回墨卡托
 */
const getCoordinateCommon = (callback) => {
	const BROWSER_TYPE = myBrowser1();
	const isPlatformMiniProgram = BROWSER_TYPE === 'miniprogram'
	const isPlatformDingtalk = BROWSER_TYPE === 'dingtalk'
	const isPlatformWeb = BROWSER_TYPE === 'web'
	const isPlatformAndroid = BROWSER_TYPE === 'android'
	const isPlatformIos = BROWSER_TYPE === 'iOS'
	const isPlatformWxWork = BROWSER_TYPE === 'wxWork'
	const isPlatformWxCommon = BROWSER_TYPE === 'wxcommon'
    if(isPlatformAndroid || isPlatformIos) {
        window.$bridge.callHandler("GET_COORDINATE", "调用获取坐标信息", data => {
            const [lng, lat] = data.split(',');
            const [x, y] = lngLat2WebMercator(lng, lat);
            typeof callback === 'function' && callback(`${x},${y}`);
        });
    } else if(isPlatformMiniProgram || isPlatformWxWork || isPlatformWxCommon) {
        window.wx.getLocation({
            type: 'wgs84',
            success (res) {
                const lng = res.longitude;
                const lat = res.latitude;
                const [x, y] = lngLat2WebMercator(lng, lat);
                typeof callback === 'function' && callback(`${x},${y}`);
            },
            fail(err) { // 失败后调用高德
                positionByGaode((lng, lat) => {
                    const [x, y] = lngLat2WebMercator(lng, lat);
                    typeof callback === 'function' && callback(`${x},${y}`);
                });
            }
        })
    } else {
        positionByGaode((lng, lat) => {
            const [x, y] = lngLat2WebMercator(lng, lat);
            typeof callback === 'function' && callback(`${x},${y}`);
        });
    }
}
  1. 样式文件
@import '../../common/common.less';
@img-width: 0.5rem;
.map-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  #map-container {
    width: 100%;
    flex: 1;
    .amap-copyright {
      display: none !important;
    }
  }
  .map-input {
    line-height: @line-height;
    height: @line-height;
    background-color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 0.32rem;
    width: 100%;
    div {
      display: flex;
      align-items: center;
      width: 80%;
      img {
        width: @img-width;
        height: @img-width;
      }
      span {
        color: #333333;
        font-weight: bold;
        margin-left: 0.1rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
    .re-locate {
      font-weight: 500;
      color: #00a189;
      white-space: nowrap;
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值