-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
157 lines (139 loc) · 6.54 KB
/
Copy pathindex.html
File metadata and controls
157 lines (139 loc) · 6.54 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!DOCTYPE html>
<html>
<head>
<title>CSV2Map</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel=icon href="data:,">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<style>
* {
font-family: sans-serif;
margin: 0;
padding: 0;
font-size: 19px;
box-sizing: border-box;
}
html, body {
overscroll-behavior: contain;
}
header>* {
padding: 1rem;
}
main {
width: 100vw;
height: 100vh;
}
form>* {
margin-bottom: 1rem;
}
input, select {
width: 100%;
padding: 0.5rem;
}
button {
padding: 0.5rem 1rem;
}
h1 {
font-size: 22px;
}
h1, h2, h3, h4, h5, .leaflet-popup-content p {
margin: 0 0 0.5em 0;
}
.leaflet-tooltip {
padding: 0 4px;
line-height: 22px;
}
.leaflet-tooltip>* {
font-size: 14px;
}
</style>
</head>
<body>
<header>
<h1>CSV2Map</h1>
<p id="loading" style="display:none">Loading...</p>
<form id="form" action="" style="display:none">
<p>This webapp turns rows of CSV files into markers on an interactive map. It's just some glue between <a href="https://www.papaparse.com/">PapaParse</a> and <a href="https://leafletjs.com/">Leaflet</a>, base map is provided by <a href="https://www.openstreetmap.org/">OpenStreetMap</a>.</p>
<p>To get started, just enter the URL of your CSV file (eg. <a href="https://docs.google.com/spreadsheets/d/1dski_07gHa9LGK2491SN4-FepTHpsiaSQU9aY1CRoPc">a Google Sheet</a> <a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vTrTyLnsl1Z8d48GBXT2fy-PbNEeo1AGa4U_-q9E3opt_gcvq73JVrWXoAAR4wrCqlOUZHO61rHVZVL/pub?single=true&output=csv">published as CSV</a> will <a href=".?csv_url=https%3A%2F%2Fdocs.google.com%2Fspreadsheets%2Fd%2Fe%2F2PACX-1vTrTyLnsl1Z8d48GBXT2fy-PbNEeo1AGa4U_-q9E3opt_gcvq73JVrWXoAAR4wrCqlOUZHO61rHVZVL%2Fpub%3Fsingle%3Dtrue%26output%3Dcsv">turn into this</a>).</p>
<p>The file must include a <strong>Latitude</strong> and <strong>Longitude</strong> column. Optional columns are <abbr title="Shows a permanent HTML tooltip below the marker"><strong>TooltipHTML</strong></abbr>, <abbr title="Shows a HTML popup when the marker is clicked."><strong>PopupHTML</strong></abbr> and <abbr title="Replaces default blue marker with a circle of that color; accepts HTML color names or hex values like #ff00ff."><strong>MarkerColor</strong></abbr>.</p>
<input type="text" name="csv_url" placeholder="CSV URL (eg. https://example.com/places.csv)">
<input type="text" name="title" placeholder="Map title (eg. My Awesome Map) - optional">
<select name="geolocation">
<option value="0" selected>Don't use geolocation</option>
<option value="1">Show current geolocation on map (may ask for permission)</option>
</select>
<button type="submit">Generate link</button>
<p><small>© 2023-2025 <a href="https://fodi.be">Fodi</a> | You can find the source code <a href="https://github.com/fodi/csv2map">over here</a>.</small></p>
</form>
</header>
<main id="map"></main>
<script src="https://unpkg.com/papaparse@5.4.1/papaparse.min.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
/* global L, Papa */
const urlParams = new URL(document.location).searchParams;
const csvURL = urlParams.get('csv_url');
const title = urlParams.get('title') ? urlParams.get('title') + ' | CSV2Map' : 'CSV2Map';
let map, rows = [], markers = [];
function onCSVParsed(results) {
rows = results.data ?? [];
if (results.errors.length > 0) {
console.warn('Errors while parsing CSV:');
console.warn(results.errors);
}
document.querySelector('header').remove();
for (const row of rows) {
let marker;
if (row?.MarkerColor) {
marker = L.circleMarker([row.Latitude, row.Longitude], { radius: 10, color: "#000", fillColor: row.MarkerColor, fillOpacity: 0.9, weight: 2 });
} else {
marker = L.marker([row.Latitude, row.Longitude]);
}
if (row?.PopupHTML) {
marker.bindPopup(row.PopupHTML);
}
if (row?.TooltipHTML) {
marker.bindTooltip(row.TooltipHTML, { direction: 'bottom', permanent: true, offset: [0, 12] });
}
markers.push(marker);
}
map = L.map('map');
const featureGroup = L.featureGroup(markers).addTo(map);
map.fitBounds(featureGroup.getBounds().pad(0.1));
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
if (urlParams.get('geolocation') === '1' && navigator?.geolocation) {
// request geolocation, start watching and add a marker to the map which is updated on every change
const geoMarker = L.marker([0, 0]).addTo(map);
navigator.geolocation.watchPosition((position) => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
geoMarker.setLatLng([lat, lon]);
}, (error) => {
console.warn('Error while retrieving geolocation:');
console.warn(error);
}, {
enableHighAccuracy: true,
maximumAge: 5000,
timeout: 10000
});
}
}
if (csvURL) {
document.querySelector('title').textContent = title;
document.getElementById('loading').style.display = 'block';
Papa.parse(csvURL, {
worker: urlParams.get('worker'),
header: true,
download: true,
complete: onCSVParsed
});
} else {
document.getElementById('form').style.display = 'block';
}
</script>
</body>
</html>