提交 412224a8 authored 作者: guoqing's avatar guoqing

feat:适配 flutter 3.38.3

上级 55bca669
......@@ -4,24 +4,25 @@ version '1.0'
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.android.tools.build:gradle:8.11.1'
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}
apply plugin: 'com.android.library'
android {
namespace 'com.amap.flutter.map'
compileSdkVersion 31
defaultConfig {
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amap.flutter.amap_flutter_map">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'dev.flutter.flutter-gradle-plugin'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystorePropertiesFile = rootProject.file("app/key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 31
namespace 'com.amap.flutter.test_map'
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
lintOptions {
disable 'InvalidPackage'
......@@ -38,32 +31,42 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.amap.flutter.test_map"
minSdkVersion 16
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
minSdk flutter.minSdkVersion
targetSdk flutter.targetSdkVersion
versionCode flutter.versionCode
versionName flutter.versionName
}
signingConfigs {
release {
//keystore中key的别名
keyAlias keystoreProperties['keyAlias']
//keystore中key的密码
keyPassword keystoreProperties['keyPassword']
//keystore的文件路径,可以是绝对路径也可以是相对路径
storeFile file(keystoreProperties['storeFile'])
//keystore的密码l
storePassword keystoreProperties['storePassword']
if (keystorePropertiesFile.exists()) {
//keystore中key的别名
keyAlias keystoreProperties['keyAlias']
//keystore中key的密码
keyPassword keystoreProperties['keyPassword']
//keystore的文件路径,可以是绝对路径也可以是相对路径
storeFile file(keystoreProperties['storeFile'])
//keystore的密码l
storePassword keystoreProperties['storePassword']
}
}
}
buildTypes {
debug {
signingConfig signingConfigs.release
signingConfig keystorePropertiesFile.exists()
? signingConfigs.release
: signingConfigs.debug
}
release {
// flutter build apk
signingConfig signingConfigs.release
signingConfig keystorePropertiesFile.exists()
? signingConfigs.release
: signingConfigs.debug
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
......
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}
......@@ -24,6 +13,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
tasks.register("clean", Delete) {
delete rootProject.layout.buildDirectory
}
......@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.11.1" apply false
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
include ':app'
......@@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>9.0</string>
<string>13.0</string>
</dict>
</plist>
#
# Generated file, do not edit.
#
import lldb
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
base = frame.register["x0"].GetValueAsAddress()
page_len = frame.register["x1"].GetValueAsUnsigned()
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
# first page to see if handled it correctly. This makes diagnosing
# misconfiguration (e.g. missing breakpoint) easier.
data = bytearray(page_len)
data[0:8] = b'IHELPED!'
error = lldb.SBError()
frame.GetThread().GetProcess().WriteMemory(base, data, error)
if not error.Success():
print(f'Failed to write into {base}[+{page_len}]', error)
return
def __lldb_init_module(debugger: lldb.SBDebugger, _):
target = debugger.GetDummyTarget()
# Caveat: must use BreakpointCreateByRegEx here and not
# BreakpointCreateByName. For some reasons callback function does not
# get carried over from dummy target for the later.
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
bp.SetAutoContinue(True)
print("-- LLDB integration loaded --")
#
# Generated file, do not edit.
#
command script import --relative-to-command-file flutter_lldb_helper.py
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
......
PODS:
- AMap3DMap (8.1.0):
- AMapFoundation (~> 1.6.9)
- amap_flutter_map (0.0.1):
- AMap3DMap
- AMapNavi
- AMapSearch
- Flutter
- AMapFoundation (1.6.9)
- AMapNavi (8.1.0):
- AMapFoundation (~> 1.6.9)
- AMapSearch (9.2.0):
- AMapFoundation (~> 1.6.9)
- Flutter (1.0.0)
- permission_handler_apple (9.0.4):
- permission_handler_apple (9.1.1):
- Flutter
DEPENDENCIES:
......@@ -19,8 +19,8 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- AMap3DMap
- AMapFoundation
- AMapNavi
- AMapSearch
EXTERNAL SOURCES:
......@@ -32,13 +32,13 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/permission_handler_apple/ios"
SPEC CHECKSUMS:
AMap3DMap: 135eaaf64a29aeb2f0bca07670db26fbf3271245
amap_flutter_map: f3fe3434a2e11b12a9d0e2194ee6ff5a534702fe
amap_flutter_map: f87bda918a6a47003f07873dba6004496602618b
AMapFoundation: 8d8ecbb0b2e9ce5487995360d26c885d94642bfd
AMapNavi: 257ceddc7f4e26012e284e7b6c08f72e95fd1759
AMapSearch: b461cdf25b39cdca8957017de2f376cd1ac5da85
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
permission_handler_apple: 3787117e48f80715ff04a3830ca039283d6a4f29
PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d
PODFILE CHECKSUM: d85ddc5f90e8c593f9dc16ef40fc88253b4f8f6b
COCOAPODS: 1.10.1
COCOAPODS: 1.16.2
......@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
......@@ -166,7 +166,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
......@@ -209,10 +209,12 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
......@@ -262,6 +264,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
......@@ -350,7 +353,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
......@@ -436,7 +439,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
......@@ -485,7 +488,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
......
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......@@ -48,6 +48,7 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
......
......@@ -52,5 +52,9 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
......@@ -6,14 +6,14 @@ description: Demonstrates how to use the amap_flutter_map plugin.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: ">=2.12.0 <3.0.0"
sdk: ^3.10.1
dependencies:
flutter:
sdk: flutter
permission_handler: ^9.2.0
flutter_plugin_android_lifecycle: ^2.0.0
permission_handler: ^12.0.1
flutter_plugin_android_lifecycle: ^2.0.33
amap_flutter_map:
# When depending on this package from a real application you should use:
......@@ -28,12 +28,16 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0
cupertino_icons: ^1.0.8
dev_dependencies:
flutter_test:
sdk: flutter
dependency_overrides:
amap_flutter_base:
path: ../third_party/amap_flutter_base
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
......
......@@ -2,7 +2,6 @@
library amap_flutter_map;
import 'dart:async';
import 'dart:typed_data';
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:amap_flutter_map/src/core/amap_flutter_platform.dart';
......
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:flutter/cupertino.dart';
/// 相机位置,包含可视区域的位置参数。
class CameraPosition {
......@@ -29,11 +28,11 @@ class CameraPosition {
///
/// 主要在插件内部使用
dynamic toMap() => <String, dynamic>{
'bearing': bearing,
'target': target.toJson(),
'tilt': tilt,
'zoom': zoom,
};
'bearing': bearing,
'target': target.toJson(),
'tilt': tilt,
'zoom': zoom,
};
/// 从Map转换成[CameraPosition]
///
......@@ -66,7 +65,7 @@ class CameraPosition {
}
@override
int get hashCode => hashValues(bearing, target, tilt, zoom);
int get hashCode => Object.hash(bearing, target, tilt, zoom);
@override
String toString() =>
......@@ -81,9 +80,10 @@ class CameraUpdate {
///
///主要用于改变地图的中心点、缩放级别、倾斜角、角度等信息
static CameraUpdate newCameraPosition(CameraPosition cameraPosition) {
return CameraUpdate._(
<dynamic>['newCameraPosition', cameraPosition.toMap()],
);
return CameraUpdate._(<dynamic>[
'newCameraPosition',
cameraPosition.toMap(),
]);
}
///移动到一个新的位置点[latLng]
......@@ -108,9 +108,7 @@ class CameraUpdate {
///
/// 主要用于同时改变中心点和缩放级别
static CameraUpdate newLatLngZoom(LatLng latLng, double zoom) {
return CameraUpdate._(
<dynamic>['newLatLngZoom', latLng.toJson(), zoom],
);
return CameraUpdate._(<dynamic>['newLatLngZoom', latLng.toJson(), zoom]);
}
/// 按照指定到像素点[dx]和[dy]移动地图中心点
......@@ -121,9 +119,7 @@ class CameraUpdate {
///
/// 返回包含x,y方向上移动像素数的cameraUpdate对象。
static CameraUpdate scrollBy(double dx, double dy) {
return CameraUpdate._(
<dynamic>['scrollBy', dx, dy],
);
return CameraUpdate._(<dynamic>['scrollBy', dx, dy]);
}
/// 创建一个在当前地图显示的级别基础上加1的CameraUpdate对象
......
......@@ -2,11 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues, Offset;
import 'dart:ui' show Offset;
import 'package:amap_flutter_map/src/types/base_overlay.dart';
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'bitmap.dart';
import 'base_overlay.dart';
/// Marker拖动回调
typedef void MarkerDragEndCallback(String id, LatLng endPosition);
......@@ -16,10 +15,7 @@ typedef void MarkerDragEndCallback(String id, LatLng endPosition);
///Android和iOS的实现机制有差异,仅在接口层面拉齐,效果一致
class InfoWindow {
/// 为 [Marker] 产生一个不可修改的文本气泡.
const InfoWindow({
this.title,
this.snippet,
});
const InfoWindow({this.title, this.snippet});
/// 无文本的气泡
static const InfoWindow noText = InfoWindow();
......@@ -32,10 +28,7 @@ class InfoWindow {
/// 气泡copy方法
///
InfoWindow copyWith({
String? titleParam,
String? snippetParam,
}) {
InfoWindow copyWith({String? titleParam, String? snippetParam}) {
return InfoWindow(
title: titleParam ?? title,
snippet: snippetParam ?? snippet,
......@@ -60,7 +53,7 @@ class InfoWindow {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
if (other is !InfoWindow) {
if (other is! InfoWindow) {
return false;
}
final InfoWindow typedOther = other;
......@@ -68,7 +61,7 @@ class InfoWindow {
}
@override
int get hashCode => hashValues(title, snippet);
int get hashCode => Object.hash(title, snippet);
@override
String toString() {
......@@ -92,19 +85,16 @@ class Marker extends BaseOverlay {
this.zIndex = 0.0,
this.onTap,
this.onDragEnd,
}) : this.alpha =
// ignore: unnecessary_null_comparison
(alpha != null ? (alpha < 0 ? 0 : (alpha > 1 ? 1 : alpha)) : alpha),
// ignore: unnecessary_null_comparison
this.anchor = (anchor == null
? Offset(0.5, 1.0)
: ((anchor.dx < 0 ||
anchor.dx > 1 ||
anchor.dy < 0 ||
anchor.dy > 1)
? Offset(0.5, 1.0)
: anchor)),
super();
}) : this.alpha =
// ignore: unnecessary_null_comparison
(alpha != null ? (alpha < 0 ? 0 : (alpha > 1 ? 1 : alpha)) : alpha),
// ignore: unnecessary_null_comparison
this.anchor = (anchor == null
? Offset(0.5, 1.0)
: ((anchor.dx < 0 || anchor.dx > 1 || anchor.dy < 0 || anchor.dy > 1)
? Offset(0.5, 1.0)
: anchor)),
super();
/// 透明度
final double alpha;
......@@ -161,7 +151,7 @@ class Marker extends BaseOverlay {
LatLng? positionParam,
double? rotationParam,
bool? visibleParam,
ArgumentCallback<String?> ? onTapParam,
ArgumentCallback<String?>? onTapParam,
MarkerDragEndCallback? onDragEndParam,
}) {
Marker copyMark = Marker(
......@@ -218,7 +208,7 @@ class Marker extends BaseOverlay {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
if(other is !Marker) return false;
if (other is! Marker) return false;
final Marker typedOther = other;
return id == typedOther.id &&
alpha == typedOther.alpha &&
......@@ -247,6 +237,9 @@ class Marker extends BaseOverlay {
}
Map<String, Marker> keyByMarkerId(Iterable<Marker> markers) {
return Map<String, Marker>.fromEntries(markers.map(
(Marker marker) => MapEntry<String, Marker>(marker.id, marker.clone())));
return Map<String, Marker>.fromEntries(
markers.map(
(Marker marker) => MapEntry<String, Marker>(marker.id, marker.clone()),
),
);
}
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart' show setEquals;
import 'types.dart';
......@@ -29,8 +27,9 @@ class MarkerUpdates {
return currentMarkers[id]!;
}
final Set<String> _markerIdsToRemove =
prevMarkerIds.difference(currentMarkerIds);
final Set<String> _markerIdsToRemove = prevMarkerIds.difference(
currentMarkerIds,
);
final Set<Marker> _markersToAdd = currentMarkerIds
.difference(prevMarkerIds)
......@@ -82,7 +81,7 @@ class MarkerUpdates {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
if(other is !MarkerUpdates) return false;
if (other is! MarkerUpdates) return false;
final MarkerUpdates typedOther = other;
return setEquals(markersToAdd, typedOther.markersToAdd) &&
setEquals(markerIdsToRemove, typedOther.markerIdsToRemove) &&
......@@ -91,7 +90,7 @@ class MarkerUpdates {
@override
int get hashCode =>
hashValues(markersToAdd, markerIdsToRemove, markersToChange);
Object.hash(markersToAdd, markerIdsToRemove, markersToChange);
@override
String toString() {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart' show setEquals;
import 'types.dart';
......@@ -31,8 +29,9 @@ class PolygonUpdates {
return currentPolygons[id]!;
}
final Set<String> _polygonIdsToRemove =
prevPolygonIds.difference(currentPolygonIds);
final Set<String> _polygonIdsToRemove = prevPolygonIds.difference(
currentPolygonIds,
);
final Set<Polygon> _polygonsToAdd = currentPolygonIds
.difference(prevPolygonIds)
......@@ -85,7 +84,7 @@ class PolygonUpdates {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
if (other is !PolygonUpdates) return false;
if (other is! PolygonUpdates) return false;
final PolygonUpdates typedOther = other;
return setEquals(polygonsToAdd, typedOther.polygonsToAdd) &&
setEquals(polygonIdsToRemove, typedOther.polygonIdsToRemove) &&
......@@ -94,7 +93,7 @@ class PolygonUpdates {
@override
int get hashCode =>
hashValues(polygonsToAdd, polygonIdsToRemove, polygonsToChange);
Object.hash(polygonsToAdd, polygonIdsToRemove, polygonsToChange);
@override
String toString() {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show hashValues;
import 'package:flutter/foundation.dart' show setEquals;
import 'polyline.dart';
......@@ -33,8 +31,9 @@ class PolylineUpdates {
return currentPolylines[id]!;
}
final Set<String> _polylineIdsToRemove =
prevPolylineIds.difference(currentPolylineIds);
final Set<String> _polylineIdsToRemove = prevPolylineIds.difference(
currentPolylineIds,
);
final Set<Polyline> _polylinesToAdd = currentPolylineIds
.difference(prevPolylineIds)
......@@ -87,7 +86,7 @@ class PolylineUpdates {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
if (other is !PolylineUpdates) return false;
if (other is! PolylineUpdates) return false;
final PolylineUpdates typedOther = other;
return setEquals(polylinesToAdd, typedOther.polylinesToAdd) &&
setEquals(polylineIdsToRemove, typedOther.polylineIdsToRemove) &&
......@@ -96,7 +95,7 @@ class PolylineUpdates {
@override
int get hashCode =>
hashValues(polylinesToAdd, polylineIdsToRemove, polylinesToChange);
Object.hash(polylinesToAdd, polylineIdsToRemove, polylinesToChange);
@override
String toString() {
......
import 'dart:typed_data';
import 'dart:ui' show Color, hashValues;
import 'dart:ui' show Color;
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:amap_flutter_map/amap_flutter_map.dart';
......@@ -63,8 +63,14 @@ class MinMaxZoomPreference {
/// 缩放级别范围为[3, 20],超出范围取边界值
///
const MinMaxZoomPreference(double minZoom, double maxZoom)
: this.minZoom = ((minZoom < 3 ? 3 : minZoom) > (maxZoom > 20 ? 20 : maxZoom) ? maxZoom : minZoom),
this.maxZoom = ((minZoom < 3 ? 3 : minZoom) > (maxZoom > 20 ? 20 : maxZoom) ? minZoom : maxZoom);
: this.minZoom =
((minZoom < 3 ? 3 : minZoom) > (maxZoom > 20 ? 20 : maxZoom)
? maxZoom
: minZoom),
this.maxZoom =
((minZoom < 3 ? 3 : minZoom) > (maxZoom > 20 ? 20 : maxZoom)
? minZoom
: maxZoom);
/// 最小zoomLevel
final double? minZoom;
......@@ -73,8 +79,10 @@ class MinMaxZoomPreference {
final double? maxZoom;
/// 高德地图默认zoomLevel的范围.
static const MinMaxZoomPreference defaultPreference =
MinMaxZoomPreference(3, 20);
static const MinMaxZoomPreference defaultPreference = MinMaxZoomPreference(
3,
20,
);
/// JSON序列化.
dynamic toJson() => <dynamic>[minZoom, maxZoom];
......@@ -88,7 +96,7 @@ class MinMaxZoomPreference {
}
@override
int get hashCode => hashValues(minZoom, maxZoom);
int get hashCode => Object.hash(minZoom, maxZoom);
@override
String toString() {
......@@ -165,7 +173,7 @@ class MyLocationStyleOptions {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (runtimeType != other.runtimeType) return false;
if (other is !MyLocationStyleOptions) return false;
if (other is! MyLocationStyleOptions) return false;
final MyLocationStyleOptions typedOther = other;
return enabled == typedOther.enabled &&
circleFillColor == typedOther.circleFillColor &&
......@@ -184,7 +192,7 @@ class MyLocationStyleOptions {
@override
int get hashCode =>
hashValues(enabled, circleFillColor, circleStrokeColor, icon);
Object.hash(enabled, circleFillColor, circleStrokeColor, icon);
}
///地图自定义样式
......@@ -198,11 +206,7 @@ class CustomStyleOptions {
///自定义扩展样式的二进制数据,对应下载的自定义地图文件中的style_extra.data中的二进制数据
Uint8List? styleExtraData;
CustomStyleOptions(
this.enabled, {
this.styleData,
this.styleExtraData,
});
CustomStyleOptions(this.enabled, {this.styleData, this.styleExtraData});
static CustomStyleOptions? fromMap(dynamic json) {
if (json == null) {
......@@ -233,7 +237,7 @@ class CustomStyleOptions {
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (runtimeType != other.runtimeType) return false;
if (other is !CustomStyleOptions) return false;
if (other is! CustomStyleOptions) return false;
final CustomStyleOptions typedOther = other;
return enabled == typedOther.enabled &&
styleData == typedOther.styleData &&
......@@ -241,10 +245,13 @@ class CustomStyleOptions {
}
@override
int get hashCode => hashValues(enabled, styleData, styleExtraData);
int get hashCode => Object.hash(enabled, styleData, styleExtraData);
CustomStyleOptions clone() {
return CustomStyleOptions(enabled,
styleData: styleData, styleExtraData: styleExtraData);
return CustomStyleOptions(
enabled,
styleData: styleData,
styleExtraData: styleExtraData,
);
}
}
......@@ -4,13 +4,12 @@ version: 3.0.0
homepage: https://lbs.amap.com/
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"
sdk: ^3.10.1
dependencies:
flutter:
sdk: flutter
flutter_plugin_android_lifecycle: ^2.0.1
flutter_plugin_android_lifecycle: ^2.0.33
meta: ^1.3.0
plugin_platform_interface: ^2.0.0
stream_transform: ^2.0.0
......@@ -27,6 +26,10 @@ dev_dependencies:
pedantic: ^1.11.0
mockito: ^5.0.0-nullsafety.7
dependency_overrides:
amap_flutter_base:
path: third_party/amap_flutter_base
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
......
# 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;
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 => Object.hash(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 => Object.hash(hasContains, hasShow, hasAgree);
@override
String toString() {
return 'AMapPrivacyStatement(hasContains: $hasContains, hasShow: $hasShow, hasAgree: $hasAgree)';
}
}
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 =>
Object.hash(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 => Object.hash(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 => Object.hash(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: ">=3.0.0 <4.0.0"
flutter: ">=3.10.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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论