Flutter地理JSON地图渲染插件flutter_map_geojson的使用
Flutter地理JSON地图渲染插件flutter_map_geojson的使用
简介
GeoJson作为一种用于表示地理特征的数据格式,正逐渐成为获取空间数据(如点、线和多边形)的事实标准。其格式规范定义在RFC7946中,详情可参见https://www.rfc-editor.org/rfc/rfc7946。
flutter_map_geojson
包解析GeoJson数据,并创建由flutter_map
包定义的空间对象,如Marker
、Polyline
和Polygon
等。通过默认回调函数完成这些对象的创建,但用户也可以根据需要自定义这些回调函数以实现更复杂的功能,比如指定颜色、线条宽度、标签文本和其他参数。
特性
该GeoJson解析器会创建包含以下内容的列表:
Marker
:由GeoJson中的Point转换而来。CircleMarker
:虽然不在官方GeoJson规范中,但为了方便而加入,用于表示圆形区域。可以通过属性指定半径。Polyline
:由LineString转换而来。Polygon
:由Polygon或多边形集合MultiPolygon转换而来。
支持的几何类型包括但不限于:
- Point(点)
- Circle(圆)
- Multipoint(多点)
- LineString(线串)
- MultiLineString(多线串)
- Polygon(多边形)
- MultiPolygon(多边形集合)
入门指南
添加依赖
首先,在pubspec.yaml
文件中添加flutter_map_geojson
包:
dependencies:
flutter_map_geojson: ^1.0.8
然后在Dart代码中导入此库:
import 'package:flutter_map_geojson/flutter_map_geojson.dart';
使用方法
下面是一个完整的示例demo,演示如何使用flutter_map_geojson
来加载并显示GeoJson数据到Flutter应用中。
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_geojson/flutter_map_geojson.dart';
// ignore: depend_on_referenced_packages
import 'package:latlong2/latlong.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Map GeoJson Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// 实例化解析器,使用默认设置
GeoJsonParser geoJsonParser = GeoJsonParser(
defaultMarkerColor: Colors.red,
defaultPolygonBorderColor: Colors.red,
defaultPolygonFillColor: Colors.red.withOpacity(0.1),
defaultCircleMarkerColor: Colors.red.withOpacity(0.25),
);
bool loadingData = false;
// 定义过滤函数,可以根据属性筛选特定要素
bool myFilterFunction(Map<String, dynamic> properties) {
if (properties['section'].toString().contains('Point M-4')) {
return false;
} else {
return true;
}
}
// 定义点击标记时的回调函数
void onTapMarkerFunction(Map<String, dynamic> map) {
print('onTapMarkerFunction: $map');
}
Future<void> processData() async {
// 解析测试用的GeoJson字符串
geoJsonParser.parseGeoJsonAsString(testGeoJson);
}
@override
void initState() {
geoJsonParser.setDefaultMarkerTapCallback(onTapMarkerFunction);
geoJsonParser.filterFunction = myFilterFunction;
loadingData = true;
processData().then((_) {
setState(() {
loadingData = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('GeoJson Processing time: ${Stopwatch()..start()}'),
duration: const Duration(milliseconds: 5000),
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.green,
),
);
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: FlutterMap(
mapController: MapController(),
options: const MapOptions(
initialCenter: LatLng(45.993807, 14.483972),
initialZoom: 14,
),
children: [
TileLayer(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: const ['a', 'b', 'c'],
),
if (!loadingData)
PolygonLayer(polygons: geoJsonParser.polygons),
if (!loadingData)
PolylineLayer(polylines: geoJsonParser.polylines),
if (!loadingData)
MarkerLayer(markers: geoJsonParser.markers),
if (!loadingData)
CircleLayer(circles: geoJsonParser.circles),
if (loadingData)
const Center(child: CircularProgressIndicator()),
],
),
);
}
}
示例GeoJson数据
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[0, 0],
[14.48295359322937, 45.997073943280554],
[14.48544268319519, 45.99498698835544],
[14.485614344572143, 45.992124750758606],
[14.485356852506714, 45.99033577708827],
[14.478318736051635, 45.98801002486849],
[14.475314661954956, 45.99528512959203]
]
],
[
[
[14.486300990079956, 45.997670201660156],
[14.493510767911987, 45.99933969094237],
[14.49668650338562, 45.99361551797875],
[14.488532587980346, 45.991409168229445],
[14.486043498014526, 45.990872475261],
[14.486043498014526, 45.99516587329015],
[14.4832110852948, 45.99737207327347],
[14.486300990079956, 45.997670201660156]
],
[
[14.48706543480164, 45.99650302788219],
[14.490992188799442, 45.997486860913625],
[14.492451310503544, 45.99505705971195],
[14.488138318407596, 45.99395392456707],
[14.48706543480164, 45.99650302788219]
],
[
[14.4890395406366, 45.99229686071988],
[14.493502736437382, 45.993429843946096],
[14.49281609092957, 45.99435410255712],
[14.488524556505741, 45.99319132308913],
[14.4890395406366, 45.99229686071988]
]
]
]
},
"properties": {
"gid": 14,
"obmocje": "Test polygon"
}
},
{
"type": "Feature",
"geometry": {
"type": "MultiPoint",
"coordinates": [
[14.482672, 45.989040],
[14.489469, 45.990370]
]
},
"properties": {
"section": "Multipoint M-10"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [14.481, 45.982]
},
"properties": {
"section": "Point M-4"
}
},
{
"type": "Feature",
"geometry": {
"type": "Circle",
"coordinates": [14.481, 45.982]
},
"properties": {
"section": "Multipoint M-10",
"radius": 250
}
}
]
}
以上代码展示了如何配置flutter_map_geojson
插件以及如何将其与flutter_map
结合使用,以展示来自GeoJson的数据。此外,还介绍了如何自定义标记点击事件的处理逻辑和根据要素属性进行筛选的方法。
更多关于Flutter地理JSON地图渲染插件flutter_map_geojson的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地理JSON地图渲染插件flutter_map_geojson的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 flutter_map_geojson
插件在 Flutter 应用中渲染地理 JSON 地图的示例代码。这个插件允许你将 GeoJSON 数据渲染到 flutter_map
地图上。
首先,确保你的 pubspec.yaml
文件中包含以下依赖项:
dependencies:
flutter:
sdk: flutter
flutter_map: ^0.14.0 # 请检查最新版本
flutter_map_geojson: ^0.3.0 # 请检查最新版本
然后运行 flutter pub get
来获取这些依赖项。
接下来,创建一个 Flutter 应用并在你的 Dart 文件中使用以下代码:
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:flutter_map_geojson/flutter_map_geojson.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter GeoJSON Map'),
),
body: MapScreen(),
),
);
}
}
class MapScreen extends StatelessWidget {
final String geoJsonData = '''
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"name": "Sample Point"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
},
"properties": {
"name": "Sample Line"
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]
]
]
},
"properties": {
"name": "Sample Polygon"
}
}
]
}
''';
@override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(0.0, 100.0),
zoom: 4.0,
),
layers: [
TileLayerOptions(
urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c'],
),
GeoJsonLayer(
geoJsonData: jsonDecode(geoJsonData),
pointBuilder: (context, document) {
return Marker(
width: 8.0,
height: 8.0,
point: LatLng(document['geometry']['coordinates'][1], document['geometry']['coordinates'][0]),
builder: (context) => Container(
child: Icon(
Icons.location_on,
color: Colors.red,
),
),
);
},
lineBuilder: (context, document) {
return Polyline(
points: document['geometry']['coordinates']
.map((coord) => LatLng(coord[1], coord[0]))
.toList(),
color: Colors.blue,
width: 2.0,
);
},
polygonBuilder: (context, document) {
return PolygonLayerOptions(
polygons: document['geometry']['coordinates']
.map((outer) => Polygon(
points: outer
.map((coord) => LatLng(coord[1], coord[0]))
.toList(),
borderColor: Colors.green,
borderWidth: 2.0,
color: Colors.greenAccent.withOpacity(0.5),
))
.toList(),
);
},
),
],
);
}
}
代码解释
- 依赖项:在
pubspec.yaml
中添加flutter_map
和flutter_map_geojson
依赖项。 - GeoJSON 数据:在
MapScreen
类中定义一个包含 GeoJSON 数据的字符串geoJsonData
。 - FlutterMap:创建一个
FlutterMap
组件,设置地图的中心点和缩放级别。 - TileLayer:添加一个 OpenStreetMap 的瓦片图层。
- GeoJsonLayer:使用
GeoJsonLayer
组件渲染 GeoJSON 数据。pointBuilder
:用于渲染点(Marker)。lineBuilder
:用于渲染线(Polyline)。polygonBuilder
:用于渲染多边形(PolygonLayerOptions)。
这段代码展示了如何将 GeoJSON 数据渲染到 Flutter 地图上,包括点、线和多边形。你可以根据需要调整 GeoJSON 数据和样式。