forked from simonw/tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsv-marker-map.html
119 lines (116 loc) · 3.72 KB
/
csv-marker-map.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSV marker map - use ?csv=URL to CSV to populate</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
<style>
html, body {
height: 100%;
margin: 0;
}
.custom-marker {
background-color: darkred;
border-radius: 50%;
border: 1px solid white;
}
</style>
</head>
<body>
<div id="map" style="width: 100%; height: 100%;"></div>
<script>
function toPoint(s) {
return s.split(",").map(parseFloat);
}
async function load() {
let params = new URLSearchParams(location.search);
let center = params.get('center') || '0,0';
let initialZoom = params.get('zoom');
let zoom = parseInt(initialZoom || '2', 10);
let q = params.get('q');
let markers = params.getAll('marker');
let csvUrl = params.get('csv');
let markerColor = params.get('color') || 'blue';
let styleElement = document.getElementsByTagName('style')[0];
// Get the CSS rule for .custom-marker
let cssRules = styleElement.sheet.cssRules;
let customMarkerRule;
for (var i = 0; i < cssRules.length; i++) {
if (cssRules[i].selectorText === '.custom-marker') {
customMarkerRule = cssRules[i];
break;
}
}
if (customMarkerRule) {
customMarkerRule.style.backgroundColor = markerColor;
}
let map = L.map('map', { zoomControl: false }).setView(toPoint(center), zoom);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
detectRetina: true
}).addTo(map);
if (q && !params.get('center')) {
let response = await fetch(
`https://nominatim.openstreetmap.org/search.php?q=${encodeURIComponent(q)}&format=jsonv2`
)
let data = await response.json();
let bounds = [
[data[0].boundingbox[0],data[0].boundingbox[2]],
[data[0].boundingbox[1],data[0].boundingbox[3]]
];
map.fitBounds(bounds);
// User-provided zoom over-rides this
if (initialZoom) {
map.setZoom(parseInt(initialZoom));
}
}
map.on('moveend zoomend', () => {
// Update URL bar with current location
let newZoom = map.getZoom();
let center = map.getCenter();
let u = new URLSearchParams();
markers.forEach(s => u.append('marker', s));
u.append('center', `${center.lat},${center.lng}`);
u.append('zoom', newZoom);
if (csvUrl) {
u.append('csv', csvUrl);
}
history.replaceState(null, null, '?' + u.toString());
});
markers.forEach(s => {
L.marker(toPoint(s)).addTo(map);
});
if (csvUrl) {
await new Promise((resolve, reject) => {
let script = document.createElement('script');
script.src = 'https://unpkg.com/papaparse@5.3.0/papaparse.min.js';
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
Papa.parse(csvUrl, {
download: true,
header: true,
complete: results => {
results.data.forEach(row => {
if (row.latitude && row.longitude) {
L.marker([parseFloat(row.latitude), parseFloat(row.longitude)], {
icon: L.divIcon({
className: 'custom-marker',
iconSize: [10, 10],
iconAnchor: [5, 5]
})
}).addTo(map);
}
});
}
});
}
}
load();
</script>
</body>
</html>