From 4782eff0ec0c8a7c8baf899a1f41e5023ed614fd Mon Sep 17 00:00:00 2001 From: Alex Richey Date: Mon, 20 Apr 2026 15:20:25 -0400 Subject: [PATCH 1/6] fix water tz lots --- .../transitzone/_transitzone_models.yml | 3 +++ .../transitzone/int_pluto__transitzone.sql | 18 +++++++++++++++--- .../transitzone/int_tz__union_coverage.sql | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql diff --git a/products/pluto/models/intermediate/transitzone/_transitzone_models.yml b/products/pluto/models/intermediate/transitzone/_transitzone_models.yml index 506c6a4811..ce625bb175 100644 --- a/products/pluto/models/intermediate/transitzone/_transitzone_models.yml +++ b/products/pluto/models/intermediate/transitzone/_transitzone_models.yml @@ -4,6 +4,9 @@ models: - name: int_tz__atomic_geoms description: Decomposed transit zone multipolygons into atomic parts for performance + - name: int_tz__union_coverage + description: Union of all transit zones (excluding Beyond the Greater Transit Zone) for identifying lots outside coverage + - name: int_tz__tax_blocks description: Tax blocks split into sub-blocks with BBL assignments diff --git a/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql b/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql index 386a74247c..c092838dbb 100644 --- a/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql +++ b/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql @@ -8,6 +8,7 @@ -- Final transit zone assignment per BBL -- Uses block-level for unambiguous blocks, lot-level for ambiguous ones +-- Nulls out transit zones for lots in water (outside all transit zone coverage) WITH assignments AS ( -- Block-level assignments for non-ambiguous blocks @@ -35,9 +36,20 @@ WITH assignments AS ( transit_zone FROM {{ ref('int_tz__bbl_to_tz_ranked') }} WHERE tz_rank = 1 +), + +lots_in_coverage AS ( + SELECT p.bbl + FROM {{ target.schema }}.pluto AS p + INNER JOIN {{ ref('int_tz__union_coverage') }} AS tz + ON ST_INTERSECTS(p.geom, tz.geom) ) SELECT - bbl, - transit_zone AS trnstzone -FROM assignments + a.bbl, + CASE + WHEN lic.bbl IS NOT NULL THEN a.transit_zone + ELSE NULL + END AS trnstzone +FROM assignments AS a +LEFT JOIN lots_in_coverage AS lic ON a.bbl = lic.bbl diff --git a/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql b/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql new file mode 100644 index 0000000000..0033105788 --- /dev/null +++ b/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql @@ -0,0 +1,14 @@ +{{ + config( + materialized='table', + indexes=[{'columns': ['geom'], 'type': 'gist'}], + tags=['pluto_enrichment'] + ) +}} + +-- Union of all transit zones to identify land coverage +-- Lots outside this union are in water and should have NULL transit zones + +SELECT + ST_UNION(geom) AS geom +FROM {{ ref('stg__dcp_transit_zones') }} From 169d1c8b7343d932fc84f38e075c1d9696d788d7 Mon Sep 17 00:00:00 2001 From: Alex Richey Date: Mon, 20 Apr 2026 15:20:49 -0400 Subject: [PATCH 2/6] Update contributor docs --- docs/CONTRIBUTING.md | 1 + docs/dbt/project_conventions.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 357174b55c..7e95166c98 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -9,6 +9,7 @@ Terse reference for agents working in this codebase. ### dbt - [dbt project conventions](./dbt/project_conventions.md) +- **If adding a dbt model, read the conventions doc above first** ### Frontend/Products - [apps, glossary, and environment setup](./products/README.md) diff --git a/docs/dbt/project_conventions.md b/docs/dbt/project_conventions.md index cc09337d9a..77e3667573 100644 --- a/docs/dbt/project_conventions.md +++ b/docs/dbt/project_conventions.md @@ -1,3 +1,4 @@ + # DBT Project Conventions Standard conventions for all dbt projects in this repository. @@ -21,6 +22,9 @@ Final tables ready for export. ## Model Configuration +## Adding New Models +When adding a new .sql file, also check whether you need to add an accompanying models yml file. + ### Materialization - `staging/`: `view` (default) unless indexes are required - `intermediate/`: `table` with appropriate indexes From c675b203b77d4fddde9fd2cf00b3035357e2a3ca Mon Sep 17 00:00:00 2001 From: Alex Richey Date: Mon, 20 Apr 2026 16:21:28 -0400 Subject: [PATCH 3/6] Add Jack's research input --- products/pluto/seeds/pluto_input_research.csv | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/products/pluto/seeds/pluto_input_research.csv b/products/pluto/seeds/pluto_input_research.csv index cfd877db22..0aab8c1b5e 100644 --- a/products/pluto/seeds/pluto_input_research.csv +++ b/products/pluto/seeds/pluto_input_research.csv @@ -27526,3 +27526,10 @@ bbl,field,old_value,new_value,Type,reason,version 4033307501,unitstotal,135,40,2,PTS error - units,26v1 2028507501,unitsres,31,103,2,pluto_rpad_geo,26v1 2028507501,unitstotal,32,104,2,PTS error - units,26v1 +1007660030,unitsres,59,20,2,PTS error – units,26v1 +1015550046,unitsres,56,18,2,PTS error – units,26v1 +4001517502,unitsres,100,10,2,PTS error – units,26v1 +3032657503,unitsres,64,8,2,PTS error – units,26v1 +4004317501,unitsres,55,28,2,PTS error – units,26v1 +1015550046,unitsres,56,18,2,PTS error – units,26v1 +1007660030,unitsres,59,20,2,PTS error – units,26v1 From 2115b21f8b1cc9dbfc7d723e6bab3bc396bc21b4 Mon Sep 17 00:00:00 2001 From: Alex Richey Date: Tue, 21 Apr 2026 16:04:29 -0400 Subject: [PATCH 4/6] Pin Versions for this build --- products/pluto/recipe.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/products/pluto/recipe.yml b/products/pluto/recipe.yml index f88badcb11..16db2e858e 100644 --- a/products/pluto/recipe.yml +++ b/products/pluto/recipe.yml @@ -43,6 +43,10 @@ inputs: - name: lpc_historic_districts - name: lpc_landmarks - name: pluto_input_cama_dof + version: 20260302 - name: pluto_input_geocodes + version: 20260330 - name: pluto_input_numbldgs + version: 20260329 - name: pluto_pts + version: 20260330 From 9910b79cbfe6bfe6d0cd9619be3d5ae4416aa500 Mon Sep 17 00:00:00 2001 From: Alex Richey Date: Wed, 22 Apr 2026 11:23:01 -0400 Subject: [PATCH 5/6] Move shape area and leng to end of exports --- products/pluto/pluto_build/sql/export_mappluto_gdb.sql | 6 +++--- products/pluto/pluto_build/sql/export_mappluto_shp.sql | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/products/pluto/pluto_build/sql/export_mappluto_gdb.sql b/products/pluto/pluto_build/sql/export_mappluto_gdb.sql index 2e67a85e36..47d6c5be78 100644 --- a/products/pluto/pluto_build/sql/export_mappluto_gdb.sql +++ b/products/pluto/pluto_build/sql/export_mappluto_gdb.sql @@ -92,8 +92,6 @@ SELECT a.latitude AS "Latitude", a.longitude AS "Longitude", a.notes AS "Notes", - round(st_length(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Leng", - round(st_area(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Area", st_makevalid(b.:GEOM) AS geom, a.mih_opt1 AS "MIHOption1", a.mih_opt2 AS "MIHOption2", @@ -101,7 +99,9 @@ SELECT a.mih_opt4 AS "MIHOption4", a.trnstzone AS "TrnstZone", a.affresfar AS "AffResFAR", - a.mnffar AS "ManuFAR" + a.mnffar AS "ManuFAR", + round(st_length(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Leng", + round(st_area(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Area" INTO :TABLE FROM export_pluto AS a, pluto_geom AS b WHERE diff --git a/products/pluto/pluto_build/sql/export_mappluto_shp.sql b/products/pluto/pluto_build/sql/export_mappluto_shp.sql index 3073830826..a943db440d 100644 --- a/products/pluto/pluto_build/sql/export_mappluto_shp.sql +++ b/products/pluto/pluto_build/sql/export_mappluto_shp.sql @@ -92,8 +92,6 @@ SELECT a.latitude AS "Latitude", a.longitude AS "Longitude", a.notes AS "Notes", - round(st_length(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Leng", - round(st_area(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Area", st_makevalid(b.:GEOM) AS geom, a.mih_opt1 AS "MIHOption1", a.mih_opt2 AS "MIHOption2", @@ -101,7 +99,9 @@ SELECT a.mih_opt4 AS "MIHOption4", a.trnstzone AS "TrnstZone", a.affresfar AS "AffResFAR", - a.mnffar AS "ManuFAR" + a.mnffar AS "ManuFAR", + round(st_length(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Leng", + round(st_area(b.:GEOM)::numeric, 11)::numeric(19, 7) AS "Shape_Area" INTO :TABLE FROM export_pluto AS a, pluto_geom AS b WHERE From 508722c3db7a041e80a8c98a67700bd72628108d Mon Sep 17 00:00:00 2001 From: Alex Richey Date: Thu, 23 Apr 2026 11:08:59 -0400 Subject: [PATCH 6/6] appease the fluff --- .../models/intermediate/transitzone/int_pluto__transitzone.sql | 1 - .../models/intermediate/transitzone/int_tz__union_coverage.sql | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql b/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql index c092838dbb..c9a7582999 100644 --- a/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql +++ b/products/pluto/models/intermediate/transitzone/int_pluto__transitzone.sql @@ -49,7 +49,6 @@ SELECT a.bbl, CASE WHEN lic.bbl IS NOT NULL THEN a.transit_zone - ELSE NULL END AS trnstzone FROM assignments AS a LEFT JOIN lots_in_coverage AS lic ON a.bbl = lic.bbl diff --git a/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql b/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql index 0033105788..08ff6a7951 100644 --- a/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql +++ b/products/pluto/models/intermediate/transitzone/int_tz__union_coverage.sql @@ -9,6 +9,5 @@ -- Union of all transit zones to identify land coverage -- Lots outside this union are in water and should have NULL transit zones -SELECT - ST_UNION(geom) AS geom +SELECT ST_UNION(geom) AS geom FROM {{ ref('stg__dcp_transit_zones') }}