Skip to content

Commit 4cb9bdb

Browse files
committed
syntethic census from routing to POIs
1 parent 7268d70 commit 4cb9bdb

2 files changed

Lines changed: 59 additions & 59 deletions

File tree

pois.qmd

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,65 @@ city_limit = census |> st_union() |> st_as_sf()
5454
plot(city_limit)
5555
```
5656

57+
::: callout-note
58+
## Note
59+
60+
If you don't have census data at a reasonable level (census blocks), you can recreate random points in your city.
61+
See the code bellow 🔎
62+
:::
63+
64+
```{r}
65+
#| code-fold: true
66+
#| code-summary: "Generate synthetic census-like points for a City"
67+
# 0. Load libraries
68+
library(sf)
69+
library(dplyr)
70+
71+
# 1. Read city polygon (replace with your file path)
72+
city_limit <- st_read("data/city_limit.gpkg") |> st_transform(4326)
73+
74+
# 2. Set parameters
75+
set.seed(42) # for reproducibility
76+
total_pop <- 545000 # your city population
77+
avg_residents <- 300 # a census block average
78+
n_points <- round(total_pop / avg_residents)
79+
80+
# 3. Generate random points within the city boundary
81+
census_syn <- st_sample(city_limit, size = n_points, type = "random") |>
82+
st_as_sf() |>
83+
mutate(id = 1:n_points)
84+
85+
# # 4. Compute distance from city center (for density weighting) - OPTIONAL
86+
# center <- st_centroid(city_limit)
87+
# dist_center <- as.numeric(st_distance(census_syn, center)) # in meters
88+
#
89+
# # 5. Create weights so closer points get higher population - OPTIONAL
90+
# # Inverse distance weighting (add +1 to avoid division by zero)
91+
# weights <- 1 / (dist_center + 1)
92+
93+
# assign random populations that sum to total_pop
94+
weights <- runif(n_points)
95+
96+
# Normalize weights to sum to 1 and assign residents
97+
residents <- round(weights / sum(weights) * total_pop)
98+
99+
# 6. Adjust rounding so the total sums exactly to total_pop
100+
diff <- total_pop - sum(residents)
101+
if (diff != 0) {
102+
residents[1:abs(diff)] <- residents[1:abs(diff)] + sign(diff)
103+
}
104+
105+
# 7. Add residents to points
106+
census_syn$residents <- residents
107+
sum(census_syn$residents) # should be total_pop
108+
109+
# 8. Quick visualization
110+
mapview::mapview(census_syn, zcol = "residents")
111+
112+
# 9. Save for later
113+
st_write(census_syn, "data/synthetic_census_points.gpkg", delete_dsn = TRUE)
114+
```
115+
57116
## Points of Interest
58117

59118
### OpenStreetMap

routing.qmd

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -45,65 +45,6 @@ city_center$lon = st_coordinates(city_center)[,1]
4545
city_center$lat = st_coordinates(city_center)[,2]
4646
```
4747

48-
::: callout-note
49-
## Note
50-
51-
If you don't have census data at a reasonable level (census blocks), you can recreate random points in your city.
52-
See the code bellow 🔎
53-
:::
54-
55-
```{r}
56-
#| code-fold: true
57-
#| code-summary: "Generate synthetic census-like points for a City"
58-
# 0. Load libraries
59-
library(sf)
60-
library(dplyr)
61-
62-
# 1. Read city polygon (replace with your file path)
63-
city_limit <- st_read("data/city_limit.gpkg") |> st_transform(4326)
64-
65-
# 2. Set parameters
66-
set.seed(42) # for reproducibility
67-
total_pop <- 545000 # your city population
68-
avg_residents <- 300 # a census block average
69-
n_points <- round(total_pop / avg_residents)
70-
71-
# 3. Generate random points within the city boundary
72-
census_syn <- st_sample(city_limit, size = n_points, type = "random") |>
73-
st_as_sf() |>
74-
mutate(id = 1:n_points)
75-
76-
# # 4. Compute distance from city center (for density weighting) - OPTIONAL
77-
# center <- st_centroid(city_limit)
78-
# dist_center <- as.numeric(st_distance(census_syn, center)) # in meters
79-
#
80-
# # 5. Create weights so closer points get higher population - OPTIONAL
81-
# # Inverse distance weighting (add +1 to avoid division by zero)
82-
# weights <- 1 / (dist_center + 1)
83-
84-
# assign random populations that sum to total_pop
85-
weights <- runif(n_points)
86-
87-
# Normalize weights to sum to 1 and assign residents
88-
residents <- round(weights / sum(weights) * total_pop)
89-
90-
# 6. Adjust rounding so the total sums exactly to total_pop
91-
diff <- total_pop - sum(residents)
92-
if (diff != 0) {
93-
residents[1:abs(diff)] <- residents[1:abs(diff)] + sign(diff)
94-
}
95-
96-
# 7. Add residents to points
97-
census_syn$residents <- residents
98-
sum(census_syn$residents) # should be total_pop
99-
100-
# 8. Quick visualization
101-
mapview::mapview(census_syn, zcol = "residents")
102-
103-
# 9. Save to GeoPackage
104-
st_write(census_syn, "data/synthetic_census_points.gpkg", delete_dsn = TRUE)
105-
```
106-
10748
## Travel Time Matrix {#ttm}
10849

10950
```{r}

0 commit comments

Comments
 (0)