地图渲染

步骤:

  1. 通过 DataV.GeoAtlas地理小工具系列 网站获取到数据
  2. registerMap注册地图
  3. 初始化图表
  4. 配置echarts地理坐标系组件, 配置要渲染的数据
示意图 示意图
效果图
效果图
tooltip内容自定义
tooltip内容自定义

核心代码如下,更多代码详细见仓库: https://gitee.com/whongli/map

import * as echarts from 'echarts'
import {httpGet} from '@/js/api/baseApi'
var chinaMap

export default {
  methods: {
    async init ({url, option}) {
      let res = await httpGet(url) // 获取地图数据
      let chinaJson = res
      echarts.registerMap('china', chinaJson)
      chinaMap = echarts.init(document.getElementById('china-map'))
      chinaMap.setOption(option)
      chinaMap.on('click', async (params) => {
        console.log(params)
        this.$router.push(`/province?name=${params.name}`)
      })
    },
    async provinceInit ({url, option}) {
      let res = await httpGet(url)
      let chinaJson = res
      echarts.registerMap('china', chinaJson)
      chinaMap = echarts.init(document.getElementById('china-map'))
      chinaMap.setOption(option)
      chinaMap.on('click', async (params) => {
        console.log(params)
        // TODO: 省市点击回调
      })
    },
    /**
     * 地图配置
     * @param {*} series {data,title,zoom, tooltip, center}
     * @returns 返回配置信息
     */
    constructorOption (series) {
      return {
        backgroundColor: '#fff',
        // 地图上圆点的提示
        tooltip: {
          trigger: 'item',
          formatter: function (params) {
            console.log(params)
            return params.name + ' : ' + params.value[2]
          }
        },
        // 图例按钮 点击可选择哪些不显示
        legend: {
          orient: 'vertical',
          left: 'left',
          top: 'bottom',
          data: [],
          textStyle: {
            color: '#fff'
          }
        },
        // 地理坐标系组件
        geo: {
          map: 'china',
          zoom: series.zoom || 1.25, // 设置初始化的缩放比例
          roam: false, // true 允许缩放拖动
          center: series.center || [104.123557, 32.058039],
          label: {
            // true hover时地图内部会显示城市名
            emphasis: {
              show: false
            }
          },
          tooltip: series.tooltip || {
            show: true,
            trigger: 'item',
            formatter: function (params) {
              console.log(params)
              let html = `<div class="m-tooltip-wrap">
              <p>地区: ${params.name} </p>
              <p>人口:<span class="m-text-red">46万</span>(人) ${params.name} </p>
              <p>旅游人数:<span class="m-text-red">6万</span>(人) ${params.name} </p>
              </div>`
              return html
            }
          },
          itemStyle: {
            // 地图背景色
            normal: {
              areaColor: '#fff',
              borderColor: '#747569'
            },
            // 悬浮时
            emphasis: {
              areaColor: '#c82a29',
              borderColor: '#c82a29'
            }
          },
          regions: [{ // 省份颜色与界线颜色的修改,如果想修改多个省份就在后面多添加几个对象即可.
            // name: '广东', // 对应的是import './china'  数据中的名称如: name: '广东'
            // itemStyle: {
            //   normal: {
            //     borderColor: '#c82a29', // 省份界线颜色
            //     borderWidth: 1 // 省份界线的宽度
            //   }
            // }
          }]
        },
        // 系列列表
        series: [
          {
            name: series.name,
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: series.data, // 从方法中传进来
            symbolSize: 8, // 点的大小
            symbol: 'circle',
            label: {
              normal: {
                show: false
              },
              emphasis: {
                show: false
              }
            },
            // 涟漪特效相关配置
            rippleEffect: {
              color: '#c82a29',
              period: 4,
              scale: 2,
              brushType: 'fill', // stroke | fill
              number: 2
            },
            showEffectOn: 'render',
            itemStyle: {
              normal: {
                color: {
                  type: 'radial',
                  colorStops: [
                    {
                      offset: 1,
                      color: '#c82a29'
                    }
                  ],
                  global: false // 缺省为 false
                }
              }
            }
          }
        ]
      }
    }
  }
}

  1. 直接下载的地图数据文件比较大,可做压缩处理,控制台执行 node minify-map-data.js,压缩代码参考 echart源码-encode.js
// minify-map-data.js
var fs = require('fs');
var glob = require('glob');

glob('static/map-data/*.json', {}, function (err, files) {
  files.forEach(function (file) {
    // 这里有做修改
    var output = file.replace('map-data', 'minify-map');
    var rawStr = fs.readFileSync(file, 'utf8');
    var json = JSON.parse(rawStr);
    // Meta tag
    json.UTF8Encoding = true;
    var features = json.features;
    if (!features) {
      return;
    }
    features.forEach(function (feature) {
      var encodeOffsets = feature.geometry.encodeOffsets = [];
      var coordinates = feature.geometry.coordinates;
      if (feature.geometry.type === 'Polygon') {
        coordinates.forEach(function (coordinate, idx) {
          coordinates[idx] = encodePolygon(
            coordinate, encodeOffsets[idx] = []
          );
        });
      } else if (feature.geometry.type === 'MultiPolygon') {
        coordinates.forEach(function (polygon, idx1) {
          encodeOffsets[idx1] = [];
          polygon.forEach(function (coordinate, idx2) {
            coordinates[idx1][idx2] = encodePolygon(
              coordinate, encodeOffsets[idx1][idx2] = []
            );
          });
        });
      }
    });
    // 这里有做修改
    fs.writeFileSync(
      output, JSON.stringify(json), 'utf8'
    );
  });
});

function encodePolygon(coordinate, encodeOffsets) {
  var result = '';

  var prevX = quantize(coordinate[0][0]);
  var prevY = quantize(coordinate[0][1]);
  // Store the origin offset
  encodeOffsets[0] = prevX;
  encodeOffsets[1] = prevY;

  for (var i = 0; i < coordinate.length; i++) {
    var point = coordinate[i];
    result += encode(point[0], prevX);
    result += encode(point[1], prevY);

    prevX = quantize(point[0]);
    prevY = quantize(point[1]);
  }

  return result;
}
// 这个方法我没用
function addAMDWrapper(jsonStr) {
  return ['define(function() {',
    '    return ' + jsonStr + ';',
    '});'].join('\n');
}

function encode(val, prev) {
  // Quantization
  val = quantize(val);
  // var tmp = val;
  // Delta
  val = val - prev;

  if (((val << 1) ^ (val >> 15)) + 64 === 8232) {
    //WTF, 8232 will get syntax error in js code
    val--;
  }
  // ZigZag
  val = (val << 1) ^ (val >> 15);
  // add offset and get unicode
  return String.fromCharCode(val + 64);
  // var tmp = {'tmp' : str};
  // try{
  //     eval("(" + JSON.stringify(tmp) + ")");
  // }catch(e) {
  //     console.log(val + 64);
  // }
}

function quantize(val) {
  return Math.ceil(val * 1024);
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容