63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
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;
|
|
};
|