| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Dark Store Placement & Heatmap</title> |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> |
| <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" /> |
| <style> |
| body { |
| font-family: 'Poppins', sans-serif; |
| background: url('https://wallpapercave.com/wp/wp4411792.jpg') no-repeat center center fixed; |
| background-size: cover; |
| color: #ffffff; |
| margin: 0; |
| padding: 0; |
| } |
| .container { |
| background: rgba(255, 255, 255, 0.1); |
| backdrop-filter: blur(15px); |
| padding: 30px; |
| border-radius: 15px; |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); |
| text-align: center; |
| max-width: 900px; |
| margin: 40px auto; |
| border: 1px solid rgba(255, 255, 255, 0.2); |
| } |
| h2 { |
| font-weight: 600; |
| text-transform: uppercase; |
| background: linear-gradient(90deg, #ff416c, #ff4b2b); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| } |
| .file-upload { |
| position: relative; |
| display: inline-block; |
| } |
| .file-upload input[type="file"] { |
| position: absolute; |
| opacity: 0; |
| width: 100%; |
| height: 100%; |
| cursor: pointer; |
| } |
| .file-upload label { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| padding: 12px 20px; |
| background: linear-gradient(135deg, #007bff, #00d4ff); |
| color: #fff; |
| font-weight: 600; |
| border-radius: 8px; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); |
| } |
| .btn { |
| padding: 12px 24px; |
| font-size: 16px; |
| font-weight: 600; |
| border-radius: 8px; |
| text-transform: uppercase; |
| transition: all 0.3s ease-in-out; |
| cursor: pointer; |
| } |
| .btn-primary { |
| background: linear-gradient(135deg, #007bff, #00d4ff); |
| color: #fff; |
| } |
| .btn-danger { |
| background: linear-gradient(135deg, #ff416c, #ff4b2b); |
| color: #fff; |
| } |
| .btn:hover { |
| transform: translateY(-3px); |
| box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); |
| } |
| #map, #heatmap { |
| height: 500px; |
| border-radius: 10px; |
| overflow: hidden; |
| box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); |
| margin-top: 20px; |
| } |
| </style> |
| </head> |
| <body> |
| <div class="container mt-4"> |
| <h2 class="text-center"> Dark Store Placement & Heatmap</h2> |
| |
| <div class="mb-3"> |
| <label class="form-label">Upload CSV File (Latitude, Longitude, Location)</label> |
| <div class="file-upload"> |
| <input type="file" id="csvFileInput"> |
| <label for="csvFileInput">Choose File</label> |
| </div> |
| </div> |
|
|
| <div class="d-flex justify-content-center gap-3"> |
| <button class="btn btn-primary" onclick="processCSV()">Generate Store Map</button> |
| <button class="btn btn-danger" onclick="generateHeatmap()">Generate Heatmap</button> |
| </div> |
|
|
| <div id="map" class="mt-4"></div> |
| <h3 class="text-center mt-4">🔥 Heatmap Representation</h3> |
| <div id="heatmap" class="mt-2"></div> |
| </div> |
|
|
| <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.heat/0.2.0/leaflet-heat.js"></script> |
| |
| <script> |
| let map = L.map('map').setView([18.5204, 73.8567], 10); |
| L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); |
| |
| let heatmapMap = L.map('heatmap').setView([18.5204, 73.8567], 10); |
| L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(heatmapMap); |
| |
| let selectedLocations = []; |
| let heatLayer; |
| |
| function processCSV() { |
| const fileInput = document.getElementById("csvFileInput"); |
| if (!fileInput.files.length) return alert("Please upload a CSV file"); |
| |
| Papa.parse(fileInput.files[0], { |
| header: true, |
| skipEmptyLines: true, |
| complete: function (result) { |
| let data = result.data; |
| selectedLocations = []; |
| |
| data.forEach(row => { |
| let lat = parseFloat(row.Latitude); |
| let lon = parseFloat(row.Longitude); |
| let location = row.Location; |
| |
| selectedLocations.push([lat, lon, 1.0]); |
| L.marker([lat, lon]).addTo(map) |
| .bindPopup(`<b>${location}</b><br>Lat: ${lat}, Lon: ${lon}`); |
| }); |
| } |
| }); |
| } |
| |
| function generateHeatmap() { |
| if (heatLayer) heatmapMap.removeLayer(heatLayer); |
| |
| heatLayer = L.heatLayer(selectedLocations, { |
| radius: 25, |
| blur: 15, |
| maxZoom: 10 |
| }).addTo(heatmapMap); |
| } |
| </script> |
| </body> |
| </html> |
|
|