IT/互联网/科技
带你撬开百度地图API的大门
2023-08-26 08:09

带你撬开百度地图API的大门

百度地图快捷入口背景

给甲方做项目, 我们公司的H5应用一直使用的是腾讯地图(组内别的成员负责开发的,我对这一块知之甚少), 而甲方之前别的应用采购了百度地图,虽说腾讯地图目前不收费,难保以后不收费,甲方不想采购两套地图。应甲方要求,需要将H5应用中的腾讯地图替换成百度地图,由此我也开始了一场学习在H5应用中使用百度地图之旅。

第一站 注册开发者账号

首先你得有一个百度账号,才能登陆,由于我在百度App上注册过账号,所以无需再次注册。然而我打开百度App,打算扫码登陆百度地图开放平台时,却发现百度App的扫码功能入口藏得有点深,找了半天才找到。入口是拍照图标,进入之后底部默认是识万物功能,需要向左滑动,才是扫码功能。

进入注册页,开发者类型选择个人开发者,点击成为个人开发者按钮,开始注册,按部就班,勾选协议,填写个人信息,做人脸识别。

有一个必填项是应用场景,不能少于100字, 我东拼西凑了100字。

主要的应用场景有:

在h5移动端端,发起定位带你撬开百度地图API的大门,获取当前打开页面者的位置信息。在PC端发起定位,获取当前登陆者的位置信息在PC端,可以在地图上移动选择地址,校正定位带来的误差在移动端,可以把PC端的经纬度数值转换成具体的地址

账号注册成功后,会跳转到百度地图开放平台首页,点击控制台

第二站 创建应用,获取AK

进入控制台--应用管理--我的应用下面,创建应用。

我们创建一个浏览器端的学习demo应用, 启用服务选择提供的所有服务,Referer白名单填写*号,不限制域名

注册成功之后,会生成一个App Key, 这个AK贯穿你使用百度地图Api的始终。

另外, 百度地图对个人认证用户, 绝大多数Api每天调用的限制次数是5000次, 每秒钟只能查询30次。用于学习的话,够用了。

第三站 调用百度地图功能3.1 展示地图

在E盘study/baidu-map文件夹下创建一个index.html文件,内容如下:

<head>
    <meta charset="utf-8">
    <title>地图展示title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <style>
    body,
    html,
    #container {
        overflow: hidden;
        width: 100%;
        height: 100%;
        margin: 0;
        font-family: "微软雅黑";
    }
    .info {
        z-index: 999;
        width: auto;
        min-width: 22rem;
        padding: .75rem 1.25rem;
        margin-left: 1.25rem;
        position: fixed;
        top: 1rem;
        background-color: #fff;
        border-radius: .25rem;
        font-size: 14px;
        color: #666;
        box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
    }
    style>
    <script src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=申请的AppKey">script>
head>
<body>
    <div class = "info">最新版GL地图命名空间为BMapGL, 可按住鼠标右键控制地图旋转、修改倾斜角度。div>
    <div id="container">div>
body>
html>
<script>
// 创建地图容器
var map = new BMapGL.Map('container'); 
// 初始化地图,设置中心点坐标和地图级别,中心坐标设置的是天安门
map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 12); 
// 使能鼠标滚轮缩放地图功能
map.enableScrollWheelZoom(true); 
script>

3.2 启动运行

安装静态服务器

npm install -g http-server

启动静态服务

http-server e:/study/baidu-map

3.3 效果图

下面这张地图都可以移动和放大。

3.4 定位标注功能

再看一个vue3版本,实现获取位置并在地图上进行标注的功能。注意:第一次同意获取位置信息授权也会提示失败,之后运行正常。

<template>
  <div id="baidu-map-box">div>
template>
<script setup lang="ts">
  import { onMounted } from 'vue';
  onMounted(() => {
    const map = mapInit();
    getLocation(map);
  });
  const BMap= window.BMapGL;
  const mapInit = () => { 
    const map = new BMap.Map('baidu-map-box');
    // 绘制地图,中央点设置为北京天安门
    const point = new BMap.Point(116.331398, 39.897445);
    map.centerAndZoom(point, 12);
    return map;
  };
  // 获取定位,需要授权
  const getLocation = (map) => {
    var geolocation = new BMap.Geolocation();
    geolocation.getCurrentPosition(function (r) {
      if (this.getStatus() == BMAP_STATUS_SUCCESS) {
        // 在地图上添加坐标
        var mk = new BMap.Marker(r.point);
        map.addOverlay(mk);
        map.panTo(r.point);
        // 将经纬度解析成地址
        parseLngLat(r.point);
        // alert('您的位置:' + r.point.lng + ',' + r.point.lat);
      } else {
        alert('failed' + this.getStatus());
      }
    });
  };
  // 解析经纬度为具体的地址
  const parseLngLat = ({ lng, lat }) => {
    // 创建地理编码实例
    var myGeo = new BMap.Geocoder();
    // 根据坐标得到地址描述
    myGeo.getLocation(new BMap.Point(lng, lat), function (result) {
      if (result) {
        alert(result.address);
      }
    });
  };
script>
<style scoped>
  #baidu-map-box {
    height: 100%;
  }
style>

有两点要说明一下:

定位出来的经纬度不是GPS的经纬度,而是百度坐标系的经纬度。不是通用的,使用其它地图时,需要转换。官方文档是这样说的:

目前国内主要有以下三种坐标系:

WGS84:大地坐标系,也称国际标准。是目前广泛使用的GPS全球卫星定位系统使用的坐标系。

GCJ02:火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。也称中国坐标偏移标准,、高德、腾讯使用

BD09:为百度坐标系,在GCJ02坐标系基础上再次加密。其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标。

非中国地区地图,服务坐标统一使用WGS84坐标

墨卡托坐标是为了解决什么问题?

简而言之,使用二维平面地图的坐标就是墨卡托坐标。使用球形坐标,航海家航行时用罗盘、六分仪确定的航向很难将他们的航线画在地图上,因为球形地图的方位角随着地理位置不断改变的。墨卡托坐标是为了解决将球面上的一部分地物绘制在平面上,航海者可以在平面图上用直线来表示航线,准确地表示出方向角指示航向。

需要转换时百度地图 反解析,请参考

  
  const qqGDMapToBMap=({lng, lat})=>{
    let x_pi = (3.14159265358979324 * 3000.0) / 180.0;
    let x = lng;
    let y = lat;
    let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
    let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
    let lngs = z * Math.cos(theta) + 0.0065;
    let lats = z * Math.sin(theta) + 0.006;
    return {
      lng: lngs,
      lat: lats,
    };
  }
  
  const bMapToQQGDMap=({lng, lat})=>{
    let x_pi = (3.14159265358979324 * 3000.0) / 180.0;
    let x = lng - 0.0065;
    let y = lat - 0.006;
    let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
    let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
    let lngs = z * Math.cos(theta);
    let lats = z * Math.sin(theta);
    return {
      lng: lngs,
      lat: lats,
    };
  }

另外,看到这里,大家可能觉得百度地图在国际上不通用,出国之后应该使用高德地图。然而笔者以前去过日本,发现在日本,高德地图不能使用,高德地图只提供国内导航服务,这个时候才发现冲出中国的是百度地图百度地图 反解析,百度地图才是中国地图界的一哥呀。

对于刚学习百度地图Api用法的小白而言,相信你也和我一样,肯定不知道上面示例,或者官方展示的demo示例代码片段中Api的作用及传参含义,比如说这个方法的传参含义及参数的约束条件,贴心的楼主已经给你把链接放在文中了, 请点击这里

3.5 将GPS坐标转换成百度坐标

在企业微信中,调用获取定位的JS-SDK,wx.获取到的是GPS坐标,现在需要转换成百度坐标,之后逆向解析出地址,如何根据经纬度解析出地址,上一章节有提及,现在看看如何将GPS坐标转换成百度坐标。

wx.getLocation({
    type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
    success: function (res) {
        var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
        var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
        var speed = res.speed; // 速度,以米/每秒计
        var accuracy = res.accuracy; // 位置精度
        var gpsPoint = new BMap.Point(latitude, longitude);
        var convertor = new BMap.Convertor();
         convertor.translate(gpsPoint, 1, 5, ()=>{
            if (data.status === 0) {
              // 转换出来的百度地图
              console.log(data.points[0]);
            }
        })
    }
});

细心的同学可能发现了,上一章节示例代码中,百度地图类空间的命名是BMapGL,本章节是BMap,这两者有什么区别呢?

BMap引入版本是2.0及以上版本  <script src="//api.map.baidu.com/api?v=2.0&ak=您的秘钥">script>
BMapGL引入版本是1.0  <script src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=您的密钥">script>

API v3.0 是在 v2.0 的基础上进行开发的,并针对2.0的一些接口进行了升级,为开发者提供更完善的服务。v3.0的绝大部分接口向下兼容,开发者仅需要修改版本参数 (v=3.0) 就可以切换到 API v3.0版本。具体版本差异请参考服务版本说明书。

如果项目使用的是Vue3的话,现在百度地图还没有做vue3的适配,所以写法与官方教程示例稍微不一样,如下所示

  const BMap= window.BMapGL;
  const mapInit = () => { 
    const map = new BMap.Map('baidu-map-box');
    // 绘制地图,中央点设置为北京天安门
    const point = new BMap.Point(116.331398, 39.897445);
    map.centerAndZoom(point, 12);
    return map;
  };

v2.0和v3.0的主要差异如下,由下表可以看出,高版本的功能多一点,或者对低版本的实现有优化, 绝大多数接口向下兼容,所以使用时尽量选择高版本,比如现在应该在项目中使用v3.0版本。

3.6 在ts中使用百度地图

declare const BMapGL: any;

yarn add -D @types/bmapgl

在.lib.json中引入bmapgl的定义

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "types": ["webpack-env", "node", "bmapgl"]
  },
  "exclude": ["***.spec.tsx"],
  "include": ["../../types", "***.tsx", "**/*.vue"]
}

最后

师傅领进门,学艺在个人。这扇门已经打开,就不要浅尝辄止114信息网MIP移动站,轻易的关闭它,探索一下更多更好玩,更实用的功能吧。若想玩转百度地图开放的其它高级功能的话,请移步 API GL继续深入学习。

参考文章

【本文来源于互联网转载,如侵犯您的权益或不适传播,请邮件通知我们删除】

发表评论
0评