function drawMapBackground()

in src/Wmap/index.tsx [557:658]


function drawMapBackground(ctx: Map, chart: Chart, ds: DataSet, config: WmapConfig) {
  let geoData = null;
  if (ctx.geoData) {
    // 如果用户有传geoData,优先使用
    geoData = ctx.geoData;
  } else if (config.type === 'china') {
    // 自带中国地图数据
    geoData = chinaGeo;
  } else {
    warn('Wmap', "no geo data, can't draw the map!");
  }

  const bgMapDataView = ds.createView('bgMap').source(geoData, {
    type: 'GeoJSON',
  });

  let { projection } = config;

  if (!projection) {
    projection = bgMapDataView.getGeoProjection('geoConicEqualArea');
    projection
      // @ts-ignore
      .center([0, 36.4])
      .parallels([25, 47])
      .scale(1000)
      .rotate([-105, 0])
      .translate([0, 0]);
  }

  bgMapDataView.transform({
    type: 'geo.projection',
    // 因为G2的投影函数不支持设置投影参数,这里使用自定义的投影函数设置参数
    // @ts-ignore
    projection() {
      return projection;
    },
    as: ['x', 'y', 'cX', 'cY'],
  });

  if (config.type === 'china') {
    // 过滤掉南海诸岛
    bgMapDataView.transform({
      type: 'filter',
      callback(row) {
        return row.properties.name !== '南海诸岛';
      },
    });
  }

  // start: 按照投影后尺寸比例调整图表的真实比例
  const longitudeRange = bgMapDataView.range('x');
  const latitudeRange = bgMapDataView.range('y');
  const ratio = (longitudeRange[1] - longitudeRange[0]) / (latitudeRange[1] - latitudeRange[0]);
  ctx.bgMapRatio = ratio;
  const { width: chartWidth, height: chartHeight } = chart;
  const chartRatio = chartWidth / chartHeight;

  let width = chartWidth;
  let height = chartHeight;
  if (chartRatio > ratio) {
    width = chartHeight * ratio;
  } else if (chartRatio < ratio) {
    height = chartWidth / ratio;
  }
  if (width !== chartWidth || height !== chartHeight) {
    const p1 = (chartWidth - width) / 2;
    const p2 = (chartHeight - height) / 2;
    // 不设置尺寸,通过padding控制地图形状
    chart.appendPadding = [p2, p1, p2, p1];
  }
  ctx.bgMapSize = [width, height];
  // end: 按照投影后尺寸比例调整图表的真实比例

  const { fill: bgFill, stroke: bgStroke, ...otherBgStyle } = config.background || {};

  const bgMapView = chart.createView({
    padding: 0,
  });
  bgMapView.data(bgMapDataView.rows);
  bgMapView.tooltip(false);
  bgMapView
    .polygon()
    .position('x*y')
    .style('name', function (name) {
      const result = {
        fill: bgFill || themes['widgets-map-area-bg'],
        stroke: bgStroke || themes['widgets-map-area-border'],
        lineWidth: 1,
        ...otherBgStyle,
      };
      // 对一些尺寸非常小的形状特殊处理,以显示出来。
      if (minArea.indexOf(name) > -1) {
        result.stroke = bgFill || themes['widgets-map-area-bg'];
      }
      return result;
    });

  ctx.bgMapDataView = bgMapDataView;
  ctx.bgMapView = bgMapView;

  ctx.projection = projection;
}