H5获取经纬度地址跳转Apple地图、百度、腾讯、高德地图导航

需求:H5移动端获取返回的经纬度和地址、点击导航按钮打开地图app实现导航功能、ios环境打开自带苹果地图、安卓环境弹出百度、腾讯、高德供选择跳转、判断ios环境、判断是否安装地图APP

一、实现一个导航按钮、绑定点击事件

 //根据后端返回的经纬度显示按钮、没有经纬度就不显示
{!!this.store.latitude && !!this.store.longitude && (
                    <p
                      className="to-address-btn"
                      onClick={() => this.store.goToAddress()}
                    >
                      <ReIcon icon="tour" className="icon" />
                      <Trans>导航</Trans>
                    </p>
                  )}

this.store:使用mobx状态管理、点击事件写在store里面。

二、判断ios环境、ios直接打开自带苹果地图

1.判断ios环境

代码如下(示例):

 IsIOS() {
        var u = navigator.userAgent;
        var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
        if (isiOS) {
            return true;
        }
    },

2.跳转苹果地图

代码如下(示例):

  goToAddress() {
    // 苹果自带地图
    if (utils.IsIOS()) {
      const iosUrl = `https://maps.apple.com/?q=${this.address}&sll=${this.longitude},${this.latitude}&z=10&t=m`;
      window.location.href = iosUrl;
    } else {
     //如果是安卓环境弹出选择地图app菜单
      this.mapListState = true;
    }
  }

三、Android打开地图App导航

1.判断android环境

 IsAndroid() {
        var u = navigator.userAgent;
        if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {
            return true;
        }
    },

2.导航地图菜单

@o mapAppList = [
    { id: 1, name: "百度地图" },
    { id: 2, name: "腾讯地图" },
    { id: 3, name: "高德地图" },
    { id: 5, name: "取消" },
  ];

3.渲染地图App菜单

//通过mapListState状态显示菜单显示
         <div
          className={
               this.store.mapListState
                        ? "map_app_choose_list show"
                        : "map_app_choose_list hide"
                    }
                    onClick={() => (this.store.mapListState = false)}
                  >
                    <div className="map_list_name">
                      {this.store.mapAppList.map((item) => {
                        return (
                          <p
                            onClick={() => this.store.goToMapApp(item.name)}
                            key={item.id}
                          >
                            {item.name}
                          </p>
                        );
                      })}
                    </div>
                  </div>

4. 判断跳转高德、腾讯、百度App导航

//判断手机是否安卓地图app的回调、h5不能判断是否安装app、只能通过延时器去判断 
 setTimeoutMyFn(data, setData) {
    window.location.href = data;
    window.setTimeout(() => {
      window.location.href = setData;
    }, 1000);
  }

  goToMapApp(name) {
    let destination = this.address;
    let key = "ZJ3BZ-7THCX-U3U4I-7DLMP-B3EAS-4OBRD";
    let urlCollect = {};
    // 腾讯
    let tengxunMobileUrl = `qqmap://map/marker?marker=coord:${this.latitude},${this.longitude};title:${destination};addr:${destination}&referer=${key}`;
    let tengxunH5Url = `https://apis.map.qq.com/uri/v1/marker?marker=coord:${this.latitude},${this.longitude};title:${destination};addr:${destination}&referer=${key}`;
    // 高德
    let gaodeH5Url = `https://uri.amap.com/marker?position=${this.longitude},${this.latitude}&name=${destination}&src=mypage&coordinate=gaode&callnative=1`;
    // 百度
    let baiduUrl = `marker?location=${this.latitude},${this.longitude}&title=${destination}&content=${destination}`;
    urlCollect.H5 = `https://api.map.baidu.com/${baiduUrl}&output=html&src=webapp.baidu.openAPIdemo`;
    //Android百度url
    urlCollect.Android = `bdapp://map/${baiduUrl}&src=andr.baidu.openAPIdemo`;
    switch (name) {
      case "百度地图":
        if (utils.IsAndroid()) {
          this.setTimeoutMyFn(urlCollect.Android, urlCollect.H5);
        } else {
          window.location.href = urlCollect.H5;
        }
        break;
      case "腾讯地图":
        this.setTimeoutMyFn(tengxunMobileUrl, tengxunH5Url);
        break;
      case "高德地图":
        window.location.href = gaodeH5Url;
        break;
      default:
        break;
    }
  }

5.显示效果

四、苹果跳转地图的bug:

window.location.replace(iosUrl) 来打开苹果地图,并且发现原先的地址栏域名被替换成了苹果地图的地址,这是因为 window.location.replace() 会在浏览器地址栏中直接替换当前URL,而不会保留原始的URL。这是浏览器行为的一部分,不会保留原始URL、下面是解决方案。
class YourComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      originalURL: window.location.href, // 保存原始URL
    };
  }

  goToAddress() {
    // 苹果自带地图
    if (utils.IsIOS()) {
      const iosUrl = `https://maps.apple.com/?q=${this.itemsWithCoordinates[0].address}&sll=${this.itemsWithCoordinates[0].longitude},${this.itemsWithCoordinates[0].latitude}&z=10&t=m`;

      // 使用pushState来保存原始URL,然后跳转到苹果地图
      window.history.pushState({ originalURL: this.state.originalURL }, '', this.state.originalURL);
      window.location.replace(iosUrl);
    } else {
      this.mapListState = true;
      this.openStop();
    }
  }

  componentDidMount() {
    // 添加popstate事件监听器,以便在用户返回时还原原始URL
    window.addEventListener('popstate', this.handlePopState);
  }

  componentWillUnmount() {
    // 在组件卸载时移除popstate事件监听器
    window.removeEventListener('popstate', this.handlePopState);
  }

  handlePopState = (event) => {
    // 当用户返回时,event.state中包含原始URL的信息
    if (event.state && event.state.originalURL) {
      window.location.replace(event.state.originalURL);
    }
  };

  render() {
    return (
      <div className="YourComponent">
        {/* 在这里放置你的React组件内容 */}
      </div>
    );
  }
}

总结

只要熟悉各类地图api参数、多看官方文档、实现起来还是比较简单

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐