具体思路:向微信公众号发送位置,后台获取经纬度并写入JSON,最后通过高德地图API渲染并制作散点图。
后台获取位置信息
- 先创建一个
citys.json
,并在里面填上一对方括号[]
,否则无法正常打开并写入文件 - 公众号后台完整代码在文末,这里只是获取数据并写入JSON文件的部分。需要注意如果写入的数据含有中文,则
json_decod()
和json_encode()
两个函数都需要加上JSON_UNESCAPED_UNICODE
参数
[collapse title=”获取数据并写入” status=”false”]
$json_string = file_get_contents('citys.json');
$data = json_decode( $json_string, true, JSON_UNESCAPED_UNICODE);
$lnglat = Array($message['Location_Y'], $message['Location_X']);
$arr = Array(
'lnglat' => $lnglat,
'name' => $message['Label'],
'date' => date("Y-m-d")
);
array_push($data, $arr);
file_put_contents( 'citys.json', json_encode($data, JSON_UNESCAPED_UNICODE));
return "发送成功!";
exit();
前端渲染
这里在读取JSON时,由于谷歌浏览器默认不允许用
Ajax
读取客户端本地的文件C:\xxx
,所以本地测试时需要搭建服务器或配置Chrome启动参数--allow-file-access-from-files
这里使用Python开启HTTP服务
python -m http.server 3000 # 3000是端口号,可以自定义
然后准备一个
citys.json
文件,里面随便写点数据。数据来源:高德地图 - 全国市县位置[
{"lnglat":[104.065735,30.659462],"name":"成都市","date":"1970-01-01"},
{"lnglat":[103.823557,36.058039],"name":"兰州市","date":"1970-01-01"},
{"lnglat":[106.713478,26.578343],"name":"贵阳市","date":"1970-01-01"},
{"lnglat":[102.712251,25.040609],"name":"昆明市","date":"1970-01-01"},
{"lnglat":[91.132212,29.660361],"name":"拉萨市","date":"1970-01-01"},
{"lnglat":[108.948024,34.263161],"name":"西安市","date":"1970-01-01"},
{"lnglat":[114.502461,38.045474],"name":"石家庄市","date":"1970-01-01"},
{"lnglat":[117.190182,39.125596],"name":"天津市","date":"1970-01-01"},
{"lnglat":[116.405285,39.904989],"name":"北京市","date":"1970-01-01"}
]
创建
index.html
文件,新建一个div
标签并引入2个script
,其中Key
可以在高德开放平台申请获得<div id="map" class="container"></div>
<script src="https://webapi.amap.com/maps?&v=1.4.15&key=[Your_Key]"></script>
<script src="https://webapi.amap.com/loca?&v=1.3.2&key=[Your_Key]"></script>
然后就是读取
JSON
文件部分。先用XMLHttpRequest
对象进行读取本地JSON文件,再用JSON.parse()
解析
[collapse title=”读取本地JSON” status=”false”]
<script>
// 读取JSON
var data = new Array();
var request = new XMLHttpRequest();
request.open("get", "citys.json");
request.send();
request.onload = function () {
if (request.status == 200) { // 返回状态为200,即为数据获取成功
var citys = JSON.parse(request.responseText);
for(index in citys){
data.push(citys[index]);
}
console.log(citys);
}
</script>
[/collapse]
- 需要注意的是,使用
JSON.parse()
时返回给citys
的时候,每一行数据前面增加了一个下标。因此需要遍历citys
并将其中的数据存储到data
数组
[collapse title=”点击打开” status=”false”]
# 原本的数据格式
[
{"lnglat":[104.065735,30.659462],"name":"成都市","date":"1970-01-01"},
{"lnglat":[103.823557,36.058039],"name":"兰州市","date":"1970-01-01"},
{"lnglat":[106.713478,26.578343],"name":"贵阳市","date":"1970-01-01"},
{"lnglat":[102.712251,25.040609],"name":"昆明市","date":"1970-01-01"},
{"lnglat":[91.132212,29.660361],"name":"拉萨市","date":"1970-01-01"},
{"lnglat":[108.948024,34.263161],"name":"西安市","date":"1970-01-01"},
{"lnglat":[114.502461,38.045474],"name":"石家庄市","date":"1970-01-01"},
{"lnglat":[117.190182,39.125596],"name":"天津市","date":"1970-01-01"},
{"lnglat":[116.405285,39.904989],"name":"北京市","date":"1970-01-01"}
]
# JSON.parse()返回的数据格式
[
0: {lnglat: Array(2), name: "成都市", "date":"1970-01-01"}
1: {lnglat: Array(2), name: "兰州市", "date":"1970-01-01"}
2: {lnglat: Array(2), name: "贵阳市", "date":"1970-01-01"}
3: {lnglat: Array(2), name: "昆明市", "date":"1970-01-01"}
4: {lnglat: Array(2), name: "拉萨市", "date":"1970-01-01"}
5: {lnglat: Array(2), name: "西安市", "date":"1970-01-01"}
6: {lnglat: Array(2), name: "石家庄市", "date":"1970-01-01"}
7: {lnglat: Array(2), name: "天津市", "date":"1970-01-01"}
8: {lnglat: Array(2), name: "北京市", "date":"1970-01-01"}
]
[/collapse]
- 最后进行数据处理并渲染,参考快速上手
[collapse title=”点击打开” status=”false”]
// 创建地图
var map = new AMap.Map('map', {
mapStyle: 'amap://styles/grey', // 地图样式
zoom: 6, // 缩放等级
center: [107.4976,32.1697] // 中心
});
var layer = new Loca.ScatterPointLayer({
map: map
});
// 传入数据
layer.setData(data, {
lnglat: 'lnglat' // 指定坐标数据的来源
});
// 配置样式
layer.setOptions({
unit: 'px',
style: {
radius: 5, // 圆形半径(px)
color: '#b7eff7', // 填充颜色
borderWidth: 0.5, // 边框宽度
borderColor: '#ffffff' // 边框颜色
}
});
// 渲染
layer.render();
完整代码
- 前端渲染:
index.html
[collapse title=”前端渲染” status=”false”]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Map</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<style>
html,body,.container {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map" class="container"></div>
<script src="https://webapi.amap.com/maps?&v=1.4.15&key=[Your_Key]"></script>
<script src="https://webapi.amap.com/loca?&v=1.3.2&key=[Your_Key]"></script>
<script>
// 读取JSON
var data = new Array();
var request = new XMLHttpRequest();
request.open("get", "citys.json");
request.send();
request.onload = function () {
if (request.status == 200) { // 返回状态为200,即为数据获取成功
var citys = JSON.parse(request.responseText);
for(index in citys){
data.push(citys[index]);
}
}
// 创建地图
var map = new AMap.Map('map', {
mapStyle: 'amap://styles/grey', // 地图样式
zoom: 4.5, // 缩放等级
center: [105.4976,35.1697] // 中心
});
var layer = new Loca.ScatterPointLayer({
map: map
});
// 传入数据
layer.setData(data, {
lnglat: 'lnglat' // 指定坐标数据的来源
});
// 配置样式
layer.setOptions({
unit: 'px',
style: {
radius: 5, // 圆形半径(px)
color: '#b7eff7', // 填充颜色
borderWidth: 0.5, // 边框宽度
borderColor: '#ffffff' // 边框颜色
}
});
// 渲染
layer.render();
}
</script>
</body>
</html>
[/collapse]
- 公众号后台
index.php
。每个公众号使用的语言和配置都不同,关键是可以获取到数据并写入JSON文件中。这里仅作参考
[hide]
<?php
require __DIR__.'/vendor/autoload.php';
use EasyWeChat\Factory;
$config = [
'app_id' => '[Your_app_id]',
'secret' => '[Your_secret]',
'token' => '[Your_token]',
'aes_key' => '[Your_aes_key]',
'response_type' => 'array'
];
$app = Factory::officialAccount($config);
$app->server->push(function ($message) {
if (!empty($message)) {
switch ($message['MsgType']) {
case "location":
$json_string = file_get_contents('citys.json');
$data = json_decode( $json_string, true, JSON_UNESCAPED_UNICODE);
$lnglat = Array($message['Location_Y'], $message['Location_X']);
$arr = Array(
'lnglat' => $lnglat,
'name' => $message['Label'],
'date' => date("Y-m-d")
);
array_push($data, $arr);
file_put_contents( 'citys.json', json_encode($data, JSON_UNESCAPED_UNICODE));
return "发送成功!";
exit();
default:
$content = $message['Event']=="subscribe" ? "欢迎关注!" : "不支持的消息类型";
return $content;
exit();
}
}
else {
return "else";
}
});
$response = $app->server->serve();
$response->send(); // 将响应输出
[/hide]
- 相关文件:请前往博客共享网盘下载