spring结合Echarts实现中国地图大区、省、市、区/县的穿透

前言

目前Echarts官网有很多关于省市区3级穿透的案例,但是很少有区域、省、市、区4级穿透的案例,本案例采用SpringMVC结合JSP、Echarts、本地化地图JSON完成(本地json可替换成高德地区获取区划的API)


提示:以下是本篇文章正文内容,下面案例可供参考

一、Echarts是什么?

一个基于 JavaScript 的开源可视化图表库,
官网https://echarts.apache.org/
案例库网址:https://www.makeapie.com/explore.html

二、实现效果

1.初始化地图展示

在这里插入图片描述

2.钻取

区域–>省份
在这里插入图片描述

省份–>市
在这里插入图片描述

三、实现步骤

1.引入JS库

代码如下(示例):

<script type="text/javascript" src="/echarts/echarts.min.js"></script>

2.初始化HTML标签、存放Echarts图

代码如下(示例):

<div style="width: 100%;height:100%" id="Map"></div>

注意需要设置ID值,方便后续进行配置文件注册,需要设置宽高,不然会显示空白。


3.初始化配置文件

var mapOption = {
        layoutCenter: ['60%', '65%'],//控制地图左边,上边的位置
        layoutSize: "70%",//控制地图的大小
        tooltip: { //格式化提示
            trigger: "item",
            formatter: function (p) {
                let val = p.value;
                if (!val) {
                    val = 0;
                }
                let txtCon = p.name + ":" + val.toFixed(2);
                return txtCon;
            }
        },
        title: {
            show: true,
            left: "center",
            top: "15",
            text: currentArea+currentTab,
            textStyle: {//标题样式控制
                color: "rgb(255,255,255)",
                fontSize: 20
            }
        },
        visualMap: {//刻度
            min: 1,
            max: 1,
            left: "1%",
            bottom:"3%",
            showLabel: !0,
            pieces:[],
            textStyle: {
                color: "#24CFF4"
            },
            show: !0
        },
        series: [{
            name: "地图",
            type: "map",//显示的类型
            map: "china",//显示地图为中国地图
            roam: true, //是否可缩放
            zoom: 1, //缩放比例
            data: [],//地图数据
            label: {
                normal: {
                    show: true,
                    color: "#000000", //省份标签字体颜色
                    fontSize: 16,
                    // fontWeight: 'bold',
                    areaStyle: {
                        color: '#ffffff',//默认的地图板块颜色
                    },
                    formatter: function (p) {//格式化显示各个省份名称,主要是为了不要显示的太长
                        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:
                                break;
                        }
                        return p.name;
                    }
                },
                emphasis: {
                    show: true,
                    color: "#000000"
                }
            },
            itemStyle: {//地图边界线样式
                normal: {
                    // areaColor: "#24CFF4",
                    borderColor: "#fea8a6",
                    // borderWidth: 1.3,
                    shadowBlur: 1,
                    shadowColor: "#fffdfe",
                    // shadowOffsetX: 7,
                    // shadowOffsetY: 6
                },
                emphasis: {
                    areaColor: "#8dd7fc",
                    borderWidth: 1.6,
                    shadowBlur: 25
                }
            }
        }]
    };

配置文件可参考官网,里面的数据需要通过JS动态加载

3.获取地图数据

//热力图

//初始化方法,100000为全国地图编码
getMapJson(100000);
/**
* adcodes: 区域编码数组:各区域存放的省份编码,如华南区域
* isArea: 是否不钻取数据,true:不钻取 false:钻取
**/
function getMapJson(adcodes,cityCode,isArea) {
 var that = this;
  city_code = cityCode.toString();

  let mapData = [];
  //不钻取数据,只匹配数据
  if (isArea) {
  //获取本地地图JSON
      $.get('/echarts/json/china.json',function(ret) {
          //全国省份数据
          var areaJson = [];
          mapData = ret.features;
          for (let i = 0; i < adcodes.length; i++) {
              for (let j = 0; j < mapData.length; j++) {
                  //不允许用全等于,后端id为字符串
                  if (adcodes[i] == mapData[j].properties.adcode) {
                      areaJson.push(mapData[j]);
                  }
              }
          }
          that.geoJson.features = areaJson;
          area_pri_city_type = "PROVINCE";
          //获取子集展示数据
          that.getMapData();
      });
      //钻取数据
  } else {
      var type = "";

      if(adcodes.length === 1){
          let code = adcodes.toString();
          $.get('/echarts/json/province/'+code+'.json',function(res) {
              mapData = res.features;
              //只钻取数据到市级,如果是直辖市,则不往下钻取,需要钻取区县的可以把这个去掉
              if (adcodes[0] != "110000" && adcodes[0] != "120000" && adcodes[0] != "310000" && adcodes[0] != "500000" && mapData.length > 0 && mapData[0].properties.level === "district") {
                  return;
              }
              //无地图数据
              if (mapData.length === 0) {
                  return;
              }
              switch (mapData[0].properties.level) {
                  case "province":
                      area_pri_city_type = "AREA";
                      type = "AREA";
                      break;
                  // case "city":
                  default:
                      area_pri_city_type = "CITY";
                      type = "CITY";
                      break;
                  // default:
                  //     type = "COUNTY"
              }
              //判断是否有子集数据
              if (mapData.length > 0) {
                  that.geoJson.features = mapData;
              } else if (mapData.length === 0) {
                  that.geoJson.features = [];
                  if (that.geoJson.features.length === 0) return;
              }
              //获取子集展示数据
              that.getMapData();
          });
      }

  }

}
//关于地图省份合并参考这位大佬的文章,更改而来
//文章地址:https://blog.csdn.net/weixin_33743661/article/details/93469931?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-8.baidujs&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-8.baidujs
//获取数据
function getMapData() {
   //省市区使用getMapData获取数据
   //地图、柱状图数据
   if (this.parentInfo.length === 1 && is_init) {
   		//后台封装的区域及下级省份的名称,编码数据
   		//数据格式:
   		//var params = {
		//		names: [//把各个大区的省份用二维数组分开
		//			['北京','天津','河北','山西','内蒙古'],
		//			["黑龙江","吉林","辽宁"],
		//			['山东','江苏','安徽','江西','浙江','福建','上海','台湾'],
		//			['河南','湖北','湖南'],
		//			['广东','广西','海南','香港','澳门'],
		//			['重庆','四川','云南','西藏','贵州'],
		//			['陕西','甘肃','青海','宁夏','新疆']
		//		],
		//		properties: {//自定义大区的名字,要和上面的大区省份一一对应
		//			name: ['华北','东北','华东','华中','华南','西南','西北'],
		//			cp: [//经纬度可以自己随意定义
		//				[116.24,39.54],
		//				[126.32,43.50],
		//				[121.28,31.13],
		//				[114.20,30.32],
		//				[113.15,23.08],
		//				[104.04,30.39],
		//				[103.49,36.03]
		//			]
		//		}
		//	};

       var mapPriAreaDataList = '${mapPriAreaDataList}';
       // var jsonData = $.parseJSON(mapPriAreaDataList);
       data = eval(mapPriAreaDataList);
       var params = {
           names:[],//省份名称
           adcode:[],//大区编码
           properties:{
               name:[],//大区名称
               cp:[],//经纬度,中文显示的位置
               cityCode:[]//省份获取市区编码
           }
       };
       data.forEach(function(item,index){
           params.names[index] = item.childName;
           params.adcode[index] = item.value;
           params.properties.name[index] = item.name;
           params.properties.cp[index] = item.description;
           params.properties.cityCode[index] = item.childValue;
       });
       //合并省份图层
       mergeProvinces(this.geoJson, params.names, params.properties, params.adcode);
       is_init = false;
   }
   //获取时间
   let dateTime = $("#fillDateTime").val();
   //获取组织
   let orgId = $("#jqCodeId").val();
   //查询后台地图数据
   $.getJSON("示例路径?code="+city_code+"&type="+area_pri_city_type+"&dateTime="+dateTime+"&orgId="+orgId, function (res) {
       // console.log(res,1);
       haltMapData = res;
       //循环地图数据
       //格式化数据,显示新签合同额
       var echartsData = formatData(res,indicatorType);
       //注册初始化地图
       initEcharts(echartsData.mapData,echartsData.projectBarData,echartsData.areaBarData);

       //更新8大指标数据


   });
}

4.合并省份图层

 //合并大区,主要是根据格式化的地图省份编码,合并边界线
function mergeProvinces(chinaJson, names, properties,adcodes) {
    //合并大区里省份的coordinates
    var features = chinaJson.features;
    var polygons = [];
    var polygons2 = [];
    for (var i = 0; i < names.length; i++) {
        var polygonsCoordinates = [];
        var polygonsEncodeOffsets = [];
        for (var z = 0; z < names[i].length; z++) {
            for (var j = 0; j < features.length; j++) {
                if (features[j].properties.name === names[i][z]) {
                    if (features[j].geometry.coordinates[0].constructor === String) {
                        //合并coordinates
                        for (var l = 0; l < features[j].geometry.coordinates.length; l++) {
                            polygonsCoordinates.push(features[j].geometry.coordinates[l]);
                        }
                    } else if (
                        features[j].geometry.coordinates[0].constructor === Array
                    ) {
                        for (var k = 0; k < features[j].geometry.coordinates.length; k++) {
                            for (var d = 0; d < features[j].geometry.coordinates[k].length; d++) {
                                polygonsCoordinates.push(
                                    features[j].geometry.coordinates[k][d]
                                );
                            }
                        }
                    }

                    console.log(features[j].geometry.encodeOffsets,features[j]);
                     if(features[j].geometry.encodeOffsets[0].constructor == String){//合并encodeOffsets
                     	polygonsEncodeOffsets.push(features[j].geometry.encodeOffsets);
                     }else if(features[j].geometry.encodeOffsets[0].constructor == Array){
                    	for(var k=0;k<features[j].geometry.encodeOffsets.length;k++){
                     		if(features[j].geometry.encodeOffsets[k][0].constructor == Array){
                    			for(var e=0;e<features[j].geometry.encodeOffsets[k].length;e++){
                    				polygonsEncodeOffsets.push(features[j].geometry.encodeOffsets[k][e]);
                    			}
                   		}else{
                   			polygonsEncodeOffsets.push(features[j].geometry.encodeOffsets[k]);
                    		}
                    	}
                    }

                    break;
                }
            }
        }
        polygons.push(polygonsCoordinates);
        polygons2.push(polygonsEncodeOffsets);
    }

    // 构建新的合并区域
    var features = [];

    for (var a = 0; a < names.length; a++) {
        var feature = {
            id: features.length.toString(),
            type: "FeatureCollection",
            geometry: {
                type: "Polygon",
                coordinates: polygons[a],
                encodeOffsets: polygons2[a]
            },
            properties: {
                name: properties.name[a] || "",
                childNum: polygons[a].length,
                adcode:adcodes[a] || ""
            }
        };
        if (properties.cp[a]) {
            feature.properties.cp = properties.cp[a];
        }
        // 将新的合并区域添加到地图中
        features.push(feature);
    }
    
    this.geoJson.features = features;
}

5.注册地图

function initEcharts(mapData,projectBarData,areaBarData) {
		//获取标签
		this.myChart = echarts.init(document.getElementById("Map"));
		//这里是切换地图,china标识全国地图,map标签区域地图(区域、省、市级、区县)
		if (this.parentInfo.length === 1) {
		    echarts.registerMap('china', this.geoJson); //注册
		     mapOption.series[0].map = "china";
		} else {
		     echarts.registerMap('Map', this.geoJson); //注册
		     mapOption.series[0].map = "Map";
		}
		//这里是获取后台地图展示的数据,如果只是看地图,这块可注释
		var min = mapData.length > 0 ?mapData[mapData.length-1].value:0;;
		var max = mapData.length > 0 ?mapData[0].value:0;
		//设置地图刻度颜色方法
		setAreaColor(max,min);
		//判断目前展示的是区域还是全国地图,调整地图中心点和大小
		if(area_pri_city_type !== "AREA"){
		   mapOption.layoutCenter = ["50%","50%"];
		   mapOption.layoutSize = "100%";
		}else{
		   mapOption.layoutCenter = ["60%","65%"];
		   mapOption.layoutSize = "70%";
		}
		//设置地图数据和标题
		mapOption.visualMap.min = min;
		mapOption.visualMap.max = Math.ceil(max / 5) * 5;
		mapOption.visualMap.pieces = piecesArray;
		mapOption.series[0].data = mapData;
		mapOption.title.text = currentArea+currentTab;
		// mapOption.toolbox.feature.saveAsImage.name = currentArea+currentTab;
		//注册地图
		this.myChart.setOption(mapOption,true);
		// //点击前解绑,防止点击事件触发多次
		this.myChart.off('click');
		//地图点击实现,点击传入编码和名称,进行钻取
		this.myChart.on('click', this.echartsMapClick);
}

6.实现地图点击向下钻取

//点击下钻
 function echartsMapClick(params) {

     if (!params.data) {
         return
     }
     //省份CODE数组
     let isArea = true;
     let data = Object.assign({},params.data);
     //后台获取各个区域对应的省份编码数组
     var mapPriAreaDataList = '${mapPriAreaDataList}';
     priAreaData = eval(mapPriAreaDataList);
     
     let areaData = priAreaData.filter(function(item ) {
         return item.name === data.name;
     });
     //点击的的区域是名称能匹配上,则编码为这个区域的省份编码,进行匹配显示,否则直接钻取,省-->市-->区县
     if(areaData[0] != null){
         data.cityCode = areaData[0].childValue;
     }else{
         isArea = false;
     }
     parentInfo.push({
         cityName: data.name,
         code: data.cityCode ? data.cityCode : 0
     });
     //增加导航路径,可进行切换
     setBreadcrumb(isArea,data.cityCode,params);
     //获取子集地域,点击继续获取数据,刷新地图
     getGeoJson(isArea ? data.cityCode : [data.cityCode],params.data.cityCode, isArea);

 }
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值