上传代码

This commit is contained in:
2025-08-18 14:20:34 +08:00
commit 527fd07910
2408 changed files with 427370 additions and 0 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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
}

View File

@ -0,0 +1,7 @@
const common = require('./common');
const error = require('./error');
module.exports = {
common,
error
};

View File

@ -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.5",
"plugin-dev-name": "uni-map-common",
"plugin-version": "1.1.5"
}

View File

@ -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;

View File

@ -0,0 +1,4 @@
module.exports = {
"qqmap": require('./qqmap.js'),
"amap": require('./amap.js')
}

View File

@ -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;