最近接到一个需求,在微信小程序中展现一个地图,并且实现点击对应省份跳转到省份地图的效果。参阅了很多网络上的教程,感觉都不是很清晰,于是就把我的实现路径记录下来,保证重复可用。
接上篇:echarts在微信小程序绘制中国地图,并实现点击跳转省地图功能(一) - 掘金 (juejin.cn)
上篇文章在微信小程序中实现了地图。
其实按照上篇文章流程将全国地图换为各省份地图再加上我们在原地图绑定的点击跳转事件就能完成这个任务。
但是,因为微信小程序体量限制(不允许超过2M),而全部省份的地图文件就已经超过2G了。所以按照原来的方式将地图文件放入小程序的路就被堵死了。
1. 小程序内通过request获取文件
因为我们的地图文件也是通过一个接口:https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json访问得到的,但是如果你在小程序中通过request方法想要获取这个接口的内容就会报错403 forbidden。
var url = 'https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json'
wx.request({
url: url,
header: {
"content-type": "application/json;charset=UTF-8"
},
method: 'GET',
success: function (res) {
console.log(res.data);
},
fail: function () {
console.log(res.data);
},
后来,我尝试了加入不同的header;增加域名白名单;本地设置取消域名校验等方案都不能成功时,我就尝试去看看前人的智慧,结果真让我找到了根本原因。
参考这篇博客,我了解到一个小程序相当于一个封闭的网络环境,其中的的js中是不允许访问外网的,你只能用下载好的包,云存储中的内容。
如果想要请求外网内容,也可以,得通过一个官方中介:云函数。
2. 云函数访问接口
以上博客中已经介绍了如何通过云函数来实现的内容。具体实现路径如下:
新建个云函数:
// 云函数入口文件
const cloud = require('wx-server-sdk')
var rp = require('request-promise');
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
let url = "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json"
return await rp(url)
.then(function (res){
return res
})
.catch(function(err){
return err
})
}
通过访问云函数来获取地图文件内容:
wx.cloud.callFunction({
// 云函数名称
name: 'reqGeoJson',
data:{
adcode:options.adcode
},
// 传给云函数的参数
success: function(res) {
geoJson = res.result
geoJson = JSON.parse(geoJson)
// console.log(geoJson)
},
fail: function(res) {
console.log(res);
}
})
3. 云存储方案
同理,我们也可以通过云存储来实现。毕竟阿里云的接口容易崩,把内容持久化存储,然后访问存储的方式更加保险。
以上内容为python中下载各个省份地图文件的爬虫,代码比较简单,最后将下载好的文件传入云存储自行访问即可。
需要特别注意的是,台湾省(71)地图文件下载容易失败,建议手动访问,然后把内容复制进去。
4. 本地尝试实现
如果你只想要实现这个内容,做一个demo的话,那就不用管2M的限制,直接把所有地图文件放入小程序目录中。
以下就是mapSub.js的全部内容,wxml,wxss,json文件与全国地图部分完全一致,直接照抄就行。
吐槽一句:因为微信小程序不支持
eval设置动态变量,害得我得引入这么多文件。一点都不优雅
因为全国地图点击事件传入的省份的中文名字,而在option时需要省份的拼音,同样的获取对应省份的地图文件需要省份代码,所以还需要省份对拼音、对省代码的映射文件。
需要引入的两个js文件如下:
1. provinceIDMap.js
export default {
"新疆":"65",
"西藏":"54",
"内蒙古":"15",
"青海":"63",
"四川":"51",
"黑龙江":"23",
"甘肃":"62",
"云南":"53",
"广西":"45",
"湖南":"43",
"陕西":"61",
"广东":"44",
"吉林":"22",
"河北":"13",
"湖北":"42",
"贵州":"52",
"山东":"37",
"江西":"36",
"河南":"41",
"辽宁":"21",
"山西":"14",
"安徽":"34",
"福建":"35",
"浙江":"33",
"江苏":"32",
"重庆":"50",
"宁夏":"64",
"海南":"46",
"台湾":"71",
"北京":"11",
"天津":"12",
"上海":"31",
"香港":"81",
"澳门":"82"
}
2. provinceNameMap.js
export default{
'安徽': 'anhui',
'澳门': 'aomen',
'北京': 'beijing',
'重庆': 'chongqing',
'福建': 'fujian',
'甘肃': 'gansu',
'广东': 'guangdong',
'广西': 'guangxi',
'海南': 'hainan',
'河北': 'hebei',
'黑龙江': 'heilongjiang',
'河南': 'henan',
'湖北': 'hubei',
'湖南': 'hunan',
'江苏': 'jiangsu',
'江西': 'jiangxi',
'辽宁': 'liaoning',
'内蒙古': 'neimenggu',
'宁夏': 'ningxia',
'青海': 'qinghai',
'山东': 'shandong',
'山西': 'shanxi',
'四川': 'sichuan',
'台湾': 'taiwan',
'天津': 'tianjing',
'香港': 'xianggang',
'新疆': 'xinjiang',
'西藏': 'xizang',
'云南': 'yunnan',
'浙江': 'zhejiang',
'上海': 'shanghai',
'陕西': 'shanxi'
}