diff --git a/README.md b/README.md index fb2be98..e0a390d 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,11 @@ interface PositioningData { isMocked: boolean; mode: 'normal' | 'driving'; predicted?: boolean; + // opsional: detail asal speed + speedSource?: 'GNSS' | 'IMU' | 'DELTA' | 'NONE'; + speedGnss?: number; // m/s dari Location.getSpeed bila tersedia & segar + speedImu?: number; // m/s dari IMU (heuristik internal) + speedDerived?: number; // m/s hasil Δpos/Δt (kasar) } ``` @@ -189,6 +194,14 @@ interface PermissionStatus { - Prediksi maju (dead‑reckoning) bersifat opsional dan nonaktif secara default. Aktifkan dengan `setOptions({ enableForwardPrediction: true, maxPredictionSeconds?: number })`. - Saat prediksi aktif, posisi dapat diproyeksikan pendek (<= `maxPredictionSeconds`) berdasarkan `speed` dan `directionRad` dari IMU, serta ditandai `predicted: true`. Nilai `source` tidak berubah. +### Kebijakan `speed` + +- Field `speed` kini dipilih dengan prioritas: GNSS > IMU > Δpos/Δt > 0. + - GNSS: dipakai jika `Location.hasSpeed()` dan usia fix ≤ ~3000 ms. + - IMU: fallback dari integrasi percepatan IMU (dibatasi ke 0..30 m/s, dengan smoothing & idle handling). + - Δpos/Δt: fallback terakhir, hanya bila selang waktu antar fix ≥ 3 s. +- Field tambahan opsional: `speedSource`, `speedGnss`, `speedImu`, `speedDerived` untuk transparansi asal nilai. + --- ## Detail Sensor (untuk pengembangan lanjutan) diff --git a/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt b/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt index 5b091aa..4666a83 100644 --- a/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt +++ b/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt @@ -60,6 +60,7 @@ class DumonGeolocation : Plugin() { private var latestAccuracy = 999.0 private var latestSource = "GNSS" private var latestTimestamp: Long = 0L + private var latestGnssSpeed: Float? = null private var latestImu: ImuData? = null private var satelliteStatus: SatelliteStatus? = null @@ -72,6 +73,7 @@ class DumonGeolocation : Plugin() { private var prevLongitude = 0.0 private var prevSpeed = 0f private var prevDirection = 0f + private var prevTimestamp: Long = 0L // private val significantChangeThreshold = 0.00007 // ~7 meters private var significantChangeThreshold = 7.0 // ~7 meters private var speedChangeThreshold = 0.5f // m/s @@ -121,6 +123,7 @@ class DumonGeolocation : Plugin() { latestSource = if (isMocked) "MOCK" else "GNSS" isMockedLocation = isMocked latestTimestamp = location.time + latestGnssSpeed = if (location.hasSpeed()) location.speed else null if (currentTrackingMode == GpsTrackingMode.DRIVING) { bufferedDrivingLocation = location @@ -160,6 +163,7 @@ class DumonGeolocation : Plugin() { latestAccuracy = location.accuracy.toDouble() latestTimestamp = location.time latestSource = if (isMockedLocation) "MOCK" else "GNSS" + latestGnssSpeed = if (location.hasSpeed()) location.speed else null emitPositionUpdate(forceEmit = true) // force emit in driving } drivingEmitHandler?.postDelayed(this, drivingEmitIntervalMs) @@ -229,6 +233,7 @@ class DumonGeolocation : Plugin() { latestSource = if (isMocked) "MOCK" else "GNSS" isMockedLocation = isMocked latestTimestamp = location.time + latestGnssSpeed = if (location.hasSpeed()) location.speed else null call.resolve(buildPositionData()) } } else { @@ -653,6 +658,7 @@ class DumonGeolocation : Plugin() { prevLongitude = latestLongitude prevSpeed = speedNow prevDirection = directionNow + prevTimestamp = if (latestTimestamp > 0) latestTimestamp else now lastEmitTimestamp = now // Ensure listener notifications run on the main thread for consistency @@ -740,13 +746,42 @@ class DumonGeolocation : Plugin() { obj.put("isMocked", isMockedLocation) obj.put("mode", if (currentTrackingMode == GpsTrackingMode.DRIVING) "driving" else "normal") - // Always provide IMU-related fields to match TS definitions - val speedVal = latestImu?.speed ?: 0f - val accelVal = latestImu?.acceleration ?: 0f - val dirVal = latestImu?.directionRad ?: 0f - obj.put("speed", speedVal) - obj.put("acceleration", accelVal) - obj.put("directionRad", dirVal) + // Gather speed candidates + val imuSpeed: Float? = latestImu?.speed + val imuAccel: Float = latestImu?.acceleration ?: 0f + val imuDir: Float = latestImu?.directionRad ?: 0f + + // GNSS speed candidate is valid only if recent enough + val fixAgeMs = if (latestTimestamp > 0) (now - latestTimestamp) else Long.MAX_VALUE + val gnssSpeed: Float? = latestGnssSpeed?.takeIf { fixAgeMs <= 3000L } + + // Derived speed from delta position and timestamps (use only on sufficient dt) + val derivedSpeed: Float? = run { + val dtMs = if (prevTimestamp > 0 && latestTimestamp > 0) (latestTimestamp - prevTimestamp) else 0L + val dtSec = dtMs.toDouble() / 1000.0 + if (dtSec >= 3.0 && dtSec <= 30.0) { + val dMeters = calculateDistance(latestLatitude, latestLongitude, prevLatitude, prevLongitude) + (dMeters / dtSec).toFloat() + } else null + } + + // Choose final speed: GNSS > IMU > Derived > 0 + val (finalSpeed, speedSource) = when { + gnssSpeed != null -> Pair(gnssSpeed, "GNSS") + imuSpeed != null -> Pair(imuSpeed, "IMU") + derivedSpeed != null -> Pair(derivedSpeed, "DELTA") + else -> Pair(0f, "NONE") + } + + obj.put("speed", finalSpeed) + obj.put("acceleration", imuAccel) + obj.put("directionRad", imuDir) + obj.put("speedSource", speedSource) + + // Optional additional fields when available + gnssSpeed?.let { obj.put("speedGnss", it.toDouble()) } + imuSpeed?.let { obj.put("speedImu", it.toDouble()) } + derivedSpeed?.let { obj.put("speedDerived", it.toDouble()) } obj.put("predicted", predicted) diff --git a/dist/docs.json b/dist/docs.json index 6948e07..09b74a1 100644 --- a/dist/docs.json +++ b/dist/docs.json @@ -386,6 +386,34 @@ "docs": "", "complexTypes": [], "type": "boolean | undefined" + }, + { + "name": "speedSource", + "tags": [], + "docs": "", + "complexTypes": [], + "type": "'GNSS' | 'IMU' | 'DELTA' | 'NONE' | undefined" + }, + { + "name": "speedGnss", + "tags": [], + "docs": "", + "complexTypes": [], + "type": "number | undefined" + }, + { + "name": "speedImu", + "tags": [], + "docs": "", + "complexTypes": [], + "type": "number | undefined" + }, + { + "name": "speedDerived", + "tags": [], + "docs": "", + "complexTypes": [], + "type": "number | undefined" } ] }, diff --git a/dist/esm/definitions.d.ts b/dist/esm/definitions.d.ts index 626b52b..11cbae1 100644 --- a/dist/esm/definitions.d.ts +++ b/dist/esm/definitions.d.ts @@ -11,6 +11,10 @@ export interface PositioningData { isMocked: boolean; mode: 'normal' | 'driving'; predicted?: boolean; + speedSource?: 'GNSS' | 'IMU' | 'DELTA' | 'NONE'; + speedGnss?: number; + speedImu?: number; + speedDerived?: number; } export interface SatelliteStatus { satellitesInView: number; diff --git a/dist/esm/definitions.js.map b/dist/esm/definitions.js.map index 5bb8ce6..7eb0307 100644 --- a/dist/esm/definitions.js.map +++ b/dist/esm/definitions.js.map @@ -1 +1 @@ -{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n// export interface SatelliteStatus {\n// satellitesInView: number;\n// usedInFix: number;\n// constellationCounts: { [key: string]: number };\n// }\n\n// export interface WifiAp {\n// ssid: string;\n// bssid: string;\n// rssi: number;\n// distance?: number;\n// }\n\n// export interface WifiScanResult {\n// apCount: number;\n// aps: WifiAp[];\n// }\n\n// export interface ImuData {\n// accelX: number;\n// accelY: number;\n// accelZ: number;\n// gyroX: number;\n// gyroY: number;\n// gyroZ: number;\n// speed?: number;\n// acceleration?: number;\n// directionRad?: number;\n// }\n\n// export interface GpsData {\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n// satellitesInView?: number;\n// usedInFix?: number;\n// constellationCounts?: { [key: string]: number };\n// }\n\n// export interface PositioningData {\n// source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n// timestamp: number;\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n\n// gnssData?: SatelliteStatus;\n// wifiData?: WifiAp[];\n// imuData?: ImuData;\n// }\n\nexport interface PositioningData {\n source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n timestamp: number;\n latitude: number;\n longitude: number;\n accuracy: number;\n speed: number;\n acceleration: number;\n directionRad: number;\n isMocked: boolean;\n mode: 'normal' | 'driving';\n predicted?: boolean;\n}\n\nexport interface SatelliteStatus {\n satellitesInView: number;\n usedInFix: number;\n constellationCounts: { [key: string]: number };\n}\n\nexport interface DumonGeoOptions {\n distanceThresholdMeters?: number;\n speedChangeThreshold?: number;\n directionChangeThreshold?: number;\n emitDebounceMs?: number;\n drivingEmitIntervalMs?: number;\n wifiScanIntervalMs?: number;\n enableWifiRtt?: boolean;\n enableLogging?: boolean;\n enableForwardPrediction?: boolean;\n maxPredictionSeconds?: number;\n emitGnssStatus?: boolean;\n suppressMockedUpdates?: boolean;\n keepScreenOn?: boolean;\n backgroundPollingIntervalMs?: number; // Android background polling interval\n backgroundPostMinDistanceMeters?: number; // Android background min distance to post\n backgroundPostMinAccuracyMeters?: number; // Android background min acceptable accuracy for POST (meters)\n backgroundMinPostIntervalMs?: number; // Android background minimum interval between POST attempts\n}\n\nexport interface PermissionStatus {\n location: 'granted' | 'denied';\n wifi: 'granted' | 'denied';\n}\n\nexport interface DumonGeolocationPlugin {\n startPositioning(): Promise;\n stopPositioning(): Promise;\n getLatestPosition(): Promise;\n checkAndRequestPermissions(): Promise;\n setOptions(options: DumonGeoOptions): Promise;\n getGnssStatus(): Promise;\n getLocationServicesStatus(): Promise<{ gpsEnabled: boolean; networkEnabled: boolean }>;\n // Background tracking (Android)\n startBackgroundTracking(options?: {\n title?: string;\n text?: string;\n channelId?: string;\n channelName?: string;\n postUrl?: string; // optional: service will POST latest fixes here as JSON\n }): Promise;\n stopBackgroundTracking(): Promise;\n isBackgroundTrackingActive(): Promise<{ active: boolean }>;\n getBackgroundLatestPosition(): Promise;\n openBackgroundPermissionSettings(): Promise;\n openNotificationPermissionSettings(): Promise;\n // Auth token management for background posting\n setAuthTokens(tokens: { accessToken: string; refreshToken: string }): Promise;\n clearAuthTokens(): Promise;\n getAuthState(): Promise<{ present: boolean }>;\n setBackgroundPostUrl(options: { url?: string }): Promise;\n getBackgroundPostUrl(): Promise<{ url: string | null }>;\n\n configureEdgeToEdge(options: {\n bgColor: string;\n style: 'DARK' | 'LIGHT';\n overlay?: boolean;\n }): Promise;\n\n setGpsMode(options: { mode: 'normal' | 'driving' }): Promise;\n\n addListener(\n eventName: 'onPositionUpdate',\n listenerFunc: (data: PositioningData) => void\n ): PluginListenerHandle;\n\n addListener(\n eventName: 'onGnssStatus',\n listenerFunc: (data: SatelliteStatus) => void\n ): PluginListenerHandle;\n}\n"]} \ No newline at end of file +{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n// export interface SatelliteStatus {\n// satellitesInView: number;\n// usedInFix: number;\n// constellationCounts: { [key: string]: number };\n// }\n\n// export interface WifiAp {\n// ssid: string;\n// bssid: string;\n// rssi: number;\n// distance?: number;\n// }\n\n// export interface WifiScanResult {\n// apCount: number;\n// aps: WifiAp[];\n// }\n\n// export interface ImuData {\n// accelX: number;\n// accelY: number;\n// accelZ: number;\n// gyroX: number;\n// gyroY: number;\n// gyroZ: number;\n// speed?: number;\n// acceleration?: number;\n// directionRad?: number;\n// }\n\n// export interface GpsData {\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n// satellitesInView?: number;\n// usedInFix?: number;\n// constellationCounts?: { [key: string]: number };\n// }\n\n// export interface PositioningData {\n// source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n// timestamp: number;\n// latitude: number;\n// longitude: number;\n// accuracy: number;\n\n// gnssData?: SatelliteStatus;\n// wifiData?: WifiAp[];\n// imuData?: ImuData;\n// }\n\nexport interface PositioningData {\n source: 'GNSS' | 'WIFI' | 'FUSED' | 'MOCK';\n timestamp: number;\n latitude: number;\n longitude: number;\n accuracy: number;\n speed: number;\n acceleration: number;\n directionRad: number;\n isMocked: boolean;\n mode: 'normal' | 'driving';\n predicted?: boolean;\n // Optional detailed speed fields and provenance\n speedSource?: 'GNSS' | 'IMU' | 'DELTA' | 'NONE';\n speedGnss?: number; // m/s from Location.getSpeed when available and fresh\n speedImu?: number; // m/s from IMU fusion (internal heuristic)\n speedDerived?: number; // m/s from delta-position / delta-time (coarse)\n}\n\nexport interface SatelliteStatus {\n satellitesInView: number;\n usedInFix: number;\n constellationCounts: { [key: string]: number };\n}\n\nexport interface DumonGeoOptions {\n distanceThresholdMeters?: number;\n speedChangeThreshold?: number;\n directionChangeThreshold?: number;\n emitDebounceMs?: number;\n drivingEmitIntervalMs?: number;\n wifiScanIntervalMs?: number;\n enableWifiRtt?: boolean;\n enableLogging?: boolean;\n enableForwardPrediction?: boolean;\n maxPredictionSeconds?: number;\n emitGnssStatus?: boolean;\n suppressMockedUpdates?: boolean;\n keepScreenOn?: boolean;\n backgroundPollingIntervalMs?: number; // Android background polling interval\n backgroundPostMinDistanceMeters?: number; // Android background min distance to post\n backgroundPostMinAccuracyMeters?: number; // Android background min acceptable accuracy for POST (meters)\n backgroundMinPostIntervalMs?: number; // Android background minimum interval between POST attempts\n}\n\nexport interface PermissionStatus {\n location: 'granted' | 'denied';\n wifi: 'granted' | 'denied';\n}\n\nexport interface DumonGeolocationPlugin {\n startPositioning(): Promise;\n stopPositioning(): Promise;\n getLatestPosition(): Promise;\n checkAndRequestPermissions(): Promise;\n setOptions(options: DumonGeoOptions): Promise;\n getGnssStatus(): Promise;\n getLocationServicesStatus(): Promise<{ gpsEnabled: boolean; networkEnabled: boolean }>;\n // Background tracking (Android)\n startBackgroundTracking(options?: {\n title?: string;\n text?: string;\n channelId?: string;\n channelName?: string;\n postUrl?: string; // optional: service will POST latest fixes here as JSON\n }): Promise;\n stopBackgroundTracking(): Promise;\n isBackgroundTrackingActive(): Promise<{ active: boolean }>;\n getBackgroundLatestPosition(): Promise;\n openBackgroundPermissionSettings(): Promise;\n openNotificationPermissionSettings(): Promise;\n // Auth token management for background posting\n setAuthTokens(tokens: { accessToken: string; refreshToken: string }): Promise;\n clearAuthTokens(): Promise;\n getAuthState(): Promise<{ present: boolean }>;\n setBackgroundPostUrl(options: { url?: string }): Promise;\n getBackgroundPostUrl(): Promise<{ url: string | null }>;\n\n configureEdgeToEdge(options: {\n bgColor: string;\n style: 'DARK' | 'LIGHT';\n overlay?: boolean;\n }): Promise;\n\n setGpsMode(options: { mode: 'normal' | 'driving' }): Promise;\n\n addListener(\n eventName: 'onPositionUpdate',\n listenerFunc: (data: PositioningData) => void\n ): PluginListenerHandle;\n\n addListener(\n eventName: 'onGnssStatus',\n listenerFunc: (data: SatelliteStatus) => void\n ): PluginListenerHandle;\n}\n"]} \ No newline at end of file diff --git a/dist/esm/web.js b/dist/esm/web.js index 83fc98e..8633533 100644 --- a/dist/esm/web.js +++ b/dist/esm/web.js @@ -23,6 +23,10 @@ export class DumonGeolocationWeb extends WebPlugin { directionRad: 0, isMocked: false, mode: this._mode, + speedSource: 'NONE', + speedImu: 0, + speedGnss: 0, + speedDerived: 0, }; } async checkAndRequestPermissions() { diff --git a/dist/esm/web.js.map b/dist/esm/web.js.map index 54e8e44..d1c0a53 100644 --- a/dist/esm/web.js.map +++ b/dist/esm/web.js.map @@ -1 +1 @@ -{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { PositioningData, DumonGeoOptions, SatelliteStatus } from './definitions';\n\nexport class DumonGeolocationWeb extends WebPlugin {\n private _mode: 'normal' | 'driving' = 'normal';\n async startPositioning(): Promise {\n console.log('DumonGeolocationWeb: startPositioning() called (no-op)');\n }\n\n async stopPositioning(): Promise {\n console.log('DumonGeolocationWeb: stopPositioning() called (no-op)');\n }\n\n async getLatestPosition(): Promise {\n console.log('DumonGeolocationWeb: getLatestPosition() called (returning dummy data)');\n return {\n source: 'GNSS',\n timestamp: Date.now(),\n latitude: 0,\n longitude: 0,\n accuracy: 999,\n speed: 0,\n acceleration: 0,\n directionRad: 0,\n isMocked: false,\n mode: this._mode,\n };\n }\n\n async checkAndRequestPermissions(): Promise<{\n location: 'granted' | 'denied';\n wifi: 'granted' | 'denied';\n }> {\n console.info('[dumon-geolocation] checkAndRequestPermissions mocked for web.');\n return {\n location: 'granted',\n wifi: 'granted',\n };\n }\n\n async configureEdgeToEdge(options: {\n bgColor: string;\n style: 'DARK' | 'LIGHT';\n overlay?: boolean;\n }): Promise {\n console.info('[dumon-geolocation] configureEdgeToEdge called on web with:', options);\n // No-op\n }\n\n async setOptions(_options: DumonGeoOptions): Promise {\n // No-op on web\n }\n\n async setGpsMode(options: { mode: 'normal' | 'driving' }): Promise {\n this._mode = options?.mode === 'driving' ? 'driving' : 'normal';\n }\n\n async getGnssStatus(): Promise {\n return null;\n }\n\n async getLocationServicesStatus(): Promise<{ gpsEnabled: boolean; networkEnabled: boolean }> {\n // Web stub; assume enabled\n return { gpsEnabled: true, networkEnabled: true };\n }\n\n // Background tracking stubs (no-op on web)\n async startBackgroundTracking(_options?: {\n title?: string;\n text?: string;\n channelId?: string;\n channelName?: string;\n postUrl?: string;\n }): Promise {\n console.info('[dumon-geolocation] startBackgroundTracking is not supported on web.');\n }\n\n async stopBackgroundTracking(): Promise {\n console.info('[dumon-geolocation] stopBackgroundTracking is not supported on web.');\n }\n\n async isBackgroundTrackingActive(): Promise<{ active: boolean }> {\n return { active: false };\n }\n\n async getBackgroundLatestPosition(): Promise {\n return null;\n }\n\n async openBackgroundPermissionSettings(): Promise {\n console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');\n }\n\n async openNotificationPermissionSettings(): Promise {\n console.info('[dumon-geolocation] openNotificationPermissionSettings is not supported on web.');\n }\n\n async setAuthTokens(_tokens: { accessToken: string; refreshToken: string }): Promise {\n console.info('[dumon-geolocation] setAuthTokens is a no-op on web.');\n }\n\n async clearAuthTokens(): Promise {\n console.info('[dumon-geolocation] clearAuthTokens is a no-op on web.');\n }\n\n async getAuthState(): Promise<{ present: boolean }> {\n return { present: false };\n }\n\n async setBackgroundPostUrl(_options: { url?: string }): Promise {\n console.info('[dumon-geolocation] setBackgroundPostUrl is not supported on web.');\n }\n\n async getBackgroundPostUrl(): Promise<{ url: string | null }> {\n return { url: null };\n }\n}\n"]} \ No newline at end of file +{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { PositioningData, DumonGeoOptions, SatelliteStatus } from './definitions';\n\nexport class DumonGeolocationWeb extends WebPlugin {\n private _mode: 'normal' | 'driving' = 'normal';\n async startPositioning(): Promise {\n console.log('DumonGeolocationWeb: startPositioning() called (no-op)');\n }\n\n async stopPositioning(): Promise {\n console.log('DumonGeolocationWeb: stopPositioning() called (no-op)');\n }\n\n async getLatestPosition(): Promise {\n console.log('DumonGeolocationWeb: getLatestPosition() called (returning dummy data)');\n return {\n source: 'GNSS',\n timestamp: Date.now(),\n latitude: 0,\n longitude: 0,\n accuracy: 999,\n speed: 0,\n acceleration: 0,\n directionRad: 0,\n isMocked: false,\n mode: this._mode,\n speedSource: 'NONE',\n speedImu: 0,\n speedGnss: 0,\n speedDerived: 0,\n };\n }\n\n async checkAndRequestPermissions(): Promise<{\n location: 'granted' | 'denied';\n wifi: 'granted' | 'denied';\n }> {\n console.info('[dumon-geolocation] checkAndRequestPermissions mocked for web.');\n return {\n location: 'granted',\n wifi: 'granted',\n };\n }\n\n async configureEdgeToEdge(options: {\n bgColor: string;\n style: 'DARK' | 'LIGHT';\n overlay?: boolean;\n }): Promise {\n console.info('[dumon-geolocation] configureEdgeToEdge called on web with:', options);\n // No-op\n }\n\n async setOptions(_options: DumonGeoOptions): Promise {\n // No-op on web\n }\n\n async setGpsMode(options: { mode: 'normal' | 'driving' }): Promise {\n this._mode = options?.mode === 'driving' ? 'driving' : 'normal';\n }\n\n async getGnssStatus(): Promise {\n return null;\n }\n\n async getLocationServicesStatus(): Promise<{ gpsEnabled: boolean; networkEnabled: boolean }> {\n // Web stub; assume enabled\n return { gpsEnabled: true, networkEnabled: true };\n }\n\n // Background tracking stubs (no-op on web)\n async startBackgroundTracking(_options?: {\n title?: string;\n text?: string;\n channelId?: string;\n channelName?: string;\n postUrl?: string;\n }): Promise {\n console.info('[dumon-geolocation] startBackgroundTracking is not supported on web.');\n }\n\n async stopBackgroundTracking(): Promise {\n console.info('[dumon-geolocation] stopBackgroundTracking is not supported on web.');\n }\n\n async isBackgroundTrackingActive(): Promise<{ active: boolean }> {\n return { active: false };\n }\n\n async getBackgroundLatestPosition(): Promise {\n return null;\n }\n\n async openBackgroundPermissionSettings(): Promise {\n console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');\n }\n\n async openNotificationPermissionSettings(): Promise {\n console.info('[dumon-geolocation] openNotificationPermissionSettings is not supported on web.');\n }\n\n async setAuthTokens(_tokens: { accessToken: string; refreshToken: string }): Promise {\n console.info('[dumon-geolocation] setAuthTokens is a no-op on web.');\n }\n\n async clearAuthTokens(): Promise {\n console.info('[dumon-geolocation] clearAuthTokens is a no-op on web.');\n }\n\n async getAuthState(): Promise<{ present: boolean }> {\n return { present: false };\n }\n\n async setBackgroundPostUrl(_options: { url?: string }): Promise {\n console.info('[dumon-geolocation] setBackgroundPostUrl is not supported on web.');\n }\n\n async getBackgroundPostUrl(): Promise<{ url: string | null }> {\n return { url: null };\n }\n}\n"]} \ No newline at end of file diff --git a/dist/plugin.cjs.js b/dist/plugin.cjs.js index c2f908f..8f72228 100644 --- a/dist/plugin.cjs.js +++ b/dist/plugin.cjs.js @@ -30,6 +30,10 @@ class DumonGeolocationWeb extends core.WebPlugin { directionRad: 0, isMocked: false, mode: this._mode, + speedSource: 'NONE', + speedImu: 0, + speedGnss: 0, + speedDerived: 0, }; } async checkAndRequestPermissions() { diff --git a/dist/plugin.cjs.js.map b/dist/plugin.cjs.js.map index 6d4e1fb..ce97e91 100644 --- a/dist/plugin.cjs.js.map +++ b/dist/plugin.cjs.js.map @@ -1 +1 @@ -{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DumonGeolocation = registerPlugin('DumonGeolocation', {\n web: () => import('./web').then((m) => new m.DumonGeolocationWeb()),\n});\nexport * from './definitions';\nexport { DumonGeolocation };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class DumonGeolocationWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this._mode = 'normal';\n }\n async startPositioning() {\n console.log('DumonGeolocationWeb: startPositioning() called (no-op)');\n }\n async stopPositioning() {\n console.log('DumonGeolocationWeb: stopPositioning() called (no-op)');\n }\n async getLatestPosition() {\n console.log('DumonGeolocationWeb: getLatestPosition() called (returning dummy data)');\n return {\n source: 'GNSS',\n timestamp: Date.now(),\n latitude: 0,\n longitude: 0,\n accuracy: 999,\n speed: 0,\n acceleration: 0,\n directionRad: 0,\n isMocked: false,\n mode: this._mode,\n };\n }\n async checkAndRequestPermissions() {\n console.info('[dumon-geolocation] checkAndRequestPermissions mocked for web.');\n return {\n location: 'granted',\n wifi: 'granted',\n };\n }\n async configureEdgeToEdge(options) {\n console.info('[dumon-geolocation] configureEdgeToEdge called on web with:', options);\n // No-op\n }\n async setOptions(_options) {\n // No-op on web\n }\n async setGpsMode(options) {\n this._mode = (options === null || options === void 0 ? void 0 : options.mode) === 'driving' ? 'driving' : 'normal';\n }\n async getGnssStatus() {\n return null;\n }\n async getLocationServicesStatus() {\n // Web stub; assume enabled\n return { gpsEnabled: true, networkEnabled: true };\n }\n // Background tracking stubs (no-op on web)\n async startBackgroundTracking(_options) {\n console.info('[dumon-geolocation] startBackgroundTracking is not supported on web.');\n }\n async stopBackgroundTracking() {\n console.info('[dumon-geolocation] stopBackgroundTracking is not supported on web.');\n }\n async isBackgroundTrackingActive() {\n return { active: false };\n }\n async getBackgroundLatestPosition() {\n return null;\n }\n async openBackgroundPermissionSettings() {\n console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');\n }\n async openNotificationPermissionSettings() {\n console.info('[dumon-geolocation] openNotificationPermissionSettings is not supported on web.');\n }\n async setAuthTokens(_tokens) {\n console.info('[dumon-geolocation] setAuthTokens is a no-op on web.');\n }\n async clearAuthTokens() {\n console.info('[dumon-geolocation] clearAuthTokens is a no-op on web.');\n }\n async getAuthState() {\n return { present: false };\n }\n async setBackgroundPostUrl(_options) {\n console.info('[dumon-geolocation] setBackgroundPostUrl is not supported on web.');\n }\n async getBackgroundPostUrl() {\n return { url: null };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DumonGeolocation = registerPlugin('DumonGeolocation', {\n web: () => import('./web').then((m) => new m.DumonGeolocationWeb()),\n});\nexport * from './definitions';\nexport { DumonGeolocation };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class DumonGeolocationWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this._mode = 'normal';\n }\n async startPositioning() {\n console.log('DumonGeolocationWeb: startPositioning() called (no-op)');\n }\n async stopPositioning() {\n console.log('DumonGeolocationWeb: stopPositioning() called (no-op)');\n }\n async getLatestPosition() {\n console.log('DumonGeolocationWeb: getLatestPosition() called (returning dummy data)');\n return {\n source: 'GNSS',\n timestamp: Date.now(),\n latitude: 0,\n longitude: 0,\n accuracy: 999,\n speed: 0,\n acceleration: 0,\n directionRad: 0,\n isMocked: false,\n mode: this._mode,\n speedSource: 'NONE',\n speedImu: 0,\n speedGnss: 0,\n speedDerived: 0,\n };\n }\n async checkAndRequestPermissions() {\n console.info('[dumon-geolocation] checkAndRequestPermissions mocked for web.');\n return {\n location: 'granted',\n wifi: 'granted',\n };\n }\n async configureEdgeToEdge(options) {\n console.info('[dumon-geolocation] configureEdgeToEdge called on web with:', options);\n // No-op\n }\n async setOptions(_options) {\n // No-op on web\n }\n async setGpsMode(options) {\n this._mode = (options === null || options === void 0 ? void 0 : options.mode) === 'driving' ? 'driving' : 'normal';\n }\n async getGnssStatus() {\n return null;\n }\n async getLocationServicesStatus() {\n // Web stub; assume enabled\n return { gpsEnabled: true, networkEnabled: true };\n }\n // Background tracking stubs (no-op on web)\n async startBackgroundTracking(_options) {\n console.info('[dumon-geolocation] startBackgroundTracking is not supported on web.');\n }\n async stopBackgroundTracking() {\n console.info('[dumon-geolocation] stopBackgroundTracking is not supported on web.');\n }\n async isBackgroundTrackingActive() {\n return { active: false };\n }\n async getBackgroundLatestPosition() {\n return null;\n }\n async openBackgroundPermissionSettings() {\n console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');\n }\n async openNotificationPermissionSettings() {\n console.info('[dumon-geolocation] openNotificationPermissionSettings is not supported on web.');\n }\n async setAuthTokens(_tokens) {\n console.info('[dumon-geolocation] setAuthTokens is a no-op on web.');\n }\n async clearAuthTokens() {\n console.info('[dumon-geolocation] clearAuthTokens is a no-op on web.');\n }\n async getAuthState() {\n return { present: false };\n }\n async setBackgroundPostUrl(_options) {\n console.info('[dumon-geolocation] setBackgroundPostUrl is not supported on web.');\n }\n async getBackgroundPostUrl() {\n return { url: null };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"} \ No newline at end of file diff --git a/dist/plugin.js b/dist/plugin.js index d9c86a6..056b3bb 100644 --- a/dist/plugin.js +++ b/dist/plugin.js @@ -29,6 +29,10 @@ var capacitorDumonGeolocation = (function (exports, core) { directionRad: 0, isMocked: false, mode: this._mode, + speedSource: 'NONE', + speedImu: 0, + speedGnss: 0, + speedDerived: 0, }; } async checkAndRequestPermissions() { diff --git a/dist/plugin.js.map b/dist/plugin.js.map index 9d562ae..b3bd020 100644 --- a/dist/plugin.js.map +++ b/dist/plugin.js.map @@ -1 +1 @@ -{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DumonGeolocation = registerPlugin('DumonGeolocation', {\n web: () => import('./web').then((m) => new m.DumonGeolocationWeb()),\n});\nexport * from './definitions';\nexport { DumonGeolocation };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class DumonGeolocationWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this._mode = 'normal';\n }\n async startPositioning() {\n console.log('DumonGeolocationWeb: startPositioning() called (no-op)');\n }\n async stopPositioning() {\n console.log('DumonGeolocationWeb: stopPositioning() called (no-op)');\n }\n async getLatestPosition() {\n console.log('DumonGeolocationWeb: getLatestPosition() called (returning dummy data)');\n return {\n source: 'GNSS',\n timestamp: Date.now(),\n latitude: 0,\n longitude: 0,\n accuracy: 999,\n speed: 0,\n acceleration: 0,\n directionRad: 0,\n isMocked: false,\n mode: this._mode,\n };\n }\n async checkAndRequestPermissions() {\n console.info('[dumon-geolocation] checkAndRequestPermissions mocked for web.');\n return {\n location: 'granted',\n wifi: 'granted',\n };\n }\n async configureEdgeToEdge(options) {\n console.info('[dumon-geolocation] configureEdgeToEdge called on web with:', options);\n // No-op\n }\n async setOptions(_options) {\n // No-op on web\n }\n async setGpsMode(options) {\n this._mode = (options === null || options === void 0 ? void 0 : options.mode) === 'driving' ? 'driving' : 'normal';\n }\n async getGnssStatus() {\n return null;\n }\n async getLocationServicesStatus() {\n // Web stub; assume enabled\n return { gpsEnabled: true, networkEnabled: true };\n }\n // Background tracking stubs (no-op on web)\n async startBackgroundTracking(_options) {\n console.info('[dumon-geolocation] startBackgroundTracking is not supported on web.');\n }\n async stopBackgroundTracking() {\n console.info('[dumon-geolocation] stopBackgroundTracking is not supported on web.');\n }\n async isBackgroundTrackingActive() {\n return { active: false };\n }\n async getBackgroundLatestPosition() {\n return null;\n }\n async openBackgroundPermissionSettings() {\n console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');\n }\n async openNotificationPermissionSettings() {\n console.info('[dumon-geolocation] openNotificationPermissionSettings is not supported on web.');\n }\n async setAuthTokens(_tokens) {\n console.info('[dumon-geolocation] setAuthTokens is a no-op on web.');\n }\n async clearAuthTokens() {\n console.info('[dumon-geolocation] clearAuthTokens is a no-op on web.');\n }\n async getAuthState() {\n return { present: false };\n }\n async setBackgroundPostUrl(_options) {\n console.info('[dumon-geolocation] setBackgroundPostUrl is not supported on web.');\n }\n async getBackgroundPostUrl() {\n return { url: null };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DumonGeolocation = registerPlugin('DumonGeolocation', {\n web: () => import('./web').then((m) => new m.DumonGeolocationWeb()),\n});\nexport * from './definitions';\nexport { DumonGeolocation };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class DumonGeolocationWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this._mode = 'normal';\n }\n async startPositioning() {\n console.log('DumonGeolocationWeb: startPositioning() called (no-op)');\n }\n async stopPositioning() {\n console.log('DumonGeolocationWeb: stopPositioning() called (no-op)');\n }\n async getLatestPosition() {\n console.log('DumonGeolocationWeb: getLatestPosition() called (returning dummy data)');\n return {\n source: 'GNSS',\n timestamp: Date.now(),\n latitude: 0,\n longitude: 0,\n accuracy: 999,\n speed: 0,\n acceleration: 0,\n directionRad: 0,\n isMocked: false,\n mode: this._mode,\n speedSource: 'NONE',\n speedImu: 0,\n speedGnss: 0,\n speedDerived: 0,\n };\n }\n async checkAndRequestPermissions() {\n console.info('[dumon-geolocation] checkAndRequestPermissions mocked for web.');\n return {\n location: 'granted',\n wifi: 'granted',\n };\n }\n async configureEdgeToEdge(options) {\n console.info('[dumon-geolocation] configureEdgeToEdge called on web with:', options);\n // No-op\n }\n async setOptions(_options) {\n // No-op on web\n }\n async setGpsMode(options) {\n this._mode = (options === null || options === void 0 ? void 0 : options.mode) === 'driving' ? 'driving' : 'normal';\n }\n async getGnssStatus() {\n return null;\n }\n async getLocationServicesStatus() {\n // Web stub; assume enabled\n return { gpsEnabled: true, networkEnabled: true };\n }\n // Background tracking stubs (no-op on web)\n async startBackgroundTracking(_options) {\n console.info('[dumon-geolocation] startBackgroundTracking is not supported on web.');\n }\n async stopBackgroundTracking() {\n console.info('[dumon-geolocation] stopBackgroundTracking is not supported on web.');\n }\n async isBackgroundTrackingActive() {\n return { active: false };\n }\n async getBackgroundLatestPosition() {\n return null;\n }\n async openBackgroundPermissionSettings() {\n console.info('[dumon-geolocation] openBackgroundPermissionSettings is not supported on web.');\n }\n async openNotificationPermissionSettings() {\n console.info('[dumon-geolocation] openNotificationPermissionSettings is not supported on web.');\n }\n async setAuthTokens(_tokens) {\n console.info('[dumon-geolocation] setAuthTokens is a no-op on web.');\n }\n async clearAuthTokens() {\n console.info('[dumon-geolocation] clearAuthTokens is a no-op on web.');\n }\n async getAuthState() {\n return { present: false };\n }\n async setBackgroundPostUrl(_options) {\n console.info('[dumon-geolocation] setBackgroundPostUrl is not supported on web.');\n }\n async getBackgroundPostUrl() {\n return { url: null };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"} \ No newline at end of file diff --git a/documentation/PLUGIN_REFERENCE.md b/documentation/PLUGIN_REFERENCE.md index 2509353..eb3ef9f 100644 --- a/documentation/PLUGIN_REFERENCE.md +++ b/documentation/PLUGIN_REFERENCE.md @@ -25,12 +25,17 @@ export interface PositioningData { latitude: number; longitude: number; accuracy: number; // meter - speed: number; // m/s (dari IMU heuristik) + speed: number; // m/s (lihat kebijakan pemilihan di bawah) acceleration: number; // m/s^2 (magnitude IMU) directionRad: number; // radian, relatif utara isMocked: boolean; // lokasi terdeteksi palsu mode: 'normal' | 'driving'; // mode tracking aktif saat emisi predicted?: boolean; // true jika posisi diproyeksikan ke depan + // opsional: detail asal speed + speedSource?: 'GNSS' | 'IMU' | 'DELTA' | 'NONE'; + speedGnss?: number; // m/s dari Location.getSpeed bila tersedia & segar + speedImu?: number; // m/s dari IMU (heuristik internal) + speedDerived?: number; // m/s hasil Δpos/Δt (kasar) } export interface SatelliteStatus { @@ -184,6 +189,14 @@ Implementasi utama: `android/src/main/java/com/dumon/plugin/geolocation/DumonGeo - Jika `enableForwardPrediction` aktif dan ada IMU, posisi dapat diproyeksikan pendek (<= `maxPredictionSeconds`) memakai `speed` dan `directionRad` → flag `predicted: true`. - `source` tetap diisi nilai asli (mis. `GNSS`), bukan `FUSED`. +### Kebijakan pemilihan `speed` + +- Urutan prioritas: GNSS > IMU > Δpos/Δt > 0. + - GNSS: dipakai bila `Location.hasSpeed()` dan usia fix ≤ ~3000 ms. + - IMU: fallback dari integrasi percepatan IMU (0..30 m/s; smoothing dan idle handling diterapkan). + - Δpos/Δt: dipakai hanya bila selang waktu antar fix memadai (≥ 3 s). Cocok sebagai estimasi kasar. +- Untuk transparansi, payload dapat menyertakan `speedSource`, `speedGnss`, `speedImu`, `speedDerived` (opsional). + ### getLatestPosition (perilaku terbaru) - Memicu `GpsStatusManager.requestSingleFix()` (GPS + opsional Network) dengan timeout default ~3000 ms. diff --git a/package.json b/package.json index 66f5951..6fdc9a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dumon-geolocation", - "version": "1.0.3", + "version": "1.0.4", "description": "Implement manager GNSS, Wi‑Fi RTT, IMU, Kalman fusion, event emitter", "main": "dist/plugin.cjs.js", "module": "dist/esm/index.js", diff --git a/src/definitions.ts b/src/definitions.ts index 1d5979f..507e6dd 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -63,6 +63,11 @@ export interface PositioningData { isMocked: boolean; mode: 'normal' | 'driving'; predicted?: boolean; + // Optional detailed speed fields and provenance + speedSource?: 'GNSS' | 'IMU' | 'DELTA' | 'NONE'; + speedGnss?: number; // m/s from Location.getSpeed when available and fresh + speedImu?: number; // m/s from IMU fusion (internal heuristic) + speedDerived?: number; // m/s from delta-position / delta-time (coarse) } export interface SatelliteStatus { diff --git a/src/web.ts b/src/web.ts index 5fdcc28..f097f4c 100644 --- a/src/web.ts +++ b/src/web.ts @@ -24,6 +24,10 @@ export class DumonGeolocationWeb extends WebPlugin { directionRad: 0, isMocked: false, mode: this._mode, + speedSource: 'NONE', + speedImu: 0, + speedGnss: 0, + speedDerived: 0, }; }