Flutter坐标计算插件coordinate_calculator的使用
Flutter坐标计算插件coordinate_calculator的使用
coordinate_calculator
插件用于在 Flutter 应用中进行坐标计算。本文将详细介绍如何安装和使用该插件,并提供一个完整的示例来展示其功能。
使用
首先,在 pubspec.yaml
文件中添加 coordinate_calculator
插件依赖:
dependencies:
coordinate_calculator:
git:
url: https://github.com/DeliriousLee/CoordinateCalculator.git
然后在 Dart 文件中导入该插件:
import 'package:coordinate_calculator/coordinate_calculator.dart';
接下来,我们可以使用插件提供的方法来计算两个坐标之间的距离(以公里为单位):
var result = DLCoordinateManager.kilometersDistanceFrom(
lat1: double.parse(_originLatitude.text),
long1: double.parse(_originLong.text),
lat2: double.parse(_destLatitude.text),
long2: double.parse(_destLong.text));
示例
以下是一个完整的示例,展示了如何在 Flutter 应用中使用 coordinate_calculator
插件来计算两个地点之间的直线距离。
主要文件
main.dart
import 'package:coordinate_calculator/coordinate_calculator.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'coordinate_calculator Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Coordinate Calculator 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> {
double calculatorResult = 0.0;
final TextEditingController _originLong = TextEditingController();
final TextEditingController _originLatitude = TextEditingController();
final TextEditingController _destLong = TextEditingController();
final TextEditingController _destLatitude = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 54),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 150),
const Text('请填写起始目标经纬度后\n点击计算按钮',
style: TextStyle(
color: Color(0xff333333),
fontSize: 24,
fontWeight: FontWeight.w700)),
const SizedBox(height: 40),
Row(
children: <Widget>[
Container(
child: const Text('起始经度'),
),
const SizedBox(width: 10),
_buildTextField(
controller: _originLong,
hintText: '请输入起始地经度',
formats: [
FilteringTextInputFormatter(RegExp("[0-9.]"), allow: true)
]),
],
),
Container(
height: 1,
color: const Color(0xffEEEEEE),
),
Row(
children: <Widget>[
Container(
child: const Text('起始纬度'),
),
const SizedBox(width: 10),
_buildTextField(
controller: _originLatitude,
hintText: '请输入起始地纬度',
formats: [
FilteringTextInputFormatter(RegExp("[0-9.]"), allow: true)
]),
],
),
Container(
height: 1,
color: const Color(0xffEEEEEE),
),
const SizedBox(height: 20),
Row(
children: <Widget>[
Container(
child: const Text('目标经度'),
),
const SizedBox(width: 10),
_buildTextField(
controller: _destLong,
hintText: '请输入目的地经度',
formats: [
FilteringTextInputFormatter(RegExp("[0-9.]"), allow: true)
]),
],
),
Container(
height: 1,
color: const Color(0xffEEEEEE),
),
Row(
children: <Widget>[
Container(
child: const Text('目标纬度'),
),
const SizedBox(width: 10),
_buildTextField(
controller: _destLatitude,
hintText: '请输入目的地纬度',
formats: [
FilteringTextInputFormatter(RegExp("[0-9.]"), allow: true)
]),
],
),
Container(
height: 1,
color: const Color(0xffEEEEEE),
),
SizedBox(height: 32),
GestureDetector(
onTap: () {
if (_originLong.text.isEmpty ||
_originLatitude.text.isEmpty ||
_destLatitude.text.isEmpty ||
_destLong.text.isEmpty) {
return;
}
var result = DLCoordinateManager.kilometersDistanceFrom(
lat1: double.parse(_originLatitude.text),
long1: double.parse(_originLong.text),
lat2: double.parse(_destLatitude.text),
long2: double.parse(_destLong.text));
calculatorResult = result;
setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 8),
child: Center(
child: Text('点击计算',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500)),
),
width: double.infinity,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(8))),
),
),
SizedBox(height: 20),
Text('起始到目的地的距离为${calculatorResult} km',
style: TextStyle(
color: Color(0xff333333),
fontSize: 24,
fontWeight: FontWeight.w700))
],
),
),
);
}
Widget _buildTextField({
required TextEditingController controller,
String? hintText,
TextInputType? keyboard,
List<TextInputFormatter>? formats,
bool visible = true,
}) {
return Flexible(
child: SizedBox(
height: 36,
child: TextField(
inputFormatters: formats,
keyboardType: keyboard,
obscureText: !visible,
cursorColor: Colors.blue,
style: const TextStyle(
color: Color(0xff333333),
fontSize: 16,
fontWeight: FontWeight.w500),
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 1),
hintText: hintText,
hintStyle: const TextStyle(
color: Color(0xff999999),
fontSize: 12,
fontWeight: FontWeight.w500),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(width: 0.0, color: Colors.transparent)),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(width: 0.0, color: Colors.transparent)),
),
controller: controller,
),
),
);
}
}
示例效果
以下是运行上述代码后的示例效果图:
大圆公式
大圆公式用于计算地球上两点之间的距离。公式如下:
d = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon1 - lon2))
等价且较少出现舍入误差的公式为:
d = 2 * asin(sqrt((sin((lat1 - lat2) / 2))^2 +
cos(lat1) * cos(lat2) * (sin((lon1 - lon2) / 2))^2))
更多关于Flutter坐标计算插件coordinate_calculator的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter坐标计算插件coordinate_calculator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 coordinate_calculator
插件进行坐标计算的 Flutter 代码示例。这个插件通常用于地理坐标(经纬度)之间的转换和计算,比如距离计算等。
首先,确保你已经在 pubspec.yaml
文件中添加了 coordinate_calculator
依赖:
dependencies:
flutter:
sdk: flutter
coordinate_calculator: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get
来获取依赖。
以下是一个简单的 Flutter 应用示例,展示如何使用 coordinate_calculator
插件来计算两个地理坐标之间的距离:
import 'package:flutter/material.dart';
import 'package:coordinate_calculator/coordinate_calculator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Coordinate Calculator Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _lat1Controller = TextEditingController();
final TextEditingController _lon1Controller = TextEditingController();
final TextEditingController _lat2Controller = TextEditingController();
final TextEditingController _lon2Controller = TextEditingController();
String _distance = '';
void _calculateDistance() {
double lat1 = double.tryParse(_lat1Controller.text) ?? 0.0;
double lon1 = double.tryParse(_lon1Controller.text) ?? 0.0;
double lat2 = double.tryParse(_lat2Controller.text) ?? 0.0;
double lon2 = double.tryParse(_lon2Controller.text) ?? 0.0;
// 使用 coordinate_calculator 计算距离
double distance = haversine(lat1, lon1, lat2, lon2);
setState(() {
_distance = '${distance.toStringAsFixed(2)} km';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Coordinate Calculator Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
controller: _lat1Controller,
decoration: InputDecoration(labelText: 'Latitude 1'),
keyboardType: TextInputType.numberWithOptions(decimal: true),
),
SizedBox(height: 16),
TextField(
controller: _lon1Controller,
decoration: InputDecoration(labelText: 'Longitude 1'),
keyboardType: TextInputType.numberWithOptions(decimal: true),
),
SizedBox(height: 16),
TextField(
controller: _lat2Controller,
decoration: InputDecoration(labelText: 'Latitude 2'),
keyboardType: TextInputType.numberWithOptions(decimal: true),
),
SizedBox(height: 16),
TextField(
controller: _lon2Controller,
decoration: InputDecoration(labelText: 'Longitude 2'),
keyboardType: TextInputType.numberWithOptions(decimal: true),
),
SizedBox(height: 24),
ElevatedButton(
onPressed: _calculateDistance,
child: Text('Calculate Distance'),
),
SizedBox(height: 16),
Text(
'Distance: $_distance',
style: TextStyle(fontSize: 18),
),
],
),
),
);
}
}
// haversine 函数计算两个地理坐标之间的距离(单位:公里)
double haversine(double lat1, double lon1, double lat2, double lon2) {
final R = 6371e3; // 地球半径,单位:米
final φ1 = lat1.toRadians();
final φ2 = lat2.toRadians();
final Δφ = (lat2 - lat1).toRadians();
final Δλ = (lon2 - lon1).toRadians();
final a = sin(Δφ / 2) * sin(Δφ / 2) +
cos(φ1) * cos(φ2) * sin(Δλ / 2) * sin(Δλ / 2);
final c = 2 * atan2(sqrt(a), sqrt(1 - a));
return R * c; // 距离,单位:米,转换为公里需要除以1000
}
请注意,这里我们实际上并没有直接使用 coordinate_calculator
插件提供的 haversine
函数,而是手动实现了它,以便展示其背后的数学原理。coordinate_calculator
插件内部已经实现了这些功能,你可以直接使用它提供的 API。然而,由于插件的具体 API 可能会随着版本更新而变化,请参考插件的官方文档以获取最新的使用方法。
如果你希望直接使用插件提供的函数,可以替换 _calculateDistance
方法中的自定义 haversine
函数调用为插件提供的相应方法。例如:
void _calculateDistance() {
double lat1 = double.tryParse(_lat1Controller.text) ?? 0.0;
double lon1 = double.tryParse(_lon1Controller.text) ?? 0.0;
double lat2 = double.tryParse(_lat2Controller.text) ?? 0.0;
double lon2 = double.tryParse(_lon2Controller.text) ?? 0.0;
// 假设插件提供了一个名为 haversine 的函数
// double distance = CoordinateCalculator.haversine(lat1, lon1, lat2, lon2);
// 注意:上面的代码是假设性的,请查阅插件文档获取正确的方法调用方式
// 由于我们不知道插件的确切 API,这里我们仍然使用自定义的 haversine 函数
double distance = haversine(lat1, lon1, lat2, lon2) / 1000; // 转换为公里
setState(() {
_distance = '${distance.toStringAsFixed(2)} km';
});
}
请查阅 coordinate_calculator
插件的文档以获取最新的 API 使用方法,并根据需要调整代码。