Skip to content

Commit

Permalink
feat: 新增坐标转换 hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
yue1123 committed Nov 22, 2022
1 parent 7f5d537 commit 2e5955d
Show file tree
Hide file tree
Showing 4 changed files with 318 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/sidebar.config.zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ const sidebarConfig = {
text: 'useAddressGeocoder 地址解析',
link: '/zh/hooks/useAddressGeocoder'
},
{
text: 'usePointConvertor 坐标转换',
link: '/zh/hooks/usePointConvertor'
},
{
text: 'useAreaBoundary 区域边界',
link: '/zh/hooks/useAreaBoundary'
Expand Down
205 changes: 205 additions & 0 deletions docs/zh/hooks/usePointConvertor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# usePointConvertor 坐标点转换

用于将其他坐标系的坐标转换为百度坐标。

```ts
import { usePointConvertor } from 'vue3-baidu-map-gl'
```

## 示例

<Map @initd="handleInitd" :center="googlePoint">
<template v-if="!isLoading && !isError">
<template v-for="(point, index) in result">
<Marker :position="point"></Marker>
<Label :position="point" style="color:#333;font-size:9px" content="转换后的百度标注(正确)"></Label>
</template>
</template>
<Marker :position="googlePoint"></Marker>
<Label :position="googlePoint" style="color:#333;font-size:9px" content="未转换的谷歌标注(错误)"></Label>
</Map>

<script lang="ts" setup>
import { CoordinatesFromType, CoordinatesToType, usePointConvertor } from 'vue3-baidu-map-gl'
const { convert, result, isLoading, isError } = usePointConvertor()
const googlePoint = { lng: 116.32715863448607, lat: 39.990912172420714 }
function handleInitd() {
convert([googlePoint], CoordinatesFromType['COORDINATES_GCJ02'], CoordinatesToType['COORDINATES_BD09'])
}
</script>

::: details 点击查看代码

<!-- prettier-ignore -->
```html
<Map @initd="handleInitd" :center="googlePoint">
<template v-if="!isLoading && !isError">
<template v-for="(point, index) in result">
<Marker :position="point"></Marker>
<label :position="point" style="color:#333;font-size:9px" content="转换后的百度标注(正确)"></label>
</template>
</template>
<Marker :position="googlePoint"></Marker>
<label :position="googlePoint" style="color:#333;font-size:9px" content="未转换的谷歌标注(错误)"></label>
</Map>

<script lang="ts" setup>
import { CoordinatesFromType, CoordinatesToType, usePointConvertor } from 'vue3-baidu-map-gl'
const { convert, result, isLoading, isError } = usePointConvertor()
const googlePoint = { lng: 116.32715863448607, lat: 39.990912172420714 }
function handleInitd() {
convert([googlePoint], CoordinatesFromType['COORDINATES_GCJ02'], CoordinatesToType['COORDINATES_BD09'])
}
</script>
```

:::

## 用法

```ts
const { result, convert, isLoading, isError, status } = usePointConvertor()
```

:::tip
该 hooks 依赖于 `BMapGL` ,所以需要在 `Map` 组件初始化完毕调用 `convert` 方法后数据才可用
:::

### 参数


### 引用

| 引用 | 描述 | 类型 |
| --------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| result | 目标坐标点数组 | `{ lng: number; lat: number }[]` |
| isLoading | 是否加载中 | `boolean` |
| isError | 是否出错 | `boolean` |
| status | 当前状态 | [`UsePointConvertorStatus`](#usepointconvertorstatus) |
| convert | 点坐标转换方法,需要在`Map`组件`initd`事件触发后才可调用 | `({ lng: number; lat: number }[], `[`CoordinatesFromType, `](#coordinatesfromtype) [`CoordinatesToType`](#coordinatestotype)`) => void` |

### CoordinatesFromType

原坐标类型

```ts
export enum CoordinatesFromType {
/**
* WGS84坐标(GPS标准坐标)
*/
'COORDINATES_WGS84' = 1,
/**
* WGS84的平面墨卡托坐标(搜狗地图坐标)
*/
'COORDINATES_WGS84_MC' = 2,
/**
* GCJ02坐标(火星坐标),即高德地图、腾讯地图、谷歌坐标和MapABC等地图使用的坐标;
*/
'COORDINATES_GCJ02' = 3,
/**
* GCJ02的平面墨卡托坐标(火星坐标对应的墨卡托平面坐标)
*/
'COORDINATES_GCJ02_MC' = 4,
/**
* 百度地图采用的经纬度坐标(bd09ll)
*/
'COORDINATES_BD09' = 5,
/**
* 百度地图采用的墨卡托平面坐标(bd09mc)
*/
'COORDINATES_BD09_MC' = 6,
/**
* 图吧地图坐标
*/
'COORDINATES_MAPBAR' = 7,
/**
* 51地图坐标
*/
'COORDINATES_51' = 8
}
```

### CoordinatesToType

目标坐标类型

```ts
export enum CoordinatesToType {
/**
* GCJ02坐标(火星坐标),即高德地图、腾讯地图、谷歌坐标和MapABC等地图使用的坐标;
*/
'COORDINATES_GCJ02' = 3,
/**
* 百度地图采用的经纬度坐标(bd09ll)
*/
'COORDINATES_BD09' = 5,
/**
* 百度地图采用的墨卡托平面坐标(bd09mc)
*/
'COORDINATES_BD09_MC' = 6
}
```

### UsePointConvertorStatus

:::warning 警告
当转换不被允许的坐标系,如:X→GPS,可能不会响应返回以下错误 code,会拒绝响应,浏览器直接报跨域请求
:::

| code | 描述 |
| ---- | -------------------------------------------------------------------------- |
| 0 | ok 正常 服务请求正常召回 |
| 1 | 内部错误 |
| 4 | 转换失败 X→GPS 时必现,根据法律规定,不支持将任何类型的坐标转换为 GPS 坐标 |
| 21 | from 非法 |
| 22 | to 非法 |
| 24 | coords 格式非法 |
| 25 | coords 个数非法,超过限制 |
| 26 | 参数错误 |

## 代码示例

<!-- prettier-ignore -->
```html
<Map @initd="handleInitd"></Map>

<script setup lang="ts">
import { useAreaBoundary } from 'vue3-baidu-map-gl'
const { point, set } = usePoint()
function handleInitd() {
set({
lng: 116.297611,
lat: 40.047363
})
}
</script>
```

## TS 类型定义参考

```ts
import { Ref } from 'vue'
/**
* 地图经纬度点
*/
export declare type Point = {
lng: number
lat: number
}
/**
* 获取一个地图经纬度点实例
*/
export declare function usePoint(): {
/**
* BMapGL.Point 实例对象
*/
point: Ref<BMapGL.Point | null>
/**
* 设置实例点坐标
*/
set: ({ lng, lat }: { lng: number; lat: number }) => void
}
```
108 changes: 108 additions & 0 deletions packages/hooks/usePointConvertor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { ref } from 'vue'
import { error } from '../utils'
import { Point } from './usePoint'

export enum CoordinatesFromType {
/**
* WGS84坐标(GPS标准坐标)
*/
'COORDINATES_WGS84' = 1,
/**
* WGS84的平面墨卡托坐标(搜狗地图坐标)
*/
'COORDINATES_WGS84_MC' = 2,
/**
* GCJ02坐标(火星坐标),即高德地图、腾讯地图、谷歌坐标和MapABC等地图使用的坐标;
*/
'COORDINATES_GCJ02' = 3,
/**
* GCJ02的平面墨卡托坐标(火星坐标对应的墨卡托平面坐标)
*/
'COORDINATES_GCJ02_MC' = 4,
/**
* 百度地图采用的经纬度坐标(bd09ll)
*/
'COORDINATES_BD09' = 5,
/**
* 百度地图采用的墨卡托平面坐标(bd09mc)
*/
'COORDINATES_BD09_MC' = 6,
/**
* 图吧地图坐标
*/
'COORDINATES_MAPBAR' = 7,
/**
* 51地图坐标
*/
'COORDINATES_51' = 8
}

export enum CoordinatesToType {
/**
* GCJ02坐标(火星坐标),即高德地图、腾讯地图、谷歌坐标和MapABC等地图使用的坐标;
*/
'COORDINATES_GCJ02' = 3,
/**
* 百度地图采用的经纬度坐标(bd09ll)
*/
'COORDINATES_BD09' = 5,
/**
* 百度地图采用的墨卡托平面坐标(bd09mc)
*/
'COORDINATES_BD09_MC' = 6
}

export type UsePointConvertorStatus = 0 | 1 | 4 | 21 | 22 | 24 | 25 | 26

export function usePointConvertor() {
const result = ref<Point[]>()
const isLoading = ref<boolean>(true)
const isError = ref<boolean>(false)
const status = ref<UsePointConvertorStatus>()
let convertor: BMapGL.Convertor
const init = (points: Point[], from: CoordinatesFromType, to: CoordinatesToType) => {
if (!points) return error('missed required params: points')
if (!from) return error('missed required params: from')
if (!to) return error('missed required params: to')
if (!points.length) return
if (!convertor) {
convertor = new BMapGL.Convertor()
}
isLoading.value = true
const pointsInstance = points.map((item) => new BMapGL.Point(item.lng, item.lat))
getConvertor(convertor, pointsInstance, from, to)
.then((res) => {
result.value = res.points.map((item) => ({ lng: item.lng, lat: item.lat }))
status.value = res.status as UsePointConvertorStatus
isError.value = false
})
.catch((status) => {
status.value = status as UsePointConvertorStatus
isError.value = true
})
.finally(() => {
isLoading.value = false
})
}
return {
convert: init,
result,
isLoading,
isError,
status
}
}

function getConvertor(
convertor: BMapGL.Convertor,
point: BMapGL.Point[],
from: CoordinatesFromType,
to: CoordinatesToType
) {
return new Promise<{ points: BMapGL.Point[]; status: number }>((resolve, reject) => {
convertor.translate(point, from, to, (res) => {
if (res.status === 0) resolve(res)
else reject(res.status)
})
})
}
1 change: 1 addition & 0 deletions packages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './hooks/useIpLocation'
export * from './hooks/useBrowserLocation'
export * from './hooks/useAddressGeocoder'
export * from './hooks/usePointGeocoder'
export * from './hooks/usePointConvertor'

// components
import Map from './components/map/index.vue'
Expand Down

0 comments on commit 2e5955d

Please sign in to comment.