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