thêm giao diện map và cập nhật nativewind

This commit is contained in:
Tran Anh Tuan
2025-10-30 17:55:25 +07:00
parent d717a360b7
commit f9ca9542c4
31 changed files with 1068 additions and 65 deletions

View File

@@ -1,32 +1,125 @@
import { showToastError } from "@/config";
import { fetchGpsData } from "@/controller/DeviceController";
import {
queryAlarm,
queryGpsData,
queryTrackPoints,
} from "@/controller/DeviceController";
import { getShipIcon } from "@/services/map_service";
import { Image as ExpoImage } from "expo-image";
import { useState } from "react";
import { StyleSheet, Text, TouchableOpacity } from "react-native";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import MapView, { Marker } from "react-native-maps";
import MapView, { Circle, Marker } from "react-native-maps";
import { SafeAreaProvider } from "react-native-safe-area-context";
export default function HomeScreen() {
const [gpsData, setGpsData] = useState<Model.GPSResonse | null>(null);
// useEffect(() => {
// getGpsData();
// }, []);
const [alarmData, setAlarmData] = useState<Model.AlarmResponse | null>(null);
const [trackPoints, setTrackPoints] = useState<Model.ShipTrackPoint[] | null>(
null
);
const getGpsData = async () => {
try {
const response = await fetchGpsData();
const response = await queryGpsData();
console.log("GpsData: ", response.data);
console.log(
"Heading value:",
response.data?.h,
"Type:",
typeof response.data?.h
);
setGpsData(response.data);
} catch (error) {
console.error("Error fetching GPS data:", error);
showToastError("Lỗi", "Không thể lấy dữ liệu GPS");
}
};
const getAlarmData = async () => {
try {
const response = await queryAlarm();
console.log("AlarmData: ", response.data);
setAlarmData(response.data);
} catch (error) {
console.error("Error fetching Alarm Data: ", error);
showToastError("Lỗi", "Không thể lấy dữ liệu báo động");
}
};
const getShipTrackPoints = async () => {
try {
const response = await queryTrackPoints();
console.log(
"TrackPoints Data: ",
response.data[response.data.length - 1]
);
setTrackPoints(response.data);
} catch (error) {
console.error("Error fetching TrackPoints Data: ", error);
showToastError("Lỗi", "Không thể lấy lịch sử di chuyển");
}
};
const handleMapReady = () => {
console.log("Map loaded successfully!");
getGpsData();
getAlarmData();
getShipTrackPoints();
};
// Tính toán region để bao phủ cả GPS và track points
const getMapRegion = () => {
if (!gpsData && (!trackPoints || trackPoints.length === 0)) {
return {
latitude: 15.70581,
longitude: 116.152685,
latitudeDelta: 2,
longitudeDelta: 2,
};
}
let minLat = gpsData?.lat ?? 90;
let maxLat = gpsData?.lat ?? -90;
let minLon = gpsData?.lon ?? 180;
let maxLon = gpsData?.lon ?? -180;
// Bao gồm track points
if (trackPoints) {
trackPoints.forEach((point) => {
minLat = Math.min(minLat, point.lat);
maxLat = Math.max(maxLat, point.lat);
minLon = Math.min(minLon, point.lon);
maxLon = Math.max(maxLon, point.lon);
});
}
const latDelta = Math.max(maxLat - minLat, 0.01) * 1.2; // Padding 20%
const lonDelta = Math.max(maxLon - minLon, 0.01) * 1.2;
console.log("Map region:", {
minLat,
maxLat,
minLon,
maxLon,
latDelta,
lonDelta,
});
return {
latitude: (minLat + maxLat) / 2,
longitude: (minLon + maxLon) / 2,
latitudeDelta: latDelta,
longitudeDelta: lonDelta,
};
};
return (
<SafeAreaProvider style={styles.container}>
<MapView
onMapReady={handleMapReady}
onPoiClick={(point) => {
console.log("Poi clicked: ", point.nativeEvent);
}}
style={styles.map}
initialRegion={{
latitude: 15.70581,
@@ -34,20 +127,65 @@ export default function HomeScreen() {
latitudeDelta: 2,
longitudeDelta: 2,
}}
mapType="none"
region={getMapRegion()}
// userInterfaceStyle="dark"
showsBuildings={false}
showsIndoors={false}
loadingEnabled={true}
mapType="standard"
>
{trackPoints &&
trackPoints.length > 0 &&
trackPoints.map((point, index) => {
// console.log(`Rendering circle ${index}:`, point);
return (
<Circle
key={index}
center={{
latitude: point.lat,
longitude: point.lon,
}}
zIndex={50}
radius={20} // Tăng từ 50 → 1000m
fillColor="rgba(241, 12, 65, 0.8)" // Tăng opacity từ 0.06 → 0.8
strokeColor="rgba(221, 240, 15, 0.8)"
strokeWidth={2}
/>
);
})}
{gpsData && (
<Marker
coordinate={{
latitude: gpsData.lat,
longitude: gpsData.lon,
}}
title="Device Location"
description={`Lat: ${gpsData.lat}, Lon: ${gpsData.lon}`}
/>
title="Tàu của mình"
zIndex={100}
>
<View
style={{
transform: [
{
rotate: `${
typeof gpsData.h === "number" && !isNaN(gpsData.h)
? gpsData.h
: 0
}deg`,
},
],
alignItems: "center",
justifyContent: "center",
}}
>
<ExpoImage
source={getShipIcon(alarmData?.level || 0, gpsData.fishing)}
style={{ width: 32, height: 32 }}
/>
</View>
</Marker>
)}
</MapView>
<TouchableOpacity style={styles.button} onPress={getGpsData}>
<TouchableOpacity style={styles.button} onPress={handleMapReady}>
<Text style={styles.buttonText}>Get GPS Data</Text>
</TouchableOpacity>
</SafeAreaProvider>