Skip to content

Instantly share code, notes, and snippets.

Chris Whong chriswhong

Block or report user

Report or block chriswhong

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View keybase.md

Keybase proof

I hereby claim:

  • I am chriswhong on github.
  • I am cwhong (https://keybase.io/cwhong) on keybase.
  • I have a public key ASCScIKKKJdJewGrjgHOzYmnx7P7j7d2Bxdxs4E3qVopBQo

To claim this, I am signing this object:

@chriswhong
chriswhong / README.md
Last active May 30, 2019
Clickable Markers in MapboxGL
View README.md

This example shows how to extend mapboxGL's Marker class to add custom functionality on click.

Why?

MapboxGL has a very convenient Marker class that can be used to quickly get markers on the map with a few lines of code (versus the more complex method of adding sources and layers). They behave a bit differently from the rest of the map features because they are actually HTML elements overlaid on the map canvas.

The stock markers are great, and they are SVG so you can color them by passing in a color option! However, the only interactivity you can easily set up is a popup. When you google 'clickable markers', the examples you find are all using symbol layers with queryRenderedFeatures.

I wanted to trigger navigation in a single page app using the stock Markers and determined a simple extension of the class would help me accomplish this. You can also see these markers in action at https://paintthetown.chriswhong.com

@chriswhong
chriswhong / scrape.js
Created Apr 22, 2019
Decrypting Amtrak's real-time train location geoJSON feed
View scrape.js
// decrypting Amtrak's real-time train location geoJSON feed
// based on https://github.com/Vivalize/Amtrak-Train-Stats
const fetch = require('node-fetch');
const CryptoJS = require('crypto-js');
// this is the xhr call done by https://www.amtrak.com/track-your-train.html containing encrypted train location data
const dataUrl = 'https://maps.amtrak.com/services/MapDataService/trains/getTrainsData';
// these constants are pulled from RoutesList.v.json, which is an object with keys 'arr', 's', and 'v'
const sValue = '9a3686ac'; // found at s[8]
@chriswhong
chriswhong / Maputnik.png
Last active Feb 7, 2019
Custom buffersize param on carto maps api tile instantiation
@chriswhong
chriswhong / sparklines.js
Last active Dec 3, 2018
Creating weekly commit sparklines using JQuery and D3.js
View sparklines.js
$.getJSON('https://home-api.planninglabs.nyc/github/repo-activity', (labsData) => {
const yMax = d3.max(labsData, d => d3.max(d.data, e => e.total));
labsData
.sort(function(a, b) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
@chriswhong
chriswhong / maputnik-push.js
Last active Feb 13, 2019
Push any mapboxGL map style to maputnik using planning labs' maputnik-push service
View maputnik-push.js
// this will only work if window.map === your mapboxgl map instance
// we usually set window.map = map in the callback using map.on('style.load', function () { ... })
fetch('https://maputnik-push.planninglabs.nyc/style', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(window.map.getStyle()),
@chriswhong
chriswhong / chart.js
Last active Jul 27, 2018
A D3 Stacked Bar Chart showing NYC Planning Labs' Weekly Commits on Major Projects between July 2017 and July 2018
View chart.js
// based on https://bl.ocks.org/mbostock/3886208
const svg = d3.select('svg');
const margin = {
top: 20, right: 20, bottom: 100, left: 40,
};
@chriswhong
chriswhong / gist:11e2b2d68505e239f89f46e36aaa03d2
Created Jul 20, 2018
Convenience Redirect in express.js. Build URLs using a known unique id
View gist:11e2b2d68505e239f89f46e36aaa03d2
const express = require('express');
const router = express.Router();
router.get('/:ulurpnumber', async (req, res) => {
const { app, params } = req;
const { ulurpnumber } = params;
// find projectid for this ceqrnumber
// http://localhost:3000/projects/ulurp/170358ZMM
@chriswhong
chriswhong / downloadroute.js
Created Jul 10, 2018
Streaming from ps-promise to json2csv to express response
View downloadroute.js
// This code queries postgresql and streams the results into a csv
// Works like a charm for a download button, no hangup for large files!
const Json2csvTransform = require('json2csv').Transform;
const QueryStream = require('pg-query-stream');
const JSONStream = require('JSONStream');
router.get('/download.csv', async (req, res) => {
const { query } = req;
@chriswhong
chriswhong / gist:762ceac7fb8a1420e7e7adceb770b707
Last active Sep 18, 2018
Using ST_AsMVT() and ST_AsMVTGeom() in express to build a vector tile endpoint
View gist:762ceac7fb8a1420e7e7adceb770b707
/* GET /tiles/:z/:x/:y.mvt */
/* Retreive a vector tile by tileid */
router.get('/tiles/:z/:x/:y.mvt', async (req, res) => {
const { z, x, y } = req.params;
// calculate the bounding polygon for this tile
const bbox = mercator.bbox(x, y, z, false);
// Query the database, using ST_AsMVTGeom() to clip the geometries
// Wrap the whole query with ST_AsMVT(), which will create a protocol buffer
You can’t perform that action at this time.