geolocation.ts
3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { EmitterSubscription } from "react-native";
import { addLocationListener, start, stop, _options } from "./amap-geolocation";
import { ILocation as Location } from "./gen-types";
/**
* 坐标信息
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Coordinates
*/
export interface Coordinates {
latitude: number;
longitude: number;
altitude: number;
accuracy: number;
altitudeAccuracy: number;
heading: number;
speed: number;
}
/**
* 定位信息
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Position
*/
export interface Position {
coords: Coordinates;
timestamp: number;
location: Location;
}
/**
* 定位错误信息
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/PositionError
*/
export class PositionError {
static PERMISSION_DENIED: 1;
static POSITION_UNAVAILABLE: 2;
static TIMEOUT: 3;
code: number;
message: string;
location: Location;
constructor(code: number, message: string, location: Location) {
this.code = code;
this.message = message;
this.location = location;
}
}
/**
* 定位选项
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/PositionOptions
*/
export interface PositionOptions {
timeout?: number;
maximumAge?: number;
enableHighAccuracy?: boolean;
/**
* @see [[setDistanceFilter]]
*/
distanceFilter?: number;
}
let watchId = 0;
const watchMap: { [watchId: number]: EmitterSubscription } = {};
/**
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation
*/
export default class Geolocation {
/**
* 获取当前位置信息
*
* 注意:使用该方法会停止持续定位
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/getCurrentPosition
*/
static getCurrentPosition(
success: (position: Position) => void,
error?: (error: PositionError) => void
// options: PositionOptions = {}
) {
const listener = addLocationListener((location) => {
if (location.errorCode) {
error && error(new PositionError(location.errorCode, location.errorInfo ?? "", location));
stop();
return listener.remove();
}
if (_options.locatingWithReGeocode && typeof location.address !== "string") {
return;
}
success(toPosition(location));
stop();
return listener.remove();
});
start();
}
/**
* 注册监听器进行持续定位
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/watchPosition
*/
static watchPosition(
success: (position: Position) => void,
error?: (error: PositionError) => void
// options?: PositionOptions
) {
watchMap[++watchId] = addLocationListener((location) => {
if (location.errorCode) {
error && error(new PositionError(location.errorCode, location.errorInfo ?? "", location));
} else {
success(toPosition(location));
}
});
start();
return watchId;
}
/**
* 移除位置监听
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/clearWatch
*/
static clearWatch(id: number) {
const listener = watchMap[id];
if (listener) {
listener.remove();
}
}
}
function toPosition(location: Location) {
return {
location,
coords: {
latitude: location.latitude,
longitude: location.longitude,
altitude: location.altitude ?? 0,
accuracy: location.accuracy,
altitudeAccuracy: 0, // 高德定位接口没有找到对应的数据
heading: location.heading ?? 0,
speed: location.speed ?? 0,
},
timestamp: location.timestamp ?? 0,
};
}