let AMap
export const MapKey = 'xxxxxxxxxxxxxxx'
/**
* 异步加载js, 在每次初始化地图的时候,都需要异步调用一下
*/
export const checkMapLoad = () =>
new Promise((resolve, reject) => {
if (window.AMap) {
resolve()
} else {
scp.onload = () => {
resolve(window.AMap)
}
// 添加 JS API
const scp = document.createElement('script')
scp.onerror = () => reject()
scp.setAttribute('src', `https://webapi.amap.com/maps?v=1.4.15&key=${MapKey}`)
document.getElementsByTagName('head')[0].appendChild(scp)
// 移动端开发时, 在head内添加viewport设置, 以达到最佳的绘制性能
const meta = document.createElement('meta')
meta.name='viewport'
meta.content='initial-scale=1.0, user-scalable=no'
document.getElementsByTagName('head')[0].appendChild(meta)
}
}).then(fn => {
if (fn) AMap = fn
})
/**
* 加载地图, 并返回地图的实例
*/
export const loadMap = ({ containerId, zoom, center, features, resizeEnable }) => {
const map = new AMap.Map(containerId, {
zoom,
center: center instanceof Array ? center.map(n => n || 0) : undefined,
features,
resizeEnable
})
return map
}
/**
* 点标记
*/
export const setMapMark = ({ containerId, zoom, center, features, content }) => {
const map = loadMap({
containerId,
zoom,
center,
features
})
const marker = new AMap.Marker({
position: map.getCenter(),
content
})
map.add(marker)
return { map, marker }
}
export const initMapLocation = ({ map }) =>
new Promise(resolve => {
const mapObj = map
// 此插件用来显示当前位置,可在引入API时一同引入
mapObj.plugin('AMap.Geolocation', () => {
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true,
timeout: 10000,
buttonOffset: new AMap.Pixel(10, 20),
zoomToAccuracy: true,
buttonPosition: 'RB'
})
mapObj.center = geolocation
mapObj.addControl(geolocation) // 地图控件右下角显示当前位置
resolve({ geolocation })
})
})
export const initMapCoder = ({ map }) =>
new Promise(resolve => {
map.plugin('AMap.Geocoder', () => {
resolve({ geocoder: new AMap.Geocoder() })
})
})
const xPi = (Math.PI * 3000.0) / 180.0
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
* @param {Array} lnglat
*/
export function gcj02ToBd09(lnglat) {
const x = lnglat[0]
const y = lnglat[1]
const z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * xPi)
const theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * xPi)
const tempLng = +(z * Math.cos(theta) + 0.0065).toFixed(6)
const tempLat = +(z * Math.sin(theta) + 0.006).toFixed(6)
return [tempLng, tempLat]
}
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标
* @param {Array} lnglat
*/
export function bd09ToGcj02(lnglat) {
const x = lnglat[0] - 0.0065
const y = lnglat[1] - 0.006
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xPi)
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xPi)
const tempLng = z * Math.cos(theta)
const tempLat = z * Math.sin(theta)
return [tempLng, tempLat]
}
/**
* 默认的地址
*/
export const defaultPosition = {
longitude: 114.017576,
latitude: 22.528234,
city: '深圳市',
cityCode: '福田区竹子林',
area: '0755',
areaCode: '440304'
}
/**
* 按经纬度反查位置信息
* @param {Array} lnglat
*/
export function getLocationByLnglat(lnglat) {
return new Promise(resolve => {
if (lnglat) {
AMap.plugin('AMap.Geocoder', () => {
const geo = new AMap.Geocoder()
geo.getAddress(lnglat, (status, res) => {
if (status === 'complete' && res.regeocode) {
const { addressComponent } = res.regeocode
resolve({
longitude: lnglat[0],
latitude: lnglat[1],
city: addressComponent.city,
cityCode: addressComponent.citycode,
area: addressComponent.district,
areaCode: addressComponent.adcode
})
} else {
resolve({ ...defaultPosition })
}
})
})
} else {
AMap.plugin('AMap.Geolocation', () => {
const geo = new AMap.Geolocation({
needAddress: true,
extensions: 'all'
})
geo.getCurrentPosition((status, res) => {
if (status === 'complete') {
const { addressComponent, position } = res
const data = {
longitude: position.lng,
latitude: position.lat,
city: addressComponent.city,
cityCode: addressComponent.citycode,
area: addressComponent.district,
areaCode: addressComponent.adcode
}
resolve(data)
} else {
resolve({ ...defaultPosition })
}
})
})
}
})
}
export function searchNearby({ keyword, options, lnglat, radius = 4000, onSelect, search }) {
return new Promise(resolve => {
AMap.service(['AMap.PlaceSearch'], () => {
let placeSearch
if (search) {
// search.clear()
placeSearch = search
} else {
// 构造地点查询类
placeSearch = new AMap.PlaceSearch({
pageSize: 10, // 单页显示结果条数
pageIndex: 1, // 页码
citylimit: true, // 是否强制限制在设置的城市内搜索
// map, // 展现结果的地图实例
// panel: "panel", // 结果列表将在此容器中进行展示。
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
// renderStyle: 'default',
showCover: false,
...options
})
}
placeSearch.searchNearBy(keyword, lnglat, radius, (status, result) => {
if (status === 'complete') {
resolve({ ...result.poiList, search: placeSearch })
} else if (status === 'no_data') {
resolve({ search: placeSearch })
}
})
if (onSelect) AMap.event.addListener(placeSearch, 'selectChanged', e => onSelect(e.selected))
})
})
}
参考
高德地图官网示例