Как сделать так, чтобы реагирующая собственная камера карты анимировалась при движении маркера, но должна быть одновремеAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как сделать так, чтобы реагирующая собственная камера карты анимировалась при движении маркера, но должна быть одновреме

Сообщение Anonymous »

как сделать так, чтобы камера реагирующей нативной карты анимировалась при движении маркера, но должна быть в то же время
я использую React-native-maps с картами Google на Android
и мне нужна камера карта анимированная, маркер перемещается одновременно
но всегда маркер перемещается, а карта следует за ним, поэтому между картой и маркером есть задержка, также я хочу, чтобы маркер всегда находился в нижней части экрана
animate_point для анимации камеры с использованием координат облака и animate_point_GPS с использованием координат GPS
это компонент карты

Код: Выделить всё

export default function MapUI() {
const { authData } = useContext(AuthContext);
const { gpsStatus, setGPSStatus } = useContext(AuthContext);
const { mapLayer, setMapLayer } = useContext(AuthContext);
const { positiveRCM, setPositiveRCM } = useContext(AuthContext);

const [token, setToken] = useState();
const [loading, setLoading] = useState(true);
const [coordinate, setCoordinate] = useState(null);
const mapRef = useRef(null);
const [markersMeasurement, setMarkersMeasurement] = useState([]);
const [prevDirection, setPrevDirection] = useState(null); // State to store previous direction

const navigation = useNavigation();
const { height } = Dimensions.get("window");

/**
* connectWebSocketApi
*/
useEffect(() => {
connectWebSocketApi(authData.ClientPrefix);
}, []);

// WebSocket event handler
const onMessage = (event) => {
try {
const data = JSON.parse(event.data);
if (data.type === "coordinate" && data.device == authData.DeviceID) {
// Update coordinate state with the received data
if (!gpsStatus) {
Updatecoordinate(
data?.latitude,
data?.longitude,
data?.azimuth,
data?.speed
);
}
}
} catch (error) {
console.error("Error parsing WebSocket data:", error);
}
};
/**
* control the permission
*/
useEffect(() => {
setToken(authData.TOKEN);
setGPSStatus(gpsStatus);
setMapLayer(mapLayer);
setPositiveRCM(positiveRCM);
}, []);

/**
* control the switch between GPS and  cloud
*/
useEffect(() => {
// Wait for a short delay before checking gpsStatus
const timeoutId = setTimeout(() => {
if (gpsStatus) {
getLocation(); //getLocation()
} else {
getCoordinates();
}
}, 500); // Adjust the delay time as needed

// Clean up the timeout to avoid memory leaks
return () => clearTimeout(timeoutId);
}, [gpsStatus]);

/**
* control the switch between GPS and cloud
*/
useEffect(() => {
if (gpsStatus) {
const intervalId = setInterval(async () => {
try {
const location = await Location.getCurrentPositionAsync({
accuracy: Location.Accuracy.Highest,
});

Updatecoordinate_GPS(
location.coords?.latitude,
location.coords?.longitude,
location.coords?.heading,
location.coords?.speed
);
} catch (error) {
console.error("Error getting location:", error);
}
}, 800); // Update location every 1 second

return () => clearInterval(intervalId);
}
}, []);

/**
*
* @param {*} latitude
* @param {*} longitude
* @param {*} azimuth
*/
const Updatecoordinate_GPS = (latitude, longitude, azimuth, speed) => {
if (
latitude != coordinate?.latitude ||
longitude != coordinate?.longitude
) {
const newCoordinate = {
latitude,
longitude,
azimuth,
speed,
};
//console.log(newCoordinate)
setCoordinate(newCoordinate);
animate_point_GPS(newCoordinate);
}
};

/**
*
*/
const animate_point_GPS = async (newCoordinate) => {
let duration = 0;
const heading = newCoordinate?.azimuth;
const headingChanged = Math.abs(heading - prevDirection) > 10; // Define a threshold for significant change
headingChanged && setPrevDirection(heading); // Update previous direction

if (newCoordinate?.speed > 100) {
duration = 1100;
} else if (newCoordinate?.speed >  50) {
duration = 900;
} else {
duration = 1100;
}
// Animate camera to the new coordinates
mapRef?.current?.animateCamera(
{
heading: headingChanged ? heading : prevDirection,
center: {
latitude: newCoordinate.latitude,
longitude: newCoordinate.longitude,
},

pitch: 55,
},
{ duration: duration }
);
};

/**
* get current location using GPS
*/
const getLocation = async () => {
setLoading(true);
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
console.error("Permission to access location was denied");
return;
}

let location = await Location.getCurrentPositionAsync({
accuracy: Location.Accuracy.High,
});
const newCoordinate = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
azimuth: location.coords.heading,
};

setCoordinate(newCoordinate);
//console.log("location: ", location.coords)

setLoading(false);
};
/**
* get current location using
*/

/**
*
* @param {number} latitude
* @param {number} longitude import defaultPin from "/default.png"

* @param {number} azimuth
*/
const Updatecoordinate = (latitude, longitude, azimuth, speed) => {
const newCoordinate = {
latitude,
longitude,
};
setCoordinate(newCoordinate);
animate_point();
};
/**
* animate_point the camera to follow the device
*/
const animate_point = async () => {
let duration = 0;
const heading = gpsStatus ? coordinate?.heading : coordinate?.azimuth;
const headingThreshold = 10; // Define a threshold for significant heading changes

// Determine if the heading change is significant
const headingChanged =
prevDirection === null ||
Math.abs(heading - prevDirection) > headingThreshold;

if (headingChanged) {
setPrevDirection(heading); // Update previous direction only if change is significant
}

if (coordinate?.speed > 100) {
duration = 1100;
} else if (coordinate?.speed > 50) {
duration = 900;
} else {
duration = 1100;
}

mapRef?.current?.animateCamera(
{
// heading: headingChanged ? heading : prevDirection,
center: {
latitude: coordinate.latitude,
longitude: coordinate.longitude,
},
pitch: 55,
},
{ duration: duration }
);
};

return (


{/* WebSocket configuration component */}


{coordinate && (






)}








);
}

а это компонент DeviceMarker

Код: Выделить всё

export default function DeviceMarker({ coord, gpsStatus, mapRef }) {
const [marker, setMarker] = useState(null);
const markerRef = useRef(null);
const duration = 1100;
const [tracksViewChanges, setTracksViewChanges] = useState(true);

const [coordinate, setCoordinate] = useState(
new AnimatedRegion({
latitude: coord?.latitude || 0, // Ensure default value is provided
longitude: coord?.longitude || 0, // Ensure default value is provided
latitudeDelta: 0.001,
longitudeDelta: 0.001,
})
);

useEffect(() => {
const timer = setTimeout(() => {
setTracksViewChanges(false);
detectHeadingAtFirstLoad();
}, 1000); // Adjust the delay as necessary

return () => clearTimeout(timer);
}, []);

useEffect(() => {
// Update marker position when coord changes
if (markerRef.current) {
const newCoordinate = {
latitude: coord?.latitude || 0, // Ensure default value is provided
longitude: coord?.longitude || 0, // Ensure default value is provided
latitudeDelta: 0.001,
longitudeDelta: 0.001,
};

coordinate
.timing({
...newCoordinate,
duration,
easing: Easing.linear,
useNativeDriver: false,

})
.start();
}
}, [coord]);

/**
* detectHeadingAtFirstLoad
*/
const detectHeadingAtFirstLoad = async () => {
const heading = gpsStatus ? coord?.heading : coord?.azimuth;
mapRef?.current?.animateCamera({
heading: heading,
center: {
latitude: coord.latitude,
longitude: coord.longitude,
},
pitch: 55,
});
};
return (



);
}

пожалуйста, помогите мне разобраться
Спасибо

Подробнее здесь: https://stackoverflow.com/questions/785 ... the-marker
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»