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

Flutter中GeoJson MultiPolygon转模型及绘制Polyline问题求助

解决方案:处理Flutter中GeoJson的MultiPolygon解析与绘制

一、修改GeoJson模型类,支持MultiPolygon类型

首先需要扩展模型,兼容Polygon和MultiPolygon两种结构的坐标解析,同时提供统一的坐标提取方法:

class FeatureGeometry {
  final String type;
  final List<List<List<double>>>? polygonCoordinates; // 对应Polygon类型
  final List<List<List<List<double>>>>? multiPolygonCoordinates; // 对应MultiPolygon类型

  FeatureGeometry({
    required this.type,
    this.polygonCoordinates,
    this.multiPolygonCoordinates,
  });

  factory FeatureGeometry.fromJson(Map<String, dynamic> json) {
    final geometryType = json['type'] as String;
    if (geometryType == 'Polygon') {
      return FeatureGeometry(
        type: geometryType,
        polygonCoordinates: List<List<List<double>>>.from(
          json['coordinates'].map((ring) => List<List<double>>.from(
                ring.map((coord) => List<double>.from(coord)),
              )),
        ),
      );
    } else if (geometryType == 'MultiPolygon') {
      return FeatureGeometry(
        type: geometryType,
        multiPolygonCoordinates: List<List<List<List<double>>>>.from(
          json['coordinates'].map((polygon) => List<List<List<double>>>.from(
                polygon.map((ring) => List<List<double>>.from(
                      ring.map((coord) => List<double>.from(coord)),
                    )),
              )),
        ),
      );
    } else {
      throw Exception('不支持的几何类型:$geometryType');
    }
  }

  // 统一提取所有多边形的坐标(兼容Polygon/MultiPolygon)
  List<List<List<double>>> getAllPolygonRings() {
    final allRings = <List<List<double>>>[];
    if (type == 'Polygon') {
      allRings.addAll(polygonCoordinates!);
    } else if (type == 'MultiPolygon') {
      for (final polygon in multiPolygonCoordinates!) {
        allRings.addAll(polygon);
      }
    }
    return allRings;
  }
}

如果使用json_serializable,可保留上述fromJson逻辑,忽略自动生成的坐标字段映射即可。

二、调整UI绘制逻辑(以Google Maps为例)

GeoJson坐标顺序为[经度, 纬度],需转换为Flutter地图组件的[纬度, 经度]格式,同时遍历所有提取出的多边形环进行绘制:

// 假设已获取到FeatureGeometry实例
final geometry = feature.geometry;
final allPolygonRings = geometry.getAllPolygonRings();

// 生成地图Polygon集合
final Set<Polygon> mapPolygons = {};
int polygonIdCounter = 0;

for (final ring in allPolygonRings) {
  // 转换坐标顺序并生成LatLng列表
  final latLngs = ring.map((coord) => LatLng(coord[1], coord[0])).toList();
  mapPolygons.add(
    Polygon(
      polygonId: PolygonId('polygon_${polygonIdCounter++}'),
      points: latLngs,
      strokeWidth: 2,
      strokeColor: Colors.blueAccent,
      fillColor: Colors.blueAccent.withOpacity(0.1),
    ),
  );
}

// 在GoogleMap组件中使用
GoogleMap(
  initialCameraPosition: CameraPosition(target: LatLng(...), zoom: 10),
  polygons: mapPolygons,
  // 其他配置...
)

若使用flutter_map,逻辑类似,替换为PolygonLayer即可:

FlutterMap(
  options: MapOptions(center: LatLng(...), zoom: 10),
  children: [
    TileLayer(urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'),
    PolygonLayer(
      polygons: allPolygonRings.map((ring) {
        final points = ring.map((coord) => LatLng(coord[1], coord[0])).toList();
        return Polygon(
          points: points,
          borderStrokeWidth: 2,
          borderColor: Colors.blueAccent,
          color: Colors.blueAccent.withOpacity(0.1),
        );
      }).toList(),
    ),
  ],
)

三、关键注意事项

  • 坐标顺序转换:GeoJson的[lon, lat]必须转为地图组件的[lat, lon],否则绘制位置会偏移。
  • 多边形环处理:MultiPolygon本质是多个Polygon的集合,通过getAllPolygonRings方法可统一提取所有需要绘制的环。

内容的提问来源于stack exchange,提问作者Arnab Ghosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:23:19