Istanbul District Distance Calculator
Istanbul District Distance Calculator
<div class="mb-5">
<label for="originDistrict" class="block text-gray-700 text-sm font-semibold mb-2">Origin District:</label>
<select id="originDistrict" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-50 text-gray-800">
<!-- Districts will be populated here by JavaScript -->
</select>
</div>
<div class="mb-6">
<label for="destinationDistrict" class="block text-gray-700 text-sm font-semibold mb-2">Destination District:</label>
<select id="destinationDistrict" class="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-50 text-gray-800">
<!-- Districts will be populated here by JavaScript -->
</select>
</div>
<button id="calculateBtn" class="w-full bg-blue-600 text-white font-bold py-3 px-4 rounded-lg hover:bg-blue-700 transition duration-300 ease-in-out shadow-md hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-75">
Calculate Distance
</button>
<div id="result" class="mt-8 p-4 bg-blue-100 border border-blue-200 text-blue-800 rounded-lg text-center font-semibold text-lg hidden">
<!-- Result will be displayed here -->
</div>
<div id="errorMessage" class="mt-8 p-4 bg-red-100 border border-red-200 text-red-800 rounded-lg text-center font-semibold text-lg hidden">
Please select different districts.
</div>
</div>
<script>
// Define Istanbul districts with approximate coordinates
// These coordinates are approximate and may not represent the exact center of each district.
// For more precise results, a dedicated mapping service API would be required.
const districts = [
{ name: "Adalar", lat: 40.875, lon: 29.12 },
{ name: "Arnavutköy", lat: 41.20, lon: 28.75 },
{ name: "Ataşehir", lat: 40.98, lon: 29.10 },
{ name: "Avcılar", lat: 40.98, lon: 28.70 },
{ name: "Bağcılar", lat: 41.03, lon: 28.85 },
{ name: "Bahçelievler", lat: 40.99, lon: 28.87 },
{ name: "Bakırköy", lat: 40.98, lon: 28.80 },
{ name: "Başakşehir", lat: 41.08, lon: 28.78 },
{ name: "Bayrampaşa", lat: 41.03, lon: 28.90 },
{ name: "Beşiktaş", lat: 41.05, lon: 29.00 },
{ name: "Beykoz", lat: 41.10, lon: 29.20 },
{ name: "Beylikdüzü", lat: 41.00, lon: 28.65 },
{ name: "Beyoğlu", lat: 41.03, lon: 28.97 },
{ name: "Büyükçekmece", lat: 41.02, lon: 28.57 },
{ name: "Çatalca", lat: 41.15, lon: 28.35 },
{ name: "Çekmeköy", lat: 41.02, lon: 29.20 },
{ name: "Esenler", lat: 41.03, lon: 28.88 },
{ name: "Esenyurt", lat: 41.03, lon: 28.68 },
{ name: "Eyüpsultan", lat: 41.07, lon: 28.92 },
{ name: "Fatih", lat: 41.01, lon: 28.95 },
{ name: "Gaziosmanpaşa", lat: 41.05, lon: 28.92 },
{ name: "Güngören", lat: 41.02, lon: 28.86 },
{ name: "Kadıköy", lat: 40.98, lon: 29.03 },
{ name: "Kağıthane", lat: 41.07, lon: 28.97 },
{ name: "Kartal", lat: 40.90, lon: 29.20 },
{ name: "Küçükçekmece", lat: 41.00, lon: 28.75 },
{ name: "Maltepe", lat: 40.92, lon: 29.15 },
{ name: "Pendik", lat: 40.88, lon: 29.23 },
{ name: "Sancaktepe", lat: 40.97, lon: 29.23 },
{ name: "Sarıyer", lat: 41.17, lon: 29.05 },
{ name: "Silivri", lat: 41.07, lon: 28.25 },
{ name: "Sultanbeyli", lat: 40.93, lon: 29.27 },
{ name: "Sultangazi", lat: 41.08, lon: 28.90 },
{ name: "Şile", lat: 41.18, lon: 29.60 },
{ name: "Şişli", lat: 41.06, lon: 28.99 },
{ name: "Tuzla", lat: 40.82, lon: 29.30 },
{ name: "Ümraniye", lat: 41.02, lon: 29.15 },
{ name: "Üsküdar", lat: 41.02, lon: 29.02 },
{ name: "Zeytinburnu", lat: 40.99, lon: 28.90 }
];
const originDistrictSelect = document.getElementById('originDistrict');
const destinationDistrictSelect = document.getElementById('destinationDistrict');
const calculateBtn = document.getElementById('calculateBtn');
const resultDiv = document.getElementById('result');
const errorMessageDiv = document.getElementById('errorMessage');
// Populate dropdowns
function populateDistricts() {
districts.forEach(district => {
const option1 = document.createElement('option');
option1.value = district.name;
option1.textContent = district.name;
originDistrictSelect.appendChild(option1);
const option2 = document.createElement('option');
option2.value = district.name;
option2.textContent = district.name;
destinationDistrictSelect.appendChild(option2);
});
}
// Convert degrees to radians
function toRadians(degrees) {
return degrees * Math.PI / 180;
}
// Calculate distance using Haversine formula
function calculateDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // Radius of Earth in kilometers
const dLat = toRadians(lat2 - lat1);
const dLon = toRadians(lon2 - lon1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c; // Distance in kilometers
return distance;
}
// Event listener for the calculate button
calculateBtn.addEventListener('click', () => {
const originName = originDistrictSelect.value;
const destinationName = destinationDistrictSelect.value;
// Hide previous messages
resultDiv.classList.add('hidden');
errorMessageDiv.classList.add('hidden');
if (originName === destinationName) {
errorMessageDiv.classList.remove('hidden');
return;
}
const origin = districts.find(d => d.name === originName);
const destination = districts.find(d => d.name === destinationName);
if (origin && destination) {
const distance = calculateDistance(origin.lat, origin.lon, destination.lat, destination.lon);
resultDiv.textContent = `Distance between ${originName} and ${destinationName}: ${distance.toFixed(2)} km`;
resultDiv.classList.remove('hidden');
} else {
// This case should ideally not happen if dropdowns are populated correctly
errorMessageDiv.textContent = "An error occurred. Please try again.";
errorMessageDiv.classList.remove('hidden');
}
});
// Initialize the app
populateDistricts();
</script>