百度地圖api採坑指南

語言: CN / TW / HK

一 網址

  • 百度地圖開放平臺 https://lbsyun.baidu.com/index.php?title=jspopularGL
  • 高德地圖開放平臺 https://lbs.amap.com/api/jsapi-v2/summary/
  • 百度經緯度與高德經緯度互轉https://blog.csdn.net/qq_38935512/article/details/105856515
  • H5頁面調起高德地圖APP/百度地圖APP https://blog.csdn.net/bamboozjy/article/details/121521030

二 專項

1. 我發現使用相同的經緯度放在百度地圖和高德地圖的官網網站上查詢地址不一樣,需要相互裝換。

  • 將百度地圖經緯度轉換為騰訊/高德地圖經緯度 ``` bMapTransQQMap(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        
    }
    

    }

- 將騰訊/高德地圖經緯度轉換為百度地圖經緯度 qqMapTransBMap(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 
    } 
}

```

2. 百度地圖獲取當前定位經緯度

  • new BMapGL.Geolocation()只能獲取到市政府的位置,具體原因不知道。。。 ```
    const geolocation = new BMapGL.Geolocation(); // 獲取當前位置
    // 開啟SDK輔助定位
    // geolocation.enableSDKLocation();
    geolocation.getCurrentPosition((r) => {
      // window.alert(JSON.stringify(r));
    
      if (geolocation.getStatus() === window.BMAP_STATUS_SUCCESS) {
        const point = new BMapGL.Point(r.point.lng, r.point.lat); // 建立座標
        const Mark = new BMapGL.Marker(point); // 初始化終點標記
        this.mapRef.current.addOverlay(Mark); // 在地圖上新增點標記
    
    });
    

```

3. 通過經緯度獲取地址地名

``` const gc = new BMapGL.Geocoder(); gc.getLocation(endPoint, (rs) => { const addComp = rs.addressComponents; console.log(addComp); // {"streetNumber":"xxx號","street":"xxx路","district":"xxx區","city":"xxx市","province":"xx省"} });

```

4. H5 喚起百度地圖高德地圖

  • 喚起高德地圖 ```

export const gaodeMapApp = () => { // mode: car 駕車, bus 公交, ride 騎車, walk 步行

if (isIOS) { // 這個是ios作業系統 window.location.href = iosamap://viewMap?sourceApplication=appname&poiname=${地址名}&lat=${緯度}&lon=${經度}&dev=0;

if (!mcBizApp.isPajkApp()) {
  const d = new Date();
  const t0 = d.getTime();
  // 由於開啟需要1~2秒,利用這個時間差來處理--開啟app後,返回h5頁面會出現頁面變成app下載頁面,影響使用者體驗
  const delay = setInterval(() => {
    const d1 = new Date();
    const t1 = d1.getTime();
    if (t1 - t0 < 3000 && t1 - t0 > 2000) {
      window.location.href = `https://uri.amap.com/navigation?from=${起點緯度},${起點經度},${起點名}&to=${終點緯度},${終點經度},${終點名}&mode=${公交方式}&callnative=1&coordinate=wgs84&src=mypage`;
    }
    if (t1 - t0 >= 3000) {
      clearInterval(delay);
    }
  }, 1000);
}

} else { // 這個是安卓作業系統 window.location.href = androidamap://viewMap?sourceApplication=appname&poiname=${終點名}&lat=${終點緯度}&lon=${終點經度}&dev=0&&coord_type=bd09ll; const d = new Date(); const t0 = d.getTime(); // 由於開啟需要1~2秒,利用這個時間差來處理--開啟app後,返回h5頁面會出現頁面變成app下載頁面,影響使用者體驗 const delay = setInterval(() => { const d2 = new Date(); const t1 = d2.getTime(); if (t1 - t0 < 3000 && t1 - t0 > 2000) { window.location.href = https://uri.amap.com/navigation?from=${起點緯度},${起點經度},${起點名}&to=${終點緯度},${終點經度},${終點名}&mode=${公交方式}&callnative=1&coordinate=wgs84&src=mypage; console.log('delay -> window.location.href', window.location.href); } if (t1 - t0 >= 3000) { clearInterval(delay); } }, 1000); } };

```

  • 喚起百度地圖 ``` export const baiduMapApp = () => { // mode: driving 駕車, transit 公交, 和riding 騎車, walking 步行

if (startLat && startLon) { let scheme = ''; const queryStr = ?origin=name:地點名(我的位置)|latlng:${起點緯度},${起點經度}&destination=${終點緯度},${終點經度}&region=上海&coord_type=bd09ll&mode=${交通方式};

if (isIOS()) {
  // ios 端
  scheme = `bdapp://map/direction${queryStr}`;
} else {
  // android 端
  scheme = `baidumap://map/direction${queryStr}`;
}
window.location.href = scheme;
  const startTime = Date.now();
  let count = 0;
  let endTime = 0;
  const t = setInterval(() => {
    count += 1;
    endTime = Date.now() - startTime;
    if (endTime > 800) {
      clearInterval(t);
    }
    if (count < 30) return;
    if (!(document.hidden || document.webkitHidden)) {
      window.location.href = `http://api.map.baidu.com/direction${queryStr}&output=html`;
    }
  }, 20);

  window.onblur = () => {
    clearInterval(t);
  };

} else { console.log('獲取不到定位,請檢查手機定位設定'); } }; ```

五. 搜尋關鍵詞獲取地址列表

``` function () { const searchComplete = (results) => { console.log(results) }; const local = new BMapGL.LocalSearch(this.mapRef.current, { renderOptions: { }, onSearchComplete: searchComplete,

});
local.search(searchInputStart);

} ```

六. 點選齒輪定位回到當前位置

```

const startPoint = new BMapGL.Point(起點緯度, 起點經度);
this.mapRef.current.centerAndZoom(startPoint, 15);
const point = new BMapGL.Point(起點緯度, 起點經度); // 建立點座標A
const startMark = new BMapGL.Marker(point); // 初始化起點標記
this.mapRef.current.addOverlay(startMark); // 在地圖上新增點起點標記

```

七. 清除地圖上的覆蓋物(切換路線用到)

``` this.mapRef.current.clearOverlays();

```

八. 獲取兩點距離

getLineDistance = () => { const pointA = new BMapGL.Point(終點緯度, 終點經度); // 建立點座標A const pointB = new BMapGL.Point(起點緯度, 起點經度); // 建立點座標B const startMarkA = new BMapGL.Marker(pointA); // 初始化起點標記 const startMarkB = new BMapGL.Marker(pointB); // 初始化終點標記 this.mapRef.current.addOverlay(startMarkA); // 在地圖上新增點起點標記 this.mapRef.current.addOverlay(startMarkB); // 在地圖上新增點終點標記 console.log(this.mapRef.current.getDistance(pointA, pointB)); }

九. 格式化時間地點

  • 格式化距離 ```

export const getDistance = (distance, isObj = false) => { if (distance < 1000) { if (isObj) { return [{ data: distance, unit: 'm', }]; } return ${distance}m; } if (distance > 1000) { if (isObj) { return [ { data: (Math.round(distance / 100) / 10).toFixed(1), unit: 'km', }, ]; } return ${(Math.round(distance / 100) / 10).toFixed(1)}km; } }; ``` - 格式化時間

export const getDuration = (duration, isObj = false) => { const days = parseInt((duration * 1000) / (1000 * 60 * 60 * 24), 10); const hours = parseInt(((duration * 1000) % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), 10); const minutes = parseInt(((duration * 1000) % (1000 * 60 * 60)) / (1000 * 60), 10); let str = ''; const arr = []; if (days) { str += `${days}天`; arr.push({ data: days, unit: '天', }); } if (hours) { str += `${hours}小時`; arr.push({ data: hours, unit: '小時', }); } if (minutes) { str += `${minutes}分鐘`; arr.push({ data: minutes, unit: '分鐘', }); } if (isObj) { return arr.length ? arr : [{ data: 1, unit: '分鐘', }]; } return str || '1分鐘'; };

十. 交通方式

  • 駕車 ```

drive = () => {

this.mapRef.current.clearOverlays(); // 清除覆蓋物
const endPoint = new BMapGL.Point(終點緯度, 終點經度);
const startPoint = new BMapGL.Point(起點緯度, 起點經度);

this.mapRef.current.centerAndZoom(startPoint, 12);
const searchComplete = (results) => {
  if (!results._distance) {
  console.log('我沒有路線推薦')
  }
  if (driveRoute.getStatus() !== window.BMAP_STATUS_SUCCESS) {
    return;
  }
  const plan = results.getPlan(0);
  console.log(plan)
  const duration = `${plan._duration}`;
  const distance = `${plan._distance}`;
};

const driveRoute = new BMapGL.DrivingRoute(this.mapRef.current, {
  renderOptions: { map: this.mapRef.current, autoViewport: true },
  onSearchComplete: searchComplete,
}); // 獲取路徑資訊
driveRoute.search(startPoint, endPoint); // 繪製路徑

}

```

  • 公交
  • 公交返回資料之後自定義設計圖,點選對應的交通路線,未找到方法重新繪製公交路線,才用切換策略取第一條路線。

```

bus = (tipId, isSearch = false) => {

this.mapRef.current.clearOverlays(); // 清除覆蓋物
const endPoint = new BMapGL.Point(終點緯度, 終點經度);
const startPoint = new BMapGL.Point(起點緯度, 起點經度);
this.mapRef.current.centerAndZoom(startPoint, 12);
const tempArr = [];

// '時間最少 換乘最少 步行最少'.split(' ');
// 'BMAP_TRANSIT_POLICY_RECOMMEND BMAP_TRANSIT_POLICY_LEAST_TRANSFER BMAP_TRANSIT_POLICY_LEAST_WALKING'.split(' ');
let tempData;

const busRoute = new BMapGL.TransitRoute(this.mapRef.current, {
  renderOptions: {
    map: this.mapRef.current,
    // panel: 'result',
    // selectFirstResult: false,
    autoViewport: true,
  },
  policy: BMAP_TRANSIT_POLICY_LEAST_WALKING,
  onSearchComplete: (result) => {
    if (!result._plans) {
       console.log('無推薦路線')
      return;
    }
    // 路線成功後才繼續獲取
    if (busRoute.getStatus() === BMAP_STATUS_SUCCESS) {
      console.log(result)
    }
  },
});
if (isSearch) {
  busRoute.setPolicy(window[tipId]);
  busRoute.search(startPoint, endPoint);
  return;
}
busRoute.setPolicy(BMAP_TRANSIT_POLICY_LEAST_WALKING); // 改變策略
busRoute.search(startPoint, endPoint);

}

```

  • 騎行

`` bike = () => { this.mapRef.current.clearOverlays(); // 清除覆蓋物 const endPoint = new BMapGL.Point(終點緯度, 終點經度); const startPoint = new BMapGL.Point(起點緯度, 起點經度); this.mapRef.current.centerAndZoom(startPoint, 12); const searchComplete = (results) => { if (!results._distance) { console.log(沒有路線) } if (bikeRoute.getStatus() !== window.BMAP_STATUS_SUCCESS) { return; } const plan = results.getPlan(0); const duration =${plan._duration}; const distance =${plan._distance}`; }; const bikeRoute = new BMapGL.RidingRoute(this.mapRef.current, { renderOptions: { map: this.mapRef.current, autoViewport: true }, onSearchComplete: searchComplete, }); // 獲取路徑資訊 bikeRoute.search(startPoint, endPoint); // 繪製路徑 }

```

  • 步行 ```

walk = () => { this.mapRef.current.clearOverlays(); // 清除覆蓋物 const endPoint = new BMapGL.Point(終點緯度, 終點經度); const startPoint = new BMapGL.Point(起點緯度, 起點經度); this.mapRef.current.centerAndZoom(startPoint, 12); const searchComplete = (results) => { if (!results._distance) { console.log(沒有路線) } if (walkRoute.getStatus() !== window.BMAP_STATUS_SUCCESS) { return; }

  const plan = results.getPlan(0);
  const duration = `${plan._duration}`;
  const distance = `${plan._distance}`;
  this.setState({
    duration, // 獲取時間
    distance, // 獲取距離
  });
};
const walkRoute = new BMapGL.WalkingRoute(this.mapRef.current, {
  renderOptions: { map: this.mapRef.current, autoViewport: true },
  onSearchComplete: searchComplete,
}); // 獲取路徑資訊
walkRoute.search(startPoint, endPoint); // 繪製路徑

} ```