PPOL 6805 / DSAN 6750: GIS for Spatial Data Science
Fall 2026
Wednesday, September 2, 2026
Today’s Planned Schedule:
| Start | End | Topic | |
|---|---|---|---|
| Lecture | 6:30pm | 7:00pm | Logistics 1: Positron → |
| 6:50pm | 7:15pm | Logistics 2: Reducing Fear → | |
| 7:20pm | 7:50pm | Building Our First Map! → | |
| Break! | 7:50pm | 8:00pm | |
| 8:00pm | 8:30pm | Raster Data → | |
| 8:30pm | 9:00pm | Finding GIS Data → |
\[ \DeclareMathOperator*{\argmax}{argmax} \DeclareMathOperator*{\argmin}{argmin} \newcommand{\bigexp}[1]{\exp\mkern-4mu\left[ #1 \right]} \newcommand{\bigexpect}[1]{\mathbb{E}\mkern-4mu \left[ #1 \right]} \newcommand{\definedas}{\overset{\small\text{def}}{=}} \newcommand{\definedalign}{\overset{\phantom{\text{defn}}}{=}} \newcommand{\eqeventual}{\overset{\text{eventually}}{=}} \newcommand{\Err}{\text{Err}} \newcommand{\expect}[1]{\mathbb{E}[#1]} \newcommand{\expectsq}[1]{\mathbb{E}^2[#1]} \newcommand{\fw}[1]{\texttt{#1}} \newcommand{\given}{\mid} \newcommand{\green}[1]{\color{green}{#1}} \newcommand{\heads}{\outcome{heads}} \newcommand{\iid}{\overset{\text{\small{iid}}}{\sim}} \newcommand{\lik}{\mathcal{L}} \newcommand{\loglik}{\ell} \DeclareMathOperator*{\maximize}{maximize} \DeclareMathOperator*{\minimize}{minimize} \newcommand{\mle}{\textsf{ML}} \newcommand{\nimplies}{\;\not\!\!\!\!\implies} \newcommand{\orange}[1]{\color{orange}{#1}} \newcommand{\outcome}[1]{\textsf{#1}} \newcommand{\param}[1]{{\color{purple} #1}} \newcommand{\pgsamplespace}{\{\green{1},\green{2},\green{3},\purp{4},\purp{5},\purp{6}\}} \newcommand{\pedge}[2]{\require{enclose}\enclose{circle}{~{#1}~} \rightarrow \; \enclose{circle}{\kern.01em {#2}~\kern.01em}} \newcommand{\pnode}[1]{\require{enclose}\enclose{circle}{\kern.1em {#1} \kern.1em}} \newcommand{\ponode}[1]{\require{enclose}\enclose{box}[background=lightgray]{{#1}}} \newcommand{\pnodesp}[1]{\require{enclose}\enclose{circle}{~{#1}~}} \newcommand{\purp}[1]{\color{purple}{#1}} \newcommand{\sign}{\text{Sign}} \newcommand{\spacecap}{\; \cap \;} \newcommand{\spacewedge}{\; \wedge \;} \newcommand{\tails}{\outcome{tails}} \newcommand{\Var}[1]{\text{Var}[#1]} \newcommand{\bigVar}[1]{\text{Var}\mkern-4mu \left[ #1 \right]} \]
| Umbrella Term | Concepts | Specific Skills |
|---|---|---|
| Coding |
|
|
| GIS |
|
|
Analogy from non-geospatial data science:
| Text Drawn Map |
→ | Speadsheet Digital Map |
→ | Equations Maps w/ArcGIS |
→ | Code This Class |
||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Start writing
info.txt
|
Start entering info in rows
|
Start using equations
|
Write code Profit 💲💰🤑💰💲 |
|||||||||||||||||||||||||||
Our teaching should be governed, not by a desire to make students learn things, but by the endeavor to keep burning within them that light which is called curiosity. (Montessori 1916)
| Take the time/energy you're using to worry about... | Use it instead to worry about... |
|---|---|
|
Learning GIS |
Geometers solved w/geometry (300 BC)…

…Algebraists solved w/algebra (2000 BC)…
\[ \begin{align*} &ax^2 + bx + c = 0 \\ \Rightarrow \; & x_+ = \frac{-b + \sqrt{b^2 - 4ac}}{2a} \end{align*} \]
…From 1637 onwards, whichever is easier! 🤯🤯🤯 (Isomorphism)

Reading layer `Census_Tracts_in_2020' from data source
`/Users/jpj/gtown-local/ppol6805/w02/data/DC_Census_2020/Census_Tracts_in_2020.shp'
using driver `ESRI Shapefile'
Simple feature collection with 206 features and 315 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -8584933 ymin: 4691871 xmax: -8561515 ymax: 4721078
Projected CRS: WGS 84 / Pseudo-Mercator
sf Objectsdc_sf is an R object of type sf (short for “simple features”), which extends data.frame by adding a special column named geometry (containing POLYGONs)
POLYGON Objects?Simple feature collection with 6 features and 12 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -8577962 ymin: 4708107 xmax: -8572564 ymax: 4716136
Projected CRS: WGS 84 / Pseudo-Mercator
OBJECTID TRACT GEOID ALAND AWATER STUSAB SUMLEV GEOCODE STATE
1 1 002002 11001002002 849376 0 DC 140 11001002002 11
2 2 002101 11001002101 600992 0 DC 140 11001002101 11
3 3 002102 11001002102 725975 0 DC 140 11001002102 11
4 4 002201 11001002201 415173 0 DC 140 11001002201 11
5 5 002202 11001002202 698895 566 DC 140 11001002202 11
6 6 000101 11001000101 199776 5261 DC 140 11001000101 11
NAME POP100 HU100 geometry
1 Census Tract 20.02 4072 1532 POLYGON ((-8575655 4714476,...
2 Census Tract 21.01 5687 2335 POLYGON ((-8574745 4715676,...
3 Census Tract 21.02 5099 2221 POLYGON ((-8573824 4715684,...
4 Census Tract 22.01 3485 1229 POLYGON ((-8574654 4714781,...
5 Census Tract 22.02 3339 1454 POLYGON ((-8573792 4714811,...
6 Census Tract 1.01 1406 999 POLYGON ((-8577962 4708867,...
Nope, we’ll have to open the “black box” using the st_coordinates() function from the sf library →
X Y L1 L2
[1,] -8575655 4714476 1 1
[2,] -8575655 4714588 1 1
[3,] -8575655 4714628 1 1
[4,] -8575655 4714781 1 1
[5,] -8575655 4714876 1 1
[6,] -8575636 4714900 1 1
[7,] -8575622 4714920 1 1
[8,] -8575613 4714934 1 1
[9,] -8575595 4714962 1 1
[10,] -8575564 4715009 1 1
[11,] -8575519 4715077 1 1
[12,] -8575502 4715104 1 1
[13,] -8575452 4715179 1 1
[14,] -8575408 4715248 1 1
[15,] -8575362 4715318 1 1
[16,] -8575359 4715322 1 1
[17,] -8575320 4715400 1 1
[18,] -8575294 4715424 1 1
[19,] -8575272 4715454 1 1
[20,] -8575268 4715459 1 1
[21,] -8575242 4715499 1 1
[22,] -8575237 4715507 1 1
[23,] -8575226 4715523 1 1
[24,] -8575221 4715531 1 1
[25,] -8575205 4715556 1 1
[26,] -8575198 4715567 1 1
[27,] -8575190 4715579 1 1
[28,] -8575167 4715614 1 1
[29,] -8575142 4715652 1 1
[30,] -8575132 4715668 1 1
[31,] -8575116 4715692 1 1
[32,] -8575105 4715709 1 1
[33,] -8575094 4715724 1 1
[34,] -8575069 4715764 1 1
[35,] -8575031 4715822 1 1
[36,] -8575021 4715836 1 1
[37,] -8575008 4715855 1 1
[38,] -8574983 4715894 1 1
[39,] -8574959 4715928 1 1
[40,] -8574954 4715933 1 1
[41,] -8574952 4715935 1 1
[42,] -8574943 4715943 1 1
[43,] -8574939 4715947 1 1
[44,] -8574907 4715975 1 1
[45,] -8574904 4715976 1 1
[46,] -8574901 4715977 1 1
[47,] -8574898 4715978 1 1
[48,] -8574893 4715980 1 1
[49,] -8574889 4715984 1 1
[50,] -8574886 4715986 1 1
[51,] -8574883 4715990 1 1
[52,] -8574857 4716021 1 1
[53,] -8574802 4716086 1 1
[54,] -8574783 4716108 1 1
[55,] -8574779 4716114 1 1
[56,] -8574778 4716117 1 1
[57,] -8574775 4716123 1 1
[58,] -8574774 4716127 1 1
[59,] -8574775 4716129 1 1
[60,] -8574776 4716136 1 1
[61,] -8574735 4716130 1 1
[62,] -8574724 4716125 1 1
[63,] -8574719 4716120 1 1
[64,] -8574720 4716116 1 1
[65,] -8574721 4716094 1 1
[66,] -8574721 4716090 1 1
[67,] -8574724 4716050 1 1
[68,] -8574730 4715948 1 1
[69,] -8574736 4715850 1 1
[70,] -8574742 4715760 1 1
[71,] -8574743 4715730 1 1
[72,] -8574744 4715709 1 1
[73,] -8574744 4715699 1 1
[74,] -8574745 4715676 1 1
[75,] -8574745 4715665 1 1
[76,] -8574744 4715654 1 1
[77,] -8574744 4715631 1 1
[78,] -8574742 4715608 1 1
[79,] -8574742 4715596 1 1
[80,] -8574741 4715585 1 1
[81,] -8574737 4715555 1 1
[82,] -8574736 4715539 1 1
[83,] -8574733 4715518 1 1
[84,] -8574731 4715495 1 1
[85,] -8574726 4715446 1 1
[86,] -8574721 4715403 1 1
[87,] -8574720 4715389 1 1
[88,] -8574718 4715373 1 1
[89,] -8574713 4715331 1 1
[90,] -8574706 4715261 1 1
[91,] -8574705 4715250 1 1
[92,] -8574703 4715235 1 1
[93,] -8574699 4715194 1 1
[94,] -8574695 4715157 1 1
[95,] -8574688 4715097 1 1
[96,] -8574687 4715085 1 1
[97,] -8574670 4714929 1 1
[98,] -8574669 4714917 1 1
[99,] -8574669 4714914 1 1
[100,] -8574654 4714781 1 1
[101,] -8574651 4714745 1 1
[102,] -8574638 4714628 1 1
[103,] -8574637 4714615 1 1
[104,] -8574636 4714603 1 1
[105,] -8574634 4714590 1 1
[106,] -8574633 4714578 1 1
[107,] -8574631 4714565 1 1
[108,] -8574630 4714553 1 1
[109,] -8574625 4714503 1 1
[110,] -8574622 4714475 1 1
[111,] -8574616 4714418 1 1
[112,] -8574612 4714382 1 1
[113,] -8574611 4714369 1 1
[114,] -8574608 4714347 1 1
[115,] -8574607 4714336 1 1
[116,] -8574602 4714293 1 1
[117,] -8574601 4714283 1 1
[118,] -8574600 4714275 1 1
[119,] -8574599 4714264 1 1
[120,] -8574586 4714137 1 1
[121,] -8574583 4714111 1 1
[122,] -8574569 4713998 1 1
[123,] -8574562 4713958 1 1
[124,] -8574609 4713959 1 1
[125,] -8574659 4713958 1 1
[126,] -8574695 4713958 1 1
[127,] -8574741 4713958 1 1
[128,] -8574821 4713959 1 1
[129,] -8574901 4713958 1 1
[130,] -8574921 4713996 1 1
[131,] -8574923 4713999 1 1
[132,] -8574946 4714027 1 1
[133,] -8574966 4714053 1 1
[134,] -8574989 4714082 1 1
[135,] -8575017 4714117 1 1
[136,] -8575019 4714120 1 1
[137,] -8575029 4714133 1 1
[138,] -8575049 4714158 1 1
[139,] -8575057 4714171 1 1
[140,] -8575060 4714175 1 1
[141,] -8575062 4714178 1 1
[142,] -8575065 4714181 1 1
[143,] -8575103 4714228 1 1
[144,] -8575122 4714253 1 1
[145,] -8575129 4714261 1 1
[146,] -8575244 4714265 1 1
[147,] -8575259 4714265 1 1
[148,] -8575284 4714264 1 1
[149,] -8575358 4714264 1 1
[150,] -8575432 4714264 1 1
[151,] -8575443 4714264 1 1
[152,] -8575540 4714264 1 1
[153,] -8575639 4714264 1 1
[154,] -8575656 4714264 1 1
[155,] -8575655 4714476 1 1
sf Objects[1] "Census Tract 20.02" "Census Tract 21.01" "Census Tract 21.02"
[4] "Census Tract 22.01" "Census Tract 22.02" "Census Tract 1.01"
Simple feature collection with 6 features and 1 field
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -8577962 ymin: 4708107 xmax: -8572564 ymax: 4716136
Projected CRS: WGS 84 / Pseudo-Mercator
ALAND geometry
1 849376 POLYGON ((-8575655 4714476,...
2 600992 POLYGON ((-8574745 4715676,...
3 725975 POLYGON ((-8573824 4715684,...
4 415173 POLYGON ((-8574654 4714781,...
5 698895 POLYGON ((-8573792 4714811,...
6 199776 POLYGON ((-8577962 4708867,...
ggplot!\[ \text{Data} = \left\{Z(\mathbf{s}) \mid \mathbf{s} \in D \subset \mathbb{R}^2\right\} \]
| Geostatistical Data | Lattice/Region Data | Point Pattern | |
|---|---|---|---|
| Criteria | Fixed \(D\), Continuous | Fixed \(D\), Discrete | Random subset \(D^* \subseteq D\) |
| Interest | Infer non-observed parts of \(D\) | Autocorrelation, clustering | Point-generating process |
| Example |
|
|
|
library(tidyverse)
library(spatstat)
set.seed(6805)
N <- 60
r_core <- 0.05
obs_window <- square(1)
# Regularity via Inhibition
#reg_sims <- rMaternI(N, r=r_core, win=obs_window)
cond_reg_sims <- rSSI(r=r_core, N)
# CSR data
#csr_sims <- rpoispp(N, win=obs_window)
cond_sr_sims <- rpoint(N, win=obs_window)
### Clustered data
#clust_sims <- rMatClust(kappa=6, r=2.5*r_core, mu=10, win=obs_window)
#clust_sims <- rMatClust(mu=5, kappa=1, scale=0.1, win=obs_window, n.cond=N, w.cond=obs_window)
#clust_sims <- rclusterBKBC(clusters="MatClust", kappa=10, mu=10, scale=0.05, verbose=FALSE)
# Each cluster consist of 10 points in a disc of radius 0.2
nclust <- function(x0, y0, radius, n) {
#print(n)
return(runifdisc(10, radius, centre=c(x0, y0)))
}
cond_clust_sims <- rNeymanScott(kappa=5, expand=0.0, rclust=nclust, radius=2*r_core, n=10)
# And PLOT
plot_w <- 400
plot_h <- 400
plot_scale <- 2.25
cond_reg_plot <- cond_reg_sims |> sf::st_as_sf() |>
ggplot() +
geom_sf() +
dsan_theme() +
transparent_bg()
ggsave("images/cond_reg.png", cond_reg_plot, width=plot_w, height=plot_h, units="px", scale=plot_scale)
cond_sr_plot <- cond_sr_sims |> sf::st_as_sf() |>
ggplot() +
geom_sf() +
dsan_theme() +
transparent_bg()
ggsave("images/cond_sr.png", cond_sr_plot, width=plot_w, height=plot_h, units="px", scale=plot_scale)
cond_clust_plot <- cond_clust_sims |> sf::st_as_sf() |>
ggplot() +
geom_sf() +
dsan_theme() +
transparent_bg()
ggsave("images/cond_clust.png", cond_clust_plot, width=plot_w, height=plot_h, units="px", scale=plot_scale)| Autocorrelation | \(I = -1\) | ← | \(I = 0\) | → | \(I = 1\) |
|---|---|---|---|---|---|
| Description | Negative Autocorr | No Autocorr | Positive Autocorr | ||
| Event at \(\mathbf{s} = (x,y)\) Implies | Less likely to find another point nearby | No information about nearby points | More likely to find another point nearby | ||
| Resulting Pattern | Regularity | Reg/Clustered Mix | Clustering | ||
| Process(es) Which Could Produce Pattern | 1st Order: Random within even-spaced grid 2nd Order: Competition |
1st Order: i.i.d. points 2nd Order: i.i.d. distances |
1st Order: Tasty food at clust centers 2nd Order: Cooperation |
||
| Fixed \(N\) | 60 | 60 | 60 | ||
![]() |
![]() |
![]() |
library(tidyverse)
library(spatstat)
set.seed(6807)
lambda <- 60
r_core <- 0.05
obs_window <- square(1)
# Regularity via Inhibition
# Regularity via Inhibition
reg_sims <- rMaternI(lambda, r=r_core, win=obs_window)
# CSR data
csr_sims <- rpoispp(N, win=obs_window)
### Clustered data
clust_mu <- 10
clust_sims <- rMatClust(kappa=lambda / clust_mu, scale=2*r_core, mu=10, win=obs_window)
# And PLOT
plot_w <- 400
plot_h <- 400
plot_scale <- 2.25
reg_plot <- reg_sims |> sf::st_as_sf() |>
ggplot() +
geom_sf() +
labs(title=paste0("N = ",reg_sims$n)) +
dsan_theme() +
transparent_bg()
ggsave("images/reg.png", reg_plot, width=plot_w, height=plot_h, units="px", scale=plot_scale)
csr_plot <- csr_sims |> sf::st_as_sf() |>
ggplot() +
geom_sf() +
labs(title=paste0("N = ",csr_sims$n)) +
dsan_theme() +
transparent_bg()
ggsave("images/csr.png", csr_plot, width=plot_w, height=plot_h, units="px", scale=plot_scale)
clust_plot <- clust_sims |> sf::st_as_sf() |>
ggplot() +
geom_sf() +
labs(title=paste0("N = ",clust_sims$n)) +
dsan_theme() +
transparent_bg()
ggsave("images/clust.png", clust_plot, width=plot_w, height=plot_h, units="px", scale=plot_scale)| Autocorrelation | \(I = -1\) | ← | \(I = 0\) | → | \(I = 1\) |
|---|---|---|---|---|---|
| Description | Negative Autocorr | No Autocorr | Positive Autocorr | ||
| Event at \(\mathbf{s} = (x,y)\) Implies | Less likely to find another point nearby | No information about nearby points | More likely to find another point nearby | ||
| Resulting Pattern | Regularity | Reg/Clustered Mix | Clustering | ||
| Process(es) Which Could Produce Pattern | 1st Order: Random within even-spaced grid 2nd Order: Competition |
1st Order: i.i.d. points 2nd Order: i.i.d. distances |
1st Order: Tasty food at clust centers 2nd Order: Cooperation |
||
| Fixed Intensity \(\lambda\) | 60 | 60 | 60 | ||
| Random \(N\) | ![]() |
![]() |
![]() |
Geometers solved w/geometry (300 BC)…

…Algebraists solved w/algebra (2000 BC)…
\[ \begin{align*} &ax^2 + bx + c = 0 \\ \Rightarrow \; & x_+ = \frac{-b + \sqrt{b^2 - 4ac}}{2a} \end{align*} \]
…From 1637 onwards, whichever is easier! 🤯🤯🤯 (Isomorphism)

POLYGONPOLYGONs may make sense for demographers, but how about someone studying air pollution in DC? (Smog, for example, does not confine itself to census tracts!)terra)[1] 29 23 1
Welcome to Gridtown!
Figure 6: Gridtown Values
PPOL 6805 Week 2: How Do Maps Work?