Skip to content

Commit

Permalink
Add geolocation api
Browse files Browse the repository at this point in the history
  • Loading branch information
qiuxiang committed May 4, 2019
1 parent f343ad1 commit f4a4c24
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 79 deletions.
32 changes: 21 additions & 11 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,35 @@ react-native link react-native-amap-geolocation
## 基本用法

```javascript
import { init, addLocationListener, start, stop } from "react-native-amap-geolocation";
import { PermissionsAndroid } from "react-native";
import { init, Geolocation } from "react-native-amap-geolocation";

// 对于 Android 需要自行根据需要申请权限
await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);

// 使用自己申请的高德 App Key
// 使用自己申请的高德 App Key 进行初始化
await init({
ios: "9bd6c82e77583020a73ef1af59d0c759",
android: "043b24fe18785f33c491705ffe5b6935"
});

const { coords } = await Geolocation.getCurrentPosition();
```

# 更多用法

该项目除了提供符合 Web 标准的 Geolocation API,同时为了最大程度的发挥高德定位 SDK 的功能,
会尽可能提供和原生 SDK 尽可能一致的接口封装。由于 iOS 和 Android SDK 提供的接口并不一致,
于是最终实现的接口大部分是并不通用的。这在接口文档或文档注释有注明,
比如 `@platform android` 表示该接口仅用于 Android。

以下是一些常用接口的用法说明以及示例代码,更多接口的具体用法请参考[接口文档]()

## 直接使用原生接口

```javascript
import { init, addLocationListener, start, stop } from "react-native-amap-geolocation";

// 添加定位监听函数
addLocationListener(location => console.log(location));

Expand All @@ -113,14 +131,6 @@ start();
stop();
```

# 更多用法

该项目的目标是提供和原生 SDK 尽可能一致的接口,由于 iOS 和 Android SDK 提供的接口并不一致,
于是最终实现的接口大部分是并不通用的。这在接口文档或文档注释有注明,
比如 `@platform android` 表示该接口仅用于 Android。

以下是一些常用接口的用法说明以及示例代码,更多接口的具体用法请参考[接口文档]()

## 逆地理编码

Android 默认返回逆地理编码,而 iOS 需要手动设置。
Expand All @@ -145,4 +155,4 @@ setInterval(5000);

// ios,设备移动超过 10 米才会更新位置信息
setDistanceFilter(10);
```
```
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public String getName() {

@Override
public void onLocationChanged(AMapLocation location) {
eventEmitter.emit("AMapGeolocation", locationToMap(location));
if (location != null) {
eventEmitter.emit("AMapGeolocation", toJSON(location));
}
}

@ReactMethod
Expand All @@ -60,9 +62,14 @@ public void stop() {
client.stopLocation();
}

@ReactMethod
public void isStarted(Promise promise) {
promise.resolve(client.isStarted());
}

@ReactMethod
public void getLastKnownLocation(Promise promise) {
promise.resolve(locationToMap(client.getLastKnownLocation()));
promise.resolve(toJSON(client.getLastKnownLocation()));
}

@ReactMethod
Expand Down Expand Up @@ -155,7 +162,7 @@ public void setGeoLanguage(String language) {
client.setLocationOption(option);
}

private ReadableMap locationToMap(AMapLocation location) {
private ReadableMap toJSON(AMapLocation location) {
if (location == null) {
return null;
}
Expand All @@ -170,6 +177,7 @@ private ReadableMap locationToMap(AMapLocation location) {
map.putDouble("longitude", location.getLongitude());
map.putDouble("altitude", location.getAltitude());
map.putDouble("speed", location.getSpeed());
map.putDouble("heading", location.getBearing());
map.putInt("locationType", location.getLocationType());
map.putString("coordinateType", location.getCoordType());
map.putInt("gpsAccuracy", location.getGpsAccuracyStatus());
Expand Down
2 changes: 1 addition & 1 deletion lib/ios/AMapGeolocation.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ - (id)json:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode {
@"longitude" : @(location.coordinate.longitude),
@"altitude" : @(location.altitude),
@"speed" : @(location.speed),
@"direction" : @(location.course),
@"heading" : @(location.course),
@"timestamp" : @(location.timestamp.timeIntervalSince1970 * 1000),
@"address" : reGeocode.formattedAddress,
@"poiName" : reGeocode.POIName,
Expand Down
54 changes: 9 additions & 45 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,20 @@

React Native 高德地图定位模块,支持 Android + iOS。

<img src="https://user-images.githubusercontent.com/1709072/39578441-c39bd3f0-4f16-11e8-83e5-99badbd68473.png" width=300>

## 使用

1. [安装](docs/installation.md)
2. 获取 Key:
* [Android](http://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key)
* [iOS](http://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key)
## 用法

```javascript
import { PermissionsAndroid } from "react-native"
import { Geolocation } from "react-native-amap-geolocation"

const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION
);

if (granted === PermissionsAndroid.RESULTS.GRANTED) {
await Geolocation.init({
ios: "9bd6c82e77583020a73ef1af59d0c759",
android: "043b24fe18785f33c491705ffe5b6935"
})

Geolocation.setOptions({
interval: 8000,
distanceFilter: 20
})

Geolocation.addLocationListener(location => console.log(location))
Geolocation.start()
}
```

## 文档

* [Geolocation](docs/geolocation.md)

## 示例

你可以直接下载安装 [example.apk](https://github.com/qiuxiang/react-native-amap-geolocation/releases/download/v0.3.0/example.apk),或者按照以下步骤运行项目示例:
import { PermissionsAndroid } from "react-native";
import { init, Geolocation } from "react-native-amap-geolocation";

```shell
yarn
await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);

# android
yarn run-android
await init({
ios: "9bd6c82e77583020a73ef1af59d0c759",
android: "043b24fe18785f33c491705ffe5b6935"
});

# ios
cd ios && pod install && cd ..
yarn run-ios
const { coords } = await Geolocation.getCurrentPosition();
```

[npm]: https://www.npmjs.com/package/react-native-amap-geolocation
Expand Down
134 changes: 134 additions & 0 deletions src/geolocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { start, stop, addLocationListener, Location } from ".";
import { EmitterSubscription } from "react-native";

/**
* 坐标信息
*
* @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 interface PositionError {
code: number;
message: string;
PERMISSION_DENIED: 1;
POSITION_UNAVAILABLE: 2;
TIMEOUT: 3;
}

/**
* 定位选项
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/PositionOptions
*/
export interface PositionOptions {
timeout?: number;
maximumAge?: number;
enableHighAccuracy?: boolean;

/**
* @see [[setDistanceFilter]]
*/
distanceFilter?: number;
}

/**
* 获取当前位置信息
*
* 注意:使用该方法会停止持续定位
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/getCurrentPosition
*/
export function getCurrentPosition(
success: (position: Position) => void,
error?: (error: PositionError) => void,
options?: PositionOptions
) {
const listener = addLocationListener(location => {
success(toPosition(location));
stop();
listener.remove();
});
start();
}

let count = 0;
const watchMap: { [watchId: number]: EmitterSubscription } = {};

/**
* 注册监听器进行持续定位
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/watchPosition
*/
export function watchPosition(
success: (position: Position) => void,
error?: (error: PositionError) => void,
options?: PositionOptions
) {
watchMap[++count] = addLocationListener(location => {
success(toPosition(location));
});
start();
return count;
}

/**
* 移除位置监听
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/clearWatch
*/
export function 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,
accuracy: location.accuracy,
altitudeAccuracy: null, // 高德定位接口没有找到对应的数据
heading: location.heading,
speed: location.speed
},
timestamp: location.timestamp
};
}

/**
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation
*/
export default class Geolocation {
static getCurrentPosition = getCurrentPosition;
static watchPosition = watchPosition;
static clearWatch = clearWatch;
}
25 changes: 14 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import { NativeModules, NativeEventEmitter, Platform } from "react-native";
import {
Location,
ReGeocode,
AppKey,
LocationMode,
LocationPurpose,
GeoLanguage
} from "./types";
export * from "./types";
import { Location, ReGeocode, AppKey, LocationMode, LocationPurpose, GeoLanguage } from "./types";

const AMapGeolocation = NativeModules.AMapGeolocation;
const eventEmitter = new NativeEventEmitter(AMapGeolocation);
Expand Down Expand Up @@ -44,6 +36,13 @@ export function stop() {
AMapGeolocation.stop();
}

/**
* 获取当前是否正在定位的状态
*/
export function isStarted(): boolean {
return AMapGeolocation.isStarted();
}

/**
* 设置发起定位请求的时间间隔(毫秒),默认 2000,最小值为 1000
*
Expand Down Expand Up @@ -223,7 +222,7 @@ export function setGeoLanguage(language: GeoLanguage) {
* @platform ios
*/
export function setDistanceFilter(distance: number) {
AMapGeolocation.setGpsFirstTimeout(distance);
AMapGeolocation.setDistanceFilter(distance);
}

/**
Expand All @@ -238,7 +237,7 @@ export function setDistanceFilter(distance: number) {
* @platform ios
*/
export function setDesiredAccuracy(desiredAccuracy: number) {
AMapGeolocation.setGpsFirstTimeout(desiredAccuracy);
AMapGeolocation.setDesiredAccuracy(desiredAccuracy);
}

/**
Expand Down Expand Up @@ -300,3 +299,7 @@ export function setReGeocodeTimeout(timeout: number) {
export function setLocatingWithReGeocode(withReGeocode: boolean) {
AMapGeolocation.setLocatingWithReGeocode(withReGeocode);
}

export * from "./types";
export * from "./geolocation";
export { default as Geolocation } from "./geolocation";
Loading

0 comments on commit f4a4c24

Please sign in to comment.