Compare commits
3 Commits
b44f1a9b29
...
device_sgw
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28739ddcd9 | ||
|
|
53dfb861dd | ||
|
|
076d0460cb |
@@ -1,7 +1,15 @@
|
|||||||
import { DefaultFooter } from '@ant-design/pro-components';
|
import { DefaultFooter } from '@ant-design/pro-components';
|
||||||
|
import './style.less';
|
||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
return <DefaultFooter copyright="2025 Sản phẩm của Mobifone v1.0" />;
|
return (
|
||||||
|
<DefaultFooter
|
||||||
|
style={{
|
||||||
|
background: 'none',
|
||||||
|
color: 'white',
|
||||||
|
}}
|
||||||
|
copyright="2025 Sản phẩm của Mobifone v1.2"
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Footer;
|
export default Footer;
|
||||||
|
|||||||
3
src/components/Footer/style.less
Normal file
3
src/components/Footer/style.less
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.ant-pro-global-footer-copyright {
|
||||||
|
color: white !important; /* hoặc mã màu bạn muốn */
|
||||||
|
}
|
||||||
@@ -6,3 +6,7 @@ export enum STATUS {
|
|||||||
UPDATE_FISHING_LOG_SUCCESS = 'UPDATE_FISHING_LOG_SUCCESS',
|
UPDATE_FISHING_LOG_SUCCESS = 'UPDATE_FISHING_LOG_SUCCESS',
|
||||||
UPDATE_FISHING_LOG_FAIL = 'UPDATE_FISHING_LOG_FAIL',
|
UPDATE_FISHING_LOG_FAIL = 'UPDATE_FISHING_LOG_FAIL',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ENTITY_TYPE_ENUM {
|
||||||
|
SOS_WARNING = '50:15',
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default function useGetGpsModel() {
|
|||||||
const res = await getGPS(); // đổi URL cho phù hợp
|
const res = await getGPS(); // đổi URL cho phù hợp
|
||||||
console.log('GPS Data fetched:', res);
|
console.log('GPS Data fetched:', res);
|
||||||
|
|
||||||
setGpsData(res || []);
|
setGpsData(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Fetch gps data failed', err);
|
console.error('Fetch gps data failed', err);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import Footer from '@/components/Footer/Footer';
|
||||||
import { ROUTE_HOME } from '@/constants';
|
import { ROUTE_HOME } from '@/constants';
|
||||||
import { login } from '@/services/controller/AuthController';
|
import { login } from '@/services/controller/AuthController';
|
||||||
import { parseJwt } from '@/utils/jwtTokenUtils';
|
import { parseJwt } from '@/utils/jwtTokenUtils';
|
||||||
@@ -127,6 +128,17 @@ const LoginPage = () => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
</LoginFormPage>
|
</LoginFormPage>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
zIndex: 99,
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,16 +7,21 @@ import {
|
|||||||
} from '@/utils/mapUtils';
|
} from '@/utils/mapUtils';
|
||||||
import { Feature, Map, View } from 'ol';
|
import { Feature, Map, View } from 'ol';
|
||||||
import { Coordinate } from 'ol/coordinate';
|
import { Coordinate } from 'ol/coordinate';
|
||||||
|
import { easeOut } from 'ol/easing';
|
||||||
|
import { EventsKey } from 'ol/events';
|
||||||
import { createEmpty, extend, Extent, isEmpty } from 'ol/extent';
|
import { createEmpty, extend, Extent, isEmpty } from 'ol/extent';
|
||||||
import { LineString, MultiPolygon, Point, Polygon } from 'ol/geom';
|
import { LineString, MultiPolygon, Point, Polygon } from 'ol/geom';
|
||||||
import BaseLayer from 'ol/layer/Base';
|
import BaseLayer from 'ol/layer/Base';
|
||||||
import VectorLayer from 'ol/layer/Vector';
|
import VectorLayer from 'ol/layer/Vector';
|
||||||
|
import { unByKey } from 'ol/Observable';
|
||||||
import { fromLonLat } from 'ol/proj';
|
import { fromLonLat } from 'ol/proj';
|
||||||
|
import { getVectorContext } from 'ol/render';
|
||||||
|
import RenderEvent from 'ol/render/Event';
|
||||||
import VectorSource from 'ol/source/Vector';
|
import VectorSource from 'ol/source/Vector';
|
||||||
|
import { Circle as CircleStyle, Style } from 'ol/style';
|
||||||
import Fill from 'ol/style/Fill';
|
import Fill from 'ol/style/Fill';
|
||||||
import Icon from 'ol/style/Icon';
|
import Icon from 'ol/style/Icon';
|
||||||
import Stroke from 'ol/style/Stroke';
|
import Stroke from 'ol/style/Stroke';
|
||||||
import Style from 'ol/style/Style';
|
|
||||||
import Text from 'ol/style/Text';
|
import Text from 'ol/style/Text';
|
||||||
|
|
||||||
interface MapManagerConfig {
|
interface MapManagerConfig {
|
||||||
@@ -25,6 +30,12 @@ interface MapManagerConfig {
|
|||||||
onFeaturesClick?: (features: any[]) => void;
|
onFeaturesClick?: (features: any[]) => void;
|
||||||
onError?: (error: string[]) => void;
|
onError?: (error: string[]) => void;
|
||||||
}
|
}
|
||||||
|
interface AnimationConfig {
|
||||||
|
duration?: number;
|
||||||
|
maxRadius?: number;
|
||||||
|
strokeColor?: string;
|
||||||
|
strokeWidthBase?: number;
|
||||||
|
}
|
||||||
|
|
||||||
interface StyleConfig {
|
interface StyleConfig {
|
||||||
icon?: string; // URL của icon
|
icon?: string; // URL của icon
|
||||||
@@ -66,6 +77,7 @@ class MapManager {
|
|||||||
private errors: string[];
|
private errors: string[];
|
||||||
private layers: BaseLayer[]; // Assuming layers is defined elsewhere
|
private layers: BaseLayer[]; // Assuming layers is defined elsewhere
|
||||||
private isInitialized: boolean; // Thêm thuộc tính để theo dõi trạng thái khởi tạo
|
private isInitialized: boolean; // Thêm thuộc tính để theo dõi trạng thái khởi tạo
|
||||||
|
private eventKey: EventsKey | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
mapRef: React.RefObject<HTMLDivElement>,
|
mapRef: React.RefObject<HTMLDivElement>,
|
||||||
@@ -83,11 +95,12 @@ class MapManager {
|
|||||||
this.errors = [];
|
this.errors = [];
|
||||||
this.layers = []; // Initialize layers (adjust based on actual usage)
|
this.layers = []; // Initialize layers (adjust based on actual usage)
|
||||||
this.isInitialized = false; // Khởi tạo là false
|
this.isInitialized = false; // Khởi tạo là false
|
||||||
|
this.eventKey = undefined; // Khởi tạo eventKey
|
||||||
}
|
}
|
||||||
|
|
||||||
async getListLayers(): Promise<[]> {
|
async getListLayers(): Promise<[]> {
|
||||||
const resp: [] = await getAllLayer();
|
const resp: [] = await getAllLayer();
|
||||||
console.log('resp', resp);
|
// console.log('resp', resp);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,10 +112,15 @@ class MapManager {
|
|||||||
for (const layerMeta of listLayers) {
|
for (const layerMeta of listLayers) {
|
||||||
try {
|
try {
|
||||||
const data = await getLayer(layerMeta); // lấy GeoJSON từ server
|
const data = await getLayer(layerMeta); // lấy GeoJSON từ server
|
||||||
|
let style = {};
|
||||||
|
if (layerMeta === 'base-countries') {
|
||||||
|
style = createLabelAndFillStyle('#F3F2EC', '#E5BEB5');
|
||||||
|
} else {
|
||||||
|
style = createLabelAndFillStyle('#77BEF0', '#000000');
|
||||||
|
}
|
||||||
const vectorLayer = createGeoJSONLayer({
|
const vectorLayer = createGeoJSONLayer({
|
||||||
data,
|
data,
|
||||||
style: createLabelAndFillStyle('#77BEF0', '#000000'),
|
style: style,
|
||||||
});
|
});
|
||||||
|
|
||||||
dynamicLayers.push(vectorLayer);
|
dynamicLayers.push(vectorLayer);
|
||||||
@@ -328,8 +346,10 @@ class MapManager {
|
|||||||
// Lưu feature
|
// Lưu feature
|
||||||
this.features.push(feature);
|
this.features.push(feature);
|
||||||
this.featureLayer?.getSource()?.addFeature(feature);
|
this.featureLayer?.getSource()?.addFeature(feature);
|
||||||
|
if (styleConfig.animate) {
|
||||||
console.log('Point added successfully:', { coord, data, styleConfig });
|
this.animatedMarker(feature, styleConfig.animationConfig);
|
||||||
|
}
|
||||||
|
// console.log('Point added successfully:', { coord, data, styleConfig });
|
||||||
|
|
||||||
return feature;
|
return feature;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -340,6 +360,74 @@ class MapManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
animatedMarker = (
|
||||||
|
feature: Feature<Point>,
|
||||||
|
config: AnimationConfig = {},
|
||||||
|
): void => {
|
||||||
|
const {
|
||||||
|
duration = 3000,
|
||||||
|
maxRadius = 20,
|
||||||
|
strokeColor = 'rgba(255, 0, 0, 0.8)',
|
||||||
|
strokeWidthBase = 0.25,
|
||||||
|
} = config;
|
||||||
|
console.log('Starting animatedMarker with config:', config);
|
||||||
|
|
||||||
|
const flashGeom = feature.getGeometry()?.clone() as Point | undefined;
|
||||||
|
if (!flashGeom || !this.featureLayer) {
|
||||||
|
console.error('Invalid geometry or featureLayer for animation');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tạo 2 "pha" sóng, mỗi sóng bắt đầu cách nhau duration/2
|
||||||
|
const waveCount = 1;
|
||||||
|
const waveOffsets = Array.from(
|
||||||
|
{ length: waveCount },
|
||||||
|
(_, i) => (duration / waveCount) * i,
|
||||||
|
);
|
||||||
|
const start = Date.now();
|
||||||
|
|
||||||
|
const listenerKey: EventsKey = this.featureLayer.on(
|
||||||
|
'postrender',
|
||||||
|
(event: RenderEvent) => {
|
||||||
|
const frameState = event.frameState;
|
||||||
|
if (!frameState) return;
|
||||||
|
|
||||||
|
const elapsedTotal = frameState.time - start;
|
||||||
|
if (elapsedTotal >= duration * 3) {
|
||||||
|
// chạy 2 chu kỳ rồi dừng (bạn có thể bỏ điều kiện này để chạy mãi)
|
||||||
|
unByKey(listenerKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vectorContext = getVectorContext(event);
|
||||||
|
|
||||||
|
waveOffsets.forEach((offset) => {
|
||||||
|
const elapsed =
|
||||||
|
(frameState.time - start - offset + duration) % duration;
|
||||||
|
const elapsedRatio = elapsed / duration;
|
||||||
|
|
||||||
|
const radius = easeOut(elapsedRatio) * (maxRadius - 5) + 5;
|
||||||
|
const opacity = easeOut(1 - elapsedRatio);
|
||||||
|
|
||||||
|
const style = new Style({
|
||||||
|
image: new CircleStyle({
|
||||||
|
radius,
|
||||||
|
stroke: new Stroke({
|
||||||
|
color: strokeColor.replace('0.8', opacity.toString()),
|
||||||
|
width: strokeWidthBase + opacity,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
vectorContext.setStyle(style);
|
||||||
|
vectorContext.drawGeometry(flashGeom);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.map!.render();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.eventKey = listenerKey;
|
||||||
|
};
|
||||||
|
|
||||||
addPolygon(
|
addPolygon(
|
||||||
coords: Coordinate[][],
|
coords: Coordinate[][],
|
||||||
@@ -510,12 +598,12 @@ class MapManager {
|
|||||||
if (this.featureLayer && this.isInitialized) {
|
if (this.featureLayer && this.isInitialized) {
|
||||||
this.features.push(feature);
|
this.features.push(feature);
|
||||||
this.featureLayer.getSource()?.addFeature(feature);
|
this.featureLayer.getSource()?.addFeature(feature);
|
||||||
console.log(
|
// console.log(
|
||||||
'LineString added successfully at',
|
// 'LineString added successfully at',
|
||||||
new Date().toLocaleTimeString(),
|
// new Date().toLocaleTimeString(),
|
||||||
':',
|
// ':',
|
||||||
{ coords, data, styleConfig },
|
// { coords, data, styleConfig },
|
||||||
);
|
// );
|
||||||
// Đảm bảo bản đồ được render lại
|
// Đảm bảo bản đồ được render lại
|
||||||
this.map?.render();
|
this.map?.render();
|
||||||
return feature;
|
return feature;
|
||||||
@@ -540,10 +628,10 @@ class MapManager {
|
|||||||
styleConfig: Record<string, any> = {},
|
styleConfig: Record<string, any> = {},
|
||||||
zoom: number,
|
zoom: number,
|
||||||
) => {
|
) => {
|
||||||
console.log(
|
// console.log(
|
||||||
`createPolygonStyle called with zoom: ${zoom}, styleConfig:`,
|
// `createPolygonStyle called with zoom: ${zoom}, styleConfig:`,
|
||||||
styleConfig,
|
// styleConfig,
|
||||||
); // Debug
|
// ); // Debug
|
||||||
const textContent = `Tên: ${data?.name ?? 'Chưa có'}\n\n Loại: ${
|
const textContent = `Tên: ${data?.name ?? 'Chưa có'}\n\n Loại: ${
|
||||||
data?.type ?? 0
|
data?.type ?? 0
|
||||||
}\n\nThông tin: ${data?.description ?? 'Chưa có'}`;
|
}\n\nThông tin: ${data?.description ?? 'Chưa có'}`;
|
||||||
@@ -581,7 +669,7 @@ class MapManager {
|
|||||||
text: textStyle,
|
text: textStyle,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Polygon style created:`, style); // Debug
|
// console.log(`Polygon style created:`, style); // Debug
|
||||||
return [style];
|
return [style];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
MAP_TRACKPOINTS_ID,
|
MAP_TRACKPOINTS_ID,
|
||||||
ROUTE_TRIP,
|
ROUTE_TRIP,
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
|
import { ENTITY_TYPE_ENUM } from '@/constants/enums';
|
||||||
import {
|
import {
|
||||||
queryAlarms,
|
queryAlarms,
|
||||||
queryEntities,
|
queryEntities,
|
||||||
@@ -29,6 +30,21 @@ import ShipInfo from './components/ShipInfo';
|
|||||||
import SosButton from './components/SosButton';
|
import SosButton from './components/SosButton';
|
||||||
import VietNamMap, { MapManager } from './components/VietNamMap';
|
import VietNamMap, { MapManager } from './components/VietNamMap';
|
||||||
|
|
||||||
|
// // Define missing types locally for now
|
||||||
|
// interface AlarmData {
|
||||||
|
// level: number;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface EntityData {
|
||||||
|
// id: string;
|
||||||
|
// valueString: string;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface TrackPoint {
|
||||||
|
// lat: number;
|
||||||
|
// lon: number;
|
||||||
|
// }
|
||||||
|
|
||||||
export interface GpsData {
|
export interface GpsData {
|
||||||
lat: number;
|
lat: number;
|
||||||
lon: number;
|
lon: number;
|
||||||
@@ -78,9 +94,9 @@ const HomePage: React.FC = () => {
|
|||||||
getGPSData();
|
getGPSData();
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
getGPSData();
|
getGPSData();
|
||||||
getEntitiesData();
|
getEntitiesData(mapManagerRef.current, gpsData!);
|
||||||
getShipTrackPoints();
|
fetchAndAddTrackPoints(mapManagerRef.current);
|
||||||
getEntityData();
|
fetchAndProcessEntities(mapManagerRef.current);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
@@ -91,107 +107,76 @@ const HomePage: React.FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
// getGPSData();
|
// getGPSData();
|
||||||
getEntitiesData();
|
getEntitiesData(mapManagerRef.current, gpsData!);
|
||||||
getShipTrackPoints();
|
fetchAndAddTrackPoints(mapManagerRef.current);
|
||||||
getEntityData();
|
fetchAndProcessEntities(mapManagerRef.current);
|
||||||
}, 1000); // delay 1s
|
}, 1000); // delay 1s
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [gpsData]);
|
}, [gpsData]);
|
||||||
|
|
||||||
const getEntitiesData = async () => {
|
// Helper function to add features to the map
|
||||||
try {
|
const addFeatureToMap = (
|
||||||
const alarm = await queryAlarms();
|
mapManager: MapManager,
|
||||||
// console.log('Fetched alarm data:', alarm);
|
gpsData: GpsData,
|
||||||
// console.log('GPS Data:', gpsData);
|
alarm: API.AlarmResponse,
|
||||||
|
) => {
|
||||||
|
console.log(
|
||||||
|
'Adding feature to map with GPS data:',
|
||||||
|
gpsData,
|
||||||
|
'and alarm:',
|
||||||
|
alarm,
|
||||||
|
);
|
||||||
|
const isSos = alarm?.alarms.find(
|
||||||
|
(a) => a.id === ENTITY_TYPE_ENUM.SOS_WARNING,
|
||||||
|
);
|
||||||
|
console.log('Is SOS Alarm Present:', isSos);
|
||||||
|
|
||||||
if (mapManagerRef.current?.featureLayer && gpsData) {
|
if (mapManager?.featureLayer && gpsData) {
|
||||||
// Clear trước
|
mapManager.featureLayer.getSource()?.clear();
|
||||||
mapManagerRef.current.featureLayer.getSource()?.clear();
|
mapManager.addPoint(
|
||||||
|
|
||||||
try {
|
|
||||||
// Tạo feature mới
|
|
||||||
const feature = mapManagerRef.current.addPoint(
|
|
||||||
[gpsData.lon, gpsData.lat],
|
[gpsData.lon, gpsData.lat],
|
||||||
{
|
{ bearing: gpsData.h || 0 },
|
||||||
bearing: gpsData.h || 0,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
icon: getShipIcon(alarm.level || 0, gpsData?.fishing || false),
|
icon: getShipIcon(alarm.level || 0, gpsData?.fishing || false),
|
||||||
scale: 0.1,
|
scale: 0.1,
|
||||||
|
animate: isSos ? true : false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (parseError) {
|
|
||||||
console.error(
|
|
||||||
`Error parsing valueString for entity: ${parseError}`,
|
|
||||||
parseError,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching entities:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getShipTrackPoints = async () => {
|
|
||||||
try {
|
|
||||||
const trackpoints = await queryShipTrackPoints();
|
|
||||||
// console.log('Fetched ship track points:', trackpoints.length);
|
|
||||||
if (trackpoints.length > 0) {
|
|
||||||
mapManagerRef.current?.addLineString(
|
|
||||||
trackpoints.map((point) => [point.lon, point.lat]),
|
|
||||||
{
|
|
||||||
id: MAP_TRACKPOINTS_ID,
|
|
||||||
// You can add more properties here if needed
|
|
||||||
},
|
|
||||||
{
|
|
||||||
strokeColor: 'blue',
|
|
||||||
strokeWidth: 3,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching ship track points:', error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getEntityData = async () => {
|
const fetchAndProcessEntities = async (mapManager: MapManager) => {
|
||||||
try {
|
try {
|
||||||
const entities = await queryEntities();
|
const entities: API.TransformedEntity[] = await queryEntities();
|
||||||
console.log('Fetched entities:', entities.length);
|
console.log('Fetched entities:', entities.length);
|
||||||
if (entities.length > 0) {
|
|
||||||
entities.forEach(async (entity) => {
|
for (const entity of entities) {
|
||||||
if (entity.id == '50:2') {
|
if (entity.id === '50:2' && entity.valueString !== '[]') {
|
||||||
const banzones = await queryBanzones();
|
const banzones = await queryBanzones();
|
||||||
console.log('Fetched banzones:', banzones.length);
|
const zones: any[] = JSON.parse(entity.valueString);
|
||||||
if (entity.valueString != '[]') {
|
|
||||||
const zones = JSON.parse(entity.valueString);
|
zones.forEach((zone: any) => {
|
||||||
console.log('Parsed zones:', zones);
|
|
||||||
for (const zone of zones) {
|
|
||||||
const geom = banzones.find((b) => b.id === zone.zone_id);
|
const geom = banzones.find((b) => b.id === zone.zone_id);
|
||||||
if (geom) {
|
if (geom) {
|
||||||
if (geom.geom?.geom_type === 2) {
|
const { geom_type, geom_lines, geom_poly } = geom.geom || {};
|
||||||
// Polyline
|
if (geom_type === 2) {
|
||||||
const coordinates = convertWKTLineStringToLatLngArray(
|
const coordinates = convertWKTLineStringToLatLngArray(
|
||||||
geom?.geom?.geom_lines || '',
|
geom_lines || '',
|
||||||
);
|
);
|
||||||
if (coordinates.length > 0) {
|
if (coordinates.length > 0) {
|
||||||
mapManagerRef.current.addLineString(
|
mapManager.addLineString(
|
||||||
coordinates,
|
coordinates,
|
||||||
{
|
{
|
||||||
id: MAP_POLYLINE_BAN,
|
id: MAP_POLYLINE_BAN,
|
||||||
text: `${geom.name} - ${zone.message}`,
|
text: `${geom.name} - ${zone.message}`,
|
||||||
},
|
},
|
||||||
{
|
{ strokeColor: 'red', strokeWidth: 4 },
|
||||||
strokeColor: 'red',
|
|
||||||
strokeWidth: 4,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (geom.geom?.geom_type === 1) {
|
} else if (geom_type === 1) {
|
||||||
const coordinates = convertWKTtoLatLngString(
|
const coordinates = convertWKTtoLatLngString(geom_poly || '');
|
||||||
geom?.geom?.geom_poly || '',
|
|
||||||
);
|
|
||||||
if (coordinates.length > 0) {
|
if (coordinates.length > 0) {
|
||||||
mapManagerRef.current.addPolygon(
|
mapManager.addPolygon(
|
||||||
coordinates,
|
coordinates,
|
||||||
{
|
{
|
||||||
id: MAP_POLYGON_BAN,
|
id: MAP_POLYGON_BAN,
|
||||||
@@ -200,23 +185,41 @@ const HomePage: React.FC = () => {
|
|||||||
description: zone.message,
|
description: zone.message,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
strokeColor: 'yellow',
|
strokeColor: '#FCC61D',
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
fillColor: 'rgba(255, 255, 0, 0.3)', // Màu vàng với độ trong suốt
|
fillColor: '#FCC61D',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.log('No geometry found for zone:', zone.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('Zone rỗng');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching entities:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchAndAddTrackPoints = async (mapManager: MapManager) => {
|
||||||
|
try {
|
||||||
|
const trackpoints: API.ShipTrackPoint[] = await queryShipTrackPoints();
|
||||||
|
if (trackpoints.length > 0) {
|
||||||
|
mapManager.addLineString(
|
||||||
|
trackpoints.map((point) => [point.lon, point.lat]),
|
||||||
|
{ id: MAP_TRACKPOINTS_ID },
|
||||||
|
{ strokeColor: 'blue', strokeWidth: 3 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching ship track points:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getEntitiesData = async (mapManager: MapManager, gpsData: GpsData) => {
|
||||||
|
try {
|
||||||
|
const alarm: API.AlarmResponse = await queryAlarms();
|
||||||
|
addFeatureToMap(mapManager, gpsData, alarm);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching entities:', error);
|
console.error('Error fetching entities:', error);
|
||||||
}
|
}
|
||||||
@@ -268,7 +271,12 @@ const HomePage: React.FC = () => {
|
|||||||
<SosButton
|
<SosButton
|
||||||
onRefresh={(value) => {
|
onRefresh={(value) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
getEntitiesData();
|
// Ensure null check for gpsData in all usages
|
||||||
|
if (gpsData) {
|
||||||
|
getEntitiesData(mapManagerRef.current, gpsData);
|
||||||
|
} else {
|
||||||
|
console.warn('GPS data is null, skipping getEntitiesData call');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user