echarts世界地图

<!-- 世界地图页面 -->
<template>
  <div class="map-wrap">
    <div class="world-map-wrap">
      <div class="left-container">
        <div class="worldMap" ref="worldMap" id="worldMap"></div>

        <div class="status-wrap">
          <div><span class="circle" style="background-color: #c90d0d;"></span><span>网络设备/线路故障</span></div>
          <div><span class="circle" style="background-color: #f3df2c;"></span><span>网络负载高</span></div>
          <div><span class="circle" style="background-color: #3bbd03;"></span><span>正常</span></div>
          <div><span class="circle" style="background-color: #7d7d7d;"></span><span>未添加设备</span></div>
        </div>

        <div ref="tooltip" class="tooltip" v-show="showTooltip" :style="{left: `${tooltipData.x}px`,top: `${tooltipData.y}px`}">
          <div class="site">
            <span>{{tooltipData.siteName}}</span>
            <el-popconfirm title="确定删除?" @onConfirm="deleteSite()">
              <i slot="reference" class="el-icon-delete delbtn" style="font-size: 12px;" title="删除站点"></i>
            </el-popconfirm>
          </div>
          <div class="machine" v-for="(item, index) in tooltipData.machines" :key="index">
            <span class="circle" :style="{'background-color': item.color}"></span>
            <span>{{item.comment}}</span>:<span style="font-size: 13px;">{{item.endpoint}}</span>
            <el-popconfirm title="确定删除?" @onConfirm="deleteMachine(item, index)">
              <i slot="reference" class="el-icon-delete delbtn" title="删除设备"></i>
            </el-popconfirm>
            <i class="el-icon-setting delbtn" title="设为主设备" @click="setMainMachine(item)"></i>
          </div>
        </div>

        <div ref="tooltipHidden" class="tooltip" :style="{left: '-10000px',top: '0'}">
          <div class="site">
            <span>{{tooltipData.siteName}}</span>
            <el-popconfirm title="确定删除?" @onConfirm="deleteSite()">
              <i slot="reference" class="el-icon-delete delbtn" style="font-size: 12px;" title="删除站点"></i>
            </el-popconfirm>
          </div>
          <div class="machine" v-for="(item, index) in tooltipData.machines" :key="index">
            <span class="circle" :style="{'background-color': item.color}"></span>
            <span>{{item.comment}}</span>:<span style="font-size: 13px;">{{item.endpoint}}</span>
            <el-popconfirm title="确定删除?" @onConfirm="deleteMachine(item, index)">
              <i slot="reference" class="el-icon-delete delbtn" title="删除设备"></i>
            </el-popconfirm>
            <i class="el-icon-setting delbtn" title="设为主设备" @click="setMainMachine(item)"></i>
          </div>
        </div>

        <div ref="lineTooltip" class="tooltip" v-if="showLineTooltip" :style="{left: `${lineTooltipData.x}px`,top: `${lineTooltipData.y}px`}">
          <div class="site">
            从<span>{{lineTooltipData.cityFrom}}</span>到<span>{{lineTooltipData.cityTo}}</span>
            <el-popconfirm title="确定删除?" @onConfirm="deleteLine(lineTooltipData)">
              <i slot="reference" class="el-icon-delete delbtn" style="font-size: 12px;" title="删除连线"></i>
            </el-popconfirm>
          </div>
        </div>
      </div>
      <div class="right-container">
        <div class="site-wrap">
          <el-form :model="siteForm" :rules="siteRules" ref="siteForm" label-suffix=":" label-position="center" label-width="80px">
            <el-form-item label="站点" prop="siteId">
              <el-select v-model="siteForm.siteId" filterable placeholder="请选择" size="small">
                <el-option
                  v-for="(item, index) in siteList"
                  :key="index"
                  :label="item.siteNm"
                  :value="item.siteId"
                  @click.native="selectSite()">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="设备" prop="endpointId">
              <el-select v-model="siteForm.endpointId" filterable placeholder="请选择" size="small">
                <el-option
                  v-for="(item, index) in deviceList"
                  :key="index"
                  :label="item.endpoint"
                  :value="item.id"
                  @click.native="selectDevice()">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="指标" prop="metric">
              <el-select v-model="siteForm.metric" filterable placeholder="请选择" size="small">
                <el-option
                  v-for="(item, index) in metricList"
                  :key="index"
                  :label="item"
                  :value="item">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="备注" prop="comment">
              <el-input class="input-self" v-model="siteForm.comment" placeholder="请输入备注" size="small"></el-input>
            </el-form-item>
            <el-form-item label="带宽(M)" prop="bandwidth" class="error-self">
              <el-input class="input-self" v-model="siteForm.bandwidth" @keyup.native="siteForm.bandwidth=siteForm.bandwidth.replace(/^(0+)|[^\d]+/g,'')" placeholder="请输入整数" size="small"></el-input>
            </el-form-item>
            <el-form-item label="负载(%)" prop="loadPercent">
              <el-input class="input-self" v-model="siteForm.loadPercent" @keyup.native="siteForm.loadPercent=siteForm.loadPercent.replace(/^(0+)|[^\d]+/g,'')" placeholder="请输入整数" size="small"></el-input>
            </el-form-item>
          </el-form>
          <el-row>
            <el-button type="primary" size="small" @click="addMachine('siteForm')">确定</el-button>
          </el-row>
        </div>

        <div class="line-wrap">
          <el-form :model="interConnect" :rules="lineRules" ref="lineForm" label-suffix=":" label-position="center" label-width="80px">
            <el-form-item label="站点从" prop="siteFrom">
              <el-select v-model="interConnect.siteFrom" filterable placeholder="请选择" size="small">
                <el-option
                  v-for="(item, index) in siteList"
                  :key="index"
                  :label="item.siteNm"
                  :value="item.siteId"
                  @click.native="selectSiteFrom(item)">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="站点至" prop="siteTo">
              <el-select v-model="interConnect.siteTo" filterable placeholder="请选择" size="small">
                <el-option
                  v-for="(item, index) in siteList"
                  :key="index"
                  :label="item.siteNm"
                  :value="item.siteId"
                  @click.native="selectSiteTo(item)">
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
          <el-row>
            <el-button type="primary" size="small" @click="saveLine('lineForm')">确定</el-button>
          </el-row>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import echarts from "echarts";
  import "echarts/map/js/world.js";
  import nameMap from "./nameMap";
  import worldMapApi from '@/api/worldMap';
  export default {
    name: "worldMap",
    data() {
      return {
        geoCoordMap: {},
        showTooltip: false,
        tooltipHtml: '',
        tooltipData: {},
        showLineTooltip: false,
        lineTooltipData: {},
        lineData: [],
        siteList: [],
        deviceList: [],
        metricList: [],
        siteForm: {
          siteId: '',
          endpointId: '',
          metric: '',
          comment: '',
          bandwidth: '',
          loadPercent: ''
        },
        siteRules: {
          siteId: [
            { required: true, message: '请选择站点', trigger: 'change' }
          ],
          endpointId: [
            { required: true, message: '请选择设备', trigger: 'change' }
          ],
          metric: [
            { required: true, message: '请选择指标', trigger: 'change' }
          ],
          comment: [
            { required: true, message: '请输入备注', trigger: 'blur' }
          ],
          bandwidth: [
            { required: true, message: '请输入带宽', trigger:'blur'}
          ],
          loadPercent: [
            { required: true, message: '请输入负载', trigger: 'blur' }
          ]
        },
        interConnect: {
          enpointFrom: "",
          enpointFromNm: "",
          enpointTo: "",
          enpointToNm: "",
          siteFrom: "",
          siteFromNm: "",
          siteTo: "",
          siteToNm: ""
        },
        lineRules: {
          siteFrom: [
            { required: true, message: '请选择站点从', trigger: 'change' }
          ],
          enpointFrom: [
            { required: true, message: '请选择设备', trigger: 'change' }
          ],
          siteTo: [
            { required: true, message: '请选择站点至', trigger: 'change' }
          ],
          enpointTo: [
            { required: true, message: '请选择设备', trigger: 'change' }
          ]
        }
      }
    },
    created() {
      // 解决字符串模板@click无效的问题
      // window.deleteSite = this.deleteSite;
      // window.deleteMachine = this.deleteMachine;
    },
    mounted() {
      this.$refs.worldMap.style.height = (window.innerHeight - 140) + "px";

      this.init();

      this.dataInterval = setInterval(() => {
        this.init();
      }, 60000);
    },
    destroyed() {
      clearInterval(this.dataInterval);
    },
    methods: {
      init() {
        this.getSiteList();
        this.getNetDeviceList();
        this.getMetricList();
        this.getMapData();
      },
      async getMapData() {
        // 地图站点数据
        let mapData = await worldMapApi.list();
        if (mapData.code === 200) {
          this.geoCoordMap = Object.fromEntries(mapData.data.map(item => {
            item.geoCoordMap['siteId'] = item.siteId;
            return [item.name, item.geoCoordMap]
          }));
          // console.log('this.geoCoordMap', this.geoCoordMap)
        }

        // 站点链路数据
        let lineData = await worldMapApi.siteLink();
        if (lineData.code === 200) {
          this.lineData = lineData.data.map(item => [{name: item['siteFromNm']}, {name: item['siteToNm']}]);
          // console.log('this.lineData', this.lineData)
        }

        this.map(this.geoCoordMap, this.lineData);
      },
      /**
       * 全球地图生成方法
       * @param geoCoordMap 坐标点数据
       * @param lineData 连线数据
       */
      map(geoCoordMap, lineData) {
        let geoCoords = [];
        let geoRegions = [];
        for (let k in geoCoordMap) {
          let name = k;
          if(geoCoordMap[k] && geoCoordMap[k].machines[0] && geoCoordMap[k].machines[0].pingTime) {
            name = k + "(" + parseInt(geoCoordMap[k].machines[0].pingTime).toFixed(2) + "ms)";
          };
          geoCoords.push({
            name: name,
            value: geoCoordMap[k].coordinatesArr,
            status: geoCoordMap[k].status
          });
          geoRegions.push({
            name: geoCoordMap[k].country,
            selected: true,
            itemStyle: {
              emphasis: {
                areaColor: '#3e6e8b'
              }
            }
          })
        }

        // 获取地图中起点和终点的坐标,以数组形式保存下来
        let convertData = function (data) {
          let res = [];
          for (let i = 0; i < data.length; i++) {
            let dataItem = data[i];
            let fromCoord = geoCoordMap[dataItem[0].name];
            let toCoord = geoCoordMap[dataItem[1].name];
            if (fromCoord && toCoord) {
              res.push([{
                coord: fromCoord.coordinatesArr, // 起点坐标
                siteFrom: fromCoord.siteId,
                cityFrom: fromCoord.city
              }, {
                coord: toCoord.coordinatesArr, // 终点坐标
                siteTo: toCoord.siteId,
                cityTo: toCoord.city
              }])
            }
          }
          return res;
        };

        let series = [];
        let planePath = "arrow";

        /**
         * 图中一共用到三种效果,分别为航线特效图、飞机航线图及城市图标涟漪图。
         * 要用到setOption中的series属性,并且对每个城市都要进行三次设置。
         */
        series.push(
          {
            // 白色航线特效图
            type: "lines",
            zlevel: 1, // 用于分层,z-index的效果
            effect: {
              show: false, // 动效是否显示
              period: 6, // 特效动画时间
              trailLength: 0.7, // 特效尾迹的长度
              color: "#db9982", // 特效颜色
              symbol: planePath,
              // symbolSize: 3 // 特效大小
            },
            lineStyle: {
              normal: { // 正常情况下的线条样式
                color: "#fff",
                opacity: 0.8,
                width: 1.5, // 因为是叠加效果,要是有宽度,线条会变粗,白色航线特效不明显
                curveness: 0 // 线条曲度
              }
            },
            itemStyle: {
              normal: {
                label: {
                  show: true,
                  textStyle: {
                    color: "rgb(249, 249, 249)"
                  }
                }
              }
            },
            data: convertData(lineData) // 特效的起始、终点位置
          },
          // {
          //   // 小飞机航线效果
          //   type: "lines",
          //   zlevel: 2,
          //   // symbol: ['none', 'arrow'],   // 用于设置箭头
          //   // symbolSize: 10,
          //   effect: {
          //     show: false,
          //     period: 6,
          //     trailLength: 0.1,
          //     color: "#db9982",
          //     // symbol: planePath, // 特效形状,可以用其他svg pathdata路径代替
          //     symbolSize: 5
          //   },
          //   lineStyle: {
          //     normal: {
          //       color: "#fff",
          //       width: 0,
          //       opacity: 0.4,
          //       curveness: 0
          //     }
          //   },
          //   data: convertData(lineData) // 特效的起始、终点位置
          // },
          {
            // 散点效果
            type: 'effectScatter',
            coordinateSystem: 'geo',
            zlevel: 2,
            // rippleEffect: {
            //     period: 3,
            //     scale: 6,
            //     brushType: "stroke"
            // },
            label: {
              normal: {
                show: true,
                position: 'right',
                formatter: '{b}',
                color: '#fff',
                fontSize: 10
              }
            },
            symbolSize: 8,
            data: geoCoords.map((dataItem) => {
              let status = dataItem.status;
              let color = '';
              if (status == '0') {
                color = '#3bbd03';
              }
              if (status == '1') {
                color = '#f3df2c';
              }
              if (status == '2') {
                color = '#c90d0d';
              }
              if (status == '4') {
                color = '#7d7d7d';
              }
              return {
                name: dataItem.name,
                // value: geoCoordMap[dataItem.name].coordinatesArr,
                value: geoCoordMap[dataItem.name.split("(")[0]].coordinatesArr,
                visualMap: false,
                itemStyle: {
                  color: color,
                  borderColor: '#fff'
                }
              };
            })
          }
        );

        let myChart = echarts.init(document.getElementById('worldMap'));
        window.addEventListener('resize', function () {
          myChart.resize()
        });
        let self = this;
        myChart.setOption({
          geo: {
            type: 'map',
            map: 'world',
            top: '6%',
            left: '8%',
            right: '8%',
            bottom: '8%',
            roam: true,
            silent: false,
            selectedMode: true,
            label: {
              emphasis: {
                show: true,
                color: '#fff'
              }
            },
            itemStyle: {
              normal: {
                areaColor: '#c9c7c7',
                borderColor: '#000'
              },
              emphasis: {
                areaColor: '#2a333d'
              }
            },
            nameMap: nameMap,
            regions: geoRegions
          },
          tooltip: {
            show: false,
            trigger: 'item',
            triggerOn: 'mousemove',
            enterable: true,//鼠标是否可进入提示框浮层中
            // formatter:formatterHover,//修改鼠标悬停显示的内容
            backgroundColor: 'transparent',
            formatter: function (params) {
              let showHtm = '';
              let siteName = params.name;
              let siteData = geoCoordMap[siteName];
              let machines = [];
              if (siteData) {
                machines = siteData.machines;
                let machinesHtml = '';
                machines.forEach((item, index) => {
                  let status = item.machinesStatus;
                  let color = '';
                  if (status == 'green') {
                    color = '#3bbd03';
                  }
                  if (status == 'yellow') {
                    color = '#f3df2c';
                  }
                  if (status == 'red') {
                    color = '#c90d0d';
                  }
                  machinesHtml += `<div class="machine"><span class="circle" style="background-color: ${color};"></span><span>${item.comment}</span>:<span style="font-size: 13px;">${item.endpoint}</span>
                                  <i class="el-icon-delete delbtn" onClick="deleteMachine(${index})"></i>
                                  </div>`;
                })
                showHtm = `<div class="tooltip"><div style="font-size: 14px;font-weight: bold;"><span>${siteName}</span><i class="el-icon-delete delbtn" οnclick="deleteSite(${siteData})"></i></div>${machinesHtml}</div>`;
              }
              return showHtm;
            }
          },
          series: series
        });

        myChart.on("mouseover", function (params){
          if(params){
            if(params.seriesType === "effectScatter") {
              let x = params.event.offsetX;
              let y = params.event.offsetY;

              let siteName = params.name.split("(")[0];
              let siteData = geoCoordMap[siteName];
              let machines = [];
              if (siteData) {
                machines = siteData.machines;
                machines.forEach((item) => {
                  let status = item.machinesStatus;
                  let color = '';
                  if (status == 'green') {
                    color = '#3bbd03';
                  }
                  if (status == 'yellow') {
                    color = '#f3df2c';
                  }
                  if (status == 'red') {
                    color = '#c90d0d';
                  }
                  item.color = color;
                });

                self.tooltipData = {
                  // x: x - width,
                  y: y,
                  siteName: siteName,
                  machines: machines,
                  siteId: siteData && siteData.siteId || ""
                }

                setTimeout(() => {
                  let width = self.$refs['tooltipHidden'] && self.$refs['tooltipHidden'].clientWidth || 0;
                  // console.log(x, width)
                  self.tooltipData.x = x - width;
                  self.showTooltip = true;
                },200)
              }
            }else{
              self.showTooltip = false;
            }

            if (params.seriesType === "lines") {
              let x = params.event.offsetX;
              let y = params.event.offsetY;
              self.lineTooltipData = {x: x, y: y, ...params.data};
              self.showLineTooltip = true;
            }else{
              self.showLineTooltip = false;
            }
          }
        });

        // myChart.on("mouseout", function (params){
        //   if(params) {
        //     self.showTooltip = false
        //     self.showLineTooltip = false;
        //   }
        // });
      },
      /**
       * 获取站点列表
       * @returns {Promise<void>}
       */
      async getSiteList() {
        let siteList = await worldMapApi.siteList();
        if (siteList.code === 200) {
          this.siteList = siteList.data;
        }
      },
      /**
       * 获取设备列表
       * @returns {Promise<void>}
       */
      async getNetDeviceList() {
        let deviceList = await worldMapApi.netDeviceList({siteId: this.siteForm.siteId});
        if (deviceList.code === 200) {
          this.deviceList = deviceList.data;
        }
      },
      /**
       * 获取指标列表
       * @returns {Promise<void>}
       */
      async getMetricList() {
        let metricList = await worldMapApi.metricInfoList({endpointId: this.siteForm.endpointId});
        if (metricList.code === 200) {
          this.metricList = metricList.data;
        }
      },
      selectSite() {
        this.siteForm.endpointId = "";
        this.getNetDeviceList();
      },
      selectDevice() {
        this.siteForm.metric = "";
        this.getMetricList();
      },
      selectSiteFrom(selected) {
        this.interConnect.siteFromNm = selected.siteNm;
      },
      selectSiteTo(selected) {
        this.interConnect.siteToNm = selected.siteNm;
      },
      /**
       * 站点添加关联设备
       */
      addMachine(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            worldMapApi.addMachine(this.siteForm).then((res)=>{
              if(res.code === 200) {
                this.getMapData();
                this.operateMsg({type: 'success', msg: '确定成功'});
              }else if(res.code === 400) {
                this.operateMsg({type: 'warning', msg: '已添加该设备'});
              }
            })
          } else {
            return false;
          }
        });
      },
      /**
       * 删除站点
       */
      deleteSite() {
        if(this.tooltipData.machines && this.tooltipData.machines.length > 0) {
          this.operateMsg({type: 'warning', msg: '该站点下有设备,不允许删除'});
        }else {
          let params = {
            siteId: this.tooltipData.siteId
          };
          worldMapApi.removeSite(params).then((res) => {
            if (res.code === 200) {
              this.getMapData();

              this.operateMsg({type: 'success', msg: '删除成功'});
            }
          })
        }
      },
      /**
       * 确定互联
       */
      saveLine(formName) {
        this.$refs[formName].validate((valid) => {
          if (valid) {
            worldMapApi.addInterConnect(this.interConnect).then((res)=>{
              if(res.code === 200) {
                this.getMapData();

                this.operateMsg({type: 'success', msg: '确定成功'});
              }
            })
          } else {
            return false;
          }
        });
      },
      /**
       * 取消互联
       */
      deleteLine(item) {
        let params = {
          siteFrom: item.siteFrom,
          siteTo: item.siteTo
        };

        worldMapApi.cancelInterConnect(params).then((res)=>{
          if(res.code === 200) {
            this.showLineTooltip = false;
            this.getMapData();
            this.operateMsg({type: 'success', msg: '取消成功'});
          }
        })
      },
      /**
       * 删除站点关联设备
       */
      deleteMachine(item) {
        // let item = {};
        // if(index != 'undefined') {
        //   item = this.tooltipData.machines[index];
        //   console.log(item);
        //
        // }

        let params = {
          siteId: item.siteId,
          endpointId: item.endpointId,
          metric: item.metric
        };

        worldMapApi.removeMachine(params).then((res) => {
          if (res.code === 200) {
            this.showTooltip = false;
            this.getMapData();
            this.operateMsg({type: 'success', msg: '删除成功'});
          }
        })
      },
      /**
       * 设为主设备
       * @param item
       */
      setMainMachine(item) {
        let params = {
          siteId: item.siteId,
          endpointId: item.endpointId,
          metric: item.metric
        };

        worldMapApi.orderFlgUpdate(params).then((res) => {
          if (res.code === 200) {
            this.getMapData();
            this.operateMsg({type: 'success', msg: '设置成功'});
          }
        })
      },
      operateMsg(p) {
        this.$notify({
          type: p.type,
          title: '操作提示',
          message: p.msg,
          duration: 2000,
          position: 'top-right'
        })
      }
    }
  }
</script>

<style lang="scss">
  .map-wrap {
    width: 100%;

    .world-map-wrap {
      /*min-height: 89.5vh;*/
      display: flex;
    }

    .left-container {
      width: 75%;
      height: 100%;
      position: relative;

      #worldMap {
        width: 100%;
      }

      .circle {
        display: inline-block;
        margin-right: 5px;
        width: 10px;
        height: 10px;
        border-radius: 50%;
      }

      .status-wrap {
        display: flex;
        justify-content: center;
        color: #fff;

        div {
          margin-right: 5vmin;
        }
      }

      .tooltip {
        position: absolute;
        background:#153244;
        border-color: #b5b5b5;
        border-radius: 5px;
        padding: 10px;
        color: #fff;

        .delbtn {
          display: inline-block;
          margin-left: 10px;
          cursor: pointer;
        }

        .site {
          font-size: 14px;
          font-weight: bold;
        }

        .machine {
          margin: 5px 0;

          .circle {
            display: inline-block;
            margin-right: 5px;
            width: 10px;
            height: 10px;
            border-radius: 50%;
          }
        }
      }
    }

    .right-container {
      width: 25%;
      margin-top: 8vmin;
      padding-right: 2vmin;

      .el-form-item {
        margin-bottom: 8px;

        .el-form-item__label {
          color: #fff !important;
        }
      }

      .el-form-item__error {
        top: 80% !important;
        left: 6% !important;
      }

      .site-wrap {
        width: 95%;
        background:#153244;
        border-color: #b5b5b5;
        border-radius: 8px;
        padding: 2vmin 3vmin;
        text-align: center;
      }

      .line-wrap {
        width: 95%;
        background:#153244;
        border-color: #b5b5b5;
        border-radius: 8px;
        padding: 2vmin 3vmin;
        text-align: center;
        margin-top: 2vmin;
      }

      .row-wrap {
        display: inline-block;
        margin-bottom: 2vmin;
        /*padding-left: 5vmin;*/

        .label {
          display: inline-block;
          height: 4vmin;
          line-height: 4vmin;
          color: #fff;
          font-size: 14px;
          width: 8vmin;
        }

        .input-self {
          width: 24.6vmin;
        }
      }
    }
  }
</style>

 

<!-- nameMapping -->

<script>
  export default {
    'Canada': '加拿大',
    'Turkmenistan': '土库曼斯坦',
    'Saint Helena': '圣赫勒拿',
    'Lao PDR': '老挝',
    'Lithuania': '立陶宛',
    'Cambodia': '柬埔寨',
    'Ethiopia': '埃塞俄比亚',
    'Faeroe Is.': '法罗群岛',
    'Swaziland': '斯威士兰',
    'Palestine': '巴勒斯坦',
    'Belize': '伯利兹',
    'Argentina': '阿根廷',
    'Bolivia': '玻利维亚',
    'Cameroon': '喀麦隆',
    'Burkina Faso': '布基纳法索',
    'Aland': '奥兰群岛',
    'Bahrain': '巴林',
    'Saudi Arabia': '沙特阿拉伯',
    'Fr. Polynesia': '法属波利尼西亚',
    'Cape Verde': '佛得角',
    'W. Sahara': '西撒哈拉',
    'Slovenia': '斯洛文尼亚',
    'Guatemala': '危地马拉',
    'Guinea': '几内亚',
    'Dem. Rep. Congo': '刚果(金)',
    'Germany': '德国',
    'Spain': '西班牙',
    'Liberia': '利比里亚',
    'Netherlands': '荷兰',
    'Jamaica': '牙买加',
    'Solomon Is.': '所罗门群岛',
    'Oman': '阿曼',
    'Tanzania': '坦桑尼亚',
    'Costa Rica': '哥斯达黎加',
    'Isle of Man': '曼岛',
    'Gabon': '加蓬',
    'Niue': '纽埃',
    'Bahamas': '巴哈马',
    'New Zealand': '新西兰',
    'Yemen': '也门',
    'Jersey': '泽西岛',
    'Pakistan': '巴基斯坦',
    'Albania': '阿尔巴尼亚',
    'Samoa': '萨摩亚',
    'Czech Rep.': '捷克',
    'United Arab Emirates': '阿拉伯联合酋长国',
    'Guam': '关岛',
    'India': '印度',
    'Azerbaijan': '阿塞拜疆',
    'N. Mariana Is.': '北马里亚纳群岛',
    'Lesotho': '莱索托',
    'Kenya': '肯尼亚',
    'Belarus': '白俄罗斯',
    'Tajikistan': '塔吉克斯坦',
    'Turkey': '土耳其',
    'Afghanistan': '阿富汗',
    'Bangladesh': '孟加拉国',
    'Mauritania': '毛里塔尼亚',
    'Dem. Rep. Korea': '朝鲜',
    'Saint Lucia': '圣卢西亚',
    'Br. Indian Ocean Ter.': '英属印度洋领地',
    'Mongolia': '蒙古',
    'France': '法国',
    'Cura?ao': '库拉索岛',
    'S. Sudan': '南苏丹',
    'Rwanda': '卢旺达',
    'Slovakia': '斯洛伐克',
    'Somalia': '索马里',
    'Peru': '秘鲁',
    'Vanuatu': '瓦努阿图',
    'Norway': '挪威',
    'Malawi': '马拉维',
    'Benin': '贝宁',
    'St. Vin. and Gren.': '圣文森特和格林纳丁斯',
    'Korea': '韩国',
    'Singapore': '新加坡',
    'Montenegro': '黑山共和国',
    'Cayman Is.': '开曼群岛',
    'Togo': '多哥',
    'China': '中国',
    'Heard I. and McDonald Is.': '赫德岛和麦克唐纳群岛',
    'Armenia': '亚美尼亚',
    'Falkland Is.': '马尔维纳斯群岛(福克兰)',
    'Ukraine': '乌克兰',
    'Ghana': '加纳',
    'Tonga': '汤加',
    'Finland': '芬兰',
    'Libya': '利比亚',
    'Dominican Rep.': '多米尼加',
    'Indonesia': '印度尼西亚',
    'Mauritius': '毛里求斯',
    'Eq. Guinea': '赤道几内亚',
    'Sweden': '瑞典',
    'Vietnam': '越南',
    'Mali': '马里',
    'Russia': '俄罗斯',
    'Bulgaria': '保加利亚',
    'United States': '美国',
    'Romania': '罗马尼亚',
    'Angola': '安哥拉',
    'Chad': '乍得',
    'South Africa': '南非',
    'Fiji': '斐济',
    'Liechtenstein': '列支敦士登',
    'Malaysia': '马来西亚',
    'Austria': '奥地利',
    'Mozambique': '莫桑比克',
    'Uganda': '乌干达',
    'Japan': '日本',
    'Niger': '尼日尔',
    'Brazil': '巴西',
    'Kuwait': '科威特',
    'Panama': '巴拿马',
    'Guyana': '圭亚那',
    'Madagascar': '马达加斯加',
    'Luxembourg': '卢森堡',
    'American Samoa': '美属萨摩亚',
    'Andorra': '安道尔',
    'Ireland': '爱尔兰',
    'Italy': '意大利',
    'Nigeria': '尼日利亚',
    'Turks and Caicos Is.': '特克斯和凯科斯群岛',
    'Ecuador': '厄瓜多尔',
    'U.S. Virgin Is.': '美属维尔京群岛',
    'Brunei': '文莱',
    'Australia': '澳大利亚',
    'Iran': '伊朗',
    'Algeria': '阿尔及利亚',
    'El Salvador': '萨尔瓦多',
    "C?te d'Ivoire": '科特迪瓦',
    'Chile': '智利',
    'Puerto Rico': '波多黎各',
    'Belgium': '比利时',
    'Thailand': '泰国',
    'Haiti': '海地',
    'Iraq': '伊拉克',
    'S?o Tomé and Principe': '圣多美和普林西比',
    'Sierra Leone': '塞拉利昂',
    'Georgia': '格鲁吉亚',
    'Denmark': '丹麦',
    'Philippines': '菲律宾',
    'S. Geo. and S. Sandw. Is.': '南乔治亚岛和南桑威奇群岛',
    'Moldova': '摩尔多瓦',
    'Morocco': '摩洛哥',
    'Namibia': '纳米比亚',
    'Malta': '马耳他',
    'Guinea-Bissau': '几内亚比绍',
    'Kiribati': '基里巴斯',
    'Switzerland': '瑞士',
    'Grenada': '格林纳达',
    'Seychelles': '塞舌尔',
    'Portugal': '葡萄牙',
    'Estonia': '爱沙尼亚',
    'Uruguay': '乌拉圭',
    'Antigua and Barb.': '安提瓜和巴布达',
    'Lebanon': '黎巴嫩',
    'Uzbekistan': '乌兹别克斯坦',
    'Tunisia': '突尼斯',
    'Djibouti': '吉布提',
    'Greenland': '格陵兰',
    'Timor-Leste': '东帝汶',
    'Dominica': '多米尼克',
    'Colombia': '哥伦比亚',
    'Burundi': '布隆迪',
    'Bosnia and Herz.': '波斯尼亚和黑塞哥维那',
    'Cyprus': '塞浦路斯',
    'Barbados': '巴巴多斯',
    'Qatar': '卡塔尔',
    'Palau': '帕劳',
    'Bhutan': '不丹',
    'Sudan': '苏丹',
    'Nepal': '尼泊尔',
    'Micronesia': '密克罗尼西亚',
    'Bermuda': '百慕大',
    'Suriname': '苏里南',
    'Venezuela': '委内瑞拉',
    'Israel': '以色列',
    'St. Pierre and Miquelon': '圣皮埃尔和密克隆群岛',
    'Central African Rep.': '中非',
    'Iceland': '冰岛',
    'Zambia': '赞比亚',
    'Senegal': '塞内加尔',
    'Papua New Guinea': '巴布亚新几内亚',
    'Trinidad and Tobago': '特立尼达和多巴哥',
    'Zimbabwe': '津巴布韦',
    'Jordan': '约旦',
    'Gambia': '冈比亚',
    'Kazakhstan': '哈萨克斯坦',
    'Poland': '波兰',
    'Eritrea': '厄立特里亚',
    'Kyrgyzstan': '吉尔吉斯斯坦',
    'Montserrat': '蒙特塞拉特',
    'New Caledonia': '新喀里多尼亚',
    'Macedonia': '马其顿',
    'Paraguay': '巴拉圭',
    'Latvia': '拉脱维亚',
    'Hungary': '匈牙利',
    'Syria': '叙利亚',
    'Honduras': '洪都拉斯',
    'Myanmar': '缅甸',
    'Mexico': '墨西哥',
    'Egypt': '埃及',
    'Nicaragua': '尼加拉瓜',
    'Cuba': '古巴',
    'Serbia': '塞尔维亚',
    'Comoros': '科摩罗',
    'United Kingdom': '英国',
    'Fr. S. Antarctic Lands': '南极洲',
    'Congo': '刚果(布)',
    'Greece': '希腊',
    'Sri Lanka': '斯里兰卡',
    'Croatia': '克罗地亚',
    'Botswana': '博茨瓦纳',
    'Siachen Glacier': '锡亚琴冰川地区'
  }
</script>
免费分享大家 [44.38652343750002,10.430224609374989],[44.94296875,10.43671875],[45.81669921875002,10.835888671874997],[46.565039062500006,10.745996093749994],[47.40498046875001,11.174023437499997],[48.01923828125001,11.139355468749997],[48.57255859375002,11.320507812499997],[48.938574218750006,11.258447265624994],[50.11005859375001,11.529296875],[50.79228515625002,11.983691406249989],[51.2548828125,11.830712890624994],[51.08427734375002,11.335644531249997],[51.140625,10.656884765624994],[51.031835937500006,10.444775390624997],[51.19296875,10.554638671874997],[51.390234375,10.422607421875],[50.93007812500002,10.33554687499999],[50.825,9.428173828124997],[50.10283203125002,8.199804687499991],[49.85205078125,7.962548828124994],[49.234960937500006,6.77734375],[49.04931640625,6.173632812499989],[47.97529296875001,4.497021484374997],[46.87880859375002,3.28564453125],[46.05117187500002,2.475146484374989],[44.92021484375002,1.81015625],[43.71757812500002,0.857861328124997],[41.97988281250002,-0.973046875],[41.53271484375,-1.6953125],[41.521875,-1.572265625],[41.42695312500001,-1.449511718750003],[41.24980468750002,-1.220507812500003],[40.97871093750001,-0.870312500000011],[40.964453125,2.814648437499997],[41.341796875,3.20166015625],[41.61347656250001,3.590478515624994],[41.88398437500001,3.977734375],[41.91533203125002,4.031298828124989],[42.02412109375001,4.137939453125],[42.85664062500001,4.32421875],[43.12568359375001,4.644482421874997],[43.58349609375,4.85498046875],[43.988867187500006,4.950537109374991],[44.940527343750006,4.912011718749994],[47.97822265625001,7.9970703125]]]},"properties":{"name":"索马里","childNum":1}},{"geometry":{"type":"Polygon","coordinates":[[[9.579979133936737,47.05856388629306],[9.409458596647225,47.02019676540292],[9.46249431093294,47.09010747968864],[9.46249431093294,47.19858962254578],[9.527658197470123,47.27026989773668],[9.579979133936737,47.05856388629306]]]},"properties":{"name":"列支敦斯登","childNum":1}},{"geometry":{"type":"Polygon","coordinates":[[[-8.683349609375,27.77800740805682],[-13.038761787013554,27.81190166624856],[-12.948925781249926,27.914160156250034],[-11.552685546874955,28.31010742187496],[-10.486474609374994,29.06494140625],[-10.200585937499994,29.380371093750057],[-9.667089843749949,30.10927734375005],[-9.652929687499977,30.447558593750045],[-9.875488281249943,30.717919921874966],[-9.80869140624992,31.42460937499996],[-9.347460937499932,32.086376953124955],[-9.245849609375,32.572460937499955],[-8.512841796874994,33.25244140625003],[-6.900976562499949,33.96904296874999],[-6.353125,34.77607421875001],[-5.924804687499943,35.78579101562502],[-5.277832031249943,35.90273437500002],[-5.252685546874972,35.61474609374997],[-4.628320312499966,35.206396484375006],[-4.329980468749937,35.161474609375006],[-3.693261718749994,35.27998046874998],[-3.394726562499926,35.21181640625005],[-2.972216796874989,35.40727539062499],[-2.839941406249949,35.127832031249994],[-2.731396484374955,35.13520507812498],[-2.636816406249977,35.11269531250002],[-2.423730468749994,35.12348632812498],[-2.219628906249966,35.10419921874998],[-1.795605468749926,34.751904296874955],[-1.67919921875,33.31865234375002],[-1.550732421874955,33.073583984375006],[-1.510009765625,32.877636718749955],[-1.45,32.784814453124966],[-1.352148437499977,32.70336914062497],[-1.29638671875,32.67568359375002],[-1.188232421875,32.608496093750006],[-1.111035156249983,32.55229492187502],[-1.065527343749949,32.46831054687496],[-1.16259765625,32.399169921875],[-1.275341796874983,32.089013671874966],[-2.863427734374937,32.07470703124997],[-2.930859374999926,32.04252929687499],[-2.988232421874983,31.874218749999983],[-3.01738281249996,31.834277343750017],[-3.439794921874949,31.704541015624983],[-3.604589843749949,31.686767578125],[-3.700244140624989,31.70009765625005],[-3.768164062499977,31.689550781250034],[-3.837109374999983,31.512353515624994],[-3.833398437499937,31.197802734375045],[-3.626904296874955,31.000927734374983],[-4.148779296874977,30.8095703125],[-4.322851562500006,30.698876953124994],[-4.52915039062492,30.62553710937499],[-4.778515624999926,30.552392578124994],[-4.968261718749943,30.465380859375045],[-5.061914062499937,30.326416015625057],[-5.180126953124955,30.166162109374994],[-5.293652343749983,30.058642578125045],[-5.44877929687496,29.956933593750023],[-6.00429687499999,29.83125],[-6.479736328124943,29.82036132812499],[-6.520556640624989,29.659863281249983],[-6.59775390624992,29.578955078125006],[-6.635351562499949,29.568798828124983],[-6.755126953125,29.583837890625034],[-6.855566406249949,29.601611328125017],[-7.142431640624949,29.61958007812504],[-7.427685546874983,29.425],[-7.485742187499994,29.392236328124994],[-8.659912109375,28.718603515625063],[-8.683349609375,27.900390625],[-8.683349609375,27.77800740805682]]]},"properties":{"name":"摩洛哥","childNum":1}},{"geometry":{"type":"Polygon","coordinates":[[[-13.038761787013554,27.81190166624856],[-8.683349609375,27.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值