Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CapacitorGeolocation.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ Pod::Spec.new do |s|
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
s.ios.deployment_target = '15.0'
s.dependency 'Capacitor'
s.dependency 'IONGeolocationLib', spec='2.0.0'
s.dependency 'IONGeolocationLib', '2.1.0'
s.swift_version = '5.1'
end
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"),
.package(url: "https://github.com/ionic-team/ion-ios-geolocation.git", from: "2.0.0")
.package(url: "https://github.com/ionic-team/ion-ios-geolocation.git", from: "2.1.0")
],
targets: [
.target(
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ Not available on web.

#### Position

| Prop | Type | Description | Since |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----- |
| **`timestamp`** | <code>number</code> | Creation timestamp for coords | 1.0.0 |
| **`coords`** | <code>{ latitude: number; longitude: number; accuracy: number; altitudeAccuracy: number \| null; altitude: number \| null; speed: number \| null; heading: number \| null; }</code> | The GPS coordinates along with the accuracy of the data | 1.0.0 |
| Prop | Type | Description | Since |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----- |
| **`timestamp`** | <code>number</code> | Creation timestamp for coords | 1.0.0 |
| **`coords`** | <code>{ latitude: number; longitude: number; accuracy: number; altitudeAccuracy: number \| null; altitude: number \| null; speed: number \| null; heading: number \| null; magneticHeading: number \| null; trueHeading: number \| null; headingAccuracy: number \| null; course: number \| null; }</code> | The GPS coordinates along with the accuracy of the data | 1.0.0 |


#### PositionOptions
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ dependencies {
implementation project(':capacitor-android')
}

implementation("io.ionic.libs:iongeolocation-android:2.1.0")
implementation("io.ionic.libs:iongeolocation-android:2.2.0")
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"

implementation 'com.google.code.gson:gson:2.13.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ class GeolocationPlugin : Plugin() {
put("altitude", locationResult.altitude)
locationResult.altitudeAccuracy?.let { put("altitudeAccuracy", it) }
put("speed", locationResult.speed)
put("heading", locationResult.heading)
put("heading", if (locationResult.heading != -1f) locationResult.heading else null)
put("magneticHeading", locationResult.magneticHeading)
put("trueHeading", locationResult.trueHeading)
put("headingAccuracy", locationResult.headingAccuracy)
put("course", locationResult.course)
}
return JSObject().apply {
put("timestamp", locationResult.timestamp)
Expand Down
45 changes: 39 additions & 6 deletions example-app/src/js/capacitor-welcome.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,46 @@ window.customElements.define(
}
const timeRepresentation = location.timestamp ? new Date(location.timestamp).toISOString() : '-';
stringRepresentation += `- Time: ${timeRepresentation}\n`;
stringRepresentation += `- Latitute: ${location?.coords.latitude}\n- Longitude: ${location?.coords.longitude}\n`;
if (location?.coords.altitude || location?.coords.heading || location?.coords.speed) {
stringRepresentation += `- Altitude: ${location?.coords.altitude}\n- Heading: ${location?.coords.heading}\n- Speed: ${location?.coords.speed}\n`;
}
stringRepresentation += `- Latitude: ${location?.coords.latitude}\n- Longitude: ${location?.coords.longitude}\n`;
stringRepresentation += `- Accuracy: ${location?.coords.accuracy}\n`;
if (location?.coords.altitudeAccuracy) {
stringRepresentation += `- Altitude accuracy: ${location?.coords.altitudeAccuracy}\n`;
stringRepresentation += `- Altitude: ${location?.coords.altitude}\n`;
stringRepresentation += `- Altitude accuracy: ${location?.coords.altitudeAccuracy}\n`;
stringRepresentation += `- Speed: ${location?.coords.speed}\n`;

if (
location?.coords.heading !== null &&
location?.coords.heading !== undefined &&
location?.coords.heading !== -1
) {
stringRepresentation += `- Heading: ${location.coords.heading}\n`;
}
if (
location?.coords.magneticHeading !== null &&
location?.coords.magneticHeading !== undefined &&
location?.coords.magneticHeading !== -1
) {
stringRepresentation += `- Magnetic Heading: ${location.coords.magneticHeading}\n`;
}
if (
location?.coords.trueHeading !== null &&
location?.coords.trueHeading !== undefined &&
location?.coords.trueHeading !== -1
) {
stringRepresentation += `- True Heading: ${location.coords.trueHeading}\n`;
}
if (
location?.coords.headingAccuracy !== null &&
location?.coords.headingAccuracy !== undefined &&
location?.coords.headingAccuracy !== -1
) {
stringRepresentation += `- Heading Accuracy: ${location.coords.headingAccuracy}\n`;
}
if (
location?.coords.course !== null &&
location?.coords.course !== undefined &&
location?.coords.course !== -1
) {
stringRepresentation += `- Course: ${location.coords.course}\n`;
}
return stringRepresentation;
}
Expand Down
4 changes: 4 additions & 0 deletions ios/Sources/GeolocationPlugin/GeolocationConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ enum Constants {
static let speed: String = "speed"
static let timestamp: String = "timestamp"
static let altitudeAccuracy: String = "altitudeAccuracy"
static let magneticHeading: String = "magneticHeading"
static let trueHeading: String = "trueHeading"
static let headingAccuracy: String = "headingAccuracy"
static let course: String = "course"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ extension IONGLOCPositionModel {
}

private var coordsJSObject: JSObject {
[
let headingValue = trueHeading ?? magneticHeading ?? (course != -1.0 ? course : nil)
return [
Constants.Position.altitude: altitude,
Constants.Position.heading: course,
Constants.Position.heading: headingValue ?? NSNull(),
Constants.Position.magneticHeading: magneticHeading ?? NSNull(),
Constants.Position.trueHeading: trueHeading ?? NSNull(),
Constants.Position.headingAccuracy: headingAccuracy ?? NSNull(),
Constants.Position.course: course != -1.0 ? course : NSNull(),
Constants.Position.accuracy: horizontalAccuracy,
Constants.Position.latitude: latitude,
Constants.Position.longitude: longitude,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@
"src": "android"
}
}
}
}
42 changes: 41 additions & 1 deletion src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,51 @@ export interface Position {
speed: number | null;

/**
* The heading the user is facing (if available)
* The heading the user is facing (if available).
*
* Historically, this field returned the direction of travel (course) on iOS and Android.
* It now prioritizes the compass heading (true or magnetic) if available, falling back
* to the direction of travel (course).
*
* @since 1.0.0
*/
heading: number | null;

/**
* The heading (measured in degrees) relative to magnetic north.
*
* Only available when using `watchPosition`.
*
* @since 8.2.0
*/
magneticHeading: number | null | undefined;

/**
* The heading (measured in degrees) relative to true north.
*
* Only available when using `watchPosition`.
*
* @since 8.2.0
*/
trueHeading: number | null | undefined;

/**
* The maximum deviation (measured in degrees) between the reported heading and the true geomagnetic heading.
*
* Only available when using `watchPosition`.
*
* @since 8.2.0
*/
headingAccuracy: number | null | undefined;

/**
* The direction in which the device is travelling, measured in degrees and relative to due north.
*
* Only available when using `watchPosition`.
*
* @since 8.2.0
*/
course: number | null | undefined;
};
}

Expand Down
72 changes: 70 additions & 2 deletions src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,79 @@ import type {
} from './definitions';

export class GeolocationWeb extends WebPlugin implements GeolocationPlugin {
private latestOrientation: {
magneticHeading: number | null;
trueHeading: number | null;
headingAccuracy: number | null;
} | null = null;

constructor() {
super();
if (typeof window !== 'undefined') {
const win = window as any;
if ('ondeviceorientationabsolute' in win) {
win.addEventListener('deviceorientationabsolute', (event: any) => this.updateOrientation(event, true), true);
} else if ('ondeviceorientation' in win) {
win.addEventListener('deviceorientation', (event: any) => this.updateOrientation(event, false), true);
}
}
}

private updateOrientation(event: any, isAbsolute: boolean) {
let trueHeading: number | null = null;
let magneticHeading: number | null = null;
let headingAccuracy: number | null = null;

if (isAbsolute && event.alpha !== null) {
trueHeading = (360 - event.alpha) % 360;
} else if (event.webkitCompassHeading !== undefined && event.webkitCompassHeading !== null) {
magneticHeading = event.webkitCompassHeading;
headingAccuracy = event.webkitCompassAccuracy;
} else if (event.alpha !== null && event.absolute === true) {
trueHeading = (360 - event.alpha) % 360;
} else if (event.alpha !== null) {
magneticHeading = (360 - event.alpha) % 360;
}

if (trueHeading !== null || magneticHeading !== null) {
this.latestOrientation = {
trueHeading,
magneticHeading,
headingAccuracy,
};
}
}

private augmentPosition(pos: globalThis.GeolocationPosition, isWatch = false): Position {
const coords = pos.coords;
const orientation = isWatch ? this.latestOrientation : null;

const heading =
orientation?.trueHeading ?? orientation?.magneticHeading ?? (isWatch ? coords.heading : null) ?? null;

return {
timestamp: pos.timestamp,
coords: {
latitude: coords.latitude,
longitude: coords.longitude,
accuracy: coords.accuracy,
altitude: coords.altitude,
altitudeAccuracy: (coords as any).altitudeAccuracy,
speed: coords.speed,
heading: heading,
magneticHeading: orientation?.magneticHeading ?? null,
trueHeading: orientation?.trueHeading ?? null,
headingAccuracy: orientation?.headingAccuracy ?? null,
course: (isWatch ? coords.heading : null) ?? null,
},
};
}

async getCurrentPosition(options?: PositionOptions): Promise<Position> {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
(pos) => {
resolve(pos);
resolve(this.augmentPosition(pos, false));
},
(err) => {
reject(err);
Expand All @@ -32,7 +100,7 @@ export class GeolocationWeb extends WebPlugin implements GeolocationPlugin {
async watchPosition(options: PositionOptions, callback: WatchPositionCallback): Promise<CallbackID> {
const id = navigator.geolocation.watchPosition(
(pos) => {
callback(pos);
callback(this.augmentPosition(pos, true));
},
(err) => {
callback(null, err);
Expand Down
Loading