Manthan2004/heatmap
0
1let storeData = [];2let map = L.map('map').setView([18.5204, 73.8567], 10);3L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);4 5let heatmapMap = L.map('heatmap').setView([18.5204, 73.8567], 10);6L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(heatmapMap);7let heatLayer;8 9document.getElementById('drop-zone').addEventListener('click', () => {10 document.getElementById('csvFileInput').click();11});12 13document.getElementById('csvFileInput').addEventListener('change', (event) => {14 readCSV(event.target.files[0]);15});16 17function getMarkerColor(storeType) {18 return storeType === "Retail" ? "blue" :19 storeType === "Restaurant" ? "green" :20 storeType === "Pharmacy" ? "red" : "orange";21}22 23function readCSV(file) {24 Papa.parse(file, {25 header: true,26 skipEmptyLines: true,27 complete: (result) => {28 storeData = result.data.map(row => ([ 29 parseFloat(row.Latitude), 30 parseFloat(row.Longitude), 31 row["Store Type"], 32 parseFloat(row["Foot Traffic"]) || 1, 33 parseFloat(row["Population Density"]) || 0 // Adding Population Density34 ]));35 }36 });37}38 39function processCSV() {40 if (!storeData.length) return alert("Please upload a CSV file first!");41 storeData.forEach(([lat, lon, storeType, footTraffic]) => {42 L.marker([lat, lon], {43 icon: L.icon({44 iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-${getMarkerColor(storeType)}.png`,45 iconSize: [25, 41]46 })47 }).addTo(map).bindPopup(`<b>Store Type:</b> ${storeType}<br><b>Foot Traffic:</b> ${footTraffic}`);48 });49}50 51function generateHeatmap() {52 if (heatLayer) heatmapMap.removeLayer(heatLayer);53 if (!storeData.length) return alert("No data found! Upload a CSV first.");54 heatLayer = L.heatLayer(storeData.map(([lat, lon, , footTraffic]) => [lat, lon, footTraffic]), { 55 radius: 25, 56 blur: 15, 57 maxZoom: 10 58 }).addTo(heatmapMap);59}60 61function kMeansClustering(k) {62 if (!storeData.length) return alert("No data to cluster! Upload a CSV first.");63 64 // Function to calculate Euclidean distance65 function euclideanDistance(point1, point2) {66 return Math.sqrt(Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));67 }68 69 // Initialize centroids randomly70 let centroids = [];71 while (centroids.length < k) {72 let randIndex = Math.floor(Math.random() * storeData.length);73 if (!centroids.some(centroid => centroid[0] === storeData[randIndex][0] && centroid[1] === storeData[randIndex][1])) {74 centroids.push(storeData[randIndex].slice(0, 2)); // Only use lat and lon for centroid75 }76 }77 78 let clusters = Array(k).fill().map(() => []);79 let prevCentroids = new Array(k).fill([0, 0]);80 81 // K-Means Loop82 while (JSON.stringify(centroids) !== JSON.stringify(prevCentroids)) {83 clusters = Array(k).fill().map(() => []);84 85 // Assign each point to the nearest centroid86 storeData.forEach(([lat, lon, storeType, footTraffic]) => {87 let closestCentroidIndex = centroids.reduce((closest, centroid, index) => {88 let dist = euclideanDistance([lat, lon], centroid);89 return dist < closest.dist ? { dist, index } : closest;90 }, { dist: Infinity }).index;91 92 clusters[closestCentroidIndex].push([lat, lon, storeType, footTraffic]);93 });94 95 prevCentroids = [...centroids];96 97 // Recalculate centroids98 centroids = clusters.map(cluster => {99 let sumLat = 0, sumLon = 0;100 cluster.forEach(([lat, lon]) => {101 sumLat += lat;102 sumLon += lon;103 });104 return [sumLat / cluster.length, sumLon / cluster.length];105 });106 }107 108 // Display clusters on the map109 clusters.forEach((cluster, clusterIndex) => {110 cluster.forEach(([lat, lon, storeType, footTraffic]) => {111 L.marker([lat, lon], {112 icon: L.icon({113 iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-${clusterIndex + 1}.png`,114 iconSize: [25, 41]115 })116 }).addTo(map).bindPopup(`<b>Store Type:</b> ${storeType}<br><b>Foot Traffic:</b> ${footTraffic}<br><b>Cluster:</b> ${clusterIndex + 1}`);117 });118 });119}120 121function recommendDarkStores() {122 if (!storeData.length) return alert("Please upload a CSV file first!");123 124 // Sort stores by population density and foot traffic to find optimal locations125 const potentialDarkStores = storeData126 .filter(([lat, lon, storeType, footTraffic, popDensity]) => {127 return storeType !== "Retail" && footTraffic < 50 && popDensity > 5000; // Criteria for Dark Store128 })129 .sort((a, b) => b[4] - a[4]); // Sort by Population Density130 131 // Display recommended dark stores on the map132 potentialDarkStores.forEach(([lat, lon, storeType, footTraffic, popDensity], index) => {133 L.marker([lat, lon], {134 icon: L.icon({135 iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-3.png', // Dark Store Marker136 iconSize: [25, 41]137 })138 }).addTo(map).bindPopup(`<b>Recommended Dark Store Location</b><br><b>Population Density:</b> ${popDensity}<br><b>Foot Traffic:</b> ${footTraffic}`);139 });140 141 alert("Dark Store recommendations displayed on the map.");142}143 