uniapp 唤醒 手机地图软件源码
/*
* 功能:应用外唤起地图并标注地点
* 特点:uni.openLocation()的简易替代品,唤起指定地图的某个标点。
* 优点:不依赖uniapi,无须集成sdk,无须声明位置权限,兼容多个地图。
* 缺点:非应用内置地图,依赖文档等等等。
* 日期:2021年12月15日
* 支付宝:\u004e\u0054\u0041\u0079\u004d\u0054\u0067\u0077\u004e\u007a\u0051\u0035\u0051\u0048\u0046\u0078\u004c\u006d\u004e\u0076\u0062\u0051\u003d\u003d
*/
/*
# 用法
import mapTool from 'xxx.js'
mapTool.navTo(point, map)
# 提示
1.未加入Google Map,未使用WGS84坐标系,需要唤起后直接导航 或 地址逆解析,请自行解决。
2.(重要)使用腾讯地图scheme需要开发者Key,请自行注册。
3.(重要)使用查询地图是否安装的方法mapsExist(),iOS9以后需要添加白名单才可查询。即在manifest.json文件plus->distribute->apple->urlschemewhitelist节点下添加(如urlschemewhitelist:["xxx"]),名称请参考下方MapsInfo对象各属性的i_wlname。
4.Document:
<https://lbsyun.baidu.com/index.php?title=uri>
<https://lbs.amap.com/api/amap-mobile/summary>
<https://lbs.qq.com/webApi/uriV1/uriGuide/uriOverview>
<https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html>
<https://developers.google.com/maps/documentation/ios/urlscheme>
*/
// 腾讯地图开发者Key
const QQMapKey = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
const Platform = plus.os.name // Android;iOS;...
const MapsInfo = {
baidu: {
url: 'http://map.baidu.com',
CN: '百度地图',
EN: 'bdmap',
w_uri: 'http://api.map.baidu.com',
a_intent: 'baidumap://',
a_pname: 'com.baidu.BaiduMap', //package name
i_scheme: 'baidumap://', // action
i_wlname: 'baidumap' // white list name
},
gaode: {
url: 'https://m.amap.com',
CN: '高德地图',
EN: 'amap',
w_uri: 'https://uri.amap.com',
a_intent: 'androidamap://',
a_pname: 'com.autonavi.minimap', //package name
i_scheme: 'iosamap://', // action
i_wlname: 'iosamap' // white list name
},
tengxun: {
url: 'https://map.qq.com',
CN: '腾讯地图',
EN: 'qqmap',
w_uri: 'https://apis.map.qq.com',
a_intent: 'qqmap://',
a_pname: 'com.tencent.map', //package name
i_scheme: 'qqmap://', // action
i_wlname: 'qqmap' // white list name
},
pingguo: { // 白名单需要增加maps,才可检测到系统地图
url: 'http://maps.apple.com',
CN: '系统地图',
EN: 'maps',
w_uri: 'http://maps.apple.com',
a_intent: 'androidamap://', // 安卓高德地图,理论上用不到
a_pname: 'com.autonavi.minimap', // 安卓高德地图,理论上用不到
i_scheme: 'maps://', // action
i_wlname: 'maps' // white list name
}
}
const DefaultMap = MapsInfo.tengxun // 据自身业务采用【腾讯地图】作为默认地图,腾讯地图scheme需要开发者Key
const DefaultPoint = { // 默认标注,【找不到所在位置】意为lat、lng缺失;【未知位置】意为lbl缺失;
lat: 22.517007, // gcj02
lng: 113.392532, // gcj02
lbl: '找不到所在位置', // label
dtl: '未知地址' // detail
}
const DefaultService = { // 来源信息(可设为包名),百度地图、高德地图必填,不可空
web: 'web.xxx.app',
ios: 'ios.xxx.app',
android: 'android.xxx.app'
}
// GCJ-02(腾讯、高德等火星坐标系) To BD-09(百度坐标系)
const gcj2bd = function(lat, lng) {
var point = new Object();
var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
var x = new Number(lng);
var y = new Number(lat);
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
var bd_lng = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
point.lng = bd_lng;
point.lat = bd_lat;
return point;
}
// BD-09(百度坐标系) To GCJ-02(腾讯、高德等火星坐标系)
const bd2gcj = function(lat, lng) {
var point = new Object();
var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
var x = new Number(lng - 0.0065);
var y = new Number(lat - 0.006);
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
var gcj_lng = z * Math.cos(theta);
var gcj_lat = z * Math.sin(theta);
point.lng = gcj_lng;
point.lat = gcj_lat;
return point;
}
// URL参数 To JSON对象
const query2json = function(query) {
let param = {}; // 存储最终JSON结果对象
query.replace(/([^?&]+)=([^?&]+)/g, function(s, v, k) {
param[v] = decodeURIComponent(k); //解析字符为中文(据业务处理)
return k + '=' + v;
});
return param;
}
// JSON对象 To URL参数
const json2query = function(json) {
let param = []
Object.keys(json).forEach(e => {
param.push(e + '=' + encodeURIComponent(json[e]))
})
return param.join('&')
}
// 深拷贝
function _isArray (arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
function _deepClone(obj) {
// 对常见的“非”值,直接返回原来值
if([null, undefined, NaN, false].includes(obj)) return obj;
if(typeof obj !== "object" && typeof obj !== 'function') {
//原始类型直接返回
return obj;
}
var o = _isArray(obj) ? [] : {};
for(let i in obj) {
if(obj.hasOwnProperty(i)){
o[i] = typeof obj[i] === "object" ? _deepClone(obj[i]) : obj[i];
}
}
return o;
}
// 判断是否存在这四个应用(百度地图、高德地图、腾讯地图、苹果地图),返回对象数组
const mapsExist = function() {
let res = []
if (plus.runtime.isApplicationExist({
pname: MapsInfo.baidu.a_pname,
action: MapsInfo.baidu.i_scheme
})) {
console.log("[已安装百度地图]");
res.push(MapsInfo.baidu)
}
if (plus.runtime.isApplicationExist({
pname: MapsInfo.gaode.a_pname,
action: MapsInfo.gaode.i_scheme
})) {
console.log("[已安装高德地图]");
res.push(MapsInfo.gaode)
}
if (plus.runtime.isApplicationExist({
pname: MapsInfo.tengxun.a_pname,
action: MapsInfo.tengxun.i_scheme
})) {
console.log("[已安装腾讯地图]");
res.push(MapsInfo.tengxun)
}
if (Platform == 'iOS' && plus.runtime.isApplicationExist({
pname: MapsInfo.pingguo.a_pname,
action: MapsInfo.pingguo.i_scheme
})) {
console.log("[已安装系统地图]");
res.push(MapsInfo.pingguo)
}
return res
}
// 仅仅是打开地图应用(不荐)
const openApp = function(map) {
if (Platform == "Android") {
plus.runtime.launchApplication({
pname: map.a_pname,
}, function(e) {
alert("Open system default browser failed: " + e.message);
});
} else if (Platform == "iOS") {
plus.runtime.launchApplication({
action: map.i_scheme
}, function(e) {
alert("Open system default browser failed: " + e.message);
});
} else {
alert("Operating system is not supported");
}
}
// 坐标参数处理
const argHandle = function(point) {
if (!point) {
return DefaultPoint
}
let pot = _deepClone(point)
if (!pot.lat || !pot.lng) {
pot = DefaultPoint
}
if (!pot.lbl) {
pot['lbl'] = '未知位置'
}
if (!pot.dtl) {
pot['dtl'] = '未知地址'
}
return pot
}
// 应用内唤起地图应用,并标注位置,失败则使用浏览器唤起 C2C 对应导航path请查阅api文档
const openByApp = function(map, point) {
return new Promise((resolve) => {
let pot = argHandle(point)
let url = ''
if (map.EN == 'bdmap') {
// 腾讯坐标系转换为百度坐标
let p = gcj2bd(pot.lat, pot.lng)
pot = {
...pot,
...p
}
if (Platform == 'Android') {
url =
`bdapp://map/marker?location=${pot.lat},${pot.lng}&title=${pot.lbl}&content=${pot.dtl}&src=${DefaultService.android}`
} else if (Platform == 'iOS') {
url =
`baidumap://map/marker?location=${pot.lat},${pot.lng}&title=${pot.lbl}&content=${pot.dtl}&src=${DefaultService.ios}`
}
} else if (map.EN == 'amap') {
if (Platform == 'Android') {
url =
`androidamap://viewMap?lat=${pot.lat}&lon=${pot.lng}&poiname=${pot.lbl}&sourceApplication=${DefaultService.android}&dev=0`
} else if (Platform == 'iOS') {
url =
`iosamap://viewMap?lat=${pot.lat}&lon=${pot.lng}&poiname=${pot.lbl}&sourceApplication=${DefaultService.ios}&dev=0`
}
} else if (map.EN == 'qqmap') {
if (Platform == 'Android') {
url =
`qqmap://map/marker?marker=coord:${pot.lat},${pot.lng};title:${pot.lbl};addr:${pot.dtl}&referer=${QQMapKey}`
} else if (Platform == 'iOS') {
url =
`qqmap://map/marker?marker=coord:${pot.lat},${pot.lng};title:${pot.lbl};addr:${pot.dtl}&referer=${QQMapKey}`
}
} else if (map.EN == 'maps') {
if (Platform == 'Android') {
url =
`androidamap://viewMap?lat=${pot.lat}&lon=${pot.lng}&poiname=${pot.lbl}&sourceApplication=${DefaultService.android}&dev=0`
} else if (Platform == 'iOS') {
// Unlike some schemes, map URLs do not start with a “maps” scheme identifier. Instead, map links are specified as regular http links and are opened either in Safari or the Maps app on the target platform.
url = `http://maps.apple.com?ll=${pot.lat},${pot.lng}&q=${pot.lbl}`
}
}
if (url != '') {
plus.runtime.openURL(encodeURI(url), async function(e) {
console.error(e)
let result = await openByBrowser(map, point)
resolve(result)
});
resolve(true)
} else {
console.error('应用内唤起失败')
resolve(false)
}
})
}
// 浏览器唤起地图应用,并标注位置 C2B2C 对应导航path请查阅api文档
const openByBrowser = function(map, point) {
return new Promise((resolve) => {
let pot = argHandle(point)
let url = ''
if (map.EN == 'bdmap') {
// 腾讯坐标系转换为百度坐标
let p = gcj2bd(pot.lat, pot.lng)
pot = {
...pot,
...p
}
url =
`http://api.map.baidu.com/marker?location=${pot.lat},${pot.lng}&title=${pot.lbl}&content=${pot.dtl}&src=${DefaultService.web}&output=html`
} else if (map.EN == 'amap') {
url =
`https://uri.amap.com/marker?position=${pot.lng},${pot.lat}&name=${pot.lbl}&src=${DefaultService.web}&callnative=1`
} else if (map.EN == 'qqmap') {
url =
`https://apis.map.qq.com/uri/v1/marker?marker=coord:${pot.lat},${pot.lng};title:${pot.lbl};addr:${pot.dtl}&referer=${DefaultService.web}`
} else if (map.EN == 'maps') {
url = `http://maps.apple.com?ll=${pot.lat},${pot.lng}&q=${pot.lbl}`
}
if (url != '') {
plus.runtime.openURL(encodeURI(url), function(e) {
console.error(e)
resolve(false)
});
resolve(true)
} else {
console.error('浏览器唤起失败')
resolve(false)
}
})
}
// 地图标注,map指定唤起地图(string,['qqmap','amap','bdmap','maps']之一),point坐标对象(object,DefaultPoint)
const navTo = async function(point, map) {
// test
// let result = openByBrowser(MapsInfo.pingguo, point)
// let result = await openByApp(MapsInfo.pingguo, point)
// console.log('打开结果', result)
// return false
let result = false
let res = mapsExist()
if (res.length > 0) { // 无地图应用
let index = res.findIndex(e => { // 参数有指定地图应用
return e.EN == map
})
if (index != -1) {
result = await openByApp(res[index], point)
} else if (res.findIndex(e => { // 如果有安装默认地图应用,优先使用默认地图Api
return e.EN == DefaultMap.EN
}) != -1) {
result = await openByApp(DefaultMap, point)
} else { // 默认用第一个地图导航
result = await openByApp(res[0], point)
}
} else { // 无地图应用,浏览器打开
let arr = Object.values(MapsInfo)
let index = Object.values(MapsInfo).findIndex(e => { // 参数有指定地图应用
return e.EN == map
})
if (index != -1) {
result = await openByBrowser(arr[index], point)
} else {
result = await openByBrowser(DefaultMap, point)
}
}
return result
}
module.exports = {
navTo
}
一个小前端
我是一个小前端
zs.duan@qq.com
重庆市沙坪坝
我的标签
小程序
harmonyOS
HTML
微信小程序
javaSrcipt
typeSrcipt
vue
uniapp
nodejs
react
防篡改
nginx
mysql
请求加解密
还没有人评论 快来占位置吧