Skip to content

Instantly share code, notes, and snippets.

Chris Whong chriswhong

View GitHub Profile
@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 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
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
chriswhong / README.md
Created Feb 27, 2018
Consuming USGS OrthoImagery in MapboxGL
View README.md

MapboxGL Layer Definition for consuming tiles from the USGS Imagery MapServer

{
  id: 'usgs-aerials',
  type: 'raster',
  source: {
    type: 'raster',
    tiles: [
      'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}',
    ],
@chriswhong
chriswhong / geosupport-autocomplete.md
Last active Nov 6, 2017
An autocomplete web API for geosupport
View geosupport-autocomplete.md

Problem

DCP maintains geosupport, the city's official geocoder, which can be accessed by using the libraries directly, or via various client-facing application/services including GOAT, GeoClient, GeoBat, etc.

The NYC Planning Labs team would like to incorporate geosupport results into web mapping applications, but geosupport's architecture does not work well with the "autocomplete" search style that is popular in modern web applications. Traditionally, to use geosupport, the user must provide at least a house number, street name, and borough, and will either git a hit, or a list of possible alternatives.

Below we propose some high-level specifications for a GeoSupport Autocomplete Web API that would be useful for search in modern web applications.

A Model to Emulate: Mapzen Search's Autocomplete API

Mapzen Search has an autocomplete API, which is well-documente, open source, and provides the type of experience developers want in a modern g

@chriswhong
chriswhong / README.md
Created Aug 8, 2017
A Vector Tile microservice for MapPLUTO (or any other data)
View README.md

Background

We like building mapping applications with carto as the backend, because it gets us an instant map tiler and SQL API. However, carto's tiler is raster-based, and we would like to take advantage of mapboxGL for it's vector-based rendering. We discovered an undocumented vector tile endpoint in carto, which has enabled us to use vector tiles without any additional work

Problem

Using the undocumented MVT API has worked well enough to date, but when faced with a dataset with lots of very small contiguous polygons, the tiler seems to choke at low zoom levels, and does not include all data that should be rendered in a tile.

Solution

We have contemplated setting up a microservice to serve vector tiles of MapPLUTO, either cutting static tiles, or using some other tile server.

TileStrata is a good candidate for this task. It's an extensible nodejs-based tile server.

You can’t perform that action at this time.