Last active
January 11, 2024 12:33
-
-
Save clhenrick/5787a12a8bf3b02821839e4f9556d997 to your computer and use it in GitHub Desktop.
Node.JS script to aggregate NYC vehicle collision data into a hexagonal grid and compute the ck means for each cell using Turf.JS and Simple Statistics.JS
This file contains 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
node_modules/ | |
.DS_Store |
This file contains 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
// load libraries | |
const fs = require("fs") | |
const turf = require("turf") | |
const turfMeta = require("@turf/meta") | |
const simpleStats = require("simple-statistics") | |
const d3 = require("d3-array") | |
// load our data | |
const data = require("./nyc_crashes.json") | |
// rough geographic bounding box of NYC | |
const bbox = [ -74.24939, 40.50394, -73.701195, 40.90995 ] | |
// size in kilometers we want each side of our hex grids | |
const cellSize = 0.5 | |
// create the hexbin geometry for the given bbox and cell resolution | |
const hexGrid = turf.hexGrid(bbox, cellSize) | |
// perform a "spatial join" on our hexGrid geometry and our crashes point data | |
const collected = turf.collect(hexGrid, data, "cartodb_id", "values") | |
// get rid of polygons with no joined data, to reduce our final output file size | |
collected.features = collected.features.filter(d => d.properties.values.length) | |
// count the number of crashes per hexbin | |
turfMeta.propEach(collected, props => { | |
props.count = props.values.reduce((acc, cur) => acc += 1, 0) | |
}) | |
// reduce our count values to a new array of numbers | |
const reduced = turfMeta.featureReduce(collected, (acc, cur) => { | |
acc.push(cur.properties.count) | |
return acc | |
}, []) | |
// compute the ckMeans binning for data into 7 classes from reduced values | |
const ck = simpleStats.ckmeans(reduced, 7) | |
// tack on the bin number to our data, as well as its min and max values | |
turfMeta.propEach(collected, props => { | |
ck.forEach((bin, index) => { | |
if (bin.indexOf(props.count) > -1) { | |
props.bin = index | |
props.binVal = d3.extent(bin) | |
} | |
}) | |
}) | |
// remove the "values" property from our hexBins as it's no longer needed | |
turfMeta.propEach(collected, props => { | |
delete props.values | |
}) | |
// write output data | |
fs.writeFileSync("./processed.json", JSON.stringify(collected)) |
View raw
(Sorry about that, but we can’t show files that are this big right now.)
View raw
(Sorry about that, but we can’t show files that are this big right now.)
View raw
(Sorry about that, but we can’t show files that are this big right now.)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment