Add US Census Bureau layers
This commit is contained in:
parent
77ff710b0d
commit
0b88a77b15
38
layers/census-bureau/README.md
Normal file
38
layers/census-bureau/README.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
from the US Census Bureau:
|
||||
|
||||
https://www.census.gov/geographies/mapping-files/time-series/geo/cartographic-boundary.html
|
||||
|
||||
more description here:
|
||||
|
||||
https://www.census.gov/programs-surveys/geography/technical-documentation/naming-convention/cartographic-boundary-file.html
|
||||
|
||||
Including the following:
|
||||
|
||||
> # File Naming Convention
|
||||
> ## 2013 to Present Files
|
||||
>
|
||||
> The cartographic boundary files are named cb_yyyy_ss_<entity>_rr.zip where:
|
||||
>
|
||||
> * yyyy = 4 digit year
|
||||
> * ss = state FIPS code or 'us' for a national level file
|
||||
> * entity = the entity name
|
||||
> * rr = resolution level
|
||||
> * 500k = 1:500,000
|
||||
> * 5m = 1:5,000,000
|
||||
> * 20m = 1:20,000,000
|
||||
|
||||
I prefer the KML options when available since OpenLayers doesn't [citation
|
||||
needed?] have built-in support for shapefiles (.shp)? That said, we also do
|
||||
transform KML to GeoJSON to be able to edit more easily (and it's sometimes good
|
||||
for a smaller file size).
|
||||
|
||||
For more information, see e.g.:
|
||||
|
||||
https://indicatrix.org/post/shapefiles-in-openlayers/
|
||||
|
||||
Census Bureau data appears to be using a different (US-centric, possibly?)
|
||||
projection; this may require more work to be accurate going forward.
|
||||
|
||||
https://gis.stackexchange.com/a/310949
|
||||
|
||||
https://epsg.io/4269
|
47
layers/census-bureau/cleanup_data.py
Normal file
47
layers/census-bureau/cleanup_data.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import json
|
||||
|
||||
with open(sys.argv[1]) as f:
|
||||
data = json.load(f)
|
||||
|
||||
# {
|
||||
# "type": "FeatureCollection",
|
||||
# "name": "cb_2022_us_county_20m",
|
||||
# "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
|
||||
# "features": [
|
||||
# {
|
||||
# "type": "Feature",
|
||||
# "properties": {
|
||||
# "Name": "<at><openparen>Autauga<closeparen>",
|
||||
# "Description": "<center><table><tr><th colspan='2' align='center'><em>Attributes</em></th></tr><tr bgcolor=\"#E3E3F3\"> <th>STATEFP</th> <td>01</td> </tr><tr bgcolor=\"\"> <th>COUNTYFP</th> <td>001</td> </tr><tr bgcolor=\"#E3E3F3\"> <th>COUNTYNS</th> <td>00161526</td> </tr><tr bgcolor=\"\"> <th>AFFGEOID</th> <td>0500000US01001</td> </tr><tr bgcolor=\"#E3E3F3\"> <th>GEOID</th> <td>01001</td> </tr><tr bgcolor=\"\"> <th>NAME</th> <td>Autauga</td> </tr><tr bgcolor=\"#E3E3F3\"> <th>NAMELSAD</th> <td>Autauga County</td> </tr><tr bgcolor=\"\"> <th>STUSPS</th> <td>AL</td> </tr><tr bgcolor=\"#E3E3F3\"> <th>STATE_NAME</th> <td>Alabama</td> </tr><tr bgcolor=\"\"> <th>LSAD</th> <td>06</td> </tr><tr bgcolor=\"#E3E3F3\"> <th>ALAND</th> <td>1539631461</td> </tr><tr bgcolor=\"\"> <th>AWATER</th> <td>25677536</td> </tr></table></center>"
|
||||
# },
|
||||
# "geometry": {
|
||||
# "type": "Polygon",
|
||||
# "coordinates": [
|
||||
# [
|
||||
# [
|
||||
# -86.917595,
|
||||
# 32.664169,
|
||||
# 0.0
|
||||
# ],
|
||||
# ...
|
||||
# ]
|
||||
# ]
|
||||
# }
|
||||
# },
|
||||
# [...]
|
||||
# ]
|
||||
# }
|
||||
|
||||
# len("<at><openparen>") == 15
|
||||
# len("<closeparen>") == 12
|
||||
# "<at><openparen>Autauga<closeparen>"[15:-12] == "Autauga"
|
||||
|
||||
for feature in data['features']:
|
||||
# del feature['properties']['Description']
|
||||
feature['properties']['Name'] = feature['properties']['Name'][15:-12]
|
||||
|
||||
with open(sys.argv[1], 'w') as f:
|
||||
json.dump(data, f)
|
17
layers/census-bureau/get_data.sh
Executable file
17
layers/census-bureau/get_data.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
for resolution in 20m 5m; do
|
||||
curl --silent --remote-name https://www2.census.gov/geo/tiger/GENZ2022/shp/cb_2022_us_county_${resolution}.zip
|
||||
unzip cb_2022_us_county_${resolution}.zip
|
||||
ogr2ogr -f GeoJSON us-counties-${resolution}.geojson cb_2022_us_county_${resolution}.shp
|
||||
sed -i '/^"crs":/d' us-counties-${resolution}.geojson # TODO: handle this projection properly
|
||||
rm cb_2022_us_county_${resolution}.*
|
||||
# python cleanup_data.py us-counties-${resolution}.geojson # Only needed for KML files
|
||||
done
|
||||
|
||||
curl --silent --remote-name https://www2.census.gov/geo/tiger/GENZ2022/shp/cb_2022_us_unsd_500k.zip
|
||||
unzip cb_2022_us_unsd_500k.zip
|
||||
ogr2ogr -f GeoJSON us-school-districts.geojson cb_2022_us_unsd_500k.shp
|
||||
sed -i '/^"crs":/d' us-school-districts.geojson # TODO: handle this projection properly
|
||||
rm cb_2022_us_unsd_500k.*
|
||||
# TODO: some kind of cleanup to save space?
|
63
layers/census-bureau/index.js
Normal file
63
layers/census-bureau/index.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
import GeoJSON from 'ol/format/GeoJSON.js';
|
||||
import VectorLayer from 'ol/layer/Vector.js';
|
||||
import VectorSource from 'ol/source/Vector.js';
|
||||
|
||||
import counties20m from './us-counties-20m.geojson?url';
|
||||
import counties5m from './us-counties-5m.geojson?url';
|
||||
import schoolDistricts from './us-school-districts.geojson?url';
|
||||
|
||||
import { Fill, Stroke, Style, Text } from 'ol/style.js';
|
||||
|
||||
function style(feature){
|
||||
return new Style({
|
||||
text: new Text({
|
||||
text: feature.get('NAME'),
|
||||
}),
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,255,255,0.4)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#3399CC',
|
||||
width: 1.25,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
const layers = {
|
||||
name: "US Census Bureau Data",
|
||||
layers: [
|
||||
{
|
||||
name: "All Counties (2022; low-res)",
|
||||
layer: new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: counties20m,
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: style,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "All Counties (2022; medium-res)",
|
||||
layer: new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: counties5m,
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: style,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "School Districts (2022; unreasonably large)",
|
||||
layer: new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: schoolDistricts,
|
||||
format: new GeoJSON(),
|
||||
// TODO: this probably uses projection 'EPSG:4326'
|
||||
}),
|
||||
style: style,
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default layers;
|
|
@ -7,6 +7,7 @@ import amtrakLayer from './amtrak/layer.js';
|
|||
import arenasLayer from './nhl-arenas/layer.js';
|
||||
import bikepackingLayer from './bikepacking/layer.js';
|
||||
import chains from './chains/index.js';
|
||||
import census_bureau from './census-bureau/index.js';
|
||||
|
||||
const layerCategories = [
|
||||
{ // Base maps
|
||||
|
@ -70,7 +71,8 @@ const layerCategories = [
|
|||
},
|
||||
]
|
||||
},
|
||||
chains
|
||||
chains,
|
||||
census_bureau,
|
||||
];
|
||||
|
||||
export default layerCategories;
|
||||
|
|
Loading…
Reference in a new issue