Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Build files
## Build files
*/Data/_Processed/

# random stuff that's too big or unneeded to push
Expand Down Expand Up @@ -55,5 +55,10 @@ backend/logger/*.log
out/
dist/
backend/Data/Census/**/*.csv
backend/Data/_Processed/parcels/
**/.jupyter_cache/
backend/notebooks/**/*.html
backend/notebooks/**/*_files/
backend/notebooks/**/*.ipynb

tmp/
2 changes: 2 additions & 0 deletions backend/api/routes/post_routes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from .post_cdc import router as post_cdc_router
from .post_census import router as post_census_router
from .post_export import router as post_export_router
from .post_parcels import router as post_parcels_router
from .post_qcew import router as post_qcew_router
from .post_zoning import router as post_zoning_router
from .post_wastewater import router as post_wastewater_router
Expand All @@ -14,4 +15,5 @@
post_wastewater_router,
post_export_router,
post_cdc_router,
post_parcels_router,
]
14 changes: 14 additions & 0 deletions backend/api/routes/post_routes/post_parcels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from fastapi import APIRouter, Response

from api.core_functions import request_to_source
from api.models import FilterRequest
from query.parcels import get_parcels_geojson

router = APIRouter()


@router.post("/load/mapping/parcels")
async def read_parcels(request: FilterRequest):
source = request_to_source(request, "parcels_info", "default")
data = get_parcels_geojson([source])
return Response(content=data, media_type="application/json")
9 changes: 8 additions & 1 deletion backend/api/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@
"Prevalence Measure": "Data_Value_Type"
}
},
"parcels_info": {
"join_key": "OBJECTID",
"join_type": "inner",
"columns": {
"Town": "TOWN",
"Category": "CAT",
"Property Type": "PROPTYPE",
"soil_suitability_info_soil_suit": {
"join_key": "ID",
"join_type": "inner",
Expand Down Expand Up @@ -87,4 +94,4 @@
}
}
}
}
}}}
3 changes: 2 additions & 1 deletion backend/build/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Runs all the build scripts one after the other.
"""

from build import FIPS_data, acs5, cdc, wastewater, zoning
from build import FIPS_data, acs5, cdc, parcels, wastewater, zoning


def main():
Expand All @@ -17,6 +17,7 @@ def main():
# information here" layer subtracts the districts from -- so it runs first.
FIPS_data.main()
zoning.main()
parcels.main()
wastewater.main()


Expand Down
94 changes: 94 additions & 0 deletions backend/build/parcels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"""
**Author**:
Isaac Wedaman
**Created**:
2026-07-23
**Description**:
Build script to convert the CDC-places csv data into a single vermont-based SQL table.
"""

from pathlib import Path

from build import BACKEND, CON

data_directory = Path("Data")
parcels_fgb = Path("Data/parcels/parcels_f.fgb")
parcel_path = data_directory / "parcels" / "parcels_vermont.geojson"


proc_dir = BACKEND / "Data" / "_Processed" / "parcels"
TABLES = ["geom", "info"]
INFO_COLS = [
"OBJECTID",
"SPAN",
"CAT",
"RESCODE",
"PARCID",
"CITYGL",
"TOWN",
"ZIPGL",
"PROPTYPE",
"DESCPROP",
"SOURCENAME",
"YEAR",
"ACRESGL",
"REAL_FLV",
"HSTED_FLV",
"IMPRV_LV",
]


def load_dataset():
if not parcels_fgb.exists():
CON.execute(f"""
COPY (
SELECT * FROM ST_Read('{parcel_path}')
WHERE geom IS NOT NULL
)
TO '{parcels_fgb}' (FORMAT GDAL, DRIVER 'FlatGeobuf')
""")
CON.execute(
"CREATE OR REPLACE VIEW parcels_raw AS SELECT * FROM ST_Read('Data/Parcels/parcels_f.fgb')"
)

CON.execute("""
CREATE OR REPLACE VIEW final_view AS
SELECT
* EXCLUDE (TOWN),
UPPER(TOWN) AS TOWN,
FROM parcels_raw;
""")


def load_geom():
CON.execute("""
CREATE OR REPLACE VIEW geom AS
SELECT OBJECTID, geom FROM final_view
""")


def load_info():
CON.execute("""CREATE OR REPLACE VIEW info AS
SELECT OBJECTID, SPAN, CAT, RESCODE, PARCID, CITYGL, TOWN, ZIPGL, PROPTYPE, DESCPROP, SOURCENAME, YEAR,
ACRESGL, REAL_FLV, HSTED_FLV, IMPRV_LV
FROM final_view""")


def final_writing():
path = Path("Data/_Processed/parcels")
path.mkdir(parents=True, exist_ok=True)
for item in ["info", "geom"]:
CON.execute(
f"COPY (SELECT * FROM {item}) TO '{path / f'{item}.parquet'}' (FORMAT PARQUET)"
)


def main():
load_dataset()
load_geom()
load_info()
final_writing()


if __name__ == "__main__":
main()
Loading
Loading