Created
June 14, 2017 22:19
-
-
Save hcliff/32f50c8f7cc9cc8ce0a0689024037f87 to your computer and use it in GitHub Desktop.
// source http://jsbin.com/pezewij
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' /> | |
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.32.1/mapbox-gl.js'></script> | |
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.32.1/mapbox-gl.css' rel='stylesheet' /> | |
<style id="jsbin-css"> | |
html, body { | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
width: 100%; | |
} | |
#map { | |
width: 100%; | |
height: calc(100% - 25px); | |
position:absolute; | |
top:25px; | |
} | |
#name-search{ | |
float: left; | |
} | |
input { | |
box-sizing: border-box; | |
width:50%; | |
border: 0; | |
height: 25px; | |
padding: 0 5px; | |
} | |
#aggregates { | |
position: absolute; | |
top: 25px; | |
} | |
#tags { | |
margin: 0; | |
padding: 0; | |
display: block; | |
position: absolute; | |
bottom: 0; | |
max-height: 150px; | |
overflow: hidden; | |
} | |
#tags li { | |
display: inline-block; | |
margin: 2px 5px; | |
background: rgba(0,0,0,0.5); | |
padding: 3px 7px; | |
font-size: 12px; | |
font-family: verdana; | |
color: white; | |
border-radius: 6px; | |
} | |
li.active { | |
background: rgba(255,255,255,0.5); | |
color: black; | |
} | |
</style> | |
</head> | |
<body> | |
<input type="text" id="name-search" placeholder="search" /> | |
<input type="datetime-local" id="start" /> | |
<div id='map'></div> | |
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script> | |
<script src="https://code.jquery.com/jquery-3.1.0.js"></script> | |
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script> | |
<div id='aggregates'></div> | |
<ul id='tags'>venues: 30<ul> | |
<script id="jsbin-javascript"> | |
mapboxgl.accessToken = 'pk.eyJ1IjoiY2FsZW5kcmUiLCJhIjoiY2lwMDk4NThhMDJpOHVmbTR6dWp3ZXIzbCJ9.QoQKozHFNWDVAiQy2c_AnQ'; | |
const showVenues = true; | |
const showAggregates = true; | |
const showCache = true; | |
var map = new mapboxgl.Map({ | |
container: 'map', | |
style: 'mapbox://styles/mapbox/light-v9', | |
zoom: 20, | |
center: [-73.95185028352992, 40.711077039996724] | |
}); | |
// const baseUrl = "https://pr-968.liveapp.com/"; | |
const baseUrl = "http://localhost:3000/"; | |
function getCallouts(value, start, finish, map, tagIds, venueId){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/callouts?clientVersion=${encodeURIComponent("consumer#1.0")}`; | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
start = moment(start); | |
finish = moment(finish); | |
url += `&events.occurrences.start=${start.format()}&events.occurrences.finish=${finish.format()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
url += `&firstVenueId=${venueId}`; | |
url += `&limit=10`; | |
$.ajax(url, { | |
'success': function(response){ | |
debugger; | |
const venue = response.items[0]; | |
let html = `${venue.resolvedName}`; | |
if (venue.highlights && venue.highlights.length > 0){ | |
html += '<ul>'; | |
venue.highlights.forEach(function(highlight){ | |
if(highlight.type === 'event'){ | |
html += `<li>${highlight.item.name}</li>`; | |
} | |
}); | |
html += '</ul>'; | |
} | |
html += '<ul>'; | |
response.items.slice(1).forEach(function(venue){ | |
html += `<li>next: ${venue.resolvedName}`; | |
if (venue.highlights && venue.highlights.length > 0){ | |
html += '<ul>'; | |
venue.highlights.forEach(function(highlight){ | |
if(highlight.type === 'event'){ | |
html += `<li>${highlight.item.name}</li>`; | |
} | |
}); | |
html += '</ul>'; | |
} | |
html += '</li>'; | |
}); | |
html += '</ul>'; | |
// Populate the popup and set its coordinates | |
// based on the feature found. | |
new mapboxgl.Popup() | |
.setLngLat([venue.geometry.coordinates[0], venue.geometry.coordinates[1]]) | |
.setHTML(html) | |
.addTo(map); | |
} | |
}) | |
} | |
function makeLegend(value, start, finish, map, tagIds){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/legend?clientVersion=${encodeURIComponent("consumer#1.0")}` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
start = moment(start); | |
finish = moment(finish); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
$.ajax(url, { | |
'success': function(response){ | |
$('#tags').empty(); | |
if (response.selectedTags) { | |
const selectedTags = response.selectedTags.items; | |
selectedTags.forEach(function(tag){ | |
const li = $(`<li class="active">${tag.name}: ${tag.useCount || "-"}</li>`); | |
li.on("click", function(){ | |
const inTagIds = _.indexOf(oldTagIds, tag.id) !== -1; | |
if(inTagIds){ | |
oldTagIds = _.without(oldTagIds, tag.id); | |
$(li).removeClass('active'); | |
}else{ | |
oldTagIds.push(tag.id); | |
$(li).addClass('active'); | |
} | |
swapSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
return $('#tags').append(li); | |
}); | |
} | |
const tags = response.tags.items; | |
tags.forEach(function(tag){ | |
const li = $(`<li>${tag.name}: ${tag.useCount}</li>`); | |
li.on("click", function(){ | |
const inTagIds = _.indexOf(oldTagIds, tag.id) !== -1; | |
if(inTagIds){ | |
oldTagIds = _.without(oldTagIds, tag.id); | |
$(li).removeClass('active'); | |
}else{ | |
oldTagIds.push(tag.id); | |
$(li).addClass('active'); | |
} | |
swapSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
return $('#tags').append(li); | |
}); | |
} | |
}); | |
} | |
function makeAggregates(value, start, finish, map, tagIds){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/aggregates?clientVersion=${encodeURIComponent("consumer#1.0")}` | |
start = moment(start); | |
finish = moment(finish); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
url += `&eventsOccurrencesStart=${start.toJSON()}&eventsOccurrencesFinish=${finish.toJSON()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
$.ajax(url, { | |
'success': function(response){ | |
$('#aggregates').html(`${response.venueCount} venues`); | |
} | |
}); | |
} | |
function makeSearch(value, start, finish, tagIds){ | |
var url = `${baseUrl}browse/tiles/{z}/{x}/{y}.pbf?clientVersion=${encodeURIComponent("consumer#1.0")}&debugTiles=true` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
start = moment(start).startOf('hour'); | |
finish = moment(finish).startOf('hour'); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
url += `&aggregateThreshold=100` | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
map.addSource("live-venues", { | |
type: 'vector', | |
"tiles": [url] | |
}); | |
const genreColors = { | |
property: 'genre', | |
type: 'categorical', | |
stops: [ | |
['misc', '#22364D'], | |
['municipal', '#737780'], | |
['service', '#A3846A'], | |
['none', '#FFFFFF'], | |
['lodging', '#C2574E'], | |
['body', '#F77CC6'], | |
['homeAndHobby', '#FF8F33'], | |
['activity', '#4CCF78'], | |
['groups', '#9BC2A2'], | |
['food', '#17C2E8'], | |
['essentials', '#3D87FF'], | |
['drinks', '#772EE6'], | |
['style', '#FABF0F'] | |
] | |
}; | |
const circleRadius = { | |
"base": 1, | |
"stops": [ | |
[5, 1], | |
[8, 1], | |
[9, 1.25], | |
[11, 1.5], | |
[12, 2], | |
[13, 2], | |
[14, 2], | |
[15, 2], | |
[16, 2.5], | |
[17, 2.8], | |
[18, 3], | |
[19, 3.5], | |
[20, 4], | |
[21, 5] | |
] | |
}; | |
if(showAggregates){ | |
map.addLayer({ | |
"id": "aggregate-dots-layer", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "aggregates", | |
"paint": { | |
"circle-radius": circleRadius, | |
'circle-stroke-width': { | |
property: 'hasEvent', | |
stops: [ | |
[0, 0], | |
[1, 2] | |
] | |
}, | |
'circle-stroke-color': '#000000', | |
'circle-color': '#ff0000', | |
'circle-color': genreColors | |
} | |
}); | |
} | |
map.addLayer({ | |
"id": "debugTiles", | |
"type": "line", | |
"source": "live-venues", | |
"source-layer": "debugTiles", | |
"layout": {}, | |
'paint': { | |
'line-color': '#ff0000', | |
'line-opacity': 0.8, | |
'line-width': 3 | |
} | |
}); | |
if(showCache){ | |
map.addLayer({ | |
"id": "skinnyVenues", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "skinnyVenues", | |
"layout": {}, | |
"paint": { | |
"circle-color": genreColors, | |
"circle-radius": circleRadius | |
} | |
}); | |
} | |
// map.addLayer({ | |
// "id": "geohashDebug", | |
// "type": "line", | |
// "source": "live-venues", | |
// "source-layer": "aggregatesDebug", | |
// "layout": {}, | |
// 'paint': { | |
// 'line-color': '#000000', | |
// 'line-opacity': 0.2, | |
// 'line-width': 1 | |
// } | |
// }); | |
if(showVenues){ | |
// map.addLayer({ | |
// "id": "venue-labels-layer", | |
// "type": "symbol", | |
// "source": "live-venues", | |
// "source-layer": "venues", | |
// "layout": { | |
// "text-field": "{name}", | |
// "text-size": 14, | |
// "text-offset": [0, -1], | |
// "text-max-width": 15 | |
// } | |
// }); | |
map.addLayer({ | |
"id": "venue-dots-layer", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "venues", | |
'paint': { | |
'circle-radius': circleRadius, | |
'circle-stroke-width': { | |
property: 'hasEvent', | |
stops: [ | |
[0, 0], | |
[1, 2] | |
] | |
}, | |
'circle-stroke-color': '#000000', | |
'circle-color': genreColors | |
} | |
}); | |
} | |
} | |
function swapSearch(value, start, finish, tagIds){ | |
map.removeSource('live-venues'); | |
map.removeLayer('venue-labels-layer'); | |
map.removeLayer('venue-dots-layer'); | |
makeSearch(value, start, finish, tagIds); | |
} | |
Date.prototype.toDateInputValue = (function() { | |
var local = new Date(this); | |
local.setMinutes(this.getMinutes() - this.getTimezoneOffset()); | |
return local.toJSON().slice(0,16); | |
}); | |
var oldQuery = ""; | |
var oldStart = new Date(); | |
var oldFinish = new Date(oldStart); | |
oldFinish.setMinutes(oldFinish.getMinutes() + 180); | |
var oldTagIds = []; | |
document.addEventListener('DOMContentLoaded', function(){ | |
var search = document.getElementById("name-search"); | |
search.addEventListener('keyup', function(){ | |
if(search.value.length < 3 && oldQuery.length < 3){ | |
return | |
} | |
swapSearch(search.value, oldStart, oldFinish, oldTagIds); | |
makeLegend(search.value, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(search.value, oldStart, oldFinish, map, oldTagIds); | |
oldQuery = search.value; | |
}); | |
var startInput = document.getElementById("start"); | |
start.value = oldStart.toDateInputValue(); | |
startInput.addEventListener('keyup', function(){ | |
let start = new Date(startInput.value); | |
let finish = new Date(startInput.value); | |
finish.setMinutes(finish.getMinutes() + 90); | |
swapSearch(oldQuery, start, finish, oldTagIds); | |
makeLegend(oldQuery, start, finish, map, oldTagIds); | |
makeAggregates(oldQuery, start, finish, map, oldTagIds); | |
oldStart = start; | |
oldFinish = finish; | |
}); | |
map.on('load', function () { | |
makeSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
map.on('moveend', function() { | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
map.on('click', function (e) { | |
var features = map.queryRenderedFeatures(e.point, { layers: ['venue-dots-layer'] }); | |
if (!features.length) { | |
return; | |
} | |
// console.log("features", features); | |
features.map(function(feature){ | |
console.log("feature", feature.properties); | |
}) | |
var feature = features[0]; | |
getCallouts(oldQuery, oldStart, oldFinish, map, oldTagIds, feature.properties.id); | |
}); | |
}); | |
map.addControl(new mapboxgl.NavigationControl()); | |
window.map = map; | |
window.parent.map = map; | |
</script> | |
<script id="jsbin-source-css" type="text/css">html, body { | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
width: 100%; | |
} | |
#map { | |
width: 100%; | |
height: calc(100% - 25px); | |
position:absolute; | |
top:25px; | |
} | |
#name-search{ | |
float: left; | |
} | |
input { | |
box-sizing: border-box; | |
width:50%; | |
border: 0; | |
height: 25px; | |
padding: 0 5px; | |
} | |
#aggregates { | |
position: absolute; | |
top: 25px; | |
} | |
#tags { | |
margin: 0; | |
padding: 0; | |
display: block; | |
position: absolute; | |
bottom: 0; | |
max-height: 150px; | |
overflow: hidden; | |
} | |
#tags li { | |
display: inline-block; | |
margin: 2px 5px; | |
background: rgba(0,0,0,0.5); | |
padding: 3px 7px; | |
font-size: 12px; | |
font-family: verdana; | |
color: white; | |
border-radius: 6px; | |
} | |
li.active { | |
background: rgba(255,255,255,0.5); | |
color: black; | |
}</script> | |
<script id="jsbin-source-javascript" type="text/javascript">mapboxgl.accessToken = 'pk.eyJ1IjoiY2FsZW5kcmUiLCJhIjoiY2lwMDk4NThhMDJpOHVmbTR6dWp3ZXIzbCJ9.QoQKozHFNWDVAiQy2c_AnQ'; | |
const showVenues = true; | |
const showAggregates = true; | |
const showCache = true; | |
var map = new mapboxgl.Map({ | |
container: 'map', | |
style: 'mapbox://styles/mapbox/light-v9', | |
zoom: 20, | |
center: [-73.95185028352992, 40.711077039996724] | |
}); | |
// const baseUrl = "https://pr-968.liveapp.com/"; | |
const baseUrl = "http://localhost:3000/"; | |
function getCallouts(value, start, finish, map, tagIds, venueId){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/callouts?clientVersion=${encodeURIComponent("consumer#1.0")}`; | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
start = moment(start); | |
finish = moment(finish); | |
url += `&events.occurrences.start=${start.format()}&events.occurrences.finish=${finish.format()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
url += `&firstVenueId=${venueId}`; | |
url += `&limit=10`; | |
$.ajax(url, { | |
'success': function(response){ | |
debugger; | |
const venue = response.items[0]; | |
let html = `${venue.resolvedName}`; | |
if (venue.highlights && venue.highlights.length > 0){ | |
html += '<ul>'; | |
venue.highlights.forEach(function(highlight){ | |
if(highlight.type === 'event'){ | |
html += `<li>${highlight.item.name}</li>`; | |
} | |
}); | |
html += '</ul>'; | |
} | |
html += '<ul>'; | |
response.items.slice(1).forEach(function(venue){ | |
html += `<li>next: ${venue.resolvedName}`; | |
if (venue.highlights && venue.highlights.length > 0){ | |
html += '<ul>'; | |
venue.highlights.forEach(function(highlight){ | |
if(highlight.type === 'event'){ | |
html += `<li>${highlight.item.name}</li>`; | |
} | |
}); | |
html += '</ul>'; | |
} | |
html += '</li>'; | |
}); | |
html += '</ul>'; | |
// Populate the popup and set its coordinates | |
// based on the feature found. | |
new mapboxgl.Popup() | |
.setLngLat([venue.geometry.coordinates[0], venue.geometry.coordinates[1]]) | |
.setHTML(html) | |
.addTo(map); | |
} | |
}) | |
} | |
function makeLegend(value, start, finish, map, tagIds){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/legend?clientVersion=${encodeURIComponent("consumer#1.0")}` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
start = moment(start); | |
finish = moment(finish); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
$.ajax(url, { | |
'success': function(response){ | |
$('#tags').empty(); | |
if (response.selectedTags) { | |
const selectedTags = response.selectedTags.items; | |
selectedTags.forEach(function(tag){ | |
const li = $(`<li class="active">${tag.name}: ${tag.useCount || "-"}</li>`); | |
li.on("click", function(){ | |
const inTagIds = _.indexOf(oldTagIds, tag.id) !== -1; | |
if(inTagIds){ | |
oldTagIds = _.without(oldTagIds, tag.id); | |
$(li).removeClass('active'); | |
}else{ | |
oldTagIds.push(tag.id); | |
$(li).addClass('active'); | |
} | |
swapSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
return $('#tags').append(li); | |
}); | |
} | |
const tags = response.tags.items; | |
tags.forEach(function(tag){ | |
const li = $(`<li>${tag.name}: ${tag.useCount}</li>`); | |
li.on("click", function(){ | |
const inTagIds = _.indexOf(oldTagIds, tag.id) !== -1; | |
if(inTagIds){ | |
oldTagIds = _.without(oldTagIds, tag.id); | |
$(li).removeClass('active'); | |
}else{ | |
oldTagIds.push(tag.id); | |
$(li).addClass('active'); | |
} | |
swapSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
return $('#tags').append(li); | |
}); | |
} | |
}); | |
} | |
function makeAggregates(value, start, finish, map, tagIds){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/aggregates?clientVersion=${encodeURIComponent("consumer#1.0")}` | |
start = moment(start); | |
finish = moment(finish); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
url += `&eventsOccurrencesStart=${start.toJSON()}&eventsOccurrencesFinish=${finish.toJSON()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
$.ajax(url, { | |
'success': function(response){ | |
$('#aggregates').html(`${response.venueCount} venues`); | |
} | |
}); | |
} | |
function makeSearch(value, start, finish, tagIds){ | |
var url = `${baseUrl}browse/tiles/{z}/{x}/{y}.pbf?clientVersion=${encodeURIComponent("consumer#1.0")}&debugTiles=true` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
start = moment(start).startOf('hour'); | |
finish = moment(finish).startOf('hour'); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
url += `&aggregateThreshold=100` | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
map.addSource("live-venues", { | |
type: 'vector', | |
"tiles": [url] | |
}); | |
const genreColors = { | |
property: 'genre', | |
type: 'categorical', | |
stops: [ | |
['misc', '#22364D'], | |
['municipal', '#737780'], | |
['service', '#A3846A'], | |
['none', '#FFFFFF'], | |
['lodging', '#C2574E'], | |
['body', '#F77CC6'], | |
['homeAndHobby', '#FF8F33'], | |
['activity', '#4CCF78'], | |
['groups', '#9BC2A2'], | |
['food', '#17C2E8'], | |
['essentials', '#3D87FF'], | |
['drinks', '#772EE6'], | |
['style', '#FABF0F'] | |
] | |
}; | |
const circleRadius = { | |
"base": 1, | |
"stops": [ | |
[5, 1], | |
[8, 1], | |
[9, 1.25], | |
[11, 1.5], | |
[12, 2], | |
[13, 2], | |
[14, 2], | |
[15, 2], | |
[16, 2.5], | |
[17, 2.8], | |
[18, 3], | |
[19, 3.5], | |
[20, 4], | |
[21, 5] | |
] | |
}; | |
if(showAggregates){ | |
map.addLayer({ | |
"id": "aggregate-dots-layer", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "aggregates", | |
"paint": { | |
"circle-radius": circleRadius, | |
'circle-stroke-width': { | |
property: 'hasEvent', | |
stops: [ | |
[0, 0], | |
[1, 2] | |
] | |
}, | |
'circle-stroke-color': '#000000', | |
'circle-color': '#ff0000', | |
'circle-color': genreColors | |
} | |
}); | |
} | |
map.addLayer({ | |
"id": "debugTiles", | |
"type": "line", | |
"source": "live-venues", | |
"source-layer": "debugTiles", | |
"layout": {}, | |
'paint': { | |
'line-color': '#ff0000', | |
'line-opacity': 0.8, | |
'line-width': 3 | |
} | |
}); | |
if(showCache){ | |
map.addLayer({ | |
"id": "skinnyVenues", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "skinnyVenues", | |
"layout": {}, | |
"paint": { | |
"circle-color": genreColors, | |
"circle-radius": circleRadius | |
} | |
}); | |
} | |
// map.addLayer({ | |
// "id": "geohashDebug", | |
// "type": "line", | |
// "source": "live-venues", | |
// "source-layer": "aggregatesDebug", | |
// "layout": {}, | |
// 'paint': { | |
// 'line-color': '#000000', | |
// 'line-opacity': 0.2, | |
// 'line-width': 1 | |
// } | |
// }); | |
if(showVenues){ | |
// map.addLayer({ | |
// "id": "venue-labels-layer", | |
// "type": "symbol", | |
// "source": "live-venues", | |
// "source-layer": "venues", | |
// "layout": { | |
// "text-field": "{name}", | |
// "text-size": 14, | |
// "text-offset": [0, -1], | |
// "text-max-width": 15 | |
// } | |
// }); | |
map.addLayer({ | |
"id": "venue-dots-layer", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "venues", | |
'paint': { | |
'circle-radius': circleRadius, | |
'circle-stroke-width': { | |
property: 'hasEvent', | |
stops: [ | |
[0, 0], | |
[1, 2] | |
] | |
}, | |
'circle-stroke-color': '#000000', | |
'circle-color': genreColors | |
} | |
}); | |
} | |
} | |
function swapSearch(value, start, finish, tagIds){ | |
map.removeSource('live-venues'); | |
map.removeLayer('venue-labels-layer'); | |
map.removeLayer('venue-dots-layer'); | |
makeSearch(value, start, finish, tagIds); | |
} | |
Date.prototype.toDateInputValue = (function() { | |
var local = new Date(this); | |
local.setMinutes(this.getMinutes() - this.getTimezoneOffset()); | |
return local.toJSON().slice(0,16); | |
}); | |
var oldQuery = ""; | |
var oldStart = new Date(); | |
var oldFinish = new Date(oldStart); | |
oldFinish.setMinutes(oldFinish.getMinutes() + 180); | |
var oldTagIds = []; | |
document.addEventListener('DOMContentLoaded', function(){ | |
var search = document.getElementById("name-search"); | |
search.addEventListener('keyup', function(){ | |
if(search.value.length < 3 && oldQuery.length < 3){ | |
return | |
} | |
swapSearch(search.value, oldStart, oldFinish, oldTagIds); | |
makeLegend(search.value, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(search.value, oldStart, oldFinish, map, oldTagIds); | |
oldQuery = search.value; | |
}); | |
var startInput = document.getElementById("start"); | |
start.value = oldStart.toDateInputValue(); | |
startInput.addEventListener('keyup', function(){ | |
let start = new Date(startInput.value); | |
let finish = new Date(startInput.value); | |
finish.setMinutes(finish.getMinutes() + 90); | |
swapSearch(oldQuery, start, finish, oldTagIds); | |
makeLegend(oldQuery, start, finish, map, oldTagIds); | |
makeAggregates(oldQuery, start, finish, map, oldTagIds); | |
oldStart = start; | |
oldFinish = finish; | |
}); | |
map.on('load', function () { | |
makeSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
map.on('moveend', function() { | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
map.on('click', function (e) { | |
var features = map.queryRenderedFeatures(e.point, { layers: ['venue-dots-layer'] }); | |
if (!features.length) { | |
return; | |
} | |
// console.log("features", features); | |
features.map(function(feature){ | |
console.log("feature", feature.properties); | |
}) | |
var feature = features[0]; | |
getCallouts(oldQuery, oldStart, oldFinish, map, oldTagIds, feature.properties.id); | |
}); | |
}); | |
map.addControl(new mapboxgl.NavigationControl()); | |
window.map = map; | |
window.parent.map = map;</script></body> | |
</html> |
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
html, body { | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
width: 100%; | |
} | |
#map { | |
width: 100%; | |
height: calc(100% - 25px); | |
position:absolute; | |
top:25px; | |
} | |
#name-search{ | |
float: left; | |
} | |
input { | |
box-sizing: border-box; | |
width:50%; | |
border: 0; | |
height: 25px; | |
padding: 0 5px; | |
} | |
#aggregates { | |
position: absolute; | |
top: 25px; | |
} | |
#tags { | |
margin: 0; | |
padding: 0; | |
display: block; | |
position: absolute; | |
bottom: 0; | |
max-height: 150px; | |
overflow: hidden; | |
} | |
#tags li { | |
display: inline-block; | |
margin: 2px 5px; | |
background: rgba(0,0,0,0.5); | |
padding: 3px 7px; | |
font-size: 12px; | |
font-family: verdana; | |
color: white; | |
border-radius: 6px; | |
} | |
li.active { | |
background: rgba(255,255,255,0.5); | |
color: black; | |
} |
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
mapboxgl.accessToken = 'pk.eyJ1IjoiY2FsZW5kcmUiLCJhIjoiY2lwMDk4NThhMDJpOHVmbTR6dWp3ZXIzbCJ9.QoQKozHFNWDVAiQy2c_AnQ'; | |
const showVenues = true; | |
const showAggregates = true; | |
const showCache = true; | |
var map = new mapboxgl.Map({ | |
container: 'map', | |
style: 'mapbox://styles/mapbox/light-v9', | |
zoom: 20, | |
center: [-73.95185028352992, 40.711077039996724] | |
}); | |
// const baseUrl = "https://pr-968.liveapp.com/"; | |
const baseUrl = "http://localhost:3000/"; | |
function getCallouts(value, start, finish, map, tagIds, venueId){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/callouts?clientVersion=${encodeURIComponent("consumer#1.0")}`; | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
start = moment(start); | |
finish = moment(finish); | |
url += `&events.occurrences.start=${start.format()}&events.occurrences.finish=${finish.format()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
url += `&firstVenueId=${venueId}`; | |
url += `&limit=10`; | |
$.ajax(url, { | |
'success': function(response){ | |
debugger; | |
const venue = response.items[0]; | |
let html = `${venue.resolvedName}`; | |
if (venue.highlights && venue.highlights.length > 0){ | |
html += '<ul>'; | |
venue.highlights.forEach(function(highlight){ | |
if(highlight.type === 'event'){ | |
html += `<li>${highlight.item.name}</li>`; | |
} | |
}); | |
html += '</ul>'; | |
} | |
html += '<ul>'; | |
response.items.slice(1).forEach(function(venue){ | |
html += `<li>next: ${venue.resolvedName}`; | |
if (venue.highlights && venue.highlights.length > 0){ | |
html += '<ul>'; | |
venue.highlights.forEach(function(highlight){ | |
if(highlight.type === 'event'){ | |
html += `<li>${highlight.item.name}</li>`; | |
} | |
}); | |
html += '</ul>'; | |
} | |
html += '</li>'; | |
}); | |
html += '</ul>'; | |
// Populate the popup and set its coordinates | |
// based on the feature found. | |
new mapboxgl.Popup() | |
.setLngLat([venue.geometry.coordinates[0], venue.geometry.coordinates[1]]) | |
.setHTML(html) | |
.addTo(map); | |
} | |
}) | |
} | |
function makeLegend(value, start, finish, map, tagIds){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/legend?clientVersion=${encodeURIComponent("consumer#1.0")}` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
start = moment(start); | |
finish = moment(finish); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
$.ajax(url, { | |
'success': function(response){ | |
$('#tags').empty(); | |
if (response.selectedTags) { | |
const selectedTags = response.selectedTags.items; | |
selectedTags.forEach(function(tag){ | |
const li = $(`<li class="active">${tag.name}: ${tag.useCount || "-"}</li>`); | |
li.on("click", function(){ | |
const inTagIds = _.indexOf(oldTagIds, tag.id) !== -1; | |
if(inTagIds){ | |
oldTagIds = _.without(oldTagIds, tag.id); | |
$(li).removeClass('active'); | |
}else{ | |
oldTagIds.push(tag.id); | |
$(li).addClass('active'); | |
} | |
swapSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
return $('#tags').append(li); | |
}); | |
} | |
const tags = response.tags.items; | |
tags.forEach(function(tag){ | |
const li = $(`<li>${tag.name}: ${tag.useCount}</li>`); | |
li.on("click", function(){ | |
const inTagIds = _.indexOf(oldTagIds, tag.id) !== -1; | |
if(inTagIds){ | |
oldTagIds = _.without(oldTagIds, tag.id); | |
$(li).removeClass('active'); | |
}else{ | |
oldTagIds.push(tag.id); | |
$(li).addClass('active'); | |
} | |
swapSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
return $('#tags').append(li); | |
}); | |
} | |
}); | |
} | |
function makeAggregates(value, start, finish, map, tagIds){ | |
const bounds = map.getBounds(); | |
const ne = bounds.getNorthEast().toArray(); | |
const sw = bounds.getSouthWest().toArray(); | |
var url = `${baseUrl}browse/aggregates?clientVersion=${encodeURIComponent("consumer#1.0")}` | |
start = moment(start); | |
finish = moment(finish); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
url += `&eventsOccurrencesStart=${start.toJSON()}&eventsOccurrencesFinish=${finish.toJSON()}` | |
url += `&ne=${ne.join(",")}&sw=${sw.join(",")}`; | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
$.ajax(url, { | |
'success': function(response){ | |
$('#aggregates').html(`${response.venueCount} venues`); | |
} | |
}); | |
} | |
function makeSearch(value, start, finish, tagIds){ | |
var url = `${baseUrl}browse/tiles/{z}/{x}/{y}.pbf?clientVersion=${encodeURIComponent("consumer#1.0")}&debugTiles=true` | |
if(value !== "" && value.length >= 3){ | |
url += "&query="+value | |
} | |
start = moment(start).startOf('hour'); | |
finish = moment(finish).startOf('hour'); | |
url += `&highlights.start=${start.format()}&highlights.finish=${finish.format()}` | |
url += `&aggregateThreshold=100` | |
tagIds.forEach(function(tagId){ | |
url += `&tagIds=${tagId}`; | |
}); | |
map.addSource("live-venues", { | |
type: 'vector', | |
"tiles": [url] | |
}); | |
const genreColors = { | |
property: 'genre', | |
type: 'categorical', | |
stops: [ | |
['misc', '#22364D'], | |
['municipal', '#737780'], | |
['service', '#A3846A'], | |
['none', '#FFFFFF'], | |
['lodging', '#C2574E'], | |
['body', '#F77CC6'], | |
['homeAndHobby', '#FF8F33'], | |
['activity', '#4CCF78'], | |
['groups', '#9BC2A2'], | |
['food', '#17C2E8'], | |
['essentials', '#3D87FF'], | |
['drinks', '#772EE6'], | |
['style', '#FABF0F'] | |
] | |
}; | |
const circleRadius = { | |
"base": 1, | |
"stops": [ | |
[5, 1], | |
[8, 1], | |
[9, 1.25], | |
[11, 1.5], | |
[12, 2], | |
[13, 2], | |
[14, 2], | |
[15, 2], | |
[16, 2.5], | |
[17, 2.8], | |
[18, 3], | |
[19, 3.5], | |
[20, 4], | |
[21, 5] | |
] | |
}; | |
if(showAggregates){ | |
map.addLayer({ | |
"id": "aggregate-dots-layer", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "aggregates", | |
"paint": { | |
"circle-radius": circleRadius, | |
'circle-stroke-width': { | |
property: 'hasEvent', | |
stops: [ | |
[0, 0], | |
[1, 2] | |
] | |
}, | |
'circle-stroke-color': '#000000', | |
'circle-color': '#ff0000', | |
'circle-color': genreColors | |
} | |
}); | |
} | |
map.addLayer({ | |
"id": "debugTiles", | |
"type": "line", | |
"source": "live-venues", | |
"source-layer": "debugTiles", | |
"layout": {}, | |
'paint': { | |
'line-color': '#ff0000', | |
'line-opacity': 0.8, | |
'line-width': 3 | |
} | |
}); | |
if(showCache){ | |
map.addLayer({ | |
"id": "skinnyVenues", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "skinnyVenues", | |
"layout": {}, | |
"paint": { | |
"circle-color": genreColors, | |
"circle-radius": circleRadius | |
} | |
}); | |
} | |
// map.addLayer({ | |
// "id": "geohashDebug", | |
// "type": "line", | |
// "source": "live-venues", | |
// "source-layer": "aggregatesDebug", | |
// "layout": {}, | |
// 'paint': { | |
// 'line-color': '#000000', | |
// 'line-opacity': 0.2, | |
// 'line-width': 1 | |
// } | |
// }); | |
if(showVenues){ | |
// map.addLayer({ | |
// "id": "venue-labels-layer", | |
// "type": "symbol", | |
// "source": "live-venues", | |
// "source-layer": "venues", | |
// "layout": { | |
// "text-field": "{name}", | |
// "text-size": 14, | |
// "text-offset": [0, -1], | |
// "text-max-width": 15 | |
// } | |
// }); | |
map.addLayer({ | |
"id": "venue-dots-layer", | |
"type": "circle", | |
"source": "live-venues", | |
"source-layer": "venues", | |
'paint': { | |
'circle-radius': circleRadius, | |
'circle-stroke-width': { | |
property: 'hasEvent', | |
stops: [ | |
[0, 0], | |
[1, 2] | |
] | |
}, | |
'circle-stroke-color': '#000000', | |
'circle-color': genreColors | |
} | |
}); | |
} | |
} | |
function swapSearch(value, start, finish, tagIds){ | |
map.removeSource('live-venues'); | |
map.removeLayer('venue-labels-layer'); | |
map.removeLayer('venue-dots-layer'); | |
makeSearch(value, start, finish, tagIds); | |
} | |
Date.prototype.toDateInputValue = (function() { | |
var local = new Date(this); | |
local.setMinutes(this.getMinutes() - this.getTimezoneOffset()); | |
return local.toJSON().slice(0,16); | |
}); | |
var oldQuery = ""; | |
var oldStart = new Date(); | |
var oldFinish = new Date(oldStart); | |
oldFinish.setMinutes(oldFinish.getMinutes() + 180); | |
var oldTagIds = []; | |
document.addEventListener('DOMContentLoaded', function(){ | |
var search = document.getElementById("name-search"); | |
search.addEventListener('keyup', function(){ | |
if(search.value.length < 3 && oldQuery.length < 3){ | |
return | |
} | |
swapSearch(search.value, oldStart, oldFinish, oldTagIds); | |
makeLegend(search.value, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(search.value, oldStart, oldFinish, map, oldTagIds); | |
oldQuery = search.value; | |
}); | |
var startInput = document.getElementById("start"); | |
start.value = oldStart.toDateInputValue(); | |
startInput.addEventListener('keyup', function(){ | |
let start = new Date(startInput.value); | |
let finish = new Date(startInput.value); | |
finish.setMinutes(finish.getMinutes() + 90); | |
swapSearch(oldQuery, start, finish, oldTagIds); | |
makeLegend(oldQuery, start, finish, map, oldTagIds); | |
makeAggregates(oldQuery, start, finish, map, oldTagIds); | |
oldStart = start; | |
oldFinish = finish; | |
}); | |
map.on('load', function () { | |
makeSearch(oldQuery, oldStart, oldFinish, oldTagIds); | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
map.on('moveend', function() { | |
makeLegend(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
makeAggregates(oldQuery, oldStart, oldFinish, map, oldTagIds); | |
}); | |
map.on('click', function (e) { | |
var features = map.queryRenderedFeatures(e.point, { layers: ['venue-dots-layer'] }); | |
if (!features.length) { | |
return; | |
} | |
// console.log("features", features); | |
features.map(function(feature){ | |
console.log("feature", feature.properties); | |
}) | |
var feature = features[0]; | |
getCallouts(oldQuery, oldStart, oldFinish, map, oldTagIds, feature.properties.id); | |
}); | |
}); | |
map.addControl(new mapboxgl.NavigationControl()); | |
window.map = map; | |
window.parent.map = map; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment