令人震惊的是,尽管
react-native-geolocation
和 lat
会实时更新并且设备会移动,但 lng
软件包无法显示 Android 设备的实时航向。我避免使用内置于谷歌地图本身的 onLocationChange ,因为它会放置一个蓝色圆形图标,我无法绕过它。我更喜欢使用我自己的标记图标。我已按照 github 页面上的说明进行操作,但标题仍然没有更新。我结果只使用设备上的传感器来使用我的两个设备,并且它们都没有磁力计。如果设备没有磁力计,我必须优雅地退出并处理。我尝试使用陀螺仪四处走动,但我的设备也没有。第二部分让我感到震惊,因为有很长一段时间可用的硬件模块。我又回来修复地理位置,或者是否有办法删除 onLocationChange 附带的蓝色图标。不管怎样,检查我的代码,看看是否有任何差距。
React.useEffect(() => {
Geolocation.requestAuthorization(() => {});
if (!origin && !destination && !recordingMode) {
if (watchId !== null) {
Geolocation.clearWatch(watchId);
setWatchId(null);
}
const noSaveWatchId = Geolocation.watchPosition(
(position) => {
const {
latitude,
longitude,
altitude,
accuracy,
speed,
heading: geoHeading,
altitudeAccuracy,
} = position.coords;
setCurrentPosition({
coordinate: { latitude, longitude },
altitude: altitude as number,
timestamp: position.timestamp,
accuracy: accuracy,
speed: speed as number,
heading: heading || (geoHeading as number),
altitudeAccuracy: altitudeAccuracy as number,
isFromMockProvider: (position as any).mocked,
});
},
(error) => console.log(error),
{
enableHighAccuracy: true,
distanceFilter: 0,
interval: 5000,
fastestInterval: 2000,
}
);
setWatchId(noSaveWatchId);
return () => {
if (noSaveWatchId !== null) {
Geolocation.clearWatch(noSaveWatchId);
}
};
} else if (origin && destination && recordingMode) {
if (watchId !== null) {
Geolocation.clearWatch(watchId);
setWatchId(null);
}
const saveWatchId = Geolocation.watchPosition(
(position) => {
const {
latitude,
longitude,
altitude,
accuracy,
speed,
heading: geoHeading,
altitudeAccuracy,
} = position.coords;
const bearing: number = calculateBearing(
latitude,
longitude,
destination.latitude,
destination.longitude
);
setCurrentPosition({
coordinate: { latitude, longitude },
altitude: altitude as number,
timestamp: position.timestamp,
accuracy: accuracy,
speed: speed as number,
heading: heading || bearing || (geoHeading as number),
altitudeAccuracy: altitudeAccuracy as number,
isFromMockProvider: (position as any).mocked,
});
if (
state &&
state.location.lat !== latitude &&
state.location.lng !== longitude
// state.location.heading !== heading
) {
dispatch({
type: Types.SetLocation,
payload: {
lat: latitude ?? 0,
lng: longitude ?? 0,
heading: heading ?? 0,
},
});
} else return;
makeLogEntry({
latitude,
longitude,
heading: heading || undefined,
})
.then(() => console.log("Log made successfully"))
.catch((error) => console.log("Error making log entry:", error));
},
(error) => console.log(error),
{
enableHighAccuracy: true,
distanceFilter: 0,
interval: 5000,
fastestInterval: 2000,
}
);
setWatchId(saveWatchId);
return () => {
if (saveWatchId !== null) {
Geolocation.clearWatch(saveWatchId);
}
};
}
}, [origin, destination, recordingMode]);
据我所知,
position.coords.heading
在某些情况下在Android上并不可靠,因为如果设备以至少每秒5m的速度移动,它通常会报告航向。
因此,您应该根据移动来计算航向,而不是依赖设备航向,因为在某些情况下它可能不会航向。当方向不可用或不可靠时使用回调函数。
const calculateBearing = (lat1: number, lon1: number, lat2: number, lon2: number) => {
const toRadians = (degree: number) => (degree * Math.PI) / 180;
const y = Math.sin(lon2 - lon1) * Math.cos(lat2);
const x =
Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
const bearing = (Math.atan2(y, x) * 180) / Math.PI;
return (bearing + 360) % 360; // Normalize bearing to 0-360 degrees
};
React.useEffect(() => {
Geolocation.requestAuthorization();
if (!origin && !destination && !recordingMode) {
if (watchId !== null) {
Geolocation.clearWatch(watchId);
setWatchId(null);
}
const noSaveWatchId = Geolocation.watchPosition(
(position) => {
const { latitude, longitude, speed, heading: geoHeading } = position.coords;
const fallbackHeading = calculateBearing(
prevLatitude, prevLongitude,
latitude, longitude
); // Calculate heading from the previous and current coordinates
setCurrentPosition({
coordinate: { latitude, longitude },
speed: speed as number,
heading: geoHeading || fallbackHeading,
});
// Update prevLatitude and prevLongitude to the current location
prevLatitude = latitude;
prevLongitude = longitude;
},
(error) => console.error(error),
{
enableHighAccuracy: true,
distanceFilter: 0,
interval: 5000,
fastestInterval: 2000,
}
);
setWatchId(noSaveWatchId);
return () => {
if (noSaveWatchId !== null) {
Geolocation.clearWatch(noSaveWatchId);
}
};
} else if (origin && destination && recordingMode) {
// Same approach here for `saveWatchId`
}
}, [origin, destination, recordingMode]);
尝试一下,如果它能解决您的问题,请告诉我。