thêm zustand để cấu hình global state, hook để lấy platform, thêm polyline và polygon b vào map

This commit is contained in:
Tran Anh Tuan
2025-10-31 19:54:16 +07:00
parent 2fac0b8093
commit 5801992eae
19 changed files with 1202 additions and 89 deletions

View File

@@ -0,0 +1,62 @@
import { useCallback, useState } from "react";
/**
* Hook để tính radius cố định cho Circle trên MapView
* Radius sẽ được điều chỉnh dựa trên zoom level để giữ kích thước pixel cố định
*/
export const useFixedCircleRadius = (pixelRadius: number = 30) => {
const [radius, setRadius] = useState(100); // Giá trị default
const calculateRadiusFromZoom = useCallback((zoomLevel: number) => {
// Công thức: radius (meters) = pixelRadius * 156543.04 * cos(latitude) / 2^(zoomLevel + 8)
// Đơn giản hơn: radius tỉ lệ với 2^(maxZoom - currentZoom)
// Khi zoom = 14, dùng radius = 100 làm reference
const baseZoom = 14;
const baseRadius = 100;
// Mỗi level zoom tương ứng với 2x sự khác biệt
const zoomDifference = baseZoom - zoomLevel;
const calculatedRadius = baseRadius * Math.pow(2, zoomDifference);
return Math.max(calculatedRadius, 10); // Minimum 10 meters
}, []);
const handleZoomChange = useCallback(
(zoomLevel: number) => {
const newRadius = calculateRadiusFromZoom(zoomLevel);
setRadius(newRadius);
},
[calculateRadiusFromZoom]
);
return {
radius,
handleZoomChange,
};
};
/**
* Alternative: Sử dụng Polygon thay vì Circle để có kích thước cố định theo pixel
* Tạo một hình tròn bằng Polygon với điểm tâm là coordinate
*/
export const createCircleCoordinates = (
center: { latitude: number; longitude: number },
radiusInMeters: number,
points: number = 36
) => {
const coordinates = [];
const latDelta = radiusInMeters / 111000; // 1 degree ~ 111km
for (let i = 0; i < points; i++) {
const angle = (i / points) * (2 * Math.PI);
const longitude =
center.longitude +
(latDelta * Math.cos(angle)) /
Math.cos((center.latitude * Math.PI) / 180);
const latitude = center.latitude + latDelta * Math.sin(angle);
coordinates.push({ latitude, longitude });
}
return coordinates;
};

23
hooks/use-platform.ts Normal file
View File

@@ -0,0 +1,23 @@
import { Platform } from "react-native";
export type PlatformType = "ios" | "android" | "web";
export const usePlatform = (): PlatformType => {
return Platform.OS as PlatformType;
};
export const useIsIOS = (): boolean => {
return Platform.OS === "ios";
};
export const useIsAndroid = (): boolean => {
return Platform.OS === "android";
};
export const useIsWeb = (): boolean => {
return Platform.OS === "web";
};
export const getPlatform = (): PlatformType => {
return Platform.OS as PlatformType;
};