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
相关产品推荐
相关产品推荐

