Flutter地理编码与反地理编码插件geocoder_buddy的使用
Flutter地理编码与反地理编码插件geocoder_buddy的使用
特性
- 易于使用
- 快速且安全
- 无需API密钥
- 更详细的数据
- 无需API密钥即可搜索位置
开始使用
在终端中运行以下命令以安装插件:
flutter pub add geocoder_buddy
搜索位置
使用GBSearchData
类来查询位置:
// GBSearchData 类由 geocoder_buddy 提供
List<GBSearchData> data = await GeocoderBuddy.query(query);
GBSearchData 类
int placeId;
int id;
List<String> boundingbox;
String lat;
String lon;
String displayName;
int placeRank;
double importance;
将 GBSearchData 转换为 GBData
使用searchToGBData
方法将GBSearchData
转换为GBData
:
// GBData 类由 geocoder_buddy 提供
GBData data = await GeocoderBuddy.searchToGBData(GBSearchData data);
根据经纬度获取详细信息
通过纬度和经度获取位置详细信息:
GBLatLng position = GBLatLng(38.8951,-77.0364);
GBData data = await GeocoderBuddy.findDetails(position);
GBData 类
int placeId;
String osmType;
int id;
String lat;
String lon;
int placeRank;
double importance;
String displayName;
Address address; // 由 geocoder_buddy 提供
List<String> boundingbox;
Address 类
String road;
String village;
String county;
String stateDistrict;
String state;
String iso31662Lvl4;
String postcode;
String country;
String countryCode;
示例代码
以下是完整的示例应用,展示如何使用 geocoder_buddy
插件进行地理编码和反地理编码。
import 'package:flutter/material.dart';
import 'package:geocoder_buddy/geocoder_buddy.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Geocoder Buddy Example',
theme: ThemeData(
useMaterial3: true,
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Geocoder Buddy Example'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final searchTextController = TextEditingController();
final latTextController = TextEditingController();
final lngTextController = TextEditingController();
List<GBSearchData> searchItem = [];
Map<String, dynamic> details = {};
bool isSearching = false;
bool isLoading = false;
void searchLocation(String query) async {
setState(() {
isSearching = true;
});
List<GBSearchData> data = await GeocoderBuddy.query(query);
setState(() {
isSearching = false;
searchItem = data;
});
}
getAddressDetails(GBLatLng pos) async {
setState(() {
isLoading = true;
});
GBData data = await GeocoderBuddy.findDetails(pos);
setState(() {
isLoading = false;
details = data.toJson();
});
print(data.address.village);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 10),
Text("Search Location", style: Theme.of(context).textTheme.headline3),
Container(
padding: const EdgeInsets.all(20),
child: TextField(
controller: searchTextController,
decoration: const InputDecoration(
hintText: "Search Location",
border: OutlineInputBorder()),
),
),
ElevatedButton(
onPressed: () {
if (searchTextController.text.isNotEmpty) {
searchLocation(searchTextController.text);
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Please Enter Location")));
}
},
child: const Text("Search")),
SizedBox(
height: 300,
child: !isSearching
? ListView.builder(
itemCount: searchItem.length,
itemBuilder: (context, index) {
var item = searchItem[index];
return ListTile(
onTap: () {
// Navigate to detail page if needed
},
title: Text(item.displayName),
);
})
: const Center(child: CircularProgressIndicator()),
),
const SizedBox(height: 20),
Text("Lat/Lng to Details", style: Theme.of(context).textTheme.headline3),
Container(
padding: const EdgeInsets.all(20),
child: TextField(
controller: latTextController,
decoration: const InputDecoration(hintText: "Latitude", border: OutlineInputBorder()),
),
),
Container(
padding: const EdgeInsets.all(20),
child: TextField(
controller: lngTextController,
decoration: const InputDecoration(hintText: "Longitude", border: OutlineInputBorder()),
),
),
ElevatedButton(
onPressed: () {
if (latTextController.text.isNotEmpty && lngTextController.text.isNotEmpty) {
GBLatLng pos = GBLatLng(lat: double.parse(latTextController.text), lng: double.parse(lngTextController.text));
getAddressDetails(pos);
} else {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Please Enter Lat/Lng")));
}
},
child: const Text("Get Details")),
const SizedBox(height: 20),
SizedBox(
height: 300,
child: !isLoading
? ListView.builder(
itemCount: details.keys.length,
itemBuilder: (context, index) {
var key = details.keys.elementAt(index);
return ListTile(
title: Text("$key: ${details[key]}"),
);
})
: const Center(child: CircularProgressIndicator()),
),
const SizedBox(height: 20),
],
),
));
}
}
以上是完整的示例代码,展示了如何使用 geocoder_buddy
插件进行地理编码和反地理编码。希望这些内容能帮助您更好地理解和使用该插件。
更多关于Flutter地理编码与反地理编码插件geocoder_buddy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地理编码与反地理编码插件geocoder_buddy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于Flutter中的地理编码与反地理编码插件geocoder_buddy
的使用,下面是一个简单的代码示例,展示了如何使用该插件进行地理编码和反地理编码操作。
首先,确保你已经在pubspec.yaml
文件中添加了geocoder_buddy
依赖:
dependencies:
flutter:
sdk: flutter
geocoder_buddy: ^latest_version # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个完整的Flutter应用示例,展示了如何使用geocoder_buddy
进行地理编码和反地理编码:
import 'package:flutter/material.dart';
import 'package:geocoder_buddy/geocoder_buddy.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Geocoder Buddy Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: GeocoderScreen(),
);
}
}
class GeocoderScreen extends StatefulWidget {
@override
_GeocoderScreenState createState() => _GeocoderScreenState();
}
class _GeocoderScreenState extends State<GeocoderScreen> {
String _address = '';
String _latitude = '';
String _longitude = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Geocoder Buddy Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Enter Address'),
onChanged: (value) {
setState(() {
_address = value;
});
},
),
SizedBox(height: 16),
ElevatedButton(
onPressed: _geocodeAddress,
child: Text('Geocode Address'),
),
SizedBox(height: 16),
Text('Latitude: $_latitude'),
SizedBox(height: 8),
Text('Longitude: $_longitude'),
SizedBox(height: 32),
ElevatedButton(
onPressed: _reverseGeocode,
child: Text('Reverse Geocode'),
),
SizedBox(height: 16),
Text('Address: $_address'),
],
),
),
);
}
Future<void> _geocodeAddress() async {
if (_address.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Address cannot be empty')));
return;
}
final Geocoding geocoding = Geocoding();
List<Placemark> placemarks = await geocoding.placemarkFromAddress(_address);
if (placemarks.isNotEmpty) {
Placemark place = placemarks.first;
setState(() {
_latitude = place.position?.latitude.toString() ?? '';
_longitude = place.position?.longitude.toString() ?? '';
});
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Address not found')));
}
}
Future<void> _reverseGeocode() async {
double lat = double.tryParse(_latitude) ?? 0.0;
double lng = double.tryParse(_longitude) ?? 0.0;
if (lat == 0.0 || lng == 0.0) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Latitude and Longitude cannot be empty')));
return;
}
final Geocoding geocoding = Geocoding();
List<Placemark> placemarks = await geocoding.placemarkFromCoordinates(lat, lng);
if (placemarks.isNotEmpty) {
Placemark place = placemarks.first;
setState(() {
_address = '${place.thoroughfare}, ${place.subThoroughfare}, ${place.locality}, ${place.postalCode}, ${place.country}';
});
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Coordinates not found')));
}
}
}
注意事项:
- 在实际使用中,确保设备具有网络权限,因为地理编码与反地理编码操作需要访问网络。
geocoder_buddy
插件实际上依赖于geolocator
和geocoding
插件进行地理定位与编码操作。上面的代码示例实际上结合了geocoding
插件进行地理编码与反地理编码,因为geocoder_buddy
并不是一个官方或广泛使用的Flutter插件名称。如果geocoder_buddy
是一个自定义或特定项目中的插件名称,请确保按照其实际API文档进行调整。- 在实际项目中,可能还需要处理异常和错误情况,例如网络错误、API限制等。
如果geocoder_buddy
确实是你项目中特定的插件,并且有不同的API调用方式,请参考该插件的官方文档或源代码进行调整。