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

如何在Next.js中用react-google-maps/api添加一级行政区FeatureLayer样式

解决方案:在react-google-maps/api中高亮选中地点所属的一级行政区

你当前代码的核心问题有两个:

  • 未遵循react-google-maps/api的组件体系,直接操作原生Google Maps实例,不符合库的使用规范
  • 尝试用地点(如MIT)的placeId匹配一级行政区的placeId,两者并不一致,因此无法触发样式

下面是适配react-google-maps/api的完整实现,包含地理编码反查一级行政区、FeatureLayer样式设置的逻辑:

步骤1:确保依赖安装

npm install @react-google-maps/api
# 或
yarn add @react-google-maps/api

步骤2:重构ShowMap.tsx组件

import React, { useRef, useState, useCallback } from "react";
import { GoogleMap, useLoadScript } from "@react-google-maps/api";
import SearchComponent from "./SearchComponent";

const mapContainerStyle = {
  width: "100%",
  height: "700px",
};

const center = { lat: 23.685, lng: 90.3563 };

const libraries = ["places", "geocoding"]; // 需要加载places和geocoding库

export default function ShowMap({ showPin }: { showPin: boolean }) {
  const mapRef = useRef<google.maps.Map | null>(null);
  const featureLayerRef = useRef<google.maps.FeatureLayer | null>(null);
  const [selectedAdminPlaceId, setSelectedAdminPlaceId] = useState<string | null>(null);

  // 使用useLoadScript加载地图脚本,替代手动创建script标签
  const { isLoaded, loadError } = useLoadScript({
    googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY!,
    mapIds: [process.env.NEXT_PUBLIC_MAP_ID!],
    libraries,
  });

  // 地图加载完成后获取FeatureLayer并设置样式逻辑
  const onMapLoad = useCallback((map: google.maps.Map) => {
    mapRef.current = map;
    // 获取一级行政区FeatureLayer
    const featureLayer = map.getFeatureLayer("ADMINISTRATIVE_AREA_LEVEL_1");
    featureLayerRef.current = featureLayer;

    // 初始化样式:默认状态+选中高亮逻辑
    featureLayer.style = (options) => {
      const baseStyle: google.maps.Data.StyleOptions = {
        fillColor: "#ffffff",
        fillOpacity: 0.3,
        strokeColor: "#cccccc",
        strokeOpacity: 0.8,
        strokeWeight: 1,
      };

      // 匹配到目标行政区时应用高亮样式
      if (options.feature.placeId === selectedAdminPlaceId) {
        return {
          ...baseStyle,
          fillColor: "#ff7859",
          fillOpacity: 0.8,
          strokeColor: "#ff7859",
          strokeWeight: 3,
        };
      }
      return baseStyle;
    };
  }, [selectedAdminPlaceId]);

  // 处理搜索:获取选中地点所属的一级行政区placeId
  const handleSearch = useCallback(async (place: google.maps.places.PlaceResult) => {
    if (!mapRef.current || !featureLayerRef.current || !place.geometry?.location) return;

    // 使用地理编码API,根据地点坐标反查所属的一级行政区
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode(
      { location: place.geometry.location },
      (results, status) => {
        if (status !== google.maps.GeocoderStatus.OK || !results?.length) return;

        // 从地理编码结果中提取administrative_area_level_1的placeId
        const adminAreaResult = results.find(result =>
          result.types.includes("administrative_area_level_1")
        );

        if (adminAreaResult?.place_id) {
          setSelectedAdminPlaceId(adminAreaResult.place_id);
        }

        // 移动地图到选中地点
        mapRef.current?.setZoom(12);
        mapRef.current?.setCenter(place.geometry.location);
        setTimeout(() => {
          mapRef.current?.setZoom(8);
        }, 3000);
      }
    );
  }, []);

  if (loadError) return <div>地图加载失败</div>;
  if (!isLoaded) return <div>加载中...</div>;

  return (
    <>
      <SearchComponent onSearch={handleSearch} />
      <GoogleMap
        mapContainerStyle={mapContainerStyle}
        center={center}
        zoom={10}
        mapId={process.env.NEXT_PUBLIC_MAP_ID!}
        onLoad={onMapLoad}
      />
    </>
  );
}

关键说明

  1. 组件体系适配:

    • 用useLoadScript自动加载地图脚本,符合React组件生命周期,替代手动创建script标签
    • 通过GoogleMap组件的onLoad回调获取map实例,避免全局变量污染
  2. placeId匹配问题解决:

    • 搜索到的地点(如MIT)的placeId不属于一级行政区,必须通过地理编码API反查该地点坐标对应的一级行政区信息,提取其合法的placeId
  3. FeatureLayer样式逻辑:

    • 在onMapLoad中初始化样式回调,根据selectedAdminPlaceId动态判断是否高亮目标区域
    • 样式回调会自动遍历所有一级行政区Feature,匹配到目标placeId时自动应用高亮样式
  4. 类型安全优化:

    • 移除了//@ts-ignore注释,通过正确的类型声明保证代码类型安全
    • 使用useRef保存map和featureLayer实例,避免全局变量

内容的提问来源于stack exchange,提问作者Anindo Sarker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:02:06