提交 f69744df 编写于 作者: DCloud-WZF's avatar DCloud-WZF 💬

feat: chooseLocation 示例支持 app 端

上级 6e302012
<template> <template>
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view style="background:#FFFFFF; padding:40rpx;"> <view style="background:#FFFFFF; padding:40rpx;">
<view class="uni-hello-text uni-center">当前位置信息</view> <view class="uni-hello-text uni-center">位置信息</view>
<block v-if="hasLocation === false"> <view v-if="!hasLocation">
<view class="uni-h2 uni-center uni-common-mt">未选择位置</view> <view class="uni-h2 uni-center uni-common-mt">未选择位置</view>
</block> </view>
<block v-if="hasLocation === true"> <view v-if="hasLocation">
<view class="uni-hello-text uni-center" style="margin-top:10px;"> <view class="uni-hello-text uni-center" style="margin-top:10px;">
{{locationAddress}} {{locationAddress}}
</view> </view>
<view class="uni-h2 uni-center uni-common-mt"> <view class="uni-h2 uni-center uni-common-mt" v-if="location.latitude.length>1">
<text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text> <text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text>
<text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text> <text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text>
</view> </view>
</block> </view>
</view> </view>
<view class="uni-btn-v"> <view class="uni-btn-v">
<view class="tips">注意:Web和App需要正确配置地图服务商的Key并且保证Key的权限和余额足够,才能正常选择位置</view> <view class="tips">注意:Web和App需要正确配置地图服务商的Key并且保证Key的权限和余额足够,才能正常选择位置</view>
<button type="primary" @tap="chooseLocation">选择位置</button> <button type="primary" @tap="chooseLocation">选择位置</button>
<button @tap="clear">清空</button> <button @tap="clear">清空</button>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script lang="uts"> <script lang="uts">
function formatLocation(longitude, latitude) { type Location = {
if (typeof longitude === 'string' && typeof latitude === 'string') { latitude: string[]
longitude = parseFloat(longitude) longitude: string[]
latitude = parseFloat(latitude) }
} export default {
longitude = longitude.toFixed(2) data() {
latitude = latitude.toFixed(2) return {
return { title: 'chooseLocation',
longitude: longitude.toString().split('.'), hasLocation: false,
latitude: latitude.toString().split('.') location: {
} latitude: [],
} longitude: []
export default { } as Location,
data() { locationAddress: ''
return { }
title: 'chooseLocation', },
hasLocation: false, methods: {
location: {}, chooseLocation: function () {
locationAddress: '' uni.chooseLocation({
} success: (res) => {
}, console.log('chooseLocation success', res)
methods: { this.hasLocation = true
chooseLocation: function () { this.location = this.formatLocation(res.longitude, res.latitude)
uni.chooseLocation({ this.locationAddress = res.address
success: (res) => { }
console.log(res, 123) })
this.hasLocation = true },
this.location = formatLocation(res.longitude, res.latitude) formatLocation: function(longitude:number, latitude:number):Location {
this.locationAddress = res.address const longitudeArr = longitude.toString().split('.')
} const latitudeArr = latitude.toString().split('.')
}) if(longitudeArr.length>1){
}, longitudeArr[1] = longitudeArr[1].substring(0,2)
clear: function () { }
this.hasLocation = false if(latitudeArr.length>1){
} latitudeArr[1] = latitudeArr[1].substring(0,2)
} }
} return {
</script> longitude: longitudeArr,
latitude: latitudeArr
<style> }
.page-body-info { },
padding-bottom: 0; clear: function () {
height: 440rpx; this.hasLocation = false
} }
}
.tips { }
font-size: 12px; </script>
margin-top: 15px;
opacity: .8; <style>
} .page-body-info {
padding-bottom: 0;
height: 440rpx;
}
.tips {
font-size: 12px;
margin-top: 15px;
opacity: .8;
}
</style> </style>
## 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
{
"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
# 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)
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
/**
* 通用公共函数
*/
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
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
const common = require('./common');
const error = require('./error');
module.exports = {
common,
error
};
\ No newline at end of file
{
"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
module.exports = {
"qqmap": require('./qqmap.js'),
"amap": require('./amap.js')
}
\ No newline at end of file
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
// 引入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
{
"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
// 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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册