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

Flutter技术求助:如何将JSON数据转为Google Maps地图标记

问题分析与解决方案

核心问题点

你的代码存在三个关键问题导致地图标记无法显示:

  • 经纬度类型不匹配:Shop类中refineWgs84Lat和refineWgs84Logt是String类型,但LatLng构造函数要求传入double类型,直接传递字符串会导致标记位置无效。
  • 实体类属性访问错误:构建Marker时使用了shop['cmpnmNm']这种Map键值访问方式,但shops是List<Shop>实体列表,需直接访问类属性。
  • 异步数据加载未处理:若未通过FutureBuilder等待fetchJson()完成,地图渲染时shops可能为空列表,自然看不到标记。

分步修复

1. 修改Shop类的经纬度类型

将经纬度字段改为double类型,并在fromJson中完成字符串到数值的转换:

class Shop {
  final String cmpnmNm;          // shopname
  final String indutypeNm;
  final String sigunNm;
  final String bsnTmNm;
  final String provsnProdlstNm;
  final String bizregno;
  final String provsnTrgtNm2;
  final String refineLotnoAddr;
  final String refineZipno;
  final double refineWgs84Lat;          // 改为double类型
  final double refineWgs84Logt;         // 改为double类型
  final String detailAddr;
  final String provsnTrgtNm1;
  final String refineRoadnmAddr;

  Shop({
    required this.cmpnmNm,
    required this.indutypeNm,
    required this.sigunNm,
    required this.bsnTmNm,
    required this.provsnProdlstNm,
    required this.bizregno,
    required this.provsnTrgtNm2,
    required this.refineLotnoAddr,
    required this.refineZipno,
    required this.refineWgs84Lat,
    required this.refineWgs84Logt,
    required this.detailAddr,
    required this.provsnTrgtNm1,
    required this.refineRoadnmAddr,
  });

  Shop.fromJson(Map<String, dynamic> json)
      : cmpnmNm=json["CMPNM_NM"] as String,
        indutypeNm= json["INDUTYPE_NM"] as String,
        sigunNm= json["SIGUN_NM"] as String,
        bsnTmNm= json["BSN_TM_NM"] as String,
        provsnProdlstNm= json["PROVSN_PRODLST_NM"] as String,
        bizregno= json["BIZREGNO"] as String,
        provsnTrgtNm2= json["PROVSN_TRGT_NM2"] as String,
        refineLotnoAddr= json["REFINE_LOTNO_ADDR"] as String,
        refineZipno= json["REFINE_ZIPNO"] as String,
        // 转换字符串为double,兼容空值情况
        refineWgs84Lat= double.tryParse(json["REFINE_WGS84_LAT"] as String) ?? 0.0,
        refineWgs84Logt= double.tryParse(json["REFINE_WGS84_LOGT"] as String) ?? 0.0,
        detailAddr= json["DETAIL_ADDR"] as String,
        provsnTrgtNm1= json["PROVSN_TRGT_NM1"] as String,
        refineRoadnmAddr= json["REFINE_ROADNM_ADDR"] as String;

  Map<String, dynamic> toJson() => {
    "CMPNM_NM": cmpnmNm,
    "INDUTYPE_NM": indutypeNm,
    "SIGUN_NM": sigunNm,
    "BSN_TM_NM": bsnTmNm,
    "PROVSN_PRODLST_NM": provsnProdlstNm,
    "BIZREGNO": bizregno,
    "PROVSN_TRGT_NM2": provsnTrgtNm2,
    "REFINE_LOTNO_ADDR": refineLotnoAddr,
    "REFINE_ZIPNO": refineZipno,
    "REFINE_WGS84_LAT": refineWgs84Lat.toString(),
    "REFINE_WGS84_LOGT": refineWgs84Logt.toString(),
    "DETAIL_ADDR": detailAddr,
    "PROVSN_TRGT_NM1": provsnTrgtNm1,
    "REFINE_ROADNM_ADDR": refineRoadnmAddr
  };
}

2. 修正Google Map的Marker构建代码

直接访问Shop类的属性,替代Map键值访问方式:

GoogleMap(
  initialCameraPosition: CameraPosition(
    target: LatLng(37.532600, 127.024612), 
    zoom: 18,
  ),
  markers: Set<Marker>.of(shops.map((shop) {
    return Marker(
      markerId: MarkerId(shop.cmpnmNm),
      position: LatLng(shop.refineWgs84Lat, shop.refineWgs84Logt),
      infoWindow: InfoWindow(title: shop.cmpnmNm),
    );
  })),
)

3. 确保异步数据正确加载

使用FutureBuilder等待接口请求完成后再渲染地图:

// 页面Widget中替换原GoogleMap的渲染逻辑
FutureBuilder<List<Shop>>(
  future: fetchJson(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(child: CircularProgressIndicator());
    } else if (snapshot.hasError) {
      return Center(child: Text('加载失败: ${snapshot.error}'));
    } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
      return const Center(child: Text('没有店铺数据'));
    } else {
      final shops = snapshot.data!;
      return GoogleMap(
        initialCameraPosition: CameraPosition(
          target: LatLng(37.532600, 127.024612), 
          zoom: 18,
        ),
        markers: Set<Marker>.of(shops.map((shop) {
          return Marker(
            markerId: MarkerId(shop.cmpnmNm),
            position: LatLng(shop.refineWgs84Lat, shop.refineWgs84Logt),
            infoWindow: InfoWindow(title: shop.cmpnmNm),
          );
        })),
      );
    }
  },
)

额外检查点

  • 确认API返回的经纬度是有效的数值字符串,无空值或非数字内容。
  • 检查Google Map API密钥是否在Android/iOS配置文件中正确设置。
  • 若店铺位置不在初始相机范围内,可调整初始缩放比例或自动计算包含所有标记的相机边界。

内容的提问来源于stack exchange,提问作者이유림

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:24:55