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:
62
hooks/use-fixed-circle-radius.ts
Normal file
62
hooks/use-fixed-circle-radius.ts
Normal 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;
|
||||
};
|
||||
Reference in New Issue
Block a user