大二下学期第一次结对作业(第一阶段:地图下钻)

今日主要完成了地图下钻的功能:

对于地图下钻前几天在网上找到过资源,可以实现下钻,但是当时知识将代码粘了过来,并没有理解代码的逻辑,所以导致无法插入数据。

今日将代码重头到尾理解了一番,实现了数据的插入,首先要代码需要引入高德地图api,要到官网上申请key。

地图下钻:https://www.makeapie.com/editor.html?c=xz3jGj90ns   https://juejin.cn/post/6844903982377205768#heading-7

需要引入的内容:

<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key="></script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=&plugin=AMap.DistrictSearch"></script>
<script src="https://webapi.amap.com/ui/1.0/main.js"></script>
<script src="https://cdn.bootcss.com/PapaParse/4.1.2/papaparse.min.js"></script>
    <script>
        $('<div class="back">返回</div>').appendTo(
            $('#chart-panel')
        );

        $('.back').css({
            'position': 'absolute',
            'left': '17px',
            'top': '25px',
            'color': 'rgb(222,222,222)',
            'font-size': '15px',
            'cursor': 'pointer',
            'z-index': '100'
        })

        $('.back').click(function() {
            if (parentInfo.length === 1) {
                return;
            }
            parentInfo.pop()
            getGeoJson(parentInfo[parentInfo.length - 1].code)
        })
        var parentJson = null
        var parentInfo = [{
            cityName: '全国',
            level: 'china',
            code: 100000
        }]
        var parent
        getGeoJson(100000)

        /**
         *  利用高德api获取行政区边界geoJson
         *   adcode 行政区code 编号
         **/

        //此版本不再维护,准备在写另一个新版本

        function getGeoJson(adcode) {
            AMapUI.loadUI(['geo/DistrictExplorer'], DistrictExplorer => {
                var districtExplorer = new DistrictExplorer()
                districtExplorer.loadAreaNode(adcode, function(error, areaNode) {
                    if (error) {
                        console.error(error);
                        return;
                    }
                    parent = areaNode;
                    let Json = areaNode.getSubFeatures()
                    if (Json.length > 0) {
                        parentJson = Json
                    } else if (Json.length === 0) {
                        Json = parentJson.filter(item => {
                            if (item.properties.adcode == adcode) {
                                return item
                            }
                        })
                        if (Json.length === 0) return
                    }
                    //去获取数据
                    getMapData(Json)
                });
            })
        }

        //获取数据,这里我们用随机数模拟数据

        function getMapData(Json) {
            /*
            let mapData = [{
                    name: '广东省',
                    value: 1000,
                    cityCode: 440000,
                    value2:200
                }, {
                    name: '湖南省',
                    value: 2000,
                    cityCode: 430000
                }]*/
            /*
                全国:100000
                北京:110000
                天津:120000
                河北:130000
                山西:140000
                内蒙古:150000
                辽宁:210000
                吉林:220000
                黑龙江:230000
                上海:310000
                江苏:320000
                浙江:330000
                安徽:340000
                福建:350000
                江西:360000
                山东:370000
                河南:410000
                湖北:420000
                湖南:430000
                广东:440000
                广西:450000
                海南:460000
                重庆:500000
                四川:510000
                贵州:520000
                云南:530000
                西藏:540000
                陕西:610000
                甘肃:620000
                青海:630000
                宁夏:640000
                新疆:650000
                台湾:710000
                香港:810000
                澳门:820000
            */
            var mapData
            $.ajax({
                url:"/c2",
                data: {name: parent.getName() },
                success: function (data) {
                    mapData=data.data;
                    let pointData = Json.map(item => {
                        return ({
                            name: item.properties.name,
                            value: ['118.83531246', '32.0267395887', Math.random() * 1000],
                            cityCode: item.properties.adcode
                        })
                    })
                    let mapJson = {}
                    //geoJson必须这种格式
                    mapJson.features = Json
                    //去渲染echarts
                    initEcharts(mapData, pointData, mapJson)
                },
                error: function (xhr, type, errorThrown) {
                }
            })
            /*
             mapData = Json.map(item => {
                return ({
                    name: item.properties.name,
                    value: Math.random() * 100,
                    level: item.properties.level,
                    cityCode: item.properties.adcode
                })
            })*/
        }
        var myChart = echarts.init(document.querySelector(".map .chart"));
        function initEcharts(mapData, pointData, mapJson) {
            //注册
            echarts.registerMap('Map', mapJson);

            //这里加true是为了让地图重新绘制,不然如果你有筛选的时候地图会飞出去
            myChart.setOption({

                borderColor: "rgba(0, 0, 0, 0.5)",
                // tooltip: {
                //     trigger: "item",
                //     formatter: p => {
                //         let val = p.value;
                //         if (window.isNaN(val)) {
                //             val = 0;
                //         }
                //         let txtCon =
                //             "<div style='text-align:center'>" + p.name + ":<br />台量:" + val.toFixed(2) + '</div>';
                //         return txtCon;
                //     }
                // },
                tooltip: {
                    formatter: function(params, ticket, callback) {
                        return params.data.name + "<br />" + "累计确诊" + ":" + params.data.value +
                            "<br />" + "累计治愈" + ":" + params.data.heal + "<br />" + "累计死亡" + ":" + params.data.dead + "<br />" + "疑似病例:" + 0
                    }
                },
                toolbox: {
                    feature: {
                        dataView: {
                            show: false,
                            readOnly: true
                        },
                        magicType: {
                            show: false,
                            type: ["line", "bar"]
                        },
                        restore: {
                            show: false
                        },
                        saveAsImage: {
                            show: true,
                            name: parentInfo[parentInfo.length - 1].cityName + "地图",
                            pixelRatio: 2
                        }
                    },
                    iconStyle: {
                        normal: {
                            borderColor: "#41A7DE"
                        }
                    },
                    itemSize: 15,
                    top: 20,
                    right: 22
                },
                visualMap: {
                    left: 26,
                    bottom: 30,
                    showLabel: !0,
                    text: ["高", "低"],
                    textStyle: {
                        fontSize: 12,
                        color: "#fff"
                    },
                    pieces: [{
                        max: 100,
                        label: '<100',
                        color: '#ffd768'
                    }, {
                        min: 100,
                        max: 1000,
                        label: '100-1000',
                        color: '#ff8c71'
                    }, {
                        min: 1000,
                        max: 10000,
                        label: '1000-10000',
                        color: '#ff5428'
                    }, {
                        min: 10000,
                        label: '>10000',
                        color: '#7f1100'
                    }, ],
                    color: '#fff',
                    textStyle: {
                        color: '#fff',
                    },
                    show: !0
                },

                series: [{
                    name: "地图",
                    type: "map",
                    map: "Map",
                    roam: true, //是否可缩放
                    zoom: 1.1, //缩放比例
                    top: 120,
                    data: mapData,
                    itemStyle: {
                        normal: {
                            show: true,
                            areaColor: '#2E98CA',
                            borderColor: "rgba(0, 0, 0, 0.5)",
                            borderWidth: '1',
                        },
                    },
                    label: {

                        normal: {
                            show: true, //显示省份标签
                            textStyle: {
                                color: "rgb(249, 249, 249)", //省份标签字体颜色
                                fontSize: 12
                            },
                            formatter: p => {
                                let val = p.value;
                                if (window.isNaN(val)) {
                                    val = 0;
                                }
                                //
                                switch (p.name) {
                                    case '内蒙古自治区':
                                        p.name = "内蒙古"
                                        break;
                                    case '西藏自治区':
                                        p.name = "西藏"
                                        break;
                                    case '新疆维吾尔自治区':
                                        p.name = "新疆"
                                        break;
                                    case '宁夏回族自治区':
                                        p.name = "宁夏"
                                        break;
                                    case '广西壮族自治区':
                                        p.name = "广西"
                                        break;
                                    case '香港特别行政区':
                                        p.name = "香港"
                                        break;
                                    case '澳门特别行政区':
                                        p.name = "澳门"
                                        break;
                                    default:
                                        // code
                                }
                                if (p.name === "内蒙古自治区") {
                                    p.name = "内蒙古";
                                }
                                let txtCon =
                                    p.name;
                                return txtCon;
                            }
                        },
                        emphasis: {
                            //对应的鼠标悬浮效果
                            show: true,
                            textStyle: {
                                color: "#000"
                            }
                        }
                    }
                }, {
                    name: '散点',
                    type: 'effectScatter',
                    coordinateSystem: 'geo',
                    rippleEffect: {
                        brushType: 'fill'
                    },
                    itemStyle: {
                        normal: {
                            borderColor: "rgba(0, 0, 0, 0.5)"
                        }
                    },
                    data: pointData,
                    symbolSize: 8,
                    showEffectOn: 'render', //加载完毕显示特效
                }, ]

            }, true)

            //点击前解绑,防止点击事件触发多次
            myChart.off('click');
            myChart.on('click', echartsMapClick);

            window.addEventListener("resize", function() {
                myChart.resize();
            });
        }

        //echarts点击事件

        function echartsMapClick(params) {
            //如果当前是最后一级,那就直接return
            if (parentInfo[parentInfo.length - 1].code == params.data.cityCode) {
                return
            }
            let data = params.data
            parentInfo.push({
                cityName: data.name,
                level: data.level,
                code: data.cityCode
            })
            getGeoJson(data.cityCode)

        }
    </script>
    <script>

1.首先代码开头定义了一个返回按钮以及点击事件,比较容易理解。

2.然后是getGeoJson(100000)这是获取地图边界geoJson,就是说要通过这个画地图,这里面的参数就是当前地图的code。

所以一开始定义了一个“全国” 里面的code是100000,所以会返回各省的code,这样一开始进入网页就会绘制全国地图。注意这

里的code是一一对应的,可到高德地图官网查看。代码中的注释里我已经给出了各个省的code。

3.接着就是获取数据,只需要修改mapdata即可,用ajax请求返回数据。这就遇到了一个问题,如何获取数据,根据什么我能确

定我需要各省的还是一个省中各个市的数据。

我们先不看绘制地图部分的代码,最后有一个地图点击事件,这里其实是获取了你当前点击的省的的名字和code,这样将code

传入getGeoJson就可以获取这个省份的地图,然后返回各市区的code。

这样又有一个问题,在getMapData(Json)函数中我们只有了各个市区的信息,并没办法确定这是那个省,我们通过省份查取数

据库要比通过市方便许多。所以在getGeoJson中我设置了一个parent,这样就可以获取市之上省的名字。

4.传数据,只要修改mapdata,但是不能随便修改,要注意一定要有name与value以及cityCode属性,且name要与高德地图上的

名字相符,而且citycode也要一一对应正确。

5.接着就是最后的渲染地图的部分利用echarts渲染,没有太大问题。

不过因为是爬取的腾讯疫情的信息,里面的各省的地区数据不全,而且名字也会因为个别字不一样导致对应不上。对于省份,我们

还可以一一修改,但是对于每个省的市区,我们无法一一修改,而且因为修改情况太多所以没办法修改,导致有的地区没有数据。

下面给出数据库查询以及服务层的函数:

@app.route('/c2')
def get_c2_data():
    name=request.values.get("name")
    res=[]
    if(name=="全国"):
        res=[]
        for tup in utils.get_c2_data():
            res.append({"name": addname(tup[0]), "value": int(tup[1]),"cityCode":getcode(tup[0]),"heal": int(tup[2]),"dead": int(tup[3])})
    else:
        res=[]
        for tup in utils.get_city_data(delname(name)):
            res.append({"name":addcityname(tup[0]),"value":int(tup[1]),"heal": int(tup[2]),"dead": int(tup[3])})
    print(res)
    return jsonify({"data":res})
def addname(name):
    list=["北京","天津","上海","重庆"]
    list2=["内蒙古","西藏"]
    list3=["香港","澳门"]
    list4=["河北","山西","辽宁","吉林","黑龙江","江苏","浙江","安徽","福建","江西",
           "山东","河南","湖北","湖南","广东","海南","四川","贵州","云南",
           "陕西","甘肃","青海","台湾"]
    if(name in list):
        return name+""
    if(name in list2):
        return name+"自治区"
    if(name=="新疆"):
        return "新疆维吾尔自治区"
    if(name=="宁夏"):
        return "宁夏回族自治区"
    if(name=="广西"):
        return "广西壮族自治区"
    if(name in list3):
        return name+"特别行政区"
    if(name in list4):
        return name+""

def delname(name):
    list=["北京市","天津市","上海市","重庆市"]
    list2=["内蒙古自治区","西藏自治区","新疆维吾尔自治区","宁夏回族自治区","广西壮族自治区"]
    list3=["香港特别行政区","澳门特别行政区"]
    list4=["河北省","山西省","辽宁省","吉林省","黑龙江省","江苏省","浙江省","安徽省","福建省","江西省",
           "山东省","河南省","湖北省","湖南省","广东省","海南省","四川省","贵州省","云南省",
           "陕西省","甘肃省","青海省","台湾省"]
    if(name in list):
        return name[0:len(name)-1]
    if(name in list2):
        return name[0:len(name)-3]
    if(name in list3):
        return name[0:len(name)-5]
    if(name in list4):
        return name[0:len(name)-1]

def getcode(name):
    if(name=="全国"):
        return 100000
    if(name=="北京"):
        return 110000
    if(name=="天津"):
        return 120000
    if(name=="河北"):
        return 130000
    if(name=="山西"):
        return 140000
    if(name=="内蒙古"):
        return 150000
    if(name=="辽宁"):
        return 210000
    if(name=="吉林"):
        return 220000
    if(name=="黑龙江"):
        return 230000
    if(name=="上海"):
        return 310000
    if(name=="江苏"):
        return 320000
    if(name=="浙江"):
        return 330000
    if(name=="安徽"):
        return 340000
    if(name=="福建"):
        return 350000
    if(name=="江西"):
        return 360000
    if(name=="山东"):
        return 370000
    if(name=="河南"):
        return 410000
    if(name=="湖北"):
        return 420000
    if(name=="湖南"):
        return 430000
    if(name=="广东"):
        return 440000
    if(name=="广西"):
        return 450000
    if(name=="海南"):
        return 460000
    if(name=="重庆"):
        return 500000
    if(name=="四川"):
        return 510000
    if(name=="贵州"):
        return 520000
    if(name=="云南"):
        return 530000
    if(name=="西藏"):
        return 540000
    if(name=="陕西"):
        return 610000
    if(name=="甘肃"):
        return 620000
    if(name=="青海"):
        return 630000
    if(name=="宁夏"):
        return 640000
    if(name=="新疆"):
        return 650000
    if(name=="台湾"):
        return 710000
    if(name=="香港"):
        return 810000
    if(name=="澳门"):
        return 820000

def addcityname(name):
    if(name[len(name)-1]==''):
        return name
    if(name[len(name)-1]==''):
        return name
    return name+""
def get_city_data(name):
    sql='select city ,confirm ,heal ,dead from details '\
        'where update_time=(select update_time from details order by update_time desc limit 1) '\
        'and province='+'"'+name+'"'+' and city not in ("境外输入","地区待确认") '
    res=query(sql)
    print(res)
    return res
def get_c2_data():
    """
    :return:  返回各省数据
    """
    # 因为会更新多次数据,取时间戳最新的那组数据
    sql = "select province,sum(confirm),sum(heal),sum(dead) from details " \
          "where update_time=(select update_time from details " \
          "order by update_time desc limit 1) " \
          "group by province"
    res = query(sql)
    print(res)
    return res

数据库结构:

 

posted @ 2021-03-17 10:50  风吹过半夏  阅读(63)  评论(0编辑  收藏  举报