Skip to content

Instantly share code, notes, and snippets.

Chris Whong chriswhong

View GitHub Profile
chriswhong / RadiusMode.js
Created Mar 1, 2018
RadiusMode, a custom mode for mapbox-gl-draw for drawing a radius
View RadiusMode.js
// custom mapbopx-gl-draw mode that modifies draw_line_string
// shows a center point, radius line, and circle polygon while drawing
// forces draw.create on creation of second vertex
import MapboxDraw from 'mapbox-gl-draw';
import numeral from 'numeral';
import lineDistance from 'npm:@turf/line-distance';
const RadiusMode = MapboxDraw.modes.draw_line_string;
chriswhong / gist:ff86b482273ce20cc8dc2391a6b30c4c
Created May 11, 2020
Pulling a Qri versioned dataset from the distributed web into a pandas dataframe (python)
View gist:ff86b482273ce20cc8dc2391a6b30c4c
# an example of pulling in a CSV string from a local qri repo,
# and parsing it into a dataframe with pandas.read_csv()
import pandas as pd
import subprocess
from io import StringIO
# this Qri class should eventually have all the methods we would need for reading,
# writing, pushing, pulling, committing, etc.
class Qri:
chriswhong / index.html
Last active Apr 12, 2020
D3 Sankey Link with Variable Width
View index.html
<!DOCTYPE html>
<meta charset="utf-8">
<title>Variable Width Sankey Link</title>
path {
fill: steelblue;
chriswhong / gist:93ed4660ff23fdf483b41654290f0b18
Created Apr 7, 2020
Socrata Download URL generates different files when accessed multiple times
View gist:93ed4660ff23fdf483b41654290f0b18
## Problem
When troubleshooting another bug at, we noticed that hitting the same download URL from the NYC Open Data portal (powered by Socrata) generated csv files with different md5 hashes. This was causing our version control software to consider the csv "changed". On further investigation, the actual data was the same, but the ordering of the rows was different. This is likely due to the fact that the files are being generated on the fly from a database query (PostgreSQL in the case of Socrata open data portals) returning unpredictable row orders when no `ORDER BY` is specified in the query.
To reproduce:
- curl the same download URL several times and save to csv, such as this one for popular baby names:
$curl > 0.csv
$curl > 1.csv
chriswhong / convert csv with WKT to GeoJson
Last active Mar 5, 2020
How to parse a CSV with a well-known text geometry column and convert to geojson FeatureCollection with the 'wellknown' package
View convert csv with WKT to GeoJson
// Use papa parse to download and parse a CSV
Papa.parse('data/nyc_zoning_lots.csv', {
download: true,
header: true,
complete: ({ data }) => {
// transform array of objects to geojson FeatureCollection
const FC = {
type: 'FeatureCollection',
features: => { // map csv rows to geojson features
const geometry = wellknown.parse(row.geom) // WKT to geojson geometry
chriswhong /
Created Feb 28, 2020
Using ogr2ogr to load a CSV into Postgres

The absolute easiest way to get a CSV into a postgresql table is to use ogr2ogr with AUTODETECT_TYPE=YES.

I learned a while back that this is what cartoDB uses to import your CSV into postgis (with a lot of other parameters added)

ogr2ogr -f PostgreSQL PG:"host=localhost user=postgres dbname=postgres password=password"  docs.csv -oo AUTODETECT_TYPE=YES
chriswhong / Qmf6Vfs78CeKHsWus2gXjBkvha93acBXN3FB7DtEFha4oj.csv
Created Jan 23, 2020
NYC Plaza Program Sites from Qri Dataset chriswhong/nyc_plaza_program_sites@/ipfs/Qmf6Vfs78CeKHsWus2gXjBkvha93acBXN3FB7DtEFha4oj.csv
View Qmf6Vfs78CeKHsWus2gXjBkvha93acBXN3FB7DtEFha4oj.csv
We can make this file beautiful and searchable if this error is corrected: It looks like row 5 should actually have 13 columns, instead of 9. in line 4.
Albee Square Plaza,BK02,,C,25200,Dekalb Ave,Bond Street,Fulton Mall,Fulton Mall Improvement Association,,-73.983171,40.689973,
Ave C Plaza,BK12,,D,5600,McDonald Ave,Avenue C,Church Ave,Kensington Stewards,,-73.979094,40.640571,
Brooklyn Plaza,BK02,,B,50000,Jay Street,High Street,Manhattan Bridge,DOT,,-73.986569,40.699203,
Cadman Plaza East,BK02,,,,Cadman Plaza East,Tillary St,Johnson St,Down
chriswhong / gist:762ceac7fb8a1420e7e7adceb770b707
Last active Jan 13, 2020
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
chriswhong / index.html
Last active Sep 9, 2019
Qri blob loading spinner prototype
View index.html
<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/ >
<title>Qri Loading Spinner Prototype</title>
<script src=""></script>
<!-- jQuery -->
<script src=""></script>
<!-- Bootstrap 3 -->
chriswhong /
Last active Sep 8, 2019
Run open trip planner docker container for NYC

This set of commands is for setting up an open trip planner instance for New York City. OTP requires GTFS data and OSM streets data to build a graph, which it uses for trip planning.

Lucky for us, someone here dockerhub has left a nice CLI command to build the graph and run the container, but we need to get the data first.

The data are downloaded on the host machine. For me, this is a digitalocean droplet running ubuntu 14.

First, get GTFS for the New York City Subway from the MTA's downloads page: wget Next, get OSM city extract for NYC. Thanks Mapzen!

Finally, run the following docker command: docker run -it -v $(pwd):/var/otp/graphs opentripplanner/opentripplanner --build /var/otp/graphs --analyst

You can’t perform that action at this time.