You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目中Google Maps调用getFeatureLayer报函数不存在错误

问题解决:map.getFeatureLayer is not a function 错误及后续功能实现

错误原因及修复步骤

1. Map构造函数参数错误

你的代码中创建Map时传入了三个参数,但google.maps.Map仅接受DOM元素和配置对象两个参数,第三个参数会被忽略,导致部分配置不生效,同时可能影响API功能加载。

修正方式:将全屏控件配置合并到mapOption中:

const mapOption = {
  center: { lat: 39.80986, lng: -98.555183 },
  zoom: 4,
  minZoom: 2,
  controlSize: 25,
  mapTypeControl: false,
  streetViewControl: false,
  mapId:'dda013exxxxxxxxx',
  fullscreenControlOptions: {
    position: google.maps.ControlPosition.LEFT_BOTTOM,
  }
};

2. useState异步更新导致的实例获取问题

用useState存储map实例时,状态更新是异步的,同一个useEffect回调中无法立即获取到更新后的map实例,导致调用map.getFeatureLayer时map仍为undefined。

改用useRef存储map实例,同步获取最新实例:

import React, { useEffect, useRef } from "react";
import { Loader } from "@googlemaps/js-api-loader"

const mapOption = {
  center: { lat: 39.80986, lng: -98.555183 },
  zoom: 4,
  minZoom: 2,
  controlSize: 25,
  mapTypeControl: false,
  streetViewControl: false,
  mapId:'dda013exxxxxxxxx',
  fullscreenControlOptions: {
    position: google.maps.ControlPosition.LEFT_BOTTOM,
  }
};

export const MapSection = ({ mapData }) => {
  const mapDiv = useRef(null);
  const map = useRef(null); // 用useRef替代useState存储map实例

  useEffect(() => {
    const loader = new Loader({
      apiKey: process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY,
      version: "weekly",
      libraries: ["places", "geometry"],
    });

    loader
      .load()
      .then(async () => {
        const google = window.google;

        if (mapDiv.current && !map.current) {
          // 初始化map并存储到ref
          map.current = new google.maps.Map(mapDiv.current, mapOption);
          
          // 直接调用getFeatureLayer处理着色
          const countryLayer = map.current.getFeatureLayer('COUNTRY');
          const featureStyleOptions = {
            strokeColor: "#810FCB",
            strokeOpacity: 1.0,
            strokeWeight: 3.0,
            fillColor: "#810FCB",
            fillOpacity: 0.5,
          };
          
          // 多国着色:定义需要着色的国家placeId列表
          const targetCountryPlaceIds = [
            "ChIJCzYy5IS16lQRQrfeQ5K5Oxw", // 美国
            // 可添加其他国家的placeId
          ];
          
          countryLayer.style = (options) => {
            if (targetCountryPlaceIds.includes(options.feature.placeId)) {
              return featureStyleOptions;
            }
          };

          // 添加城市标记
          if (mapData && mapData.length > 0) {
            mapData.forEach(city => {
              new google.maps.Marker({
                position: { lat: city.lat, lng: city.lng },
                map: map.current,
                title: city.name, // 假设mapData包含城市名称字段
              });
            });
          }
        }
      })
      .catch((e) => {
        console.log("Error loading the google map", e.message);
      });
  }, [mapData]);

  return (
    <Grid
      item
      container
      xs={12}
      ref={mapDiv}
      sx={{
        width: "100vw",
        height: "500px",
        margin: "auto",
        overflow: "hidden",
      }}
    />
  )
};

3. Map ID及API配置验证

getFeatureLayer属于Data-Driven Styling(DDS)边界功能,必须满足以下条件:

  • 你的Map ID已在Google Cloud控制台启用了DDS边界数据集(需关联国家/地区边界等数据集)
  • 项目已启用Maps JavaScript API
  • API密钥拥有访问DDS功能的权限(确保密钥未被过度限制)

后续功能实现说明

多国批量着色

将需要着色的国家placeId存入数组,在style回调中通过includes判断是否匹配,即可实现批量着色。你可以从后端或配置文件中加载这个placeId列表,动态更新着色范围。

城市标记添加

遍历mapData中的城市数据,为每个城市创建google.maps.Marker实例,绑定到当前map上即可。注意确保mapData包含城市的经纬度信息,以及需要显示的标题等字段。

内容的提问来源于stack exchange,提问作者Vaidehi S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:45:37