-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMap (1).tsx
More file actions
108 lines (95 loc) · 3.36 KB
/
Copy pathMap (1).tsx
File metadata and controls
108 lines (95 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { useEffect, useState } from 'react';
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import 'leaflet-routing-machine/dist/leaflet-routing-machine.css';
import { Customer, Location, RouteInfo } from '../types';
import L from 'leaflet';
import 'leaflet-routing-machine';
// Fix for default marker icons in React-Leaflet
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png',
iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png',
});
interface MapProps {
source: Location | null;
destination: Location | null;
onRouteUpdate: (route: RouteInfo) => void;
}
function RouteManager({ source, destination, onRouteUpdate }: MapProps) {
const map = useMap();
useEffect(() => {
let routingControl: L.Routing.Control | null = null;
if (source && destination) {
const waypoints = [
L.latLng(source.lat, source.lng),
L.latLng(destination.lat, destination.lng)
];
routingControl = L.Routing.control({
waypoints,
routeWhileDragging: true,
showAlternatives: true,
fitSelectedRoutes: true,
lineOptions: {
styles: [{ color: '#6366f1', weight: 6 }],
extendToWaypoints: true,
missingRouteTolerance: 0
}
}).addTo(map);
routingControl.on('routesfound', (e) => {
const route = e.routes[0];
const steps = route.instructions.map(step => ({
instruction: step.text,
distance: step.distance,
duration: step.time / 60 // Convert to minutes
}));
onRouteUpdate({
distance: route.summary.totalDistance / 1000, // Convert to km
duration: route.summary.totalTime / 60, // Convert to minutes
steps
});
});
const bounds = L.latLngBounds(waypoints);
map.fitBounds(bounds, { padding: [50, 50] });
}
return () => {
if (routingControl) {
map.removeControl(routingControl);
}
};
}, [source, destination, map, onRouteUpdate]);
return null;
}
export default function Map({ source, destination, onRouteUpdate }: MapProps) {
const defaultCenter = { lat: 12.9716, lng: 77.5946 }; // Bangalore center
return (
<div className="h-[500px] w-full rounded-lg overflow-hidden shadow-lg">
<MapContainer
center={[defaultCenter.lat, defaultCenter.lng]}
zoom={11}
style={{ height: '100%', width: '100%' }}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{source && (
<Marker position={[source.lat, source.lng]}>
<Popup>Source Location</Popup>
</Marker>
)}
{destination && (
<Marker position={[destination.lat, destination.lng]}>
<Popup>Destination Location</Popup>
</Marker>
)}
<RouteManager
source={source}
destination={destination}
onRouteUpdate={onRouteUpdate}
/>
</MapContainer>
</div>
);
}