From f69744df237584f2a61cfcb05883c221a4c648dd Mon Sep 17 00:00:00 2001
From: zhenyuWang <13641039885@163.com>
Date: Thu, 14 Nov 2024 22:28:44 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20chooseLocation=20=E7=A4=BA=E4=BE=8B?=
=?UTF-8?q?=E6=94=AF=E6=8C=81=20app=20=E7=AB=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../API/choose-location/choose-location.uvue | 165 +--
uni_modules/uni-map-common/changelog.md | 14 +
uni_modules/uni-map-common/package.json | 83 ++
uni_modules/uni-map-common/readme.md | 11 +
.../common/uni-map-common/index.js | 100 ++
.../common/uni-map-common/libs/common.js | 74 ++
.../common/uni-map-common/libs/error.js | 13 +
.../common/uni-map-common/libs/index.js | 7 +
.../common/uni-map-common/package.json | 19 +
.../common/uni-map-common/service/amap.js | 979 ++++++++++++++++++
.../common/uni-map-common/service/index.js | 4 +
.../common/uni-map-common/service/qqmap.js | 856 +++++++++++++++
.../cloudfunctions/uni-map-co/index.obj.js | 518 +++++++++
.../cloudfunctions/uni-map-co/package.json | 9 +
.../uni-map-co/uni-map-co.param.js | 123 +++
15 files changed, 2897 insertions(+), 78 deletions(-)
create mode 100644 uni_modules/uni-map-common/changelog.md
create mode 100644 uni_modules/uni-map-common/package.json
create mode 100644 uni_modules/uni-map-common/readme.md
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/index.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/common.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/error.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/index.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/package.json
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/amap.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/index.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/qqmap.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/index.obj.js
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/package.json
create mode 100644 uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/uni-map-co.param.js
diff --git a/pages/API/choose-location/choose-location.uvue b/pages/API/choose-location/choose-location.uvue
index 364edb05..6d8e3020 100644
--- a/pages/API/choose-location/choose-location.uvue
+++ b/pages/API/choose-location/choose-location.uvue
@@ -1,79 +1,88 @@
-
-
-
-
-
- 当前位置信息
-
- 未选择位置
-
-
-
- {{locationAddress}}
-
-
- E: {{location.longitude[0]}}°{{location.longitude[1]}}′
- \nN: {{location.latitude[0]}}°{{location.latitude[1]}}′
-
-
-
-
- 注意:Web和App需要正确配置地图服务商的Key并且保证Key的权限和余额足够,才能正常选择位置
-
-
-
-
-
-
-
-
-
diff --git a/uni_modules/uni-map-common/changelog.md b/uni_modules/uni-map-common/changelog.md
new file mode 100644
index 00000000..21749635
--- /dev/null
+++ b/uni_modules/uni-map-common/changelog.md
@@ -0,0 +1,14 @@
+## 1.1.3(2024-11-11)
+优化 chooseLocation 函数供 uni-app x 的 uni.chooseLocation 使用
+## 1.1.2(2024-10-21)
+新增chooseLocation函数供uni.chooseLocation使用
+## 1.1.1(2024-07-23)
+[调整] 移除db_init.json文件,初始化数据库请用新版方式(右键database,初始化数据库)
+## 1.1.0(2024-03-25)
+[重要] 支持支付宝小程序云
+## 1.0.2(2023-08-01)
+优化配置读取方式
+## 1.0.1(2023-08-01)
+初版
+## 1.0.0(2023-08-01)
+初版,文档地址:https://uniapp.dcloud.net.cn/uniCloud/uni-map-common.html
diff --git a/uni_modules/uni-map-common/package.json b/uni_modules/uni-map-common/package.json
new file mode 100644
index 00000000..daf00bb1
--- /dev/null
+++ b/uni_modules/uni-map-common/package.json
@@ -0,0 +1,83 @@
+{
+ "id": "uni-map-common",
+ "displayName": "uni-map-common地图服务端API",
+ "version": "1.1.3",
+ "description": "聚合了多家地图供应商的服务端API,几行代码即可快速接入地图API",
+ "keywords": [
+ "uni-map-common",
+ "地图服务端API"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "type": "unicloud-template-function",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "插件不采集任何数据",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "u",
+ "vue3": "u"
+ },
+ "App": {
+ "app-vue": "u",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "u",
+ "Android Browser": "u",
+ "微信浏览器(Android)": "u",
+ "QQ浏览器(Android)": "u"
+ },
+ "H5-pc": {
+ "Chrome": "u",
+ "IE": "u",
+ "Edge": "u",
+ "Firefox": "u",
+ "Safari": "u"
+ },
+ "小程序": {
+ "微信": "u",
+ "阿里": "u",
+ "百度": "u",
+ "字节跳动": "u",
+ "QQ": "u",
+ "钉钉": "u",
+ "快手": "u",
+ "飞书": "u",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/readme.md b/uni_modules/uni-map-common/readme.md
new file mode 100644
index 00000000..21580ccb
--- /dev/null
+++ b/uni_modules/uni-map-common/readme.md
@@ -0,0 +1,11 @@
+# uni-map-common
+
+聚合了多家地图供应商的服务端API
+
+## 使用教程
+
+> 文档地址:[https://uniapp.dcloud.net.cn/uniCloud/uni-map-common.html](https://uniapp.dcloud.net.cn/uniCloud/uni-map-common.html)
+
+## bug反馈地址
+
+> 加群:[uni-map交流群](https://im.dcloud.net.cn/#/?joinGroup=64d62b106823de10406ad72f)
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/index.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/index.js
new file mode 100644
index 00000000..82253e4e
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/index.js
@@ -0,0 +1,100 @@
+const service = require('./service/index.js');
+
+class UniMap {
+
+ // 构造函数
+ constructor(data = {}) {
+ let {
+ provider, // 平台 weixin-mp 微信小程序 weixin-h5 微信公众号
+ key, // 密钥
+ needOriginalResult = false, // 是否需要返回原始信息,默认false
+ } = data;
+
+ let runService = service[provider];
+ if (!runService) {
+ throw new Error(`不支持平台:${provider}`);
+ }
+ this.service = new runService({
+ provider,
+ key,
+ needOriginalResult
+ });
+ //return this.service;
+ }
+
+ // API - 逆地址解析(坐标转地址)
+ async location2address(data = {}) {
+ let res = await this._call("location2address", data);
+ return res;
+ }
+
+ // API - 地址解析(地址转坐标)
+ async address2location(data = {}) {
+ let res = await this._call("address2location", data);
+ return res;
+ }
+
+ // API - 坐标转换
+ async translate(data = {}) {
+ let res = await this._call("translate", data);
+ return res;
+ }
+
+ // API - IP定位
+ async ip2location(data = {}) {
+ let res = await this._call("ip2location", data);
+ return res;
+ }
+
+ // API - 关键词输入提示
+ async inputtips(data = {}) {
+ let res = await this._call("inputtips", data);
+ return res;
+ }
+
+ // API - 周边搜索
+ async search(data = {}) {
+ let res = await this._call("search", data);
+ return res;
+ }
+
+ // API - 行政区划
+ async districtSearch(data = {}) {
+ let res = await this._call("districtSearch", data);
+ return res;
+ }
+
+ // API - 路线规划(驾车/步行/骑行/电动车/公交)
+ async route(data = {}) {
+ let urlObj = {
+ "driving": "drivingRoute",
+ "walking": "walkingRoute",
+ "bicycling": "bicyclingRoute",
+ "ebicycling": "ebicyclingRoute",
+ "transit": "transitRoute"
+ };
+ let res = await this._call(urlObj[data.mode], data);
+ res.result.mode = data.mode;
+ return res;
+ }
+
+ // 私有函数
+ async _call(name, data = {}) {
+ let runFunction = this.service[name];
+ if (!runFunction) {
+ throw new Error(`平台:${this.service.config.provider} 不支持API:${name}`);
+ }
+ let res = await runFunction.call(this.service, data); // 此处需要使用call,防止里面的this作用域被意外改变
+ if (!this.service.config.needOriginalResult) {
+ delete res.originalResult;
+ }
+ //res = JSON.parse(JSON.stringify(res));
+ return {
+ provider: this.service.config.provider,
+ ...res
+ };
+ }
+
+}
+
+module.exports = UniMap;
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/common.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/common.js
new file mode 100644
index 00000000..d15e145c
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/common.js
@@ -0,0 +1,74 @@
+/**
+ * 通用公共函数
+ */
+var common = {};
+
+// 经纬度表示形式转换
+common.getLocation = function(location = "", type = "", returnType = "") {
+ let lat;
+ let lng;
+ // 去除所有空格
+ type = type.trim();
+ returnType = returnType.replace(/\s+/g, '');
+ if (type === "lat,lng") {
+ location = location.replace(/\s+/g, '');
+ let arr = location.split(",");
+ lat = arr[0];
+ lng = arr[1];
+ } else if (type === "lng,lat") {
+ location = location.replace(/\s+/g, '');
+ let arr = location.split(",");
+ lat = arr[1];
+ lng = arr[0];
+ } else if (type === "lat lng") {
+ let arr = location.split(" ");
+ lat = arr[0];
+ lng = arr[1];
+ } else if (type === "lng lat") {
+ let arr = location.split(" ");
+ lat = arr[1];
+ lng = arr[0];
+ } else {
+ lat = location.lat;
+ lng = location.lng;
+ }
+ if (returnType == "lng,lat") {
+ return `${lng},${lat}`;
+ } else if (returnType == "lat,lng") {
+ return `${lat},${lng}`;
+ } else {
+ return {
+ lat: Number(lat),
+ lng: Number(lng)
+ }
+ }
+};
+
+// 字符串格式的坐标经纬度反转
+common.getReversalLocation = function(input="") {
+ // 按分隔符拆分字符串
+ let parts = input.split("|");
+
+ // 遍历每个部分进行值交换
+ for (let i = 0; i < parts.length; i++) {
+ let pairs = parts[i].split(";");
+ for (let j = 0; j < pairs.length; j++) {
+ let values = pairs[j].split(",");
+ // 交换两个值
+ let temp = values[0];
+ values[0] = values[1];
+ values[1] = temp;
+ // 更新交换后的值
+ pairs[j] = values.join(",");
+ }
+ // 更新交换后的部分
+ parts[i] = pairs.join(";");
+ }
+
+ // 返回交换后的结果
+ return parts.join("|");
+};
+
+
+
+module.exports = common;
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/error.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/error.js
new file mode 100644
index 00000000..4cdda804
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/error.js
@@ -0,0 +1,13 @@
+const errSubject = "uni-map-common";
+
+class UniCloudError {
+ constructor(options = {}) {
+ this.errCode = options.errCode || options.code;
+ this.errMsg = options.errMsg || options.msg || options.message || "";
+ this.errSubject = options.subject || errSubject;
+ }
+}
+
+module.exports = {
+ UniCloudError
+}
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/index.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/index.js
new file mode 100644
index 00000000..dbaf95f9
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/libs/index.js
@@ -0,0 +1,7 @@
+const common = require('./common');
+const error = require('./error');
+
+module.exports = {
+ common,
+ error
+};
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/package.json b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/package.json
new file mode 100644
index 00000000..dfbb59e8
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "uni-map-common",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "uni-config-center": "file:..\/..\/..\/..\/..\/uni-config-center\/uniCloud\/cloudfunctions\/common\/uni-config-center"
+ },
+ "origin-plugin-dev-name": "uni-map-common",
+ "origin-plugin-version": "1.1.3",
+ "plugin-dev-name": "uni-map-common",
+ "plugin-version": "1.1.3"
+}
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/amap.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/amap.js
new file mode 100644
index 00000000..18a66c54
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/amap.js
@@ -0,0 +1,979 @@
+const libs = require('../libs');
+
+// https://lbs.amap.com/api/webservice/guide/tools/info
+
+const ERRCODE = {
+ "10000": 0,
+ "10001": 190,
+ "10002": 113,
+ "10003": 121,
+ "10004": 120,
+ "10005": 112,
+ "10006": 110,
+ "10007": 111,
+ "10008": 111,
+ "10009": 110,
+ "10010": 122,
+ "10011": 311,
+ "10012": 113,
+ "10013": 190,
+ "10014": 500,
+ "10015": 500,
+ "10016": 500,
+ "10017": 500,
+ "10019": 500,
+ "10020": 500,
+ "10021": 500,
+ "10026": 110,
+ "10029": 500,
+ "10041": 110,
+ "10044": 121,
+ "10045": 121,
+ "20000": 395,
+ "20001": 300,
+ "20002": 500,
+ "20003": 500,
+ "20011": 395,
+ "20012": 395,
+ "20801": 395,
+ "20802": 395,
+ "20803": 373,
+ "40000": 123,
+ "40001": 123,
+ "40002": 123,
+ "40003": 123
+};
+
+class Service {
+
+ // 构造函数
+ constructor(data = {}) {
+ let {
+ key,
+ needOriginalResult = false, // 是否需要返回原始信息,默认false
+ } = data;
+
+ this.config = {
+ provider: "amap",
+ key,
+ needOriginalResult,
+ serviceUrl: "https://restapi.amap.com"
+ }
+ }
+
+ async request(obj = {}) {
+ let {
+ url,
+ data = {}
+ } = obj;
+ if (url.indexOf("http") !== 0) {
+ url = `${this.config.serviceUrl}/${url}`
+ }
+ if (this.config.key && !data.key) {
+ data.key = this.config.key;
+ }
+ obj.data = JSON.parse(JSON.stringify(obj.data));
+ let requestRes = await uniCloud.httpclient.request(url, obj);
+ let result = this.getResult(requestRes);
+ if (result.errCode != 0) {
+ throw new libs.error.UniCloudError(result);
+ }
+ return result;
+ }
+
+ getResult(requestRes) {
+ let {
+ data: originalResult = {}
+ } = requestRes;
+ let res = {
+ errCode: originalResult.infocode == "10000" ? 0 : this.getErrCode(originalResult.infocode),
+ errMsg: originalResult.info,
+ originalResult,
+ };
+ return res;
+ }
+
+ getErrCode(errCode) {
+ return ERRCODE[errCode] || errCode;
+ }
+
+ // API - 逆地址解析(坐标转地址)
+ async location2address(data = {}) {
+ let {
+ location,
+ get_poi,
+ poi_options,
+ } = data;
+
+ let requestData = {
+ location: libs.common.getLocation(location, "lat,lng", "lng,lat"),
+ extensions: get_poi ? "all" : "base",
+ };
+
+ if (get_poi && typeof poi_options == "object") {
+ let {
+ poitype,
+ radius,
+ roadlevel,
+ homeorcorp
+ } = poi_options;
+ requestData = Object.assign(requestData, {
+ poitype,
+ radius,
+ roadlevel,
+ homeorcorp
+ })
+ }
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v3/geocode/regeo",
+ dataType: "json",
+ data: requestData
+ });
+
+ let originalResult = requestRes.originalResult.regeocode;
+ let pois;
+ if (originalResult.pois) {
+ pois = originalResult.pois.map((item) => {
+ return {
+ id: item.id,
+ title: item.name,
+ address: item.address,
+ location: libs.common.getLocation(item.location, "lng,lat", "object"),
+ distance: item.distance,
+ direction: item.direction,
+ category: item.type
+ }
+ });
+ }
+
+ let roads;
+ if (originalResult.roads) {
+ roads = originalResult.roads.map((item) => {
+ return {
+ id: item.id,
+ title: item.name,
+ distance: Number(item.distance),
+ direction: item.direction,
+ location: libs.common.getLocation(item.location, "lng,lat", "object")
+ }
+ });
+ }
+
+ let roadinters;
+ if (originalResult.roadinters) {
+ roadinters = originalResult.roadinters.map((item) => {
+ return {
+ distance: Number(item.distance),
+ direction: item.direction,
+ first_id: item.first_id,
+ first_name: item.first_name,
+ second_id: item.second_id,
+ second_name: item.second_name,
+ location: libs.common.getLocation(item.location, "lng,lat", "object")
+ }
+ });
+ }
+
+ let result = {
+ formatted_addresses: originalResult.formatted_address,
+ country: originalResult.addressComponent.country,
+ province: originalResult.addressComponent.province,
+ city: JSON.stringify(originalResult.addressComponent.city) === "[]" || !originalResult.addressComponent.city ? originalResult.addressComponent.province : originalResult
+ .addressComponent.city,
+ district: originalResult.addressComponent.district,
+ street: originalResult.addressComponent.country,
+ street_number: originalResult.addressComponent.streetNumber.street + originalResult.addressComponent.streetNumber.number,
+ adcode: originalResult.addressComponent.adcode,
+ pois,
+ roads,
+ roadinters
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 地址解析(地址转坐标)
+ async address2location(data = {}) {
+ let {
+ address,
+ city,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v3/geocode/geo",
+ dataType: "json",
+ data: {
+ address,
+ city
+ }
+ });
+
+ let originalResult = requestRes.originalResult.geocodes[0];
+ let result = {
+ location: libs.common.getLocation(originalResult.location, "lng,lat", "object"),
+ adcode: originalResult.adcode,
+ province: originalResult.province,
+ city: originalResult.city,
+ district: originalResult.district,
+ street: originalResult.street,
+ street_number: originalResult.number,
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 坐标转换
+ async translate(data = {}) {
+ let {
+ locations,
+ type,
+ } = data;
+ let locationsStr = "";
+ locations.map((item, index) => {
+ if (index > 0) {
+ locationsStr += ";";
+ }
+ locationsStr += libs.common.getLocation(item, "object", "lng,lat");
+ })
+
+ let coordsys = {
+ "1": "gps",
+ "4": "mapbar",
+ "3": "baidu",
+ "": "autonavi",
+ } [type + ""];
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v3/assistant/coordinate/convert",
+ dataType: "json",
+ data: {
+ locations: locationsStr,
+ coordsys
+ }
+ });
+ let originalResult = requestRes.originalResult;
+ let returnLocationsStr = originalResult.locations;
+ let arr = returnLocationsStr.split(";");
+
+ let returnLocations = arr.map((item) => {
+ return libs.common.getLocation(item, "lng,lat", "object");
+ });
+
+ let result = {
+ locations: returnLocations
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - IP定位
+ async ip2location(data = {}) {
+ let {
+ ip,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v3/ip",
+ dataType: "json",
+ data: {
+ ip
+ }
+ });
+ let originalResult = requestRes.originalResult;
+ let result = {
+ adcode: originalResult.adcode,
+ province: originalResult.province,
+ city: originalResult.city,
+ rectangle: originalResult.rectangle
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 关键词输入提示
+ async inputtips(data = {}) {
+ let {
+ keyword,
+ city,
+ citylimit,
+ location,
+ datatype,
+ } = data;
+
+ let requestData = {
+ keywords: keyword,
+ city,
+ citylimit,
+ datatype
+ };
+ if (location) {
+ requestData.location = libs.common.getLocation(location, "object", "lng,lat");
+ }
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v3/assistant/inputtips",
+ dataType: "json",
+ data: requestData,
+ });
+
+ let originalResult = requestRes.originalResult;
+
+ let _data = originalResult.tips.map((item) => {
+ return {
+ id: item.id,
+ name: item.name,
+ address: item.address,
+ location: libs.common.getLocation(item.location, "lng,lat", "object"),
+ adcode: item.adcode,
+ district: item.district
+ }
+ });
+
+ let result = {
+ data: _data
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 周边搜索
+ async search(data = {}) {
+ let {
+ keyword,
+ location,
+ radius = 1000,
+ auto_extend = 1,
+ get_subpois,
+ orderby,
+ page_index = 1,
+ page_size = 20,
+ types,
+ city
+ } = data;
+
+ let requestData = {
+ keywords: keyword,
+ types,
+ location: libs.common.getLocation(location, "object", "lng,lat"),
+ radius,
+ sortrule: orderby,
+ region: city,
+ city_limit: auto_extend ? false : true,
+ page_num: page_index,
+ page_size,
+ show_fields: get_subpois ? "children,business,navi,photos" : "business,navi,photos"
+ };
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v5/place/around",
+ dataType: "json",
+ data: requestData
+ });
+ let originalResult = requestRes.originalResult;
+
+ let _data = originalResult.pois.map((item) => {
+ return {
+ id: item.id,
+ title: item.name,
+ tel: item.business.tel,
+ address: item.address,
+ category: item.type,
+ location: libs.common.getLocation(item.location, "lng,lat", "object"),
+ distance: Number(item.distance),
+ adcode: item.adcode,
+ province: item.pname,
+ city: item.cityname,
+ district: item.adname,
+ children: item.children ? item.children.map((item2) => {
+ return {
+ parent_id: item.id,
+ id: item2.id,
+ title: item2.name,
+ address: item2.address,
+ category: item2.subtype,
+ location: libs.common.getLocation(item2.location, "lng,lat", "object")
+ }
+ }) : get_subpois ? [] : undefined,
+ }
+ });
+ let result = {
+ data: _data
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 行政区划
+ async districtSearch(data = {}) {
+ let {
+ adcode,
+ get_polygon,
+ page_index,
+ page_size,
+ filter,
+ subdistrict
+ } = data;
+
+ let requestData = {
+ keywords: adcode,
+ subdistrict,
+ page: page_index,
+ offset: page_size,
+ filter
+ };
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "v3/config/district",
+ dataType: "json",
+ data: requestData
+ });
+ let originalResult = requestRes.originalResult;
+
+ const formatDistricts = (list) => {
+ return list.map((item) => {
+ return {
+ adcode: item.adcode,
+ name: item.name,
+ fullname: item.name,
+ location: libs.common.getLocation(item.center, "lng,lat", "object"),
+ level: item.level,
+ children: typeof item.districts !== "undefined" ? formatDistricts(item.districts): undefined,
+ //polygon: item.polyline,
+ }
+ });
+ }
+ let _data = formatDistricts(originalResult.districts[0].districts);
+
+ let result = {
+ data: _data
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(驾车)
+ async drivingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ from_poi,
+ to_poi,
+ policy,
+ waypoints,
+ avoid_polygons,
+ road_type,
+ plate_number,
+ cartype,
+ avoidroad,
+ ferry,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `v5/direction/driving`,
+ dataType: "json",
+ data: {
+ origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
+ destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
+ origin_id: from_poi,
+ destination_id: to_poi,
+ strategy: policy,
+ waypoints: libs.common.getReversalLocation(waypoints),
+ avoidpolygons: libs.common.getReversalLocation(avoid_polygons),
+ origin_type: road_type,
+ plate: plate_number,
+ cartype,
+ avoidroad,
+ ferry,
+ show_fields: "cost,tmcs,navi,cities,polyline"
+ }
+ });
+
+ let originalResult = requestRes.originalResult.route;
+ let routes = originalResult.paths.map((item) => {
+ let steps = item.steps.map((item2) => {
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.orientation,
+ distance: Number(item2.step_distance),
+ act_desc: item2.navi.action,
+ accessorial_desc: item2.navi.assistant_action,
+ cost: this.costFormat(item2.cost),
+ speed: item2.tmcs ? item2.tmcs.map((item3) => {
+ let levelIndex = {
+ "畅通": 0,
+ "缓行": 1,
+ "拥堵": 2,
+ "未知": 3,
+ "严重拥堵": 4,
+ }
+ return {
+ distance: Number(item3.tmc_distance),
+ level: levelIndex[item3.tmc_status],
+ polyline: this.polylineFormat(item3.tmc_polyline),
+ }
+ }) : undefined,
+ cities: item2.cities,
+ polyline: this.polylineFormat(item2.polyline),
+ }
+ });
+ return {
+ mode: "driving",
+ distance: Number(item.distance),
+ restriction_status: Number(item.restriction),
+ taxi_cost: Number(originalResult.taxi_cost),
+ steps
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(步行)
+ async walkingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ alternative_route,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `v5/direction/walking`,
+ dataType: "json",
+ data: {
+ origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
+ destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
+ alternative_route,
+ show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
+ }
+ });
+ let originalResult = requestRes.originalResult.route;
+ let routes = originalResult.paths.map((item) => {
+ let duration1 = 0;
+ let steps = item.steps.map((item2) => {
+ let duration2 = this.durationFormat(item2.cost.duration);
+ duration1 += duration2;
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.orientation,
+ distance: Number(item2.step_distance),
+ act_desc: item2.navi.action || item2.navi.assistant_action,
+ taxi_cost: item2.cost.taxi ? this.priceFormat(item2.cost.taxi) : undefined,
+ duration: duration2,
+ polyline: this.polylineFormat(item2.polyline),
+ }
+ });
+
+ return {
+ mode: "walking",
+ distance: Number(item.distance),
+ duration: duration1,
+ steps
+ }
+
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(骑行)
+ async bicyclingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ alternative_route,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `v5/direction/bicycling`,
+ dataType: "json",
+ data: {
+ origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
+ destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
+ alternative_route,
+ show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
+ }
+ });
+ let originalResult = requestRes.originalResult.route;
+ let routes = originalResult.paths.map((item) => {
+ let duration1 = 0;
+ let steps = item.steps.map((item2) => {
+ let duration2 = this.durationFormat(item2.cost.duration);
+ duration1 += duration2;
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.orientation,
+ distance: Number(item2.step_distance),
+ act_desc: item2.navi.action || item2.navi.assistant_action,
+ duration: duration2,
+ polyline: this.polylineFormat(item2.polyline),
+ }
+ });
+
+ return {
+ mode: "walking",
+ distance: Number(item.distance),
+ duration: duration1,
+ steps
+ }
+
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(电动车)
+ async ebicyclingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ alternative_route,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `v5/direction/electrobike`,
+ dataType: "json",
+ data: {
+ origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
+ destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
+ alternative_route,
+ show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
+ }
+ });
+ let originalResult = requestRes.originalResult.route;
+ let routes = originalResult.paths.map((item) => {
+ let duration1 = 0;
+ let steps = item.steps.map((item2) => {
+ let duration2 = this.durationFormat(item2.cost.duration);
+ duration1 += duration2;
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.orientation,
+ distance: Number(item2.step_distance),
+ act_desc: item2.navi.action || item2.navi.assistant_action,
+ duration: duration2,
+ polyline: this.polylineFormat(item2.polyline),
+ }
+ });
+
+ return {
+ mode: "walking",
+ distance: Number(item.distance),
+ duration: duration1,
+ steps
+ }
+
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(公交)
+ async transitRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ from_poi,
+ to_poi,
+ policy,
+ ad1,
+ ad2,
+ city1,
+ city2,
+ alternative_route,
+ multiexport,
+ max_trans,
+ nightflag,
+ date,
+ time
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `v5/direction/transit/integrated`,
+ dataType: "json",
+ data: {
+ origin: libs.common.getLocation(from, "lat,lng", "lng,lat"),
+ destination: libs.common.getLocation(to, "lat,lng", "lng,lat"),
+ originpoi: from_poi,
+ destinationpoi: to_poi,
+ strategy: policy,
+ ad1,
+ ad2,
+ city1,
+ city2,
+ AlternativeRoute: alternative_route,
+ multiexport,
+ max_trans,
+ nightflag,
+ date,
+ time,
+ show_fields: "cost,navi,polyline", // 此处强制传,为了和腾讯地图字段对齐
+ }
+ });
+
+ let originalResult = requestRes.originalResult.route;
+ let routes = originalResult.transits.map((item) => {
+ let stepsItem = this.getSteps(item.segments);
+ let steps = stepsItem.map((item2) => {
+ let mode = item2.mode.toLowerCase();
+ if (mode === "walking") {
+ // 步行
+ return {
+ mode: "walking",
+ distance: Number(item2.distance),
+ duration: this.durationFormat(item2.cost.duration),
+ steps: item2.steps.map((item3) => {
+ return {
+ instruction: item3.instruction,
+ road_name: item3.road,
+ distance: Number(item3.distance),
+ act_desc: item3.navi.action || item3.navi.assistant_action,
+ polyline: this.polylineFormat(item3.polyline)
+ }
+ }),
+ }
+ } else if (mode === "bus") {
+ return {
+ mode: "transit",
+ lines: item2.buslines.map((item3) => {
+ return {
+ vehicle: item3.type.indexOf("地铁") > -1 ? "SUBWAY" : "BUS",
+ id: item3.id,
+ title: item3.name,
+ type: item3.type,
+ station_count: Number(item3.via_num),
+ distance: Number(item3.distance),
+ duration: this.durationFormat(item3.cost.duration),
+ polyline: this.polylineFormat(item3.polyline),
+ start_time: item3.start_time,
+ end_time: item3.end_time,
+ geton: {
+ id: item3.departure_stop.id,
+ title: item3.departure_stop.name,
+ location: libs.common.getLocation(item3.departure_stop.location, "lng,lat", "object"),
+ },
+ getoff: {
+ id: item3.arrival_stop.id,
+ title: item3.arrival_stop.name,
+ location: libs.common.getLocation(item3.arrival_stop.location, "lng,lat", "object"),
+ },
+ stations: item3.via_stops.map((item4) => {
+ return {
+ id: item4.id,
+ title: item4.name,
+ location: libs.common.getLocation(item4.location, "lng,lat", "object"),
+ }
+ })
+ }
+ }),
+ }
+ } else if (mode === "railway") {
+ // 火车
+ let item3 = item2;
+ return {
+ mode: "transit",
+ lines: [{
+ vehicle: "RAIL",
+ id: item3.id,
+ title: item3.name,
+ type: item3.type,
+ distance: Number(item3.distance),
+ duration: this.durationFormat(item3.time),
+ geton: {
+ id: item3.departure_stop.id,
+ title: item3.departure_stop.name,
+ location: libs.common.getLocation(item3.departure_stop.location, "lng lat", "object"),
+ adcode: item3.departure_stop.adcode,
+ time: item3.departure_stop.time,
+ start: Number(item3.departure_stop.start),
+ },
+ getoff: {
+ id: item3.arrival_stop.id,
+ title: item3.arrival_stop.name,
+ location: libs.common.getLocation(item3.arrival_stop.location, "lng lat", "object"),
+ adcode: item3.arrival_stop.adcode,
+ time: item3.arrival_stop.time,
+ end: Number(item3.arrival_stop.end),
+ },
+ spaces: item3.spaces ? item3.spaces.map((item4) => {
+ return {
+ code: item4.code,
+ cost: this.priceFormat(item4.cost),
+ }
+ }) : undefined
+ }],
+ }
+ } else if (mode === "taxi") {
+ // 打车
+ let item3 = item2;
+ return {
+ mode: "transit",
+ lines: [{
+ vehicle: "TAXI",
+ distance: Number(item3.distance),
+ price: this.priceFormat(item3.price),
+ drivetime: this.durationFormat(item3.drivetime),
+ polyline: this.polylineFormat(item3.polyline),
+ startpoint: libs.common.getLocation(item3.startpoint, "lng,lat", "lat,lng"),
+ startname: item3.startname,
+ endpoint: libs.common.getLocation(item3.endpoint, "lng,lat", "lat,lng"),
+ endname: item3.endname
+ }]
+ }
+ }
+ });
+
+ return {
+ mode: "transit",
+ distance: Number(item.distance),
+ duration: this.durationFormat(item.cost.duration),
+ transit_fee: this.priceFormat(item.cost.transit_fee),
+ steps
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ getSteps(segments) {
+ let steps = [];
+ segments.map((item, index) => {
+ for (let mode in item) {
+ steps.push({
+ mode,
+ ...item[mode]
+ });
+ }
+ });
+ return steps;
+ }
+
+ // 格式化价格,将字符串价格转成数值,保留2位小数
+ priceFormat(price) {
+ try {
+ if (price === "") {
+ return -1;
+ } else {
+ return parseFloat(Number(price).toFixed(2));
+ }
+ } catch (err) {
+ return -1;
+ }
+ }
+
+ // 格式化cost
+ costFormat(cost = {}) {
+ let {
+ duration,
+ taxi_cost,
+ transit_fee,
+ tolls,
+ toll_distance,
+ toll_road,
+ traffic_lights
+ } = cost;
+ let res = {};
+ if (typeof duration !== "undefined") res.duration = this.durationFormat(duration);
+ if (typeof taxi_cost !== "undefined") res.taxi_cost = this.priceFormat(taxi_cost);
+ if (typeof transit_fee !== "undefined") res.transit_fee = this.priceFormat(transit_fee);
+ if (typeof tolls !== "undefined") res.tolls = this.priceFormat(tolls);
+ if (typeof toll_distance !== "undefined") res.toll_distance = Number(toll_distance);
+ if (typeof toll_road !== "undefined") res.toll_road = toll_road;
+ if (typeof traffic_lights !== "undefined") res.traffic_lights = Number(traffic_lights);
+
+ return res;
+ }
+
+ // 格式化polyline,将原本polyline.polyline转成polyline
+ polylineFormat(polyline = {}) {
+ if (polyline.polyline) {
+ return libs.common.getReversalLocation(polyline.polyline);
+ } else if (typeof polyline === "string") {
+ return libs.common.getReversalLocation(polyline);
+ } else {
+ return "";
+ }
+ }
+
+ // 格式化时间(秒转分,向上进1)
+ durationFormat(duration) {
+ try {
+ return Math.ceil(Number(duration) / 60);
+ } catch (err) {
+ return undefined;
+ }
+ }
+
+}
+module.exports = Service;
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/index.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/index.js
new file mode 100644
index 00000000..f78b2d6d
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/index.js
@@ -0,0 +1,4 @@
+module.exports = {
+ "qqmap": require('./qqmap.js'),
+ "amap": require('./amap.js')
+}
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/qqmap.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/qqmap.js
new file mode 100644
index 00000000..d90e820c
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/common/uni-map-common/service/qqmap.js
@@ -0,0 +1,856 @@
+const libs = require('../libs');
+
+class Service {
+
+ // 构造函数
+ constructor(data = {}) {
+ let {
+ key,
+ needOriginalResult = false, // 是否需要返回原始信息,默认false
+ } = data;
+
+ this.config = {
+ provider: "qqmap",
+ key,
+ needOriginalResult,
+ serviceUrl: "https://apis.map.qq.com"
+ }
+ }
+
+ async request(obj = {}) {
+ let {
+ url,
+ data = {}
+ } = obj;
+ if (url.indexOf("http") !== 0) {
+ url = `${this.config.serviceUrl}/${url}`
+ }
+ if (this.config.key && !data.key) {
+ data.key = this.config.key;
+ }
+ obj.data = JSON.parse(JSON.stringify(obj.data));
+ let requestRes = await uniCloud.httpclient.request(url, obj);
+ let result = this.getResult(requestRes);
+ if (result.errCode != 0) {
+ throw new libs.error.UniCloudError(result);
+ }
+ return result;
+ }
+
+ getResult(requestRes) {
+ let {
+ data: originalResult = {}
+ } = requestRes;
+
+ let res = {
+ errCode: originalResult.status == 0 ? 0 : this.getErrCode(originalResult.status),
+ errMsg: originalResult.message,
+ originalResult,
+ };
+
+ return res;
+ }
+
+ getErrCode(errCode) {
+ return errCode;
+ }
+
+ // API - 逆地址解析(坐标转地址)
+ async location2address(data = {}) {
+ let {
+ location,
+ get_poi,
+ poi_options
+ } = data;
+
+ let _poi_options = "";
+ if (typeof poi_options === "object") {
+ let {
+ address_format,
+ radius,
+ policy,
+ page_index,
+ page_size
+ } = poi_options;
+ if (address_format && address_format !== "long") {
+ _poi_options += `address_format=${address_format};`
+ }
+ if (radius) {
+ _poi_options += `radius=${radius};`
+ }
+ if (policy) {
+ _poi_options += `policy=${policy};`
+ }
+ if (page_index) {
+ _poi_options += `page_index=${page_index};`
+ }
+ if (page_size) {
+ _poi_options += `page_size=${page_size};`
+ }
+
+ if (_poi_options.lastIndexOf(";") === _poi_options.length - 1) {
+ _poi_options = _poi_options.substring(0, _poi_options.length - 1);
+ }
+ }
+ if (!_poi_options) _poi_options = undefined;
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/geocoder/v1/",
+ dataType: "json",
+ data: {
+ location,
+ get_poi,
+ poi_options: _poi_options,
+ }
+ });
+ let originalResult = requestRes.originalResult.result;
+ let pois;
+ if (originalResult.pois) {
+ pois = originalResult.pois.map((item) => {
+ return {
+ id: item.id,
+ title: item.title,
+ address: item.address,
+ location: item.location,
+ distance: item._distance,
+ direction: item._dir_desc,
+ category: item.category
+ }
+ });
+ }
+ let result = {
+ formatted_addresses: originalResult.address,
+ country: originalResult.address_component.nation,
+ province: originalResult.address_component.province,
+ city: originalResult.address_component.city,
+ district: originalResult.address_component.district,
+ street: originalResult.address_component.street,
+ street_number: originalResult.address_component.street_number,
+ adcode: originalResult.ad_info.adcode,
+ pois
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 地址解析(地址转坐标)
+ async address2location(data = {}) {
+ let {
+ address,
+ city,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/geocoder/v1/",
+ dataType: "json",
+ data: {
+ address: address,
+ region: city,
+ }
+ });
+ let originalResult = requestRes.originalResult.result;
+
+ let result = {
+ location: originalResult.location,
+ adcode: originalResult.ad_info.adcode,
+ province: originalResult.address_components.province,
+ city: originalResult.address_components.city,
+ district: originalResult.address_components.district,
+ street: originalResult.address_components.street,
+ street_number: originalResult.address_components.street_number,
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+
+ return res;
+ }
+
+ // API - 坐标转换
+ async translate(data = {}) {
+ let {
+ locations,
+ type,
+ } = data;
+ let locationsStr = "";
+ locations.map((item, index) => {
+ if (index > 0) {
+ locationsStr += ";";
+ }
+ locationsStr += libs.common.getLocation(item, "object", "lat,lng");
+ })
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/coord/v1/translate",
+ dataType: "json",
+ data: {
+ locations: locationsStr,
+ type
+ }
+ });
+ let originalResult = requestRes.originalResult;
+
+ let result = {
+ locations: originalResult.locations
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - IP定位
+ async ip2location(data = {}) {
+ let {
+ ip,
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/location/v1/ip",
+ dataType: "json",
+ data: {
+ ip
+ }
+ });
+ let originalResult = requestRes.originalResult.result;
+ let result = {
+ location: libs.common.getLocation(originalResult.location, "object", "object"),
+ nation: originalResult.ad_info.nation,
+ nation_code: originalResult.ad_info.nation_code,
+ adcode: originalResult.ad_info.adcode,
+ province: originalResult.ad_info.province,
+ city: originalResult.ad_info.city,
+ district: originalResult.ad_info.district
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 关键词输入提示
+ async inputtips(data = {}) {
+ let {
+ keyword,
+ city,
+ citylimit,
+ location,
+ get_subpois,
+ policy,
+ filter,
+ address_format,
+ page_index,
+ page_size
+ } = data;
+
+ let requestData = {
+ keyword,
+ region: city,
+ region_fix: citylimit ? 1 : 0,
+ get_subpois,
+ policy,
+ filter,
+ address_format,
+ page_index,
+ page_size
+ };
+ if (location) {
+ requestData.location = libs.common.getLocation(location, "object", "lat,lng");
+ }
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/place/v1/suggestion",
+ dataType: "json",
+ data: requestData
+ });
+ let originalResult = requestRes.originalResult;
+
+ let _data = originalResult.data.map((item) => {
+
+ let children;
+ if (originalResult.sub_pois) {
+ children = [];
+ originalResult.sub_pois.map((item2) => {
+ if (item2.parent_id === item.id) {
+ children.push({
+ parent_id: item.id,
+ id: item2.id,
+ title: item2.title,
+ address: item2.address,
+ category: item2.category,
+ location: item2.location,
+ adcode: String(item2.adcode),
+ city: item2.city,
+ });
+ }
+ });
+ }
+
+ return {
+ id: item.id,
+ title: item.title,
+ address: item.address,
+ category: item.category,
+ type: item.type,
+ location: item.location,
+ adcode: item.adcode,
+ province: item.province,
+ city: item.city,
+ district: item.district,
+ children
+ }
+ });
+
+ let result = {
+ data: _data
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 周边搜索
+ async search(data = {}) {
+ let {
+ keyword,
+ location,
+ radius = 1000,
+ auto_extend = 1,
+ get_subpois,
+ orderby,
+ page_index = 1,
+ page_size = 20,
+ filter
+ } = data;
+
+ if (radius < 10) radius = 10;
+
+ let boundary = `nearby(${location.lat},${location.lng},${radius},${auto_extend})`;
+
+ let requestData = {
+ keyword,
+ boundary,
+ get_subpois,
+ filter,
+ orderby: orderby === "distance" ? "_distance" : undefined,
+ page_index,
+ page_size
+ };
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/place/v1/search",
+ dataType: "json",
+ data: requestData
+ });
+ let originalResult = requestRes.originalResult;
+
+ let _data = originalResult.data.map((item) => {
+ let children;
+ if (originalResult.sub_pois) {
+ children = [];
+ originalResult.sub_pois.map((item2) => {
+ if (item2.parent_id === item.id) {
+ children.push({
+ parent_id: item.id,
+ id: item2.id,
+ title: item2.title,
+ address: item2.address,
+ category: item2.category,
+ location: item2.location,
+ tel: item2.tel,
+ adcode: String(item2.ad_info.adcode),
+ province: item2.ad_info.province,
+ city: item2.ad_info.city,
+ district: item2.ad_info.district,
+ });
+ }
+ });
+ }
+
+ return {
+ id: item.id,
+ title: item.title,
+ tel: item.tel,
+ address: item.address,
+ category: item.category,
+ type: item.type,
+ location: item.location,
+ distance: item._distance,
+ adcode: String(item.ad_info.adcode),
+ province: item.ad_info.province,
+ city: item.ad_info.city,
+ district: item.ad_info.district,
+ children
+ }
+ });
+
+ let result = {
+ data: _data
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 行政区划
+ async districtSearch(data = {}) {
+ let {
+ adcode,
+ get_polygon,
+ max_offset
+ } = data;
+
+ let requestData = {
+ id: adcode,
+ get_polygon,
+ max_offset
+ };
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: "ws/district/v1/getchildren",
+ dataType: "json",
+ data: requestData
+ });
+ let originalResult = requestRes.originalResult;
+ let _data = originalResult.result[0].map((item) => {
+ return {
+ adcode: item.id,
+ name: item.name || item.fullname,
+ fullname: item.fullname,
+ location: item.location,
+ pinyin: item.pinyin,
+ cidx: item.cidx,
+ polygon: item.polygon,
+ }
+ });
+
+ let result = {
+ data: _data,
+ data_version: originalResult.data_version
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(驾车)
+ async drivingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ from_poi,
+ to_poi,
+ policy,
+ waypoints,
+ avoid_polygons,
+ road_type,
+ plate_number,
+ cartype,
+ heading,
+ speed,
+ accuracy,
+ from_track,
+ get_mp,
+ no_step
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `ws/direction/v1/driving`,
+ dataType: "json",
+ data: {
+ from,
+ to,
+ from_poi,
+ to_poi,
+ policy,
+ waypoints,
+ avoid_polygons,
+ road_type,
+ plate_number,
+ cartype,
+ heading,
+ speed,
+ accuracy,
+ from_track,
+ get_mp,
+ get_speed: 1,
+ added_fields: "cities",
+ no_step
+ }
+ });
+
+ let originalResult = requestRes.originalResult.result;
+ let routes = originalResult.routes.map((item) => {
+ let waypoints;
+ if (item.waypoints) {
+ waypoints = item.waypoints.map((item2) => {
+ return {
+ title: item2.title,
+ location: item2.location,
+ duration: item2.duration,
+ distance: item2.distance,
+ polyline: this.getPolyline(item.polyline, item2.polyline_idx),
+ polyline_idx: item2.polyline_idx,
+ }
+ });
+ }
+ let steps = item.steps.map((item2) => {
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.dir_desc,
+ distance: item2.distance,
+ act_desc: item2.act_desc,
+ accessorial_desc: item2.accessorial_desc,
+ polyline: this.getPolyline(item.polyline, item2.polyline_idx),
+ polyline_idx: item2.polyline_idx,
+ }
+ });
+
+ let speed = item.speed.map((item2) => {
+ return {
+ distance: item2.distance,
+ level: item2.level,
+ polyline: this.getPolyline(item.polyline, item2.polyline_idx),
+ polyline_idx: item2.polyline_idx,
+ }
+ });
+
+ return {
+ mode: "driving",
+ tags: item.tags,
+ distance: item.distance,
+ duration: item.duration,
+ traffic_light_count: item.traffic_light_count,
+ restriction_status: item.restriction.status,
+ polyline: this.polylineFormat(item.polyline),
+ waypoints,
+ taxi_cost: item.taxi_fare.fare,
+ cities: item.cities,
+ steps,
+ speed
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(步行)
+ async walkingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ to_poi
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `ws/direction/v1/walking`,
+ dataType: "json",
+ data: {
+ from,
+ to,
+ to_poi
+ }
+ });
+
+ let originalResult = requestRes.originalResult.result;
+ let routes = originalResult.routes.map((item) => {
+ let steps = item.steps.map((item2) => {
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.dir_desc,
+ distance: item2.distance,
+ act_desc: item2.act_desc,
+ type: item2.type,
+ polyline: this.getPolyline(item.polyline, item2.polyline_idx),
+ polyline_idx: item2.polyline_idx,
+ }
+ });
+
+ return {
+ mode: "walking",
+ distance: item.distance,
+ duration: item.duration,
+ direction: item.direction,
+ polyline: this.polylineFormat(item.polyline),
+ steps
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(骑行)
+ async bicyclingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ to_poi
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `ws/direction/v1/bicycling`,
+ dataType: "json",
+ data: {
+ from,
+ to,
+ to_poi
+ }
+ });
+
+ let originalResult = requestRes.originalResult.result;
+ let routes = originalResult.routes.map((item) => {
+ let steps = item.steps.map((item2) => {
+ return {
+ instruction: item2.instruction,
+ road_name: item2.road_name,
+ dir_desc: item2.dir_desc,
+ distance: item2.distance,
+ act_desc: item2.act_desc,
+ polyline: this.getPolyline(item.polyline, item2.polyline_idx),
+ polyline_idx: item2.polyline_idx
+ }
+ });
+
+ return {
+ mode: "bicycling",
+ distance: item.distance,
+ duration: item.duration,
+ direction: item.direction,
+ polyline: this.polylineFormat(item.polyline),
+ steps
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(电动车)
+ async ebicyclingRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ to_poi
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `ws/direction/v1/ebicycling`,
+ dataType: "json",
+ data: {
+ from,
+ to,
+ to_poi
+ }
+ });
+
+ let originalResult = requestRes.originalResult.result;
+ let routes = originalResult.routes.map((item) => {
+ let steps = item.steps.map((item2) => {
+ return {
+ instruction: item2.instruction,
+ polyline_idx: item2.polyline_idx,
+ road_name: item2.road_name,
+ dir_desc: item2.dir_desc,
+ distance: item2.distance,
+ act_desc: item2.act_desc,
+ polyline: this.getPolyline(item.polyline, item2.polyline_idx)
+ }
+ });
+
+ return {
+ mode: "ebicycling",
+ distance: item.distance,
+ duration: item.duration,
+ direction: item.direction,
+ polyline: this.polylineFormat(item.polyline),
+ steps
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // API - 路线规划(公交)
+ async transitRoute(data = {}) {
+ let {
+ mode,
+ from,
+ to,
+ from_poi,
+ to_poi,
+ departure_time,
+ policy
+ } = data;
+
+ let requestRes = await this.request({
+ method: "GET",
+ url: `ws/direction/v1/transit`,
+ dataType: "json",
+ data: {
+ from,
+ to,
+ from_poi,
+ to_poi,
+ departure_time,
+ policy
+ }
+ });
+
+ let originalResult = requestRes.originalResult.result;
+ let routes = originalResult.routes.map((item) => {
+ let steps = item.steps.map((item2) => {
+ let mode = item2.mode.toLowerCase();
+ if (mode === "walking") {
+ // 步行
+ return {
+ mode: mode,
+ distance: item2.distance,
+ duration: item2.duration,
+ direction: item2.direction,
+ polyline: this.polylineFormat(item2.polyline),
+ steps: item2.steps ? item2.steps.map((item3) => {
+ return {
+ instruction: item3.instruction,
+ road_name: item3.road_name,
+ act_desc: item3.dir_desc,
+ distance: item3.distance,
+ polyline: this.getPolyline(item2.polyline, item3.polyline_idx),
+ polyline_idx: item3.polyline_idx,
+ }
+ }) : undefined,
+ }
+ } else {
+ // 非步行
+ return {
+ mode: mode,
+ lines: item2.lines.map((item3) => {
+ return {
+ ...item3,
+ price: item3.vehicle !== "RAIL" ? this.priceFormat(item3.price) : item3.price,
+ polyline: this.polylineFormat(item3.polyline)
+ }
+ })
+ }
+ }
+ });
+
+ return {
+ mode: "transit",
+ distance: item.distance,
+ duration: item.duration,
+ bounds: item.bounds,
+ steps
+ }
+ });
+ let result = {
+ routes
+ };
+ let res = {
+ result,
+ ...requestRes
+ };
+ return res;
+ }
+
+ // 格式化polyline,将压缩的polyline还原成完整的经纬度
+ polylineFormat(polyline) {
+ try {
+ let coors = JSON.parse(JSON.stringify(polyline));
+ for (let i = 2; i < coors.length; i++) {
+ coors[i] = parseFloat((coors[i - 2] + coors[i] / 1000000).toFixed(6));
+ }
+ return coors;
+ } catch (err) {
+ return "";
+ }
+ }
+
+ // 格式化价格,将以分为单位的价格转元,保留2位小数
+ priceFormat(price) {
+ try {
+ if (price === "" || price == -1) {
+ return -1;
+ } else {
+ return parseFloat((price / 100).toFixed(2));
+ }
+ } catch (err) {
+ return -1;
+ }
+ }
+
+ getPolyline(polyline, polyline_idx) {
+ let polylineArr = this.polylineFormat(polyline);
+ if (typeof polyline_idx == "object") {
+ let arr = polylineArr.slice(polyline_idx[0], polyline_idx[1] + 1);
+ let str = "";
+ arr.map((item, index) => {
+ if (index % 2 === 0) {
+ str += `${item}`
+ } else {
+ str += `,${item};`
+ }
+ });
+ // 去除最后一个;
+ if (str.lastIndexOf(";") === str.length - 1) {
+ str = str.substring(0, str.length - 1);
+ }
+ return str;
+ } else {
+ return polylineArr[polyline_idx] + "," + polylineArr[polyline_idx + 1];
+ }
+
+ }
+
+}
+module.exports = Service;
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/index.obj.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/index.obj.js
new file mode 100644
index 00000000..0211e7c1
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/index.obj.js
@@ -0,0 +1,518 @@
+// 引入uni-map-common公共模块
+const UniMap = require('uni-map-common');
+
+const configCenter = require("uni-config-center");
+
+// 读取配置中心地图配置
+var UniMapConfig = configCenter({ pluginId: 'uni-map' }).requireFile('config.js');
+
+// 本地地图配置
+var LocalMapConfig = {
+ "default": "", // 默认使用的平台
+ "key": {
+ "qqmap": "", // 腾讯地图key
+ "amap": "", // 高德地图key
+ }
+}
+
+const db = uniCloud.database();
+const _ = db.command;
+const $ = _.aggregate;
+
+const opendbPoiDB = db.collection("opendb-poi");
+
+module.exports = {
+ _before: function() {
+ // 如果配置中心不存在地图配置,则使用本地地图配置
+ if (!UniMapConfig) {
+ UniMapConfig = LocalMapConfig;
+ }
+ let defaultProvider = UniMapConfig.default || "qqmap";
+ let params = this.getParams();
+ let {
+ provider = defaultProvider,
+ needOriginalResult = false
+ } = params[0] || {};
+ console.log('provider: ', provider)
+ const key = UniMapConfig.key[provider] || LocalMapConfig.key[provider];
+ if (!key) {
+ throw { errCode: -1, errMsg: `请在uni-config-center/uni-map/config.js中或LocalMapConfig中配置地图供应商${provider}对应的key` };
+ }
+ // 初始化实例
+ let uniMap = new UniMap({
+ provider: provider, // 指定使用哪家地图供应商
+ key: key,
+ needOriginalResult
+ });
+ this.uniMap = uniMap;
+ },
+ _after: function(error, res) {
+ if (error) {
+ throw error; // 如果方法抛出错误,也直接抛出不处理
+ }
+ console.log("result", res.result);
+ return res;
+ },
+ // 函数chooseLocation是给uni.chooseLocation使用,请勿修改chooseLocation函数的代码
+ async chooseLocation(parame = {}) {
+ let res = {};
+ let {
+ action,
+ data,
+ needOriginalResult
+ } = parame;
+ // 初始化实例
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap[action](data);
+ res.result = needOriginalResult ? result.originalResult : result;
+ return res;
+ },
+ // 经纬度坐标转地址
+ async location2address(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.location2address(data);
+ res.result = result;
+ return res;
+ },
+ // 地址转经纬度坐标
+ async address2location(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.address2location(data);
+ res.result = result;
+ return res;
+ },
+ // 坐标系转换
+ async translate(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.translate(data);
+ res.result = result;
+ return res;
+ },
+ // ip定位
+ async ip2location(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.ip2location(data);
+ res.result = result;
+ return res;
+ },
+ // 输入提示
+ async inputtips(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.inputtips(data);
+ res.result = result;
+ return res;
+ },
+
+ // 搜索
+ async search(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.search(data);
+ res.result = result;
+ return res;
+ },
+
+ // 行政区划
+ async districtSearch(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.districtSearch(data);
+ res.result = result;
+ return res;
+ },
+
+ // 路径规划
+ async route(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.route(data);
+ res.result = result;
+ return res;
+ },
+
+ // 演示用 - 清空所有的测试POI
+ async clearPoi(data = {}) {
+ let res = { errCode: 0 };
+ const db = uniCloud.database();
+ await db.collection("opendb-poi").where({
+ is_random: true
+ }).remove();
+ return res;
+ },
+
+ // 演示用 - 初始化静态001场景演示数据
+ async initStatic001(data = {}) {
+ let res = { errCode: 0 };
+ const category = "static-001";
+ // 先删除
+ await opendbPoiDB.where({
+ category: category
+ }).remove();
+ // 后添加随机数据
+
+ // 以天安门为中心
+ let tiananmen = {
+ longitude: 116.39747,
+ latitude: 39.908823,
+ };
+ let time = Date.now();
+
+ // 随机生成6个门店地址
+ let list = [];
+ for (let i = 1; i <= 6; i++) {
+ let randomCoordinate = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 10); // 随机生成在天安门方圆X KM内的坐标
+ list.push({
+ category: category, // 场景值,用于区分这些POI所属哪张地图
+ type: "门店",
+ title: `随机门店-${i}`,
+ location: new db.Geo.Point(randomCoordinate.longitude, randomCoordinate.latitude),
+ create_date: time,
+ visible: true,
+ is_random: true, // 表示此为随机生成的点,方便删除
+ level: i
+ });
+ }
+ // 随机生成1个总部地址
+ let randomCoordinate = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 1); // 随机生成在天安门方圆X KM内的坐标
+ list.push({
+ category: category, // 场景值,用于区分这些POI所属哪张地图
+ type: "总部",
+ title: `随机总部`,
+ location: new db.Geo.Point(randomCoordinate.longitude, randomCoordinate.latitude),
+ create_date: time,
+ visible: true,
+ is_random: true, // 表示此为随机生成的点,方便删除
+ level: 7
+ });
+
+ // 添加到数据库
+ await opendbPoiDB.add(list);
+
+ return res;
+ },
+
+ // 演示用 - 初始化动态001场景演示数据(模拟送外卖场景)
+ async initDynamics001(data = {}) {
+ let res = { errCode: 0 };
+
+ const category = "dynamics-001";
+
+ // 先删除
+ await opendbPoiDB.where({
+ category: category
+ }).remove();
+ // 后添加随机数据
+
+ // 以天安门为中心
+ let tiananmen = {
+ longitude: 116.39747,
+ latitude: 39.908823,
+ };
+
+ let time = Date.now();
+
+ // 随机生成配送员坐标
+ let randomCoordinate1 = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 2); // 随机生成在天安门方圆X KM内的坐标
+ let data1 = {
+ category: category, // 场景值,用于区分这些POI所属哪张地图
+ type: "配送员",
+ title: "配送员",
+ location: new db.Geo.Point(randomCoordinate1.longitude, randomCoordinate1.latitude),
+ create_date: time,
+ visible: true,
+ is_random: true, // 表示此为随机生成的点,方便删除
+ }
+ // 随机生成目的地坐标
+ let randomCoordinate2 = getRandomCoordinateWithinRadius(tiananmen.longitude, tiananmen.latitude, 2); // 随机生成在天安门方圆X KM内的坐标
+ let data2 = {
+ category: category, // 场景值,用于区分这些POI所属哪张地图
+ type: "目的地",
+ title: "配送目的地",
+ location: new db.Geo.Point(randomCoordinate2.longitude, randomCoordinate2.latitude),
+ create_date: time,
+ visible: true,
+ is_random: true, // 表示此为随机生成的点,方便删除
+ }
+ let list = [data1, data2];
+ // 添加到数据库
+ await opendbPoiDB.add(list);
+
+ // 获取配送路线
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用电瓶车路径规划API
+ let result = await uniMap.route({
+ mode: "ebicycling",
+ from: `${randomCoordinate1.latitude},${randomCoordinate1.longitude}`,
+ to: `${randomCoordinate2.latitude},${randomCoordinate2.longitude}`,
+ alternative_route: 1
+ });
+
+ let route = result.result.routes[0];
+ let { steps = [] } = route;
+ let points = [];
+ steps.map((step) => {
+ let {
+ polyline = ""
+ } = step;
+ let arr = polyline.split(";");
+ arr.map((item) => {
+ let arr2 = item.split(",");
+ points.push({
+ latitude: arr2[0],
+ longitude: arr2[1],
+ });
+ });
+ });
+ let polyline = {
+ points,
+ color: "#19b411",
+ width: 6,
+ dottedLine: false,
+ arrowLine: true,
+ borderWidth: 1,
+ borderColor: "#000000",
+ };
+ res.polyline = [polyline];
+ return res;
+ },
+
+ // 演示用 - 获取配送员配送路径
+ async getPolyline(data = {}) {
+ let res = { errCode: 0 };
+
+ const category = "dynamics-001";
+
+ let getRes1 = await opendbPoiDB.where({
+ category: category,
+ type: "配送员",
+ visible: true
+ }).get();
+ let poi1 = getRes1.data[0];
+
+ let getRes2 = await opendbPoiDB.where({
+ category: category,
+ type: "目的地",
+ visible: true
+ }).get();
+ let poi2 = getRes2.data[0];
+ if (!poi2) {
+ return {
+ errCode: 0,
+ end: true
+ }
+ }
+
+ let coordinate1 = {
+ longitude: poi1.location.coordinates[0],
+ latitude: poi1.location.coordinates[1]
+ };
+
+ let coordinate2 = {
+ longitude: poi2.location.coordinates[0],
+ latitude: poi2.location.coordinates[1]
+ };
+
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用电瓶车路径规划API
+ let result = await uniMap.route({
+ mode: "ebicycling",
+ from: `${coordinate1.latitude},${coordinate1.longitude}`,
+ to: `${coordinate2.latitude},${coordinate2.longitude}`,
+ alternative_route: 1
+ });
+
+ let route = result.result.routes[0];
+ //console.log('route: ', route)
+ let { steps = [], distance, duration } = route;
+ let points = [];
+ let dir_desc;
+ steps.map((step) => {
+ let {
+ polyline = ""
+ } = step;
+ if (!dir_desc) dir_desc = step.dir_desc;
+ if (polyline) {
+ let arr = polyline.split(";");
+ arr.map((item) => {
+ let arr2 = item.split(",");
+ if (!isNaN(arr2[0]) && !isNaN(arr2[1])) {
+ points.push({
+ latitude: Number(arr2[0]),
+ longitude: Number(arr2[1]),
+ });
+ }
+ });
+ }
+ });
+ let polyline = {
+ points,
+ color: "#19b411",
+ width: 6,
+ dottedLine: false,
+ arrowLine: true,
+ borderWidth: 1,
+ borderColor: "#000000",
+ };
+ res.polyline = [polyline];
+ if (distance <= 30 || duration <= 0) {
+ await opendbPoiDB.doc(poi1._id).update({
+ title: `配送员已到达目的地`,
+ location: new db.Geo.Point(Number(coordinate2.longitude), Number(coordinate2.latitude)),
+ rotate: 0
+ });
+ // 隐藏目的地
+ await opendbPoiDB.doc(poi2._id).update({
+ visible: false,
+ });
+ return {
+ errCode: 0,
+ end: true
+ }
+ } else {
+ // 从最近2个点计算出当前行驶方向
+ let rotate = 0;
+ if (points && points.length >= 2) {
+ rotate = calculateDirectionAngle(points[0], points[1]);
+ }
+ await opendbPoiDB.doc(poi1._id).update({
+ title: `配送员正在配送\r\n还有 ${distance} 米\r\n预计 ${duration} 分钟送达`,
+ rotate: rotate, // 设置角度,0°的图片方向应朝左(西) 故90° 朝上(北) 180° 朝右(东) 270° 朝下(南)
+ });
+ }
+ return res;
+ },
+ // 演示用 - 模拟上报配送员坐标
+ async updateMyLocation(data = {}) {
+ let res = {};
+
+ const category = "dynamics-001";
+
+ let {
+ longitude,
+ latitude
+ } = data;
+
+ let getRes1 = await opendbPoiDB.where({
+ category: category,
+ type: "配送员",
+ visible: true
+ }).get();
+ let poi1 = getRes1.data[0];
+
+ await opendbPoiDB.doc(poi1._id).update({
+ location: new db.Geo.Point(Number(longitude), Number(latitude))
+ });
+ return res;
+ },
+
+ // 演示用 - xxxx
+ async test(data = {}) {
+ let res = {};
+ // 获取uniMap实例
+ const uniMap = this.uniMap;
+ // 调用API
+ let result = await uniMap.location2address({
+
+ });
+ res.result = result;
+ return res;
+ }
+}
+
+
+
+/**
+ * 生成在指定经纬度圆内的随机坐标
+
+const latitude = 39.908823; // 指定纬度
+const longitude = 116.39747; // 指定经度
+const radiusInKm = 10; // 指定圆的半径(单位:千米)
+
+const randomCoordinate = getRandomCoordinateWithinRadius(latitude, longitude, radiusInKm);
+console.log(randomCoordinate);
+
+ */
+function getRandomCoordinateWithinRadius(longitude, latitude, radiusInKm) {
+ // 地球半径(单位:千米)
+ const earthRadius = 6371;
+
+ // 将圆的半径转换为弧度
+ const radiusInRad = radiusInKm / earthRadius;
+
+ // 生成随机的方位角(弧度,0到2π)
+ const randomAngleRad = Math.random() * 2 * Math.PI;
+
+ // 生成随机的距离(弧度,0到圆的半径)
+ const randomDistanceRad = Math.acos(Math.random() * (Math.cos(radiusInRad) - 1) + 1);
+
+ // 使用球面三角学计算随机点的纬度和经度
+ const randomLatitudeRad = latitude * (Math.PI / 180) + randomDistanceRad * Math.cos(randomAngleRad);
+ const randomLongitudeRad = longitude * (Math.PI / 180) + randomDistanceRad * Math.sin(randomAngleRad) / Math.cos(latitude * (Math.PI / 180));
+
+ // 转换为度,并保留6位小数
+ const randomLatitude = parseFloat((randomLatitudeRad * (180 / Math.PI)).toFixed(6));
+ const randomLongitude = parseFloat((randomLongitudeRad * (180 / Math.PI)).toFixed(6));
+
+ return { latitude: randomLatitude, longitude: randomLongitude };
+}
+
+
+/**
+ * 计算坐标B在坐标A的方向,0代表正西方 90 代表正北方
+
+const latitude = 39.908823; // 指定纬度
+const longitude = 116.39747; // 指定经度
+const radiusInKm = 10; // 指定圆的半径(单位:千米)
+
+const randomCoordinate = getRandomCoordinateWithinRadius(latitude, longitude, radiusInKm);
+console.log(randomCoordinate);
+
+ */
+function calculateDirectionAngle(coordA, coordB) {
+ const toRadians = (angle) => angle * (Math.PI / 180);
+ const toDegrees = (angle) => angle * (180 / Math.PI);
+
+ const lat1 = toRadians(coordA.latitude);
+ const lon1 = toRadians(coordA.longitude);
+ const lat2 = toRadians(coordB.latitude);
+ const lon2 = toRadians(coordB.longitude);
+
+ const dLon = lon2 - lon1;
+ const y = Math.sin(dLon) * Math.cos(lat2);
+ const x =
+ Math.cos(lat1) * Math.sin(lat2) -
+ Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
+ const angleRadians = Math.atan2(y, x);
+
+ let angleDegrees = toDegrees(angleRadians);
+ angleDegrees = (angleDegrees + 360) % 360;
+
+ angleDegrees = (angleDegrees > 180) ? angleDegrees - 180 : angleDegrees + 180;
+ angleDegrees -= 90; // 以正西方为0°表示,因此需要-90
+ return angleDegrees;
+}
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/package.json b/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/package.json
new file mode 100644
index 00000000..5d4ecb92
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "uni-map-co",
+ "dependencies": {
+ "uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
+ "uni-map-common": "file:../common/uni-map-common",
+ "uni-id-common": "file:../../../../uni-id-common/uniCloud/cloudfunctions/common/uni-id-common"
+ },
+ "extensions": {}
+}
\ No newline at end of file
diff --git a/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/uni-map-co.param.js b/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/uni-map-co.param.js
new file mode 100644
index 00000000..d5c1dd13
--- /dev/null
+++ b/uni_modules/uni-map-common/uniCloud/cloudfunctions/uni-map-co/uni-map-co.param.js
@@ -0,0 +1,123 @@
+// chooseLocation({
+// action: "location2address",
+// needOriginalResult: true,
+// data: {
+// location: "39.908815,116.397507",
+// get_poi: 1,
+// poi_options: {
+// address_format: "short",
+// radius: 5000,
+// policy: 4,
+// //poitype: "010101",
+// roadlevel: 1,
+// homeorcorp: 1,
+// page_index: 1,
+// page_size: 1,
+// }
+// }
+// })
+
+// location2address({
+// location: "39.908815,116.397507",
+// get_poi: 1,
+// poi_options: {
+// address_format: "short",
+// radius: 5000,
+// policy: 4,
+// //poitype: "010101",
+// roadlevel: 1,
+// homeorcorp: 1
+// }
+// });
+
+address2location({
+ address: "北京市海淀区彩和坊路海淀西大街74号",
+ city: "北京"
+});
+
+// translate({
+// locations: [
+// { lat: 39.908815, lng: 116.397507 },
+// { lat: 39.908815, lng: 116.397107 }
+// ],
+// type: 3
+// });
+
+// ip定位
+// ip2location({
+// ip: "111.206.145.41"
+// });
+
+// 输入提示
+// inputtips({
+// keyword: "人民医院",
+// city: "北京市",
+// datatype: "all",
+// get_subpois: 1
+// });
+
+// 周边搜索
+// search({
+// keyword: "酒店",
+// location: {
+// lat: 39.908815,
+// lng: 116.397507
+// },
+// radius: 1000,
+// auto_extend: 1,
+// get_subpois: 1,
+// orderby: "weight",
+// page_index: 1,
+// page_size: 20,
+// city: "北京市"
+// });
+
+// 行政区划
+// districtSearch({
+// adcode: "110000",
+// get_polygon: 2,
+// max_offset: 500,
+// subdistrict: 2
+// });
+
+// 导航 - 驾车
+// route({
+// mode: "driving",
+// from: "39.808815,116.387507",
+// to: "39.908815,116.397507",
+// get_mp: 1,
+// });
+
+// 导航 - 步行
+// route({
+// mode: "walking",
+// from: "40.034852,116.319820",
+// to: "39.771075,116.351395",
+// alternative_route: 3
+// });
+
+// 导航 - 骑行
+// route({
+// mode: "bicycling",
+// from: "40.034852,116.319820",
+// to: "39.771075,116.351395",
+// alternative_route: 3
+// });
+
+// 导航 - 电动车
+// route({
+// mode: "ebicycling",
+// from: "40.034852,116.319820",
+// to: "39.771075,116.351395",
+// alternative_route: 3
+// });
+
+// 导航 - 公交
+// route({
+// mode: "transit",
+// from: "40.034852,116.319820",
+// to: "29.771075,116.351395",
+// //alternative_route: 3,
+// city1: "010",
+// city2: "0792",
+// });
\ No newline at end of file
--
GitLab