traffic-test / index.html
Samikciku's picture
Add 2 files
96ac982 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Route Planner | Traffic Optimized</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" async defer></script>
<style>
#map {
height: 400px;
width: 100%;
}
.autocomplete-dropdown {
position: absolute;
z-index: 1000;
width: calc(100% - 2px);
background: white;
border: 1px solid #e2e8f0;
border-top: none;
border-radius: 0 0 0.375rem 0.375rem;
max-height: 200px;
overflow-y: auto;
}
.autocomplete-item {
padding: 8px 12px;
cursor: pointer;
}
.autocomplete-item:hover {
background-color: #f1f5f9;
}
.sidebar {
transition: all 0.3s ease;
}
.sidebar-hidden {
transform: translateX(100%);
}
</style>
</head>
<body class="bg-gray-50">
<div class="flex flex-col min-h-screen">
<!-- Header -->
<header class="bg-blue-600 text-white p-4 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<h1 class="text-2xl font-bold flex items-center">
<i class="fas fa-route mr-2"></i> Route Planner
</h1>
<button id="settings-btn" class="p-2 rounded-full hover:bg-blue-700 transition">
<i class="fas fa-cog text-xl"></i>
</button>
</div>
</header>
<!-- Main Content -->
<main class="flex-grow container mx-auto p-4 flex flex-col md:flex-row gap-6">
<!-- Left Panel - Form -->
<div class="w-full md:w-1/3 lg:w-1/4 bg-white p-6 rounded-lg shadow-md">
<div class="mb-6">
<h2 class="text-xl font-semibold mb-4 text-gray-800">Plan Your Route</h2>
<!-- Start Location -->
<div class="mb-4 relative">
<label for="start" class="block text-sm font-medium text-gray-700 mb-1">Start Location</label>
<div class="relative">
<input type="text" id="start" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Enter address or select from map">
<button id="start-map-btn" class="absolute right-3 top-3 text-gray-500 hover:text-blue-600">
<i class="fas fa-map-marker-alt"></i>
</button>
</div>
<div id="start-dropdown" class="autocomplete-dropdown hidden"></div>
<div class="mt-1 flex flex-wrap gap-2">
<button class="address-chip bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-xs flex items-center" data-address="Home">
<i class="fas fa-home mr-1"></i> Home
</button>
<button class="address-chip bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-xs flex items-center" data-address="Work">
<i class="fas fa-briefcase mr-1"></i> Work
</button>
</div>
</div>
<!-- Destination -->
<div class="mb-4 relative">
<label for="destination" class="block text-sm font-medium text-gray-700 mb-1">Destination</label>
<div class="relative">
<input type="text" id="destination" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Enter address or select from map">
<button id="dest-map-btn" class="absolute right-3 top-3 text-gray-500 hover:text-blue-600">
<i class="fas fa-map-marker-alt"></i>
</button>
</div>
<div id="dest-dropdown" class="autocomplete-dropdown hidden"></div>
<div class="mt-1 flex flex-wrap gap-2">
<button class="address-chip bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-xs flex items-center" data-address="Work">
<i class="fas fa-briefcase mr-1"></i> Work
</button>
<button class="address-chip bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-xs flex items-center" data-address="Gym">
<i class="fas fa-dumbbell mr-1"></i> Gym
</button>
</div>
</div>
<div class="flex justify-between mb-4">
<button id="swap-btn" class="text-blue-600 hover:text-blue-800 flex items-center">
<i class="fas fa-exchange-alt mr-2"></i> Swap
</button>
<button id="save-route-btn" class="text-blue-600 hover:text-blue-800 flex items-center">
<i class="fas fa-bookmark mr-2"></i> Save Route
</button>
</div>
<!-- Route Options -->
<div class="mb-6">
<h3 class="font-medium text-gray-700 mb-2">Route Options</h3>
<div class="flex flex-wrap gap-2">
<button id="fastest-route" class="route-option bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-bolt mr-2"></i> Fastest
</button>
<button id="shortest-route" class="route-option bg-gray-200 text-gray-800 px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-route mr-2"></i> Shortest
</button>
<button id="less-traffic-route" class="route-option bg-gray-200 text-gray-800 px-4 py-2 rounded-lg flex items-center">
<i class="fas fa-car-side mr-2"></i> Less Traffic
</button>
</div>
</div>
<!-- Departure Time -->
<div class="mb-6">
<h3 class="font-medium text-gray-700 mb-2">Departure Time</h3>
<div class="flex items-center gap-2">
<input type="datetime-local" id="departure-time" class="p-2 border border-gray-300 rounded-lg">
<button id="now-btn" class="bg-gray-100 hover:bg-gray-200 px-3 py-2 rounded-lg text-sm">
Now
</button>
</div>
</div>
<!-- Find Route Button -->
<button id="find-route-btn" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg shadow-md transition flex items-center justify-center">
<i class="fas fa-search mr-2"></i> Find Best Route
</button>
</div>
<!-- Saved Routes -->
<div>
<div class="flex justify-between items-center mb-2">
<h3 class="font-medium text-gray-700">Saved Routes</h3>
<button id="show-all-routes" class="text-blue-600 text-sm">View All</button>
</div>
<div class="space-y-2">
<div class="saved-route bg-gray-50 p-3 rounded-lg border border-gray-200 hover:border-blue-400 cursor-pointer">
<div class="flex justify-between">
<span class="font-medium">Home → Work</span>
<button class="text-gray-400 hover:text-red-500">
<i class="fas fa-trash-alt"></i>
</button>
</div>
<div class="text-sm text-gray-600">Fastest route - 25 min</div>
</div>
<div class="saved-route bg-gray-50 p-3 rounded-lg border border-gray-200 hover:border-blue-400 cursor-pointer">
<div class="flex justify-between">
<span class="font-medium">Work → Gym</span>
<button class="text-gray-400 hover:text-red-500">
<i class="fas fa-trash-alt"></i>
</button>
</div>
<div class="text-sm text-gray-600">Less traffic - 18 min</div>
</div>
</div>
</div>
</div>
<!-- Right Panel - Map and Results -->
<div class="flex-grow bg-white rounded-lg shadow-md overflow-hidden">
<!-- Map -->
<div id="map"></div>
<!-- Route Details -->
<div id="route-details" class="p-4 border-t border-gray-200 hidden">
<div class="flex justify-between items-center mb-3">
<h3 class="text-lg font-semibold">Route Details</h3>
<button id="clear-route" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i> Clear
</button>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div class="bg-blue-50 p-3 rounded-lg">
<div class="text-sm text-blue-600">Distance</div>
<div id="distance" class="text-xl font-bold">15.2 miles</div>
</div>
<div class="bg-green-50 p-3 rounded-lg">
<div class="text-sm text-green-600">Duration</div>
<div id="duration" class="text-xl font-bold">25 min</div>
</div>
<div class="bg-purple-50 p-3 rounded-lg">
<div class="text-sm text-purple-600">Traffic</div>
<div id="traffic" class="text-xl font-bold">Moderate</div>
</div>
</div>
<div>
<h4 class="font-medium mb-2">Directions</h4>
<div id="directions-panel" class="space-y-2 max-h-64 overflow-y-auto">
<!-- Directions will be populated here -->
</div>
</div>
</div>
</div>
</main>
<!-- Settings Sidebar -->
<div id="settings-sidebar" class="fixed top-0 right-0 h-full w-80 bg-white shadow-lg transform sidebar-sidebar-hidden z-50 transition-all duration-300 ease-in-out">
<div class="p-6 h-full overflow-y-auto">
<div class="flex justify-between items-center mb-6 border-b border-gray-200 pb-4">
<h2 class="text-xl font-bold">Settings</h2>
<button id="close-settings" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<!-- Settings Sections -->
<div class="space-y-8">
<!-- Home Address -->
<div>
<h3 class="font-medium text-gray-700 mb-3">Home Address</h3>
<div class="relative">
<input type="text" id="home-address" class="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Enter your home address">
<div id="home-dropdown" class="autocomplete-dropdown hidden"></div>
</div>
</div>
<!-- Favorite Locations -->
<div>
<h3 class="font-medium text-gray-700 mb-3">Saved Locations</h3>
<div id="favorite-locations" class="space-y-2">
<div class="flex items-center justify-between bg-gray-50 p-3 rounded-lg">
<div>
<span class="font-medium">Work</span>
<div class="text-sm text-gray-600">123 Business St, City</div>
</div>
<button class="text-gray-400 hover:text-red-500">
<i class="fas fa-trash-alt"></i>
</button>
</div>
<div class="flex items-center justify-between bg-gray-50 p-3 rounded-lg">
<div>
<span class="font-medium">Gym</span>
<div class="text-sm text-gray-600">456 Fitness Ave, City</div>
</div>
<button class="text-gray-400 hover:text-red-500">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
<button id="add-favorite-btn" class="mt-2 text-blue-600 flex items-center">
<i class="fas fa-plus mr-2"></i> Add New Location
</button>
<!-- Add Favorite Form (hidden by default) -->
<div id="add-favorite-form" class="mt-3 hidden space-y-3">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label>
<input type="text" id="favorite-name" class="w-full p-2 border border-gray-300 rounded-lg">
</div>
<div class="relative">
<label class="block text-sm font-medium text-gray-700 mb-1">Address</label>
<input type="text" id="favorite-address" class="w-full p-2 border border-gray-300 rounded-lg">
<div id="favorite-dropdown" class="autocomplete-dropdown hidden"></div>
</div>
<div class="flex gap-2">
<button id="cancel-favorite" class="flex-grow bg-gray-200 hover:bg-gray-300 p-2 rounded-lg">
Cancel
</button>
<button id="save-favorite" class="flex-grow bg-blue-600 hover:bg-blue-700 text-white p-2 rounded-lg">
Save
</button>
</div>
</div>
</div>
<!-- App Preferences -->
<div>
<h3 class="font-medium text-gray-700 mb-3">App Preferences</h3>
<div class="space-y-4">
<div class="flex items-center justify-between">
<span>Dark Mode</span>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" class="sr-only peer">
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
</label>
</div>
<div class="flex items-center justify-between">
<span>Traffic Alerts</span>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" checked class="sr-only peer">
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
</label>
</div>
<div class="flex items-center justify-between">
<span>Auto-save routes</span>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" checked class="sr-only peer">
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
</label>
</div>
</div>
</div>
<div class="border-t border-gray-200 pt-4">
<button class="w-full bg-red-50 hover:bg-red-100 text-red-600 p-2 rounded-lg font-medium">
Clear All Saved Data
</button>
</div>
</div>
</div>
</div>
</div>
<script>
// Initialize variables
let map;
let directionsService;
let directionsRenderer;
let autocompleteStart;
let autocompleteDest;
let autocompleteHome;
let autocompleteFavorite;
let markers = [];
let selectedRouteType = 'fastest';
// Initialize map when the API is loaded
function initMap() {
// Default to New York if geolocation fails
const defaultCenter = { lat: 40.7128, lng: -74.0060 };
map = new google.maps.Map(document.getElementById("map"), {
zoom: 12,
center: defaultCenter,
mapTypeControl: false,
streetViewControl: false
});
directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer({
map: map,
suppressMarkers: false,
panel: document.getElementById("directions-panel")
});
// Initialize autocomplete services
autocompleteStart = new google.maps.places.Autocomplete(
document.getElementById("start"),
{ types: ["geocode"] }
);
autocompleteDest = new google.maps.places.Autocomplete(
document.getElementById("destination"),
{ types: ["geocode"] }
);
autocompleteHome = new google.maps.places.Autocomplete(
document.getElementById("home-address"),
{ types: ["geocode"] }
);
autocompleteFavorite = new google.maps.places.Autocomplete(
document.getElementById("favorite-address"),
{ types: ["geocode"] }
);
// Set up autocomplete listeners
setupAutocomplete("start", "start-dropdown");
setupAutocomplete("destination", "dest-dropdown");
setupAutocomplete("home-address", "home-dropdown");
setupAutocomplete("favorite-address", "favorite-dropdown");
// Try to get current location
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map.setCenter(pos);
// Set the current location as the default start point
const geocoder = new google.maps.Geocoder();
geocoder.geocode({ location: pos }, (results, status) => {
if (status === "OK" && results[0]) {
document.getElementById("start").value = results[0].formatted_address;
}
});
},
() => {
// Handle geolocation error by using default center
console.log("Geolocation permission denied or failed");
map.setCenter(defaultCenter);
}
);
} else {
// Browser doesn't support Geolocation
console.log("Geolocation not supported");
map.setCenter(defaultCenter);
}
}
// Helper function to set up autocomplete
function setupAutocomplete(inputId, dropdownId) {
const input = document.getElementById(inputId);
const dropdown = document.getElementById(dropdownId);
input.addEventListener("input", function() {
if (this.value.length > 2) {
// Here you would normally call the Places API to get predictions
// For demo purposes, we'll simulate it
simulateAutocomplete(this.value, dropdown);
} else {
dropdown.classList.add("hidden");
}
});
// Hide dropdown when clicking outside
document.addEventListener("click", function(e) {
if (e.target !== input) {
dropdown.classList.add("hidden");
}
});
}
// Simulate autocomplete results (in a real app, you'd call the Places API)
function simulateAutocomplete(query, dropdown) {
dropdown.innerHTML = '';
// Simulate API delay
setTimeout(() => {
const mockResults = [
`${query} Street, City, Country`,
`${query} Avenue, City, Country`,
`${query} Business Center, City, Country`,
`${query} Mall, City, Country`
];
mockResults.forEach(result => {
const item = document.createElement("div");
item.className = "autocomplete-item";
item.textContent = result;
item.addEventListener("click", function() {
// This would be the input associated with the dropdown
const input = dropdown.previousElementSibling.querySelector("input") ||
dropdown.parentElement.previousElementSibling.querySelector("input");
input.value = result;
dropdown.classList.add("hidden");
});
dropdown.appendChild(item);
});
dropdown.classList.remove("hidden");
}, 300);
}
// Function to calculate and display the route
function calculateRoute() {
const start = document.getElementById("start").value;
const end = document.getElementById("destination").value;
const departureTime = document.getElementById("departure-time").value;
if (!start || !end) {
alert("Please enter both start and destination locations");
return;
}
let request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING,
provideRouteAlternatives: true
};
// Add departure time if provided
if (departureTime) {
request.drivingOptions = {
departureTime: new Date(departureTime),
trafficModel: selectedRouteType === 'less-traffic' ? 'pessimistic' : 'bestguess'
};
}
directionsService.route(request, function(response, status) {
if (status === "OK") {
// Show route details panel
document.getElementById("route-details").classList.remove("hidden");
// Process response to choose best route based on selection
let chosenRoute;
if (selectedRouteType === 'fastest') {
// Find route with shortest duration
chosenRoute = response.routes.reduce((prev, curr) =>
prev.legs[0].duration.value < curr.legs[0].duration.value ? prev : curr
);
} else if (selectedRouteType === 'shortest') {
// Find route with shortest distance
chosenRoute = response.routes.reduce((prev, curr) =>
prev.legs[0].distance.value < curr.legs[0].distance.value ? prev : curr
);
} else {
// Less traffic route (custom logic needed)
chosenRoute = response.routes[0]; // Simplification for demo
}
// Display chosen route
directionsRenderer.setDirections({
routes: [chosenRoute],
request: request
});
// Update route details
const leg = chosenRoute.legs[0];
document.getElementById("distance").textContent = leg.distance.text;
document.getElementById("duration").textContent = leg.duration.text;
// Simple traffic estimation (would use real traffic data in a real app)
let trafficLevel = "Light";
if (leg.duration_in_traffic) {
const diff = leg.duration_in_traffic.value - leg.duration.value;
const percentDiff = (diff / leg.duration.value) * 100;
if (percentDiff > 30) trafficLevel = "Heavy";
else if (percentDiff > 15) trafficLevel = "Moderate";
else trafficLevel = "Light";
}
document.getElementById("traffic").textContent = trafficLevel;
} else {
alert("Directions request failed due to " + status);
}
});
}
// Set up event listeners when DOM is loaded
document.addEventListener("DOMContentLoaded", function() {
// Set current time as default departure time
const now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
document.getElementById("departure-time").value = now.toISOString().slice(0, 16);
// Event listeners for route options
document.getElementById("fastest-route").addEventListener("click", function() {
document.querySelectorAll(".route-option").forEach(btn => {
btn.classList.remove("bg-blue-600", "text-white");
btn.classList.add("bg-gray-200", "text-gray-800");
});
this.classList.remove("bg-gray-200", "text-gray-800");
this.classList.add("bg-blue-600", "text-white");
selectedRouteType = 'fastest';
});
document.getElementById("shortest-route").addEventListener("click", function() {
document.querySelectorAll(".route-option").forEach(btn => {
btn.classList.remove("bg-blue-600", "text-white");
btn.classList.add("bg-gray-200", "text-gray-800");
});
this.classList.remove("bg-gray-200", "text-gray-800");
this.classList.add("bg-blue-600", "text-white");
selectedRouteType = 'shortest';
});
document.getElementById("less-traffic-route").addEventListener("click", function() {
document.querySelectorAll(".route-option").forEach(btn => {
btn.classList.remove("bg-blue-600", "text-white");
btn.classList.add("bg-gray-200", "text-gray-800");
});
this.classList.remove("bg-gray-200", "text-gray-800");
this.classList.add("bg-blue-600", "text-white");
selectedRouteType = 'less-traffic';
});
// "Now" button for departure time
document.getElementById("now-btn").addEventListener("click", function() {
const now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
document.getElementById("departure-time").value = now.toISOString().slice(0, 16);
});
// Find Route button
document.getElementById("find-route-btn").addEventListener("click", calculateRoute);
// Clear Route button
document.getElementById("clear-route").addEventListener("click", function() {
document.getElementById("route-details").classList.add("hidden");
directionsRenderer.setDirections({ routes: [] });
document.getElementById("directions-panel").innerHTML = "";
});
// Swap start and destination
document.getElementById("swap-btn").addEventListener("click", function() {
const start = document.getElementById("start");
const dest = document.getElementById("destination");
const temp = start.value;
start.value = dest.value;
dest.value = temp;
});
// Settings button
document.getElementById("settings-btn").addEventListener("click", function() {
document.getElementById("settings-sidebar").classList.remove("sidebar-hidden");
});
// Close settings
document.getElementById("close-settings").addEventListener("click", function() {
document.getElementById("settings-sidebar").classList.add("sidebar-hidden");
});
// Add favorite location
document.getElementById("add-favorite-btn").addEventListener("click", function() {
document.getElementById("add-favorite-form").classList.remove("hidden");
document.getElementById("add-favorite-btn").classList.add("hidden");
});
// Cancel adding favorite
document.getElementById("cancel-favorite").addEventListener("click", function() {
document.getElementById("add-favorite-form").classList.add("hidden");
document.getElementById("add-favorite-btn").classList.remove("hidden");
});
// Save favorite location
document.getElementById("save-favorite").addEventListener("click", function() {
const name = document.getElementById("favorite-name").value;
const address = document.getElementById("favorite-address").value;
if (name && address) {
const favoriteElement = document.createElement("div");
favoriteElement.className = "flex items-center justify-between bg-gray-50 p-3 rounded-lg";
favoriteElement.innerHTML = `
<div>
<span class="font-medium">${name}</span>
<div class="text-sm text-gray-600">${address}</div>
</div>
<button class="text-gray-400 hover:text-red-500">
<i class="fas fa-trash-alt"></i>
</button>
`;
document.getElementById("favorite-locations").appendChild(favoriteElement);
// Reset form
document.getElementById("favorite-name").value = "";
document.getElementById("favorite-address").value = "";
document.getElementById("add-favorite-form").classList.add("hidden");
document.getElementById("add-favorite-btn").classList.remove("hidden");
} else {
alert("Please enter both name and address");
}
});
// Save route
document.getElementById("save-route-btn").addEventListener("click", function() {
const start = document.getElementById("start").value;
const dest = document.getElementById("destination").value;
if (start && dest) {
const savedRoutes = document.querySelector(".saved-route").parentNode;
const newRoute = document.createElement("div");
newRoute.className = "saved-route bg-gray-50 p-3 rounded-lg border border-gray-200 hover:border-blue-400 cursor-pointer mt-2";
newRoute.innerHTML = `
<div class="flex justify-between">
<span class="font-medium">${start.split(",")[0]}${dest.split(",")[0]}</span>
<button class="text-gray-400 hover:text-red-500">
<i class="fas fa-trash-alt"></i>
</button>
</div>
<div class="text-sm text-gray-600">${selectedRouteType} route</div>
`;
savedRoutes.appendChild(newRoute);
// Click handler for the new route
newRoute.addEventListener("click", function() {
document.getElementById("start").value = start;
document.getElementById("destination").value = dest;
calculateRoute();
});
alert("Route saved to your favorites!");
} else {
alert("Please enter both start and destination locations");
}
});
// Home and Work address chips
document.querySelectorAll(".address-chip").forEach(chip => {
chip.addEventListener("click", function() {
const input = this.closest(".mb-4").querySelector("input");
if (input.id === "start" || input.id === "destination") {
input.value = this.getAttribute("data-address");
}
});
});
// Start from map button
document.getElementById("start-map-btn").addEventListener("click", function() {
alert("Click on the map to set start location");
setupMapClickListener("start");
});
// Destination from map button
document.getElementById("dest-map-btn").addEventListener("click", function() {
alert("Click on the map to set destination");
setupMapClickListener("destination");
});
});
// Set up map click listener for setting location
function setupMapClickListener(inputId) {
// Clear existing markers
markers.forEach(marker => marker.setMap(null));
markers = [];
const listener = map.addListener("click", (e) => {
// Remove the listener after first click
google.maps.event.removeListener(listener);
// Add marker
const marker = new google.maps.Marker({
position: e.latLng,
map: map,
draggable: true
});
markers.push(marker);
// Geocode the clicked location
const geocoder = new google.maps.Geocoder();
geocoder.geocode({ location: e.latLng }, (results, status) => {
if (status === "OK" && results[0]) {
document.getElementById(inputId).value = results[0].formatted_address;
} else {
document.getElementById(inputId).value = `${e.latLng.lat()}, ${e.latLng.lng()}`;
}
});
// Update position if marker is dragged
marker.addListener("dragend", (e) => {
geocoder.geocode({ location: e.latLng }, (results, status) => {
if (status === "OK" && results[0]) {
document.getElementById(inputId).value = results[0].formatted_address;
}
});
});
});
}
// Handle window resizing
window.addEventListener("resize", function() {
if (map) {
google.maps.event.trigger(map, "resize");
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Samikciku/traffic-test" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
</html>