Flutter离线地理编码插件geocoder_offline的使用
Flutter离线地理编码插件geocoder_offline的使用
简介
geocoder_offline
是一个用于超快速离线反向地理编码的Dart库。该库使用k-d树来搜索给定文件中的最近位置。一旦Geocoder初始化完成,位置搜索速度非常快,大约在4-5毫秒之间。
数据准备
为了使用反向地理编码库,你需要提供一个包含地点数据的文件。以下是两个示例文件:
- GeoNames数据文件,包含全球人口超过15,000的城市。
- USGS数据文件,包含美国人口超过5,000的城市。
你可以使用任何其他包含地点名称、纬度和经度的数据文件。
使用方法
1. 导入库
首先,在你的Dart文件中导入 geocoder_offline
库:
import 'package:geocoder_offline/geocoder_offline.dart';
2. 初始化Geocoder
接下来,初始化 GeocodeData
对象。你需要提供一个包含地点数据的文件路径,并指定文件中的列名(如地点名称、州/国家、纬度、经度等)以及分隔符和行结束符。
var geocoder = GeocodeData(
File('assets/NationalFedCodes_20191101.csv').readAsStringSync(), // 输入字符串
'FEATURE_NAME', // 地点名称列名
'STATE_ALPHA', // 州/国家列名
'PRIMARY_LATITUDE', // 纬度列名
'PRIMARY_LONGITUDE', // 经度列名
fieldDelimiter: ',', // 字段分隔符
eol: '\n'); // 行结束符
3. 反向地理编码
初始化完成后,你可以使用 search
方法进行反向地理编码。传入经纬度坐标,返回一个包含匹配地点的结果列表。
List<LocationResult> result = geocoder.search(41.881832, -87.623177);
完整示例Demo
以下是一个完整的Flutter示例,展示了如何使用 geocoder_offline
插件进行离线反向地理编码。
项目结构
lib/
main.dart
assets/
NationalFedCodes_20191101.csv
main.dart
import 'package:flutter/material.dart';
import 'package:geocoder_offline/geocoder_offline.dart';
import 'dart:io';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Offline Geocoder Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: GeocoderHomePage(),
);
}
}
class GeocoderHomePage extends StatefulWidget {
[@override](/user/override)
_GeocoderHomePageState createState() => _GeocoderHomePageState();
}
class _GeocoderHomePageState extends State<GeocoderHomePage> {
late GeocodeData geocoder;
List<LocationResult>? results;
bool isLoading = false;
[@override](/user/override)
void initState() {
super.initState();
_initializeGeocoder();
}
Future<void> _initializeGeocoder() async {
setState(() {
isLoading = true;
});
try {
// 读取资产文件
final fileContent = await rootBundle.loadString('assets/NationalFedCodes_20191101.csv');
// 初始化GeocodeData
geocoder = GeocodeData(
fileContent, // 输入字符串
'FEATURE_NAME', // 地点名称列名
'STATE_ALPHA', // 州/国家列名
'PRIMARY_LATITUDE', // 纬度列名
'PRIMARY_LONGITUDE', // 经度列名
fieldDelimiter: ',', // 字段分隔符
eol: '\n', // 行结束符
);
setState(() {
isLoading = false;
});
} catch (e) {
print('Error initializing geocoder: $e');
setState(() {
isLoading = false;
});
}
}
void _performReverseGeocoding(double latitude, double longitude) {
setState(() {
isLoading = true;
});
try {
// 执行反向地理编码
List<LocationResult> result = geocoder.search(latitude, longitude);
setState(() {
results = result;
isLoading = false;
});
} catch (e) {
print('Error performing reverse geocoding: $e');
setState(() {
isLoading = false;
});
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Offline Geocoder Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
decoration: InputDecoration(
labelText: 'Latitude',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
onChanged: (value) {
// 你可以在这里处理输入的纬度值
},
),
SizedBox(height: 16.0),
TextField(
decoration: InputDecoration(
labelText: 'Longitude',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
onChanged: (value) {
// 你可以在这里处理输入的经度值
},
),
SizedBox(height: 16.0),
ElevatedButton(
onPressed: () {
// 假设用户输入了41.881832, -87.623177
_performReverseGeocoding(41.881832, -87.623177);
},
child: Text('Perform Reverse Geocoding'),
),
SizedBox(height: 16.0),
if (isLoading)
CircularProgressIndicator(),
if (results != null && !isLoading)
Expanded(
child: ListView.builder(
itemCount: results!.length,
itemBuilder: (context, index) {
final result = results![index];
return ListTile(
title: Text(result.name),
subtitle: Text('${result.latitude}, ${result.longitude}'),
);
},
),
),
],
),
),
);
}
}
更多关于Flutter离线地理编码插件geocoder_offline的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复