Last active
January 11, 2024 17:38
-
-
Save evanwill/c70a1ee888082b85f0808bb8c82d6228 to your computer and use it in GitHub Desktop.
collectionbuilder map-js.html customization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{%- if site.data.theme.icons -%}{% assign icons = site.data.theme.icons %}{% else %} | |
{% assign cb_icons = site.pages | where: "name","cb-icons.svg" | first %} | |
{% assign icons = cb_icons.icons %}{%- endif -%} | |
{% if site.data.theme.map-child-objects == true %} | |
{%- assign items = site.data[site.metadata] | where_exp: 'item','item.objectid' -%} | |
{% else %} | |
{%- assign items = site.data[site.metadata] | where_exp: 'item','item.objectid' | where_exp: 'item','item.parentid == nil' -%} | |
{% endif %} | |
{% if page.location %} | |
{%- assign items = items | where_exp: 'item', 'item.location == page.location' -%} | |
{% endif %} | |
{%- assign items = items | where_exp: 'item', 'item.objectid != nil' | where_exp: 'item','item.latitude' -%} | |
{%- assign fields = site.data.config-map -%} | |
<!-- load leaflet dependencies --> | |
<script src="{{ '/assets/lib/leaflet/leaflet.js' | relative_url }}"></script> | |
<script src="{{ '/assets/lib/leaflet/Leaflet.fullscreen.min.js' | relative_url }}"></script> | |
{% if site.data.theme.map-search == true %}<script src="{{ '/assets/lib/leaflet/fuse.min.js' | relative_url }}"></script> | |
<script src="{{ '/assets/lib/leaflet/leaflet.fusesearch.js' | relative_url }}"></script>{% endif %} | |
{% if site.data.theme.map-cluster == true %}<script src="{{ '/assets/lib/leaflet/leaflet.markercluster.js' | relative_url }}"></script>{% endif %} | |
{% if site.data.theme.map-search == true and site.data.theme.map-cluster == true %}<script src="{{ '/assets/lib/leaflet/leaflet.markercluster.freezable.js' | relative_url }}"></script>{% endif %} | |
<script> | |
(function(){ | |
/* add collection map data */ | |
var geodata = { "type": "FeatureCollection", "features": [ | |
{% for item in items %} | |
{ "type":"Feature", "geometry":{ "type":"Point", "coordinates":[{{ item.longitude | strip }},{{ item.latitude | strip }}] }, "properties": | |
{ "title": {{ item.title | jsonify }}, | |
{% for f in fields %}{{ f.field | jsonify }}: {{ item[f.field] | jsonify }},{% endfor %}{% if item.youtubeid %} "youtube": {{ item.youtubeid | jsonify }}, {% endif %} | |
"format": {{ item.format | jsonify }}, {% if item.filename contains '/' %}"filename": "{{ item.filename }}" {% else %}"filename":{{ '/objects/' | relative_url | append: item.filename | jsonify }}{% endif %}, "link": "{% if item.parentid %}{{ item.parentid }}#{{ item.objectid }}{% else %}{{ item.objectid }}{% endif %}", "id": {{ item.objectid | jsonify }} } }{% unless forloop.last %}, {% endunless %}{% endfor %} | |
]}; | |
/* check for url parameters and set initial view options */ | |
let url = new URL(window.location); | |
var mapCenter = url.searchParams.get('location') ? url.searchParams.get('location').split(',') : [{{ page.latitude | default: site.data.theme.latitude | default: 46.727485 }}, {{ page.longitude | default: site.data.theme.longitude | default: -117.014185 }}]; | |
var mapZoom = url.searchParams.get('location') ? 16 : {{ page.zoom | default: site.data.theme.zoom-level | default: 5 }}; | |
var markerFilter = url.searchParams.get('marker') ? url.searchParams.get('marker') : ""; | |
/* init map, set center and zoom */ | |
var map = L.map('map').setView(mapCenter, mapZoom); | |
/* add map layer options */ | |
var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', { | |
attribution: 'Tiles © Esri — Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' | |
}); | |
var Esri_NatGeoWorldMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', { | |
attribution: 'Tiles © Esri — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC', | |
maxZoom: 16 | |
}); | |
var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { | |
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' | |
}); | |
var OpenStreetMap_Mapnik = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { | |
maxZoom: 19, | |
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' | |
}); | |
/* add base map switcher */ | |
var baseMaps = { | |
"Esri World StreetMap": Esri_WorldStreetMap, | |
"Esri National Geo": Esri_NatGeoWorldMap, | |
"Esri Imagery": Esri_WorldImagery, | |
"Open Street Map": OpenStreetMap_Mapnik | |
}; | |
L.control.layers(baseMaps).addTo(map); | |
/* load base map */ | |
{{ site.data.theme.map-base | default: 'Esri_WorldStreetMap' }}.addTo(map); | |
{% if site.data.theme.map-search == true %} | |
/* add leaflet-fusesearch */ | |
var options = { | |
title: 'Search Map Items', | |
locationholder: 'Search map items...', | |
threshold: {{ site.data.theme.map-search-fuzziness | default: 0.35 }}, | |
showResultFct: function(feature, container) { | |
var result = `<strong>${feature.properties.title}</strong><br>`; | |
{% for f in fields %} | |
if(feature.properties[{{ f.field | jsonify }}]) { result += feature.properties[{{ f.field | jsonify }}] + `<br>`; } | |
{% endfor %} | |
container.innerHTML = result; | |
} | |
}; | |
var searchCtrl = L.control.fuseSearch(options); | |
searchCtrl.addTo(map); | |
searchCtrl.indexFeatures(geodata.features, {{ fields | where: 'search','true' | map: 'field' | unshift: 'title' | jsonify }});{% endif %} | |
/* add fullscreen control */ | |
map.addControl(new L.Control.Fullscreen()); | |
{% if site.data.theme.map-cluster == true %} | |
/* create cluster group */ | |
var markers = L.markerClusterGroup({ | |
maxClusterRadius: {{ site.data.theme.map-cluster-radius | default: 15 }}, | |
singleMarkerMode: true, | |
iconCreateFunction: function(cluster) { | |
/* custom icon function, tweak default to add more alt text */ | |
var childCount = cluster.getChildCount(); | |
var csize; | |
if (childCount < 10) { | |
csize = 'small'; | |
} else if (childCount < 100) { | |
csize = 'medium'; | |
} else { | |
csize = 'large'; | |
} | |
var c = ' marker-cluster-' + csize; | |
return new L.DivIcon({ html: '<div><span class="visually-hidden">' + csize +' cluster of </span><span>' + childCount + '</span><span class="visually-hidden"> items</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) }); | |
} | |
{% if site.data.theme.map-search == true %}, removeOutsideVisibleBounds: false{% endif %} | |
});{% endif %} | |
/* function to create object popups */ | |
function objectPopups(feature, layer) { | |
{% if site.data.theme.map-search == true %} | |
/* bind feature for search */ | |
feature.layer = layer;{% endif %} | |
/* calculate item link */ | |
var itemHref = '{{ "/item.html?id=" | relative_url }}' + feature.properties.link; | |
/* find object thumb based on format */ | |
var thumbSrc; | |
if (feature.properties.youtube) { | |
thumbSrc = 'https://img.youtube.com/vi/' + feature.properties.youtube + '/default.jpg'; | |
} else if (feature.properties.format && feature.properties.format.includes("image")) { | |
thumbSrc = feature.properties.filename; | |
} else if (feature.properties.format && feature.properties.format.includes("audio")) { | |
thumbSrc = '{{ "/assets/lib/icons/" | relative_url }}{{ icons.icon-audio }}.svg'; | |
} else if (feature.properties.format && feature.properties.format.includes("video")) { | |
thumbSrc = '{{ "/assets/lib/icons/" | relative_url }}{{ icons.icon-video }}.svg'; | |
} else if (feature.properties.format && feature.properties.format.includes("pdf")) { | |
thumbSrc = '{{ "/assets/lib/icons/" | relative_url }}{{ icons.icon-pdf }}.svg'; | |
} else if (feature.properties.format && feature.properties.format.includes("compound")) { | |
thumbSrc = '{{ "/assets/lib/icons/" | relative_url }}{{ icons.icon-compound-object }}.svg'; | |
} else if (feature.properties.format && feature.properties.format.includes("multiple")) { | |
thumbSrc = '{{ "/assets/lib/icons/" | relative_url }}{{ icons.icon-multiple }}.svg'; | |
} else { | |
thumbSrc = '{{ "/assets/lib/icons/" | relative_url }}{{ icons.icon-default }}.svg'; | |
} | |
/* create popup content */ | |
var popupTemplate = '<h2 class="h4"><a class="text-dark" href="' + itemHref + '">' + | |
feature.properties.title + '</a></h2><div class="text-center"><a href="' + itemHref + | |
'" ><img class="mapthumb img-thumb" src="' + thumbSrc + '" alt="item thumbnail"></a></div><p>'; | |
/* add metadata fields */ | |
{% for f in fields %}{% if f.display_name %} | |
if (feature.properties[{{ f.field | jsonify }}]) { | |
popupTemplate += '<strong>{{ f.display_name }}:</strong> ' + feature.properties[{{ f.field | jsonify }}] + '<br>'; | |
} | |
{% endif %}{% endfor %} | |
/* add object link button to popup */ | |
popupTemplate += '</p><div class="text-center"><a class="btn btn-light" href="' + itemHref + '" >View Item</a></div>'; | |
/* add object popup to map layer */ | |
layer.bindPopup(popupTemplate); | |
} | |
/* function to add objects to map */ | |
function objectMarkers(feature,latlng) { | |
var marker = L.marker(latlng, {alt: feature.properties.title}); | |
{% if site.data.theme.map-cluster == true %}markers.addLayer(marker);{% endif %} | |
return marker; | |
} | |
/* use geoJson features to add objects to map */ | |
var mapFeatures = L.geoJson(geodata, { | |
onEachFeature: objectPopups, | |
pointToLayer: objectMarkers | |
}){% if site.data.theme.map-cluster != true %}.addTo(map);{% else %}; | |
map.addLayer(markers);{% endif %} | |
{% if site.data.theme.map-cluster == true and site.data.theme.map-search == true %} | |
/* uncluster when search is clicked */ | |
document.querySelector('a.button').addEventListener("click", function() { | |
markers.disableClustering(); | |
}); | |
/* recluster when search is closed */ | |
document.querySelector('a.close').addEventListener("click", function() { | |
markers.enableClustering(); | |
document.querySelector('input.search-input').value = ""; | |
});{% endif %} | |
/* show popup if id in URL query */ | |
if (markerFilter != "") { | |
{% if site.data.theme.map-cluster == true %} | |
markers.eachLayer(layer => { | |
if (layer.feature.properties.id === markerFilter) { | |
/* uncluster clusters, then show */ | |
if (markers.getVisibleParent(layer)["_childCount"]) { | |
markers.getVisibleParent(layer).spiderfy(); | |
} | |
layer.openPopup(); | |
} | |
}); | |
{% else %} | |
mapFeatures.eachLayer(layer => { | |
if (layer.feature.properties.id === markerFilter) { | |
layer.openPopup(); | |
} | |
}); | |
{% endif %} | |
} | |
})(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
a quick tweak to map-js.html to support configuration via page front matter