Built with blockbuilder.org
Last active
April 21, 2017 04:18
-
-
Save stevage/e89f350b06d8c5a9390ca24c5b625e83 to your computer and use it in GitHub Desktop.
MKW map
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
license: mit |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset='utf-8' /> | |
<title></title> | |
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<!-- Need these! --> | |
<script src="https://d3js.org/d3-collection.v1.min.js"></script> | |
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script> | |
<script src="https://d3js.org/d3-dsv.v1.min.js"></script> | |
<script src="https://d3js.org/d3-request.v1.min.js"></script> | |
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.js'></script> | |
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.css' rel='stylesheet' /> | |
<!-- --> | |
<style> | |
/* This should probably go */ | |
body { margin:0; padding:0; } | |
/* This one needs to be changed as appropriate for responsiveness */ | |
#map { position:absolute; top:0; bottom:0; width:100%; } | |
/* From here downwards should be tweaked for MKW branding */ | |
.mapboxgl-popup-content { | |
max-width: 400px; | |
} | |
.mapboxgl-popup-content img { | |
max-width: 80%; | |
} | |
.mapboxgl-popup-content .moreinfo { | |
display: block; | |
height:30px; | |
background:#00aecb; | |
color:white; | |
} | |
</style> | |
</head> | |
<body> | |
<div id='map'></div> | |
<script> | |
//http://mkw.melbourne.vic.gov.au/wp-json/wp/v2/posts?categories=1&per_page=100 | |
//http://mkw.melbourne.vic.gov.au/wp-json/acf/v3/posts?categories=1&per_page=100 | |
/* | |
TODO: | |
- how the hell do I geocode? | |
-- one off process? | |
-- convert json to csv, save to disk | |
-- load into google sheets | |
-- geocode | |
-- re-export | |
-- somehow import?? | |
- tweak style so it's just big pins, no invisible titles [text titles that use a non-present text attribute] | |
*/ | |
/* The main MKW site needs to call this hook whenever the filter changes | |
Sample values (each can be undefined for no filter) | |
dayFilter: "06/05/2017" | |
themeFilter: "Startups" | |
typeFilter: "Talk" | |
accessibilityFilter: "Wheelchair accessible" | |
*/ | |
var filters = { | |
day: undefined, | |
theme: undefined, | |
type: undefined, | |
accessibility: undefined | |
}; | |
function updateFilter(dayFilter, themeFilter, typeFilter, accessibilityFilter) { | |
//**** Replace from here... | |
// maintain state from previous filter updates | |
if (dayFilter) { | |
filters.day = dayFilter === 'all days' ? undefined : dayFilter; | |
} | |
if (themeFilter) { | |
filters.theme = themeFilter === 'all themes' ? undefined : themeFilter; | |
} | |
if (typeFilter) { | |
filters.type = typeFilter === 'all types' ? undefined : typeFilter; | |
} | |
if (accessibilityFilter) { | |
filters.accessibility = accessibilityFilter === 'all venues' ? undefined : accessibilityFilter; | |
} | |
var mapFilters = ['all']; | |
// now use the current state of filters to generate map filter | |
if (filters.day) { | |
mapFilters.push(['==', 'program_date',filters.day]); | |
} | |
if (filters.theme) { | |
mapFilters.push(['has','theme:' + filters.theme]); | |
} | |
if (filters.type) { | |
mapFilters.push(['has','type:' + filters.type]); | |
} | |
if (filters.accessibility) { | |
mapFilters.push(['has', 'accessibility:' + filters.accessibility]); | |
} | |
if (mapFilters.length === 1) { | |
map.setFilter('mkw-event-pins', undefined); | |
} else { | |
map.setFilter('mkw-event-pins', mapFilters); | |
} | |
// **** To here | |
} | |
function def(a, b) { | |
return a !== undefined ? a : b; | |
} | |
var mkwEvents = {}; | |
function eventsToGeoJson(events) { | |
var mapData = { | |
type:'FeatureCollection', | |
features: [] | |
}; | |
Object.keys(mkwEvents).forEach(function(id) { | |
mapData.features.push({ | |
type: 'Feature', | |
properties: mkwEvents[id], | |
geometry: { | |
type: 'Point', | |
// ### TODO: use actual coordinates | |
coordinates: [ | |
144.85 + Math.random() * 0.2, | |
-37.9 + Math.random() * 0.2 | |
] | |
} | |
}); | |
}); | |
console.log(mapData); | |
return mapData; | |
} | |
function dumpAddressesCsv(acfs) { | |
var rows=[]; | |
acfs.forEach(function(acf) { | |
var e = acf.acf; | |
rows.push({ | |
id: acf.id, | |
address: [e.location_address.street1, e.location_address.street2, e.location_address.city, e.location_address.state, e.location_address.zip, 'Australia'].join(' ') | |
}); | |
}); | |
console.log(d3.csvFormat(rows)); | |
} | |
var metadataCount = 0; | |
function metadataLoaded() { | |
if (++metadataCount < 2) | |
return; // keep waiting until we have both main metadata and advanced custom fields. (Because we're not using a Promises library) | |
// Now we have all the metadata for every event, let's create a GeoJSON object with all of it: | |
var mapData = eventsToGeoJson(mkwEvents); | |
whenMapLoaded(function() { | |
// add the map data so we can style it | |
map.addSource('mkw-events', { | |
type: 'geojson', | |
data: mapData | |
}); | |
// now add a style layer that depends on it. | |
map.addLayer({ | |
id: 'mkw-event-pins', | |
source: 'mkw-events', | |
'type': 'symbol', | |
layout: { | |
'icon-image': 'marker-15', | |
'icon-allow-overlap': true, | |
'icon-size': 1 | |
/*'text-optional': true, | |
'text-size': 18, | |
'text-font': ['CoM Regular', 'Arial Unicode MS Regular'], | |
'text-offset': [0,0.5], | |
'text-anchor': 'top', | |
'text-field': '{Organisation}'*/ | |
}, paint: { | |
'icon-opacity': 0.72, | |
//'text-color': '#00aecb' | |
} | |
}); | |
// When we click on a pin, show a popup. | |
map.on('click', 'mkw-event-pins', function (e) { | |
var event = e.features[0]; | |
new mapboxgl.Popup() | |
.setLngLat(event.geometry.coordinates) | |
.setHTML( | |
'<img src="' + event.properties.hero_image + '">' + | |
'<h2>' + event.properties.title + '</h2>' + | |
event.properties.excerpt + | |
'<label class="dates">' + event.properties.program_date + ', ' + event.properties.event_dates_start + ' - ' + event.properties.event_dates_end + '</label>' + | |
'<a class="moreinfo" href="' + event.properties.link + '">More information</a>' | |
).addTo(map); | |
}); | |
map.on('mouseenter', 'mkw-event-pins', function () { | |
map.getCanvas().style.cursor = 'pointer'; | |
}); | |
map.on('mouseleave', 'mkw-event-pins', function () { | |
map.getCanvas().style.cursor = ''; | |
}); | |
}); | |
} | |
function whenMapLoaded(f) { | |
return map.loaded() ? f() : map.once('load', f); | |
} | |
function onLoad() { | |
var postsUrl = 'http://mkw.melbourne.vic.gov.au/wp-json/wp/v2/posts?categories=1&per_page=100'; | |
var acfUrl = 'http://mkw.melbourne.vic.gov.au/wp-json/acf/v3/posts?categories=1&per_page=100'; | |
// ### for dev/testing as the above URLs don't support CORS | |
postsUrl = 'https://gist.githubusercontent.com/stevage/29faffd252d62f56b71319f9281f21ce/raw/fdf485a2850bb85ce80cf2f92f9be22b20daea91/posts.json'; | |
acfUrl = 'https://gist.githubusercontent.com/stevage/ca8d8f0b41f10882ec0fd1de04240410/raw/d39c4fd4dd7ec4bc1db63a38ec615528a144664c/posts.json'; | |
// get JSON with main metadata about each event | |
d3.json(postsUrl, function(j) { | |
j.forEach(function(event) { | |
mkwEvents[event.id] = def(mkwEvents[event.id], {}); | |
mkwEvents[event.id].id = event.id; | |
mkwEvents[event.id].link = event.link; | |
mkwEvents[event.id].title = event.title.rendered; | |
mkwEvents[event.id].excerpt = event.excerpt.rendered; | |
}); | |
metadataLoaded(); | |
}); | |
// get info with advanced custom fields metadata about each event | |
d3.json(acfUrl, function(j) { | |
dumpAddressesCsv(j); | |
j.forEach(function(acf) { | |
var event = acf.acf; | |
mkwEvents[acf.id] = def(mkwEvents[acf.id], {}); | |
mkwEvents[acf.id].hero_image = event.hero_image; | |
mkwEvents[acf.id].location = event.location; | |
mkwEvents[acf.id].event_dates_start = event.event_dates_start; | |
mkwEvents[acf.id].event_dates_end = event.event_dates_end; | |
mkwEvents[acf.id].program_date = event.program_date; | |
// We create properties like "theme:Startups", so we can filter on them with Mapbox. | |
def(event.theme, []).forEach(function(theme) { | |
mkwEvents[acf.id]['theme:' + theme] = true; | |
}); | |
if (event.access !== "") { | |
def(event.access, []).forEach(function(accessibility) { | |
// "Wheelchair accessible". No auslan? | |
mkwEvents[acf.id]['accessibility:' + accessibility] = true; | |
}); | |
} | |
// *** This next line had a bug. | |
def(event.type, []).forEach(function(type) { | |
mkwEvents[acf.id]['type:' + type] = true; | |
}); | |
}); | |
metadataLoaded(); | |
}); | |
} | |
mapboxgl.accessToken = 'pk.eyJ1IjoiY2l0eW9mbWVsYm91cm5lIiwiYSI6ImNpejdob2J0czAwOWQzM21ubGt6MDVqaHoifQ.55YbqeTHWMK_b6CEAmoUlA'; | |
var map = new mapboxgl.Map({ | |
container: 'map', | |
style: 'mapbox://styles/cityofmelbourne/cj1pz0q5d00382rp7zylkhxp1?update=1', | |
center: [144.9, -37.8], | |
zoom: 12 | |
}); | |
onLoad(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment