具体思路:向微信公众号发送位置,后台获取经纬度并写入JSON,最后通过高德地图API渲染并制作散点图。

后台获取位置信息

  • 先创建一个citys.json,并在里面填上一对方括号[],否则无法正常打开并写入文件
  • 公众号后台完整代码在文末,这里只是获取数据并写入JSON文件的部分。需要注意如果写入的数据含有中文,则json_decod()json_encode()两个函数都需要加上JSON_UNESCAPED_UNICODE参数

[collapse title=”获取数据并写入” status=”false”]

  1. $json_string = file_get_contents('citys.json');
  2. $data = json_decode( $json_string, true, JSON_UNESCAPED_UNICODE);
  3. $lnglat = Array($message['Location_Y'], $message['Location_X']);
  4. $arr = Array(
  5. 'lnglat' => $lnglat,
  6. 'name' => $message['Label'],
  7. 'date' => date("Y-m-d")
  8. );
  9. array_push($data, $arr);
  10. file_put_contents( 'citys.json', json_encode($data, JSON_UNESCAPED_UNICODE));
  11. return "发送成功!";
  12. exit();

[/collapse]

前端渲染

这里在读取JSON时,由于谷歌浏览器默认不允许用Ajax读取客户端本地的文件C:\xxx,所以本地测试时需要搭建服务器或配置Chrome启动参数--allow-file-access-from-files

  • 这里使用Python开启HTTP服务

    1. python -m http.server 3000 # 3000是端口号,可以自定义
  • 然后准备一个citys.json文件,里面随便写点数据。数据来源:高德地图 - 全国市县位置

    1. [
    2. {"lnglat":[104.065735,30.659462],"name":"成都市","date":"1970-01-01"},
    3. {"lnglat":[103.823557,36.058039],"name":"兰州市","date":"1970-01-01"},
    4. {"lnglat":[106.713478,26.578343],"name":"贵阳市","date":"1970-01-01"},
    5. {"lnglat":[102.712251,25.040609],"name":"昆明市","date":"1970-01-01"},
    6. {"lnglat":[91.132212,29.660361],"name":"拉萨市","date":"1970-01-01"},
    7. {"lnglat":[108.948024,34.263161],"name":"西安市","date":"1970-01-01"},
    8. {"lnglat":[114.502461,38.045474],"name":"石家庄市","date":"1970-01-01"},
    9. {"lnglat":[117.190182,39.125596],"name":"天津市","date":"1970-01-01"},
    10. {"lnglat":[116.405285,39.904989],"name":"北京市","date":"1970-01-01"}
    11. ]
  • 创建index.html文件,新建一个div标签并引入2个script,其中Key可以在高德开放平台申请获得

    1. <div id="map" class="container"></div>
    2. <script src="https://webapi.amap.com/maps?&v=1.4.15&key=[Your_Key]"></script>
    3. <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”]

  1. <script>
  2. // 读取JSON
  3. var data = new Array();
  4. var request = new XMLHttpRequest();
  5. request.open("get", "citys.json");
  6. request.send();
  7. request.onload = function () {
  8. if (request.status == 200) { // 返回状态为200,即为数据获取成功
  9. var citys = JSON.parse(request.responseText);
  10. for(index in citys){
  11. data.push(citys[index]);
  12. }
  13. console.log(citys);
  14. }
  15. </script>

[/collapse]

  • 需要注意的是,使用JSON.parse()时返回给citys的时候,每一行数据前面增加了一个下标。因此需要遍历citys并将其中的数据存储到data数组

[collapse title=”点击打开” status=”false”]

  1. # 原本的数据格式
  2. [
  3. {"lnglat":[104.065735,30.659462],"name":"成都市","date":"1970-01-01"},
  4. {"lnglat":[103.823557,36.058039],"name":"兰州市","date":"1970-01-01"},
  5. {"lnglat":[106.713478,26.578343],"name":"贵阳市","date":"1970-01-01"},
  6. {"lnglat":[102.712251,25.040609],"name":"昆明市","date":"1970-01-01"},
  7. {"lnglat":[91.132212,29.660361],"name":"拉萨市","date":"1970-01-01"},
  8. {"lnglat":[108.948024,34.263161],"name":"西安市","date":"1970-01-01"},
  9. {"lnglat":[114.502461,38.045474],"name":"石家庄市","date":"1970-01-01"},
  10. {"lnglat":[117.190182,39.125596],"name":"天津市","date":"1970-01-01"},
  11. {"lnglat":[116.405285,39.904989],"name":"北京市","date":"1970-01-01"}
  12. ]
  13. # JSON.parse()返回的数据格式
  14. [
  15. 0: {lnglat: Array(2), name: "成都市", "date":"1970-01-01"}
  16. 1: {lnglat: Array(2), name: "兰州市", "date":"1970-01-01"}
  17. 2: {lnglat: Array(2), name: "贵阳市", "date":"1970-01-01"}
  18. 3: {lnglat: Array(2), name: "昆明市", "date":"1970-01-01"}
  19. 4: {lnglat: Array(2), name: "拉萨市", "date":"1970-01-01"}
  20. 5: {lnglat: Array(2), name: "西安市", "date":"1970-01-01"}
  21. 6: {lnglat: Array(2), name: "石家庄市", "date":"1970-01-01"}
  22. 7: {lnglat: Array(2), name: "天津市", "date":"1970-01-01"}
  23. 8: {lnglat: Array(2), name: "北京市", "date":"1970-01-01"}
  24. ]

[/collapse]

[collapse title=”点击打开” status=”false”]

  1. // 创建地图
  2. var map = new AMap.Map('map', {
  3. mapStyle: 'amap://styles/grey', // 地图样式
  4. zoom: 6, // 缩放等级
  5. center: [107.4976,32.1697] // 中心
  6. });
  7. var layer = new Loca.ScatterPointLayer({
  8. map: map
  9. });
  10. // 传入数据
  11. layer.setData(data, {
  12. lnglat: 'lnglat' // 指定坐标数据的来源
  13. });
  14. // 配置样式
  15. layer.setOptions({
  16. unit: 'px',
  17. style: {
  18. radius: 5, // 圆形半径(px)
  19. color: '#b7eff7', // 填充颜色
  20. borderWidth: 0.5, // 边框宽度
  21. borderColor: '#ffffff' // 边框颜色
  22. }
  23. });
  24. // 渲染
  25. layer.render();

[/collapse]

完整代码

  • 前端渲染:index.html

[collapse title=”前端渲染” status=”false”]

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Map</title>
  6. <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
  7. <style>
  8. html,body,.container {
  9. margin: 0;
  10. padding: 0;
  11. width: 100%;
  12. height: 100%;
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <div id="map" class="container"></div>
  18. <script src="https://webapi.amap.com/maps?&v=1.4.15&key=[Your_Key]"></script>
  19. <script src="https://webapi.amap.com/loca?&v=1.3.2&key=[Your_Key]"></script>
  20. <script>
  21. // 读取JSON
  22. var data = new Array();
  23. var request = new XMLHttpRequest();
  24. request.open("get", "citys.json");
  25. request.send();
  26. request.onload = function () {
  27. if (request.status == 200) { // 返回状态为200,即为数据获取成功
  28. var citys = JSON.parse(request.responseText);
  29. for(index in citys){
  30. data.push(citys[index]);
  31. }
  32. }
  33. // 创建地图
  34. var map = new AMap.Map('map', {
  35. mapStyle: 'amap://styles/grey', // 地图样式
  36. zoom: 4.5, // 缩放等级
  37. center: [105.4976,35.1697] // 中心
  38. });
  39. var layer = new Loca.ScatterPointLayer({
  40. map: map
  41. });
  42. // 传入数据
  43. layer.setData(data, {
  44. lnglat: 'lnglat' // 指定坐标数据的来源
  45. });
  46. // 配置样式
  47. layer.setOptions({
  48. unit: 'px',
  49. style: {
  50. radius: 5, // 圆形半径(px)
  51. color: '#b7eff7', // 填充颜色
  52. borderWidth: 0.5, // 边框宽度
  53. borderColor: '#ffffff' // 边框颜色
  54. }
  55. });
  56. // 渲染
  57. layer.render();
  58. }
  59. </script>
  60. </body>
  61. </html>

[/collapse]

  • 公众号后台index.php。每个公众号使用的语言和配置都不同,关键是可以获取到数据并写入JSON文件中。这里仅作参考

[hide]

  1. <?php
  2. require __DIR__.'/vendor/autoload.php';
  3. use EasyWeChat\Factory;
  4. $config = [
  5. 'app_id' => '[Your_app_id]',
  6. 'secret' => '[Your_secret]',
  7. 'token' => '[Your_token]',
  8. 'aes_key' => '[Your_aes_key]',
  9. 'response_type' => 'array'
  10. ];
  11. $app = Factory::officialAccount($config);
  12. $app->server->push(function ($message) {
  13. if (!empty($message)) {
  14. switch ($message['MsgType']) {
  15. case "location":
  16. $json_string = file_get_contents('citys.json');
  17. $data = json_decode( $json_string, true, JSON_UNESCAPED_UNICODE);
  18. $lnglat = Array($message['Location_Y'], $message['Location_X']);
  19. $arr = Array(
  20. 'lnglat' => $lnglat,
  21. 'name' => $message['Label'],
  22. 'date' => date("Y-m-d")
  23. );
  24. array_push($data, $arr);
  25. file_put_contents( 'citys.json', json_encode($data, JSON_UNESCAPED_UNICODE));
  26. return "发送成功!";
  27. exit();
  28. default:
  29. $content = $message['Event']=="subscribe" ? "欢迎关注!" : "不支持的消息类型";
  30. return $content;
  31. exit();
  32. }
  33. }
  34. else {
  35. return "else";
  36. }
  37. });
  38. $response = $app->server->serve();
  39. $response->send(); // 将响应输出

[/hide]

  • 相关文件:请前往博客共享网盘下载