mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-19 14:04:08 +01:00
ui: update map to receive initial value
This commit is contained in:
parent
df38e1c9f2
commit
3ee9b92ce7
@ -1,52 +1,160 @@
|
|||||||
// google-map-with-drawing.tsx
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import React from "react";
|
import { Map, useMap, useMapsLibrary, MapControl, ControlPosition } from "@vis.gl/react-google-maps";
|
||||||
import { ControlPosition, Map, MapControl } from "@vis.gl/react-google-maps";
|
|
||||||
|
|
||||||
import { UndoRedoControl } from "@/components/map-component/undo-redo-control";
|
import { UndoRedoControl } from "@/components/map-component/undo-redo-control";
|
||||||
// Import ShapeData and useDrawingManager from the correct path
|
import { useDrawingManager } from "@/components/map-component/use-drawing-manager";
|
||||||
import { useDrawingManager, type ShapeData } from "@/components/map-component/use-drawing-manager"; // Adjust path if needed
|
import { GeoFeatureData, GeoPosition } from "@/types";
|
||||||
|
|
||||||
// Export the type so the form can use it
|
export type ShapeData = GeoFeatureData;
|
||||||
export { type ShapeData };
|
|
||||||
|
|
||||||
// Define props for the component
|
|
||||||
interface GoogleMapWithDrawingProps {
|
interface GoogleMapWithDrawingProps {
|
||||||
onShapeDrawn: (data: ShapeData) => void; // Callback prop
|
onShapeDrawn?: (data: GeoFeatureData) => void;
|
||||||
// Add any other props you might need, e.g., initialCenter, initialZoom
|
initialCenter?: GeoPosition;
|
||||||
initialCenter?: { lat: number; lng: number };
|
|
||||||
initialZoom?: number;
|
initialZoom?: number;
|
||||||
|
initialFeatures?: GeoFeatureData[] | null;
|
||||||
|
drawingMode?: google.maps.drawing.OverlayType | null;
|
||||||
|
editable?: boolean;
|
||||||
|
displayOnly?: boolean;
|
||||||
|
mapId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename DrawingExample to GoogleMapWithDrawing and accept props
|
const GoogleMapWithDrawingInternal = ({
|
||||||
const GoogleMapWithDrawing = ({
|
onShapeDrawn,
|
||||||
onShapeDrawn, // Destructure the callback prop
|
initialCenter = { lat: 13.7563, lng: 100.5018 },
|
||||||
initialCenter = { lat: 13.7563, lng: 100.5018 }, // Default center
|
initialZoom = 10,
|
||||||
initialZoom = 10, // Default zoom
|
initialFeatures,
|
||||||
|
drawingMode = null,
|
||||||
|
editable = true,
|
||||||
|
displayOnly = false,
|
||||||
}: GoogleMapWithDrawingProps) => {
|
}: GoogleMapWithDrawingProps) => {
|
||||||
// Pass the onShapeDrawn callback directly to the hook
|
const map = useMap();
|
||||||
|
const geometryLib = useMapsLibrary("geometry");
|
||||||
|
const [drawnOverlays, setDrawnOverlays] = useState<
|
||||||
|
(google.maps.Marker | google.maps.Polygon | google.maps.Polyline)[]
|
||||||
|
>([]);
|
||||||
|
const isMountedRef = useRef(false);
|
||||||
|
|
||||||
const drawingManager = useDrawingManager(onShapeDrawn);
|
const drawingManager = useDrawingManager(onShapeDrawn);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!map || !initialFeatures || initialFeatures.length === 0 || !geometryLib) return;
|
||||||
|
if (isMountedRef.current && !displayOnly) return;
|
||||||
|
|
||||||
|
drawnOverlays.forEach((overlay) => overlay.setMap(null));
|
||||||
|
const newOverlays: (google.maps.Marker | google.maps.Polygon | google.maps.Polyline)[] = [];
|
||||||
|
const bounds = new google.maps.LatLngBounds();
|
||||||
|
|
||||||
|
initialFeatures.forEach((feature) => {
|
||||||
|
if (!feature) return;
|
||||||
|
|
||||||
|
let overlay: google.maps.Marker | google.maps.Polygon | google.maps.Polyline | null = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (feature.type === "marker" && feature.position) {
|
||||||
|
const marker = new google.maps.Marker({
|
||||||
|
position: feature.position,
|
||||||
|
map: map,
|
||||||
|
});
|
||||||
|
bounds.extend(feature.position);
|
||||||
|
overlay = marker;
|
||||||
|
} else if (feature.type === "polygon" && feature.path && feature.path.length > 0) {
|
||||||
|
const polygon = new google.maps.Polygon({
|
||||||
|
paths: feature.path,
|
||||||
|
map: map,
|
||||||
|
strokeColor: "#FF0000",
|
||||||
|
strokeOpacity: 0.8,
|
||||||
|
strokeWeight: 2,
|
||||||
|
fillColor: "#FF0000",
|
||||||
|
fillOpacity: 0.35,
|
||||||
|
});
|
||||||
|
feature.path.forEach((pos) => bounds.extend(pos));
|
||||||
|
overlay = polygon;
|
||||||
|
} else if (feature.type === "polyline" && feature.path && feature.path.length > 0) {
|
||||||
|
const polyline = new google.maps.Polyline({
|
||||||
|
path: feature.path,
|
||||||
|
map: map,
|
||||||
|
strokeColor: "#0000FF",
|
||||||
|
strokeOpacity: 1.0,
|
||||||
|
strokeWeight: 3,
|
||||||
|
});
|
||||||
|
feature.path.forEach((pos) => bounds.extend(pos));
|
||||||
|
overlay = polyline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlay) {
|
||||||
|
newOverlays.push(overlay);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error creating map overlay:", e, "Feature:", feature);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setDrawnOverlays(newOverlays);
|
||||||
|
|
||||||
|
if (newOverlays.length === 1 && initialFeatures[0]?.type === "marker") {
|
||||||
|
map.setCenter(initialFeatures[0].position);
|
||||||
|
map.setZoom(initialZoom + 4);
|
||||||
|
} else if (!bounds.isEmpty()) {
|
||||||
|
map.fitBounds(bounds);
|
||||||
|
} else {
|
||||||
|
map.setCenter(initialCenter);
|
||||||
|
map.setZoom(initialZoom);
|
||||||
|
}
|
||||||
|
isMountedRef.current = true;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
newOverlays.forEach((overlay) => {
|
||||||
|
try {
|
||||||
|
overlay.setMap(null);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Error removing overlay during cleanup:", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setDrawnOverlays([]);
|
||||||
|
isMountedRef.current = false;
|
||||||
|
};
|
||||||
|
}, [map, initialFeatures, geometryLib, displayOnly]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (drawingManager) {
|
||||||
|
drawingManager.setOptions({
|
||||||
|
drawingControl: !displayOnly,
|
||||||
|
drawingMode: displayOnly ? null : drawingMode,
|
||||||
|
markerOptions: {
|
||||||
|
draggable: !displayOnly && editable,
|
||||||
|
},
|
||||||
|
polygonOptions: {
|
||||||
|
editable: !displayOnly && editable,
|
||||||
|
draggable: !displayOnly && editable,
|
||||||
|
},
|
||||||
|
polylineOptions: {
|
||||||
|
editable: !displayOnly && editable,
|
||||||
|
draggable: !displayOnly && editable,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [drawingManager, displayOnly, drawingMode, editable]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Use props for map defaults */}
|
|
||||||
<Map
|
<Map
|
||||||
defaultZoom={initialZoom}
|
defaultZoom={initialZoom}
|
||||||
defaultCenter={initialCenter}
|
defaultCenter={initialCenter}
|
||||||
gestureHandling={"greedy"}
|
gestureHandling={"greedy"}
|
||||||
disableDefaultUI={true}
|
disableDefaultUI={true}
|
||||||
mapId={"YOUR_MAP_ID"} // Recommended: Add a Map ID
|
mapId={"YOUR_MAP_ID"}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Render controls only if drawingManager is available */}
|
{!displayOnly && drawingManager && (
|
||||||
{drawingManager && (
|
|
||||||
<MapControl position={ControlPosition.TOP_LEFT}>
|
<MapControl position={ControlPosition.TOP_LEFT}>
|
||||||
{/* Pass drawingManager to UndoRedoControl */}
|
{editable && <UndoRedoControl drawingManager={drawingManager} />}
|
||||||
<UndoRedoControl drawingManager={drawingManager} />
|
|
||||||
</MapControl>
|
</MapControl>
|
||||||
)}
|
)}
|
||||||
{/* The drawing controls (marker, polygon etc.) are added by useDrawingManager */}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GoogleMapWithDrawing = (props: GoogleMapWithDrawingProps) => {
|
||||||
|
return <GoogleMapWithDrawingInternal {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
export default GoogleMapWithDrawing;
|
export default GoogleMapWithDrawing;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user