Code
## Set Up
library(sf)
library(tidyverse)
library(readxl)
library(leaflet)
library(here)
Kate Phan
May 4, 2023
ma_towns <- readxl::read_excel("towns.xlsx") |>
janitor::clean_names() |>
mutate(
zip_filename = basename(shapefile_download_url),
local_zip_filename = fs::path(cache_dir, zip_filename),
in_cache_dir = FALSE,
is_unzipped = FALSE
)
## Function to download zip files for specific towns
download_town <- function(town_db, towns) {
town_db |>
filter(town_name %in% towns) |>
filter(!in_cache_dir) |>
select(x = shapefile_download_url, y = local_zip_filename) |>
purrr::pwalk(function(x, y) download.file(url = x, destfile = y))
}
## download files for towns
towns <- "NORTHAMPTON"
download_town(ma_towns, towns)
safe_unzip_one <- function(path_zip) {
if (!file.exists(path_zip)) {
return(NA)
}
path_zip |>
unzip(exdir = cache_dir) |>
dirname() |>
unique()
}
safe_unzip <- function(path_zip) {
path_zip |>
purrr::map_chr(safe_unzip_one)
}
## query the cache
update_cache <- function(town_db) {
zipped <- fs::dir_ls(cache_dir, type = "file", regexp = "*.zip")
unzipped <- fs::dir_ls(cache_dir, type = "directory", regexp = "L3*")
message("Updating town cache information...")
town_db |>
mutate(
in_cache_dir = local_zip_filename %in% zipped,
dsn = safe_unzip(local_zip_filename),
is_unzipped = dsn %in% unzipped
)
}
ma_towns <- update_cache(ma_towns)
## read town parcel shapefiles
read_town_parcels <- function(dsn) {
if (!file.exists(dsn)) {
return(NA)
}
parcel_layers <- dsn |>
st_layers() |>
pluck("name")
parcel_layer_name <- parcel_layers |>
str_subset("TaxPar")
assess_layer_name <- parcel_layers |>
str_subset("Assess")
parcels <- dsn |>
st_read(layer = parcel_layer_name) |>
st_transform(4326)
assess <- dsn |>
st_read(layer = assess_layer_name)
parcels |>
left_join(assess, by = c("LOC_ID"))
}
## noho
noho <- ma_towns |>
filter(town_name == "NORTHAMPTON") |>
pull(dsn) |>
read_town_parcels() %>%
mutate(FullAdd = paste(ADDR_NUM, FULL_STR, sep = " "))
Reading layer `M214TaxPar_CY22_FY23' from data source
`/tmp/RtmpYjyNjv/L3_SHP_M214_Northampton' using driver `ESRI Shapefile'
Simple feature collection with 10692 features and 12 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 97757.07 ymin: 893258.2 xmax: 110641.8 ymax: 903377.7
Projected CRS: NAD83 / Massachusetts Mainland
Reading layer `M214Assess_CY22_FY23' from data source
`/tmp/RtmpYjyNjv/L3_SHP_M214_Northampton' using driver `ESRI Shapefile'
## Plot
## Red parcels are recently bought land, which have already been applied for building permits
## Blue parcels are properties sold by John Handzel/Nu-Way Homes
col <- colorFactor(
c("#0571b0", "#ca0020"),
domain = nuway_df$Type
)
nuway_plot <- nuway_df %>%
mutate(
popup = case_when(Type == "GR" ~ paste0(
"Address: ", FullAdd, "</br>",
"Date of Land Purchase: ", parcel_purchase_date, "</br>",
"Land Value: $", parcel_price, "k","</br>",
"Number of units built: ", num_unit, "</br>",
"Date of Sale: ", DateSold, "</br>",
"Price of House Sold: $", format(round(Value)), "k", "</br>",
"Time between land purchase and house sale: ", difference, " months"
), TRUE ~ paste0(
"Address: ", FullAdd, "</br>",
"Date of Land Purchase: ", DateSold, "</br>",
"Land Value: $", Value , "k","</br>",
"Status: Applied for construction permit"
)
)) %>%
leaflet() %>%
addTiles() %>%
addPolygons(popup = ~popup, fillColor = ~col(Type), fillOpacity = 10, weight = 0.5,
highlightOptions = highlightOptions(color="white", weight= 3, bringToFront = TRUE))
nuway_plot
I created an interactive map displaying data from 32 land parcels Nu-Way Homes Inc. purchased in Northampton from 2017 till present. 21 parcels have been reconstructed, listed and sold on William Raveis website. Out of 21, only 3 homes were sold at prices under $350k, the rest ranging from $420k to $785k.
Most importantly, from 2017 to 2021, Nu-Way Homes Inc. constructed and sold 12 houses in the neighborhood, while only using land from 5 parcels. This map makes it easy to locate the properties, especially the ones that were split and built on the same piece of land but have completely different addresses.
For example, Nu Way bought the 18000-square-feet parcel of land on 291 Riverside Dr in March 2021 for $651K. Within one year, a property with the same address 291 Riverside Dr was sold for $450K, as recorded by Massachusetts Property Tax Parcels. Fast forward 8 months later, another property on 8 Liberty St was sold by John Handzel (Nu-Way’s CEO) for $725K while no records show that he or his company ever bought any parcels of land on that street. It turns out that 8 Liberty St property is actually a part of the 291 Riverside Dr land parcel that Handzel bought in March 2021.
The map includes data on Nu-Way’s sold properties as well as recently purchased land parcels. Red parcels are purchased land parcels that have not been listed on the market yet, more than half of these have applied for construction permits and some applied to build 2 housing units on the same parcel. There are 11 red parcels, equivalent to 3.7 acres of land. The map might be a useful tool for Northampton locals, reporters or readers who are curious about Handzel’s next moves. Data used for this map has been cleaned and cross-checked with deed records from previous owners.