choose-location.md 10.6 KB
Newer Older
雪洛's avatar
雪洛 已提交
1 2 3 4
## uni.chooseLocation(options) @chooselocation

<!-- UTSAPIJSON.chooseLocation.description -->

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
5 6 7 8 9 10 11 12
调用本API会打开一个新窗体,在地图中选择一个位置,在success回调中返回选择的位置名称和坐标。

本功能依赖地图组件。App和Web需在manifest.json中正确配置地图模块以及相关的key信息。

不同平台支持的地图不同,具体见[map组件](../component/map.md)

国内图商的坐标系都是gcj02坐标,国外图商是wgs84坐标。

W
wanganxp 已提交
13
地图是商业服务,授权较贵,如需购买,请点击[获取优惠](https://ask.dcloud.net.cn/explore/map/)
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
14

W
wanganxp 已提交
15

D
DCloud_LXH 已提交
16 17
<!-- UTSAPIJSON.chooseLocation.compatibility -->

雪洛's avatar
雪洛 已提交
18 19 20 21
<!-- UTSAPIJSON.chooseLocation.param -->

<!-- UTSAPIJSON.chooseLocation.returnValue -->

D
DCloud_LXH 已提交
22
<!-- UTSAPIJSON.chooseLocation.example -->
VK1688's avatar
VK1688 已提交
23 24 25 26 27

## 三方地图SDK  

uni.chooseLocation 依赖三方地图SDK,点击[查看详情](../component/map.md#mapsdk)

W
wanganxp 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41
## App平台依赖uniCloud@unicloud
> HBuilderX 4.33+

uni.chooseLocation 中有个功能是传入位置返回周围的POI信息。在腾讯地图中该功能不是客户端API,而是一个webservice接口。因为涉及收费,该接口需要传入key。

在App中,从客户端带着key直接发起请求腾讯地图的webservice接口是不安全的。key泄露后会导致其他人调用腾讯相关能力但费用由key的所属人缴纳。

web端可以使用在腾讯地图web控制台配置域名白名单的方式,但App无法采用这种方式。

App上安全的方式是由客户端不带key请求开发者的服务器,由开发者的服务器判断客户端的身份,然后服务器带着key请求腾讯地图的服务器,成功后返回POI列表给客户端。

DCloud的所有服务器API,都是基于uniCloud的。并且uniCloud早已经有 [uni-map-common](https://doc.dcloud.net.cn/uniCloud/uni-map-common.html)

所以在腾讯地图的 uni.chooseLocation 中,需要依赖 uniCloud 的 uni-map-common 插件。开发者在该插件的配置文件中配置好key,无需自己编写代码,即可使用本API。
VK1688's avatar
VK1688 已提交
42

W
wanganxp 已提交
43
开发者首先需要开通 [uniCloud](https://unicloud.dcloud.net.cn),选择一个服务商(可自由选择,不是必须使用腾讯云),创建一个服务空间。
VK1688's avatar
VK1688 已提交
44

W
wanganxp 已提交
45
在HBuilderX对项目点右键,关联服务空间。如果你的项目没有创建过 uniCloud 环境,则先右键项目名,创建uniCloud云开发环境,uniCloud 的 web控制台地址:[https://unicloud.dcloud.net.cn](https://unicloud.dcloud.net.cn)
VK1688's avatar
VK1688 已提交
46 47 48

![](https://web-ext-storage.dcloud.net.cn/uni-app-x/API/chooseLocation/aa35d5a6-9b13-4fea-8a0c-1b3534584659.png)

VK1688's avatar
VK1688 已提交
49
关联服务空间后,将 uni-map-common 插件导入项目,插件地址:[https://ext.dcloud.net.cn/plugin?id=13872](https://ext.dcloud.net.cn/plugin?id=13872) 
W
wanganxp 已提交
50

VK1688's avatar
VK1688 已提交
51 52 53 54 55 56 57 58 59 60 61
安装完 uni-map-common 插件后,需要将你的地图key配置在 `/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-map/config.js` 如果你的项目没有此配置文件,则直接根据目录创建对应的目录和 `config.js` 文件,文件内容如下:

```js
module.exports = {
	"default": "qqmap", // 当前使用哪个平台
	"key": {
		"qqmap": "", // 腾讯地图key
		"amap": "", // 高德地图key
	}
}
```
VK1688's avatar
VK1688 已提交
62

W
wanganxp 已提交
63 64
请务必注意地图的key,是有权限的可以访问周围POI信息的,且有足够的额度。这涉及付费采购。点此联系DCloud咨询[获取优惠](https://ask.dcloud.net.cn/explore/map/)

VK1688's avatar
VK1688 已提交
65 66 67
配置完毕后,本地运行即可使用。正式发布时,记得对uniCloud目录点右键,将相关云函数和模块提交发布到正式服务器上。具体操作如下图所示

![](https://web-ext-storage.dcloud.net.cn/uni-app-x/API/chooseLocation/6ce6b6f3-2334-40d5-bd06-69efb5174305.png)
W
wanganxp 已提交
68

DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
69
如果需要在uniCloud服务器更安全的验证客户端的身份,你可以在云函数中校验客户的token,避免其他人伪造请求访问你的云函数。
W
wanganxp 已提交
70

VK1688's avatar
VK1688 已提交
71 72
### uni-map-common错误码

VK1688's avatar
VK1688 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
uni.chooseLocation 获取POI列表的功能依赖uniCloud中的 [uni-map-common](https://doc.dcloud.net.cn/uniCloud/uni-map-common.html) 插件,该插件在请求地图服务器失败时会抛出错误信息,点击查看[uni-map-common错误码](https://doc.dcloud.net.cn/uniCloud/uni-map-common.html#errorcode)


### 透传鉴权参数payload@payload
> HBuilderX 4.35+

uni.chooseLocation 自HBuilderX 4.35+ 起,新增了一个参数payload,为 UTSJSONObject 类型,此参数会透传给uni-map-co,开发者可在请求地图服务器之前对参数进行鉴权,比如只有登录用户才能调用POI查询接口等等。

**示例代码**

```js
uni.chooseLocation({
  payload: {
    token: "xxx",
  },
  success: (res) => {
    console.log('res: ', res);
  }
});
```

#### 鉴权payload参数
> HBuilderX 4.35+

开发者可以在 uni-map-co 的 `_before` 方法内进行鉴权,鉴权代码可以写在 `_before` 函数已有代码的下面。

#### 情况一: 自身业务在uniCloud,且使用了uni-id-common@payload1

1. 右键 uni-map-co 云对象,管理公共模块或扩展库依赖,打勾 uni-id-common 依赖
2.`_before` 函数已有代码的下面新增以下代码
```js
const uniIdCommon = require('uni-id-common')
const uniID = uniIdCommon.createInstance({
	clientInfo: this.getClientInfo()
});
// 获取uniIdToken
const uniIdToken = this.getUniIdToken()
// 校验uniIdToken
const checkTokenRes = await uniIDIns.checkToken(uniIdToken)
if (checkTokenRes.code) {
	// token校验不通过
	throw {
		errCode: checkTokenRes.errCode || checkTokenRes.code,
		errMsg: checkTokenRes.errMsg || checkTokenRes.msg
	}
}
// 获取payload参数
let {
	payload, // payload参数为前端传递的参数,可以在前端调用uni.chooseLocation时传递
} = this.getParams()[0] || {};
// 可继续校验payload参数
// ...

```

以上就已经完成了用户是否登录的判断,不登录不能调用,当然你还能继续优化代码以适应不同的业务需求。

#### 情况二: 自身业务在uniCloud,未使用uni-id-common@payload2

推荐使用uni-id-common,[下载地址](https://ext.dcloud.net.cn/plugin?id=8576)

当然你也可以直接在 `_before` 函数已有代码的下面新增自己的鉴权代码

```js
// 获取payload参数
let {
	payload, // payload参数为前端传递的参数,可以在前端调用uni.chooseLocation时传递
} = this.getParams()[0] || {};
if (!payload) {
	throw {
		errCode: -1,
		errMsg: "payload参数不能为空"
	}
}
// 继续校验payload参数
// ...
```

#### 情况三: 自身业务不在uniCloud@payload3

如果业务不在uniCloud,你可以在uni-map-co中通过http请求你的后端服务器。

1. 打开文件 `/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/index.obj.js`
2.`_before` 函数已有代码的下面新增以下代码

```js
// 获取payload参数
let {
	payload, // payload参数为前端传递的参数,可以在前端调用uni.chooseLocation时传递
} = this.getParams()[0] || {};
if (!payload) {
	throw {
		errCode: -1,
		errMsg: "payload参数不能为空"
	}
}
// 请求后端服务接口
const requestRes = await uniCloud.request({
	method: 'POST',
	url: '你自己的接口地址',
	data: payload,
});
// 与后端约定errCode不为0代表校验失败,errMsg为失败原因
if (requestRes.data.errCode !== 0) {
	throw {
		errCode: requestRes.data.errCode,
		errMsg: requestRes.data.errMsg
	}
}
```

VK1688's avatar
VK1688 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196

### 未依赖uniCloud时向下兼容说明

当项目未使用uniCloud时,uni.chooseLocation 功能将调整为全屏地图选点模式。在该模式下,POI列表信息将不再显示,用户无法通过POI进行选点,只能直接在地图上进行位置选择。同时返回值只有latitude和longitude是有值的,name和address为空字符串,如下所示:

```json
{
	"name": "",
	"address": "",
	"latitude": 39.951028,
	"longitude": 116.354662
}
```
VK1688's avatar
VK1688 已提交
197

W
wanganxp 已提交
198 199
## 自定义样式@custom
> HBuilderX 4.33+
VK1688's avatar
VK1688 已提交
200

W
wanganxp 已提交
201
uni.chooseLocation 虽然是一个框架内置的页面。但提供了丰富的自定义能力。
VK1688's avatar
VK1688 已提交
202

W
wanganxp 已提交
203
该页面自动适配了暗黑、横屏、国际化(内置中文繁简和英文)。页面上的图片元素均使用字体图标,可以覆盖class。
VK1688's avatar
VK1688 已提交
204

W
wanganxp 已提交
205
可通过App.vue中写入全局css样式进行覆盖修改。
VK1688's avatar
VK1688 已提交
206

W
wanganxp 已提交
207 208 209 210
- 以 .uni-choose-location-light 开头的为light模式下的样式
- 以 .uni-choose-location-dark 开头的为dark模式下的样式

样式必须以 `!important;` 结尾才能生效,以下是css的class名称,写入同名名称就可以覆盖。
VK1688's avatar
VK1688 已提交
211

VK1688's avatar
VK1688 已提交
212 213
文本样式除了下方列出的 color 和 background-color 外,你还可以替换 font-family 等任何 text 标签支持的样式。

VK1688's avatar
VK1688 已提交
214 215 216 217 218 219 220 221 222 223 224
地图中心点的icon

```css
.uni-choose-location-light .uni-choose-location-map-target-icon {
	color: red !important;
}
.uni-choose-location-dark .uni-choose-location-map-target-icon {
	color: red !important;
}
```

VK1688's avatar
VK1688 已提交
225
右上方"确认"按钮
VK1688's avatar
VK1688 已提交
226 227 228 229

```css
.uni-choose-location-light .uni-choose-location-nav-confirm-text {
	background-color: red !important;
VK1688's avatar
VK1688 已提交
230
	color: #fff !important;
VK1688's avatar
VK1688 已提交
231 232 233
}
.uni-choose-location-dark .uni-choose-location-nav-confirm-text {
	background-color: red !important;
VK1688's avatar
VK1688 已提交
234
	color: #fff !important;
VK1688's avatar
VK1688 已提交
235 236 237
}
```

VK1688's avatar
VK1688 已提交
238 239 240 241 242 243 244 245 246 247 248 249
左上方"取消"按钮

```css
.uni-choose-location-light .uni-choose-location-nav-back-text {
	color: red !important;
}
.uni-choose-location-dark .uni-choose-location-nav-back-text {
	color: red !important;
}
```

搜索框右侧的"取消"文字
VK1688's avatar
VK1688 已提交
250 251 252 253 254 255 256 257 258 259

```css
.uni-choose-location-light .uni-choose-location-poi-search-cancel {
	color: red !important;
}
.uni-choose-location-dark .uni-choose-location-poi-search-cancel {
	color: red !important;
}
```

VK1688's avatar
VK1688 已提交
260
已选中的POI右侧的对钩icon
VK1688's avatar
VK1688 已提交
261 262 263 264 265 266 267 268

```css
.uni-choose-location-light .uni-choose-location-poi-item-selected-icon {
	color: red !important;
} 
.uni-choose-location-dark .uni-choose-location-poi-item-selected-icon {
	color: red !important;
} 
W
wanganxp 已提交
269 270
```

VK1688's avatar
VK1688 已提交
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
POI标题

```css
.uni-choose-location-light .uni-choose-location-poi-item-title-text {
  color: red !important;
}
.uni-choose-location-dark .uni-choose-location-poi-item-title-text {
  color: red !important;
}
```

POI地址

```css
.uni-choose-location-light .uni-choose-location-poi-item-detail-text {
  color: red !important;
}
.uni-choose-location-dark .uni-choose-location-poi-item-detail-text {
  color: red !important;
}
```

W
wanganxp 已提交
293 294 295 296 297 298 299 300
## 历史问题
uni-app x 4.24以前,Web平台本API调用了腾讯地图的免费gcj02坐标转换接口,该接口从2024年7月18日起被腾讯逐步下线,导致老版本中本API无法使用。请升级到4.24+。

升级后注意:
1. manifest中配置好自己的地图厂商key
2. 确保在地图厂商那里配额足够
3. 确保在地图厂商那里有周边服务的权限。否则无法获取周围地址
4. 确保自己的域名在地图厂商那里正确配置了域名白名单
DCloud_Heavensoft's avatar
DCloud_Heavensoft 已提交
301 302

<!-- UTSAPIJSON.chooseLocation.tutorial -->