utils/WebApi.js

import axios from 'axios'
import { transformGCJ2WGS, transformWGS2GCJ } from './Transform'
const gdKey = '2401b18dd27d6515643a3ea52c65ff3e'
const httpsGD = 'https://restapi.amap.com/'

/**
 * 地图WebAPI-路径分析
 * @module WebApi/Path
 */

/**
 * 高德路径导航
 * @param {DegreePos} pos1 起始点位置,WGS84坐标
 * @param {DegreePos} pos2 终点位置,WGS84坐标
 * @param {String} key 高德Key,需要自己申请
 * @returns {PathAnalysisGD} 路径规划结果
 */
async function drivingByGd(pos1, pos2, key) {
  const _key = key || gdKey
  pos1 = { lng: pos1.x, lat: pos1.y }
  pos2 = { lng: pos2.x, lat: pos2.y }
  const _pos1 = transformWGS2GCJ(pos1)
  const _pos2 = transformWGS2GCJ(pos2)

  const url = `${httpsGD}v5/direction/driving?key=${_key}&show_fields=cost,tmcs&origin=${_pos1.lng.toFixed(
    6
  )},${_pos1.lat.toFixed(6)}&destination=${_pos2.lng.toFixed(
    6
  )},${_pos2.lat.toFixed(6)}`
  try {
    const res = await axios.get(url)
    if (res.status === 200 && res.data.status === '1') {
      const paths = res.data.route.paths
      const _paths = []
      if (paths && paths.length > 0) {
        for (let i = 0; i < paths.length; i++) {
          const { distance, cost, steps } = paths[i]
          const curPath = {
            distance: Number(distance),
            duration: Number(cost.duration),
            steps: [],
          }
          for (let n = 0; n < steps.length; n++) {
            const step = steps[n]
            step.tmcs.forEach((tmc) => {
              let polyline = tmc.tmc_polyline.split(';')
              polyline = polyline.map((line) => {
                return coordGcj2Wgs84(line)
              })
              tmc.tmc_polyline = polyline
              tmc.tmc_distance = Number(tmc.tmc_distance)
            })
            const curStep = {
              duration: Number(step.cost.duration),
              distance: Number(step.step_distance),
              instruction: step.instruction,
              orientation: step.orientation,
              road_name: step.road_name,
              tmcs: step.tmcs,
            }
            curPath.steps.push(curStep)
          }
          _paths.push(curPath)
        }
      }

      const result = {
        origin: pos1,
        destination: pos2,
        paths: _paths,
      }
      return result
    }
    return res
  } catch (error) {
    return undefined
  }
}

export const Path = { drivingByGd }

/**
 * 地图WebAPI-POI查询
 * @module WebApi/Poi
 */

/**
 * 高德POI搜索
 * @param {String} word 搜索关键字
 * @param {String} key 高德Key,需要自己申请
 * @param {PoiGdParams} options 自定义搜索条件,包括限制搜索区域和返回结果数量
 * @returns {Array<PoiResultGd>} POI搜索结果
 */
async function poiByGd(word, key, options = {}) {
  const _key = key || gdKey
  const { region, count } = options
  const city = region ? true : false
  const _count = count || 20
  const url = `${httpsGD}v5/place/text?keywords=${word}&region=${region}&city_limit=${city}&page_size=${_count}&key=${_key}`
  try {
    const res = await axios.get(url)
    const pois = res.data.pois
    const result = []
    for (let index = 0; index < pois.length; index++) {
      const poi = pois[index]
      let { address, adname, pname, cityname, location, name, type } = poi
      location = coordGcj2Wgs84(location)
      const curPoi = {
        address,
        adname,
        cityname,
        location,
        name,
        type,
        pname,
      }
      result.push(curPoi)
    }
    return result
  } catch (error) {
    return undefined
  }
}

export const Poi = { poiByGd }

/**
 * 地图WebAPI-地理/逆地理编码
 * @module WebApi/Geocode
 */

/**
 * 高德地理编码,地址 => 坐标
 * @param {string} address 结构化地址信息,规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。
 * @param {string} key 高德Key,需要自己申请
 * @returns {Array<GeocodeGd>} 高德地理编码查询结果
 */
async function geoByGd(address, key) {
  const _key = key || gdKey
  const url = `${httpsGD}v3/geocode/geo?address=${address}&key=${_key}`
  try {
    const res = await axios.get(url)
    const pois = res.data.geocodes
    const result = []
    for (let index = 0; index < pois.length; index++) {
      let { province, city, district, street, location, number } = pois[index]
      location = coordGcj2Wgs84(location)
      const curResult = { province, city, district, street, location, number }
      result.push(curResult)
    }
    return result
  } catch (error) {
    return undefined
  }
}

/**
 * 高德逆地理编码,坐标 => 地址
 * @param {DegreePos} pos 经纬度坐标,WGS84坐标
 * @param {string} key 高德Key,需要自己申请
 * @returns {ReGeocodeGd} 高德逆地理编码查询结果
 */
async function regeoByGd(pos, key) {
  const _key = key || gdKey
  pos = { lng: pos.x, lat: pos.y }
  const _pos = transformWGS2GCJ(pos)
  const url = `${httpsGD}v3/geocode/regeo?location=${_pos.lng},${_pos.lat}&extensions=all&roadlevel=1&key=${_key}`
  try {
    const res = await axios.get(url)
    const regeo = res.data.regeocode
    const { province, city, district, township } = regeo.addressComponent
    const address = regeo.formatted_address
    const result = { province, city, district, township, address }
    return result
  } catch (error) {
    return undefined
  }
}

function coordGcj2Wgs84(val) {
  const point = val.split(',')
  return transformGCJ2WGS({
    lng: point[0],
    lat: point[1],
  })
}

export const Geocode = { geoByGd, regeoByGd }