fix: restrict map route domain to Chennai region and implement numbered stop markers
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -16,23 +16,34 @@ L.Icon.Default.mergeOptions({
|
||||
shadowUrl: markerShadow,
|
||||
});
|
||||
|
||||
// Domain Boundary validation (Chennai and surrounding route regions)
|
||||
const MIN_LAT = 12.7;
|
||||
const MAX_LAT = 13.4;
|
||||
const MIN_LNG = 79.6;
|
||||
const MAX_LNG = 80.4;
|
||||
|
||||
const isValidCoordinate = (lat?: number, lng?: number): boolean => {
|
||||
if (lat === undefined || lng === undefined) return false;
|
||||
return lat >= MIN_LAT && lat <= MAX_LAT && lng >= MIN_LNG && lng <= MAX_LNG;
|
||||
};
|
||||
|
||||
// Custom Premium DivIcons using Tailwind CSS
|
||||
const startIcon = L.divIcon({
|
||||
html: `<div class="flex items-center justify-center w-6 h-6 rounded-full bg-emerald-500 border-2 border-white shadow-md text-white text-[10px] font-bold">A</div>`,
|
||||
const getStartIcon = (label: string = "1") => L.divIcon({
|
||||
html: `<div class="flex items-center justify-center w-6 h-6 rounded-full bg-emerald-500 border-2 border-white shadow-md text-white text-[10px] font-extrabold hover:scale-110 transition-transform">${label}</div>`,
|
||||
className: '',
|
||||
iconSize: [24, 24],
|
||||
iconAnchor: [12, 12],
|
||||
});
|
||||
|
||||
const stopIcon = L.divIcon({
|
||||
html: `<div class="w-3.5 h-3.5 rounded-full bg-blue-500 border-2 border-white shadow-sm hover:scale-125 transition-transform"></div>`,
|
||||
const getStopIcon = (num: number) => L.divIcon({
|
||||
html: `<div class="flex items-center justify-center w-5.5 h-5.5 rounded-full bg-blue-600 border-2 border-white shadow-md text-white text-[10px] font-bold hover:scale-125 hover:bg-blue-700 transition-all">${num}</div>`,
|
||||
className: '',
|
||||
iconSize: [14, 14],
|
||||
iconAnchor: [7, 7],
|
||||
iconSize: [22, 22],
|
||||
iconAnchor: [11, 11],
|
||||
});
|
||||
|
||||
const campusIcon = L.divIcon({
|
||||
html: `<div class="flex items-center justify-center w-9 h-9 rounded-full bg-gradient-to-tr from-orange-500 to-amber-500 border-2 border-white shadow-lg text-white text-sm font-bold animate-pulse">🏫</div>`,
|
||||
html: `<div class="flex items-center justify-center w-9 h-9 rounded-full bg-gradient-to-tr from-orange-500 to-amber-500 border-2 border-white shadow-lg text-white text-sm font-bold animate-pulse hover:scale-110 transition-transform">🏫</div>`,
|
||||
className: '',
|
||||
iconSize: [36, 36],
|
||||
iconAnchor: [18, 18],
|
||||
@@ -57,27 +68,27 @@ interface BusRouteMapProps {
|
||||
const DEFAULT_CENTER = [13.0118, 80.0214]; // RIT Campus default
|
||||
|
||||
export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapProps) {
|
||||
// Collect coordinates for the polyline path
|
||||
// Collect coordinates for the polyline path, filtering out any invalid outliers
|
||||
const pathCoordinates = useMemo(() => {
|
||||
if (!selectedRoute) return [];
|
||||
|
||||
const coords: [number, number][] = [];
|
||||
|
||||
// Add start stop coords if present
|
||||
if (selectedRoute.from_lat && selectedRoute.from_lng) {
|
||||
coords.push([selectedRoute.from_lat, selectedRoute.from_lng]);
|
||||
// Add start stop coords if valid
|
||||
if (isValidCoordinate(selectedRoute.from_lat, selectedRoute.from_lng)) {
|
||||
coords.push([selectedRoute.from_lat!, selectedRoute.from_lng!]);
|
||||
}
|
||||
|
||||
// Add all intermediary stop coords
|
||||
// Add all intermediary stop coords that are valid
|
||||
selectedRoute.stops.forEach(stop => {
|
||||
if (stop.lat && stop.lng) {
|
||||
coords.push([stop.lat, stop.lng]);
|
||||
if (isValidCoordinate(stop.lat, stop.lng)) {
|
||||
coords.push([stop.lat!, stop.lng!]);
|
||||
}
|
||||
});
|
||||
|
||||
// Add end stop coords if present
|
||||
if (selectedRoute.to_lat && selectedRoute.to_lng) {
|
||||
coords.push([selectedRoute.to_lat, selectedRoute.to_lng]);
|
||||
// Add end stop coords if valid
|
||||
if (isValidCoordinate(selectedRoute.to_lat, selectedRoute.to_lng)) {
|
||||
coords.push([selectedRoute.to_lat!, selectedRoute.to_lng!]);
|
||||
}
|
||||
|
||||
return coords;
|
||||
@@ -89,32 +100,38 @@ export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapPro
|
||||
return pathCoordinates as L.LatLngBoundsExpression;
|
||||
}, [pathCoordinates]);
|
||||
|
||||
// Determine which routes to display (either the selected one, or all route start pins as overview)
|
||||
// Determine which markers to display
|
||||
const renderMarkers = () => {
|
||||
if (selectedRoute) {
|
||||
// Filter out stops that do not have valid coordinates
|
||||
const validStops = selectedRoute.stops.filter(stop => isValidCoordinate(stop.lat, stop.lng));
|
||||
|
||||
return (
|
||||
<>
|
||||
{selectedRoute.stops.map((stop, index) => {
|
||||
{validStops.map((stop, index) => {
|
||||
const isStart = index === 0;
|
||||
const isEnd = index === selectedRoute.stops.length - 1;
|
||||
const isEnd = index === validStops.length - 1;
|
||||
const isRit = stop.name.toLowerCase().includes("rit");
|
||||
|
||||
let currentIcon = stopIcon;
|
||||
if (isStart) currentIcon = startIcon;
|
||||
let currentIcon = getStopIcon(index + 1);
|
||||
if (isStart) currentIcon = getStartIcon("Start");
|
||||
if (isRit || isEnd) currentIcon = campusIcon;
|
||||
|
||||
if (!stop.lat || !stop.lng) return null;
|
||||
|
||||
return (
|
||||
<Marker
|
||||
key={`${stop.name}-${index}`}
|
||||
position={[stop.lat, stop.lng]}
|
||||
position={[stop.lat!, stop.lng!]}
|
||||
icon={currentIcon}
|
||||
>
|
||||
<Popup>
|
||||
<div className="p-1 font-sans">
|
||||
<div className="flex items-center gap-1.5 mb-0.5">
|
||||
<span className="text-[10px] bg-slate-100 text-slate-700 px-1.5 py-0.5 rounded font-bold">
|
||||
Stop #{index + 1}
|
||||
</span>
|
||||
<h4 className="font-bold text-slate-800 text-xs">{stop.name}</h4>
|
||||
<p className="text-[10px] text-orange-500 font-semibold mt-0.5">Estimated: {stop.time}</p>
|
||||
</div>
|
||||
<p className="text-[10px] text-orange-500 font-semibold mt-0.5">Estimated Arrival: {stop.time}</p>
|
||||
{isStart && <span className="inline-block text-[9px] bg-emerald-100 text-emerald-700 px-1.5 py-0.5 rounded-full mt-1 font-bold">Departure Stop</span>}
|
||||
{isRit && <span className="inline-block text-[9px] bg-orange-100 text-orange-700 px-1.5 py-0.5 rounded-full mt-1 font-bold">RIT Campus</span>}
|
||||
</div>
|
||||
@@ -126,7 +143,7 @@ export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapPro
|
||||
);
|
||||
}
|
||||
|
||||
// Default view: Draw RIT Campus pin + Start pins for all routes
|
||||
// Default view: Draw RIT Campus pin + Start pins for all routes (only if coordinates are valid)
|
||||
return (
|
||||
<>
|
||||
<Marker position={[13.0118, 80.0214]} icon={campusIcon}>
|
||||
@@ -138,12 +155,12 @@ export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapPro
|
||||
</Popup>
|
||||
</Marker>
|
||||
{allRoutes.map((r, i) => {
|
||||
if (!r.from_lat || !r.from_lng) return null;
|
||||
if (!isValidCoordinate(r.from_lat, r.from_lng)) return null;
|
||||
return (
|
||||
<Marker
|
||||
key={`start-${r.number}-${i}`}
|
||||
position={[r.from_lat, r.from_lng]}
|
||||
icon={startIcon}
|
||||
position={[r.from_lat!, r.from_lng!]}
|
||||
icon={getStartIcon(r.number)}
|
||||
>
|
||||
<Popup>
|
||||
<div className="p-1 font-sans">
|
||||
|
||||
@@ -167,10 +167,6 @@
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Ayyampettai": {
|
||||
"lat": 10.8962881,
|
||||
"lng": 79.1886395
|
||||
},
|
||||
"Ayyangarkulam": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
@@ -178,5 +174,473 @@
|
||||
"Ayyapanthangal": {
|
||||
"lat": 13.041,
|
||||
"lng": 80.1412
|
||||
},
|
||||
"B.B.Road": {
|
||||
"lat": 13.0095255,
|
||||
"lng": 80.2537619
|
||||
},
|
||||
"BDO Office": {
|
||||
"lat": 12.9022177,
|
||||
"lng": 80.0257182
|
||||
},
|
||||
"Bai Kadai": {
|
||||
"lat": 13.0198261,
|
||||
"lng": 80.1430544
|
||||
},
|
||||
"Balaji Dental College": {
|
||||
"lat": 12.9441308,
|
||||
"lng": 80.208506
|
||||
},
|
||||
"Banavaram koot": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Beach Station": {
|
||||
"lat": 13.0942257,
|
||||
"lng": 80.2921033
|
||||
},
|
||||
"Bharath College": {
|
||||
"lat": 12.9079915,
|
||||
"lng": 80.1394791
|
||||
},
|
||||
"Bharathi nagar": {
|
||||
"lat": 13.1226511,
|
||||
"lng": 80.2237949
|
||||
},
|
||||
"Butt Road": {
|
||||
"lat": 13.0084,
|
||||
"lng": 80.1987
|
||||
},
|
||||
"Butt road": {
|
||||
"lat": 13.0084,
|
||||
"lng": 80.1987
|
||||
},
|
||||
"CIT Nagar": {
|
||||
"lat": 13.0293843,
|
||||
"lng": 80.2342825
|
||||
},
|
||||
"CMBT (Koyambedu)": {
|
||||
"lat": 13.0678,
|
||||
"lng": 80.2054
|
||||
},
|
||||
"CRP": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"CRPF": {
|
||||
"lat": 12.9912054,
|
||||
"lng": 80.1881366
|
||||
},
|
||||
"Camp Road ICICI Bank": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Camp Road Singal": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Canara Bank": {
|
||||
"lat": 12.9764294,
|
||||
"lng": 80.2224084
|
||||
},
|
||||
"Central": {
|
||||
"lat": 13.0827,
|
||||
"lng": 80.2707
|
||||
},
|
||||
"Chembarambakkam": {
|
||||
"lat": 13.016769,
|
||||
"lng": 80.1367942
|
||||
},
|
||||
"Chengalpattu Bypass": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Chengalpattu Rattinakinaru": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Chennai Trade Centre": {
|
||||
"lat": 13.0142534,
|
||||
"lng": 80.1905788
|
||||
},
|
||||
"Chennirkuppam": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Cheriyan Hospital": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Cheyyar-SBI": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Chinmaiya Nagar": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Chintadripet (Post Offiec)": {
|
||||
"lat": 13.0761258,
|
||||
"lng": 80.270781
|
||||
},
|
||||
"Chintamani": {
|
||||
"lat": 13.0472403,
|
||||
"lng": 80.1853252
|
||||
},
|
||||
"Chinthamani": {
|
||||
"lat": 13.0410061,
|
||||
"lng": 80.2373742
|
||||
},
|
||||
"Chithukadu Blue": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Choolai Post Office": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Choolaimedu": {
|
||||
"lat": 13.0666515,
|
||||
"lng": 80.230974
|
||||
},
|
||||
"Choolaimedu Subway": {
|
||||
"lat": 13.0645,
|
||||
"lng": 80.2224
|
||||
},
|
||||
"Choolaimedu bus stop": {
|
||||
"lat": 13.0666287,
|
||||
"lng": 80.2305198
|
||||
},
|
||||
"Chrompet": {
|
||||
"lat": 12.961,
|
||||
"lng": 80.1462
|
||||
},
|
||||
"Collector Nagar": {
|
||||
"lat": 13.0884944,
|
||||
"lng": 80.1909707
|
||||
},
|
||||
"Collector Office": {
|
||||
"lat": 13.0959177,
|
||||
"lng": 80.2922668
|
||||
},
|
||||
"Collector nagar": {
|
||||
"lat": 13.0884944,
|
||||
"lng": 80.1909707
|
||||
},
|
||||
"D.R.Super Market": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"D1 Police Station": {
|
||||
"lat": 13.0683459,
|
||||
"lng": 80.2135958
|
||||
},
|
||||
"Dasprakash": {
|
||||
"lat": 13.0811,
|
||||
"lng": 80.2524
|
||||
},
|
||||
"Deepam Foods": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Donbosco": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"E.B": {
|
||||
"lat": 13.0869258,
|
||||
"lng": 80.2194441
|
||||
},
|
||||
"E.B. Stop": {
|
||||
"lat": 13.0869258,
|
||||
"lng": 80.2194441
|
||||
},
|
||||
"Eaga Theatre": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Egambaranathar Koil": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Egmore": {
|
||||
"lat": 13.0792,
|
||||
"lng": 80.2598
|
||||
},
|
||||
"Ekkatuthangal": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Elango Nagar": {
|
||||
"lat": 12.9715538,
|
||||
"lng": 80.2523792
|
||||
},
|
||||
"Ellaimman Koil": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Erumaiyur": {
|
||||
"lat": 12.9547388,
|
||||
"lng": 80.0815988
|
||||
},
|
||||
"Eswar Nagar": {
|
||||
"lat": 13.0577106,
|
||||
"lng": 80.2190678
|
||||
},
|
||||
"G3 Police Station": {
|
||||
"lat": 13.0683459,
|
||||
"lng": 80.2135958
|
||||
},
|
||||
"GRT": {
|
||||
"lat": 12.9826003,
|
||||
"lng": 80.2181059
|
||||
},
|
||||
"Ganga Cinima": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Gangaiamman koil": {
|
||||
"lat": 13.0551756,
|
||||
"lng": 80.1913579
|
||||
},
|
||||
"Gerugambakkam": {
|
||||
"lat": 13.0152345,
|
||||
"lng": 80.1368538
|
||||
},
|
||||
"Golden Flats": {
|
||||
"lat": 13.0883017,
|
||||
"lng": 80.1784121
|
||||
},
|
||||
"Golden flat": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Govardhanagari": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Govarthanagiri Bus Stand": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Government Hospital": {
|
||||
"lat": 13.1093369,
|
||||
"lng": 80.2312849
|
||||
},
|
||||
"Gudalore": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Guduvanchery": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Guindy": {
|
||||
"lat": 13.0067,
|
||||
"lng": 80.2206
|
||||
},
|
||||
"HDFC Bank": {
|
||||
"lat": 13.0308653,
|
||||
"lng": 80.2455467
|
||||
},
|
||||
"HVF": {
|
||||
"lat": 13.0293266,
|
||||
"lng": 80.1667524
|
||||
},
|
||||
"Housing Board": {
|
||||
"lat": 13.0084674,
|
||||
"lng": 80.2475552
|
||||
},
|
||||
"ICF Church": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"ICF Signal": {
|
||||
"lat": 13.1001091,
|
||||
"lng": 80.2145485
|
||||
},
|
||||
"IOB Bank": {
|
||||
"lat": 13.0224668,
|
||||
"lng": 80.2230059
|
||||
},
|
||||
"Ice House Police Station": {
|
||||
"lat": 13.052,
|
||||
"lng": 80.2762
|
||||
},
|
||||
"Indian Bank Thiruvninravur": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Indira Gandhi Nagar": {
|
||||
"lat": 13.0914233,
|
||||
"lng": 80.2541906
|
||||
},
|
||||
"Indra Nagar (KPM Railwaygate)": {
|
||||
"lat": 13.0370804,
|
||||
"lng": 80.1887213
|
||||
},
|
||||
"Irungattukottai bus stand": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Iyyappanthangal": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"JJ Nagar": {
|
||||
"lat": 13.0790498,
|
||||
"lng": 80.1719442
|
||||
},
|
||||
"JJ Nagar Police Station": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Janappanchatram Bypass": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Jaya College": {
|
||||
"lat": 13.1225267,
|
||||
"lng": 80.0454078
|
||||
},
|
||||
"Jayalakshmi Theatre": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Jeyachandran": {
|
||||
"lat": 12.9211296,
|
||||
"lng": 80.1968403
|
||||
},
|
||||
"Joint Office": {
|
||||
"lat": 13.101916,
|
||||
"lng": 80.230392
|
||||
},
|
||||
"Joshua School": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Jothi Nagar": {
|
||||
"lat": 12.9459767,
|
||||
"lng": 80.239775
|
||||
},
|
||||
"K4 Police Station": {
|
||||
"lat": 13.0925413,
|
||||
"lng": 80.2179712
|
||||
},
|
||||
"KK Nagar": {
|
||||
"lat": 13.0373,
|
||||
"lng": 80.2045
|
||||
},
|
||||
"KK Nagar ESI": {
|
||||
"lat": 13.0373,
|
||||
"lng": 80.2045
|
||||
},
|
||||
"Kachapeswarar Koil": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kaduveti": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kaiveli": {
|
||||
"lat": 12.9633783,
|
||||
"lng": 80.2160859
|
||||
},
|
||||
"Kakkalur": {
|
||||
"lat": 13.1305159,
|
||||
"lng": 79.9243758
|
||||
},
|
||||
"Kakkalur Signal": {
|
||||
"lat": 13.1305159,
|
||||
"lng": 79.9243758
|
||||
},
|
||||
"Kakkan Bridge": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kallikuppam": {
|
||||
"lat": 13.1331405,
|
||||
"lng": 80.1701786
|
||||
},
|
||||
"Kalmandapam": {
|
||||
"lat": 13.1153712,
|
||||
"lng": 80.2905548
|
||||
},
|
||||
"Kalpana Lamp": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kalyan Jewalrs": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kamarajapuram": {
|
||||
"lat": 13.1933419,
|
||||
"lng": 80.2612852
|
||||
},
|
||||
"Kambar Colony": {
|
||||
"lat": 12.9755337,
|
||||
"lng": 80.2296597
|
||||
},
|
||||
"Ayyampettai": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Chitteri": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Ganeshapuram": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kamban Nagar": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kammal Street": {
|
||||
"lat": 13.0903441,
|
||||
"lng": 80.2791264
|
||||
},
|
||||
"Kammala street": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kankaiyamman Kovil": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kannadhasan Nagar": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Karanodai Bypass": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Karapakkam": {
|
||||
"lat": 12.9117073,
|
||||
"lng": 80.2277203
|
||||
},
|
||||
"Karapakkam - TCS": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Karayanchavadi": {
|
||||
"lat": 13.0467114,
|
||||
"lng": 80.1109051
|
||||
},
|
||||
"Karima Nagar": {
|
||||
"lat": 13.0118,
|
||||
"lng": 80.0214
|
||||
},
|
||||
"Kasi Theatre": {
|
||||
"lat": 13.0305,
|
||||
"lng": 80.2132
|
||||
},
|
||||
"Kasimedu": {
|
||||
"lat": 13.1364038,
|
||||
"lng": 80.2958012
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,13 @@ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
BUS_ROUTES_PATH = os.path.abspath(os.path.join(CURRENT_DIR, "..", "backend", "src", "main", "resources", "bus_routes.json"))
|
||||
CACHE_PATH = os.path.join(CURRENT_DIR, "coordinates_cache.json")
|
||||
|
||||
# Domain restriction (Chennai, Tiruvallur, Kanchipuram districts)
|
||||
MIN_LAT, MAX_LAT = 12.7, 13.4
|
||||
MIN_LNG, MAX_LNG = 79.6, 80.4
|
||||
|
||||
def is_valid_coordinate(lat, lng):
|
||||
return MIN_LAT <= lat <= MAX_LAT and MIN_LNG <= lng <= MAX_LNG
|
||||
|
||||
# Predefined coordinates for hard-to-geocode stops or fallback landmarks in Chennai
|
||||
STATIC_COORDINATES = {
|
||||
"RIT Campus": {"lat": 13.0118, "lng": 80.0214},
|
||||
@@ -68,7 +75,15 @@ def load_cache():
|
||||
if os.path.exists(CACHE_PATH):
|
||||
try:
|
||||
with open(CACHE_PATH, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
data = json.load(f)
|
||||
# Clean coordinates that are outside the map route domain
|
||||
cleaned = {}
|
||||
for name, coords in data.items():
|
||||
if is_valid_coordinate(coords["lat"], coords["lng"]):
|
||||
cleaned[name] = coords
|
||||
else:
|
||||
print(f"Removing invalid cache entry for '{name}': {coords}")
|
||||
return cleaned
|
||||
except Exception:
|
||||
pass
|
||||
return {}
|
||||
@@ -114,8 +129,11 @@ def geocode_nominatim(name):
|
||||
if data:
|
||||
lat = float(data[0]["lat"])
|
||||
lng = float(data[0]["lon"])
|
||||
print(f"-> Found: {lat}, {lng}")
|
||||
if is_valid_coordinate(lat, lng):
|
||||
print(f"-> Found within domain: {lat}, {lng}")
|
||||
return {"lat": lat, "lng": lng}
|
||||
else:
|
||||
print(f"-> Found but DISCARDED (outside domain): {lat}, {lng}")
|
||||
# Rest to respect API limit
|
||||
time.sleep(1.2)
|
||||
except Exception as e:
|
||||
@@ -132,39 +150,7 @@ def geocode_nominatim(name):
|
||||
print(f"-> No match found for '{name}'. Defaulting to RIT Campus.")
|
||||
return STATIC_COORDINATES["RIT Campus"]
|
||||
|
||||
def geocode_routes():
|
||||
if not os.path.exists(BUS_ROUTES_PATH):
|
||||
print(f"Error: {BUS_ROUTES_PATH} does not exist.")
|
||||
return
|
||||
|
||||
with open(BUS_ROUTES_PATH, "r", encoding="utf-8") as f:
|
||||
routes = json.load(f)
|
||||
|
||||
cache = load_cache()
|
||||
modified = False
|
||||
|
||||
# Collect all unique stop names
|
||||
unique_names = set()
|
||||
for r in routes:
|
||||
unique_names.add(r["from"])
|
||||
unique_names.add(r["to"])
|
||||
for stop in r.get("stops", []):
|
||||
unique_names.add(stop["name"])
|
||||
|
||||
print(f"Total unique stops to geocode: {len(unique_names)}")
|
||||
|
||||
# Geocode each stop
|
||||
count = 0
|
||||
for name in sorted(unique_names):
|
||||
if name not in cache:
|
||||
coords = geocode_nominatim(name)
|
||||
cache[name] = coords
|
||||
count += 1
|
||||
# Save cache incrementally
|
||||
if count % 5 == 0:
|
||||
save_cache(cache)
|
||||
save_cache(cache)
|
||||
|
||||
def update_bus_routes_json(routes, cache):
|
||||
# Enrich bus_routes.json
|
||||
for r in routes:
|
||||
from_coords = cache.get(r["from"], STATIC_COORDINATES["RIT Campus"])
|
||||
@@ -183,7 +169,49 @@ def geocode_routes():
|
||||
with open(BUS_ROUTES_PATH, "w", encoding="utf-8") as f:
|
||||
json.dump(routes, f, indent=2)
|
||||
|
||||
print("Geocoding process complete! bus_routes.json updated with coordinates.")
|
||||
def geocode_routes():
|
||||
if not os.path.exists(BUS_ROUTES_PATH):
|
||||
print(f"Error: {BUS_ROUTES_PATH} does not exist.")
|
||||
return
|
||||
|
||||
with open(BUS_ROUTES_PATH, "r", encoding="utf-8") as f:
|
||||
routes = json.load(f)
|
||||
|
||||
cache = load_cache()
|
||||
|
||||
# Save the cleaned cache to start
|
||||
save_cache(cache)
|
||||
|
||||
# Write coordinates to the JSON immediately for any stops that are already in the cache!
|
||||
update_bus_routes_json(routes, cache)
|
||||
print("Initial cache applied to bus_routes.json.")
|
||||
|
||||
# Collect all unique stop names
|
||||
unique_names = set()
|
||||
for r in routes:
|
||||
unique_names.add(r["from"])
|
||||
unique_names.add(r["to"])
|
||||
for stop in r.get("stops", []):
|
||||
unique_names.add(stop["name"])
|
||||
|
||||
print(f"Total unique stops to geocode: {len(unique_names)}")
|
||||
|
||||
# Geocode each stop
|
||||
count = 0
|
||||
for name in sorted(unique_names):
|
||||
if name not in cache:
|
||||
coords = geocode_nominatim(name)
|
||||
cache[name] = coords
|
||||
count += 1
|
||||
# Save cache and update JSON incrementally
|
||||
save_cache(cache)
|
||||
update_bus_routes_json(routes, cache)
|
||||
print(f"Updated routes JSON with '{name}' ({coords['lat']}, {coords['lng']})")
|
||||
|
||||
# Final save
|
||||
save_cache(cache)
|
||||
update_bus_routes_json(routes, cache)
|
||||
print("Geocoding process complete! bus_routes.json fully synchronized.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
geocode_routes()
|
||||
|
||||
Reference in New Issue
Block a user