深圳ncov肺炎疫情分布点高德地图显示

一、简介
如题,通过深圳市政府数据开放平台查询到的疫情分布点地址数据,批量请求高德API,将查询到坐标显示到网页地图上,先上效果(挺愕然的,本主自己的住处附近就有好几个点),如下:
在这里插入图片描述
二、实现工具:
(1)开发语言:python、javascript
(2)开发环境:python3.6
(3)开发工具:pcharm

三、实现方法:
1.阅读相关API(重点)
此处放链接,方便查阅:
(1)深圳市政府数据开放平台确诊患者曾逗留过的场所名单数据接口API:
<调用API需要注册、新建应用获取appKey,参考API调用指南↓>
https://opendata.sz.gov.cn/data/api/toApiDetails/29200_01503669
(2)高德地图Web服务API:
<调用需要注册、新建应用后获取apikey>
https://lbs.amap.com/api/webservice/summary/
2.使用django框架编写脚本请求上面的API,将地址和坐标返回前端
3.前端JS处理坐标数据,调用高德地图回显

四、实现步骤
1、编写python脚本调用API
(1)调用深圳市政府数据开放平台API
通过浏览器调试可以看到请求头,请求参数、请求地址、返回数据
在这里插入图片描述
python模拟请求代码实现(可以不加headers):

    # 查询数据量
    rows = '175'
    req_url = 'https://opendata.sz.gov.cn/data/catalog/selectDataCatalogByResId'
    data = {'resId': '29200/01503669'}
    res_data = requests.get(url=req_url, params=data)
    res_data = json.loads(res_data.text)
    rows = res_data['recordTotal']  
    # API地址
    url = "https://opendata.sz.gov.cn/api/29200_01503669/1/service.xhtml"
    page = '1'
    params = {"page": page, "rows": rows, "appKey": "50798b9a560a489e9f111ffa47b9ec29"}

    res = requests.get(url=url, params=params)
    res = json.loads(res.text)
    total = res["total"]
    print("总共:", res["total"])
    pos_list = []
    for x in res["data"]:
        # print(x["xzqh"],x["xqmc"],x["fbsj"])
        pos_list.append(x["xzqh"]+x["xqmc"])

(2)高德地图地理编码API
这里要做一些处理,该API最多支持10个地址进行批量查询,所有要根据地址数量计算次数,每次10个地址
在这里插入图片描述
python根据地址数批量请求地理编码API代码实现:

	apiurl = 'https://restapi.amap.com/v3/geocode/geo'
    apikey = '08892c38dddc0e2e68cb7ac1de2b670b'
    # 计算要查询的次数
    time = 0
    remain = total % 10
    if remain == 0:
        time = int(total/10)
    else:
        time = int(total/10) + 1
    index = 0
    print('查询次数',time)
    location = []
    while index < time:
        req_data = ""
        range = None
        # if len(pos_list) < 10: # 查询长度小于10
        #     range = pos_list[index: len(pos_list) -1]
        if index == time -1: # 最后一次查询
            range = pos_list[index*10: index*10 + remain]
        else: # 第index次查询(index不是最后一次)
            range = pos_list[index*10: index*10 + 10]
        for pos in range:
            req_data = req_data + '|' + pos
        # print(req_data)
        data = {'address': req_data, 'output': 'json', 'key': apikey, 'batch': 'true'}
        req = requests.get(url=apiurl, params=data)
        pos_res = json.loads(req.text)
        for x in pos_res["geocodes"]:
            location.append(x["location"].encode('utf8'))
        index += 1

(3)把脚本搬到django框架,方便前端页面请求,操作方法:
新建工程: python django-admin startproject shenzhen
创建应用: python manage.py startapp ncovMap
生成的目录结构:
在这里插入图片描述
修改配置文件settings.py,在关键位置添加划线部分,如下:
在这里插入图片描述
urls.py添加相关代码如下:

from django.contrib import admin
from django.urls import path
from ncovMap import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('ncovmap/', views.show_map),
] 

(4)添加网页文件
从高德地图JS API示例中 直接扣皮一个下来↓
https://lbs.amap.com/api/javascript-api/example/marker/adaptive-show-multiple-markers放到如下目录(没有目录就新建一个templates):
在这里插入图片描述
配置文件settings.py里引入:
在这里插入图片描述
顺便在配置文件末尾加上:

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

OK,基本配置到这就差不多了,后面修改views.py添加请求内容,再扣皮下来的网页JS部分代码(重点):
views.py(此处的show_map 对应上面urls.py配置的函数):

from django.shortcuts import render
from .shenzhen import *

def show_map(request):
    print('正在处理请求')
    total,pos_list = get_location()
    points = get_map_point(total, pos_list)
    data = {'point': points, 'pos':pos_list}
    return render(request, 'map.html', data)

修改map.html的JS代码如下:

<script type="text/javascript">
    var data = "";
    var pos_data = "";
    var points = [];
    var pos_list = [];
    window.onload=function(){
        console.log('正在请求数据。。。');
        data = '{{ point }}';
        pos_data = '{{ pos }}';
        //console.log(data);
        var str = data.split("&#39;");
        for(var index=0; index<str.length; index++){
            if(str[index].trim()!="," && str[index]!="[b" && str[index]!="]" && str[index].trim()!=", b")
                points.push(str[index]);
        }
        var str = pos_data.split("&#39;");
        for(var index=0; index<str.length; index++){
            if(str[index].trim()!="," && str[index]!="[b" && str[index]!="[" && str[index]!="]" && str[index].trim()!=", b")
                pos_list.push(str[index]);
        }
        console.log("请求完毕,获取的数据量为:"+points.length);
        for(var i=0; i<points.length; i++){
               console.log(i,points[i]);
         }
        console.log(pos_list);

    var map = new AMap.Map('container', {
        resizeEnable: true,
        center: [114.215567,22.684234],
        zoom: 13,
        viewMode: '3D',
        pitch: 60,

    });

    map.clearMap();  // 清除地图覆盖物
    var markers = [];
    var index = 1;
    points.forEach(function(point) {
        var pos = [];
        if(index == 1){
            var origin = {
                icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-1.png',
                position:[114.215567,22.684234] //这里可以替换成高德地理编码API查询到的自己的坐标
            };
            markers.push(origin);
            index = 0;
        }
        pos.push(point.split(",")[0]);
        pos.push(point.split(",")[1]);
        var obj = {'position': pos };
        markers.push(obj);
    });

    var infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});
    // 添加一些分布不均的点到地图上,地图上添加三个点标记,作为参照
    var count = 0;
    var pos_index = 0;
       // for(var i=0;i<markers.length;i++){
       //     console.log(markers[i]);
       // }
    markers.forEach(function(marker) {
        if(count==0){
           // var markerContent = '' +
           // '<div class="custom-content-marker">' +
           // '   <img src="//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png">' +
           // '</div>';
            mark = new AMap.Marker({
                map: map,
                icon: '{% static 'img/dir-via-marker.png' %}',
               // content: markerContent,
                position: [marker.position[0], marker.position[1]],
                // 以 icon 的 [center bottom] 为原点
                offset: new AMap.Pixel(-13, -30)
            });

            // 设置label标签
            // label默认蓝框白底左上角显示,样式className为:amap-marker-label
            mark.setLabel({
                offset: new AMap.Pixel(20, 20),  //设置文本标注偏移量
                content: "<div class='info'>我的狗窝(2020)</div>", //设置文本标注内容
                direction: 'right' //设置文本标注方位
            });

            // 设置点标记的动画效果,此处为弹跳效果
            mark.setAnimation('AMAP_ANIMATION_BOUNCE');
            count =1;
        }else{ //第一个点不是,后面都是else
             mark =new AMap.Marker({
                map: map,
                icon: '{% static 'img/red2.png' %}',
                position: [marker.position[0], marker.position[1]],
                offset: new AMap.Pixel(-13, -30)
            });

            mark.content = '<h3>'+pos_list[pos_index]+'</h3>';
            mark.content += '<div>经度:'+marker.position[0]+'</div>';
            mark.content += '<div>纬度:'+marker.position[1]+'</div>';

            mark.on('mouseover', infoOpen);
            //注释后打开地图时默认关闭信息窗体
            //marker.emit('mouseover', {target: marker});
            mark.on('mouseout', infoClose);
            mark.on('click', newMAp);

            pos_index += 1;
        }
    });

    //鼠标点击事件,设置地图中心点及放大显示级别
	function newMAp(e) {
		//map.setCenter(e.target.getPosition());
		map.setZoomAndCenter(15, e.target.getPosition());

		var infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});
		infoWindow.setContent(e.target.content);
		infoWindow.open(map, e.target.getPosition());
	}

	function infoClose(e) {
		infoWindow.close(map, e.target.getPosition());
	}

    function infoOpen(e) {
        infoWindow.setContent(e.target.content);
        infoWindow.open(map, e.target.getPosition());
    }

    var center = map.getCenter();
    var centerText = '当前中心点坐标:' + center.getLng() + ',' + center.getLat();
    document.getElementById('centerCoord').innerHTML = centerText;
    document.getElementById('tips').innerHTML = '成功添加'+points.length+'个点标记';

    // 添加事件监听, 使地图自适应显示到合适的范围
    AMap.event.addDomListener(document.getElementById('setFitView'), 'click', function() {
        var newCenter = map.setFitView();
        document.getElementById('centerCoord').innerHTML = '当前中心点坐标:' + newCenter.getCenter();
        document.getElementById('tips').innerHTML = '通过setFitView,地图自适应显示到合适的范围内,点标记已全部显示在视野中!';
    });
    }

</script>

最后运行: python manage.py runserver 0.0.0.0:8000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值