-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmaps.html
More file actions
335 lines (290 loc) · 15.8 KB
/
maps.html
File metadata and controls
335 lines (290 loc) · 15.8 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" translate="no" class="notranslate" lang="en">
<head>
<title>MANO - Maps | Visualizing Current Location and Origin Location</title>
<meta name="keywords" content="maps, provenance, origin, digital humanities, data visualization, GIS, MANO">
<meta name="description" content="Explore interactive maps visualizing the geographic origins and current locations of manuscripts in the MANO Metadata Collection.">
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0 shrink-to-fit=no"/>
<meta name="google" content="notranslate"/>
<link rel="canonical" href="https://mano-project.github.io/maps.html">
<link rel="icon" type="image/png" href="images/mano-logo_nuovoFont.png">
<link rel="alternate" hreflang="en" href="URL">
<meta property="og:type" content="website">
<meta property="og:title" content="MANO – Maps">
<meta property="og:description" content="Interactive maps visualizing the current location and origin place of manuscripts described in the MANO Metadata Collection.">
<meta property="og:image" content="https://mano-project.github.io/images/mano-logo_nuovoFont.png">
<meta property="og:url" content="https://mano-project.github.io/maps.html">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "MANO – Maps",
"url": "https://mano-project.github.io/maps.html",
"description": "Interactive maps visualizing the current location and origin place of manuscripts described in the MANO Metadata Collection.",
"isPartOf": {
"@type": "Dataset",
"name": "MANO Metadata Collection"
},
"creator": {
"@type": "Person",
"name": "Michela Parma",
"affiliation": "University of Mainz"
}
"inLanguage": "en"
}
</script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
<link rel="stylesheet" type="text/css" href="css/style.css" media="screen"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<style>
#mapCurrent, #mapOrigin {
height: 500px;
margin-top: 1rem;
width: 100%;
border: 1px solid #dee2e6;
border-radius: 0.5rem;
}
</style>
</head>
<body>
<nav class="navbar bg-body-tertiary ">
<div class="container-fluid d-flex justify-content-between align-items-center position-relative py-2">
<!-- Invisible spacer to balance layout -->
<div style="width: 80px;"></div>
<!-- Centered logo -->
<div class="position-absolute start-50 translate-middle-x text-center">
<a class="navbar-brand" href="index.html">
<img src="images/mano-logo_nuovoFont.png" alt="MANO project logo" width="65" class="d-inline-block align-text-top">
</a>
</div>
<!-- Offcanvas toggle aligned right -->
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar"
aria-controls="offcanvasNavbar" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasNavbarLabel"><MANO></h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
<li class="nav-item"><a class="nav-link" href="index.html">Home</a></li>
<li class="nav-item"><a class="nav-link" href="resources.html">Resources</a></li>
<li class="nav-item"><a class="nav-link" href="editor.html">Metadata Editor</a></li>
<li class="nav-item"><a class="nav-link" href="collection.html">Metadata Collection</a></li>
<li class="nav-item"><a class="nav-link" href="viewer.html">Transcription Viewer</a></li>
<li class="nav-item"><a class="nav-link" href="documentation.html">Documentation</a></li>
<li class="nav-item"><a class="nav-link active" href="about.html">About</a></li>
<hr class="my-3">
<div class="text-center">
<h6 class="mb-3">Participate in shaping the future of <MANO></h6>
<a href="https://survey.zdv.uni-mainz.de/index.php/822542?newtest=Y&lang=en" class="btn btn-sm btn-outline-primary" target="_blank" rel="noopener">Take the user survey</a>
</div>
</ul>
</div>
</div>
</div>
</nav>
<div class="container mt-4">
<button onclick="history.back()" class="btn back-btn btn-sm btn-outline-secondary" aria-label="Go back">Back</button>
<h1 class="page-title">Maps</h1>
<div class="row my-4 align-items-end">
<!-- Left column -->
<div class="col-12 col-md-6 d-flex justify-content-start mb-2 mb-md-0">
<button type="button" class="btn btn-primary responsive-btn" data-bs-toggle="modal" data-bs-target="#infoMaps" aria-label="Open About Maps">
<i class="bi bi-info-circle"></i> About
</button>
</div>
</div>
<!-- About Maps Modal -->
<div class="modal fade" id="infoMaps" tabindex="-1" aria-labelledby="infoMapsLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="infoMapsLabel">About Maps</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>
The Maps visualize the geographical distribution of manuscripts recorded in the MANO database.
Two maps are displayed side by side: the first shows the <strong>current location</strong> (the library or institution where the manuscript is preserved today),
while the second shows the <strong>origin location</strong> (the location where the manuscript was produced).
</p>
<p>
Each marker represents one or more manuscripts. By clicking on a marker, you can view the list of manuscripts connected to that location and access their metadata in the <a href="collection.html" target="_blank">Metadata Collection</a>.
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close">Close</button>
</div>
</div>
</div>
</div>
<div class="container mb-5">
<div class="row">
<div class="col-12 col-md-6">
<h4 style="color:#eeba2b;" class="text-center">Current Location</h4>
<div id="mapCurrent"></div>
</div>
<div class="col-12 col-md-6">
<h4 style="color:#eeba2b;" class="text-center">Origin Location</h4>
<div id="mapOrigin"></div>
</div>
</div>
</div>
</div>
<footer class="footer bg-body-tertiary text-center py-4">
<div class="container">
<!-- Logo centered -->
<div class="mb-3">
<a class="navbar-brand" href="index.html">
<img src="images/mano-logo_nuovoFont.png" alt="MANO project logo" width="50">
</a>
</div>
<!-- Links centered in one line -->
<div class="mb-3">
<a class="footer-link mx-2" href="index.html">Home</a>
<a class="footer-link mx-2" href="resources.html">Resources</a>
<a class="footer-link mx-2" href="editor.html">Metadata Editor</a>
<a class="footer-link mx-2" href="collection.html">Metadata Collection</a>
<a class="footer-link mx-2" href="viewer.html">Transcription Viewer</a>
<a class="footer-link mx-2" href="documentation.html">Documentation</a>
<a class="footer-link mx-2" href="about.html">About</a>
</div>
<!-- Copyright centered -->
<div class="text-center mt-2">
<span>© 2025 <span class="mano"><MANO></span></span>
</div>
</div>
</footer>
<div class="py-1 text-center">
<small>
<span class="m-1">
<a href="imprint.html" style="color: black!important">Imprint & Privacy</a>
</span> |
<span class="m-1">
<a href="https://github.com/orgs/mano-project/repositories" target="_blank" style="color: black!important"><i class="fa-brands fa-github"></i> GitHub Repositories</a>
</span> |
<span class="m-1">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" style="color: black!important">CC BY-NC-SA 4.0</a><img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="Creative Commons" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt="Attribution" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt="Non Commercial" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="Share Alike" style="max-width: 1em;max-height:1em;margin-left: .2em;">
</span>
</small>
</div>
<script>
const repoOwner = "mano-project";
const repoName = "mano-metadata";
const folderPath = "data";
let manuscripts = [];
// Fetch file list from GitHub
async function fetchFileList() {
const apiUrl = `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${folderPath}`;
const res = await fetch(apiUrl);
const files = await res.json();
return files.filter(f => f.name.endsWith(".json"));
}
async function fetchJSONFile(url) {
const res = await fetch(url);
return res.json();
}
// Initialize maps
const europeCenter = [44.855656, 9.4841947,5]; //central Europe
const zoomLevel = 4; // zoomed to Europe
const mapCurrent = L.map('mapCurrent').setView(europeCenter, zoomLevel);
const mapOrigin = L.map('mapOrigin').setView(europeCenter, zoomLevel);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(mapCurrent);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(mapOrigin);
const currentMarkers = L.layerGroup().addTo(mapCurrent);
const originMarkers = L.layerGroup().addTo(mapOrigin);
// Group manuscripts by coordinates
function groupByCoords(entries, fieldGeo, fieldLabel, fieldCountry) {
const groups = {};
entries.forEach(entry => {
const geo = entry[fieldGeo];
if (!geo) return;
if (!groups[geo]) {
groups[geo] = {
label: entry[fieldLabel]?.value || entry[fieldLabel] || "Unknown",
country: entry[fieldCountry]?.value || entry[fieldCountry] || "",
manuscripts: []
};
}
//groups[geo].manuscripts.push(entry.msName || "Untitled manuscript");
groups[geo].manuscripts.push({
title: entry.msName || "Untitled manuscript",
id: entry.idno || entry.msName
});
});
return groups;
}
// Plot grouped markers
function plotMarkers() {
currentMarkers.clearLayers();
originMarkers.clearLayers();
// Current Repositories
const repoGroups = groupByCoords(manuscripts, "geoRepository", "repository", "countryIdent");
for (const geo in repoGroups) {
const [lat, lon] = geo.split(",").map(Number);
const g = repoGroups[geo];
const popupHtml = `
<b>${g.label}</b><br>${g.country}<br>
<ul>
${g.manuscripts.map(m =>
`<li><a href="collection.html#ms-${m.id.replace(/\s+/g,"_")}" target="_blank">${m.title}</a></li>`
).join("")}
</ul>
`;
L.marker([lat, lon]).addTo(currentMarkers).bindPopup(popupHtml);
}
// Places of Origin
const originGroups = groupByCoords(manuscripts, "geoOrigin", "origPlace", "countryOrigin");
for (const geo in originGroups) {
const [lat, lon] = geo.split(",").map(Number);
const g = originGroups[geo];
const popupHtml = `
<b>${g.label}</b><br>${g.country}<br>
<ul>
${g.manuscripts.map(m =>
`<li><a href="collection.html#ms-${m.id.replace(/\s+/g,"_")}" target="_blank">${m.title}</a></li>`
).join("")}
</ul>
`;
L.marker([lat, lon]).addTo(originMarkers).bindPopup(popupHtml);
}
// Fit maps
if (currentMarkers.getLayers().length > 0) {
mapCurrent.fitBounds(currentMarkers.getBounds());
}
if (originMarkers.getLayers().length > 0) {
mapOrigin.fitBounds(originMarkers.getBounds());
}
}
// Load all data
async function loadData() {
const fileList = await fetchFileList();
for (const f of fileList) {
try {
const rec = await fetchJSONFile(f.download_url);
const entries = Array.isArray(rec) ? rec : [rec];
manuscripts.push(...entries);
} catch (err) {
console.error("Error loading", f.name, err);
}
}
plotMarkers();
}
loadData();
</script>
<script src="JS/adjustButtonSize.js"></script>
</body>
</html>