diff --git a/frontend/src/components/Maps/PropertyMap.js b/frontend/src/components/Maps/PropertyMap.js
index 6711346..081df01 100644
--- a/frontend/src/components/Maps/PropertyMap.js
+++ b/frontend/src/components/Maps/PropertyMap.js
@@ -112,7 +112,8 @@ const PropertyMap = ({
mode = "view", // "view", "edit", "execution"
gpsTrack = [],
currentLocation = null,
- showTrackPoints = true
+ showTrackPoints = true,
+ direction = null // optional mowing direction: N_S, E_W, NE_SW, NW_SE, CIRCULAR
}) => {
// Debug logging
@@ -413,7 +414,7 @@ const PropertyMap = ({
{/* Existing sections */}
{sections.map((section) => {
// Handle both string and object polygon data
- let polygonData = section.polygonData;
+ let polygonData = section.polygonData || section.polygon_data;
if (typeof polygonData === 'string') {
try {
polygonData = JSON.parse(polygonData);
@@ -452,9 +453,9 @@ const PropertyMap = ({
);
})}
- {/* GPS Tracking Elements */}
- {(mode === "execution" || mode === "view") && (
- <>
+ {/* GPS Tracking Elements */}
+ {(mode === "execution" || mode === "view") && (
+ <>
{/* GPS Track Polyline */}
{gpsTrack.length > 1 && (
- )}
- >
- )}
+ {currentLocation && mode === "execution" && (
+
+ )}
+
+ {/* Mowing direction guide */}
+ {direction && sections && sections.length > 0 && (() => {
+ // Compute bounding box from all section polygons
+ let minLat = 90, maxLat = -90, minLng = 180, maxLng = -180;
+ sections.forEach(section => {
+ let polygonData = section.polygonData || section.polygon_data;
+ if (typeof polygonData === 'string') {
+ try { polygonData = JSON.parse(polygonData); } catch { return; }
+ }
+ if (!polygonData?.coordinates?.[0]) return;
+ polygonData.coordinates[0].forEach(([lat, lng]) => {
+ if (lat < minLat) minLat = lat;
+ if (lat > maxLat) maxLat = lat;
+ if (lng < minLng) minLng = lng;
+ if (lng > maxLng) maxLng = lng;
+ });
+ });
+ if (!(minLat < maxLat && minLng < maxLng)) return null;
+ const midLat = (minLat + maxLat) / 2;
+ const midLng = (minLng + maxLng) / 2;
+
+ // Build a main guideline polyline based on direction
+ let mainLine = [];
+ switch ((direction || '').toUpperCase()) {
+ case 'N_S':
+ mainLine = [[maxLat, midLng], [minLat, midLng]]; // North to South
+ break;
+ case 'E_W':
+ mainLine = [[midLat, minLng], [midLat, maxLng]]; // East to West
+ break;
+ case 'NE_SW':
+ mainLine = [[maxLat, maxLng], [minLat, minLng]];
+ break;
+ case 'NW_SE':
+ mainLine = [[maxLat, minLng], [minLat, maxLng]];
+ break;
+ case 'CIRCULAR': {
+ // Approximate circle around center with radius based on bbox
+ const latRadius = (maxLat - minLat) / 3;
+ const lngRadius = (maxLng - minLng) / 3;
+ const points = Array.from({ length: 72 }).map((_, i) => {
+ const t = (i / 72) * 2 * Math.PI;
+ return [midLat + latRadius * Math.sin(t), midLng + lngRadius * Math.cos(t)];
+ });
+ return (
+ <>
+
+
Direction: Circular
+ >
+ );
+ }
+ default:
+ break;
+ }
+ if (mainLine.length === 0) return null;
+
+ // Add a couple of parallel guide lines to improve visibility
+ const offsetLat = (maxLat - minLat) * 0.02; // ~2% of bbox
+ const offsetLng = (maxLng - minLng) * 0.02;
+ const parallelLines = [];
+ if (direction === 'N_S') {
+ parallelLines.push(mainLine);
+ parallelLines.push([[maxLat, midLng - offsetLng], [minLat, midLng - offsetLng]]);
+ parallelLines.push([[maxLat, midLng + offsetLng], [minLat, midLng + offsetLng]]);
+ } else if (direction === 'E_W') {
+ parallelLines.push(mainLine);
+ parallelLines.push([[midLat - offsetLat, minLng], [midLat - offsetLat, maxLng]]);
+ parallelLines.push([[midLat + offsetLat, minLng], [midLat + offsetLat, maxLng]]);
+ } else if (direction === 'NE_SW' || direction === 'NW_SE') {
+ parallelLines.push(mainLine);
+ }
+
+ const directionLabelMap = {
+ 'N_S': 'North to South',
+ 'E_W': 'East to West',
+ 'NE_SW': 'NE to SW',
+ 'NW_SE': 'NW to SE',
+ 'CIRCULAR': 'Circular'
+ };
+
+ return (
+ <>
+ {parallelLines.map((line, idx) => (
+
+ ))}
+ Direction: {directionLabelMap[(direction || '').toUpperCase()] || direction}
+ >
+ );
+ })()}
+ >
+ )}
{/* Current polygon being drawn */}
{currentPolygon.length > 0 && (
diff --git a/frontend/src/components/Mowing/MowingExecutionModal.js b/frontend/src/components/Mowing/MowingExecutionModal.js
index 6366e2c..4d12314 100644
--- a/frontend/src/components/Mowing/MowingExecutionModal.js
+++ b/frontend/src/components/Mowing/MowingExecutionModal.js
@@ -126,7 +126,7 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
Mower: {plan.equipment_name}
Cut Height: {plan.cut_height_inches}"
-
+
{
currentLocation={currentLocation}
center={center || [39.8283, -98.5795]}
zoom={center ? 16 : 15}
+ direction={plan.direction}
className="h-80 w-full"
/>