提交 d7470675 authored 作者: 史晓晨's avatar 史晓晨

init

上级
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
.settings/
.project
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
**/pubspec.lock
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 84f3d28555368a70270e9ac8390a9441df95e752
channel: stable
project_type: package
## [3.0.0] - 2021-11-23.
* 增加高德隐私合规配置参数类AMapPrivacyStatement
## [2.0.0] - 2021-04-21.
* 支持Flutter 2.0.0以上版本
* 升级支持null-safety
## [1.0.2] - 2021-01-27.
* AMapTools 新增两个经纬度之间距离的计算方法 static double distanceBetween(LatLng latLng1, LatLng latLng2)
## [1.0.1] - 2020-12-22.
* 1.0.1版本发布,包含基础类型定义和lbs相关的常用工具方法
Copyright <2020> <lbs.amap.com>
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# amap_flutter_base
A new Flutter package.
## Getting Started
This project is a starting point for a Dart
[package](https://flutter.dev/developing-packages/),
a library module containing code that can be shared easily across
multiple Flutter or Dart projects.
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
library amap_flutter_base;
import 'dart:ui' show Offset, hashValues;
import 'package:flutter/material.dart';
import 'dart:math';
part 'src/amap_api_key.dart';
part 'src/amap_tools.dart';
part 'src/callbacks.dart';
part 'src/location.dart';
part 'src/poi.dart';
part 'src/amap_utils.dart';
part 'src/amap_privacy_statement.dart';
part of amap_flutter_base;
///高德开放平台api key配置
///
///申请key请到高德开放平台官网:https://lbs.amap.com/
///
///Android平台的key的获取请参考:https://lbs.amap.com/api/poi-sdk-android/develop/create-project/get-key/?sug_index=2
///
///iOS平台key的获取请参考:https://lbs.amap.com/api/poi-sdk-ios/develop/create-project/get-key/?sug_index=1
class AMapApiKey {
//iOS平台的key
final String? iosKey;
//Android平台的key
final String? androidKey;
///构造AMapKeyConfig
///
///[iosKey] iOS平台的key
///
///[androidKey] Android平台的key
const AMapApiKey({this.iosKey, this.androidKey});
dynamic toMap() {
final Map<String, dynamic> json = <String, dynamic>{};
void addIfPresent(String fieldName, dynamic value) {
if (value != null) {
json[fieldName] = value;
}
}
addIfPresent('androidKey', androidKey);
addIfPresent('iosKey', iosKey);
return json;
}
@override
bool operator ==(dynamic other) {
if (identical(this, other)) return true;
if (runtimeType != other.runtimeType) return false;
final AMapApiKey typedOther = other;
return androidKey == typedOther.androidKey && iosKey == typedOther.iosKey;
}
@override
int get hashCode => hashValues(androidKey, iosKey);
@override
String toString() {
return 'AMapApiKey(androidKey: $androidKey, iosKey: $iosKey)';
}
}
part of amap_flutter_base;
///高德开放平台用户隐私声明配置
///
///高德SDK合规使用方案请参考:https://lbs.amap.com/news/sdkhgsy
class AMapPrivacyStatement {
/// 隐私权政策是否包含高德开平隐私权政策
final bool ?hasContains;
/// 隐私权政策是否弹窗展示告知用户
final bool ?hasShow;
/// 隐私权政策是否已经取得用户同意
final bool ?hasAgree;
///构造AMapPrivacyStatement
///
///[hasContains] 隐私权政策是否包含高德开平隐私权政策
///
///[hasShow] 隐私权政策是否弹窗展示告知用户
///
///[hasAgree] 隐私权政策是否已经取得用户同意
const AMapPrivacyStatement({@required this.hasContains = false, @required this.hasShow=false, @required this
.hasAgree=false});
dynamic toMap() {
final Map<String, dynamic> json = <String, dynamic>{};
void addIfPresent(String fieldName, dynamic value) {
if (value != null) {
json[fieldName] = value;
}
}
addIfPresent('hasContains', hasContains);
addIfPresent('hasShow', hasShow);
addIfPresent('hasAgree', hasAgree);
return json;
}
@override
bool operator ==(dynamic other) {
if (identical(this, other)) return true;
if (runtimeType != other.runtimeType) return false;
final AMapPrivacyStatement typedOther = other;
return hasContains == typedOther.hasContains
&& hasShow == typedOther.hasShow
&& hasAgree == typedOther.hasAgree;
}
@override
int get hashCode => hashValues(hasContains, hasShow, hasAgree);
@override
String toString() {
return 'AMapPrivacyStatement(hasContains: $hasContains, hasShow: $hasShow, hasAgree: $hasAgree)';
}
}
\ No newline at end of file
part of amap_flutter_base;
const double EARTHRADIUS = 6378137.0;
const double DEG_TO_RAD = 0.0174532925199432958;
const double ESP = 1e-9;
const int POINT_ELEMENT_SIZE = 2;
const int A_CIRCLE_DEGREE = 360;
const int A_HALF_CIRCLE_DEGREE = 180;
const int MIN_OFFSET_DEGREE = 50;
class AMapTools {
///根据提供的多边形顶点坐标[points]计算多边形的面积
static double calculateArea(List<LatLng> points) {
int triangleCount = 3;
if (points.length < triangleCount) {
return 0.0;
}
double s = 0;
double metrePerDegree = EARTHRADIUS * DEG_TO_RAD;
int count = points.length;
for (int i = 0; i < count; ++i) {
LatLng coordPrev = points[i];
LatLng coordNext = points[((i + 1) % count)];
double x1 = coordPrev.longitude *
metrePerDegree *
cos(coordPrev.latitude * DEG_TO_RAD);
double y1 = coordPrev.latitude * metrePerDegree;
double x2 = coordNext.longitude *
metrePerDegree *
cos(coordNext.latitude * DEG_TO_RAD);
double y2 = coordNext.latitude * metrePerDegree;
s += x1 * y2 - x2 * y1;
}
return (s / 2.0).abs();
}
/// 判断坐标点[latLng]是否在多边形[latLngList]内
static bool latLngIsInPolygon(LatLng latLng, List<LatLng> latLngList) {
bool isInside = false;
int count = 0;
double linePoint1x;
double linePoint1y;
double linePoint2x = 180;
double linePoint2y;
linePoint1x = latLng.longitude;
linePoint1y = latLng.latitude;
linePoint2y = latLng.latitude;
if (latLngList.length < 3) {
return false;
}
if (latLngList[0] != (latLngList[latLngList.length - 1])) {
latLngList.add(latLngList[0]);
}
for (int i = 0; i < latLngList.length - 1; i++) {
double cx1 = latLngList[i].longitude;
double cy1 = latLngList[i].latitude;
double cx2 = latLngList[i + 1].longitude;
double cy2 = latLngList[i + 1].latitude;
if (_isPointOnLine(linePoint1x, linePoint1y, cx1, cy1, cx2, cy2)) {
return true;
}
if ((cy2 - cy1).abs() < ESP) {
continue;
}
if (_isPointOnLine(
cx1, cy1, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) {
if (cy1 > cy2) {
count++;
}
} else if (_isPointOnLine(
cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y)) {
if (cy2 > cy1) {
count++;
}
} else if (_isIntersect(cx1, cy1, cx2, cy2, linePoint1x, linePoint1y,
linePoint2x, linePoint2y)) {
count++;
}
}
if (count % POINT_ELEMENT_SIZE != 0) {
isInside = true;
}
return isInside;
}
static bool _isPointOnLine(
double px0, double py0, double px1, double py1, double px2, double py2) {
bool flag = false;
if (((_multiply(px0, py0, px1, py1, px2, py2).abs()) < ESP) &&
((px0 - px1) * (px0 - px2) <= 0) &&
((py0 - py1) * (py0 - py2) <= 0)) {
flag = true;
}
return flag;
}
static double _multiply(
double px0, double py0, double px1, double py1, double px2, double py2) {
return ((px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0));
}
static bool _isIntersect(double px1, double py1, double px2, double py2,
double px3, double py3, double px4, double py4) {
bool flag = false;
double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
if (d != 0) {
double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3)) / d;
double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1)) / d;
if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1)) {
flag = true;
}
}
return flag;
}
/// 获取点到直线上的垂足
static Offset getVerticalPointOnLine(
Offset target, Offset begin, Offset end) {
double dx = begin.dx - end.dx;
double dy = begin.dy - end.dy;
if (dx.abs() < 0.00000001 && dy.abs() < 0.00000001) {
return begin;
}
double u = ((target.dx - begin.dx) * dx + (target.dy - begin.dy) * dy) /
(dx * dx + dy * dy);
return Offset((begin.dx + u * dx), (begin.dy + u * dy));
}
///用haversine公式计算经纬度两点间的距离,
///注意:这里将地球当做了一个正球体来计算距离,当经纬度跨度较大时,有轻微的距离误差
static double distanceBetween(LatLng latLng1, LatLng latLng2) {
//经纬度转换成弧度
double lat1 = _convertDegreesToRadians(latLng1.latitude);
double lon1 = _convertDegreesToRadians(latLng1.longitude);
double lat2 = _convertDegreesToRadians(latLng2.latitude);
double lon2 = _convertDegreesToRadians(latLng2.longitude);
//差值
double detalLat = (lat1 - lat2).abs();
double detalLon = (lon1 - lon2).abs();
//h is the great circle distance in radians, great circle
//就是一个球体上的切面,它的圆心即是球心的一个周长最大的圆。
double h =
_haverSin(detalLat) + cos(lat1) * cos(lat2) * _haverSin(detalLon);
return (2 * EARTHRADIUS * asin(sqrt(h)));
}
static double _haverSin(double theta) {
var v = sin(theta / 2);
return v * v;
}
/// 将角度换算为弧度。
static double _convertDegreesToRadians(double degrees) {
return degrees * pi / 180;
}
}
part of amap_flutter_base;
class AMapUtil {
static AMapUtil _instance = AMapUtil._();
static double _devicePixelRatio = 0;
static void init(BuildContext context) {
_devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
}
AMapUtil._();
factory AMapUtil() {
return _instance;
}
/// 获取当前设备的屏幕像素比
static double get devicePixelRatio => _devicePixelRatio;
}
part of amap_flutter_base;
// 此文件中定义回调的模板类型
/// 带有一个回调参数的回调类型
typedef void ArgumentCallback<T>(T argument);
part of amap_flutter_base;
///定位信息类
///
///可提供内容包括:
///
///[provider]定位信息提供者,注意,如果是iOS平台只会返回‘iOS’
///
///[latLng]经纬度信息
///
///[accuracy] 水平精确度
///
///[altitude] 海拔
///
///[bearing] 角度
///
///[speed] 速度
///
///[time] 定位时间
///
class AMapLocation {
///定位提供者
///
///Android平台根据系统信息透出
///
///iOS平台只会返回'iOS'
final String provider;
///经纬度
final LatLng latLng;
///水平精确度
final double accuracy;
///海拔
final double altitude;
///角度
final double bearing;
///速度
final double speed;
///定位时间
final num time;
const AMapLocation({
this.provider = '',
required this.latLng,
this.accuracy = 0,
this.altitude = 0,
this.bearing = 0,
this.speed = 0,
this.time = 0,
});
static AMapLocation? fromMap(dynamic json) {
if (null == json) {
return null;
}
return AMapLocation(
provider: json['provider'],
latLng: LatLng.fromJson(json['latLng'])!,
accuracy: (json['accuracy']).toDouble(),
altitude: (json['altitude']).toDouble(),
bearing: (json['bearing']).toDouble(),
speed: (json['speed']).toDouble(),
time: json['time'],
);
}
/// Converts this object to something serializable in JSON.
dynamic toJson() {
final Map<String, dynamic> json = <String, dynamic>{};
void addIfPresent(String fieldName, dynamic value) {
if (value != null) {
json[fieldName] = value;
}
}
json['latlng'] = latLng.toJson();
addIfPresent('provider', provider);
addIfPresent('accuracy', accuracy);
addIfPresent('altitude', altitude);
addIfPresent('bearing', bearing);
addIfPresent('speed', speed);
addIfPresent('time', time);
return json;
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
if (other is! AMapLocation) {
return false;
}
final AMapLocation typedOther = other;
return provider == typedOther.provider &&
latLng == typedOther.latLng &&
accuracy == typedOther.accuracy &&
altitude == typedOther.altitude &&
bearing == typedOther.bearing &&
speed == typedOther.speed &&
time == typedOther.time;
}
@override
int get hashCode =>
hashValues(provider, latLng, accuracy, altitude, bearing, speed, time);
}
/// 经纬度坐标对象, 单位为度.
class LatLng {
///根据纬度[latitude]和经度[longitude]创建经纬度对象
///
///[latitude]取值范围 [-90.0,90.0].
///
/// [latitude]取值范围 [-180.0,179.0]
const LatLng(double latitude, double longitude)
: latitude =
(latitude < -90.0 ? -90.0 : (90.0 < latitude ? 90.0 : latitude)),
longitude = (longitude + 180.0) % 360.0 - 180.0;
/// 纬度
final double latitude;
/// 经度
final double longitude;
dynamic toJson() {
return <double>[latitude, longitude];
}
/// 根据传入的经纬度数组 \[lat, lng\] 序列化一个LatLng对象.
static LatLng? fromJson(dynamic json) {
if (json == null) {
return null;
}
return LatLng(json[0], json[1]);
}
@override
String toString() => '$runtimeType($latitude, $longitude)';
@override
bool operator ==(Object o) {
return o is LatLng && o.latitude == latitude && o.longitude == longitude;
}
@override
int get hashCode => hashValues(latitude, longitude);
}
/// 经纬度对齐的矩形.
class LatLngBounds {
/// 使用传入的西南角坐标[southwest]和东北角坐标[northeast]创建一个矩形区域.
LatLngBounds({required this.southwest, required this.northeast}) {
try {
assert(southwest.latitude <= northeast.latitude,
'西南角纬度超过了东北角纬度(${southwest.latitude} > ${northeast.latitude})');
} catch (e) {
print(e);
}
}
/// 西南角坐标.
final LatLng southwest;
/// 东北角坐标.
final LatLng northeast;
dynamic toJson() {
if (southwest.latitude > northeast.latitude) {
return null;
}
return <dynamic>[southwest.toJson(), northeast.toJson()];
}
/// 判断矩形区域是否包含传入的经纬度[point].
bool contains(LatLng point) {
try {
return _containsLatitude(point.latitude) &&
_containsLongitude(point.longitude);
} catch (e) {
print(e);
}
return false;
}
bool _containsLatitude(double lat) {
return (southwest.latitude <= lat) && (lat <= northeast.latitude);
}
bool _containsLongitude(double lng) {
if (southwest.longitude <= northeast.longitude) {
return southwest.longitude <= lng && lng <= northeast.longitude;
} else {
return southwest.longitude <= lng || lng <= northeast.longitude;
}
}
@visibleForTesting
static LatLngBounds? fromList(dynamic json) {
if (json == null) {
return null;
}
return LatLngBounds(
southwest: LatLng.fromJson(json[0])!,
northeast: LatLng.fromJson(json[1])!,
);
}
@override
String toString() {
return '$runtimeType($southwest, $northeast)';
}
@override
bool operator ==(Object o) {
return o is LatLngBounds &&
o.southwest == southwest &&
o.northeast == northeast;
}
@override
int get hashCode => hashValues(southwest, northeast);
}
part of amap_flutter_base;
///poi
class AMapPoi {
/// 唯一标识符
final String? id;
/// POI的名称
final String? name;
/// 经纬度
final LatLng? latLng;
AMapPoi({
this.id,
this.name,
this.latLng,
});
dynamic toJson() {
final Map<String, dynamic> json = <String, dynamic>{};
void addIfPresent(String fieldName, dynamic value) {
if (value != null) {
json[fieldName] = value;
}
}
addIfPresent('id', id);
addIfPresent('name', name);
addIfPresent('latLng', latLng?.toJson());
return json;
}
static AMapPoi? fromJson(dynamic json) {
if (null == json) {
return null;
}
return AMapPoi(
id: json['id'],
name: json['name'],
latLng: LatLng.fromJson(json['latLng'])!,
);
}
@override
String toString() {
return 'TouchPOI(id: $id, name: $name, latlng: $latLng)';
}
}
name: amap_flutter_base
description: 高德开放平台,Flutter插件,基础依赖库.
version: 3.0.0
homepage: https://lbs.amap.com/
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# To add custom fonts to your package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论