diff --git a/frontend/components/google-map-with-drawing.tsx b/frontend/components/google-map-with-drawing.tsx
index 0cdd310..91bfcca 100644
--- a/frontend/components/google-map-with-drawing.tsx
+++ b/frontend/components/google-map-with-drawing.tsx
@@ -1,52 +1,160 @@
-// google-map-with-drawing.tsx
-import React from "react";
-import { ControlPosition, Map, MapControl } from "@vis.gl/react-google-maps";
-
+import React, { useEffect, useRef, useState } from "react";
+import { Map, useMap, useMapsLibrary, MapControl, ControlPosition } from "@vis.gl/react-google-maps";
import { UndoRedoControl } from "@/components/map-component/undo-redo-control";
-// Import ShapeData and useDrawingManager from the correct path
-import { useDrawingManager, type ShapeData } from "@/components/map-component/use-drawing-manager"; // Adjust path if needed
+import { useDrawingManager } from "@/components/map-component/use-drawing-manager";
+import { GeoFeatureData, GeoPosition } from "@/types";
-// Export the type so the form can use it
-export { type ShapeData };
+export type ShapeData = GeoFeatureData;
-// Define props for the component
interface GoogleMapWithDrawingProps {
- onShapeDrawn: (data: ShapeData) => void; // Callback prop
- // Add any other props you might need, e.g., initialCenter, initialZoom
- initialCenter?: { lat: number; lng: number };
+ onShapeDrawn?: (data: GeoFeatureData) => void;
+ initialCenter?: GeoPosition;
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 GoogleMapWithDrawing = ({
- onShapeDrawn, // Destructure the callback prop
- initialCenter = { lat: 13.7563, lng: 100.5018 }, // Default center
- initialZoom = 10, // Default zoom
+const GoogleMapWithDrawingInternal = ({
+ onShapeDrawn,
+ initialCenter = { lat: 13.7563, lng: 100.5018 },
+ initialZoom = 10,
+ initialFeatures,
+ drawingMode = null,
+ editable = true,
+ displayOnly = false,
}: 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);
+ 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 (
<>
- {/* Use props for map defaults */}
- {/* Render controls only if drawingManager is available */}
- {drawingManager && (
+ {!displayOnly && drawingManager && (
- {/* Pass drawingManager to UndoRedoControl */}
-
+ {editable && }
)}
- {/* The drawing controls (marker, polygon etc.) are added by useDrawingManager */}
>
);
};
+const GoogleMapWithDrawing = (props: GoogleMapWithDrawingProps) => {
+ return ;
+};
+
export default GoogleMapWithDrawing;