<code>
library(tidyverse)
library(httr)
library(rvest)
library(VancouvR)
<- here::here("data/pplos")
pplos_cache_path if (!dir.exists(pplos_cache_path)) dir.create(pplos_cache_path)
Jens von Bergmann
MountainMath
Nathan Lauster
UBC Sociology
August 29, 2025
Too much data, too little time
Mountain Doodles is an insomnia driven side project, born out of random questions, trying to give partial answers through data. During daytime at MountainMath.
(Joint with Nathan Lauster and cross-posted at HomeFreeSociology)
From books to blog posts, we’ve long been on the record advocating for reforms to the regulation of low-density urban lots, enabling more people to share less land (e.g. (Lauster 2016; Dahmen, von Bergmann, and Das 2018; von Bergmann and Lauster 2021, 2025)). On all of the lots zoned to protect single-family detached housing - North America’s “Great House Reserve” - the most obvious reform has been to enable multiple families to divide up space instead. Reforms changing low-density zoning to enable duplex, triplex, and increasingly multiplex running to 4-6 units per lot or beyond, all seem like easy solutions to housing shortages. Vancouver was an early leader in many of these reforms via enabling secondary suite and laneway houses, but recently it seems like it is falling behind, even after a much touted shift to the R1-1 zone putatively allowing multiplexes across most of the urban landscape. As it turns out, housing regulation has grown quite complicated, and restrictions on the number of dwellings per lot aren’t the only things holding back additional housing on low-density lots. When it comes to enabling multiplexes, the devil is in the details. In this post, we first step outside of Vancouver to highlight some of our recent research into the details of multiplex reforms elsewhere in BC, and then return to the City to see how multiplex are faring locally.
Working together with colleagues, we explored the current progress and future potential of various multiplex reforms across BC on behalf of the province. We noted that two communities, Kelowna and Coquitlam, upzoned about 800 single family parcels to allow four-plexes, Kelowna in 2016 and Coquitlam in 2019. We investigated the outcomes of this upzoning for our 2023 modelling report for the provincial Small Scale Multi-Unit Housing (SSMUH) legislation. (von Bergmann et al. 2023) While these two upzonings looked quite similar on paper, they had quite different outcomes. This observation underlines the difficulty in modelling outcomes of the provincial legislation insofar as they left implementation details up to municipalities. We added very strong caveats throughout the analysis that our report assumed faithful implementation not just of the broad parameters of the legislation but also the full intent.
Subsequently, we felt that it would be worthwhile to turn the sections on Kelowna and Coquitlam into a more formal study to further quantify the effects of the two upzonings and turn this into a paper, which just came out. (von Bergmann et al. 2025) This more formally quantifies the ways in which these two reforms that look very similar on paper differ in real word outcomes.
At a high level the impact of the multiplex zoning changes in these cities can be seen in Figure 1, which shows the annual number of SFH, Duplex, Triplex and Fourplex dwelling units completed in the upzoned area as well as several “control” areas for each of the two cities.
The reasons for the difference in outcomes are complex, and we don’t have a full understanding. The biggest difference that we suspect matters here is that Kelowna focused on fast permit times, setting up pre-approved (outright) designs with very short permit times, and relatively fast permit times for general applications with different designs. One detail here is that the design competition for the fast-tracked pre-approved designs required architects to work in conjunction with developers to ensure that there was interest to actually build these. By contrast with Kelowna’s fast-tracking, permit times in Coquitlam were significantly longer, involving detailed conditional review and introducing significant risk into the development process that small builders are often ill equipped to handle.
Another difference was parking requirements, with Coquitlam requiring two parking spaces per unit while Kelowna only required one. Minimum lot width in both Kelowna and Coquitlam guaranteed that there was enough space for four parking spaces, and Coquitlam allowed the two parking spaces for each unit to be stacked, so the outer car would have to get moved in order for the inner car to get in or out. This seems like a drag, but we don’t believe parking requirements strongly constrained the number of lots where four-plexes could physically be built. Rather the Coquitlam requirements may have significantly constrained the design of four-plexes and degraded the usable outdoor space. Could be an issue, but probably not as big a deal as the permitting process.
The biggest takeaway of our comparative research is that the details of multiplex reforms matter, particularly as they apply to simplifying the process for developers, reducing timelines and providing certainty to outcomes. So let’s return to the City of Vancouver’s reform!
The province drew upon our research in formulating its Small Scale Multi Unit Housing (SSMUH) reforms, mandating all municipalities allow multiplex on previously single-family lots (as of November 2023). The City of Vancouver was working on its own multiplex reform, and snuck under the wire by passing a bylaw that reclassified single-family lots to multiplex in October of 2023, just before the lots at issue would have come under provincial regulation.1 We take this as an occasion to take stock of how Vancouver multiplexes have fared so far. We don’t have enough data to do a thorough analysis like we did for Kelowna and Coquitlam, but there is enough to take a preliminary look.
Prior to the multiplex legislation Vancouver allowed three units on most single family lots at 0.85 FSR under single ownership or up to four units structured as two strata lots with a main unit and a lock-off suite each for a combined 0.7 FSR. The multiplex legislation allowed for more freedom on how to configure units and increased the allowable density to 1 FSR. However, going beyond duplex and additions to floor space both remained conditional uses rather than outright, requiring contributions of various sorts to the City and close planner review. Contributions to the City were subjected to value capture analysis intended to balance out construction of multiplex with single detached and duplex. Subsequently the bylaw has been amended to allow up to six units in frequent transit areas as well as an expansion of the area that allows for multiplex as required by provincial SSMUH legislation. Of note, the density requirements remain far below the provincial guidelines of an implicit 1.5 to 1.6 FSR despite being in one of the the highest demand areas in the province.
get_plpos_data_for_range <- function(start_date,end_date,cache_path=tempdir(),permit_type=NULL, refresh=FALSE) {
url <- "https://plposweb.vancouver.ca/Public/Default.aspx?PossePresentation=PermitSearchByDate"
hash <- digest::digest(paste0(url,"-",start_date,"-",end_date,"-",permit_type))
cache_file <- file.path(cache_path,paste0("pplos_",hash,".rds"))
if (file.exists(cache_file) && !refresh) {
return(read_rds(cache_file))
}
datachanges <- paste0("'AP0pCEcP9fH5dRPaDCclXjvW/RWG6DuU1GJqdoYCJdeMEyQgezIdkf31vuOO6FHEH8/cUCRQrVyF1WbfAGq8Y/T9t4QFxQutWcQbJVh9WHzZCVQ7Zpc6O75JEskEPmBFKDdtN0yeAWQB0yz6jVU1Yc8hGYZMN/whBxaSFWd5K6Zxe7JaoDMkr7AMmQw58VwFKYfL2AI7D4EPpAw98aeD/JCbWPGBB2DrVpwBAnIK6UTqiFwKdpteDDJp54Xpxn6dY3U2WldqXWhkTkpvRlhlYQ%3D%3D'",",",
"('C','S0',972146,'",start_date," 00:00:00')",",",
"('C','S0',984849,'",end_date," 00:00:00')",",")
if (!is.null(permit_type)) {
datachanges <- paste0(datachanges,"('C','S0',1039023,'",permit_type,"')",",")
}
datachanges <- paste0(datachanges,
"('C','S0',972146,'",start_date," 00:00:00')",",",
"('C','S0',984849,'",end_date," 00:00:00')",",",
"('F','ext-gen1009',0,0)")
result <- httr::POST(url, body = list(datachanges = datachanges,
currentpaneid= 1018439,
functiondef= 5,
comesfrom= "posse",
sortcolumns= "{}",
paneid= 987904),
encode = "form")
if (result$status_code != 200) {
stop("Failed to fetch data")
}
content <- httr::content(result)
# data <- html_table(content, fill = TRUE)[[1]]
table <- content |>
rvest::html_node("table")
header <- table|> html_nodes("th.possegrid") |>
html_text()
if (length(header)==0) {
message("No data found: ",start_date," - ",end_date)
return (NULL)
}
header[1]="X"
data <- table |>
html_nodes("tbody") |>
map_df(\(tb){
d<-tb |> html_nodes("td.possegrid") |>
html_text() |>
as.character() |>
setNames(header) |>
enframe() |>
pivot_wider() |>
mutate(url=tb |> html_nodes("a") |> html_attr("href"))
}) |>
mutate(across(matches("Date"),\(x)gsub(".+\\n","",x) |>
as.Date(format="%B %d, %Y"))) |>
select(-X)
write_rds(data,cache_file)
data
}
get_detail_plpos_data <- function(url,cache_path=tempdir(),refresh=FALSE) {
hash <- digest::digest(url)
cache_file <- file.path(cache_path,paste0("pplos_",hash,".rds"))
if (file.exists(cache_file) && !refresh) {
return(read_rds(cache_file))
}
html<-read_html(url)
tables <- html_table(html)
zoning_table <- map_df(tables, \(tb){
r <- NULL
if (ncol(tb)>=2 && nrow(tb)>=1 && !is.na(tb[1,2]) && tb[1,2]=="Zoning Code") {
r <- tb |> select(-1) |>
setNames(c("name","value")) |>
filter(name!="") |>
filter(!duplicated(name,value)) |>
pivot_wider()
}
r
})
# sanity check
if ("Zoning Code" %in% names(zoning_table) && is.list(zoning_table$`Zoning Code`)) {
print(url)
}
details <- html |> html_nodes("span.possedetail")
detailsg <- html |> html_nodes("span.possegrid")
wd <- which(grepl("WorkDescription",details |> html_attr("id")))
wt <- which(grepl("TypeOfWork",details |> html_attr("id")))
wpid <- which(grepl("ParcelID",detailsg |> html_attr("id")))
wfolio <- which(grepl("FormattedAccountNumber",details |> html_attr("id")))
# permit_status <- html |> html_nodes("div.permitStatusDisplay") |> html_text()
dd<-tibble(`Work Description`=details[wd] |> html_text(),
`Type of Work`=details[wt] |> html_text(),
PID=paste0(detailsg[wpid] |> html_text(),collapse = ", "),
Folio=paste0(detailsg[wpid] |> html_text(),collapse = ", "))
if (nrow(zoning_table)>0) {
dd <- dd |> bind_cols(zoning_table)
}
dd<- dd |> mutate(url=url)
write_rds(dd,cache_file)
dd
}
start_date <- as.Date("2023-10-01") # date permit data seems to start in the system
end_date <- as.Date("2025-08-27") # Sys.Date()
dp_data <- seq(start_date,end_date,by="1 month") |>
map_dfr(\(d){
get_plpos_data_for_range(start_date=d,
end_date=d %m+% months(1),
cache_path = pplos_cache_path,
permit_type="Development Permit")
}) |>
unique()
bp_data <- seq(start_date,end_date,by="1 month") |>
map_dfr(\(d){
#if (strftime(d,"%m")=="01") print(paste0("Starting ",d))
get_plpos_data_for_range(start_date=d,
end_date=d %m+% months(1),
cache_path = pplos_cache_path,
permit_type="Building Permit")
}) |>
unique()
recent_dp_details <- dp_data |>
filter(`Created Date`>=as.Date('2023-10-17')) %>%
left_join(.$url |> map_df(\(x){
get_detail_plpos_data(x,cache_path=pplos_cache_path)
},.progress=TRUE), by="url")
recent_bp_details <- bp_data |>
filter(`Created Date`>=as.Date('2023-10-17')) %>%
left_join(.$url |> map_df(\(x){
get_detail_plpos_data(x,cache_path=pplos_cache_path)
},.progress=TRUE), by="url")
multiplexes_dp <- recent_dp_details |>
filter(grepl("multiplex",`Work Description`,ignore.case = TRUE),
`Zoning Code`=="R1-1",
`Type of Work`=="New Building")
multiplexes_bp <- recent_bp_details |>
filter(grepl("multiplex",`Work Description`,ignore.case = TRUE),
#`Zoning Code`=="R1-1",
`Type of Work`=="New Building")
status_levels <- c("Created","In Review","Preparing Recommendation",
"Response to Conditions","Approved Subject to Conditions",
"Stop Work",
"Ready For Issue","Issued", "Completed")
pd <- multiplexes_dp |>
bind_rows(multiplexes_bp |>
filter(PID %in% multiplexes_dp$PID)) %>%
mutate(PID=factor(PID,levels=filter(.,Type=="Development Permit") |>
arrange(`Created Date`) |> pull(PID) |> unique())) |>
mutate(min_date=min(`Created Date`),
max_date=pmax(max(`Created Date`),
max(`Issue Date`,na.rm=TRUE),
max(`Completed Date`,na.rm=TRUE)),
.by=PID) |>
mutate(Status=factor(Status,levels=status_levels))
permit_colours <- setNames(RColorBrewer::brewer.pal(9,"Set1") |> rev(),status_levels)
status_counts <- pd |>
select(Type,Status,PID) |>
distinct() |>
count(Type,Status)
So far in Vancouver there have been 429 development permit applications for multiplexes, of which 143 have been issued (or completed) and subsequently 123 building permits have been issued (or completed).2 Table Table 1 table gives a more detailed breakdown.
Type | Status | Number of multiplexes |
---|---|---|
Development Permit | In Review | 45 |
Development Permit | Preparing Recommendation | 2 |
Development Permit | Response to Conditions | 168 |
Development Permit | Approved Subject to Conditions | 71 |
Development Permit | Issued | 137 |
Development Permit | Completed | 6 |
Building Permit | In Review | 114 |
Building Permit | Stop Work | 5 |
Building Permit | Ready For Issue | 1 |
Building Permit | Issued | 119 |
Building Permit | Completed | 4 |
Our data does not come with clean unit counts, a scan of permit detail descriptions indicates that a little below half of multiplex applications are for fourplexes, with the next popular configuration being triplexes at around 30%.
Figure 2 shows how multiplex applications have been progressing.
fit.dp <- lm(rank ~ `Created Date`, data= pd |>
filter(Type=="Development Permit") |>
arrange("Created Date") |>
mutate(rank=row_number()))
slope.dp <- coefficients(fit.dp)[2] |> as.numeric()
eligible_zones <- c("R1-1","RT-7","RT-9","FSD")
eligible_parcels <- aggregate_cov_data("property-tax-report",
where="tax_assessment_year='2025'",
group_by='zoning_district') |>
filter(zoning_district %in% c(eligible_zones)) |>
pull(count) |>
sum()
pd |>
ggplot(aes(y=PID,shape=Type,colour=Status)) +
geom_point(data=~mutate(.,Status=if_else(is.na(`Issue Date`),"Created",Status)) |>
mutate(Status=factor(Status,levels=status_levels)),
aes(x=`Created Date`)) +
geom_point(data=~filter(.,!is.na(`Issue Date`)) |> mutate(Status = recode(Status, "Completed"="Issued")),
aes(x=`Issue Date`)) +
geom_point(data=~filter(.,!is.na(`Completed Date`)),aes(x=`Completed Date`)) +
geom_segment(aes(x=min_date,xend=max_date,yend=PID),linewidth =0.25,linetype="dashed",colour="black") +
theme(axis.text.y = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
axis.ticks.y = element_blank()) +
scale_colour_manual(values=permit_colours,breaks=names(permit_colours) |> rev()) +
scale_shape_manual(values=c(21,16),breaks=c("Development Permit","Building Permit")) +
scale_x_date(date_breaks = "1 month",date_labels = "%b") +
labs(y=NULL,x=NULL,title="Multiplex Development Permits in the City of Vancouver",
caption="Data: PLPOS")
Starting the clock in November of 2023, development permit applications are coming in at an average pace of 23 per month so far, or about 273 per year, almost double of the 150 applications a year that Vancouver staff originally projected. Translated into a redevelopment rate of the roughly 69,000 eligible single family parcels in Vancouver this means that at the current rate each parcel has about a 0.4% percent chance of redevelopment each year, about double what Coquitlam saw after their upzoning but less than a tenth Kelowna’s outcomes.
Figure 3 shows the distribution of permitting timelines, from creating of the development permit to issuance of building permit, conditioning on having an issued building permit. The right-censored nature of the data makes it difficult to give definitive statements about permit times, a strong lower bound on permit times derived from is 350 days, with a wide distribution ranging from very fast permit times of 200 days at the low end and over 500 days at the high end so far.
Figure 4 shows permit timelines ordered by creation data, with blank lines where building permits have not yet been issued.
permit_levels <- c("Development permit","Development permit (Pending)","Parallel development/building permit","Application gap","Building permit","Building permit (Pending)")
pd |>
summarize(`Created Date`=first(`Created Date`),`Issue Date`=last(`Issue Date`),
last_type=first(Type,order_by=Type),
.by=c(PID)) |>
mutate(PID=fct_reorder(PID,`Created Date`)) |>
mutate(Days=`Issue Date`-`Created Date`) |>
mutate(Days=ifelse(last_type=="Development Permit",NA,Days)) |>
ggplot(aes(y=PID,x=Days)) +
geom_bar(stat="identity",data=~mutate(.,Days=coalesce(Days,0))) +
theme(axis.text.y = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
axis.ticks.y = element_blank()) +
geom_vline(aes(xintercept=mean(Days,na.rm=TRUE)),colour="red") +
labs(title="Permit time for multiplexes",
y=NULL,
x="Number of days from DP application created in the system until BP issued",
caption="Data: PLPOS")
A naive interpretation might suggest that permit times are decreasing, but it would be foolish to conclude that from this graph. The blank spaces of projects that have not yet received a building permit highlight the right-censored nature of the data and signal projects with outstanding permits that, once they get issues, will necessarily have longer permit times than nearby (in terms of creation date) permit applications that have already been issued building permits. Vancouver council’s 3-3-3-1 Permit Approval Framework, which suggests that multiplex permits should be given in 3 weeks, is clearly not working yet, and there is no strong indication of improvement in multiplex permitting timelines.
Figure 5 offers a view into the landscape of low-density development in the R1-1, RT-7, RT-9, and FSD zones that legalized multiplexes by tracking issued building permits for single family, duplex, and multiplexes by year the permit was issued.
zoning <- get_cov_data("zoning-districts-and-labels")
zoning_mask <- zoning |> filter(zoning_district %in% eligible_zones)
building_permits <- get_cov_data("issued-building-permits",
where="typeofwork='New Building' AND propertyuse = 'Dwelling Uses'") |>
sf::st_filter(zoning_mask) |>
filter(issuedate <= as.Date("2025-08-28")) # pin end date
processed_permits_raw <- building_permits |>
filter(permitcategory %in% c('New Build - Low Density Housing','New Build - Standalone Laneway') |
permitnumber %in% multiplexes_bp$Number) |>
mutate(use=case_when(permitnumber %in% multiplexes_bp$Number ~ "Multiplex",
specificusecategory %in% c("Laneway House","Duplex") ~ specificusecategory,
specificusecategory %in% c("Single Detached House w/Sec Suite","1FD w/ Family Suite","Principal Dwelling Unit w/Lock Off","Secondary Suite,Single Detached House w/Sec Suite","Single Detached House w/Sec Suite,Single Detached House") ~ "SFH w/Sec Suite",
specificusecategory %in% c("Single Detached House") ~ "SFH",
specificusecategory %in% c("Duplex w/Secondary Suite","Duplex w/Secondary Suite,Secondary Suite","Duplex,Lock -off Unit","Secondary Suite,Duplex w/Secondary Suite","Duplex,Secondary Suite","Lock -off Unit,Duplex","Lock -off Unit,Duplex w/Secondary Suite","Duplex w/Secondary Suite,Lock -off Unit","Duplex,Lock -off Unit,Secondary Suite") ~ "Duplex w/Sec Suite",
TRUE ~ "Other")) %>%
sf::st_transform(mountainmathHelpers::lambert_conformal_conic_at(.))
processed_permits <- processed_permits_raw |>
filter(use != "Laneway House") |>
sf::st_join(processed_permits_raw |>
filter(use == "Laneway House") |>
select(LW_issueyear=issueyear) |>
sf::st_buffer(5)) |>
mutate(wLW=!is.na(LW_issueyear) & as.integer(issueyear)-as.integer(LW_issueyear) <=2 & as.integer(issueyear)-as.integer(LW_issueyear) >=0) |>
mutate(use=case_when(wLW & use=="SFH" ~ "SFH w/LWH",
wLW & use=="SFH w/Sec Suite" ~ "SFH w/Sec Suite & LWH",
TRUE ~ use)) |>
mutate(use=factor(use,levels=c("SFH","SFH w/Sec Suite","SFH w/LWH","SFH w/Sec Suite & LWH","Duplex","Duplex w/Sec Suite","Multiplex","Other")))
processed_permits |>
filter(use!="Other") |>
mutate(issueyear=recode(issueyear,"2025"="2025\n(up to Aug)")) |>
ggplot(aes(x=issueyear,fill=fct_rev(use))) +
geom_bar() +
scale_fill_brewer(palette="Dark2") +
labs(title = "Building permits for new buildings in area eligible for multiplexes since Oct 2023",
x="Year permit was issued",y="Number of issued building permits",
fill="Project type",
caption="Data: CoV Open Data")
We see the shift away from almost exclusive single family housing (though often suited and some with laneway houses3) towards more duplexes and multiplexes, but the overall number of low-density building permits has not increased substantially. The multiplex reform has – by design – not led to a significant increase in the overall rate of redevelopment of low-density lots.
So far results from Vancouver’s multiplex reform appear to fall somewhere between Kelowna’s and Coquitlam’s. To be sure, new multiplex have entered the pipeline, but their progress has been stalled by permitting review. Developers continue to fall back on dwelling types (single-family house and duplex) offering less relief for housing shortages but enabled by outright approval processes, as well as those including secondary suites requiring conditional approval processes, but where developers have more experience and certainty working through permitting processes.
It’s worth noting that Vancouver’s overall density of 1 FSR is higher than both Kelowna and Coquitlam, but the base density allowed for existing single family use, including secondary suites and laneway houses, is also higher in Vancouver. Nevertheless, both remain lower than provincial guidelines for SSMUH. Moreover, demand to live in the area is higher in Vancouver, so it’s not clear how differences in density allowances translates.
Apart from differences in demand and existing vs updated density allowances, value capture efforts may be holding back some of the reform’s potential. The reform handicapped higher density multiplex options with amenity contributions to the City and/or other limitations (secured rental or “affordable ownership” units) put in place intentionally to keep land values low. Importantly, though the equity concerns go unrecognized by the City, this tips the scales to the benefit of the most expensive form of housing - single-family detached - and against prospective buyers willing to share land across multiple households. Nevertheless small-scale developers are proving more willing to try out the new forms on offer than anticipated by planning staff, perhaps in hopes that they can scale up multiplex in the future or otherwise better prepare themselves for future reforms.
A more successful multiplex reform would see the City actively encouraging multiplex instead of just conditionally permitting them under value capture conditions. Expediting permits for pre-approved forms of multiplex, as was done for Kelowna, would help! Of note, there have been moves in this direction. A OneCity proposal Streamlining the Provision of Duplex and Multiplex Housing in R1-1 Zoning exploring further reforms was put forward as a motion by Councillor Lucy Maloney in July and was unanimously approved by Council ahead of a forthcoming review of R1-1 zoning being prepared by staff. If, as we suggest, the devil is in the details for multiplex reform, there’s a still a chance to get him out!
More broadly, stepping out of the multiplex fixation, more successful housing reforms would see the City asking what form of housing would match demand to live in different parts of the city and generally work to enable those forms to get built. (von Bergmann and Lauster 2025) By contrast, the provincial SSMUH initiative just sets a new baseline for zoning, stepping up from single-family detached. The Transit-Oriented Area (TOA) initiative does the same by specifying new baselines near major transit investments. Cities can go beyond these minimums by allowing more people to share land for housing everywhere, and they can get an idea of what the outcomes will be by looking to current demand and proactively planning to let developers build to that demand. That doesn’t mean everywhere will look alike (indeed, its often planning constraints that reinforce cookie-cutter designs). Instead, providing greater flexibility for builders is likely to result in more diverse urban landscapes. Working through the implications for that kind of reform would return urban planning to a forward looking activity recognizing the value of city life for everyone rather than a backward looking activity reducing land values to protect the privileges of the select few who can still afford a full lot of their own.
As usual, the code for this post is available on GitHub for anyone to reproduce or adapt for their own purposes.
[1] "2025-08-29 20:48:01 PDT"
Local: main /Users/jens/R/mountain_doodles
Remote: main @ origin (https://github.com/mountainMath/mountain_doodles.git)
Head: [e2ae55a] 2025-08-30: fix link
R version 4.5.1 (2025-06-13)
Platform: aarch64-apple-darwin20
Running under: macOS Sequoia 15.6.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: America/Vancouver
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] VancouvR_0.1.9 rvest_1.0.4 httr_1.4.7 lubridate_1.9.4
[5] forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4 purrr_1.1.0
[9] readr_2.1.5 tidyr_1.3.1 tibble_3.3.0 ggplot2_3.5.2
[13] tidyverse_2.0.0
loaded via a namespace (and not attached):
[1] generics_0.1.4 class_7.3-23
[3] xml2_1.3.8 KernSmooth_2.23-26
[5] stringi_1.8.7 hms_1.1.3
[7] digest_0.6.37 magrittr_2.0.3
[9] evaluate_1.0.4 grid_4.5.1
[11] timechange_0.3.0 RColorBrewer_1.1-3
[13] fastmap_1.2.0 rprojroot_2.0.4
[15] jsonlite_2.0.0 processx_3.8.6
[17] e1071_1.7-16 DBI_1.2.3
[19] chromote_0.5.1 urltools_1.7.3.1
[21] ps_1.9.1 promises_1.3.3
[23] scales_1.4.0 cli_3.6.5
[25] rlang_1.1.6 units_0.8-7
[27] triebeard_0.4.1 withr_3.0.2
[29] yaml_2.3.10 tools_4.5.1
[31] tzdb_0.5.0 here_1.0.1
[33] vctrs_0.6.5 R6_2.6.1
[35] git2r_0.36.2 proxy_0.4-27
[37] classInt_0.4-11 lifecycle_1.0.4
[39] htmlwidgets_1.6.4 pkgconfig_2.0.3
[41] pillar_1.11.0 later_1.4.2
[43] gtable_0.3.6 glue_1.8.0
[45] Rcpp_1.1.0 sf_1.0-21
[47] xfun_0.52 tidyselect_1.2.1
[49] rstudioapi_0.17.1 knitr_1.50
[51] farver_2.1.2 htmltools_0.5.8.1
[53] websocket_1.4.4 rmarkdown_2.29
[55] mountainmathHelpers_0.1.4 compiler_4.5.1
Vancouver amended it’s multiplex zoning to also allow multiplexes in RT-7, RT-9, and FSD zoning in June 2024.↩︎
Some projects might have several building permits, which we collapsed in this count.↩︎
Laneway houses can also be built on lots with existing single family homes as infill, we don’t show those here.↩︎
@misc{multiplex-reforms----the-details-matter.2025,
author = {{von Bergmann}, Jens and Lauster, Nathan},
title = {Multiplex Reforms -\/- the Details Matter},
date = {2025-08-29},
url = {https://doodles.mountainmath.ca/posts/2025-08-29-multiplex-reforms----the-details-matter/},
langid = {en}
}