Create a GeoJSON file of Voronoi polygons with d3

There are many examples showing how to use d3 to create voronoi polygons but I haven't seen anything describing how to use d3-voronoi and write the result as a GeoJSON file, which I found myself wanting to do recently.

I started with a shapefile from SANDAG with neighborhood boundaries. Confusingly, this dataset is in their "law" folder and is called "SDPD_BEATS.shp". Taxonomies, am I right? The shapefile has polygons in state plane and I needed points in WGS84 (because I want a GeoJSON file in WGS84). To get there, I used a series of commands:

Get the spatial reference info using gdalsrsinfo so that the shapefile can be projected to WGS84:

~/data/san-diego-neighborhoods$ gdalsrsinfo SDPD_BEATS.prj

PROJ.4 : '+proj=lcc +lat_1=32.78333333333333 +lat_2=33.88333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000 +y_0=500000.0000000001 +datum=NAD83 +units=us-ft +no_defs '

OGC WKT :  
PROJCS["NAD_1983_StatePlane_California_VI_FIPS_0406_Feet",  
    GEOGCS["GCS_North_American_1983",
        DATUM["North_American_Datum_1983",
            SPHEROID["GRS_1980",6378137.0,298.257222101]],
        PRIMEM["Greenwich",0.0],
        UNIT["Degree",0.0174532925199433]],
    PROJECTION["Lambert_Conformal_Conic_2SP"],
    PARAMETER["False_Easting",6561666.666666666],
    PARAMETER["False_Northing",1640416.666666667],
    PARAMETER["Central_Meridian",-116.25],
    PARAMETER["Standard_Parallel_1",32.78333333333333],
    PARAMETER["Standard_Parallel_2",33.88333333333333],
    PARAMETER["Latitude_Of_Origin",32.16666666666666],
    UNIT["Foot_US",0.3048006096012192]]

Reproject (the -s_srs value came from the output of gdalsrsinfo):

~/data/san-diego-neighborhoods$ ogr2ogr -f "ESRI Shapefile" sd-neighborhoods-wgs84.shp SDPD_BEATS.shp -s_srs '+proj=lcc +lat_1=32.78333333333333 +lat_2=33.88333333333333 +lat_0=32.16666666666666 +lon_0=-116.25 +x_0=2000000 +y_0=500000.0000000001 +datum=NAD83 +units=us-ft +no_defs ' -t_srs EPSG:4326

Convert the re-projected shapefile to geojson:

~/data/san-diego-neighborhoods$ shp2json sd-neighborhoods-wgs84.shp -o sd-neighborhoods.json

Point to polygon with mapshaper:

~/data/san-diego-neighborhoods$ mapshaper sd-neighborhoods.json -points inner -o sd-neighborhood-points.json

GUI GIS programs do this stuff easily, but it's not as self-documenting or easily scriptable as command line utilities.

Now that there is a GeoJSON file with one point per neighborhoood, I could get back to the original objective.

Grab a copy of d3-voronoi:

npm i d3-voronoi  

Then use it in a script:

fc.js and poly.js provide the expected GeoJSON structure (if I were doing more than scratching an itch, I'd probably use the equivalent turf modules).

To use d3-voronoi to create a set of polygons, the code first loops through the points and finds the minimum and maximum latitude and longitudes. That's use as the extent or bounding box for the resulting polygons.

Line 37 is the actual call to tell d3 to build the shapes from the neighborhood points.

Once polygons are available, they're assembled into a GeoJSON feature collection and written to a file.

With a file on disk, the handy geojsonio package can pipe it to geojson.io: